Files
ulicraft-server-v1/plan/06-launcher.md
2026-05-24 04:03:42 +02:00

4.0 KiB

Launcher — FjordLauncherUnlocked distribution

Summary

Guests use FjordLauncherUnlocked (hero-persson/FjordLauncherUnlocked) — a Prism/PolyMC fork with authlib-injector support built in. So guests add their drasl account directly in the launcher (no manual JVM -javaagent), import the modpack, and play.

We host the launcher installers for all platforms on the landing page (ulicraft.local), served by Caddy from ./mirror/launcher/. A script downloads the latest release assets ahead of time so the party is fully offline.

Release assets (latest = 11.0.2.0)

Every platform variant is published as a GitHub release asset:

  • Windows: MSVC + MinGW, each as .zip, Portable .zip, Setup .exe; x64 + arm64
  • macOS: .dmg, .zip
  • Linux: .AppImage (x86_64, aarch64) + .zsync, portable .tar.gz (Qt6)

The fetch script grabs all assets via the GitHub API (loops browser_download_url). The landing page highlights the common three: Windows Setup .exe, macOS .dmg, Linux .AppImage.

tooling/fetch-launcher.sh

#!/usr/bin/env bash
# Download all FjordLauncherUnlocked release assets for offline hosting.
# Halts on any error or ambiguity (no silent partial downloads).
set -euo pipefail

REPO="hero-persson/FjordLauncherUnlocked"
DEST_ROOT="$(dirname "$0")/../mirror/launcher"
API="https://api.github.com/repos/${REPO}/releases/latest"

command -v curl >/dev/null || { echo "curl required"; exit 1; }
command -v jq   >/dev/null || { echo "jq required";   exit 1; }

meta="$(curl -fsSL "$API")"
tag="$(jq -r '.tag_name' <<<"$meta")"
[ -n "$tag" ] && [ "$tag" != "null" ] || { echo "no tag_name resolved"; exit 1; }

dest="${DEST_ROOT}/${tag}"
mkdir -p "$dest"
echo "Fetching FjordLauncher ${tag}${dest}"

mapfile -t urls < <(jq -r '.assets[].browser_download_url' <<<"$meta")
[ "${#urls[@]}" -gt 0 ] || { echo "no assets found"; exit 1; }

for url in "${urls[@]}"; do
  fname="$(basename "$url")"
  echo "  ↓ ${fname}"
  curl -fSL --retry 3 -o "${dest}/${fname}" "$url"
done

# stable symlink for the landing page to reference
ln -sfn "$tag" "${DEST_ROOT}/latest"
echo "Done. ${#urls[@]} assets in ${dest}"

Caddy mount: ./mirror/launcher:/srv/www/launcher:ro.

The landing page (09-landing.md) links to fixed filenames, not versioned ones. After downloading, fetch-launcher.sh must create these symlinks under mirror/launcher/latest/ pointing at the real assets:

  • fjord-windows-setup.exe → Windows Setup .exe (x64)
  • fjord-macos.dmg → macOS .dmg
  • fjord-linux-x86_64.AppImage → Linux x86_64 .AppImage

Selecting the right asset from the release list needs filename matching (the upstream names carry MSVC/MinGW/arch/version). Match cautiously; halt if a category resolves to 0 or >1 candidate rather than guessing. Names must stay in sync with landing/src/data/site.ts.

Per-guest flow

  1. Open http://ulicraft.local, download launcher for their OS, install.
  2. Add account: authlib-injector type, URL http://auth.ulicraft.local/authlib-injector, drasl username/password.
  3. (Offline) Settings → APIs → Assets Server = https://assets.ulicraft.local/ so the heavy asset download comes from the LAN mirror (see 10-assets-mirror.md). Requires trusting the local CA.
  4. Import the modpack (packwiz URL http://packwiz.ulicraft.local/pack.toml, or a shared instance zip).
  5. Connect to mc.ulicraft.local:25565.

Tasks

  • Create tooling/fetch-launcher.sh (above); chmod +x
  • Extend script: create stable symlinks (win/mac/linux) in mirror/launcher/latest/
  • Run it pre-party while online; verify all assets land in ./mirror/launcher/<tag>/
  • .gitignore ./mirror/ (done)
  • Landing page DONE — landing/ Astro project, builds to www/ (see 09-landing.md)
  • Confirm Fjord authlib-injector account flow against drasl
  • Decide whether to ship a pre-built instance zip vs packwiz URL import
  • Pin a launcher version (don't silently follow latest on party day)