mirror of
https://git.sanhost.net/sanasol/hytale-f2p.git
synced 2026-02-26 14:51:48 -03:00
Compare commits
16 Commits
refactor/b
...
v2.3.0-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4b5368538 | ||
|
|
e0ebf137fc | ||
|
|
5241a502e5 | ||
|
|
3e7c7ccff3 | ||
|
|
89d09f032f | ||
|
|
8bdb78d1e2 | ||
|
|
e9e66dbca7 | ||
|
|
82f1dd2739 | ||
|
|
4502c11bd0 | ||
|
|
bcc7476322 | ||
|
|
ae6a7db80a | ||
|
|
48395fbff3 | ||
|
|
aae90a72e8 | ||
|
|
a6c61aef68 | ||
|
|
31653a37a7 | ||
|
|
1cb08f029a |
24
.github/workflows/release.yml
vendored
24
.github/workflows/release.yml
vendored
@@ -6,6 +6,12 @@ on:
|
|||||||
- 'v*'
|
- 'v*'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Domain for small API calls (goes through Cloudflare - fine for <100MB)
|
||||||
|
FORGEJO_API: https://git.sanhost.net/api/v1
|
||||||
|
# Direct to Forgejo port (bypasses Cloudflare + Traefik for large uploads)
|
||||||
|
FORGEJO_UPLOAD: http://208.69.78.130:3001/api/v1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-release:
|
create-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -13,7 +19,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Create Draft Release
|
- name: Create Draft Release
|
||||||
run: |
|
run: |
|
||||||
curl -s -X POST "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases" \
|
curl -s -X POST "${FORGEJO_API}/repos/${GITHUB_REPOSITORY}/releases" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "{\"tag_name\":\"${{ github.ref_name }}\",\"name\":\"${{ github.ref_name }}\",\"body\":\"Release ${{ github.ref_name }}\",\"draft\":true,\"prerelease\":false}" \
|
-d "{\"tag_name\":\"${{ github.ref_name }}\",\"name\":\"${{ github.ref_name }}\",\"body\":\"Release ${{ github.ref_name }}\",\"draft\":true,\"prerelease\":false}" \
|
||||||
@@ -40,16 +46,16 @@ jobs:
|
|||||||
- run: npm ci
|
- run: npm ci
|
||||||
|
|
||||||
- name: Build Windows Packages
|
- name: Build Windows Packages
|
||||||
run: npx electron-builder --win --publish never
|
run: npx electron-builder --win --publish never --config.npmRebuild=false
|
||||||
|
|
||||||
- name: Upload to Release
|
- name: Upload to Release
|
||||||
run: |
|
run: |
|
||||||
RELEASE_ID=$(curl -s "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases/tags/${{ github.ref_name }}" \
|
RELEASE_ID=$(curl -s "${FORGEJO_API}/repos/${GITHUB_REPOSITORY}/releases/tags/${{ github.ref_name }}" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
||||||
for file in dist/*.exe dist/*.exe.blockmap dist/latest.yml; do
|
for file in dist/*.exe dist/*.exe.blockmap dist/latest.yml; do
|
||||||
[ -f "$file" ] || continue
|
[ -f "$file" ] || continue
|
||||||
echo "Uploading $file..."
|
echo "Uploading $file..."
|
||||||
curl -s -X POST "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename $file)" \
|
curl -s --max-time 600 -X POST "${FORGEJO_UPLOAD}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename $file)" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
||||||
-F "attachment=@${file}" || echo "Failed to upload $file"
|
-F "attachment=@${file}" || echo "Failed to upload $file"
|
||||||
done
|
done
|
||||||
@@ -75,19 +81,19 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload to Release
|
- name: Upload to Release
|
||||||
run: |
|
run: |
|
||||||
RELEASE_ID=$(curl -s "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases/tags/${{ github.ref_name }}" \
|
RELEASE_ID=$(curl -s "${FORGEJO_API}/repos/${GITHUB_REPOSITORY}/releases/tags/${{ github.ref_name }}" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
||||||
for file in dist/*.dmg dist/*.zip dist/*.blockmap dist/latest-mac.yml; do
|
for file in dist/*.dmg dist/*.zip dist/*.blockmap dist/latest-mac.yml; do
|
||||||
[ -f "$file" ] || continue
|
[ -f "$file" ] || continue
|
||||||
echo "Uploading $file..."
|
echo "Uploading $file..."
|
||||||
curl -s -X POST "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename $file)" \
|
curl -s --max-time 600 -X POST "${FORGEJO_UPLOAD}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename $file)" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
||||||
-F "attachment=@${file}" || echo "Failed to upload $file"
|
-F "attachment=@${file}" || echo "Failed to upload $file"
|
||||||
done
|
done
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
needs: [create-release]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: [create-release]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install build dependencies
|
- name: Install build dependencies
|
||||||
@@ -105,12 +111,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload to Release
|
- name: Upload to Release
|
||||||
run: |
|
run: |
|
||||||
RELEASE_ID=$(curl -s "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases/tags/${{ github.ref_name }}" \
|
RELEASE_ID=$(curl -s "${FORGEJO_API}/repos/${GITHUB_REPOSITORY}/releases/tags/${{ github.ref_name }}" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
||||||
for file in dist/*.AppImage dist/*.AppImage.blockmap dist/*.deb dist/*.rpm dist/latest-linux.yml; do
|
for file in dist/*.AppImage dist/*.AppImage.blockmap dist/*.deb dist/*.rpm dist/latest-linux.yml; do
|
||||||
[ -f "$file" ] || continue
|
[ -f "$file" ] || continue
|
||||||
echo "Uploading $file..."
|
echo "Uploading $file..."
|
||||||
curl -s -X POST "https://git.sanhost.net/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename $file)" \
|
curl -s --max-time 600 -X POST "${FORGEJO_UPLOAD}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename $file)" \
|
||||||
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
|
||||||
-F "attachment=@${file}" || echo "Failed to upload $file"
|
-F "attachment=@${file}" || echo "Failed to upload $file"
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const FORCE_CLEAN_INSTALL_VERSION = false;
|
const FORCE_CLEAN_INSTALL_VERSION = false;
|
||||||
const CLEAN_INSTALL_TEST_VERSION = '4.pwr';
|
const CLEAN_INSTALL_TEST_VERSION = 'v4';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
FORCE_CLEAN_INSTALL_VERSION,
|
FORCE_CLEAN_INSTALL_VERSION,
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ async function safeRemoveDirectory(dirPath, maxRetries = 3) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function downloadPWR(branch = 'release', fileName = '7.pwr', progressCallback, cacheDir = CACHE_DIR, manualRetry = false) {
|
async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback, cacheDir = CACHE_DIR, manualRetry = false) {
|
||||||
const osName = getOS();
|
const osName = getOS();
|
||||||
const arch = getArch();
|
const arch = getArch();
|
||||||
|
|
||||||
@@ -72,8 +72,23 @@ async function downloadPWR(branch = 'release', fileName = '7.pwr', progressCallb
|
|||||||
throw new Error('Hytale x86_64 Intel Mac Support has not been released yet. Please check back later.');
|
throw new Error('Hytale x86_64 Intel Mac Support has not been released yet. Please check back later.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `https://game-patches.hytale.com/patches/${osName}/${arch}/${branch}/0/${fileName}`;
|
const { getPWRUrlFromNewAPI } = require('../services/versionManager');
|
||||||
const dest = path.join(cacheDir, `${branch}_${fileName}`);
|
|
||||||
|
let url;
|
||||||
|
let isUsingNewAPI = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`[DownloadPWR] Fetching URL from new API for branch: ${branch}, version: ${fileName}`);
|
||||||
|
url = await getPWRUrlFromNewAPI(branch, fileName);
|
||||||
|
isUsingNewAPI = true;
|
||||||
|
console.log(`[DownloadPWR] Using new API URL: ${url}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[DownloadPWR] Failed to get URL from new API: ${error.message}`);
|
||||||
|
console.log(`[DownloadPWR] Falling back to old URL format`);
|
||||||
|
url = `https://game-patches.hytale.com/patches/${osName}/${arch}/${branch}/0/${fileName}.pwr`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dest = path.join(cacheDir, `${branch}_${fileName}.pwr`);
|
||||||
|
|
||||||
// Check if file exists and validate it
|
// Check if file exists and validate it
|
||||||
if (fs.existsSync(dest) && !manualRetry) {
|
if (fs.existsSync(dest) && !manualRetry) {
|
||||||
@@ -93,7 +108,7 @@ async function downloadPWR(branch = 'release', fileName = '7.pwr', progressCallb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Fetching PWR patch file:', url);
|
console.log(`Fetching PWR patch file from ${isUsingNewAPI ? 'NEW API' : 'old API'}:`, url);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (manualRetry) {
|
if (manualRetry) {
|
||||||
|
|||||||
@@ -6,32 +6,186 @@ const { smartRequest } = require('../utils/proxyClient');
|
|||||||
|
|
||||||
const BASE_PATCH_URL = 'https://game-patches.hytale.com/patches';
|
const BASE_PATCH_URL = 'https://game-patches.hytale.com/patches';
|
||||||
const MANIFEST_API = 'https://files.hytalef2p.com/api/patch_manifest';
|
const MANIFEST_API = 'https://files.hytalef2p.com/api/patch_manifest';
|
||||||
|
const NEW_API_URL = 'https://thecute.cloud/ShipOfYarn/api.php';
|
||||||
|
|
||||||
async function getLatestClientVersion(branch = 'release') {
|
let apiCache = null;
|
||||||
|
let apiCacheTime = 0;
|
||||||
|
const API_CACHE_DURATION = 60000; // 1 minute
|
||||||
|
|
||||||
|
async function fetchNewAPI() {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (apiCache && (now - apiCacheTime) < API_CACHE_DURATION) {
|
||||||
|
console.log('[NewAPI] Using cached API data');
|
||||||
|
return apiCache;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`Fetching latest client version from API (branch: ${branch})...`);
|
console.log('[NewAPI] Fetching from:', NEW_API_URL);
|
||||||
const response = await smartRequest(`https://files.hytalef2p.com/api/version_client?branch=${branch}`, {
|
const response = await axios.get(NEW_API_URL, {
|
||||||
timeout: 40000,
|
timeout: 15000,
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'Hytale-F2P-Launcher'
|
'User-Agent': 'Hytale-F2P-Launcher'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.data && response.data.client_version) {
|
if (response.data && response.data.hytale) {
|
||||||
const version = response.data.client_version;
|
apiCache = response.data;
|
||||||
console.log(`Latest client version for ${branch}: ${version}`);
|
apiCacheTime = now;
|
||||||
return version;
|
console.log('[NewAPI] API data fetched and cached successfully');
|
||||||
|
return response.data;
|
||||||
} else {
|
} else {
|
||||||
console.log('Warning: Invalid API response, falling back to latest known version (7.pwr)');
|
throw new Error('Invalid API response structure');
|
||||||
return '7.pwr';
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching client version:', error.message);
|
console.error('[NewAPI] Error fetching API:', error.message);
|
||||||
console.log('Warning: API unavailable, falling back to latest known version (7.pwr)');
|
if (apiCache) {
|
||||||
return '7.pwr';
|
console.log('[NewAPI] Using expired cache due to error');
|
||||||
|
return apiCache;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getLatestVersionFromNewAPI(branch = 'release') {
|
||||||
|
try {
|
||||||
|
const apiData = await fetchNewAPI();
|
||||||
|
const osName = getOS();
|
||||||
|
const arch = getArch();
|
||||||
|
|
||||||
|
let osKey = osName;
|
||||||
|
if (osName === 'darwin') {
|
||||||
|
osKey = 'mac';
|
||||||
|
}
|
||||||
|
|
||||||
|
const branchData = apiData.hytale[branch];
|
||||||
|
if (!branchData || !branchData[osKey]) {
|
||||||
|
throw new Error(`No data found for branch: ${branch}, OS: ${osKey}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const osData = branchData[osKey];
|
||||||
|
|
||||||
|
const versions = Object.keys(osData).filter(key => key.endsWith('.pwr'));
|
||||||
|
|
||||||
|
if (versions.length === 0) {
|
||||||
|
throw new Error(`No .pwr files found for ${osKey}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const versionNumbers = versions.map(v => {
|
||||||
|
const match = v.match(/v(\d+)/);
|
||||||
|
return match ? parseInt(match[1]) : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const latestVersionNumber = Math.max(...versionNumbers);
|
||||||
|
console.log(`[NewAPI] Latest version number: ${latestVersionNumber} for branch ${branch}`);
|
||||||
|
|
||||||
|
return `v${latestVersionNumber}`;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[NewAPI] Error getting latest version:', error.message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPWRUrlFromNewAPI(branch = 'release', version = 'v8') {
|
||||||
|
try {
|
||||||
|
const apiData = await fetchNewAPI();
|
||||||
|
const osName = getOS();
|
||||||
|
const arch = getArch();
|
||||||
|
|
||||||
|
let osKey = osName;
|
||||||
|
if (osName === 'darwin') {
|
||||||
|
osKey = 'mac';
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileName;
|
||||||
|
if (osName === 'windows') {
|
||||||
|
fileName = `${version}-windows-amd64.pwr`;
|
||||||
|
} else if (osName === 'linux') {
|
||||||
|
fileName = `${version}-linux-amd64.pwr`;
|
||||||
|
} else if (osName === 'darwin') {
|
||||||
|
fileName = `${version}-darwin-arm64.pwr`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const branchData = apiData.hytale[branch];
|
||||||
|
if (!branchData || !branchData[osKey]) {
|
||||||
|
throw new Error(`No data found for branch: ${branch}, OS: ${osKey}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const osData = branchData[osKey];
|
||||||
|
const url = osData[fileName];
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
throw new Error(`No URL found for ${fileName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[NewAPI] URL for ${fileName}: ${url}`);
|
||||||
|
return url;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[NewAPI] Error getting PWR URL:', error.message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLatestClientVersion(branch = 'release') {
|
||||||
|
try {
|
||||||
|
console.log(`[NewAPI] Fetching latest client version from new API (branch: ${branch})...`);
|
||||||
|
|
||||||
|
// Utiliser la nouvelle API
|
||||||
|
const latestVersion = await getLatestVersionFromNewAPI(branch);
|
||||||
|
console.log(`[NewAPI] Latest client version for ${branch}: ${latestVersion}`);
|
||||||
|
return latestVersion;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[NewAPI] Error fetching client version from new API:', error.message);
|
||||||
|
console.log('[NewAPI] Falling back to old API...');
|
||||||
|
|
||||||
|
// Fallback vers l'ancienne API si la nouvelle échoue
|
||||||
|
try {
|
||||||
|
const response = await smartRequest(`https://files.hytalef2p.com/api/version_client?branch=${branch}`, {
|
||||||
|
timeout: 40000,
|
||||||
|
headers: {
|
||||||
|
'User-Agent': 'Hytale-F2P-Launcher'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.data && response.data.client_version) {
|
||||||
|
const version = response.data.client_version;
|
||||||
|
console.log(`Latest client version for ${branch} (old API): ${version}`);
|
||||||
|
return version;
|
||||||
|
} else {
|
||||||
|
console.log('Warning: Invalid API response, falling back to latest known version (v8)');
|
||||||
|
return 'v8';
|
||||||
|
}
|
||||||
|
} catch (fallbackError) {
|
||||||
|
console.error('Error fetching client version from old API:', fallbackError.message);
|
||||||
|
console.log('Warning: Both APIs unavailable, falling back to latest known version (v8)');
|
||||||
|
return 'v8';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction utilitaire pour extraire le numéro de version
|
||||||
|
// Supporte les formats: "7.pwr", "v8", "v8-windows-amd64.pwr", etc.
|
||||||
|
function extractVersionNumber(version) {
|
||||||
|
if (!version) return 0;
|
||||||
|
|
||||||
|
// Nouveau format: "v8" ou "v8-xxx.pwr"
|
||||||
|
const vMatch = version.match(/v(\d+)/);
|
||||||
|
if (vMatch) {
|
||||||
|
return parseInt(vMatch[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ancien format: "7.pwr"
|
||||||
|
const pwrMatch = version.match(/(\d+)\.pwr/);
|
||||||
|
if (pwrMatch) {
|
||||||
|
return parseInt(pwrMatch[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: essayer de parser directement
|
||||||
|
const num = parseInt(version);
|
||||||
|
return isNaN(num) ? 0 : num;
|
||||||
|
}
|
||||||
|
|
||||||
function buildArchiveUrl(buildNumber, branch = 'release') {
|
function buildArchiveUrl(buildNumber, branch = 'release') {
|
||||||
const os = getOS();
|
const os = getOS();
|
||||||
const arch = getArch();
|
const arch = getArch();
|
||||||
@@ -50,7 +204,7 @@ async function checkArchiveExists(buildNumber, branch = 'release') {
|
|||||||
|
|
||||||
async function discoverAvailableVersions(latestKnown, branch = 'release', maxProbe = 50) {
|
async function discoverAvailableVersions(latestKnown, branch = 'release', maxProbe = 50) {
|
||||||
const available = [];
|
const available = [];
|
||||||
const latest = parseInt(latestKnown.replace('.pwr', ''));
|
const latest = extractVersionNumber(latestKnown);
|
||||||
|
|
||||||
for (let i = latest; i >= Math.max(1, latest - maxProbe); i--) {
|
for (let i = latest; i >= Math.max(1, latest - maxProbe); i--) {
|
||||||
const exists = await checkArchiveExists(i, branch);
|
const exists = await checkArchiveExists(i, branch);
|
||||||
@@ -77,7 +231,7 @@ async function fetchPatchManifest(branch = 'release') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function extractVersionDetails(targetVersion, branch = 'release') {
|
async function extractVersionDetails(targetVersion, branch = 'release') {
|
||||||
const buildNumber = parseInt(targetVersion.replace('.pwr', ''));
|
const buildNumber = extractVersionNumber(targetVersion);
|
||||||
const previousBuild = buildNumber - 1;
|
const previousBuild = buildNumber - 1;
|
||||||
|
|
||||||
const manifest = await fetchPatchManifest(branch);
|
const manifest = await fetchPatchManifest(branch);
|
||||||
@@ -103,8 +257,8 @@ function canUseDifferentialUpdate(currentVersion, targetDetails) {
|
|||||||
|
|
||||||
if (!currentVersion) return false;
|
if (!currentVersion) return false;
|
||||||
|
|
||||||
const currentBuild = parseInt(currentVersion.replace('.pwr', ''));
|
const currentBuild = extractVersionNumber(currentVersion);
|
||||||
const expectedSource = parseInt(targetDetails.sourceVersion?.replace('.pwr', '') || '0');
|
const expectedSource = extractVersionNumber(targetDetails.sourceVersion);
|
||||||
|
|
||||||
return currentBuild === expectedSource;
|
return currentBuild === expectedSource;
|
||||||
}
|
}
|
||||||
@@ -112,8 +266,8 @@ function canUseDifferentialUpdate(currentVersion, targetDetails) {
|
|||||||
function needsIntermediatePatches(currentVersion, targetVersion) {
|
function needsIntermediatePatches(currentVersion, targetVersion) {
|
||||||
if (!currentVersion) return [];
|
if (!currentVersion) return [];
|
||||||
|
|
||||||
const current = parseInt(currentVersion.replace('.pwr', ''));
|
const current = extractVersionNumber(currentVersion);
|
||||||
const target = parseInt(targetVersion.replace('.pwr', ''));
|
const target = extractVersionNumber(targetVersion);
|
||||||
|
|
||||||
const intermediates = [];
|
const intermediates = [];
|
||||||
for (let i = current + 1; i <= target; i++) {
|
for (let i = current + 1; i <= target; i++) {
|
||||||
@@ -160,5 +314,9 @@ module.exports = {
|
|||||||
needsIntermediatePatches,
|
needsIntermediatePatches,
|
||||||
computeFileChecksum,
|
computeFileChecksum,
|
||||||
validateChecksum,
|
validateChecksum,
|
||||||
getInstalledClientVersion
|
getInstalledClientVersion,
|
||||||
|
fetchNewAPI,
|
||||||
|
getLatestVersionFromNewAPI,
|
||||||
|
getPWRUrlFromNewAPI,
|
||||||
|
extractVersionNumber
|
||||||
};
|
};
|
||||||
|
|||||||
8
main.js
8
main.js
@@ -627,7 +627,7 @@ ipcMain.handle('install-game', async (event, playerName, javaPath, installPath,
|
|||||||
console.log('[Main] Processing Butler error with retry context');
|
console.log('[Main] Processing Butler error with retry context');
|
||||||
errorData.retryData = {
|
errorData.retryData = {
|
||||||
branch: error.branch || 'release',
|
branch: error.branch || 'release',
|
||||||
fileName: error.fileName || '7.pwr',
|
fileName: error.fileName || 'v8',
|
||||||
cacheDir: error.cacheDir
|
cacheDir: error.cacheDir
|
||||||
};
|
};
|
||||||
errorData.canRetry = error.canRetry !== false;
|
errorData.canRetry = error.canRetry !== false;
|
||||||
@@ -647,7 +647,7 @@ ipcMain.handle('install-game', async (event, playerName, javaPath, installPath,
|
|||||||
console.log('[Main] Processing generic error, creating default retry data');
|
console.log('[Main] Processing generic error, creating default retry data');
|
||||||
errorData.retryData = {
|
errorData.retryData = {
|
||||||
branch: 'release',
|
branch: 'release',
|
||||||
fileName: '7.pwr'
|
fileName: 'v8'
|
||||||
};
|
};
|
||||||
// For generic errors, assume it's retryable unless specified
|
// For generic errors, assume it's retryable unless specified
|
||||||
errorData.canRetry = error.canRetry !== false;
|
errorData.canRetry = error.canRetry !== false;
|
||||||
@@ -887,7 +887,7 @@ ipcMain.handle('retry-download', async (event, retryData) => {
|
|||||||
console.log('[IPC] Invalid retry data, using PWR defaults');
|
console.log('[IPC] Invalid retry data, using PWR defaults');
|
||||||
retryData = {
|
retryData = {
|
||||||
branch: 'release',
|
branch: 'release',
|
||||||
fileName: '7.pwr'
|
fileName: 'v8'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -921,7 +921,7 @@ ipcMain.handle('retry-download', async (event, retryData) => {
|
|||||||
} :
|
} :
|
||||||
{
|
{
|
||||||
branch: retryData?.branch || 'release',
|
branch: retryData?.branch || 'release',
|
||||||
fileName: retryData?.fileName || '7.pwr',
|
fileName: retryData?.fileName || 'v8',
|
||||||
cacheDir: retryData?.cacheDir
|
cacheDir: retryData?.cacheDir
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hytale-f2p-launcher",
|
"name": "hytale-f2p-launcher",
|
||||||
"version": "2.2.1",
|
"version": "2.2.2",
|
||||||
"description": "A modern, cross-platform launcher for Hytale with automatic updates and multi-client support",
|
"description": "A modern, cross-platform launcher for Hytale with automatic updates and multi-client support",
|
||||||
"homepage": "https://github.com/amiayweb/Hytale-F2P",
|
"homepage": "https://github.com/amiayweb/Hytale-F2P",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user