diff --git a/README.md b/README.md index e2a3783..43fc8a2 100644 --- a/README.md +++ b/README.md @@ -166,12 +166,15 @@ The script downloads the latest AppImage, installs a desktop entry, and creates a `kyber` command in `~/.local/bin`. **Every time you want to play:** -1. **Launch SWBF2 from Steam first** — let it fully load to the main menu -2. Launch Kyber (`kyber` or from the app menu) +1. Open **Steam** (must be running for library validation) — do NOT click Play on SWBF2 +2. Launch **Kyber** (`kyber` or from the app menu) 3. In Kyber: join a server (HOME) or create one (HOST) -4. Kyber connects to the already-running game instance +4. Kyber/Maxima launches SWBF2 via its own bundled GE-Proton — wait 1-3 minutes +5. If the SWBF2 window appears but won't focus: press **Alt+Tab** or click its + taskbar entry — this is normal when the game is launched by a wrapper process -Kyber does not launch the game itself — Steam must start it first. +Do NOT launch SWBF2 from Steam directly. If Steam's SWBF2 is already running +when Kyber starts, kill it first — Kyber cannot inject into a Steam-launched instance. **If Kyber says "Game Not Found":** Click **SET GAME FOLDER** and point it to the SWBF2 install directory. @@ -189,13 +192,24 @@ Paste that path into the SET GAME FOLDER dialog. **Hosting a private server with bots:** - HOST → pick maps/modes → set a **name** and **PASSWORD** → Start Server - Share the server name + password with friends; they search by name in HOME -- SWBF2 fills empty slots with AI automatically — no separate bot setting needed +- Bot count: in the HOST panel right side → **AUTOPLAYERS** section → + set **BOTS TEAM 1** and **BOTS TEAM 2** (e.g. 4 each) → click **UPDATE SERVER** +- Bot difficulty: the **BOT DIFFICULTY** slider (RECRUIT → OFFICER → KNIGHT → MASTER) +- After the game loads you can also update settings live and hit UPDATE SERVER again **Requirements:** -- SWBF2 (Steam AppID 1237950) installed with GE-Proton (recommended over - Proton Experimental for game stability) +- SWBF2 (Steam AppID 1237950) installed via Steam + (Kyber manages its own GE-Proton for launching the game) - glibc 2.38+ — Ubuntu 24.04+, Fedora 38+, SteamOS 3.7+ - EA account (free) at ea.com +- Unprivileged user namespaces enabled (Ubuntu 24.04 restricts these by default): + ```bash + sudo sysctl -w kernel.unprivileged_userns_clone=1 + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + ``` + The setup script applies this automatically when run with sudo and saves it + to `/etc/sysctl.d/99-userns.conf` to persist across reboots. + Without this fix Kyber fails with: `bwrap: setting up uid map: Permission denied` **What does NOT work:** - Running the Windows `kyber_launcher.exe` under Wine/Proton: EA's auth diff --git a/scripts/setup-kyber-linux.sh b/scripts/setup-kyber-linux.sh index 714a611..7759b47 100755 --- a/scripts/setup-kyber-linux.sh +++ b/scripts/setup-kyber-linux.sh @@ -18,6 +18,7 @@ # # Tested on: Ubuntu 24.04+, Fedora, SteamOS 3.7+ (requires glibc 2.38+) # Recommended Proton for SWBF2 itself: GE-Proton 10.x or proton-cachyos 11.x +# (Kyber/Maxima downloads and manages its own GE-Proton automatically) # # ── Login flow ───────────────────────────────────────────────────────────── # @@ -27,6 +28,20 @@ # 4. Kyber completes authentication via Maxima (no redirect hacks needed). # 5. Click "Skip" on Nexus Mods if you don't use mods. # +# ── How to play ──────────────────────────────────────────────────────────── +# +# Kyber launches SWBF2 itself — do NOT launch SWBF2 from Steam first. +# If Steam's SWBF2 is running when Kyber starts, kill it. +# +# 1. Open Steam (must be running for library access, but do NOT click Play). +# 2. Launch Kyber (AppImage or 'kyber' command). +# 3. In Kyber: join a server (HOME) or create one (HOST). +# 4. Kyber/Maxima launches SWBF2 via its own bundled GE-Proton. +# 5. Wait for the Frostbite/SWBF2 loading screen. This takes 1-3 minutes. +# 6. If the SWBF2 window appears but looks stuck: click its taskbar entry +# or press Alt+Tab to bring it into focus — this is normal behaviour +# when the game is launched by a wrapper process rather than directly. +# # ── Hosting a private server ─────────────────────────────────────────────── # # 1. In Kyber, click HOST. @@ -52,11 +67,37 @@ # bypasses all of this entirely. # # ── Prerequisites ────────────────────────────────────────────────────────── -# a. SWBF2 (AppID 1237950) installed via Steam with Proton (GE-Proton -# recommended). Run setup-swbf2-linux.sh first if needed. +# a. SWBF2 (AppID 1237950) installed via Steam. +# Run setup-swbf2-linux.sh first if needed. +# NOTE: Kyber manages its own GE-Proton for launching the game — you +# do not need to configure a Proton version for SWBF2 in Steam. # b. Internet access to download the AppImage (~173 MB). # c. glibc 2.38+ (Ubuntu 24.04+, Fedora 38+, SteamOS 3.7+). # On Ubuntu 22.04 the AppImage may not run — upgrade to 24.04. +# d. Unprivileged user namespaces enabled (required for Kyber's sandbox). +# This script checks and optionally fixes this for you (see below). +# +# ── Unprivileged user namespaces (bwrap) ─────────────────────────────────── +# +# Kyber's AppImage uses bubblewrap (bwrap) for sandboxing. Ubuntu 24.04 +# restricts unprivileged user namespaces by default, which causes the error: +# bwrap: setting up uid map: Permission denied +# +# Fix (this script can apply these automatically): +# sudo sysctl -w kernel.unprivileged_userns_clone=1 +# sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 +# +# To make permanent across reboots, write to /etc/sysctl.d/99-userns.conf: +# kernel.unprivileged_userns_clone = 1 +# kernel.apparmor_restrict_unprivileged_userns = 0 +# +# ── "Game Not Found" dialog ──────────────────────────────────────────────── +# +# If Kyber shows "Game Not Found" after launching: +# 1. Click SET GAME FOLDER in Kyber. +# 2. Run this command to find your SWBF2 install path: +# find ~/.steam/steam/steamapps -name 'starwarsbattlefrontii.exe' 2>/dev/null | head -1 | xargs dirname +# 3. Paste that path into the dialog. Kyber remembers it after this. # # ── Usage ────────────────────────────────────────────────────────────────── # chmod +x setup-kyber-linux.sh @@ -83,6 +124,48 @@ if [ "$GLIBC_MAJOR" -lt 2 ] || { [ "$GLIBC_MAJOR" -eq 2 ] && [ "$GLIBC_MINOR" -l echo "" fi +# ── Check/fix unprivileged user namespaces (bwrap requirement) ──────────── +echo "[0/3] Checking unprivileged user namespace support (required for Kyber)..." + +USERNS_OK=true +CLONE_VAL=$(sysctl -n kernel.unprivileged_userns_clone 2>/dev/null || echo "1") +APPARMOR_VAL=$(sysctl -n kernel.apparmor_restrict_unprivileged_userns 2>/dev/null || echo "0") + +if [ "$CLONE_VAL" != "1" ] || [ "$APPARMOR_VAL" != "0" ]; then + USERNS_OK=false + echo " WARNING: Unprivileged user namespaces are restricted." + echo " Kyber uses bubblewrap (bwrap) which requires them." + echo " Without this fix you will see: bwrap: setting up uid map: Permission denied" + echo "" + if [ "$(id -u)" -eq 0 ]; then + echo " Applying fix now (running as root)..." + sysctl -w kernel.unprivileged_userns_clone=1 + sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + SYSCTL_FILE="/etc/sysctl.d/99-userns.conf" + cat > "$SYSCTL_FILE" << 'SYSCTL' +# Required for Kyber AppImage (bubblewrap sandbox) +kernel.unprivileged_userns_clone = 1 +kernel.apparmor_restrict_unprivileged_userns = 0 +SYSCTL + echo " Saved to $SYSCTL_FILE — will persist across reboots." + USERNS_OK=true + else + echo " To fix, run these commands (requires sudo):" + echo " sudo sysctl -w kernel.unprivileged_userns_clone=1" + echo " sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0" + echo "" + echo " To make permanent, create /etc/sysctl.d/99-userns.conf:" + echo " echo 'kernel.unprivileged_userns_clone = 1' | sudo tee /etc/sysctl.d/99-userns.conf" + echo " echo 'kernel.apparmor_restrict_unprivileged_userns = 0' | sudo tee -a /etc/sysctl.d/99-userns.conf" + echo "" + echo " Re-run this script with sudo to apply automatically." + echo " Continuing with download regardless..." + fi +else + echo " OK — unprivileged user namespaces are enabled." +fi +echo "" + # ── Fetch latest release URL ─────────────────────────────────────────────── echo "[1/3] Fetching latest Kyber Linux release..." API_URL="https://api.github.com/repos/${KYBER_REPO}/releases/latest" @@ -120,7 +203,7 @@ if [ -f "$APPIMAGE_PATH.version" ]; then fi if [ -f "$APPIMAGE_PATH" ] && [ "$CURRENT_VERSION" = "$VERSION" ]; then - echo "[1/3] Already up to date ($VERSION) — skipping download." + echo "[2/3] Already up to date ($VERSION) — skipping download." else echo "[2/3] Downloading Kyber Linux AppImage ($VERSION)..." curl -L --progress-bar -o "$APPIMAGE_PATH" "$APPIMAGE_URL" @@ -158,25 +241,38 @@ echo " From app menu: search 'Kyber Launcher'" echo " Direct: $APPIMAGE_PATH" echo "" echo "Every time you want to play:" -echo " 1. Launch SWBF2 from Steam first — let it fully load to the main menu." -echo " 2. Then launch Kyber and join or host a server." -echo " Kyber does not launch the game itself — Steam must start SWBF2 first." +echo " 1. Open Steam (must be running for library validation)." +echo " Do NOT click Play on SWBF2 in Steam — Kyber launches it." +echo " 2. Launch Kyber and join or host a server." +echo " 3. Kyber/Maxima will launch SWBF2 using its own bundled GE-Proton." +echo " 4. Wait 1-3 minutes for the Frostbite loading screen." +echo " 5. If SWBF2 appears but you can't click into it: press Alt+Tab or" +echo " click its taskbar entry to bring it into focus." echo "" echo "First run (one-time):" echo " 1. Click 'EA Account' and log in with your EA credentials." -echo " 2. Click 'Skip' on the Nexus Mods step (optional — only needed for mods)." +echo " The browser opens to accounts.ea.com — log in there." +echo " 2. Click 'Skip' on the Nexus Mods step (only needed for mods)." echo " 3. EA login is cached — you stay logged in across sessions." echo "" -echo "Hosting a private server with bots:" -echo " HOST → pick maps → set a name and PASSWORD → Start Server." -echo " Share the server name + password with friends (they search by name in HOME)." -echo " Bots fill empty slots automatically — no separate bot setting needed." -echo "" echo "If Kyber says 'Game Not Found':" echo " Click SET GAME FOLDER and run this to find the path:" echo " find ~/.steam/steam/steamapps -name 'starwarsbattlefrontii.exe' 2>/dev/null | head -1 | xargs dirname" +echo " Paste that path into the SET GAME FOLDER dialog. Kyber remembers it." echo "" -echo "SWBF2 must be installed via Steam (AppID 1237950) with GE-Proton." -echo "GE-Proton: https://github.com/GloriousEggroll/proton-ge-custom/releases" +echo "Hosting a private server with bots:" +echo " HOST → pick maps/modes → set a name and PASSWORD → Start Server." +echo " Share the server name + password with friends (they search by name in HOME)." +echo " Bot count: HOST panel → AUTOPLAYERS → set BOTS TEAM 1 and BOTS TEAM 2" +echo " (e.g. 4 each) → click UPDATE SERVER." +echo " Bot difficulty: use the BOT DIFFICULTY slider (RECRUIT / OFFICER / KNIGHT / MASTER)." echo "" +if [ "$USERNS_OK" = "false" ]; then + echo "IMPORTANT: Fix unprivileged user namespaces before launching Kyber:" + echo " sudo sysctl -w kernel.unprivileged_userns_clone=1" + echo " sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0" + echo " Or re-run this script with sudo to apply automatically." + echo "" +fi +echo "SWBF2 must be installed via Steam (AppID 1237950)." echo "To update Kyber later, re-run this script."