mirror of
https://git.sanhost.net/sanasol/hytale-f2p
synced 2026-02-26 06:51:47 -03:00
v2.3.2: fix truncated download cache, update Discord link
Fix pre-release downloads failing with "unexpected EOF" by validating cached PWR file sizes against manifest expected sizes. Previously only checked > 1MB which accepted truncated files. Also update Discord invite link to new server across all files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2
.github/CODE_OF_CONDUCT.md
vendored
2
.github/CODE_OF_CONDUCT.md
vendored
@@ -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.
|
||||
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/support_request.yml
vendored
2
.github/ISSUE_TEMPLATE/support_request.yml
vendored
@@ -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
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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`** 🛑
|
||||
|
||||
<p>
|
||||
👍 If you like the project, <b>feel free to support us via Buy Me a Coffee!</b> ☕<br>
|
||||
@@ -455,7 +455,7 @@ See [BUILD.md](docs/BUILD.md) for comprehensive build instructions.
|
||||
<div align="center">
|
||||
|
||||
**Questions? Ads? Collaboration? Endorsement? Other business-related?**
|
||||
Message the founders at https://discord.gg/hf2pdc
|
||||
Message the founders at https://discord.gg/Fhbb9Yk5WW
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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**
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -91,17 +91,47 @@ async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// 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(`[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');
|
||||
@@ -180,7 +210,7 @@ async function downloadPWR(branch = 'release', fileName = 'v8', progressCallback
|
||||
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) {
|
||||
|
||||
2
main.js
2
main.js
@@ -89,7 +89,7 @@ function setDiscordActivity() {
|
||||
},
|
||||
{
|
||||
label: 'Discord',
|
||||
url: 'https://discord.gg/hf2pdc'
|
||||
url: 'https://discord.gg/Fhbb9Yk5WW'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user