Rewrite multiplayer with WebSockets
This commit is contained in:
parent
8d441465b1
commit
e80061e7ba
File diff suppressed because one or more lines are too long
|
@ -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) {
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user