- Load known bad IPs from FireHOL blocklists on startup
- ~4400 IPs blocked by default
- Set PUBLIC_BLOCKLIST=false to disable
- Combined with manual BLOCKED_IPS env var
- Global rate limiting (60 requests/minute per IP)
- IP whitelist/blacklist via ALLOWED_IPS and BLOCKED_IPS env vars
- Bot detection - silent 404 for suspicious paths (.env, phpinfo, etc.)
- Path traversal detection
- Reduced noise in logs from bot scanners
- Add version parsing to distinguish new vs legacy format builds
- New format: ZernMC-win-*.zip (1.0.8+ with bundled JRE21/JavaFX)
- Legacy: ZernMCLauncher-*.zip (< 1.0.8 or with suffix)
- /launcher/download/latest now returns new format by default
- Add /launcher/download/legacy endpoint for old builds
- Add legacy info to /launcher/info and /launcher/version responses
- Update download_zip to accept both ZernMCLauncher- and ZernMC-win- patterns
- Restructured to multi-module Maven project (bootstrap + launcher)
- Removed duplicate code (launcher/launcher/ with JCEF)
- Added JavaFX modules to lib/javafx in ZIP
- Added JRE 21 to lib/jre21 in ZIP
- Fixed Bootstrap with UTF-8 encoding and JavaFX module-path
- Fixed JAR naming (zernmclauncher.jar)
- Added Windows build configuration (ZernMC-win-*.zip)
- Fixed version parsing for -any, -alpha, -beta suffixes
- Create api package with AuthService, InstanceService, LaunchService
- Add ApiResponse<T> model for consistent responses
- Create LauncherAPI central facade for all services
- Update Main.java to use new API for session checking
- All services compile successfully
- Replace hardcoded Forge/NeoForge args with version.json parsing
- Add VersionManifest.java — parses mainClass, arguments, libraries from JSON
- Implement rule matching for OS-specific library/argument filtering
- Build classpath dynamically from manifest libraries with fallback resolution
- Resolve game args with variable substitution (${version_name}, ${game_directory}, etc.)
- Auto-discover version.json path with multiple candidate formats
- Support all Forge versions (1.12.2 through 1.21+) and NeoForge out of the box
- Fix MinecraftLib.installPack() returning false for Forge (was dead code)
- Add NeoForgeInstaller.java with installer download and execution
- Update LaunchCommandBuilder with NeoForge JVM args, classpath, launch args
- Update LaunchMenu with NeoForge option, version selector, support check
- Update Instance.java loader type comment (vanilla, fabric, forge, neoforge)
- Update PackDownloader to handle neoforge loader type
- Update ZHttpClient with NEOFORGE_MAVEN service type and detection
- Add NeoForge proxy endpoints (/proxy/neoforge/versions, /proxy/neoforge/maven)
- Add maven.neoforged.net to proxy allowed_domains
- Add asset_index to PackMeta model and pack_manager scanning
- Include asset_index in /packs list endpoint response