Forgot to fix TeaVM classes (compile)
This commit is contained in:
parent
d103637281
commit
b12fd7654f
6522
javascript/Eaglercraft_0.30_Offline_International.html
Normal file
6522
javascript/Eaglercraft_0.30_Offline_International.html
Normal file
File diff suppressed because one or more lines are too long
6522
javascript/Eaglercraft_0.30_Offline_en_US.html
Normal file
6522
javascript/Eaglercraft_0.30_Offline_en_US.html
Normal file
File diff suppressed because one or more lines are too long
BIN
javascript/assets.epk
Normal file
BIN
javascript/assets.epk
Normal file
Binary file not shown.
6437
javascript/classes.js
Normal file
6437
javascript/classes.js
Normal file
File diff suppressed because it is too large
Load Diff
1
javascript/classes.js.map
Normal file
1
javascript/classes.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -50,13 +50,13 @@ class OpenGLObjects {
|
||||
|
||||
}
|
||||
|
||||
static class BufferArrayGL implements IBufferArrayGL {
|
||||
static class VertexArrayGL implements IVertexArrayGL {
|
||||
|
||||
private static int hashGen = 0;
|
||||
final WebGLVertexArray ptr;
|
||||
final int hash;
|
||||
|
||||
BufferArrayGL(WebGLVertexArray ptr) {
|
||||
VertexArrayGL(WebGLVertexArray ptr) {
|
||||
this.ptr = ptr;
|
||||
this.hash = ++hashGen;
|
||||
}
|
||||
|
@ -31,11 +31,7 @@ import org.teavm.jso.dom.html.HTMLElement;
|
||||
import org.teavm.jso.dom.html.HTMLFormElement;
|
||||
import org.teavm.jso.dom.html.HTMLInputElement;
|
||||
import org.teavm.jso.dom.html.TextRectangle;
|
||||
import org.teavm.jso.gamepad.Gamepad;
|
||||
import org.teavm.jso.gamepad.GamepadButton;
|
||||
import org.teavm.jso.gamepad.GamepadEvent;
|
||||
|
||||
import net.lax1dude.eaglercraft.GamepadConstants;
|
||||
import net.lax1dude.eaglercraft.KeyboardConstants;
|
||||
import net.lax1dude.eaglercraft.internal.teavm.ClientMain;
|
||||
import net.lax1dude.eaglercraft.internal.teavm.EarlyLoadScreen;
|
||||
@ -74,8 +70,6 @@ public class PlatformInput {
|
||||
private static EventListener<?> touchend = null;
|
||||
private static EventListener<?> touchmove = null;
|
||||
private static EventListener<?> touchcancel = null;
|
||||
private static EventListener<?> gamepadconnected = null;
|
||||
private static EventListener<?> gamepaddisconnected = null;
|
||||
private static EventListener<?> keydown = null;
|
||||
private static EventListener<?> keyup = null;
|
||||
private static EventListener<?> wheel = null;
|
||||
@ -165,14 +159,6 @@ public class PlatformInput {
|
||||
public static int touchOffsetXTeaVM = 0;
|
||||
public static int touchOffsetYTeaVM = 0;
|
||||
|
||||
private static boolean gamepadSupported = false;
|
||||
private static final List<Gamepad> gamepadList = new ArrayList<>();
|
||||
private static Gamepad selectedGamepad = null;
|
||||
private static String selectedGamepadName = null;
|
||||
private static double gamepadTimestamp = -1.0;
|
||||
private static final boolean[] gamepadButtonStates = new boolean[24];
|
||||
private static final float[] gamepadAxisStates = new float[4];
|
||||
|
||||
private static int windowWidth = -1;
|
||||
private static int windowHeight = -1;
|
||||
private static float windowDPI = 1.0f;
|
||||
@ -617,32 +603,6 @@ public class PlatformInput {
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
try {
|
||||
gamepadSupported = gamepadSupported();
|
||||
if(gamepadSupported) {
|
||||
win.addEventListener("gamepadconnected", gamepadconnected = new EventListener<GamepadEvent>() {
|
||||
@Override
|
||||
public void handleEvent(GamepadEvent evt) {
|
||||
enumerateGamepads();
|
||||
}
|
||||
});
|
||||
win.addEventListener("gamepaddisconnected", gamepaddisconnected = new EventListener<GamepadEvent>() {
|
||||
@Override
|
||||
public void handleEvent(GamepadEvent evt) {
|
||||
if(selectedGamepad != null && evt.getGamepad().getIndex() == selectedGamepad.getIndex()) {
|
||||
selectedGamepad = null;
|
||||
}
|
||||
enumerateGamepads();
|
||||
}
|
||||
});
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
gamepadSupported = false;
|
||||
PlatformRuntime.logger.error("Gamepad detected as unsupported!");
|
||||
}
|
||||
|
||||
enumerateGamepads();
|
||||
}
|
||||
|
||||
@JSFunctor
|
||||
@ -1292,14 +1252,6 @@ public class PlatformInput {
|
||||
canvas.removeEventListener("mouseleave", mouseleave);
|
||||
mouseleave = null;
|
||||
}
|
||||
if(gamepadconnected != null) {
|
||||
win.removeEventListener("gamepadconnected", gamepadconnected);
|
||||
gamepadconnected = null;
|
||||
}
|
||||
if(gamepaddisconnected != null) {
|
||||
win.removeEventListener("gamepaddisconnected", gamepaddisconnected);
|
||||
gamepaddisconnected = null;
|
||||
}
|
||||
if(keydown != null) {
|
||||
win.removeEventListener("keydown", keydown);
|
||||
keydown = null;
|
||||
@ -1415,7 +1367,6 @@ public class PlatformInput {
|
||||
public static void clearEvenBuffers() {
|
||||
mouseEvents.clear();
|
||||
keyEvents.clear();
|
||||
net.lax1dude.eaglercraft.v1_8.Gamepad.clearEventBuffer();
|
||||
}
|
||||
|
||||
@JSBody(params = {}, script = "return window.matchMedia(\"(display-mode: fullscreen)\");")
|
||||
@ -1546,190 +1497,6 @@ public class PlatformInput {
|
||||
@JSBody(params = { "doc", "el" }, script = "return doc.activeElement === el;")
|
||||
private static native boolean isActiveElement(HTMLDocument doc, HTMLElement el);
|
||||
|
||||
private static void enumerateGamepads() {
|
||||
if(!gamepadSupported) return;
|
||||
if(selectedGamepad != null) {
|
||||
selectedGamepad = updateGamepad(selectedGamepad);
|
||||
if(selectedGamepad == null || !TeaVMUtils.isTruthy(selectedGamepad) || !selectedGamepad.isConnected()) {
|
||||
selectedGamepad = null;
|
||||
}
|
||||
}
|
||||
List<Gamepad> oldList = null;
|
||||
if(!gamepadList.isEmpty()) {
|
||||
oldList = new ArrayList<>(gamepadList);
|
||||
gamepadList.clear();
|
||||
}
|
||||
Gamepad[] gamepads = Navigator.getGamepads();
|
||||
if(gamepads != null && gamepads.length > 0) {
|
||||
for(int i = 0; i < gamepads.length; ++i) {
|
||||
Gamepad g = gamepads[i];
|
||||
if(TeaVMUtils.isTruthy(g) && g.isConnected() && "standard".equals(g.getMapping())) {
|
||||
gamepadList.add(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(selectedGamepad != null) {
|
||||
selectedGamepadName = selectedGamepad.getId();
|
||||
}
|
||||
if(oldList == null) {
|
||||
if(!gamepadList.isEmpty()) {
|
||||
for(int i = 0, l = gamepadList.size(); i < l; ++i) {
|
||||
PlatformRuntime.logger.info("Found controller: {}", gamepadList.get(i).getId());
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if(gamepadList.isEmpty()) {
|
||||
for(int i = 0, l = oldList.size(); i < l; ++i) {
|
||||
PlatformRuntime.logger.info("Lost controller: {}", oldList.get(i).getId());
|
||||
}
|
||||
}else {
|
||||
Map<String,Integer> oldDevCounts = new HashMap<>();
|
||||
for(Gamepad gg : oldList) {
|
||||
String s = gg.getId();
|
||||
Integer i = oldDevCounts.get(s);
|
||||
if(i != null) {
|
||||
oldDevCounts.put(s, Integer.valueOf(i.intValue() + 1));
|
||||
}else {
|
||||
oldDevCounts.put(s, Integer.valueOf(1));
|
||||
}
|
||||
}
|
||||
Map<String,Integer> newDevCounts = new HashMap<>();
|
||||
for(Gamepad gg : gamepadList) {
|
||||
String s = gg.getId();
|
||||
Integer i = newDevCounts.get(s);
|
||||
if(i != null) {
|
||||
newDevCounts.put(s, Integer.valueOf(i.intValue() + 1));
|
||||
}else {
|
||||
newDevCounts.put(s, Integer.valueOf(1));
|
||||
}
|
||||
}
|
||||
for(Entry<String,Integer> etr : oldDevCounts.entrySet()) {
|
||||
Integer i = newDevCounts.get(etr.getKey());
|
||||
if(i == null) {
|
||||
for(int j = 0, l = etr.getValue().intValue(); j < l; ++j) {
|
||||
PlatformRuntime.logger.info("Lost controller: {}", etr.getKey());
|
||||
}
|
||||
}else {
|
||||
int j = i.intValue();
|
||||
int k = etr.getValue().intValue();
|
||||
if(k != j) {
|
||||
if(k < j) {
|
||||
for(int m = 0, l = j - k; m < l; ++m) {
|
||||
PlatformRuntime.logger.info("Found controller: {}", etr.getKey());
|
||||
}
|
||||
}else {
|
||||
for(int m = 0, l = k - j; m < l; ++m) {
|
||||
PlatformRuntime.logger.info("Lost controller: {}", etr.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(Entry<String,Integer> etr : newDevCounts.entrySet()) {
|
||||
Integer i = oldDevCounts.get(etr.getKey());
|
||||
if(i == null) {
|
||||
for(int j = 0, l = etr.getValue().intValue(); j < l; ++j) {
|
||||
PlatformRuntime.logger.info("Found controller: {}", etr.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static int gamepadGetValidDeviceCount() {
|
||||
if(!gamepadSupported) return 0;
|
||||
return gamepadList.size();
|
||||
}
|
||||
|
||||
public static String gamepadGetDeviceName(int deviceId) {
|
||||
if(gamepadSupported && deviceId >= 0 && deviceId < gamepadList.size()) {
|
||||
return gamepadList.get(deviceId).getId();
|
||||
}else {
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public static void gamepadSetSelectedDevice(int deviceId) {
|
||||
if(!gamepadSupported) return;
|
||||
gamepadReset();
|
||||
if(deviceId >= 0 && deviceId < gamepadList.size()) {
|
||||
selectedGamepad = gamepadList.get(deviceId);
|
||||
gamepadTimestamp = -1.0;
|
||||
if(!TeaVMUtils.isTruthy(selectedGamepad) || !selectedGamepad.isConnected()) {
|
||||
selectedGamepad = null;
|
||||
}
|
||||
}else {
|
||||
selectedGamepad = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void gamepadReset() {
|
||||
for(int i = 0; i < gamepadButtonStates.length; ++i) {
|
||||
gamepadButtonStates[i] = false;
|
||||
}
|
||||
for(int i = 0; i < gamepadAxisStates.length; ++i) {
|
||||
gamepadAxisStates[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@JSBody(params = { }, script = "return (typeof navigator.getGamepads === \"function\");")
|
||||
private static native boolean gamepadSupported();
|
||||
|
||||
@JSBody(params = { "gp" }, script = "return navigator.getGamepads()[gp.index];")
|
||||
private static native Gamepad updateGamepad(Gamepad gp);
|
||||
|
||||
public static void gamepadUpdate() {
|
||||
if(!gamepadSupported) return;
|
||||
if(selectedGamepad != null) {
|
||||
selectedGamepad = updateGamepad(selectedGamepad);
|
||||
if(selectedGamepad == null || !TeaVMUtils.isTruthy(selectedGamepad) || !selectedGamepad.isConnected()) {
|
||||
gamepadReset();
|
||||
selectedGamepad = null;
|
||||
return;
|
||||
}
|
||||
double ts = selectedGamepad.getTimestamp();
|
||||
if(ts != gamepadTimestamp) {
|
||||
gamepadTimestamp = ts;
|
||||
gamepadReset();
|
||||
GamepadButton[] btns = selectedGamepad.getButtons();
|
||||
for(int i = 0; i < btns.length; ++i) {
|
||||
int j = GamepadConstants.getEaglerButtonFromBrowser(i);
|
||||
if(j >= 0 && j < gamepadButtonStates.length) {
|
||||
gamepadButtonStates[j] = btns[i].isPressed();
|
||||
}
|
||||
}
|
||||
double[] axes = selectedGamepad.getAxes();
|
||||
for(int i = 0; i < axes.length; ++i) {
|
||||
if(i >= 4) {
|
||||
break;
|
||||
}
|
||||
gamepadAxisStates[i] = (float)axes[i];
|
||||
}
|
||||
}
|
||||
}else {
|
||||
gamepadReset();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean gamepadIsValid() {
|
||||
if(!gamepadSupported) return false;
|
||||
return selectedGamepad != null;
|
||||
}
|
||||
|
||||
public static String gamepadGetName() {
|
||||
return gamepadSupported && selectedGamepad != null ? selectedGamepadName : "Unknown";
|
||||
}
|
||||
|
||||
public static boolean gamepadGetButtonState(int button) {
|
||||
return gamepadSupported && selectedGamepad != null && button >= 0 && button < gamepadButtonStates.length ? gamepadButtonStates[button] : false;
|
||||
}
|
||||
|
||||
public static float gamepadGetAxis(int axis) {
|
||||
return gamepadSupported && selectedGamepad != null && axis >= 0 && axis < gamepadAxisStates.length ? gamepadAxisStates[axis] : 0.0f;
|
||||
}
|
||||
|
||||
public static float getDPI() {
|
||||
return windowDPI;
|
||||
}
|
||||
|
@ -1,26 +1,12 @@
|
||||
package net.lax1dude.eaglercraft.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.teavm.interop.Async;
|
||||
import org.teavm.interop.AsyncCallback;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.dom.events.Event;
|
||||
import org.teavm.jso.dom.events.EventListener;
|
||||
import org.teavm.jso.dom.events.MessageEvent;
|
||||
import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||
import org.teavm.jso.websocket.WebSocket;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.teavm.TeaVMServerQuery;
|
||||
import net.lax1dude.eaglercraft.internal.teavm.TeaVMUtils;
|
||||
import net.lax1dude.eaglercraft.internal.teavm.TeaVMWebSocketClient;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
@ -36,169 +22,20 @@ import net.lax1dude.eaglercraft.internal.teavm.TeaVMUtils;
|
||||
*/
|
||||
public class PlatformNetworking {
|
||||
|
||||
private static WebSocket sock = null;
|
||||
private static boolean sockIsConnecting = false;
|
||||
private static boolean sockIsConnected = false;
|
||||
private static boolean sockIsAlive = false;
|
||||
private static boolean sockIsFailed = false;
|
||||
private static LinkedList<byte[]> readPackets = new LinkedList();
|
||||
private static String currentSockURI = null;
|
||||
private static EnumServerRateLimit serverRateLimit = null;
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("PlatformNetworking");
|
||||
|
||||
public static EnumEaglerConnectionState playConnectionState() {
|
||||
return !sockIsConnected ? (sockIsFailed ? EnumEaglerConnectionState.FAILED : EnumEaglerConnectionState.CLOSED)
|
||||
: (sockIsConnecting ? EnumEaglerConnectionState.CONNECTING : EnumEaglerConnectionState.CONNECTED);
|
||||
}
|
||||
|
||||
public static void startPlayConnection(String destination) {
|
||||
sockIsFailed = !connectWebSocket(destination).booleanValue();
|
||||
}
|
||||
|
||||
@JSBody(params = { "obj" }, script = "return typeof obj === \"string\";")
|
||||
private static native boolean isString(JSObject obj);
|
||||
|
||||
@Async
|
||||
public static native Boolean connectWebSocket(String sockURI);
|
||||
|
||||
private static void connectWebSocket(String sockURI, final AsyncCallback<Boolean> cb) {
|
||||
sockIsConnecting = true;
|
||||
sockIsConnected = false;
|
||||
sockIsAlive = false;
|
||||
currentSockURI = sockURI;
|
||||
public static IWebSocketClient openWebSocket(String socketURI) {
|
||||
try {
|
||||
sock = WebSocket.create(sockURI);
|
||||
} catch(Throwable t) {
|
||||
sockIsFailed = true;
|
||||
sockIsConnecting = false;
|
||||
sockIsAlive = false;
|
||||
cb.complete(Boolean.FALSE);
|
||||
return;
|
||||
}
|
||||
final WebSocket oldSock = sock;
|
||||
sock.setBinaryType("arraybuffer");
|
||||
TeaVMUtils.addEventListener(sock, "open", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
if (oldSock != sock) return;
|
||||
sockIsConnecting = false;
|
||||
sockIsAlive = false;
|
||||
sockIsConnected = true;
|
||||
synchronized(readPackets) {
|
||||
readPackets.clear();
|
||||
}
|
||||
cb.complete(Boolean.TRUE);
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "close", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
if (oldSock != sock) return;
|
||||
sock = null;
|
||||
boolean b = sockIsConnecting;
|
||||
sockIsConnecting = false;
|
||||
sockIsConnected = false;
|
||||
sockIsAlive = false;
|
||||
if(b) cb.complete(Boolean.FALSE);
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "message", new EventListener<MessageEvent>() {
|
||||
@Override
|
||||
public void handleEvent(MessageEvent evt) {
|
||||
if (oldSock != sock) return;
|
||||
sockIsAlive = true;
|
||||
if(isString(evt.getData())) {
|
||||
String str = evt.getDataAsString();
|
||||
if(str.equalsIgnoreCase("BLOCKED")) {
|
||||
logger.error("Reached full IP ratelimit!");
|
||||
serverRateLimit = EnumServerRateLimit.BLOCKED;
|
||||
}else if(str.equalsIgnoreCase("LOCKED")) {
|
||||
logger.error("Reached full IP ratelimit lockout!");
|
||||
serverRateLimit = EnumServerRateLimit.LOCKED_OUT;
|
||||
}
|
||||
}else {
|
||||
synchronized(readPackets) {
|
||||
readPackets.add(TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "error", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
if (oldSock != sock) return;
|
||||
if(sockIsConnecting) {
|
||||
sockIsFailed = true;
|
||||
sockIsConnecting = false;
|
||||
sockIsAlive = false;
|
||||
cb.complete(Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void playDisconnect() {
|
||||
if(sock != null) sock.close();
|
||||
sockIsConnecting = false;
|
||||
}
|
||||
|
||||
public static byte[] readPlayPacket() {
|
||||
synchronized(readPackets) {
|
||||
if(!readPackets.isEmpty()) {
|
||||
return readPackets.remove(0);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<byte[]> readAllPacket() {
|
||||
synchronized(readPackets) {
|
||||
if(!readPackets.isEmpty()) {
|
||||
List<byte[]> ret = new ArrayList<>(readPackets);
|
||||
readPackets.clear();
|
||||
return ret;
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int countAvailableReadData() {
|
||||
int total = 0;
|
||||
synchronized(readPackets) {
|
||||
for(int i = 0, l = readPackets.size(); i < l; ++i) {
|
||||
total += readPackets.get(i).length;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@JSBody(params = { "sock", "buffer" }, script = "sock.send(buffer);")
|
||||
protected static native void nativeBinarySend(WebSocket sock, ArrayBuffer buffer);
|
||||
|
||||
public static void writePlayPacket(byte[] pkt) {
|
||||
if(sock != null && !sockIsConnecting) {
|
||||
nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer(pkt));
|
||||
}
|
||||
}
|
||||
|
||||
public static IServerQuery sendServerQuery(String uri, String accept) {
|
||||
try {
|
||||
return new TeaVMServerQuery(uri, accept);
|
||||
return new TeaVMWebSocketClient(socketURI);
|
||||
}catch(Throwable t) {
|
||||
logger.error("Could not send query to \"{}\"!", uri);
|
||||
logger.error("Could not open WebSocket to \"{}\"!", socketURI);
|
||||
logger.error(t);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static EnumServerRateLimit getRateLimit() {
|
||||
return serverRateLimit == null ? EnumServerRateLimit.OK : serverRateLimit;
|
||||
}
|
||||
|
||||
public static String getCurrentURI() {
|
||||
return currentSockURI;
|
||||
|
||||
public static IWebSocketClient openWebSocketUnsafe(String socketURI) {
|
||||
return new TeaVMWebSocketClient(socketURI);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -278,12 +278,12 @@ public class PlatformOpenGL {
|
||||
return new OpenGLObjects.TextureGL(ctx.createTexture());
|
||||
}
|
||||
|
||||
public static final IBufferArrayGL _wglGenVertexArrays() {
|
||||
public static final IVertexArrayGL _wglGenVertexArrays() {
|
||||
switch(vertexArrayImpl) {
|
||||
case VAO_IMPL_CORE:
|
||||
return new OpenGLObjects.BufferArrayGL(ctx.createVertexArray());
|
||||
return new OpenGLObjects.VertexArrayGL(ctx.createVertexArray());
|
||||
case VAO_IMPL_OES:
|
||||
return new OpenGLObjects.BufferArrayGL(OESVertexArrayObject.createVertexArrayOES());
|
||||
return new OpenGLObjects.VertexArrayGL(OESVertexArrayObject.createVertexArrayOES());
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@ -317,8 +317,8 @@ public class PlatformOpenGL {
|
||||
ctx.deleteTexture(((OpenGLObjects.TextureGL)obj).ptr);
|
||||
}
|
||||
|
||||
public static final void _wglDeleteVertexArrays(IBufferArrayGL obj) {
|
||||
WebGLVertexArray ptr = ((OpenGLObjects.BufferArrayGL)obj).ptr;
|
||||
public static final void _wglDeleteVertexArrays(IVertexArrayGL obj) {
|
||||
WebGLVertexArray ptr = ((OpenGLObjects.VertexArrayGL)obj).ptr;
|
||||
switch(vertexArrayImpl) {
|
||||
case VAO_IMPL_CORE:
|
||||
ctx.deleteVertexArray(ptr);
|
||||
@ -383,8 +383,8 @@ public class PlatformOpenGL {
|
||||
ctx.bufferSubData(target, offset, EaglerArrayBufferAllocator.getDataView32F(data));
|
||||
}
|
||||
|
||||
public static final void _wglBindVertexArray(IBufferArrayGL obj) {
|
||||
WebGLVertexArray ptr = obj != null ? ((OpenGLObjects.BufferArrayGL)obj).ptr : null;
|
||||
public static final void _wglBindVertexArray(IVertexArrayGL obj) {
|
||||
WebGLVertexArray ptr = obj != null ? ((OpenGLObjects.VertexArrayGL)obj).ptr : null;
|
||||
switch(vertexArrayImpl) {
|
||||
case VAO_IMPL_CORE:
|
||||
ctx.bindVertexArray(ptr);
|
||||
|
@ -3,6 +3,7 @@ package net.lax1dude.eaglercraft.internal;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -42,9 +43,6 @@ import org.teavm.jso.webgl.WebGLFramebuffer;
|
||||
import org.teavm.platform.Platform;
|
||||
import org.teavm.platform.PlatformRunnable;
|
||||
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.jcraft.jzlib.Deflater;
|
||||
import com.jcraft.jzlib.DeflaterOutputStream;
|
||||
import com.jcraft.jzlib.GZIPInputStream;
|
||||
@ -212,7 +210,11 @@ public class PlatformRuntime {
|
||||
if(viewportTag != null) {
|
||||
String cont = viewportTag.getAttribute("content");
|
||||
if(cont != null) {
|
||||
Set<String> oldTokens = Sets.newHashSet(Iterators.transform(Iterators.forArray(cont.split(",")), String::trim));
|
||||
String[] oldTokenArray = cont.split(",");
|
||||
Set<String> oldTokens = new HashSet<>();
|
||||
for (String token : oldTokenArray) {
|
||||
oldTokens.add(token.trim());
|
||||
}
|
||||
Set<String> tokens = new HashSet<>();
|
||||
for(String str : oldTokens) {
|
||||
if (!(str.startsWith("width=") || str.startsWith("initial-scale=")
|
||||
@ -475,7 +477,11 @@ public class PlatformRuntime {
|
||||
|
||||
private static void dumpShims(Set<EnumES6Shims> shims) {
|
||||
if(!shims.isEmpty()) {
|
||||
logger.info("(Enabled {} shims: {})", shims.size(), String.join(", ", Collections2.transform(shims, (shim) -> shim.shimDesc)));
|
||||
List<String> descriptions = new ArrayList<>();
|
||||
for (EnumES6Shims shim : shims) {
|
||||
descriptions.add(shim.shimDesc);
|
||||
}
|
||||
logger.info("(Enabled {} shims: {})", shims.size(), String.join(", ", descriptions));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,14 +275,6 @@ public class EaglerArrayByteBuffer extends ByteBuffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putDouble(double value) {
|
||||
if(position + 8 > limit) throw Buffer.makeIOOBE(position);
|
||||
dataView.setFloat64(position, value, true);
|
||||
position += 8;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int index) {
|
||||
if(index < 0 || index + 4 > limit) throw Buffer.makeIOOBE(index);
|
||||
@ -340,14 +332,6 @@ public class EaglerArrayByteBuffer extends ByteBuffer {
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble() {
|
||||
if(position + 8 > limit) throw Buffer.makeIOOBE(position);
|
||||
double f = dataView.getFloat64(position, true);
|
||||
position += 8;
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putFloat(float value) {
|
||||
if(position + 4 > limit) throw Buffer.makeIOOBE(position);
|
||||
@ -424,9 +408,4 @@ public class EaglerArrayByteBuffer extends ByteBuffer {
|
||||
position = newPosition;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer compact() {
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.jso.dom.html.HTMLIFrameElement;
|
||||
import org.teavm.jso.dom.types.DOMTokenList;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public abstract class AdvancedHTMLIFrameElement implements HTMLIFrameElement {
|
||||
|
||||
@JSProperty
|
||||
public abstract void setAllow(String str);
|
||||
|
||||
@JSProperty
|
||||
public abstract String getAllow();
|
||||
|
||||
public void setAllowSafe(String requiredValue) {
|
||||
setAllow(requiredValue);
|
||||
if(!requiredValue.equals(getAllow())) {
|
||||
throw new IFrameSafetyException("Could not set allow attribute to: " + requiredValue);
|
||||
}
|
||||
}
|
||||
|
||||
@JSProperty
|
||||
public abstract void setAllowFullscreen(boolean en);
|
||||
|
||||
@JSProperty
|
||||
public abstract void setCredentialless(boolean en);
|
||||
|
||||
@JSProperty
|
||||
public abstract void setLoading(String str);
|
||||
|
||||
@JSProperty
|
||||
public abstract void setReferrerPolicy(String str);
|
||||
|
||||
@JSProperty("csp")
|
||||
public abstract void setCSP(String str);
|
||||
|
||||
@JSProperty
|
||||
public abstract void setSandbox(String str);
|
||||
|
||||
@JSProperty
|
||||
public abstract DOMTokenList getSandbox();
|
||||
|
||||
public void assertSafetyFeaturesSupported() {
|
||||
if(!checkSafetyFeaturesSupported()) {
|
||||
throw new IFrameSafetyException("Some required security features are not supported on this browser!");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSandboxSafe(Collection<String> requiredTokens) {
|
||||
setSandboxSafe(new HashSet<>(requiredTokens));
|
||||
}
|
||||
|
||||
public void setSandboxSafe(Set<String> requiredTokens) {
|
||||
setSandbox(String.join(" ", requiredTokens));
|
||||
DOMTokenList theSandbox = getSandbox();
|
||||
for(String s : requiredTokens) {
|
||||
if(!theSandbox.contains(s)) {
|
||||
throw new IFrameSafetyException("Failed to set sandbox attribute: " + s);
|
||||
}
|
||||
}
|
||||
int l = theSandbox.getLength();
|
||||
for(int i = 0; i < l; ++i) {
|
||||
String s = theSandbox.item(i);
|
||||
if(!requiredTokens.contains(s)) {
|
||||
throw new IFrameSafetyException("Unknown sandbox attribute detected: " + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSandboxSafe(Collection<String> requiredTokens, Collection<String> optionalTokens) {
|
||||
setSandboxSafe(new HashSet<>(requiredTokens), new HashSet<>(optionalTokens));
|
||||
}
|
||||
|
||||
public void setSandboxSafe(Set<String> requiredTokens, Set<String> optionalTokens) {
|
||||
setSandbox(StringUtils.join(Iterators.concat(requiredTokens.iterator(), optionalTokens.iterator()), " "));
|
||||
DOMTokenList theSandbox = getSandbox();
|
||||
for(String s : requiredTokens) {
|
||||
if(!theSandbox.contains(s)) {
|
||||
throw new IFrameSafetyException("Failed to set sandbox attribute: " + s);
|
||||
}
|
||||
}
|
||||
int l = theSandbox.getLength();
|
||||
for(int i = 0; i < l; ++i) {
|
||||
String s = theSandbox.item(i);
|
||||
if(!requiredTokens.contains(s) && !optionalTokens.contains(s)) {
|
||||
throw new IFrameSafetyException("Unknown sandbox attribute detected: " + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JSBody(params = {}, script = "return (typeof this.allow === \"string\") && (typeof this.sandbox === \"object\");")
|
||||
public native boolean checkSafetyFeaturesSupported();
|
||||
|
||||
@JSBody(params = {}, script = "return (typeof this.csp === \"string\");")
|
||||
public native boolean checkCSPSupported();
|
||||
|
||||
}
|
@ -6,7 +6,7 @@ import net.lax1dude.eaglercraft.opengl.ImageData;
|
||||
import static net.lax1dude.eaglercraft.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.IBufferArrayGL;
|
||||
import net.lax1dude.eaglercraft.internal.IVertexArrayGL;
|
||||
import net.lax1dude.eaglercraft.internal.IBufferGL;
|
||||
import net.lax1dude.eaglercraft.internal.IProgramGL;
|
||||
import net.lax1dude.eaglercraft.internal.IShaderGL;
|
||||
@ -151,7 +151,7 @@ public class EarlyLoadScreen {
|
||||
_wglUseProgram(program);
|
||||
_wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y);
|
||||
|
||||
IBufferArrayGL vao = null;
|
||||
IVertexArrayGL vao = null;
|
||||
if(vaos) {
|
||||
vao = _wglGenVertexArrays();
|
||||
_wglBindVertexArray(vao);
|
||||
@ -213,7 +213,7 @@ public class EarlyLoadScreen {
|
||||
|
||||
_wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y);
|
||||
|
||||
IBufferArrayGL vao = null;
|
||||
IVertexArrayGL vao = null;
|
||||
if(vaos) {
|
||||
vao = _wglGenVertexArrays();
|
||||
_wglBindVertexArray(vao);
|
||||
@ -283,11 +283,11 @@ public class EarlyLoadScreen {
|
||||
|
||||
_wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y);
|
||||
|
||||
IBufferArrayGL vao = null;
|
||||
IVertexArrayGL vao = null;
|
||||
if(vaos) {
|
||||
if(softVAOs) {
|
||||
vao = EaglercraftGPU.createGLBufferArray();
|
||||
EaglercraftGPU.bindGLBufferArray(vao);
|
||||
vao = EaglercraftGPU.createGLVertexArray();
|
||||
EaglercraftGPU.bindGLVertexArray(vao);
|
||||
}else {
|
||||
vao = _wglGenVertexArrays();
|
||||
_wglBindVertexArray(vao);
|
||||
@ -297,7 +297,7 @@ public class EarlyLoadScreen {
|
||||
EaglercraftGPU.bindVAOGLArrayBuffer(vbo);
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
|
||||
EaglercraftGPU.doDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
EaglercraftGPU.drawArrays(GL_TRIANGLES, 0, 6);
|
||||
}else {
|
||||
_wglBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
_wglEnableVertexAttribArray(0);
|
||||
@ -322,7 +322,7 @@ public class EarlyLoadScreen {
|
||||
}
|
||||
if(vaos) {
|
||||
if(softVAOs) {
|
||||
EaglercraftGPU.destroyGLBufferArray(vao);
|
||||
EaglercraftGPU.destroyGLVertexArray(vao);
|
||||
}else {
|
||||
_wglDeleteVertexArrays(vao);
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
@ -51,9 +51,15 @@ public class LegacyKeycodeTranslator {
|
||||
|
||||
}
|
||||
|
||||
private static final Set<String> numpadVolatile = Sets.newHashSet(
|
||||
private static final Set<String> numpadVolatile = newHashSet(
|
||||
"Comma", "Minus", "Period", "Slash", "Equal", "Enter", "Digit0", "Digit1", "Digit2", "Digit3",
|
||||
"Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "IntlYen");
|
||||
|
||||
public static <E extends Object> HashSet<E> newHashSet(E... elements) {
|
||||
HashSet<E> set = new HashSet<E>(elements.length);
|
||||
Collections.addAll(set, elements);
|
||||
return set;
|
||||
}
|
||||
|
||||
private final Map<String,LegacyKeycode> codeLookupBase = new HashMap<>();
|
||||
private final Map<String,LegacyKeycode> codeLookupLayout = new HashMap<>();
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import net.lax1dude.eaglercraft.EaglercraftVersion;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.teavm.jso.JSObject;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.IClientConfigAdapter;
|
||||
@ -32,30 +34,12 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
||||
private String serverToJoin = null;
|
||||
private String worldsDB = "worlds";
|
||||
private String resourcePacksDB = "resourcePacks";
|
||||
private JSONObject integratedServerOpts;
|
||||
private boolean checkGLErrors = false;
|
||||
private boolean checkShaderGLErrors = false;
|
||||
private boolean demoMode = EaglercraftVersion.forceDemoMode;
|
||||
private boolean isEnableDownloadOfflineButton = true;
|
||||
private String downloadOfflineButtonLink = null;
|
||||
private boolean useSpecialCursors = false;
|
||||
private boolean allowVoiceClient = true;
|
||||
private boolean allowFNAWSkins = true;
|
||||
private String localStorageNamespace = "_eaglercraftX";
|
||||
private final TeaVMClientConfigAdapterHooks hooks = new TeaVMClientConfigAdapterHooks();
|
||||
private boolean enableMinceraft = true;
|
||||
private boolean enableServerCookies = true;
|
||||
private boolean allowServerRedirects = true;
|
||||
private boolean crashOnUncaughtExceptions = false;
|
||||
private boolean openDebugConsoleOnLaunch = false;
|
||||
private boolean fixDebugConsoleUnloadListener = false;
|
||||
private boolean forceWebViewSupport = false;
|
||||
private boolean enableWebViewCSP = true;
|
||||
private boolean autoFixLegacyStyleAttr = false;
|
||||
private boolean showBootMenuOnLaunch = false;
|
||||
private boolean bootMenuBlocksUnsignedClients = false;
|
||||
private boolean allowBootMenu = true;
|
||||
private boolean forceProfanityFilter = false;
|
||||
private boolean forceWebGL1 = false;
|
||||
private boolean forceWebGL2 = false;
|
||||
private boolean allowExperimentalWebGL1 = true;
|
||||
@ -72,7 +56,6 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
||||
private boolean enableEPKVersionCheck = true;
|
||||
|
||||
public void loadNative(JSObject jsObject) {
|
||||
integratedServerOpts = new JSONObject();
|
||||
JSEaglercraftXOptsRoot eaglercraftXOpts = (JSEaglercraftXOptsRoot)jsObject;
|
||||
|
||||
defaultLocale = eaglercraftXOpts.getLang("en_US");
|
||||
@ -80,27 +63,10 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
||||
worldsDB = eaglercraftXOpts.getWorldsDB("worlds");
|
||||
resourcePacksDB = eaglercraftXOpts.getResourcePacksDB("resourcePacks");
|
||||
checkGLErrors = eaglercraftXOpts.getCheckGLErrors(false);
|
||||
checkShaderGLErrors = eaglercraftXOpts.getCheckShaderGLErrors(false);
|
||||
demoMode = EaglercraftVersion.forceDemoMode || eaglercraftXOpts.getDemoMode(false);
|
||||
isEnableDownloadOfflineButton = eaglercraftXOpts.getEnableDownloadOfflineButton(true);
|
||||
downloadOfflineButtonLink = eaglercraftXOpts.getDownloadOfflineButtonLink(null);
|
||||
useSpecialCursors = eaglercraftXOpts.getHtml5CursorSupport(false);
|
||||
allowVoiceClient = eaglercraftXOpts.getAllowVoiceClient(true);
|
||||
allowFNAWSkins = !demoMode && eaglercraftXOpts.getAllowFNAWSkins(true);
|
||||
localStorageNamespace = eaglercraftXOpts.getLocalStorageNamespace(EaglercraftVersion.localStorageNamespace);
|
||||
enableMinceraft = eaglercraftXOpts.getEnableMinceraft(true);
|
||||
enableServerCookies = !demoMode && eaglercraftXOpts.getEnableServerCookies(true);
|
||||
allowServerRedirects = eaglercraftXOpts.getAllowServerRedirects(true);
|
||||
crashOnUncaughtExceptions = eaglercraftXOpts.getCrashOnUncaughtExceptions(false);
|
||||
openDebugConsoleOnLaunch = eaglercraftXOpts.getOpenDebugConsoleOnLaunch(false);
|
||||
fixDebugConsoleUnloadListener = eaglercraftXOpts.getFixDebugConsoleUnloadListener(false);
|
||||
forceWebViewSupport = eaglercraftXOpts.getForceWebViewSupport(false);
|
||||
enableWebViewCSP = eaglercraftXOpts.getEnableWebViewCSP(true);
|
||||
autoFixLegacyStyleAttr = eaglercraftXOpts.getAutoFixLegacyStyleAttr(true);
|
||||
showBootMenuOnLaunch = eaglercraftXOpts.getShowBootMenuOnLaunch(false);
|
||||
bootMenuBlocksUnsignedClients = eaglercraftXOpts.getBootMenuBlocksUnsignedClients(false);
|
||||
allowBootMenu = eaglercraftXOpts.getAllowBootMenu(!demoMode);
|
||||
forceProfanityFilter = eaglercraftXOpts.getForceProfanityFilter(false);
|
||||
forceWebGL1 = eaglercraftXOpts.getForceWebGL1(false);
|
||||
forceWebGL2 = eaglercraftXOpts.getForceWebGL2(false);
|
||||
allowExperimentalWebGL1 = eaglercraftXOpts.getAllowExperimentalWebGL1(true);
|
||||
@ -119,65 +85,6 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
||||
if(hooksObj != null) {
|
||||
hooks.loadHooks(hooksObj);
|
||||
}
|
||||
|
||||
integratedServerOpts.put("worldsDB", worldsDB);
|
||||
integratedServerOpts.put("demoMode", demoMode);
|
||||
integratedServerOpts.put("lang", defaultLocale);
|
||||
integratedServerOpts.put("allowVoiceClient", allowVoiceClient);
|
||||
integratedServerOpts.put("allowFNAWSkins", allowFNAWSkins);
|
||||
integratedServerOpts.put("crashOnUncaughtExceptions", crashOnUncaughtExceptions);
|
||||
integratedServerOpts.put("deobfStackTraces", deobfStackTraces);
|
||||
integratedServerOpts.put("disableBlobURLs", disableBlobURLs);
|
||||
integratedServerOpts.put("eaglerNoDelay", eaglerNoDelay);
|
||||
integratedServerOpts.put("ramdiskMode", ramdiskMode);
|
||||
integratedServerOpts.put("singleThreadMode", singleThreadMode);
|
||||
}
|
||||
|
||||
public void loadJSON(JSONObject eaglercraftOpts) {
|
||||
integratedServerOpts = eaglercraftOpts;
|
||||
defaultLocale = eaglercraftOpts.optString("lang", "en_US");
|
||||
serverToJoin = eaglercraftOpts.optString("joinServer", null);
|
||||
worldsDB = eaglercraftOpts.optString("worldsDB", "worlds");
|
||||
resourcePacksDB = eaglercraftOpts.optString("resourcePacksDB", "resourcePacks");
|
||||
checkGLErrors = eaglercraftOpts.optBoolean("checkGLErrors", false);
|
||||
checkShaderGLErrors = eaglercraftOpts.optBoolean("checkShaderGLErrors", false);
|
||||
if(EaglercraftVersion.forceDemoMode) {
|
||||
eaglercraftOpts.put("demoMode", true);
|
||||
}
|
||||
demoMode = EaglercraftVersion.forceDemoMode || eaglercraftOpts.optBoolean("demoMode", false);
|
||||
isEnableDownloadOfflineButton = eaglercraftOpts.optBoolean("enableDownloadOfflineButton", true);
|
||||
downloadOfflineButtonLink = eaglercraftOpts.optString("downloadOfflineButtonLink", null);
|
||||
useSpecialCursors = eaglercraftOpts.optBoolean("html5CursorSupport", false);
|
||||
allowVoiceClient = eaglercraftOpts.optBoolean("allowVoiceClient", true);
|
||||
allowFNAWSkins = eaglercraftOpts.optBoolean("allowFNAWSkins", true);
|
||||
localStorageNamespace = eaglercraftOpts.optString("localStorageNamespace", EaglercraftVersion.localStorageNamespace);
|
||||
enableMinceraft = eaglercraftOpts.optBoolean("enableMinceraft", true);
|
||||
enableServerCookies = !demoMode && eaglercraftOpts.optBoolean("enableServerCookies", true);
|
||||
allowServerRedirects = eaglercraftOpts.optBoolean("allowServerRedirects", true);
|
||||
crashOnUncaughtExceptions = eaglercraftOpts.optBoolean("crashOnUncaughtExceptions", false);
|
||||
openDebugConsoleOnLaunch = eaglercraftOpts.optBoolean("openDebugConsoleOnLaunch", false);
|
||||
fixDebugConsoleUnloadListener = eaglercraftOpts.optBoolean("fixDebugConsoleUnloadListener", false);
|
||||
forceWebViewSupport = eaglercraftOpts.optBoolean("forceWebViewSupport", false);
|
||||
enableWebViewCSP = eaglercraftOpts.optBoolean("enableWebViewCSP", true);
|
||||
autoFixLegacyStyleAttr = eaglercraftOpts.optBoolean("autoFixLegacyStyleAttr", true);
|
||||
showBootMenuOnLaunch = eaglercraftOpts.optBoolean("showBootMenuOnLaunch", false);
|
||||
bootMenuBlocksUnsignedClients = eaglercraftOpts.optBoolean("bootMenuBlocksUnsignedClients", false);
|
||||
allowBootMenu = eaglercraftOpts.optBoolean("allowBootMenu", !demoMode);
|
||||
forceProfanityFilter = eaglercraftOpts.optBoolean("forceProfanityFilter", false);
|
||||
forceWebGL1 = eaglercraftOpts.optBoolean("forceWebGL1", false);
|
||||
forceWebGL2 = eaglercraftOpts.optBoolean("forceWebGL2", false);
|
||||
allowExperimentalWebGL1 = eaglercraftOpts.optBoolean("allowExperimentalWebGL1", true);
|
||||
useWebGLExt = eaglercraftOpts.optBoolean("useWebGLExt", true);
|
||||
useDelayOnSwap = eaglercraftOpts.optBoolean("useDelayOnSwap", false);
|
||||
useJOrbisAudioDecoder = eaglercraftOpts.optBoolean("useJOrbisAudioDecoder", false);
|
||||
useXHRFetch = eaglercraftOpts.optBoolean("useXHRFetch", false);
|
||||
useVisualViewport = eaglercraftOpts.optBoolean("useVisualViewport", true);
|
||||
deobfStackTraces = eaglercraftOpts.optBoolean("deobfStackTraces", true);
|
||||
disableBlobURLs = eaglercraftOpts.optBoolean("disableBlobURLs", false);
|
||||
eaglerNoDelay = eaglercraftOpts.optBoolean("eaglerNoDelay", false);
|
||||
ramdiskMode = eaglercraftOpts.optBoolean("ramdiskMode", false);
|
||||
singleThreadMode = eaglercraftOpts.optBoolean("singleThreadMode", false);
|
||||
enableEPKVersionCheck = eaglercraftOpts.optBoolean("enableEPKVersionCheck", true);
|
||||
}
|
||||
|
||||
public String getDefaultLocale() {
|
||||
@ -280,58 +187,133 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
||||
return hooks;
|
||||
}
|
||||
|
||||
public JSONObject toJSONObject() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("lang", defaultLocale);
|
||||
jsonObject.put("joinServer", serverToJoin);
|
||||
jsonObject.put("worldsDB", worldsDB);
|
||||
jsonObject.put("resourcePacksDB", resourcePacksDB);
|
||||
jsonObject.put("checkGLErrors", checkGLErrors);
|
||||
jsonObject.put("checkShaderGLErrors", checkShaderGLErrors);
|
||||
jsonObject.put("demoMode", demoMode);
|
||||
jsonObject.put("enableDownloadOfflineButton", isEnableDownloadOfflineButton);
|
||||
jsonObject.put("downloadOfflineButtonLink", downloadOfflineButtonLink);
|
||||
jsonObject.put("html5CursorSupport", useSpecialCursors);
|
||||
jsonObject.put("allowVoiceClient", allowVoiceClient);
|
||||
jsonObject.put("allowFNAWSkins", allowFNAWSkins);
|
||||
jsonObject.put("localStorageNamespace", localStorageNamespace);
|
||||
jsonObject.put("enableMinceraft", enableMinceraft);
|
||||
jsonObject.put("enableServerCookies", enableServerCookies);
|
||||
jsonObject.put("allowServerRedirects", allowServerRedirects);
|
||||
jsonObject.put("crashOnUncaughtExceptions", crashOnUncaughtExceptions);
|
||||
jsonObject.put("openDebugConsoleOnLaunch", openDebugConsoleOnLaunch);
|
||||
jsonObject.put("fixDebugConsoleUnloadListener", fixDebugConsoleUnloadListener);
|
||||
jsonObject.put("forceWebViewSupport", forceWebViewSupport);
|
||||
jsonObject.put("enableWebViewCSP", enableWebViewCSP);
|
||||
jsonObject.put("autoFixLegacyStyleAttr", autoFixLegacyStyleAttr);
|
||||
jsonObject.put("showBootMenuOnLaunch", showBootMenuOnLaunch);
|
||||
jsonObject.put("bootMenuBlocksUnsignedClients", bootMenuBlocksUnsignedClients);
|
||||
jsonObject.put("allowBootMenu", allowBootMenu);
|
||||
jsonObject.put("forceProfanityFilter", forceProfanityFilter);
|
||||
jsonObject.put("forceWebGL1", forceWebGL1);
|
||||
jsonObject.put("forceWebGL2", forceWebGL2);
|
||||
jsonObject.put("allowExperimentalWebGL1", allowExperimentalWebGL1);
|
||||
jsonObject.put("useWebGLExt", useWebGLExt);
|
||||
jsonObject.put("useDelayOnSwap", useDelayOnSwap);
|
||||
jsonObject.put("useJOrbisAudioDecoder", useJOrbisAudioDecoder);
|
||||
jsonObject.put("useXHRFetch", useXHRFetch);
|
||||
jsonObject.put("useVisualViewport", useVisualViewport);
|
||||
jsonObject.put("deobfStackTraces", deobfStackTraces);
|
||||
jsonObject.put("disableBlobURLs", disableBlobURLs);
|
||||
jsonObject.put("eaglerNoDelay", eaglerNoDelay);
|
||||
jsonObject.put("ramdiskMode", ramdiskMode);
|
||||
jsonObject.put("singleThreadMode", singleThreadMode);
|
||||
jsonObject.put("enableEPKVersionCheck", enableEPKVersionCheck);
|
||||
return jsonObject;
|
||||
@Override
|
||||
public List<DefaultServer> getDefaultServerList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toJSONObject().toString();
|
||||
public String getResourcePacksDB() {
|
||||
return this.resourcePacksDB;
|
||||
}
|
||||
|
||||
public String toStringFormatted() {
|
||||
return toJSONObject().toString(4);
|
||||
@Override
|
||||
public boolean isCheckShaderGLErrors() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDemo() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowUpdateSvc() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowUpdateDL() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableDownloadOfflineButton() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadOfflineButtonLink() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useSpecialCursors() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogInvalidCerts() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCheckRelaysForUpdates() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableSignatureBadge() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowVoiceClient() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowFNAWSkins() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableMinceraft() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableServerCookies() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowServerRedirects() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpenDebugConsoleOnLaunch() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceWebViewSupport() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableWebViewCSP() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowBootMenu() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceProfanityFilter() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -11,8 +13,6 @@ import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.core.JSArrayReader;
|
||||
import org.teavm.jso.core.JSString;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.internal.teavm.generators.TeaVMRuntimeDeobfuscatorGenerator;
|
||||
import net.lax1dude.eaglercraft.EagUtils;
|
||||
@ -171,7 +171,7 @@ public class TeaVMRuntimeDeobfuscator {
|
||||
public static String deobfExceptionStack(String stackLines) {
|
||||
if(!isInitialized) return stackLines;
|
||||
try {
|
||||
List<String> lines = Lists.newArrayList(EagUtils.splitPattern.split(stackLines));
|
||||
List<String> lines = Arrays.asList(EagUtils.splitPattern.split(stackLines));
|
||||
deobfExceptionStack(lines);
|
||||
return String.join("\n", lines);
|
||||
}catch(Throwable t) {
|
||||
|
@ -1,203 +0,0 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.json.JSONObject;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.dom.events.Event;
|
||||
import org.teavm.jso.dom.events.EventListener;
|
||||
import org.teavm.jso.dom.events.MessageEvent;
|
||||
import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||
import org.teavm.jso.websocket.WebSocket;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.EnumServerRateLimit;
|
||||
import net.lax1dude.eaglercraft.internal.IServerQuery;
|
||||
import net.lax1dude.eaglercraft.internal.QueryResponse;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class TeaVMServerQuery implements IServerQuery {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("WebSocketQuery");
|
||||
|
||||
private final List<QueryResponse> queryResponses = new LinkedList();
|
||||
private final List<byte[]> queryResponsesBytes = new LinkedList();
|
||||
|
||||
protected final String uri;
|
||||
protected final String accept;
|
||||
protected final WebSocket sock;
|
||||
protected boolean open = true;
|
||||
protected boolean alive = false;
|
||||
protected long pingStart = -1l;
|
||||
protected long pingTimer = -1l;
|
||||
private EnumServerRateLimit rateLimit = EnumServerRateLimit.OK;
|
||||
|
||||
public TeaVMServerQuery(String uri, String accept) {
|
||||
this.uri = uri;
|
||||
this.accept = accept;
|
||||
this.sock = WebSocket.create(uri);
|
||||
initHandlers();
|
||||
}
|
||||
|
||||
@JSBody(params = { "obj" }, script = "return typeof obj === \"string\";")
|
||||
private static native boolean isString(JSObject obj);
|
||||
|
||||
protected void initHandlers() {
|
||||
sock.setBinaryType("arraybuffer");
|
||||
TeaVMUtils.addEventListener(sock, "open", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
sock.send("Accept: " + accept);
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "close", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
open = false;
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "message", new EventListener<MessageEvent>() {
|
||||
@Override
|
||||
public void handleEvent(MessageEvent evt) {
|
||||
alive = true;
|
||||
if(pingTimer == -1) {
|
||||
pingTimer = System.currentTimeMillis() - pingStart;
|
||||
if(pingTimer < 1) {
|
||||
pingTimer = 1;
|
||||
}
|
||||
}
|
||||
if(isString(evt.getData())) {
|
||||
String str = evt.getDataAsString();
|
||||
if(str.equalsIgnoreCase("BLOCKED")) {
|
||||
logger.error("Reached full IP ratelimit for {}!", uri);
|
||||
rateLimit = EnumServerRateLimit.BLOCKED;
|
||||
return;
|
||||
}
|
||||
if(str.equalsIgnoreCase("LOCKED")) {
|
||||
logger.error("Reached full IP ratelimit lockout for {}!", uri);
|
||||
rateLimit = EnumServerRateLimit.LOCKED_OUT;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
JSONObject obj = new JSONObject(str);
|
||||
if("blocked".equalsIgnoreCase(obj.optString("type", null))) {
|
||||
logger.error("Reached query ratelimit for {}!", uri);
|
||||
rateLimit = EnumServerRateLimit.BLOCKED;
|
||||
}else if("locked".equalsIgnoreCase(obj.optString("type", null))) {
|
||||
logger.error("Reached query ratelimit lockout for {}!", uri);
|
||||
rateLimit = EnumServerRateLimit.LOCKED_OUT;
|
||||
}else {
|
||||
QueryResponse response = new QueryResponse(obj, pingTimer);
|
||||
synchronized(queryResponses) {
|
||||
queryResponses.add(response);
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
logger.error("Exception thrown parsing websocket query response from \"" + uri + "\"!");
|
||||
logger.error(t);
|
||||
}
|
||||
}else {
|
||||
synchronized(queryResponsesBytes) {
|
||||
queryResponsesBytes.add(TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "error", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
sock.close();
|
||||
open = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String str) {
|
||||
if(open) {
|
||||
sock.send(str);
|
||||
}
|
||||
}
|
||||
|
||||
@JSBody(params = { "sock", "buffer" }, script = "sock.send(buffer);")
|
||||
private static native void nativeBinarySend(WebSocket sock, ArrayBuffer buffer);
|
||||
|
||||
@Override
|
||||
public void send(byte[] bytes) {
|
||||
if(open) {
|
||||
nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int responsesAvailable() {
|
||||
synchronized(queryResponses) {
|
||||
return queryResponses.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResponse getResponse() {
|
||||
synchronized(queryResponses) {
|
||||
if(queryResponses.size() > 0) {
|
||||
return queryResponses.remove(0);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int binaryResponsesAvailable() {
|
||||
synchronized(queryResponsesBytes) {
|
||||
return queryResponsesBytes.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBinaryResponse() {
|
||||
synchronized(queryResponsesBytes) {
|
||||
if(queryResponsesBytes.size() > 0) {
|
||||
return queryResponsesBytes.remove(0);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryReadyState readyState() {
|
||||
return open ? (alive ? QueryReadyState.OPEN : QueryReadyState.CONNECTING)
|
||||
: (alive ? QueryReadyState.CLOSED : QueryReadyState.FAILED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if(open) {
|
||||
open = false;
|
||||
sock.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumServerRateLimit getRateLimit() {
|
||||
return rateLimit;
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import org.teavm.jso.dom.events.Event;
|
||||
import org.teavm.jso.dom.events.EventListener;
|
||||
import org.teavm.jso.dom.events.MessageEvent;
|
||||
import org.teavm.jso.websocket.WebSocket;
|
||||
|
||||
import net.lax1dude.eaglercraft.EagUtils;
|
||||
import net.lax1dude.eaglercraft.internal.AbstractWebSocketClient;
|
||||
import net.lax1dude.eaglercraft.internal.EnumEaglerConnectionState;
|
||||
import net.lax1dude.eaglercraft.internal.PlatformRuntime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class TeaVMWebSocketClient extends AbstractWebSocketClient {
|
||||
|
||||
private final WebSocket sock;
|
||||
private boolean sockIsConnecting = true;
|
||||
private boolean sockIsConnected = false;
|
||||
private boolean sockIsFailed = false;
|
||||
|
||||
public TeaVMWebSocketClient(String socketURI) {
|
||||
super(socketURI);
|
||||
sock = WebSocket.create(socketURI);
|
||||
sock.setBinaryType("arraybuffer");
|
||||
TeaVMUtils.addEventListener(sock, "open", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
sockIsConnecting = false;
|
||||
sockIsConnected = true;
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "close", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
sockIsConnecting = false;
|
||||
sockIsConnected = false;
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "message", new EventListener<MessageEvent>() {
|
||||
@Override
|
||||
public void handleEvent(MessageEvent evt) {
|
||||
addRecievedFrame(new TeaVMWebSocketFrame(evt.getData()));
|
||||
}
|
||||
});
|
||||
TeaVMUtils.addEventListener(sock, "error", new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
if(sockIsConnecting) {
|
||||
sockIsFailed = true;
|
||||
sockIsConnecting = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectBlocking(int timeoutMS) {
|
||||
long startTime = PlatformRuntime.steadyTimeMillis();
|
||||
while(!sockIsConnected && !sockIsFailed) {
|
||||
EagUtils.sleep(50);
|
||||
if(PlatformRuntime.steadyTimeMillis() - startTime > timeoutMS * 1000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sockIsConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumEaglerConnectionState getState() {
|
||||
return sockIsConnected ? EnumEaglerConnectionState.CONNECTED
|
||||
: (sockIsFailed ? EnumEaglerConnectionState.FAILED
|
||||
: (sockIsConnecting ? EnumEaglerConnectionState.CONNECTING : EnumEaglerConnectionState.CLOSED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return sockIsConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return !sockIsConnecting && !sockIsConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
sockIsConnecting = false;
|
||||
sockIsConnected = false;
|
||||
sock.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String str) {
|
||||
if(sockIsConnected) {
|
||||
sock.send(str);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(byte[] bytes) {
|
||||
if(sockIsConnected) {
|
||||
sock.send(TeaVMUtils.unwrapArrayBuffer(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package net.lax1dude.eaglercraft.internal.teavm;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.IWebSocketFrame;
|
||||
import net.lax1dude.eaglercraft.internal.PlatformRuntime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class TeaVMWebSocketFrame implements IWebSocketFrame {
|
||||
|
||||
private JSObject data;
|
||||
private boolean str;
|
||||
|
||||
private String cachedStrContent = null;
|
||||
private byte[] cachedByteContent = null;
|
||||
|
||||
private int cachedLen = -1;
|
||||
|
||||
private final long timestamp;
|
||||
|
||||
@JSBody(params = { "obj" }, script = "return (typeof obj === \"string\");")
|
||||
private static native boolean isStr(JSObject obj);
|
||||
|
||||
public TeaVMWebSocketFrame(JSObject data) {
|
||||
this.data = data;
|
||||
this.str = isStr(data);
|
||||
this.timestamp = PlatformRuntime.steadyTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isString() {
|
||||
return str;
|
||||
}
|
||||
|
||||
@JSBody(params = { "obj" }, script = "return obj;")
|
||||
private static native String toStr(JSObject obj);
|
||||
|
||||
@Override
|
||||
public String getString() {
|
||||
if(str) {
|
||||
if(cachedStrContent == null) {
|
||||
return (cachedStrContent = toStr(data));
|
||||
}else {
|
||||
return cachedStrContent;
|
||||
}
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
if(!str) {
|
||||
if(cachedByteContent == null) {
|
||||
return (cachedByteContent = TeaVMUtils.wrapByteArrayBuffer((ArrayBuffer)data));
|
||||
}else {
|
||||
return cachedByteContent;
|
||||
}
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
if(!str) {
|
||||
return new ArrayBufferInputStream((ArrayBuffer)data);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@JSBody(params = { "obj" }, script = "return obj.length;")
|
||||
private static native int strLen(JSObject obj);
|
||||
|
||||
@JSBody(params = { "obj" }, script = "return obj.byteLength;")
|
||||
private static native int arrLen(JSObject obj);
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
if(cachedLen == -1) {
|
||||
if(str) {
|
||||
cachedLen = strLen(data);
|
||||
}else {
|
||||
cachedLen = arrLen(data);
|
||||
}
|
||||
}
|
||||
return cachedLen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ import static net.lax1dude.eaglercraft.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import org.teavm.jso.webgl.WebGLFramebuffer;
|
||||
|
||||
import net.lax1dude.eaglercraft.internal.IBufferArrayGL;
|
||||
import net.lax1dude.eaglercraft.internal.IVertexArrayGL;
|
||||
import net.lax1dude.eaglercraft.internal.IBufferGL;
|
||||
import net.lax1dude.eaglercraft.internal.IFramebufferGL;
|
||||
import net.lax1dude.eaglercraft.internal.IProgramGL;
|
||||
@ -50,7 +50,7 @@ public class WebGLBackBuffer {
|
||||
private static ITextureGL gles2ColorTexture;
|
||||
private static IRenderbufferGL gles2DepthRenderbuffer;
|
||||
private static IProgramGL gles2BlitProgram;
|
||||
private static IBufferArrayGL gles2BlitVAO;
|
||||
private static IVertexArrayGL gles2BlitVAO;
|
||||
private static IBufferGL gles2BlitVBO;
|
||||
|
||||
private static boolean isVAOCapable = false;
|
||||
@ -60,8 +60,9 @@ public class WebGLBackBuffer {
|
||||
private static final int _GL_RENDERBUFFER = 0x8D41;
|
||||
private static final int _GL_COLOR_ATTACHMENT0 = 0x8CE0;
|
||||
private static final int _GL_DEPTH_ATTACHMENT = 0x8D00;
|
||||
private static final int _GL_DEPTH_COMPONENT16 = 0x81A5;
|
||||
private static final int _GL_DEPTH_STENCIL_ATTACHMENT = 0x821A;
|
||||
private static final int _GL_DEPTH_COMPONENT32F = 0x8CAC;
|
||||
private static final int _GL_DEPTH_STENCIL = 0x84F9;
|
||||
private static final int _GL_READ_FRAMEBUFFER = 0x8CA8;
|
||||
private static final int _GL_DRAW_FRAMEBUFFER = 0x8CA9;
|
||||
|
||||
@ -97,8 +98,8 @@ public class WebGLBackBuffer {
|
||||
_wglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sw, sh, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
|
||||
_wglFramebufferTexture2D(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gles2ColorTexture, 0);
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, gles2DepthRenderbuffer);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_COMPONENT16, sw, sh);
|
||||
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_DEPTH_ATTACHMENT, _GL_RENDERBUFFER, gles2DepthRenderbuffer);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_STENCIL, sw, sh);
|
||||
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_DEPTH_STENCIL_ATTACHMENT, _GL_RENDERBUFFER, gles2DepthRenderbuffer);
|
||||
|
||||
ByteBuffer upload = PlatformRuntime.allocateByteBuffer(48);
|
||||
upload.putFloat(0.0f); upload.putFloat(0.0f);
|
||||
@ -159,8 +160,8 @@ public class WebGLBackBuffer {
|
||||
if(isVAOCapable) {
|
||||
_wglDeleteVertexArrays(gles2BlitVAO);
|
||||
}
|
||||
gles2BlitVAO = EaglercraftGPU.createGLBufferArray();
|
||||
EaglercraftGPU.bindGLBufferArray(gles2BlitVAO);
|
||||
gles2BlitVAO = EaglercraftGPU.createGLVertexArray();
|
||||
EaglercraftGPU.bindGLVertexArray(gles2BlitVAO);
|
||||
EaglercraftGPU.bindVAOGLArrayBuffer(gles2BlitVBO);
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
|
||||
@ -171,8 +172,8 @@ public class WebGLBackBuffer {
|
||||
|
||||
private static void drawBlitQuad() {
|
||||
if(isEmulatedVAOPhase) {
|
||||
EaglercraftGPU.bindGLBufferArray(gles2BlitVAO);
|
||||
EaglercraftGPU.doDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
EaglercraftGPU.bindGLVertexArray(gles2BlitVAO);
|
||||
EaglercraftGPU.drawArrays(GL_TRIANGLES, 0, 6);
|
||||
}else {
|
||||
if(isVAOCapable) {
|
||||
_wglBindVertexArray(gles2BlitVAO);
|
||||
@ -236,7 +237,7 @@ public class WebGLBackBuffer {
|
||||
_wglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
|
||||
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, gles2DepthRenderbuffer);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_COMPONENT16, windowWidth, windowHeight);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_STENCIL, windowWidth, windowHeight);
|
||||
}
|
||||
|
||||
if(isEmulatedVAOPhase) {
|
||||
@ -280,7 +281,7 @@ public class WebGLBackBuffer {
|
||||
}
|
||||
if(gles2BlitVAO != null) {
|
||||
if(isEmulatedVAOPhase) {
|
||||
EaglercraftGPU.destroyGLBufferArray(gles2BlitVAO);
|
||||
EaglercraftGPU.destroyGLVertexArray(gles2BlitVAO);
|
||||
}else if(isVAOCapable) {
|
||||
_wglDeleteVertexArrays(gles2BlitVAO);
|
||||
}
|
||||
|
114
src/teavm/java/org/apache/commons/lang3/ArrayUtils.java
Normal file
114
src/teavm/java/org/apache/commons/lang3/ArrayUtils.java
Normal file
@ -0,0 +1,114 @@
|
||||
package org.apache.commons.lang3;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
public class ArrayUtils {
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive booleans is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final boolean[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive bytes is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final byte[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive chars is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final char[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive doubles is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final double[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive floats is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final float[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive ints is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final int[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive longs is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final long[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of Objects is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final Object[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an array of primitive shorts is empty or {@code null}.
|
||||
*
|
||||
* @param array the array to test
|
||||
* @return {@code true} if the array is empty or {@code null}
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean isEmpty(final short[] array) {
|
||||
return isArrayEmpty(array);
|
||||
}
|
||||
|
||||
private static boolean isArrayEmpty(final Object array) {
|
||||
return getLength(array) == 0;
|
||||
}
|
||||
|
||||
public static int getLength(final Object array) {
|
||||
return array != null ? Array.getLength(array) : 0;
|
||||
}
|
||||
|
||||
}
|
44
src/teavm/java/org/apache/commons/lang3/StringUtils.java
Normal file
44
src/teavm/java/org/apache/commons/lang3/StringUtils.java
Normal file
@ -0,0 +1,44 @@
|
||||
package org.apache.commons.lang3;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
/**
|
||||
* Tests if a CharSequence is empty ("") or null.
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.isEmpty(null) = true
|
||||
* StringUtils.isEmpty("") = true
|
||||
* StringUtils.isEmpty(" ") = false
|
||||
* StringUtils.isEmpty("bob") = false
|
||||
* StringUtils.isEmpty(" bob ") = false
|
||||
* </pre>
|
||||
*
|
||||
* <p>NOTE: This method changed in Lang version 2.0.
|
||||
* It no longer trims the CharSequence.
|
||||
* That functionality is available in isBlank().</p>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @return {@code true} if the CharSequence is empty or null
|
||||
* @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence)
|
||||
*/
|
||||
public static boolean isEmpty(final CharSequence cs) {
|
||||
return cs == null || cs.length() == 0;
|
||||
}
|
||||
|
||||
public static boolean isAllEmpty(final CharSequence... css) {
|
||||
if (ArrayUtils.isEmpty(css)) {
|
||||
return true;
|
||||
}
|
||||
for (final CharSequence cs : css) {
|
||||
if (isNotEmpty(cs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(final CharSequence cs) {
|
||||
return !isEmpty(cs);
|
||||
}
|
||||
|
||||
}
|
45
src/teavm/java/org/json/JSONException.java
Normal file
45
src/teavm/java/org/json/JSONException.java
Normal file
@ -0,0 +1,45 @@
|
||||
package org.json;
|
||||
|
||||
/*
|
||||
Public Domain.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The JSONException is thrown by the JSON.org classes when things are amiss.
|
||||
*
|
||||
* @author JSON.org
|
||||
* @version 2015-12-09
|
||||
*/
|
||||
public class JSONException extends RuntimeException {
|
||||
/** Serialization ID */
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
/**
|
||||
* Constructs a JSONException with an explanatory message.
|
||||
*
|
||||
* @param message Detail about the reason for the exception.
|
||||
*/
|
||||
public JSONException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JSONException with an explanatory message and cause.
|
||||
*
|
||||
* @param message Detail about the reason for the exception.
|
||||
* @param cause The cause.
|
||||
*/
|
||||
public JSONException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new JSONException with the specified cause.
|
||||
*
|
||||
* @param cause The cause.
|
||||
*/
|
||||
public JSONException(final Throwable cause) {
|
||||
super(cause.getMessage(), cause);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user