Forge manifest -p is 8 hardcoded bootstrap JARs using ${library_directory},
not ${classpath}. Intercepting it replaced those with ALL libraries causing
duplicate module errors. Version jar stays on -cp only (not -p).
- Build two separate classpaths: modulePath (libraries only) and classpath (libraries + version jar)
- Intercept manifest -p to use modulePath (no version jar) preventing _1._20._1 vs minecraft module conflict
- Intercept manifest -cp to skip (our explicit -cp already added)
- Fix --version to use getVersionId() instead of instance.getName()
Forge version.json uses -p ${classpath} to set the module path to the same
argfile as the classpath. Previously we filtered net.minecraft:* libs from the
classpath string, which meant they were absent from the module path too, causing
ClassNotFoundException for PreparableReloadListener and other MC classes.
Now net.minecraft:* libs are included in the Forge classpath argfile so
securejarhandler can load them as modules.
- Read version from bin/.version file (reliable, no JAR locking)
- Save version to bin/.version when downloading JAR
- Use getLauncherJar() for all JAR path references
- Create binDir in main()
- Remove build.version dependency completely
- Read version from bin/.version file (reliable, no JAR locking issues)
- Save version to bin/.version when downloading JAR
- Remove complex JAR/ZIP reading code
- Use simple file-based version storage
- Read version only from JAR manifest (Implementation-Version)
- Remove all VERSION_FILE references from Bootstrap
- Remove build.version from scanLocalFiles() and update methods
- Rewrite getLauncherMeta() to properly parse server meta response
- Change downloadUpdate() fallback to JAR-only (not ZIP) to avoid JRE lock issues
- Simplify downloadUpdateLegacy() to skip ZIP (which locks JRE files)
- Add handling for AccessDeniedException when updating locked files
- Improve error logging for meta parsing failures
- Add Fabric support in LaunchCommandBuilder.findVersionJson()
- Fix Bootstrap to properly use bin/ directory for launcher JAR
- Fix server.py to accept both ZernMC-win-*.zip and ZernMCLauncher-*.zip
- Add debug output for version.json resolution
- Fix CLI arrow keys: remove 50ms timeout in escape sequence handling (ArrowMenu, LoginMenu)
- Add network logs polling to UI via /api/logs endpoint
- Display user role in launcher header (AuthManager, AuthService, JFXLauncher, UI)
- Capture and display game logs in launcher via /api/game-logs endpoint
- Fix demo mode bug in VersionManifest.ruleMatches() - was incorrectly adding --demo flag
- Fix modloader launch: pass proper auth info (accessToken, uuid) from AuthManager
- Add game log capture in MinecraftLib and LaunchService
- Scan versions/ directory and generate meta.json for each version
- Log progress: 'Scanning launcher versions...', 'Launcher meta ready: vX (Y files)'
- Meta cached in memory for faster access
- Get server version from /launcher/meta (new method)
- Scan local files and calculate SHA256 hashes
- POST to /launcher/diff to get what files need update
- Download only changed files via /launcher/file/{version}/{path}
- Delete obsolete files
- Fallback to ZIP/JAR if meta system fails
- Works with legacy method as backup
- Create versions/ folder structure for new format builds
- Generate meta.json with SHA256 hashes for each file
- Add endpoints:
- GET /launcher/meta - list all versions with meta
- GET /launcher/meta/{version} - meta for specific version
- POST /launcher/diff - get diff between local and server files
- GET /launcher/file/{version}/{path} - download individual file
- GET /launcher/download/zip/{version} - download full ZIP for new install
- Legacy builds (ZIP files) remain unchanged