v2.4.1: Replace raw wrapper script editor with structured config UI

Replace the raw textarea script editor with a structured form for Java
wrapper configuration. Users now manage two lists (JVM flags to strip,
args to inject with server/always condition) instead of editing bash/batch
scripts directly. Scripts are generated at launch time from the structured
config. Includes collapsible script preview for power users.
This commit is contained in:
sanasol
2026-02-24 16:53:19 +01:00
parent 19c8991a44
commit 0d15659dc0
10 changed files with 770 additions and 20 deletions

View File

@@ -18,7 +18,9 @@ const {
saveVersionClient,
loadUsername,
hasUsername,
checkLaunchReady
checkLaunchReady,
loadWrapperConfig,
generateWrapperScript
} = require('../core/config');
const { resolveJavaPath, getJavaExec, getBundledJavaPath, detectSystemJava, JAVA_EXECUTABLE } = require('./javaManager');
const { getLatestClientVersion } = require('../services/versionManager');
@@ -328,23 +330,13 @@ async function launchGame(playerNameOverride = null, progressCallback, javaPathO
console.log('Signed server binaries (after patching)');
}
// Create java wrapper (must be signed on macOS)
if (javaBin && fs.existsSync(javaBin)) {
const javaWrapperPath = path.join(path.dirname(javaBin), 'java-wrapper');
const wrapperScript = `#!/bin/bash
# Java wrapper for macOS - adds --disable-sentry to fix Sentry hang issue
REAL_JAVA="${javaBin}"
ARGS=("$@")
for i in "\${!ARGS[@]}"; do
if [[ "\${ARGS[$i]}" == *"HytaleServer.jar"* ]]; then
ARGS=("\${ARGS[@]:0:$((i+1))}" "--disable-sentry" "\${ARGS[@]:$((i+1))}")
break
fi
done
exec "$REAL_JAVA" "\${ARGS[@]}"
`;
const wrapperScript = generateWrapperScript(loadWrapperConfig(), 'darwin', javaBin);
fs.writeFileSync(javaWrapperPath, wrapperScript, { mode: 0o755 });
await signPath(javaWrapperPath, false);
console.log('Created java wrapper with --disable-sentry fix');
console.log('Created java wrapper from config template');
javaBin = javaWrapperPath;
}
} catch (signError) {
@@ -353,6 +345,40 @@ exec "$REAL_JAVA" "\${ARGS[@]}"
}
}
// Windows: Create java wrapper to strip/inject JVM flags per wrapper config
if (process.platform === 'win32' && javaBin && fs.existsSync(javaBin)) {
try {
const javaDir = path.dirname(javaBin);
const javaOriginal = path.join(javaDir, 'java-original.exe');
const javaWrapperPath = path.join(javaDir, 'java-wrapper.bat');
if (!fs.existsSync(javaOriginal)) {
fs.copyFileSync(javaBin, javaOriginal);
console.log('Backed up java.exe as java-original.exe');
}
const wrapperScript = generateWrapperScript(loadWrapperConfig(), 'win32', null);
fs.writeFileSync(javaWrapperPath, wrapperScript);
console.log('Created Windows java wrapper from config template');
javaBin = javaWrapperPath;
} catch (wrapperError) {
console.log('Notice: Windows java wrapper creation failed:', wrapperError.message);
}
}
// Linux: Create java wrapper to strip/inject JVM flags per wrapper config
if (process.platform === 'linux' && javaBin && fs.existsSync(javaBin)) {
try {
const javaWrapperPath = path.join(path.dirname(javaBin), 'java-wrapper');
const wrapperScript = generateWrapperScript(loadWrapperConfig(), 'linux', javaBin);
fs.writeFileSync(javaWrapperPath, wrapperScript, { mode: 0o755 });
console.log('Created Linux java wrapper from config template');
javaBin = javaWrapperPath;
} catch (wrapperError) {
console.log('Notice: Linux java wrapper creation failed:', wrapperError.message);
}
}
const args = [
'--app-dir', gameLatest,
'--java-exec', javaBin,