Flash Player moves its window back to the top of the screen once the movie has loaded, bringing the menu bar back. The streamer now checks the window twice a second and puts it back, logging the first few times.
90 lines
4.3 KiB
Bash
Executable File
90 lines
4.3 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" ;;
|
|
*)
|
|
mapfile -d '' argv < <(FP_PATH=$FP_PATH FP_WRITABLE=$HOME/flashpoint fp-command "$app" "$cmd") || true
|
|
(( ${#argv[@]} > 1 )) || { echo "Unsupported application: $app" >&2; exit 1; }
|
|
export FP_PATH HTTP_PROXY=http://127.0.0.1:22500/ http_proxy=http://127.0.0.1:22500/
|
|
export PATH=$FP_PATH/FPSoftware/Wine/bin:$PATH WINEDEBUG=-all WINEDLLOVERRIDES='mscoree,mshtml='
|
|
# Flash Player keeps saves (SharedObjects) here
|
|
mkdir -p "$HOME/saves/Flash_Player" "$HOME/.macromedia"
|
|
[[ -e $HOME/.macromedia/Flash_Player ]] || ln -s "$HOME/saves/Flash_Player" "$HOME/.macromedia/Flash_Player"
|
|
if [[ ${app,,} == 'fpsoftware\flash\'* ]]; then
|
|
# Hide the projector's menu bar by moving it above the display, and fill
|
|
# the display with the movie. Not full screen, which some games, such as
|
|
# Bloons, don't play right in. The window manager keeps windows on
|
|
# screen, so the window is taken out of its hands first.
|
|
(
|
|
set +eo pipefail
|
|
wid=$(xdotool search --sync --onlyvisible --name 'Flash Player' | head -1)
|
|
read -r width height < <(xdotool getdisplaygeometry)
|
|
# GTK draws the menu bar in the window itself, and the movie in the
|
|
# largest child window, below it: the movie's offset is the menu bar's height
|
|
menu=$(xwininfo -children -id "$wid" | awk '
|
|
match($0, /[0-9]+x[0-9]+\+-?[0-9]+\+-?[0-9]+/) {
|
|
split(substr($0, RSTART, RLENGTH), g, /[x+]/)
|
|
if (g[1] * g[2] > area) { area = g[1] * g[2]; top = g[4] }
|
|
}
|
|
END { print top + 0 }')
|
|
((menu >= 0 && menu < height)) || menu=0
|
|
echo "Flash Player window $wid: menu bar ${menu}px, display ${width}x${height}"
|
|
xdotool windowunmap --sync "$wid"
|
|
xdotool set_window --overrideredirect 1 "$wid"
|
|
xdotool windowmap --sync "$wid"
|
|
place() { xdotool windowsize "$wid" "$width" $((height + menu)) windowmove "$wid" 0 $((-menu)); }
|
|
place
|
|
xdotool windowfocus "$wid"
|
|
# Flash Player moves its window back once the movie has loaded, so it's
|
|
# kept in place for as long as it's open
|
|
moves=0
|
|
while geometry=$(xdotool getwindowgeometry --shell "$wid" 2>/dev/null); do
|
|
eval "$geometry"
|
|
if ((X != 0 || Y != -menu || WIDTH != width || HEIGHT != height + menu)); then
|
|
((++moves <= 3)) && echo "Flash Player window moved to $X,$Y (${WIDTH}x${HEIGHT}); putting it back"
|
|
place
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
) &
|
|
fi
|
|
cd "${argv[0]}"
|
|
exec "${argv[@]:1}" ;;
|
|
esac
|