Run applets that use LiveConnect or load images through the proxy
appletviewer has no netscape.javascript.JSObject, so applets that touch JavaScript fail to load, and Java 8 denies applets the URLPermission they need to fetch through an HTTP proxy. Add a JSObject stand-in with a working document.cookie and a policy granting HTTP URL access.
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
FROM eclipse-temurin:8-jdk AS jsobject
|
||||||
|
COPY jsobject /src
|
||||||
|
RUN mkdir /classes && \
|
||||||
|
javac -d /classes $(find /src -name '*.java') && \
|
||||||
|
jar cf /jsobject.jar -C /classes .
|
||||||
|
|
||||||
FROM ghcr.io/linuxserver/baseimage-selkies:debiantrixie
|
FROM ghcr.io/linuxserver/baseimage-selkies:debiantrixie
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
@@ -12,3 +18,4 @@ RUN apt-get update && \
|
|||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY root/ /
|
COPY root/ /
|
||||||
|
COPY --from=jsobject /jsobject.jar /opt/flashpoint/jsobject.jar
|
||||||
|
|||||||
@@ -33,3 +33,8 @@ different game, set `GAME_ID` and recreate the container. The launch log is at
|
|||||||
the game server, mounts the game's zip through the server's `mountzip` API, and
|
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.
|
runs the game's application with its HTTP proxy pointed at the game server.
|
||||||
Selkies restarts the game when it exits (`RESTART_APP`).
|
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.
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package netscape.javascript;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** A document whose cookie member behaves like document.cookie in a browser. */
|
||||||
|
class Document extends JSObject {
|
||||||
|
private final Map<String, String> cookies = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getMember(String name) throws JSException {
|
||||||
|
if (!name.equals("cookie")) {
|
||||||
|
return super.getMember(name);
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> cookie : cookies.entrySet()) {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append("; ");
|
||||||
|
}
|
||||||
|
sb.append(cookie.getKey()).append('=').append(cookie.getValue());
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMember(String name, Object value) throws JSException {
|
||||||
|
if (!name.equals("cookie")) {
|
||||||
|
super.setMember(name, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String pair = String.valueOf(value).split(";", 2)[0];
|
||||||
|
int eq = pair.indexOf('=');
|
||||||
|
if (eq > 0) {
|
||||||
|
cookies.put(pair.substring(0, eq).trim(), pair.substring(eq + 1).trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package netscape.javascript;
|
||||||
|
|
||||||
|
public class JSException extends RuntimeException {
|
||||||
|
public JSException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package netscape.javascript;
|
||||||
|
|
||||||
|
import java.applet.Applet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stand-in for the browser's LiveConnect bridge, which appletviewer lacks. The
|
||||||
|
* window holds a document with a working cookie; calls into JavaScript do nothing.
|
||||||
|
*/
|
||||||
|
public class JSObject {
|
||||||
|
private static JSObject window;
|
||||||
|
|
||||||
|
private final Map<String, Object> members = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
protected JSObject() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized JSObject getWindow(Applet applet) throws JSException {
|
||||||
|
if (window == null) {
|
||||||
|
window = new JSObject();
|
||||||
|
window.setMember("document", new Document());
|
||||||
|
}
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object call(String methodName, Object[] args) throws JSException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object eval(String s) throws JSException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getMember(String name) throws JSException {
|
||||||
|
return members.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMember(String name, Object value) throws JSException {
|
||||||
|
members.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMember(String name) throws JSException {
|
||||||
|
members.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getSlot(int index) throws JSException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSlot(int index, Object value) throws JSException {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
grant {
|
||||||
|
permission java.net.URLPermission "http:*", "*:*";
|
||||||
|
};
|
||||||
@@ -34,6 +34,8 @@ fi
|
|||||||
echo "Launching $ID: $app $cmd"
|
echo "Launching $ID: $app $cmd"
|
||||||
case ${app,,} in
|
case ${app,,} in
|
||||||
'fpsoftware\startjava.bat' | 'fpsoftware\startjavainbrowser.bat')
|
'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"
|
||||||
FP_PATH=$FP_PATH exec "$FP_PATH/FPSoftware/startJava.sh" "$cmd" ;;
|
FP_PATH=$FP_PATH exec "$FP_PATH/FPSoftware/startJava.sh" "$cmd" ;;
|
||||||
*)
|
*)
|
||||||
echo "Unsupported application: $app" >&2; exit 1 ;;
|
echo "Unsupported application: $app" >&2; exit 1 ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user