HYTALE_PATCH_SKIP=0 - skip first occurrence only
HYTALE_PATCH_SKIP=0,2 - skip first and third
HYTALE_PATCH_SKIP=0 HYTALE_PATCH_LIMIT=1 - patch only second occurrence
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use HYTALE_PATCH_LIMIT=1 to patch only first occurrence,
HYTALE_PATCH_LIMIT=2 for first two, etc.
Helps isolate which specific occurrence causes the crash.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows hex offset, bytes before/after each patch location to help
identify if we're patching false positives.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HYTALE_PATCH_MODE=utf16le - Use pure UTF-16LE (no length prefix)
HYTALE_PATCH_MODE=length-prefixed - Use length-prefixed format (default)
This helps debug if the length-prefixed format is causing crashes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Discord URL patch was causing buffer overflow crashes and has no
practical effect on F2P functionality anyway.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Discord URL patch was writing 28 bytes (.gg/MHkEjepMQ7, 14 chars)
where only 20 bytes existed (.gg/hytale, 10 chars), corrupting 8 bytes
of adjacent data in the binary.
Changes:
- Use same-length Discord URL: .gg/santop (10 chars)
- Add length check to UTF-16LE fallback path
- Add length check and zero-fill to findAndReplaceDomainSmart
This buffer overflow explains why the crash happened on some systems
(Steam Deck, Ubuntu LTS) but not others - depending on what data
was adjacent to the patched string.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Debug env vars for clientPatcher:
- HYTALE_SKIP_SENTRY_PATCH=1 - Skip sentry URL patch (60->26 chars)
- HYTALE_SKIP_SUBDOMAIN_PATCH=1 - Skip subdomain prefix patches
Game launcher Linux options:
- HYTALE_USE_JEMALLOC=1 - Use jemalloc allocator instead of glibc
This helps isolate which patch causes "free(): invalid pointer"
on Steam Deck and Ubuntu LTS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When replacing domain strings with shorter ones, the replaceBytes function
was only copying the new bytes without clearing the leftover bytes from
the old pattern. This caused "free(): invalid pointer" crashes on Steam
Deck and Ubuntu due to corrupted string metadata in the .NET AOT binary.
Fix: Fill the entire old pattern region with 0x00 before writing the
new bytes. This ensures no leftover data remains that could corrupt
the binary structure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Introduce DualAuthPatcher with support for hybrid authentication
- Update default auth domain to `auth.sanasol.ws`
- Integrate Java detection and bundled JRE handling for patcher execution
- Add server patch flag for avoiding redundant patching
- Automate DualAuthPatcher setup: download, compile, and execute with dependencies
- Enhance patching logic for extended logging and modularity
- Add support for domains from 4 to 16 characters
- Domains <= 10 chars: direct replacement, subdomains stripped
- Domains 11-16 chars: split mode (first 6 chars -> subdomain prefix)
- Add length-prefixed byte format encoding for client binary
- Verify binary contents when checking if already patched
- Detect file updates and archive old backups with timestamps
- Fallback to legacy UTF-16LE format for older binaries
- Update patcher version to 2.0.0
Based on patching approach from Mollomm1/Hytale-EMULATOR
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>