Aligns the executable name with the repo / product naming. Backward-
compatible: existing installs that have PSLauncher.exe on disk continue
to work — the self-updater overwrites the file at the running .exe path
without renaming, so the historical filename persists on those machines.
Changes
- AssemblyName : PSLauncher → PS_Launcher (both App and Updater csproj)
- Inno Setup : MyAppExeName, MyUpdaterExeName, OutputBaseFilename all
now use PS_Launcher prefix
- LauncherSelfUpdater : looks for PS_Launcher.Updater.exe first, falls
back to legacy PSLauncher.Updater.exe so old installs keep updating
- Build scripts (build-launcher / build-updater / build-installer /
build-all) : taskkill both legacy AND new names; output paths printed
with new names
- .gitignore : added PS_Launcher.exe / PS_Launcher.Updater.exe /
PS_Launcher-*.exe patterns alongside the legacy ones; also ignored
the WebView2 user-data folder and Office ~$ lock files
- Server admin/launcher.php : URL pattern now generates
PS_Launcher-{ver}.exe ; SignManifest's existing tolerant glob
*{ver}*.exe still matches both names
- Versions bumped to 0.14.0 (App + Updater + installer .iss)
Migration story for clients
- Brand-new install via PS_Launcher-Setup-0.14.0.exe → PS_Launcher.exe
on disk
- Existing install (PSLauncher.exe) auto-updates to v0.14 → file stays
named PSLauncher.exe but contains v0.14 code; self-updater fallback
ensures future updates keep working
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- gate.php : ETag now derived from size+mtime instead of md5_file($zip).
Previously the gate hashed the entire 14 GB ZIP on every HEAD/GET call
(including each of 8 parallel segments) → 30s-5min preparation lag for
clients before the first byte. Now <1ms per request.
- SignManifest : disk-backed cache for SHA-256 keyed by (path,size,mtime).
Re-signing 5×14 GB versions used to take ~25 min, now ~1s when nothing
changed. New "Force re-hash" toggle in admin to ignore the cache.
- versions.php : per-row "🔁 Hash" button to sign a single version, plus
a "⚙ Hash" dropdown to toggle hashAlgorithm:none for builds where the
user accepts skipping client-side verification (manifest stays signed
Ed25519, only the per-ZIP SHA-256 verification is bypassed).
- DownloadUrl.php : signed-URL TTL bumped 1h → 6h to cover slow ADSL users
who need >1h to finish a 14 GB download.
- .gitignore : track server/builds/.htaccess + gate.php (still ignore the
actual ZIP/exe binaries).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`usort($manifest['versions'] ?? [], ...)` worked in PHP 7 but is a
fatal error in PHP 8 — usort requires its first arg by reference and
the null-coalesce operator produces an rvalue, not a variable. The
existing versions.php didn't trigger it because it sorts
$manifest['versions'] directly. Fixed launcher.php to guard with an
isset/is_array check and only sort when there's actually a versions
array.
Triggered by clicking "Définir" in the new Launcher page → 500 page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The launcher and the game versions are different release cadences
managed by the same operator. Mixing them on one page muddied the
workflow. Split them into two top-level nav entries.
SignManifest::run(string $scope)
--------------------------------
- 'all' (default, used by CLI tools/sign-manifest.php) — unchanged.
- 'versions' — only re-hashes the Proserve ZIPs and bumps `latest`.
- 'launcher' — only re-hashes the launcher EXE.
The Ed25519 sign step always runs at the end so the manifest stays
verifiable. Selectively hashing avoids unrelated noise (e.g. mass-hash
14 GB ZIPs when all you wanted was to update the launcher exe).
admin/launcher.php (new page)
-----------------------------
Self-contained page with the launcher state, Set/Remove forms, the
blue "🔁 Hasher le launcher + signer" button, and a list of the .exe
files present in builds/launcher/. Workflow doc inline.
admin/versions.php
------------------
Cleaned up: launcher card and its set_launcher / remove_launcher /
sync_launcher actions removed. The remaining global Sync button is
relabeled and now triggers scope='versions' (only Proserve ZIPs).
Layout::navHtml gains a "Launcher" item between Versions and Audit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>