Update #45 - Fixed various issues with the client

This commit is contained in:
lax1dude
2024-12-14 20:54:34 -08:00
parent 12535d429f
commit 346047cf24
39 changed files with 571 additions and 208 deletions

View File

@ -36,8 +36,6 @@ import org.teavm.jso.gamepad.Gamepad;
import org.teavm.jso.gamepad.GamepadButton;
import org.teavm.jso.gamepad.GamepadEvent;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ClientMain;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.EarlyLoadScreen;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.InputEvent;
@ -889,7 +887,7 @@ public class PlatformInput {
update(0);
}
private static final long[] syncTimer = new long[1];
private static double syncTimer = 0.0;
public static void update(int fpsLimit) {
double r = getDevicePixelRatio(win);
@ -943,21 +941,44 @@ public class PlatformInput {
PlatformScreenRecord.captureFrameHook();
if(getVisibilityState(win.getDocument())) {
if(vsyncSupport && vsync) {
syncTimer[0] = 0l;
syncTimer = 0.0;
asyncRequestAnimationFrame();
}else {
if(fpsLimit <= 0) {
syncTimer[0] = 0l;
if(fpsLimit <= 0 || fpsLimit > 1000) {
syncTimer = 0.0;
PlatformRuntime.swapDelayTeaVM();
}else {
if(!Display.sync(fpsLimit, syncTimer)) {
double frameMillis = (1000.0 / fpsLimit);
if(syncTimer == 0.0) {
syncTimer = PlatformRuntime.steadyTimeMillisTeaVM() + frameMillis;
PlatformRuntime.swapDelayTeaVM();
}else {
double millis = PlatformRuntime.steadyTimeMillisTeaVM();
int remaining = (int)(syncTimer - millis);
if(remaining > 0) {
if(!PlatformRuntime.useDelayOnSwap && PlatformRuntime.immediateContinueSupport) {
PlatformRuntime.immediateContinue(); // cannot stack setTimeouts, or it will throttle
millis = PlatformRuntime.steadyTimeMillisTeaVM();
remaining = (int)(syncTimer - millis);
if(remaining > 0) {
PlatformRuntime.sleep((int)remaining);
}
}else {
PlatformRuntime.sleep((int)remaining);
}
}else {
PlatformRuntime.swapDelayTeaVM();
}
millis = PlatformRuntime.steadyTimeMillisTeaVM();
if((syncTimer += frameMillis) < millis) {
syncTimer = millis;
}
}
}
}
}else {
syncTimer[0] = 0l;
EagUtils.sleep(50);
syncTimer = 0.0;
PlatformRuntime.sleep(50);
}
}
@ -1579,7 +1600,7 @@ public class PlatformInput {
EarlyLoadScreen.paintEnable(PlatformOpenGL.checkVAOCapable(), allowBootMenu);
while(mouseEvents.isEmpty() && keyEvents.isEmpty() && touchEvents.isEmpty()) {
EagUtils.sleep(100);
PlatformRuntime.sleep(100);
}
}
}
@ -1864,7 +1885,7 @@ public class PlatformInput {
if(touchKeyboardField != null) {
touchKeyboardField.blur();
touchKeyboardField.setValue("");
EagUtils.sleep(10);
PlatformRuntime.sleep(10);
if(touchKeyboardForm != null) {
touchKeyboardForm.removeChild(touchKeyboardField);
}else {
@ -2135,7 +2156,7 @@ public class PlatformInput {
touchKeyboardField.blur();
touchKeyboardField.setValue("");
if(sync) {
EagUtils.sleep(10);
PlatformRuntime.sleep(10);
if(touchKeyboardForm != null) {
touchKeyboardForm.removeChild(touchKeyboardField);
}else {

View File

@ -766,6 +766,10 @@ public class PlatformRuntime {
}
}
public static boolean immediateContinueSupported() {
return immediateContinueSupport;
}
@Async
private static native void immediateContinueTeaVM0();
@ -1101,6 +1105,10 @@ public class PlatformRuntime {
@JSBody(params = { "steadyTimeFunc" }, script = "return steadyTimeFunc();")
private static native double steadyTimeMillis0(JSObject steadyTimeFunc);
public static double steadyTimeMillisTeaVM() {
return steadyTimeMillis0(steadyTimeFunc);
}
public static long steadyTimeMillis() {
return (long)steadyTimeMillis0(steadyTimeFunc);
}

View File

@ -111,6 +111,7 @@ public class PlatformVoiceClient {
if(!PlatformWebRTC.hasCheckedSupport) PlatformWebRTC.supported();
switch(PlatformWebRTC.supportedImpl) {
case PlatformWebRTC.WEBRTC_SUPPORT_CORE:
case PlatformWebRTC.WEBRTC_SUPPORT_CORE_NON_PROMISING:
case PlatformWebRTC.WEBRTC_SUPPORT_WEBKIT:
addCoreIceCandidate(peerConnection, str);
break;

View File

@ -49,8 +49,18 @@ public class PlatformWebRTC {
static final int WEBRTC_SUPPORT_CORE = 1;
static final int WEBRTC_SUPPORT_WEBKIT = 2;
static final int WEBRTC_SUPPORT_MOZ = 3;
static final int WEBRTC_SUPPORT_CORE_NON_PROMISING = 4;
@JSBody(script = "return (typeof RTCPeerConnection !== \"undefined\") ? 1 : ((typeof webkitRTCPeerConnection !== \"undefined\") ? 2 : ((typeof mozRTCPeerConnection !== \"undefined\") ? 3 : 0));")
@JSBody(script = "var checkPromising = function() { try {"
+ "return (typeof (new RTCPeerConnection({iceServers:[{urls:\"stun:127.69.0.1:6969\"}]})).createOffer() === \"object\") ? 1 : 4;"
+ "} catch(ex) {"
+ "return (ex.name === \"TypeError\") ? 4 : 1;"
+ "}};"
+ "return (typeof RTCPeerConnection !== \"undefined\")"
+ " ? checkPromising()"
+ " : ((typeof webkitRTCPeerConnection !== \"undefined\") ? 2"
+ " : ((typeof mozRTCPeerConnection !== \"undefined\") ? 3"
+ " : 0));")
private static native int checkSupportedImpl();
static boolean hasCheckedSupport = false;
@ -69,6 +79,8 @@ public class PlatformWebRTC {
logger.info("Using webkit- prefix for RTCPeerConnection");
}else if(supportedImpl == WEBRTC_SUPPORT_MOZ) {
logger.info("Using moz- prefix for RTCPeerConnection");
}else if(supportedImpl == WEBRTC_SUPPORT_CORE_NON_PROMISING) {
logger.info("Using non-promising RTCPeerConnection");
}
if(supportedImpl != WEBRTC_SUPPORT_NONE) {
belowChrome71Fix = isChromeBelow71();
@ -160,6 +172,7 @@ public class PlatformWebRTC {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
return createCoreRTCPeerConnection(iceServers);
case WEBRTC_SUPPORT_WEBKIT:
return createWebkitRTCPeerConnection(iceServers);
@ -191,11 +204,49 @@ public class PlatformWebRTC {
@JSBody(params = { "item" }, script = "return item.channel;")
static native JSObject getChannel(JSObject item);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createOffer().then(h1).catch(h2);")
private static native void createOfferPromising(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createOffer(h1, h2);")
static native void createOffer(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
private static native void createOfferLegacy(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
static void createOffer(JSObject peerConnection, DescHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
createOfferPromising(peerConnection, h1, h2);
break;
case WEBRTC_SUPPORT_WEBKIT:
case WEBRTC_SUPPORT_MOZ:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
createOfferLegacy(peerConnection, h1, h2);
break;
default:
throw new UnsupportedOperationException();
}
}
@JSBody(params = { "peerConnection", "desc", "h1", "h2" }, script = "peerConnection.setLocalDescription(desc).then(h1).catch(h2);")
private static native void setLocalDescriptionPromising(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "desc", "h1", "h2" }, script = "peerConnection.setLocalDescription(desc, h1, h2);")
static native void setLocalDescription(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2);
private static native void setLocalDescriptionLegacy(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2);
static void setLocalDescription(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
setLocalDescriptionPromising(peerConnection, desc, h1, h2);
break;
case WEBRTC_SUPPORT_WEBKIT:
case WEBRTC_SUPPORT_MOZ:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
setLocalDescriptionLegacy(peerConnection, desc, h1, h2);
break;
default:
throw new UnsupportedOperationException();
}
}
@JSBody(params = { "peerConnection", "str" }, script = "var candidateList = JSON.parse(str); for (var i = 0; i < candidateList.length; ++i) { peerConnection.addIceCandidate(new RTCIceCandidate(candidateList[i])); }; return null;")
private static native void addCoreIceCandidates(JSObject peerConnection, String str);
@ -219,6 +270,7 @@ public class PlatformWebRTC {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
case WEBRTC_SUPPORT_WEBKIT:
addCoreIceCandidates(peerConnection, str);
break;
@ -246,6 +298,7 @@ public class PlatformWebRTC {
}
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
if(useSessionDescConstructor) {
setCoreRemoteDescriptionLegacy(peerConnection, str);
}else {
@ -267,14 +320,20 @@ public class PlatformWebRTC {
}
}
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "try { peerConnection.setRemoteDescription(str).then(h1).catch(h2); return true; } catch(ex) { if(ex.name === \"TypeError\") return false; else throw ex; }")
private static native boolean setCoreRemoteDescription2Promising(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "try { peerConnection.setRemoteDescription(str, h1, h2); return true; } catch(ex) { if(ex.name === \"TypeError\") return false; else throw ex; }")
private static native boolean setCoreRemoteDescription2(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
private static native boolean setCoreRemoteDescription2Legacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "peerConnection.setRemoteDescription(new RTCSessionDescription(str)).then(h1).catch(h2);")
private static native void setCoreRemoteDescription2PromisingLegacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "peerConnection.setRemoteDescription(new RTCSessionDescription(str), h1, h2);")
private static native void setCoreRemoteDescription2Legacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
private static native void setCoreRemoteDescription2LegacyLegacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "peerConnection.setRemoteDescription(new mozRTCSessionDescription(str), h1, h2);")
private static native void setMozRemoteDescription2Legacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
private static native void setMozRemoteDescription2LegacyLegacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
static void setRemoteDescription2(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
@ -284,20 +343,31 @@ public class PlatformWebRTC {
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
if(useSessionDescConstructor) {
setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2);
setCoreRemoteDescription2PromisingLegacy(peerConnection, str, h1, h2);
}else {
if(!setCoreRemoteDescription2(peerConnection, str, h1, h2)) {
if(!setCoreRemoteDescription2Promising(peerConnection, str, h1, h2)) {
useSessionDescConstructor = true;
logger.info("Note: Caught suspicious exception, using legacy RTCSessionDescription method");
setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2);
setCoreRemoteDescription2PromisingLegacy(peerConnection, str, h1, h2);
}
}
break;
case WEBRTC_SUPPORT_WEBKIT:
setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2);
setCoreRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
break;
case WEBRTC_SUPPORT_MOZ:
setMozRemoteDescription2Legacy(peerConnection, str, h1, h2);
setMozRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
break;
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
if(useSessionDescConstructor) {
setCoreRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
}else {
if(!setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2)) {
useSessionDescConstructor = true;
logger.info("Note: Caught suspicious exception, using legacy RTCSessionDescription method");
setCoreRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
}
}
break;
default:
throw new UnsupportedOperationException();
@ -312,8 +382,27 @@ public class PlatformWebRTC {
+ "}")
private static native void removeExtmapAllowMixed(JSObject objIn);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createAnswer().then(h1).catch(h2);")
private static native void createAnswerPromising(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createAnswer(h1, h2);")
static native void createAnswer(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
private static native void createAnswerLegacy(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
static void createAnswer(JSObject peerConnection, DescHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
createAnswerPromising(peerConnection, h1, h2);
break;
case WEBRTC_SUPPORT_WEBKIT:
case WEBRTC_SUPPORT_MOZ:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
createAnswerLegacy(peerConnection, h1, h2);
break;
default:
throw new UnsupportedOperationException();
}
}
@JSBody(params = { "sock", "buffer" }, script = "sock.send(buffer);")
static native void nativeBinarySend(WebSocket sock, ArrayBuffer buffer);

View File

@ -8,7 +8,7 @@ import org.teavm.jso.typedarrays.Uint16Array;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 lax1dude. 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
@ -30,8 +30,14 @@ public class EaglerArrayBufferAllocator {
}
}
private static final ByteBuffer ZERO_LENGTH_BYTE_BUFFER = new EaglerArrayByteBuffer(Int8Array.create(0));
public static ByteBuffer allocateByteBuffer(int size) {
return new EaglerArrayByteBuffer(Int8Array.create(size));
if(size != 0) {
return new EaglerArrayByteBuffer(Int8Array.create(size));
}else {
return ZERO_LENGTH_BYTE_BUFFER;
}
}
public static ByteBuffer wrapByteBufferTeaVM(DataView dv) {
@ -42,16 +48,28 @@ public class EaglerArrayBufferAllocator {
return new EaglerArrayByteBuffer(typedArray);
}
private static final IntBuffer ZERO_LENGTH_INT_BUFFER = new EaglerArrayIntBuffer(Int32Array.create(0));
public static IntBuffer allocateIntBuffer(int size) {
return new EaglerArrayIntBuffer(Int32Array.create(size));
if(size != 0) {
return new EaglerArrayIntBuffer(Int32Array.create(size));
}else {
return ZERO_LENGTH_INT_BUFFER;
}
}
public static IntBuffer wrapIntBufferTeaVM(Int32Array typedArray) {
return new EaglerArrayIntBuffer(typedArray);
}
private static final FloatBuffer ZERO_LENGTH_FLOAT_BUFFER = new EaglerArrayFloatBuffer(Float32Array.create(0));
public static FloatBuffer allocateFloatBuffer(int size) {
return new EaglerArrayFloatBuffer(Float32Array.create(size));
if(size != 0) {
return new EaglerArrayFloatBuffer(Float32Array.create(size));
}else {
return ZERO_LENGTH_FLOAT_BUFFER;
}
}
public static FloatBuffer wrapFloatBufferTeaVM(Float32Array typedArray) {