Merge pull request #112 from outis1one/claude/zealous-heisenberg-8ylloi
docs: rewrite SWBF2 setup guide as clean how-to with native Linux sec…
This commit is contained in:
+323
-169
@@ -1,117 +1,101 @@
|
|||||||
# Star Wars Battlefront II (2017) — Wolf/Moonlight Setup
|
# Star Wars Battlefront II (2017) — Linux Setup Guide
|
||||||
|
|
||||||
**AppID:** 1237950
|
**AppID:** 1237950
|
||||||
**Proton:** GE-Proton10-34 (required)
|
**Proton:** GE-Proton10-34 or later (required)
|
||||||
**Platform:** Wolf (Games-on-Whales) — WolfSteam Docker container
|
|
||||||
|
This guide covers two setups:
|
||||||
|
- [Wolf / Games-on-Whales + Moonlight streaming](#wolf--moonlight)
|
||||||
|
- [Native Linux Steam](#native-linux-steam)
|
||||||
|
|
||||||
|
The underlying fix is the same for both. The EA App MSI bundled with the game
|
||||||
|
fails to install in Wine due to a .NET custom action (`JunoConfigureRegistry`)
|
||||||
|
that Wine does not support, causing the installer to silently roll back. The
|
||||||
|
fix is to extract the EA Desktop files directly from the MSI on the Linux host
|
||||||
|
using `msiextract`, bypassing the installer entirely, then wire up a launch
|
||||||
|
wrapper to import the necessary registry entries on every launch.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites (both setups)
|
||||||
|
|
||||||
- SWBF2 installed via Steam in the WolfSteam session
|
- SWBF2 (AppID 1237950) installed via Steam and fully downloaded
|
||||||
- GE-Proton10-34 installed (Steam → Settings → Compatibility → Enable Steam Play)
|
- GE-Proton10-34 or later installed
|
||||||
- EA account created at ea.com and linked to your Steam account
|
- An EA account created at ea.com and linked to your Steam account
|
||||||
- `msitools` on the Docker host: `sudo apt-get install -y msitools`
|
- `msitools` installed on the host:
|
||||||
|
```bash
|
||||||
|
sudo apt-get install -y msitools # Debian / Ubuntu
|
||||||
|
sudo dnf install -y msitools # Fedora
|
||||||
|
```
|
||||||
|
|
||||||
|
### EA account requirement
|
||||||
|
|
||||||
|
SWBF2 (2017) requires EA account authentication on first launch. Steam handles
|
||||||
|
the game files; EA App handles identity. First launch requires an internet
|
||||||
|
connection and a valid EA account linked to your Steam account. After
|
||||||
|
authenticating, EA App caches credentials locally and subsequent launches work
|
||||||
|
without re-login until the token expires (typically weeks to months).
|
||||||
|
|
||||||
|
To link accounts: log in at ea.com, go to Connections, and link your Steam
|
||||||
|
account. This is a one-time step that persists across reinstalls.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## The EA dependency problem
|
## Wolf / Moonlight
|
||||||
|
|
||||||
SWBF2 (2017) requires EA's launcher infrastructure — even for single-player offline:
|
### Prerequisites (Wolf)
|
||||||
|
|
||||||
- **Steam** handles payment, library, and game files
|
- Wolf is running and Steam is open in a Moonlight session
|
||||||
- **EA App** handles identity and authentication
|
- GE-Proton is installed inside the WolfSteam container
|
||||||
|
(`./manage.sh ge-proton`)
|
||||||
|
- In Steam (via Moonlight): SWBF2 → Properties → Compatibility →
|
||||||
|
Force GE-Proton10-34
|
||||||
|
|
||||||
First launch requires internet + EA account. After that, EA App caches credentials
|
### Automated setup
|
||||||
locally and subsequent launches work offline — until the token expires or EA's servers
|
|
||||||
shut down permanently.
|
|
||||||
|
|
||||||
**If/when EA shuts down:**
|
If you are using the ubuntu-post-install framework:
|
||||||
- Community private server projects (like Kyber) may replace EA's infrastructure
|
|
||||||
- SWBF2 (2005, AppID 6060) is the zero-dependency alternative — no accounts, no
|
|
||||||
launchers, active community servers, runs perfectly through Proton
|
|
||||||
|
|
||||||
**Migrating to another machine:**
|
|
||||||
```bash
|
```bash
|
||||||
# Back up the Wine prefix — EA credentials travel with it
|
cd ~/docker/wolf
|
||||||
tar -czf swbf2-prefix-backup.tar.gz \
|
./manage.sh setup-swbf2
|
||||||
/home/retro/.steam/steam/steamapps/compatdata/1237950/
|
|
||||||
```
|
|
||||||
Tokens last weeks to months before requiring re-login.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Why docker exec can't run Wine/Proton
|
|
||||||
|
|
||||||
`docker exec` carries high Linux capabilities (`CapEff ≈ 0xa8ac35fb`).
|
|
||||||
Steam processes run with `CapEff=0`. When a high-cap process tries to run bwrap
|
|
||||||
(Steam's sniper/pressure-vessel sandbox), bwrap tries a privileged uid-map path:
|
|
||||||
|
|
||||||
```
|
|
||||||
setting up uid map: Permission denied
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Only Steam itself can launch programs through sniper+GE-Proton.** All Wine
|
Run this after completing step 1 below. The script handles steps 2–6
|
||||||
operations must go through Steam's launch chain — hence the wrapper approach.
|
automatically.
|
||||||
|
|
||||||
---
|
### Manual steps
|
||||||
|
|
||||||
## How it works
|
#### 1. Trigger Wine prefix creation
|
||||||
|
|
||||||
Steam passes a `link2ea://` URL as the "game executable" to GE-Proton. The wrapper
|
Launch SWBF2 from Moonlight. Wait approximately 10 seconds. You will see an
|
||||||
intercepts this, imports registry fixes, then passes the original URL through.
|
"Origin is not installed" error — this is expected. Close it and return to
|
||||||
GE-Proton's `steam.exe` handles `link2ea://`, finds `Link2EA.exe` via the registry,
|
the terminal.
|
||||||
runs it, and EA Desktop authenticates the session before launching the game.
|
|
||||||
|
|
||||||
```
|
Verify the MSI appeared in the Wine prefix:
|
||||||
Steam → wrapper → regedit (registry fixes) → exec original args
|
|
||||||
→ GE-Proton steam.exe → link2ea:// → Link2EA.exe → EA Desktop → SWBF2
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Step-by-step
|
|
||||||
|
|
||||||
### 1. Trigger Wine prefix creation
|
|
||||||
|
|
||||||
SWBF2 must be launched at least once so Steam creates the Wine prefix and drops
|
|
||||||
`ea_app.msi` into it. Launch SWBF2 from Moonlight, wait ~10 seconds, then close it
|
|
||||||
(the "Origin is not installed" error is expected at this point).
|
|
||||||
|
|
||||||
Verify the MSI appeared:
|
|
||||||
```bash
|
```bash
|
||||||
WOLF_CONTAINER=$(docker ps --format '{{.Names}}' | grep Wolf)
|
WOLF_CONTAINER=$(docker ps --format '{{.Names}}' | grep WolfSteam | head -1)
|
||||||
docker exec "$WOLF_CONTAINER" ls -lh \
|
docker exec "$WOLF_CONTAINER" ls -lh \
|
||||||
/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi
|
/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi
|
||||||
```
|
```
|
||||||
Expected: ~227 MB file.
|
|
||||||
|
|
||||||
### 2. Extract EA Desktop files on the host
|
Expected: approximately 227 MB.
|
||||||
|
|
||||||
The MSI's `JunoConfigureRegistry` .NET custom action fails in Wine (it uses
|
#### 2. Extract EA Desktop files on the host
|
||||||
`SetSecurityDescriptorSddlForm` for registry ACLs — unsupported in Wine). This
|
|
||||||
causes the entire install to roll back. Extract files on the host instead:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
WOLF_CONTAINER=$(docker ps --format '{{.Names}}' | grep Wolf)
|
WOLF_CONTAINER=$(docker ps --format '{{.Names}}' | grep WolfSteam | head -1)
|
||||||
|
|
||||||
docker cp "$WOLF_CONTAINER:/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi" \
|
docker cp \
|
||||||
|
"$WOLF_CONTAINER:/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi" \
|
||||||
/tmp/ea_app.msi
|
/tmp/ea_app.msi
|
||||||
|
|
||||||
sudo apt-get install -y msitools
|
|
||||||
mkdir -p /tmp/ea_app_extracted
|
mkdir -p /tmp/ea_app_extracted
|
||||||
msiextract -C /tmp/ea_app_extracted /tmp/ea_app.msi
|
msiextract -C /tmp/ea_app_extracted /tmp/ea_app.msi
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Copy EA Desktop files into the Wine prefix
|
#### 3. Copy EA Desktop files into the Wine prefix
|
||||||
|
|
||||||
The MSI installs EA Desktop under a versioned directory with a symlink.
|
|
||||||
The version (e.g. `14.2.0.3345`) is whatever the extracted MSI contains:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
EA_VERSION=$(ls /tmp/ea_app_extracted/Electronic\ Arts/EA\ Desktop/ | head -1)
|
|
||||||
# Usually "EA Desktop" — this is the versioned dir, renamed during real install
|
|
||||||
# Use the version from the failed-install symlink if present:
|
|
||||||
SYMLINK_TARGET=$(docker exec "$WOLF_CONTAINER" readlink \
|
SYMLINK_TARGET=$(docker exec "$WOLF_CONTAINER" readlink \
|
||||||
"/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/Program Files/Electronic Arts/EA Desktop/EA Desktop" \
|
"/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/Program Files/Electronic Arts/EA Desktop/EA Desktop" \
|
||||||
2>/dev/null || echo "14.2.0.3345")
|
2>/dev/null || echo "14.2.0.3345")
|
||||||
@@ -131,16 +115,14 @@ docker cp "/tmp/ea_app_extracted/Electronic Arts/EA Desktop/EA Desktop/." \
|
|||||||
docker exec "$WOLF_CONTAINER" find "$PFXBASE" -name "Link2EA.exe"
|
docker exec "$WOLF_CONTAINER" find "$PFXBASE" -name "Link2EA.exe"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Write registry fix files to drive_c
|
#### 4. Write registry fix files to drive_c
|
||||||
|
|
||||||
These are imported into the Wine registry on each launch via the wrapper.
|
These files are imported into the Wine registry on every launch by the wrapper
|
||||||
Writing to drive_c ensures they survive wineserver restarts (unlike direct
|
script. Storing them in drive_c ensures they survive wineserver restarts.
|
||||||
system.reg edits which get overwritten).
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
PFXC="$WOLF_CONTAINER:/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c"
|
PFXC="$WOLF_CONTAINER:/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c"
|
||||||
|
|
||||||
# link2ea:// protocol handler — tells Wine how to run Link2EA.exe
|
|
||||||
cat > /tmp/link2ea_fix.reg << 'EOF'
|
cat > /tmp/link2ea_fix.reg << 'EOF'
|
||||||
Windows Registry Editor Version 5.00
|
Windows Registry Editor Version 5.00
|
||||||
|
|
||||||
@@ -152,8 +134,6 @@ Windows Registry Editor Version 5.00
|
|||||||
@="\"C:\\Program Files\\Electronic Arts\\EA Desktop\\EA Desktop\\Link2EA.exe\" \"%1\""
|
@="\"C:\\Program Files\\Electronic Arts\\EA Desktop\\EA Desktop\\Link2EA.exe\" \"%1\""
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# EA Desktop Windows services — EALocalHostSvc provides local IPC that
|
|
||||||
# Link2EA.exe needs; without it launch fails with RPC_S_SERVER_UNAVAILABLE
|
|
||||||
cat > /tmp/ea_services.reg << 'EOF'
|
cat > /tmp/ea_services.reg << 'EOF'
|
||||||
Windows Registry Editor Version 5.00
|
Windows Registry Editor Version 5.00
|
||||||
|
|
||||||
@@ -178,127 +158,283 @@ docker cp /tmp/link2ea_fix.reg "$PFXC/link2ea_fix.reg"
|
|||||||
docker cp /tmp/ea_services.reg "$PFXC/ea_services.reg"
|
docker cp /tmp/ea_services.reg "$PFXC/ea_services.reg"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Lock localconfig.vdf and set launch options
|
#### 5. Write the launch wrapper
|
||||||
|
|
||||||
Steam overwrites localconfig.vdf on shutdown via atomic rename (temp file +
|
|
||||||
rename). `chmod 444` on the file is bypassed. Lock the **directory** instead:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
STEAM_UID=$(docker exec "$WOLF_CONTAINER" ls /home/retro/.steam/steam/userdata/)
|
|
||||||
CONFIG_DIR="/home/retro/.steam/steam/userdata/$STEAM_UID/config"
|
|
||||||
CONFIG_FILE="$CONFIG_DIR/localconfig.vdf"
|
|
||||||
|
|
||||||
# Stop Steam so it flushes before we edit
|
|
||||||
docker exec "$WOLF_CONTAINER" pkill -f steam.sh || true
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Lock directory
|
|
||||||
docker exec "$WOLF_CONTAINER" chmod 555 "$CONFIG_DIR"
|
|
||||||
|
|
||||||
# Add launch options for AppID 1237950
|
|
||||||
# Find the 1237950 block and insert/replace LaunchOptions
|
|
||||||
docker exec "$WOLF_CONTAINER" python3 - "$CONFIG_FILE" << 'PYEOF'
|
|
||||||
import sys, re
|
|
||||||
path = sys.argv[1]
|
|
||||||
with open(path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
launch_opt = 'STEAM_UNIX_SOCKET=/tmp/steam.sock /home/retro/ea_install.sh %command%'
|
|
||||||
|
|
||||||
# Replace existing LaunchOptions in 1237950 block if present
|
|
||||||
new = re.sub(
|
|
||||||
r'("1237950".*?"LaunchOptions"\s*)"[^"]*"',
|
|
||||||
rf'\1"{launch_opt}"',
|
|
||||||
content, flags=re.DOTALL
|
|
||||||
)
|
|
||||||
|
|
||||||
if new == content:
|
|
||||||
# LaunchOptions key missing — add it after the "1237950" line
|
|
||||||
new = re.sub(
|
|
||||||
r'("1237950"\s*\n\s*\{)',
|
|
||||||
rf'\1\n\t\t\t\t"LaunchOptions"\t\t"{launch_opt}"',
|
|
||||||
content
|
|
||||||
)
|
|
||||||
|
|
||||||
with open(path, 'w') as f:
|
|
||||||
f.write(new)
|
|
||||||
print("Done")
|
|
||||||
PYEOF
|
|
||||||
|
|
||||||
# Verify
|
|
||||||
docker exec "$WOLF_CONTAINER" grep -A3 '"1237950"' "$CONFIG_FILE" | grep -i launch
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Write the wrapper script
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat > /tmp/ea_install.sh << 'EOF'
|
cat > /tmp/ea_install.sh << 'EOF'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo "=== launch $(date) ===" >> /tmp/ea_install.log
|
echo "=== launch $(date) ===" >> /tmp/ea_install.log
|
||||||
# Import registry fixes on every launch (survives wineserver restarts)
|
|
||||||
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" regedit /S "C:\\link2ea_fix.reg"
|
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" regedit /S "C:\\link2ea_fix.reg"
|
||||||
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" regedit /S "C:\\ea_services.reg"
|
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" regedit /S "C:\\ea_services.reg"
|
||||||
# Pass original args through — Steam's link2ea:// URL goes to GE-Proton → Link2EA.exe
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
EOF
|
EOF
|
||||||
chmod +x /tmp/ea_install.sh
|
chmod +x /tmp/ea_install.sh
|
||||||
docker cp /tmp/ea_install.sh "$WOLF_CONTAINER":/home/retro/ea_install.sh
|
docker cp /tmp/ea_install.sh "$WOLF_CONTAINER":/home/retro/ea_install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7. First launch
|
#### 6. Set Steam launch options
|
||||||
|
|
||||||
|
Stop Steam so it flushes its current state before editing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
STEAM_UID=$(docker exec "$WOLF_CONTAINER" ls /home/retro/.steam/steam/userdata/)
|
||||||
|
CONFIG_DIR="/home/retro/.steam/steam/userdata/$STEAM_UID/config"
|
||||||
|
CONFIG_FILE="$CONFIG_DIR/localconfig.vdf"
|
||||||
|
|
||||||
|
docker exec "$WOLF_CONTAINER" pkill -f steam.sh || true
|
||||||
|
sleep 5
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit localconfig.vdf to add the launch option for AppID 1237950:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec "$WOLF_CONTAINER" python3 - "$CONFIG_FILE" << 'PYEOF'
|
||||||
|
import sys, re
|
||||||
|
path = sys.argv[1]
|
||||||
|
with open(path) as f:
|
||||||
|
content = f.read()
|
||||||
|
opt = 'STEAM_UNIX_SOCKET=/tmp/steam.sock /home/retro/ea_install.sh %command%'
|
||||||
|
new = re.sub(r'("1237950".*?"LaunchOptions"\s*)"[^"]*"', rf'\1"{opt}"', content, flags=re.DOTALL)
|
||||||
|
if new == content:
|
||||||
|
new = re.sub(r'("1237950"\s*\n\s*\{)', rf'\1\n\t\t\t\t"LaunchOptions"\t\t"{opt}"', content)
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(new)
|
||||||
|
print("Done")
|
||||||
|
PYEOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Lock the config directory so Steam cannot overwrite localconfig.vdf on shutdown:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec "$WOLF_CONTAINER" chmod 555 "$CONFIG_DIR"
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec "$WOLF_CONTAINER" grep -A3 '"1237950"' "$CONFIG_FILE" | grep -i launch
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7. Launch the game
|
||||||
|
|
||||||
1. Reconnect to Moonlight and launch SWBF2
|
1. Reconnect to Moonlight and launch SWBF2
|
||||||
2. **Let Vulkan shaders compile** — do not skip, takes several minutes, only happens once
|
2. Let Vulkan shaders compile — do not skip; takes several minutes on first run only
|
||||||
3. EA App authenticates via your linked Steam/EA account (no manual login if accounts are linked)
|
3. EA App authenticates via your linked Steam/EA account
|
||||||
4. Game loads
|
4. Game loads
|
||||||
|
|
||||||
|
### Fresh install behaviour (Wolf)
|
||||||
|
|
||||||
|
| Component | Survives reinstall? | Notes |
|
||||||
|
|-----------|-------------------|-------|
|
||||||
|
| EA Desktop files in Wine prefix | No | Re-run setup after prefix is recreated |
|
||||||
|
| Registry fix files in drive_c | No | Re-run setup after prefix is recreated |
|
||||||
|
| Launch options in localconfig.vdf | No | Re-run setup after prefix is recreated |
|
||||||
|
| Config dir lock | No | Re-run setup after prefix is recreated |
|
||||||
|
| ea_app.msi | No | Requires one launch to reappear |
|
||||||
|
| EA account link | Yes | Stored on EA's servers |
|
||||||
|
| EA auth token | No | Requires one re-login after prefix deletion |
|
||||||
|
|
||||||
|
If the Wine prefix (`compatdata/1237950/`) is deleted, run the setup again from
|
||||||
|
step 1. To preserve credentials when moving to a new machine, back up the prefix:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tar -czf swbf2-prefix-backup.tar.gz \
|
||||||
|
/path/to/wolf-state/Steam/.steam/steam/steamapps/compatdata/1237950/
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Is this fragile? Will it work on a fresh install?
|
## Native Linux Steam
|
||||||
|
|
||||||
**Honest assessment:**
|
### Prerequisites (native)
|
||||||
|
|
||||||
| Component | Fresh install safe? | Notes |
|
- GE-Proton installed via ProtonUp-Qt or manually into `~/.steam/compatibilitytools.d/`
|
||||||
|-----------|-------------------|-------|
|
- In Steam: SWBF2 → Properties → Compatibility → Force GE-Proton10-34
|
||||||
| EA Desktop files in Wine prefix | ✅ | Extracted from MSI in game files |
|
|
||||||
| Registry fixes (.reg files) | ✅ | Imported on every launch via wrapper |
|
|
||||||
| Launch options in localconfig.vdf | ✅ | Set by script |
|
|
||||||
| Config dir lock (chmod 555) | ✅ | Set by script |
|
|
||||||
| ea_app.msi in drive_c | ⚠️ | Requires one failed launch first to appear |
|
|
||||||
| EA account link | ⚠️ | One-time manual step |
|
|
||||||
| Vulkan shader cache | ⚠️ | Recompiles on fresh prefix — takes minutes |
|
|
||||||
| EA token in Wine prefix | ⚠️ | Requires login if prefix deleted or token expired |
|
|
||||||
|
|
||||||
**The catch:** The Wine prefix (`compatdata/1237950/`) is recreated from scratch if deleted.
|
### Automated setup
|
||||||
All file copies and registry entries live inside it. A fresh install needs all steps run again
|
|
||||||
— but the automation handles that.
|
|
||||||
|
|
||||||
**The one irreducible manual step:** Linking your EA account to Steam (done once at ea.com,
|
```bash
|
||||||
persists across reinstalls via EA's servers).
|
chmod +x setup-swbf2-linux.sh
|
||||||
|
./setup-swbf2-linux.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Run after completing step 1 below.
|
||||||
|
|
||||||
|
### Manual steps
|
||||||
|
|
||||||
|
#### 1. Trigger Wine prefix creation
|
||||||
|
|
||||||
|
Launch SWBF2 from Steam. Wait approximately 10 seconds. You will see an
|
||||||
|
"Origin is not installed" error — this is expected. Close it.
|
||||||
|
|
||||||
|
Verify the MSI appeared:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -lh ~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: approximately 227 MB.
|
||||||
|
|
||||||
|
#### 2. Extract EA Desktop files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /tmp/ea_app_extracted
|
||||||
|
msiextract -C /tmp/ea_app_extracted \
|
||||||
|
~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Copy EA Desktop files into the Wine prefix
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PFX_C=~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c
|
||||||
|
EA_DEST_BASE="$PFX_C/Program Files/Electronic Arts/EA Desktop"
|
||||||
|
|
||||||
|
SYMLINK_TARGET=$(readlink "$EA_DEST_BASE/EA Desktop" 2>/dev/null || echo "14.2.0.3345")
|
||||||
|
|
||||||
|
mkdir -p "$EA_DEST_BASE/$SYMLINK_TARGET"
|
||||||
|
cp -r "/tmp/ea_app_extracted/Electronic Arts/EA Desktop/EA Desktop/." \
|
||||||
|
"$EA_DEST_BASE/$SYMLINK_TARGET/"
|
||||||
|
|
||||||
|
rm -f "$EA_DEST_BASE/EA Desktop"
|
||||||
|
ln -sf "$SYMLINK_TARGET" "$EA_DEST_BASE/EA Desktop"
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
find "$EA_DEST_BASE" -name "Link2EA.exe"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Write registry fix files to drive_c
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PFX_C=~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c
|
||||||
|
|
||||||
|
cat > "$PFX_C/link2ea_fix.reg" << 'EOF'
|
||||||
|
Windows Registry Editor Version 5.00
|
||||||
|
|
||||||
|
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\link2ea]
|
||||||
|
@="URL:link2ea Protocol"
|
||||||
|
"URL Protocol"=""
|
||||||
|
|
||||||
|
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\link2ea\shell\open\command]
|
||||||
|
@="\"C:\\Program Files\\Electronic Arts\\EA Desktop\\EA Desktop\\Link2EA.exe\" \"%1\""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > "$PFX_C/ea_services.reg" << 'EOF'
|
||||||
|
Windows Registry Editor Version 5.00
|
||||||
|
|
||||||
|
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EALocalHostSvc]
|
||||||
|
"Type"=dword:00000010
|
||||||
|
"Start"=dword:00000002
|
||||||
|
"ErrorControl"=dword:00000001
|
||||||
|
"ImagePath"="C:\\Program Files\\Electronic Arts\\EA Desktop\\EA Desktop\\EALocalHostSvc.exe"
|
||||||
|
"DisplayName"="EA Local Host Service"
|
||||||
|
"ObjectName"="LocalSystem"
|
||||||
|
|
||||||
|
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EABackgroundService]
|
||||||
|
"Type"=dword:00000010
|
||||||
|
"Start"=dword:00000002
|
||||||
|
"ErrorControl"=dword:00000001
|
||||||
|
"ImagePath"="C:\\Program Files\\Electronic Arts\\EA Desktop\\EA Desktop\\EABackgroundService.exe"
|
||||||
|
"DisplayName"="EA Background Service"
|
||||||
|
"ObjectName"="LocalSystem"
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Write the launch wrapper
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.local/bin
|
||||||
|
|
||||||
|
cat > ~/.local/bin/ea_install.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "=== launch $(date) ===" >> /tmp/ea_install.log
|
||||||
|
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" regedit /S "C:\\link2ea_fix.reg"
|
||||||
|
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" regedit /S "C:\\ea_services.reg"
|
||||||
|
exec "$@"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x ~/.local/bin/ea_install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6. Set Steam launch options
|
||||||
|
|
||||||
|
In Steam: right-click SWBF2 → Properties → Launch Options, enter:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.local/bin/ea_install.sh %command%
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, set it from the terminal. Close Steam first, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
STEAM_UID=$(ls ~/.steam/steam/userdata/ | head -1)
|
||||||
|
CFG=~/.steam/steam/userdata/$STEAM_UID/config/localconfig.vdf
|
||||||
|
|
||||||
|
python3 - "$CFG" << 'PYEOF'
|
||||||
|
import sys, re
|
||||||
|
path = sys.argv[1]
|
||||||
|
import os
|
||||||
|
opt = os.path.expanduser('~/.local/bin/ea_install.sh') + ' %command%'
|
||||||
|
with open(path) as f:
|
||||||
|
content = f.read()
|
||||||
|
new = re.sub(r'("1237950".*?"LaunchOptions"\s*)"[^"]*"', rf'\1"{opt}"', content, flags=re.DOTALL)
|
||||||
|
if new == content:
|
||||||
|
new = re.sub(r'("1237950"\s*\n\s*\{)', rf'\1\n\t\t\t\t"LaunchOptions"\t\t"{opt}"', content)
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(new)
|
||||||
|
print("Done")
|
||||||
|
PYEOF
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7. Launch the game
|
||||||
|
|
||||||
|
1. Launch SWBF2 from Steam
|
||||||
|
2. Let Vulkan shaders compile on first run — do not skip
|
||||||
|
3. EA App authenticates via your linked Steam/EA account
|
||||||
|
4. Game loads
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### "Origin is not installed" popup
|
### "Origin is not installed" popup
|
||||||
The game binary checks for Origin before calling link2ea://. This happens when:
|
|
||||||
- The wrapper didn't run (check launch options are set)
|
|
||||||
- The wrapper ran but regedit failed (check `tail /tmp/ea_install.log`)
|
|
||||||
|
|
||||||
### `link2ea://` fails with ret 31 (SE_ERR_NOASSOC)
|
The wrapper did not run, or ran but regedit failed.
|
||||||
`link2ea_fix.reg` wasn't imported. Check drive_c has the file and wrapper ran both regedits.
|
|
||||||
|
|
||||||
### RPC_S_SERVER_UNAVAILABLE (0x800706ba) in wine log
|
- Verify launch options are set: Steam → SWBF2 → Properties → Launch Options
|
||||||
`ea_services.reg` wasn't imported or EALocalHostSvc failed to register. Check wrapper log.
|
- Check the wrapper log:
|
||||||
|
```bash
|
||||||
|
tail /tmp/ea_install.log
|
||||||
|
```
|
||||||
|
|
||||||
### Game exits immediately, no popup, no log
|
### `link2ea://` fails — game exits silently after a moment
|
||||||
Wrapper isn't being called. Config dir may not be chmod 555 or launch options missing.
|
|
||||||
|
`link2ea_fix.reg` was not imported. Confirm `link2ea_fix.reg` exists in drive_c
|
||||||
|
and the wrapper ran both regedit commands.
|
||||||
|
|
||||||
|
### RPC_S_SERVER_UNAVAILABLE (0x800706ba) in Proton log
|
||||||
|
|
||||||
|
`ea_services.reg` was not imported or the service entries were not written
|
||||||
|
correctly. Check the wrapper log and confirm `ea_services.reg` exists in drive_c.
|
||||||
|
|
||||||
|
### Game exits immediately, no popup, no log entry
|
||||||
|
|
||||||
|
The wrapper is not being called at all.
|
||||||
|
|
||||||
|
**Wolf:**
|
||||||
```bash
|
```bash
|
||||||
docker exec "$WOLF_CONTAINER" stat "$CONFIG_DIR" | grep Access
|
docker exec "$WOLF_CONTAINER" stat "$CONFIG_DIR" | grep Access
|
||||||
docker exec "$WOLF_CONTAINER" grep -A5 '"1237950"' "$CONFIG_FILE" | grep -i launch
|
docker exec "$WOLF_CONTAINER" grep -A5 '"1237950"' "$CONFIG_FILE" | grep -i launch
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Native:**
|
||||||
|
```bash
|
||||||
|
stat ~/.steam/steam/userdata/*/config | grep Access
|
||||||
|
grep -A5 '"1237950"' ~/.steam/steam/userdata/*/config/localconfig.vdf | grep -i launch
|
||||||
|
```
|
||||||
|
|
||||||
### Collecting logs after a failure
|
### Collecting logs after a failure
|
||||||
|
|
||||||
|
**Wolf:**
|
||||||
```bash
|
```bash
|
||||||
docker exec "$WOLF_CONTAINER" bash -c "
|
docker exec "$WOLF_CONTAINER" bash -c "
|
||||||
tail -20 /tmp/ea_install.log
|
tail -20 /tmp/ea_install.log
|
||||||
@@ -307,18 +443,36 @@ docker exec "$WOLF_CONTAINER" bash -c "
|
|||||||
"
|
"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Native:**
|
||||||
|
```bash
|
||||||
|
tail /tmp/ea_install.log
|
||||||
|
grep -E '(err:|link2ea|origin|RPC)' ~/.steam/steam/logs/steam_1237950.log 2>/dev/null | tail -20
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Key paths (inside WolfSteam container)
|
## Key paths
|
||||||
|
|
||||||
|
### Wolf (inside WolfSteam container)
|
||||||
|
|
||||||
| Path | Description |
|
| Path | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/` | SWBF2 Wine prefix |
|
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/` | SWBF2 Wine prefix |
|
||||||
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/system.reg` | Wine HKLM registry |
|
|
||||||
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi` | EA App MSI (~227 MB) |
|
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi` | EA App MSI (~227 MB) |
|
||||||
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/link2ea_fix.reg` | link2ea protocol handler reg |
|
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/link2ea_fix.reg` | link2ea protocol handler |
|
||||||
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_services.reg` | EA service registrations |
|
| `/home/retro/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_services.reg` | EA service registrations |
|
||||||
| `/home/retro/.steam/steam/steamapps/common/STAR WARS Battlefront II/` | Game files |
|
|
||||||
| `/home/retro/.steam/steam/userdata/<uid>/config/localconfig.vdf` | Steam launch options |
|
| `/home/retro/.steam/steam/userdata/<uid>/config/localconfig.vdf` | Steam launch options |
|
||||||
| `/home/retro/ea_install.sh` | Launch wrapper |
|
| `/home/retro/ea_install.sh` | Launch wrapper |
|
||||||
| `/tmp/ea_install.log` | Wrapper log (resets on container restart) |
|
| `/tmp/ea_install.log` | Wrapper log (resets on container restart) |
|
||||||
|
|
||||||
|
### Native Linux Steam
|
||||||
|
|
||||||
|
| Path | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `~/.steam/steam/steamapps/compatdata/1237950/pfx/` | SWBF2 Wine prefix |
|
||||||
|
| `~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_app.msi` | EA App MSI (~227 MB) |
|
||||||
|
| `~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/link2ea_fix.reg` | link2ea protocol handler |
|
||||||
|
| `~/.steam/steam/steamapps/compatdata/1237950/pfx/drive_c/ea_services.reg` | EA service registrations |
|
||||||
|
| `~/.steam/steam/userdata/<uid>/config/localconfig.vdf` | Steam launch options |
|
||||||
|
| `~/.local/bin/ea_install.sh` | Launch wrapper |
|
||||||
|
| `/tmp/ea_install.log` | Wrapper log |
|
||||||
|
|||||||
Reference in New Issue
Block a user