Update #44 - WebAssembly GC support, fix more WebRTC bugs

This commit is contained in:
lax1dude
2024-12-03 23:38:28 -08:00
parent 919014b4df
commit 70b52bbf7a
216 changed files with 34358 additions and 91 deletions

View File

@ -15,6 +15,7 @@ import org.apache.commons.lang3.StringUtils;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.EnumEaglerConnectionState;
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformType;
import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
@ -84,6 +85,7 @@ public class SingleplayerServerController implements ISaveFormat {
issuesDetected.clear();
statusState = IntegratedServerState.WORLD_WORKER_BOOTING;
loggingState = true;
callFailed = false;
boolean singleThreadSupport = ClientPlatformSingleplayer.isSingleThreadModeSupported();
if(!singleThreadSupport && forceSingleThread) {
throw new UnsupportedOperationException("Single thread mode is not supported!");
@ -294,10 +296,12 @@ public class SingleplayerServerController implements ISaveFormat {
}
}
boolean logWindowState = PlatformApplication.isShowingDebugConsole();
if(loggingState != logWindowState) {
loggingState = logWindowState;
sendIPCPacket(new IPCPacket1BEnableLogging(logWindowState));
if(EagRuntime.getPlatformType() == EnumPlatformType.JAVASCRIPT) {
boolean logWindowState = PlatformApplication.isShowingDebugConsole();
if(loggingState != logWindowState) {
loggingState = logWindowState;
sendIPCPacket(new IPCPacket1BEnableLogging(logWindowState));
}
}
if(ClientPlatformSingleplayer.isRunningSingleThreadMode()) {

View File

@ -41,6 +41,8 @@ class LANClientPeer {
protected long startTime;
protected String localICECandidate = null;
protected LANClientPeer(String clientId) {
this.clientId = clientId;
this.startTime = EagRuntime.steadyTimeMillis();
@ -50,7 +52,13 @@ class LANClientPeer {
protected void handleICECandidates(String candidates) {
if(state == SENT_DESCRIPTION) {
PlatformWebRTC.serverLANPeerICECandidates(clientId, candidates);
state = RECEIVED_ICE_CANDIDATE;
if(localICECandidate != null) {
LANServerController.lanRelaySocket.writePacket(new RelayPacket03ICECandidate(clientId, localICECandidate));
localICECandidate = null;
state = SENT_ICE_CANDIDATE;
}else {
state = RECEIVED_ICE_CANDIDATE;
}
}else {
logger.error("Relay [{}] unexpected IPacket03ICECandidate for '{}'", LANServerController.lanRelaySocket.getURI(), clientId);
}
@ -100,6 +108,12 @@ class LANClientPeer {
disconnect();
}else {
switch(state) {
case SENT_DESCRIPTION:{
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
localICECandidate = ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates;
continue read_loop;
}
}
case RECEIVED_ICE_CANDIDATE: {
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
LANServerController.lanRelaySocket.writePacket(new RelayPacket03ICECandidate(clientId, ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates));
@ -136,7 +150,7 @@ class LANClientPeer {
}
}
if(state != CLOSED) {
logger.error("LAN client '{}' had an accident: {}", clientId, evt.getClass().getSimpleName());
logger.error("LAN client '{}' had an accident: {} (state {})", clientId, evt.getClass().getSimpleName(), state);
}
disconnect();
return;

View File

@ -82,7 +82,7 @@ public class LANServerController {
}
}
EagUtils.sleep(50);
}while(EagRuntime.steadyTimeMillis() - millis < 1000l);
}while(EagRuntime.steadyTimeMillis() - millis < 2500l);
logger.info("Relay [{}] relay provide ICE servers timeout", sock.getURI());
closeLAN();
return null;

View File

@ -8,7 +8,6 @@ import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFile2;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.MinecraftException;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
@ -88,7 +87,7 @@ public class EaglerChunkLoader extends AnvilChunkLoader {
}
@Override
public void saveChunk(World var1, Chunk var2) throws IOException, MinecraftException {
public void saveChunk(World var1, Chunk var2) throws IOException {
NBTTagCompound chunkData = new NBTTagCompound();
this.writeChunkToNBT(var2, var1, chunkData);
NBTTagCompound fileData = new NBTTagCompound();

View File

@ -485,6 +485,8 @@ public class EaglerIntegratedServerWorker {
// signal thread startup successful
sendIPCPacket(new IPCPacketFFProcessKeepAlive(0xFF));
ServerPlatformSingleplayer.setCrashCallbackWASM(EaglerIntegratedServerWorker::sendIntegratedServerCrashWASMCB);
while(true) {
mainLoop(false);
ServerPlatformSingleplayer.immediateContinue();
@ -525,4 +527,11 @@ public class EaglerIntegratedServerWorker {
mainLoop(true);
}
public static void sendIntegratedServerCrashWASMCB(String stringValue, boolean terminated) {
sendIPCPacket(new IPCPacket15Crashed(stringValue));
if(terminated) {
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacketFFProcessKeepAlive.EXITED));
}
}
}

View File

@ -0,0 +1,22 @@
package net.lax1dude.eaglercraft.v1_8.sp.server;
/**
* 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 interface IWASMCrashCallback {
void callback(String crashReport, boolean terminated);
}

View File

@ -139,14 +139,24 @@ public class IntegratedVoiceService {
}
public void handleVoiceSignalPacketTypeConnect(EntityPlayerMP sender) {
if (voicePlayers.containsKey(sender.getUniqueID())) {
EaglercraftUUID senderUuid = sender.getUniqueID();
if (voicePlayers.containsKey(senderUuid)) {
return;
}
boolean hasNoOtherPlayers = voicePlayers.isEmpty();
voicePlayers.put(sender.getUniqueID(), sender);
voicePlayers.put(senderUuid, sender);
if (hasNoOtherPlayers) {
return;
}
GameMessagePacket v3p = null;
GameMessagePacket v4p = null;
for(EntityPlayerMP conn : voicePlayers.values()) {
if(conn.playerNetServerHandler.getEaglerMessageProtocol().ver <= 3) {
conn.playerNetServerHandler.sendEaglerMessage(v3p == null ? (v3p = new SPacketVoiceSignalConnectV3EAG(senderUuid.msb, senderUuid.lsb, true, false)) : v3p);
} else {
conn.playerNetServerHandler.sendEaglerMessage(v4p == null ? (v4p = new SPacketVoiceSignalConnectAnnounceV4EAG(senderUuid.msb, senderUuid.lsb)) : v4p);
}
}
Collection<SPacketVoiceSignalGlobalEAG.UserData> userDatas = new ArrayList<>(voicePlayers.size());
for(EntityPlayerMP player : voicePlayers.values()) {
EaglercraftUUID uuid = player.getUniqueID();