Add Selkies streamer prototype for Java games

Runs a Flashpoint game natively in a container and streams it to the
browser. fp-launch follows the Linux launcher's sequence: start the game
server, mount the game's zip, and run startJava.sh through the proxy.
This commit is contained in:
2026-10-10 23:36:13 -07:00
commit b0751fdbb1
6 changed files with 108 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
FROM ghcr.io/linuxserver/baseimage-selkies:debiantrixie
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
fontconfig \
fonts-dejavu-core \
libasound2-plugins \
libxi6 \
libxrender1 \
libxtst6 \
sqlite3 && \
rm -rf /var/lib/apt/lists/*
COPY root/ /
+35
View File
@@ -0,0 +1,35 @@
# Flashpoint streamer (prototype)
Runs a Flashpoint game natively on the server and streams it to the browser with
[Selkies](https://github.com/selkies-project/selkies), for platforms that cannot
run in a browser. One container plays one game, set by `GAME_ID`. Only Java
applets are supported so far.
## Requirements
A Linux Flashpoint install at `FLASHPOINT_HOST_PATH`. The streamer uses the
Infinity build's `Server/FlashpointGameServer` and `FPSoftware/Java`, which
Ultimate's packed zips do not include on Linux. To add them to an extracted
Ultimate without overwriting its data, copy an extracted
[Infinity for Linux](https://flashpointarchive.org/downloads) over it:
```sh
rsync -a --ignore-existing /path/to/infinity/ /path/to/flashpoint/
```
## Usage
```sh
FLASHPOINT_HOST_PATH=/path/to/flashpoint docker compose up -d --build
```
Open `https://<host>:3001` and accept the self-signed certificate. To play a
different game, set `GAME_ID` and recreate the container. The launch log is at
`/config/fp-launch.log` inside the container.
## How it works
`fp-launch` follows the Flashpoint launcher's Linux launch sequence: it starts
the game server, mounts the game's zip through the server's `mountzip` API, and
runs the game's application with its HTTP proxy pointed at the game server.
Selkies restarts the game when it exits (`RESTART_APP`).
+16
View File
@@ -0,0 +1,16 @@
services:
flashpoint-streamer:
build: .
container_name: flashpoint-streamer
shm_size: 1gb
ports:
- "${STREAMER_PORT:-3001}:3001"
volumes:
- ${FLASHPOINT_HOST_PATH:?FLASHPOINT_HOST_PATH is required}:/flashpoint:ro
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- GAME_ID=${GAME_ID:-247a4c93-c252-49c8-8bc9-fb43d5c039df}
- RESTART_APP=true
- NO_DECOR=true
- TITLE=Flashpoint
@@ -0,0 +1 @@
fp-launch "$GAME_ID" >>"$HOME/fp-launch.log" 2>&1
+2
View File
@@ -0,0 +1,2 @@
pcm.!default { type pulse }
ctl.!default { type pulse }
+40
View File
@@ -0,0 +1,40 @@
#!/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')
FP_PATH=$FP_PATH exec "$FP_PATH/FPSoftware/startJava.sh" "$cmd" ;;
*)
echo "Unsupported application: $app" >&2; exit 1 ;;
esac