- Add password set/change/remove with loading states and double-click prevention
- Add protected identity deletion flow (server-side password removal first)
- Add restore flow for password-protected UUIDs (verify password before saving)
- Add UUID duplicate checks in setUuidForUser (prevent accidental overwrites)
- Add name-locked error handling in launch flow (server enforces registered name)
- Sync shield icon across all identity mutation paths
- Refresh identity dropdown after all password/identity operations
- Propagate force flag through IPC for legitimate overwrites
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Password management UI in settings (set/change/remove password)
- Shield icon on play button for protected identities
- Interactive password popup on launch with inline error display
- Fix: re-throw password errors instead of falling to local tokens
- Fix: password popup properly cleans up on success/cancel
- Fix: expose updatePasswordShieldIcon for cross-module access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Agent and -Xshare:off both ruled out as causes.
Restored normal agent injection. Updated docs with
complete findings — issue remains unsolved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Temporarily skip -javaagent injection to determine if agent's
appendToBootstrapClassLoaderSearch() causes the fastutil
ClassNotFoundException on affected Windows systems.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Disables JVM Class Data Sharing when DualAuth agent is active.
May fix singleplayer crash (NoClassDefFoundError: fastutil) on some Windows systems
where appendToBootstrapClassLoaderSearch breaks CDS classloading.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow running multiple game clients simultaneously via a new
"Allow multiple game instances" toggle in Settings. When enabled,
skips the Electron single-instance lock and the pre-launch process
kill, so existing game instances stay alive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When extracting the bundled JRE, flattenJREDir renames files from
the nested jdk subdirectory up one level. On Windows this fails with
EPERM when antivirus or file indexing holds handles open, leaving
the JRE nested and unfindable — causing "Server failed to boot".
- Fall back to copy+delete when rename gets EPERM/EACCES/EBUSY
- getBundledJavaPath checks nested JRE subdirs as last resort
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.
- Auto-kill stalled HytaleClient/java processes before launch and repair
(cross-platform: Windows taskkill+PowerShell, macOS/Linux pkill)
- Remove HytaleServer.aot before launch to prevent incompatible AOT cache
causing fastutil ClassNotFoundException on singleplayer
- safeRemoveDirectory auto-kills processes on EPERM/EBUSY before retry
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Users in Russia/Ukraine where Cloudflare IPs are blocked can now
download game files via htdwnldsan.top (direct VPS → MEGA redirect).
Both manifest fetch and archive downloads try mirrors automatically
on ETIMEDOUT/ECONNREFUSED errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Players were losing character data (inventory, armor, backpack) after
each launcher update because config.json corruption wiped the UUID
mapping. Same username, new UUID = server treats as new player.
Fix: UUIDs now stored in separate uuid-store.json that saveConfig()
can never touch. Added safety check to refuse destructive writes
when config file exists but loads empty. Includes 28 regression tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Launcher now fetches patches base URL from /api/patches-config endpoint
instead of using hardcoded domain. URL cached for 5 minutes, no fallback
to hardcoded domain - requires auth server connection or cached URL.
Enables instant CDN switching without launcher updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JAVA_TOOL_OPTIONS -javaagent path was not quoted, causing JVM to
truncate at first space. Affects all users with spaces in install
path (e.g. "Hytale F2P Launcher").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Migrate from downloading pre-patched server JARs from CDN to downloading
the DualAuth ByteBuddy Agent from GitHub releases. The server JAR stays
pristine - auth patching happens at runtime via -javaagent: flag.
clientPatcher.js:
- Replace patchServer() with ensureAgentAvailable()
- Download dualauth-agent.jar to Server/ directory
- Remove serverJarContainsDualAuth() and validateServerJarSize()
gameLauncher.js:
- Set JAVA_TOOL_OPTIONS env var with -javaagent: for runtime patching
- Update logging to show agent status instead of server patch count
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: comprehensive UUID/username persistence bug fixes
Major fixes for UUID/skin reset issues that caused players to lose cosmetics:
Core fixes:
- Username rename now preserves UUID (atomic rename, not new identity)
- Atomic config writes with backup/recovery system
- Case-insensitive UUID lookup with case-preserving storage
- Pre-launch validation blocks play if no username configured
- Removed saveUsername calls from launch/install flows
UUID Modal fixes:
- Fixed isCurrent badge showing on wrong user
- Added switch identity button to change between saved usernames
- Fixed custom UUID input using unsaved DOM username
- UUID list now refreshes when player name changes
- Enabled copy/paste in custom UUID input field
UI/UX improvements:
- Added translation keys for switch username functionality
- CSS user-select fix for UUID input fields
- Allowed Ctrl+V/C/X/A shortcuts in Electron
Files: config.js, gameLauncher.js, gameManager.js, playerManager.js,
launcher.js, settings.js, main.js, preload.js, style.css, en.json
See UUID_BUGS_FIX_PLAN.md for detailed bug list (18 bugs, 16 fixed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(i18n): add switch username translations to all locales
Added translation keys for username switching functionality:
- notifications.noUsername
- notifications.switchUsernameSuccess
- notifications.switchUsernameFailed
- notifications.playerNameTooLong
- confirm.switchUsernameTitle
- confirm.switchUsernameMessage
- confirm.switchUsernameButton
Languages updated: de-DE, es-ES, fr-FR, id-ID, pl-PL, pt-BR, ru-RU, sv-SE, tr-TR
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: move UUID_BUGS_FIX_PLAN.md to docs folder
* docs: update UUID_BUGS_FIX_PLAN with complete fix details
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Added a maxlength attribute to the player name input and enforced a 16-character limit in both install and settings scripts, providing user feedback if exceeded. Refactored modManager.js to replace symlink-based mod management with a copy-based system, copying enabled mods to HytaleSaves\Mods and removing legacy symlink logic to improve compatibility and avoid permission issues.
The bundled libzstd.so is incompatible with glibc 2.41's stricter heap
validation, causing "free(): invalid pointer" crashes.
Solution: Automatically replace bundled libzstd.so with system version
on Linux. The launcher detects and symlinks to /usr/lib/libzstd.so.1.
- Auto-detect system libzstd at common paths (Arch, Debian, Fedora)
- Backup bundled version as libzstd.so.bundled
- Create symlink to system version
- Add HYTALE_NO_LIBZSTD_FIX=1 to disable if needed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
modManager.js:
- Switch from hardcoded 'junction' to dynamic symlink type based on OS (fixing Linux EPERM).
- Add retry logic for directory removal to handle file locking race conditions.
- Improve broken symlink detection during profile sync.
gameManager.js:
- Implement retry loop (3 attempts) for game directory removal in updateGameFiles to prevent EBUSY/EPERM errors on Windows.
paths.js:
- Prevent fs.mkdirSync failure in getModsPath by pre-checking for broken symbolic links.