diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 5a490cf..45067b2 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -36,7 +36,7 @@ This Code of Conduct applies within all community spaces, and also applies when ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [Discord Server, message Founders/Devs](https://discord.gg/hf2pdc). All complaints will be reviewed and investigated promptly and fairly. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [Discord Server, message Founders/Devs](https://discord.gg/Fhbb9Yk5WW). All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. diff --git a/.github/ISSUE_TEMPLATE/support_request.yml b/.github/ISSUE_TEMPLATE/support_request.yml index f7198f5..2b17e95 100644 --- a/.github/ISSUE_TEMPLATE/support_request.yml +++ b/.github/ISSUE_TEMPLATE/support_request.yml @@ -22,7 +22,7 @@ body: value: | If you need help or support with using the launcher, please fill out this support request. Provide as much detail as possible so we can assist you effectively. - **Need a quick assistance?** Please Open-A-Ticket in our [Discord Server](https://discord.gg/gME8rUy3MB)! + **Need a quick assistance?** Please Open-A-Ticket in our [Discord Server](https://discord.gg/Fhbb9Yk5WW)! - type: textarea id: question diff --git a/GUI/js/script.js b/GUI/js/script.js index cd4f8f8..a6bd492 100644 --- a/GUI/js/script.js +++ b/GUI/js/script.js @@ -53,7 +53,7 @@ window.closeDiscordPopup = function() { }; window.joinDiscord = async function() { - await window.electronAPI?.openExternal('https://discord.gg/hf2pdc'); + await window.electronAPI?.openExternal('https://discord.gg/Fhbb9Yk5WW'); try { await window.electronAPI?.saveConfig({ discordPopup: true }); diff --git a/GUI/js/ui.js b/GUI/js/ui.js index 41fa239..f823b2f 100644 --- a/GUI/js/ui.js +++ b/GUI/js/ui.js @@ -1103,7 +1103,7 @@ function getRetryContextMessage() { } window.openDiscordExternal = function() { - window.electronAPI?.openExternal('https://discord.gg/hf2pdc'); + window.electronAPI?.openExternal('https://discord.gg/Fhbb9Yk5WW'); }; window.toggleMaximize = toggleMaximize; diff --git a/README.md b/README.md index bd538fd..79b4062 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ ### ⚠️ **WARNING: READ [QUICK START](#-quick-start) before Downloading & Installing the Launcher!** ⚠️ -#### 🛑 **Found a problem? [Join the HF2P Discord](https://discord.gg/hf2pdc) and head to `#-⚠️-community-help`** 🛑 +#### 🛑 **Found a problem? [Join the HF2P Discord](https://discord.gg/Fhbb9Yk5WW) and head to `#-⚠️-community-help`** 🛑

👍 If you like the project, feel free to support us via Buy Me a Coffee!
@@ -455,7 +455,7 @@ See [BUILD.md](docs/BUILD.md) for comprehensive build instructions.

**Questions? Ads? Collaboration? Endorsement? Other business-related?** -Message the founders at https://discord.gg/hf2pdc +Message the founders at https://discord.gg/Fhbb9Yk5WW
diff --git a/SERVER.md b/SERVER.md index cbef39a..d8bf851 100644 --- a/SERVER.md +++ b/SERVER.md @@ -2,7 +2,7 @@ Play with friends online! This guide covers both easy in-game hosting and advanced dedicated server setup. -### **DOWNLOAD SERVER FILES (JAR/RAR/SCRIPTS) HERE: https://discord.gg/hf2pdc** +### **DOWNLOAD SERVER FILES (JAR/RAR/SCRIPTS) HERE: https://discord.gg/Fhbb9Yk5WW** **Table of Contents** diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index 345ee3e..0a3b5fc 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -1,6 +1,6 @@ # Hytale F2P Launcher - Troubleshooting Guide -This guide covers common issues and their solutions. If your issue isn't listed here, please check [existing issues](https://github.com/amiayweb/Hytale-F2P/issues) or join our [Discord](https://discord.gg/gME8rUy3MB). +This guide covers common issues and their solutions. If your issue isn't listed here, please check [existing issues](https://github.com/amiayweb/Hytale-F2P/issues) or join our [Discord](https://discord.gg/Fhbb9Yk5WW). --- @@ -437,7 +437,7 @@ Game sessions have a 10-hour TTL. This is by design for security. If your issue isn't resolved by this guide: 1. **Check existing issues:** [GitHub Issues](https://github.com/amiayweb/Hytale-F2P/issues) -2. **Join Discord:** [discord.gg/gME8rUy3MB](https://discord.gg/gME8rUy3MB) +2. **Join Discord:** [discord.gg/Fhbb9Yk5WW](https://discord.gg/Fhbb9Yk5WW) 3. **Open a new issue** with: - Your operating system and version - Launcher version diff --git a/backend/managers/gameManager.js b/backend/managers/gameManager.js index 873a1ca..1790353 100644 --- a/backend/managers/gameManager.js +++ b/backend/managers/gameManager.js @@ -64,7 +64,7 @@ async function safeRemoveDirectory(dirPath, maxRetries = 3) { } } -async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback, cacheDir = CACHE_DIR, manualRetry = false, directUrl = null) { +async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback, cacheDir = CACHE_DIR, manualRetry = false, directUrl = null, expectedSize = null) { const osName = getOS(); const arch = getArch(); @@ -90,17 +90,47 @@ async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback console.log(`[DownloadPWR] Fallback URL: ${url}`); } } - + + // Look up expected file size from manifest if not provided + if (!expectedSize) { + try { + const { fetchMirrorManifest } = require('../services/versionManager'); + const manifest = await fetchMirrorManifest(); + // Try to match: "0_to_11" format or "v11" format + const versionMatch = fileName.match(/^(\d+)_to_(\d+)$/); + let manifestKey; + if (versionMatch) { + manifestKey = `${osName}/${arch}/${branch}/${fileName}.pwr`; + } else { + const buildNum = extractVersionNumber(fileName); + manifestKey = `${osName}/${arch}/${branch}/0_to_${buildNum}.pwr`; + } + if (manifest.files[manifestKey]) { + expectedSize = manifest.files[manifestKey].size; + console.log(`[PWR] Expected size from manifest: ${(expectedSize / 1024 / 1024).toFixed(2)} MB`); + } + } catch (e) { + console.log(`[PWR] Could not fetch expected size from manifest: ${e.message}`); + } + } + const dest = path.join(cacheDir, `${branch}_${fileName}.pwr`); // Check if file exists and validate it if (fs.existsSync(dest) && !manualRetry) { const stats = fs.statSync(dest); if (stats.size > 1024 * 1024) { - console.log(`[PWR] Using cached file: ${dest} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`); - return dest; + // Validate against expected size - reject if file is truncated (< 99% of expected) + if (expectedSize && stats.size < expectedSize * 0.99) { + console.log(`[PWR] Cached file truncated: ${(stats.size / 1024 / 1024).toFixed(2)} MB, expected ${(expectedSize / 1024 / 1024).toFixed(2)} MB. Deleting and re-downloading.`); + fs.unlinkSync(dest); + } else { + console.log(`[PWR] Using cached file: ${dest} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`); + return dest; + } + } else { + console.log(`[PWR] Cached file too small (${stats.size} bytes), re-downloading`); } - console.log(`[PWR] Cached file too small (${stats.size} bytes), re-downloading`); } console.log(`[DownloadPWR] Downloading from: ${url}`); @@ -129,7 +159,7 @@ async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback const retryStats = fs.statSync(dest); console.log(`PWR file downloaded (auto-retry), size: ${(retryStats.size / 1024 / 1024).toFixed(2)} MB`); - if (!validatePWRFile(dest)) { + if (!validatePWRFile(dest, expectedSize)) { console.log(`[PWR Validation] PWR file validation failed after auto-retry, deleting corrupted file: ${dest}`); fs.unlinkSync(dest); throw new Error('Downloaded PWR file is corrupted or invalid after automatic retry. Please retry manually'); @@ -179,8 +209,8 @@ async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback // Enhanced PWR file validation const stats = fs.statSync(dest); console.log(`PWR file downloaded, size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`); - - if (!validatePWRFile(dest)) { + + if (!validatePWRFile(dest, expectedSize)) { console.log(`[PWR Validation] PWR file validation failed, deleting corrupted file: ${dest}`); fs.unlinkSync(dest); throw new Error('Downloaded PWR file is corrupted or invalid. Please retry'); @@ -440,7 +470,7 @@ async function updateGameFiles(newVersion, progressCallback, gameDir = GAME_DIR, progressCallback(`Downloading patch ${i + 1}/${updatePlan.steps.length} (${stepName})...`, progress, null, null, null); } - const pwrFile = await downloadPWR(branch, stepName, progressCallback, cacheDir, false, step.url); + const pwrFile = await downloadPWR(branch, stepName, progressCallback, cacheDir, false, step.url, step.size); if (!pwrFile) { throw new Error(`Failed to download patch ${stepName}`); @@ -891,7 +921,7 @@ function validateGameDirectory(gameDir, stagingDir) { // Enhanced PWR file validation // Accepts intermediate patches (50+ MB) and full installs (1.5+ GB) -function validatePWRFile(filePath) { +function validatePWRFile(filePath, expectedSize = null) { try { if (!fs.existsSync(filePath)) { return false; @@ -906,6 +936,13 @@ function validatePWRFile(filePath) { return false; } + // Validate against expected size if known (reject if < 99% of expected) + if (expectedSize && stats.size < expectedSize * 0.99) { + const expectedMB = expectedSize / 1024 / 1024; + console.log(`[PWR Validation] File truncated: ${sizeInMB.toFixed(2)} MB, expected ${expectedMB.toFixed(2)} MB`); + return false; + } + console.log(`[PWR Validation] File size: ${sizeInMB.toFixed(2)} MB - OK`); return true; } catch (error) { diff --git a/main.js b/main.js index 265052f..e15bdc7 100644 --- a/main.js +++ b/main.js @@ -89,7 +89,7 @@ function setDiscordActivity() { }, { label: 'Discord', - url: 'https://discord.gg/hf2pdc' + url: 'https://discord.gg/Fhbb9Yk5WW' } ] }); diff --git a/package.json b/package.json index 7da50bd..526c83f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hytale-f2p-launcher", - "version": "2.3.1", + "version": "2.3.2", "description": "A modern, cross-platform launcher for Hytale with automatic updates and multi-client support", "homepage": "https://github.com/amiayweb/Hytale-F2P", "main": "main.js",