Strip appletviewer's menu bar and status line

A Java agent removes them when the viewer window opens, so the stream
shows only the applet. JSObject moves into the agent jar, which puts it on
the class path applets load from.
This commit is contained in:
2026-10-11 00:22:16 -07:00
parent ffd24cb667
commit 46ff37e7fb
9 changed files with 43 additions and 10 deletions
+4 -4
View File
@@ -1,8 +1,8 @@
FROM eclipse-temurin:8-jdk AS jsobject
COPY jsobject /src
FROM eclipse-temurin:8-jdk AS applet-support
COPY applet-support /src
RUN mkdir /classes && \
javac -d /classes $(find /src -name '*.java') && \
jar cf /jsobject.jar -C /classes .
jar cfm /applet-support.jar /src/MANIFEST.MF -C /classes .
FROM ghcr.io/linuxserver/baseimage-selkies:debiantrixie
@@ -18,4 +18,4 @@ RUN apt-get update && \
rm -rf /var/lib/apt/lists/*
COPY root/ /
COPY --from=jsobject /jsobject.jar /opt/flashpoint/jsobject.jar
COPY --from=applet-support /applet-support.jar /opt/flashpoint/applet-support.jar
+4 -3
View File
@@ -36,6 +36,7 @@ runs the game's application with its HTTP proxy pointed at the game server.
Selkies restarts the game when it exits (`RESTART_APP`).
`appletviewer` lacks two things applets got from the browser's Java plugin, so
the image adds them: a `netscape.javascript.JSObject` stand-in (`jsobject/`)
whose window has a working `document.cookie`, and a policy allowing HTTP
requests through the game server's proxy.
the image adds them: a `netscape.javascript.JSObject` stand-in whose window has
a working `document.cookie`, and a policy allowing HTTP requests through the
game server's proxy. The same jar (`applet-support/`) is loaded as a Java agent
that removes appletviewer's menu bar and status line.
@@ -0,0 +1 @@
Premain-Class: flashpoint.BareAppletViewer
@@ -0,0 +1,30 @@
package flashpoint;
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.WindowEvent;
import java.lang.instrument.Instrumentation;
/** Java agent that strips appletviewer's menu bar and status line, leaving only the applet. */
public final class BareAppletViewer {
public static void premain(String args, Instrumentation inst) {
Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
Object source = event.getSource();
if (event.getID() != WindowEvent.WINDOW_OPENED
|| !source.getClass().getName().equals("sun.applet.AppletViewer")) {
return;
}
Frame frame = (Frame) source;
frame.setMenuBar(null);
for (Component component : frame.getComponents()) {
if (component instanceof Label) {
frame.remove(component);
}
}
frame.pack();
}, AWTEvent.WINDOW_EVENT_MASK);
}
}
+1 -1
View File
@@ -13,7 +13,7 @@ services:
- GAME_ID=${GAME_ID:-247a4c93-c252-49c8-8bc9-fb43d5c039df}
# Lock the display to the game window's size; the browser scales it to fit
- SELKIES_MANUAL_WIDTH=${GAME_WIDTH:-472}
- SELKIES_MANUAL_HEIGHT=${GAME_HEIGHT:-400}
- SELKIES_MANUAL_HEIGHT=${GAME_HEIGHT:-354}
- RESTART_APP=true
- NO_DECOR=true
- TITLE=Flashpoint
@@ -34,8 +34,9 @@ fi
echo "Launching $ID: $app $cmd"
case ${app,,} in
'fpsoftware\startjava.bat' | 'fpsoftware\startjavainbrowser.bat')
# Applets expect the browser's JavaScript bridge and a browser-like network policy
export JAVA_TOOL_OPTIONS="-Xbootclasspath/a:/opt/flashpoint/jsobject.jar -Djava.security.policy=/opt/flashpoint/applet.policy"
# 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" ;;
*)
echo "Unsupported application: $app" >&2; exit 1 ;;