Add Minigames profile and Fabric admission in launcher 0.1.6

This commit is contained in:
Emil
2026-09-13 22:36:20 +03:00
parent 69946e62f1
commit 799fa692ef
41 changed files with 1252 additions and 87 deletions
+18
View File
@@ -90,3 +90,21 @@ URL — cannot redirect a download to an attacker-controlled host in any of
these domains. When adding a new game-related download, verify its host is
one of the ones above (or add a new hardcoded constant following the same
pattern) rather than accepting a URL from anywhere else.
## 5. Fabric (`fabric.rs`, Minigames)
Metadata comes only from `https://meta.fabricmc.net/v2/versions/loader/` for
manifest-selected, validated version identifiers. Profile ID, parent and
KnotClient main class must match. At most 512 KiB metadata and 32 libraries
are accepted. Library URLs are constructed only below
`https://maven.fabricmc.net/` from portable three-part Maven coordinates;
other metadata origins are rejected. Libraries require a 40-hex SHA-1 and a
positive size up to 64 MiB. When Fabric metadata omits either for its loader
jar, the fixed Maven's `.sha1` sidecar and HEAD provide them. Existing verified
downloads perform the hash/size check and atomic rename. The ShaCraft signed
manifest cannot select Fabric metadata URLs, repositories or launch targets.
Minecraft 26.2's official version metadata requires Java 25. `runtime.rs`
already provisions a separate Adoptium Java 25 runtime without changing the
Aeronautics Java 21 runtime. Client companion mods and Fabric API are separately
approved ShaCraft managed files in the signed Minigames profile.
+40 -1
View File
@@ -2,7 +2,7 @@
## Current capability
The launcher persists local settings, synchronises Aeronautics mod/config
The launcher persists local settings, synchronises profile mod/config
files from the signed ShaCraft v2 manifest, installs the exact Minecraft +
NeoForge version the manifest specifies, and launches the game. A player
signs in with the same local ShaCraft account used on the website. The current
@@ -320,3 +320,42 @@ Linux Java 21 build and 8 mod tests pass. An opt-in native live test verifies
signed-manifest retrieval and download/repair/restoration of the admission jar
only in a temporary directory. Mac 0.1.5 connection failure remains unclassified
pending exact error/log; this is not a verified macOS fix or desktop UI test.
## Minigames alongside Aeronautics (2026-09-13)
The new native allowlist adds profile `minigames` at
`https://shacraft.ru/api/launcher/v2/profiles/minigames/signed-manifest` and
its display-only count at `https://shacraft.ru/api/online/minigames`.
Aeronautics remains a separate profile and keeps its previous managed files.
Minigames uses Minecraft 26.2, Fabric Loader 0.19.5, Java 25 and its own
`profiles/minigames` game directory. The signed payload supplies Fabric API
0.160.0+26.2 and `mods/shacraft-admission-client-0.1.0.jar`; it never supplies
Paper, the server plugins, maps, credentials or game-download URLs.
`fabric.rs` obtains an exact parent/loader profile from fixed Fabric metadata,
checks its identity and KnotClient entry point, and converts bounded Maven
library entries into the existing verified library contract. Each artifact
URL is constructed from a validated coordinate below fixed Fabric Maven;
metadata-supplied alternative origins are rejected. SHA-1 and size come from
Fabric metadata, or the same Maven's hash sidecar and HEAD for the loader jar.
Java provisioning already accepts exactly Java 25. Automatic installation on
a platform still requires a real cold-install check on that platform.
Both profiles claim/display the canonical `aoc` nickname. Only the native
profile mapping determines ticket `server_id` (`aoc` or `minigames`), and the
response must match that exact server. The backend is responsible for shared
access checks at both issuance and redemption. Existing account sessions and
settings need no migration. No copied subscription/whitelist grant is trusted.
Minigames adds native `--quickPlayMultiplayer 135.106.154.86:25568` at launch.
The client-only Fabric companion validates the actual socket target and signs
the existing configuration challenge with `minigames` in the transcript.
Paper performs verification before entry; its early duplicate UUID gate must
run before vanilla would evict the existing player. There is no proxy and no
client-side shared secret. One ticket is used for one game connection; a fresh
launcher start is required after expiry, consumption or a failed proof attempt.
The integration is staged until server authentication, signed profile payload,
and a newer signed launcher release are deployed and checked together. The
existing public 0.1.5 binary cannot select the new profile by a website-only
catalog change. Preserve both catalog entries when publishing either profile.
+105
View File
@@ -0,0 +1,105 @@
# Launcher 0.1.6 candidate
Adds a separate Minigames profile (Minecraft 26.2 / Fabric 0.19.5 / Java 25)
while keeping Aeronautics and its installed profile intact. Both use the
existing canonical aoc nickname and shared access. Tickets remain bound to
the selected server. Minigames connects to 135.106.154.86:25568 and proves
account admission during configuration before world entry.
Local checks: 87 native tests, 33 UI tests, TypeScript/Vite, three Java client
proof tests, an official Fabric metadata resolution check and the Linux native
release build. The [real Fabric/Paper smoke](verification/minigames-fabric-2026-09-13.json)
passed with a synthetic account: the unchanged production companion entered
the lobby and the backend consumed its Minigames ticket. Cross-platform CI
and production rollout results must be recorded before calling this published. No updater feed has
been changed by preparing this candidate.
## Build contract
Git remote: `git@github.com:emil28092005/shacraft-launcher.git`.
The production admission line is branch `codex/launcher-updater`; `main` is a
divergent unreleased prototype and must remain unchanged for this release.
Push the reviewed commit to the production branch, then dispatch
`gh workflow run build.yml --ref codex/launcher-updater --repo emil28092005/shacraft-launcher`.
The check workflow runs on branch pushes. Verify each run's head SHA equals the
reviewed commit before downloading artifacts. A main push also triggers the
build matrix, but is not the publication path for this candidate.
CI publishes unsigned artifacts named:
- `shacraft-launcher-linux-x64`: AppImage and deb.
- `shacraft-launcher-windows-x64`: NSIS exe and MSI.
- `shacraft-launcher-macos-arm64`: aarch64 app.tar.gz and DMG.
- `shacraft-launcher-macos-x64`: x86_64 app.tar.gz and DMG.
`.github/workflows/check.yml` additionally tests the Java 25 admission client
and uploads `shacraft-admission-client`. It has no production credentials.
Download the artifacts from the checked run at the exact reviewed commit with
`gh run download RUN_ID --repo emil28092005/shacraft-launcher --dir STAGING`.
## Signing and publication
Stage renamed ASCII filenames below a local downloads root, for example
`/tmp/shacraft-release-0.1.6/downloads/0.1.6/`. Preserve already published
0.1.5 bytes. Expected updater filenames:
- `ShaCraft.Launcher_0.1.6_amd64.AppImage`
- `ShaCraft.Launcher_0.1.6_amd64.deb`
- `ShaCraft.Launcher_0.1.6_x64-setup.exe`
- `ShaCraft.Launcher_0.1.6_aarch64.app.tar.gz`
- `ShaCraft.Launcher_0.1.6_x86_64.app.tar.gz`
MSI and DMG are additional manual downloads; the updater uses EXE and app.tar.gz.
Inspect package versions, architecture and contents before signing. Sign each
chosen file with the existing local operator key:
```bash
npm run tauri -- signer sign --private-key-path /home/emil/.local/share/shacraft-updater/production.key ARTIFACT
```
The key file is mode 0600 and remains local. Never read its contents into logs,
copy it to CI/server or substitute a different signing identity. Existing
`production.key.pub` is sufficient for every later verification/publication.
After creating a UTF-8 release notes file, prepare the payload:
```bash
python3 scripts/publish_launcher_update.py prepare \
--version 0.1.6 \
--downloads-root /tmp/shacraft-release-0.1.6/downloads \
--artifact linux-x86_64=ShaCraft.Launcher_0.1.6_amd64.AppImage \
--artifact linux-x86_64-appimage=ShaCraft.Launcher_0.1.6_amd64.AppImage \
--artifact linux-x86_64-deb=ShaCraft.Launcher_0.1.6_amd64.deb \
--artifact windows-x86_64=ShaCraft.Launcher_0.1.6_x64-setup.exe \
--artifact darwin-aarch64=ShaCraft.Launcher_0.1.6_aarch64.app.tar.gz \
--artifact darwin-x86_64=ShaCraft.Launcher_0.1.6_x86_64.app.tar.gz \
--notes-file /tmp/shacraft-release-0.1.6/notes.txt \
--public-key /home/emil/.local/share/shacraft-updater/production.key.pub \
--payload /tmp/shacraft-release-0.1.6/release.payload.json
npm run tauri -- signer sign \
--private-key-path /home/emil/.local/share/shacraft-updater/production.key \
/tmp/shacraft-release-0.1.6/release.payload.json
```
Upload only public packages, signatures, payload, public key and publisher.
Server downloads root is `/root/shacraft/caddy/www/downloads/shacraft-launcher`;
public artifact URLs are `https://shacraft.ru/downloads/shacraft-launcher/0.1.6/`
followed by the checked filename. Preserve the old feed before publication.
With the exact staged server paths, run the existing publisher first with
`--dry-run`, then without it:
```bash
python3 publish_launcher_update.py publish \
--downloads-root /root/shacraft/caddy/www/downloads/shacraft-launcher \
--public-key PUBLIC_KEY_FILE \
--payload SIGNED_PAYLOAD_FILE \
--signature PAYLOAD_SIGNATURE_FILE \
--output /root/shacraft/data/launcher/updates/stable.json \
--dry-run
```
Publication depends on the signed Minigames profile containing the final client
and Fabric API jars, the healthy Paper admission gate, and the shared-access
backend endpoints being available. Verify public HTTPS package hashes, feed
signatures and an actual client admission before updating the website buttons.
OS Authenticode/Apple notarization and cold installations on other platforms
remain distinct from successful native CI/builds.
@@ -0,0 +1,33 @@
{
"recorded_at": "2026-09-13T19:32:59.436884+00:00",
"result": "joined_world",
"client": "Minecraft 26.2 / Fabric Loader 0.19.5 / Fabric API 0.160.0+26.2",
"java": "25.0.2",
"client_jar_sha256": "3335626b7c8fdd233e8531ad382594398c7df48842b1b919934d1154dd4ba8f1",
"client_jar_size": 10667,
"profile": "minigames",
"synthetic_player": "AdmissionPilot",
"endpoint": "127.0.0.1:25608",
"environment": "isolated Xvfb :95; separate temporary game directory; synthetic account/ticket; explicit local socket test flag",
"server_evidence": [
"[22:32:02 INFO]: AdmissionPilot joined the game",
"[22:32:02 INFO]: AdmissionPilot[/127.0.0.1:54602] logged in with entity id 77 at ([minecraft:shacraft_lobby_v2]0.5, 96.0, 43.5)"
],
"verified": [
"production companion jar bytes unchanged",
"queued minecraft:register during configuration",
"server-bound Ed25519 response accepted",
"actual vanilla client entered lobby world"
],
"not_tested": [
"production public endpoint login",
"Windows/macOS cold installation",
"full GUI launcher install/account flow"
],
"notes": "Offline client emits Microsoft profile-certificate HTTP401; admission and world entry succeeded. Real account/session/password not used.",
"backend_evidence": {
"source": "backend agent read-only synthetic SQLite query",
"issued_minigames_tickets_for_player": 1,
"consumed_minigames_tickets_for_player": 1
}
}