#!/usr/bin/env bash # LAN party bootstrap: installs Fjord Launcher Unlocked (DRM-free Prism fork), # seeds a persistent offline account, drops in the pre-built modpack instance, # and launches straight into it on the LAN server. # # Host this file via: python3 -m http.server 8000 # Participants run: curl -fsSL http://:8000/install.sh | bash set -euo pipefail # ---- EDIT ME before hosting ---- HOST_URL="http://192.168.1.50:8000" # where THIS script + modpack.zip are served from MODPACK_URL="$HOST_URL/modpack.zip" # exported Prism instance folder, zipped (see HOSTING.md) INSTANCE_NAME="LANParty" # must match the top-level folder name inside modpack.zip SERVER_ADDR="192.168.1.50:25565" # your Minecraft server IP:port GH_REPO="unmojang/FjordLauncherUnlocked" # fallback if hero-persson's fork disappears; see note below # --------------------------------- INSTALL_DIR="$HOME/mc-lan-party" mkdir -p "$INSTALL_DIR" cd "$INSTALL_DIR" echo "==> Setting up in $INSTALL_DIR" os="$(uname -s)" arch="$(uname -m)" api_url="https://api.github.com/repos/hero-persson/FjordLauncherUnlocked/releases/latest" release_json="$(curl -fsSL "$api_url")" pick_asset() { # $1 = grep pattern for the asset name echo "$release_json" | grep -oE '"browser_download_url": *"[^"]+"' \ | cut -d'"' -f4 | grep -E "$1" | head -n1 } LAUNCHER_BIN="" if [[ "$os" == "Linux" ]]; then if [[ "$arch" == "aarch64" ]]; then url="$(pick_asset 'Linux-aarch64\.AppImage$')" else url="$(pick_asset 'Linux-x86_64\.AppImage$')" fi [[ -n "$url" ]] || { echo "Could not find a Linux AppImage in the latest release." >&2; exit 1; } echo "==> Downloading $url" curl -fsSL -o FjordLauncher.AppImage "$url" chmod +x FjordLauncher.AppImage LAUNCHER_BIN="$INSTALL_DIR/FjordLauncher.AppImage" elif [[ "$os" == "Darwin" ]]; then url="$(pick_asset 'macOS-.*\.zip$')" [[ -n "$url" ]] || { echo "Could not find a macOS build in the latest release." >&2; exit 1; } echo "==> Downloading $url" curl -fsSL -o FjordLauncher.zip "$url" unzip -oq FjordLauncher.zip -d app app_path="$(find app -maxdepth 2 -name '*.app' | head -n1)" LAUNCHER_BIN="$app_path/Contents/MacOS/$(ls "$app_path/Contents/MacOS" | head -n1)" else echo "Unsupported OS for install.sh: $os. Use install.ps1 on Windows." >&2 exit 1 fi # ---- offline account: compute Mojang-style offline UUID so playerdata persists across launches ---- read -rp "Minecraft nickname [${USER:-Player}]: " NICK NICK="${NICK:-${USER:-Player}}" md5hex="$(printf '%s' "OfflinePlayer:$NICK" | md5sum | cut -d' ' -f1)" variant_nibble=$(( (16#${md5hex:16:1} & 3) | 8 )) variant_hex="$(printf '%x' "$variant_nibble")" patched="${md5hex:0:12}3${md5hex:13:3}${variant_hex}${md5hex:17:15}" UUID="${patched:0:8}-${patched:8:4}-${patched:12:4}-${patched:16:4}-${patched:20:12}" CLIENT_TOKEN="$(printf '%s' "ClientToken:$NICK" | md5sum | cut -d' ' -f1)" cat > accounts.json < Offline account '$NICK' ready (UUID $UUID)" # ---- modpack instance ---- mkdir -p instances if [[ ! -d "instances/$INSTANCE_NAME" ]]; then echo "==> Downloading modpack from $MODPACK_URL" curl -fsSL -o modpack.zip "$MODPACK_URL" unzip -oq modpack.zip -d instances echo "==> Modpack installed to instances/$INSTANCE_NAME" else echo "==> Instance already present, skipping download" fi echo "==> Launching into $INSTANCE_NAME as $NICK, joining $SERVER_ADDR" "$LAUNCHER_BIN" --dir "$INSTALL_DIR" --launch "$INSTANCE_NAME" --profile "$NICK" --server "$SERVER_ADDR"