launcher: document build, run, and placeholder key in readme

This commit is contained in:
Jan Nedbal
2026-04-14 11:13:03 +02:00
parent 8e288fd18e
commit e1268e7cce

View File

@@ -1,3 +1,88 @@
# metin-launcher
Self-updating launcher for the Metin2 client (dev repo)
Self-updating launcher for the Metin2 client.
This is the single entry point the player runs. It fetches a signed manifest from
`updates.jakubkadlec.dev`, verifies an Ed25519 signature against a compiled-in
public key, reconciles the local client against the manifest by sha256, downloads
anything that differs from a content-addressed blob store (with HTTP Range resume),
applies updates atomically, hands launcher self-update off to Velopack, and then
starts `Metin2.exe`. If the update server is unreachable the launcher falls back
to launching whatever the player already has.
Architecture and failure modes live in the client repo under
`docs/update-manager.md` and `docs/update-manifest.md`. This project implements
those specs in C# .NET 8; it does not own the spec.
## Build
```
dotnet build Launcher.sln -c Release
dotnet test
```
Tests are xUnit and run on Linux. A local `HttpListener` stands in for the blob
server in `BlobDownloaderTests`.
## Publish (Windows single-file)
```
dotnet publish src/Metin2Launcher/Metin2Launcher.csproj \
-c Release -r win-x64 --self-contained \
-p:PublishSingleFile=true
```
The CI hasn't been wired yet; the MVP only requires the build to succeed.
## Run
Drop `Metin2Launcher.exe` next to `Metin2.exe` in the client install directory
and run it. On first launch it will:
1. fetch `https://updates.jakubkadlec.dev/manifest.json` + `.sig`
2. verify the signature against the compiled-in public key
3. hash every file listed in the manifest, download anything that doesn't match
into `.updates/staging/`, then atomically move each one into place
4. check for a Velopack launcher update against the feed at
`https://updates.jakubkadlec.dev/launcher` (skipped cleanly on non-installed
dev builds)
5. start `Metin2.exe`
A log is written to both stdout and `<client>/.updates/launcher.log`. On a plain
`dotnet run` (no client root yet), the log falls back to
`%LOCALAPPDATA%/Metin2Launcher/launcher.log` on Windows or
`$XDG_DATA_HOME/Metin2Launcher/launcher.log` on Linux.
## Project layout
```
src/Metin2Launcher/
Program.cs orchestration + Velopack bootstrap + game launch
Config/LauncherConfig.cs hardcoded URLs, timeouts, public key
Manifest/ DTOs, HTTP loader, Ed25519 verifier
Transfer/ streaming sha256, Range-resume blob downloader
Apply/ atomic staging -> final move
GameLaunch/ CreateProcess wrapper
Logging/ hand-rolled file + stdout logger
tests/Metin2Launcher.Tests/
```
## Dependencies
- **NSec.Cryptography** — libsodium-backed Ed25519 (.NET 8 BCL does not have it).
- **Velopack** — launcher self-update. Only used for the launcher binary itself;
game assets (~4 GB) are handled by our own patcher code.
- **xunit / xunit.runner.visualstudio** — tests.
## PLACEHOLDER public key
`LauncherConfig.PublicKeyHex` currently contains a **test-only** Ed25519 public
key generated locally during MVP scaffolding:
```
a8619c11348cb26cdcad9467c5dd44e3fcb40017e9fbcf225ac76ad824422c46
```
This MUST be replaced with the real production signing key before the first
public release. The private half of this placeholder was used only to prove
signature wiring works; it is not tied to any real release.