Files
dotcom-arcade/streaming/streamer/root/usr/local/bin/fp-launch
T
branderson e0e3b5d4bb Run Windows games from LocalGames under Wine
fp-launch runs a LocalGames .exe with Flashpoint's bundled Wine from a
writable copy, linking its Prefs directory, where Director projectors save,
into the synced saves directory. Players without a save start from the Prefs
the game ships with. The image adds the X, font and PulseAudio libraries the
bundled Wine loads.
2026-10-11 16:18:07 -07:00

62 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Launch a Flashpoint game by ID the way the Linux launcher does: start the
# game server, mount the game's zip, then run its application through the proxy.
set -euo pipefail
FP_PATH=${FP_PATH:-/flashpoint}
ID=${1:?usage: fp-launch <game id>}
DB=$FP_PATH/Data/flashpoint.sqlite
API=http://127.0.0.1:22501/fpProxy/api
[[ $ID =~ ^[0-9a-f-]{36}$ ]] || { echo "Invalid game id: $ID" >&2; exit 1; }
if ! curl -s -o /dev/null "$API/listmountzip"; then
"$FP_PATH/Server/FlashpointGameServer" -rootPath "$FP_PATH" \
-useInfinityServer=false -handleLegacyRequests=true &
until curl -s -o /dev/null "$API/listmountzip"; do sleep 0.2; done
fi
IFS=$'\x1f' read -r app cmd date_added < <(sqlite3 -readonly -separator $'\x1f' "$DB" "
select coalesce(nullif(d.applicationPath, ''), g.applicationPath),
coalesce(nullif(d.launchCommand, ''), g.launchCommand),
coalesce(d.dateAdded, '')
from game g left join game_data d on d.id = g.activeDataId
where g.id = '$ID'") || true
[[ -n ${app:-} ]] || { echo "Game not found: $ID" >&2; exit 1; }
if [[ -n $date_added ]]; then
zip=$FP_PATH/Data/Games/$ID-$(date -u -d "$date_added" +%s%3N).zip
curl -sf -X POST -H 'Content-Type: application/json' \
-d "{\"filePath\": \"$zip\"}" "$API/mountzip" >/dev/null ||
{ echo "Failed to mount $zip" >&2; exit 1; }
fi
echo "Launching $ID: $app $cmd"
case ${app,,} in
'fpsoftware\startjava.bat' | 'fpsoftware\startjavainbrowser.bat')
# Supplies the browser's JavaScript bridge, a browser-like network policy,
# and a window holding only the applet
export JAVA_TOOL_OPTIONS="-javaagent:/opt/flashpoint/applet-support.jar -Djava.security.policy=/opt/flashpoint/applet.policy"
FP_PATH=$FP_PATH exec "$FP_PATH/FPSoftware/startJava.sh" "$cmd" ;;
'localgames\'*.exe)
# Windows games run under Flashpoint's bundled Wine from a writable copy.
# Prefs, where Director projectors save, lives in the synced saves directory.
exe=${app//\\//}
work=$HOME/game
[[ -d $work ]] || cp -r "$FP_PATH/$(dirname "$exe")" "$work"
if [[ ! -L $work/Prefs ]]; then
mkdir -p "$HOME/saves/Prefs"
# Players without a save start from the one the game ships with
if [[ -d $work/Prefs && -z $(ls -A "$HOME/saves/Prefs") ]]; then
cp -r "$work/Prefs/." "$HOME/saves/Prefs"
fi
rm -rf "$work/Prefs"
ln -s "$HOME/saves/Prefs" "$work/Prefs"
fi
export WINEPREFIX=$HOME/.wine WINEDEBUG=-all WINEDLLOVERRIDES='mscoree,mshtml='
cd "$work"
exec "$FP_PATH/FPSoftware/Wine/bin/wine" "$(basename "$exe")" ;;
*)
echo "Unsupported application: $app" >&2; exit 1 ;;
esac