Rewrite multiplayer with WebSockets

This commit is contained in:
PeytonPlayz595 2023-12-18 16:27:14 -05:00
parent 8d441465b1
commit e80061e7ba
7 changed files with 3257 additions and 2894 deletions

5988
js/app.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -71,7 +71,6 @@ public final class Minecraft implements Runnable {
public MovingObjectPosition selected; public MovingObjectPosition selected;
public static GameSettings settings; public static GameSettings settings;
public String server; public String server;
public int port;
volatile boolean running; volatile boolean running;
public String debug; public String debug;
public boolean hasMouse; public boolean hasMouse;
@ -92,7 +91,6 @@ public final class Minecraft implements Runnable {
new HumanoidModel(0.0F); new HumanoidModel(0.0F);
this.selected = null; this.selected = null;
this.server = null; this.server = null;
this.port = 0;
this.running = false; this.running = false;
this.debug = ""; this.debug = "";
this.hasMouse = false; this.hasMouse = false;
@ -186,7 +184,7 @@ public final class Minecraft implements Runnable {
checkGLError("Post startup"); checkGLError("Post startup");
this.hud = new HUDScreen(this, this.width, this.height); this.hud = new HUDScreen(this, this.width, this.height);
if(this.server != null) { if(this.server != null) {
this.networkManager = new NetworkManager(this, this.server, this.port, this.session.username, this.session.mppass); this.networkManager = new NetworkManager(this, this.server, this.session.username, this.session.mppass);
} }
long var13 = System.currentTimeMillis(); long var13 = System.currentTimeMillis();
@ -1070,10 +1068,10 @@ public final class Minecraft implements Runnable {
NetworkManager var20 = this.networkManager; NetworkManager var20 = this.networkManager;
if(this.networkManager.successful) { if(this.networkManager.successful) {
NetworkHandler var18 = var20.netHandler; NetworkHandler var18 = var20.netHandler;
if(var20.netHandler.connected) { if(GL11.connectionOpen()) {
try { try {
NetworkHandler var22 = var20.netHandler; NetworkHandler var22 = var20.netHandler;
var20.netHandler.channel.read(var22.in); var20.netHandler.read(var22.in);
var4 = 0; var4 = 0;
while(var22.in.position() > 0 && var4++ != 100) { while(var22.in.position() > 0 && var4++ != 100) {
@ -1266,7 +1264,7 @@ public final class Minecraft implements Runnable {
} }
} }
if(!var22.connected) { if(!GL11.connectionOpen()) {
break; break;
} }
@ -1275,7 +1273,7 @@ public final class Minecraft implements Runnable {
if(var22.out.position() > 0) { if(var22.out.position() > 0) {
var22.out.flip(); var22.out.flip();
var22.channel.write(var22.out); var22.write(var22.out);
var22.out.compact(); var22.out.compact();
} }
} catch (Exception var15) { } catch (Exception var15) {

View File

@ -9,9 +9,11 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.lwjgl.opengl.GL11;
public class NetworkManager public class NetworkManager
{ {
public NetworkManager(Minecraft minecraft, String server, int port, String username, String key) public NetworkManager(Minecraft minecraft, String server, String username, String key)
{ {
minecraft.online = true; minecraft.online = true;
@ -19,7 +21,7 @@ public class NetworkManager
players = new HashMap<Byte, NetworkPlayer>(); players = new HashMap<Byte, NetworkPlayer>();
new ServerConnectThread(this, server, port, username, key, minecraft).start(); new ServerConnectThread(this, server, username, key, minecraft).start();
} }
public ByteArrayOutputStream levelData; public ByteArrayOutputStream levelData;
@ -51,7 +53,7 @@ public class NetworkManager
public boolean isConnected() public boolean isConnected()
{ {
return netHandler != null && netHandler.connected; return netHandler != null && GL11.connectionOpen();
} }
public List getPlayers() public List getPlayers()

View File

@ -6,13 +6,12 @@ import com.mojang.net.NetworkHandler;
public class ServerConnectThread extends Thread public class ServerConnectThread extends Thread
{ {
public ServerConnectThread(NetworkManager networkManager, String server, int port, String username, String key, Minecraft minecraft) { public ServerConnectThread(NetworkManager networkManager, String server, String username, String key, Minecraft minecraft) {
super(); super();
netManager = networkManager; netManager = networkManager;
this.server = server; this.server = server;
this.port = port;
this.username = username; this.username = username;
this.key = key; this.key = key;
@ -24,7 +23,7 @@ public class ServerConnectThread extends Thread
public void run() public void run()
{ {
try { try {
netManager.netHandler = new NetworkHandler(server, port); netManager.netHandler = new NetworkHandler(server);
netManager.netHandler.netManager = netManager; netManager.netHandler.netManager = netManager;
netManager.netHandler.send(PacketType.IDENTIFICATION, new Object[]{Byte.valueOf((byte)7), this.username, this.key, Integer.valueOf(0)}); netManager.netHandler.send(PacketType.IDENTIFICATION, new Object[]{Byte.valueOf((byte)7), this.username, this.key, Integer.valueOf(0)});
@ -42,7 +41,6 @@ public class ServerConnectThread extends Thread
} }
private String server; private String server;
private int port;
private String username; private String username;
private String key; private String key;

View File

@ -2,51 +2,51 @@ package com.mojang.net;
import com.mojang.minecraft.Minecraft; import com.mojang.minecraft.Minecraft;
import com.mojang.minecraft.gamemode.CreativeGameMode; import com.mojang.minecraft.gamemode.CreativeGameMode;
import com.mojang.minecraft.gui.ErrorScreen;
import com.mojang.minecraft.net.NetworkManager; import com.mojang.minecraft.net.NetworkManager;
import com.mojang.minecraft.net.PacketType; import com.mojang.minecraft.net.PacketType;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Arrays; import java.util.Arrays;
import org.lwjgl.opengl.GL11;
import org.teavm.jso.JSBody;
public final class NetworkHandler { public final class NetworkHandler {
public volatile boolean connected;
public SocketChannel channel;
public ByteBuffer in = ByteBuffer.allocate(1048576); public ByteBuffer in = ByteBuffer.allocate(1048576);
public ByteBuffer out = ByteBuffer.allocate(1048576); public ByteBuffer out = ByteBuffer.allocate(1048576);
public NetworkManager netManager; public NetworkManager netManager;
private Socket sock;
private boolean unused = false; private boolean unused = false;
private byte[] stringBytes = new byte[64]; private byte[] stringBytes = new byte[64];
public NetworkHandler(String var1, int var2) { public NetworkHandler(String var1) {
Minecraft.getMinecraft().gamemode = new CreativeGameMode(Minecraft.getMinecraft()); Minecraft.getMinecraft().gamemode = new CreativeGameMode(Minecraft.getMinecraft());
try String address = var1;
{ if(address.endsWith("/")) {
channel = SocketChannel.open(); address = address.substring(0, address.length() - 1);
this.channel.connect(new InetSocketAddress(var1, var2)); }
this.channel.configureBlocking(false);
System.currentTimeMillis(); if(address.startsWith("ws://") && isSSLPage()) {
this.sock = this.channel.socket(); address.replace("ws://", "wss://");
this.connected = true; } else if(address.startsWith("wss://") && !isSSLPage()) {
this.in.clear(); address.replace("wss://", "ws://");
this.out.clear(); } else if(!address.contains("://")) {
this.sock.setTcpNoDelay(true); if(isSSLPage()) {
this.sock.setTrafficClass(24); address = "wss://" + address;
this.sock.setKeepAlive(false); } else {
this.sock.setReuseAddress(false); address = "ws://" + address;
this.sock.setSoTimeout(100); }
this.sock.getInetAddress().toString(); } else {
} catch (SocketException e) { Minecraft.getMinecraft().setCurrentScreen(new ErrorScreen(":(", "Invalid URI protocol!"));
e.printStackTrace(); }
} catch (IOException e) {
e.printStackTrace(); if(!GL11.startConnection(address)) {
if(!GL11.startConnection(address)) {
Minecraft.getMinecraft().setCurrentScreen(new ErrorScreen(address, "Failed to connect to server!"));
}
} }
} }
@ -54,27 +54,22 @@ public final class NetworkHandler {
try { try {
if(this.out.position() > 0) { if(this.out.position() > 0) {
this.out.flip(); this.out.flip();
this.channel.write(this.out); this.write(this.out);
this.out.compact(); this.out.compact();
} }
} catch (Exception var2) { } catch (Exception var2) {
; ;
} }
this.connected = false;
try { try {
this.channel.close(); GL11.endConnection();
} catch (Exception var1) { } catch (Exception var1) {
; ;
} }
this.sock = null;
this.channel = null;
} }
public final void send(PacketType var1, Object ... var2) { public final void send(PacketType var1, Object ... var2) {
if(this.connected) { if(GL11.connectionOpen()) {
this.out.put(var1.opcode); this.out.put(var1.opcode);
for(int var3 = 0; var3 < var2.length; ++var3) { for(int var3 = 0; var3 < var2.length; ++var3) {
@ -82,7 +77,7 @@ public final class NetworkHandler {
Object var4 = var2[var3]; Object var4 = var2[var3];
Class<?> var5 = var10001; Class<?> var5 = var10001;
NetworkHandler var6 = this; NetworkHandler var6 = this;
if(this.connected) { if(GL11.connectionOpen()) {
try { try {
if(var5 == Long.TYPE) { if(var5 == Long.TYPE) {
var6.out.putLong(((Long)var4).longValue()); var6.out.putLong(((Long)var4).longValue());
@ -134,7 +129,7 @@ public final class NetworkHandler {
} }
public Object readObject(Class var1) { public Object readObject(Class var1) {
if(!this.connected) { if(!GL11.connectionOpen()) {
return null; return null;
} else { } else {
try { try {
@ -166,4 +161,54 @@ public final class NetworkHandler {
} }
} }
} }
public void read(ByteBuffer buf) {
int bytesRead = 0;
while (bytesRead < buf.capacity()) {
if (!GL11.receivedBuffers.isEmpty()) {
ByteBuffer receivedBuffer = GL11.receivedBuffers.peek();
int remainingBytes = buf.capacity() - bytesRead;
int bytesToRead = Math.min(receivedBuffer.remaining(), remainingBytes);
receivedBuffer.get(buf.array(), bytesRead, bytesToRead);
bytesRead += bytesToRead;
if (receivedBuffer.remaining() == 0) {
GL11.receivedBuffers.poll();
}
} else {
break;
}
}
}
private static ByteBuffer writeBuffer;
public void write(ByteBuffer buf) {
if (writeBuffer == null) {
writeBuffer = ByteBuffer.allocate(buf.capacity());
}
int bytesToWrite = Math.min(buf.remaining(), writeBuffer.remaining());
writeBuffer.put(buf.array(), buf.position(), bytesToWrite);
buf.position(buf.position() + bytesToWrite);
if (writeBuffer.remaining() == 0 || buf.remaining() == 0) {
writeBuffer.flip();
byte[] data = new byte[writeBuffer.remaining()];
writeBuffer.get(data);
GL11.writePacket(data);
writeBuffer.clear();
}
if (buf.remaining() > 0) {
write(buf);
}
}
@JSBody(params = { }, script = "return window.location.href;")
private static native String getLocationString();
public static final boolean isSSLPage() {
return getLocationString().startsWith("https");
}
} }

View File

@ -1212,9 +1212,9 @@ public class EaglerAdapterImpl2 {
private static boolean sockIsConnecting = false; private static boolean sockIsConnecting = false;
private static boolean sockIsConnected = false; private static boolean sockIsConnected = false;
private static boolean sockIsAlive = false; private static boolean sockIsAlive = false;
private static LinkedList<byte[]> readPackets = new LinkedList<byte[]>();
private static RateLimit rateLimitStatus = null; private static RateLimit rateLimitStatus = null;
private static String currentSockURI = null; private static String currentSockURI = null;
public static java.util.Queue<ByteBuffer> receivedBuffers = new java.util.ArrayDeque<ByteBuffer>();
public static final RateLimit getRateLimitStatus() { public static final RateLimit getRateLimitStatus() {
RateLimit l = rateLimitStatus; RateLimit l = rateLimitStatus;
@ -1261,7 +1261,7 @@ public class EaglerAdapterImpl2 {
sockIsConnecting = false; sockIsConnecting = false;
sockIsAlive = false; sockIsAlive = false;
sockIsConnected = true; sockIsConnected = true;
readPackets.clear(); receivedBuffers.clear();
cb.complete("okay"); cb.complete("okay");
} }
}); });
@ -1323,7 +1323,8 @@ public class EaglerAdapterImpl2 {
for(int i = 0; i < b.length; ++i) { for(int i = 0; i < b.length; ++i) {
b[i] = (byte) (a.get(i) & 0xFF); b[i] = (byte) (a.get(i) & 0xFF);
} }
readPackets.add(b); ByteBuffer buffer = ByteBuffer.wrap(b);
receivedBuffers.add(buffer);
} }
}); });
} }
@ -1353,13 +1354,6 @@ public class EaglerAdapterImpl2 {
nativeBinarySend(sock, arr.getBuffer()); nativeBinarySend(sock, arr.getBuffer());
} }
} }
public static final byte[] readPacket() {
if(!readPackets.isEmpty()) {
return readPackets.remove(0);
}else {
return null;
}
}
public static final byte[] loadLocalStorage(String key) { public static final byte[] loadLocalStorage(String key) {
String s = win.getLocalStorage().getItem("_eaglercraft_beta."+key); String s = win.getLocalStorage().getItem("_eaglercraft_beta."+key);
if(s != null) { if(s != null) {