- Section badges are now consistently 'N / 07' everywhere (was mixing 06/07)
and get a localized title tooltip explaining 'Section N of 7'.
- Language toggle now shows the CURRENT language (RU/EN) instead of the
next one, so the state is obvious before clicking.
- Carousel: manual navigation (arrows/dots) holds the slide 22s before
resuming, idle auto-advance returns to 6.5s; video slides no longer loop
and only advance when playback actually ends.
- downloadFileWithSmartProxy/getWithSmartProxy now rotate the proxy request
across api.zern.cc -> api.zernmc.ru -> api.zernmc.online -> api.pl.zern.cc
-> api.swe.zern.cc instead of retrying the same single proxy base, so a
region-specific CDN connection reset no longer burns every retry.
- DomainSelector registers every candidate/mirror domain as a fallback proxy
base at startup; mirrors list stays in sync with LAUNCHER_MIRRORS.
- Downloads write to <target>.part and are moved into place atomically on
success, so an interrupted transfer can no longer leave a corrupt partial
file that later 'file exists' checks treat as installed.
- Bump version to 1.1.0.0 (revision 1.1.0, hotfix 0).
- server status cards (online/players/version) via /api/status mcstatus ping
- highlights carousel ported from old site (/highlights/ static media)
- OBT (war in Zarya, open beta event server) + Season (Prologue, Create:
Aeronautics, year-long) sections
- nav updated, sections renumbered 01-06
- serve new launcher landing site (zern.cc root -> launcher server 1582)
- static assets mounted at /css /js /img
- port GET/HEAD /skin/{filename} from old site with identical headers
- exempt /skin/* + site assets from rate-limit and cache middleware
- Caddy: root domains -> 1582, old site preserved at legacy.zernmc.*
Hang on close (JFX freezes on exit):
- LaunchService: replace process.onExit().thenRun() — it completes on the common
ForkJoinPool whose non-daemon workers keep the JVM alive (the v1.0.14.2 regression
re-introduced in v1.0.14.3's sendBounded) — with a daemon watcher thread that blocks
on process.waitFor(). Removes ForkJoinPool pinning.
- JFXLauncher: HttpServer executor now uses daemon thread factory; installThread is daemon.
- ZHttpClient: drop the non-daemon CachedThreadPool executor and restore synchronous
client.send() with request-level timeout, undoing the v1.0.14.3 sendAsync().get() that
submitted work to a non-daemon pool.
Hang / no game launch (Forge/NeoForge):
- LaunchCommandBuilder: remove the self-invented -DlegacyClassPath injection. Modern
Forge derives the MC-BOOTSTRAP layer from the module path / the ${classpath}
substitution that AstralRinth and the 1.0.13 launcher use; a redundant -DlegacyClassPath
duplicated every library and broke the bootstrap. Now relies solely on ${classpath}
substitution from version.json (only built when referenced by the version.json).
- update LaunchCommandBuilderTest to assert the corrected contract (no -DlegacyClassPath,
${classpath} substituted into -p).
Version bump to new revision (hotfix=0): revision 1.0.14 -> 1.0.15.
Build: mvn -pl launcher package -> ZernMC-win-1.0.15.0.zip, build.version=1.0.15.0.
Signed-off-by: SashegDev <gdsasheg@gmail.com>
- ZHttpClient: single direct attempt per resource, then immediate retry via /proxy/download (getWithSmartProxy, downloadFileWithSmartProxy)
- getRetry() for server proxy endpoints incl. transient 502/5xx; isRetryableError classification
- MAX_FAILS_BEFORE_PROXY 1 -> service switches to proxy-first after first failure
- detectService: files.minecraftforge.net routed through proxy
- repairMissingLibraries/repairLibrariesFromJson: re-download missing libs (incl. maven-coordinates format with -v2 fallback)
- JFX: force Mojang service check synchronously before install if network init not finished
- Forge/NeoForge: installer + downloads via ZHttpClient (no more bare HttpClient without request timeout), NeoForge subprocess 10-min timeout
- Fabric: pre-download loader libs via proxy, repair after install
findVersionJar() falls back to versions/1.20.1/1.20.1.jar when the Forge
version jar doesnt exist. Filename 1.20.1.jar produces automatic module _1._20._1
which conflicts with module minecraft (split-package on net.minecraft.server).
Fix: ensureVersionJarForForge() copies vanilla jar to versions/<versionId>/
<versionId>.jar before findVersionJar() is called. Vanilla jar has
Automatic-Module-Name: minecraft so it becomes module minecraft, not _1._20._1.