From 8eb92b2c4778503ec1ad5912dc2008920d041240 Mon Sep 17 00:00:00 2001 From: PeytonPlayz595 <106421860+PeytonPlayz595@users.noreply.github.com> Date: Mon, 18 Dec 2023 13:50:13 -0500 Subject: [PATCH] WebSockets --- .../minecraft/server/MinecraftServer.java | 159 ++++++------------ src/com/mojang/net/NetworkHandler.java | 51 +++--- src/net/io/DummyLogger.java | 39 +++++ src/net/io/WebSocketNetworkManager.java | 119 +++++++++++++ 4 files changed, 232 insertions(+), 136 deletions(-) create mode 100644 src/net/io/DummyLogger.java create mode 100644 src/net/io/WebSocketNetworkManager.java diff --git a/src/com/mojang/minecraft/server/MinecraftServer.java b/src/com/mojang/minecraft/server/MinecraftServer.java index ab66368..c29ed7f 100644 --- a/src/com/mojang/minecraft/server/MinecraftServer.java +++ b/src/com/mojang/minecraft/server/MinecraftServer.java @@ -20,7 +20,6 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.net.URLEncoder; -import java.nio.channels.SocketChannel; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -286,14 +285,10 @@ public class MinecraftServer implements Runnable { try { NetworkHandler var3 = var10.networkHandler; - try { - if(var3.out.position() > 0) { - var3.out.flip(); - var3.channel.write(var3.out); - var3.out.compact(); - } - } catch (IOException var6) { - ; + if(var3.out.position() > 0) { + var3.out.flip(); + var3.write(var3.out); + var3.out.compact(); } if(var10.b-- <= 0) { @@ -332,120 +327,68 @@ public class MinecraftServer implements Runnable { } } - try { - BindTo var13 = this.bindTo; + BindTo var13 = this.bindTo; + NetworkHandler var2 = new NetworkHandler(8080); + var13.c.add(var2); - SocketChannel var14; - while((var14 = var13.serverChannel.accept()) != null) { - try { - var14.configureBlocking(false); - NetworkHandler var2 = new NetworkHandler(var14); - var13.c.add(var2); - NetworkHandler var3 = var2; - MinecraftServer var4 = var13.server; - if(var13.server.playerManager3.containsPlayer(var2.address)) { - var2.send(PacketType.DISCONNECT, new Object[]{"You\'re banned!"}); - logger.info(var2.address + " tried to connect, but is banned."); - var4.b(var2); - } else { - int var5 = 0; - Iterator var6 = var4.n.iterator(); + for(int var17 = 0; var17 < var13.c.size(); ++var17) { + NetworkHandler var15 = (NetworkHandler)var13.c.get(var17); - while(var6.hasNext()) { - if(((NetworkManager)var6.next()).networkHandler.address.equals(var3.address)) { - ++var5; - } - } + try { + NetworkHandler var20 = var15; + var15.read(var15.in); + int var19 = 0; - if(var5 >= var4.maxConnections) { - var3.send(PacketType.DISCONNECT, new Object[]{"Too many connection!"}); - logger.info(var3.address + " tried to connect, but is already connected " + var5 + " times."); - var4.b(var3); - } else { - int var24; - if((var24 = var4.e()) < 0) { - var3.send(PacketType.DISCONNECT, new Object[]{"The server is full!"}); - logger.info(var3.address + " tried to connect, but failed because the server was full."); - var4.b(var3); - } else { - NetworkManager var16 = new NetworkManager(var4, var3, var24); - logger.info(var16 + " connected"); - var4.m.put(var3, var16); - var4.n.add(var16); - if(var16.playerID >= 0) { - var4.networkManager[var16.playerID] = var16; - } - } - } + while(var20.in.position() > 0 && var19++ != 100) { + var20.in.flip(); + byte var22 = var20.in.get(0); + PacketType var25; + if((var25 = PacketType.packets[var22]) == null) { + throw new IOException("Bad command: " + var22); } - } catch (IOException var10) { - var14.close(); - throw var10; - } - } - - for(int var17 = 0; var17 < var13.c.size(); ++var17) { - NetworkHandler var15 = (NetworkHandler)var13.c.get(var17); - - try { - NetworkHandler var20 = var15; - var15.channel.read(var15.in); - int var19 = 0; - - while(var20.in.position() > 0 && var19++ != 100) { - var20.in.flip(); - byte var22 = var20.in.get(0); - PacketType var25; - if((var25 = PacketType.packets[var22]) == null) { - throw new IOException("Bad command: " + var22); - } - - if(var20.in.remaining() < var25.length + 1) { - var20.in.compact(); - break; - } - - var20.in.get(); - Object[] var21 = new Object[var25.params.length]; - - for(int var7 = 0; var7 < var21.length; ++var7) { - var21[var7] = var20.receive(var25.params[var7]); - } - - var20.networkManager.a(var25, var21); - if(!var20.connected) { - break; - } + if(var20.in.remaining() < var25.length + 1) { var20.in.compact(); + break; } - if(var20.out.position() > 0) { - var20.out.flip(); - var20.channel.write(var20.out); - var20.out.compact(); + var20.in.get(); + Object[] var21 = new Object[var25.params.length]; + + for(int var7 = 0; var7 < var21.length; ++var7) { + var21[var7] = var20.receive(var25.params[var7]); } - } catch (Exception var9) { - MinecraftServer var10001 = var13.server; - NetworkManager var23; - if((var23 = (NetworkManager)var13.server.m.get(var15)) != null) { - var23.a(var9); + + var20.networkManager.a(var25, var21); + if(!var20.connected) { + break; } + + var20.in.compact(); } - try { - if(!var15.connected) { - var15.close(); - var13.server.a(var15); - var13.c.remove(var17--); - } - } catch (Exception var8) { - var8.printStackTrace(); + if(var20.out.position() > 0) { + var20.out.flip(); + var20.write(var20.out); + var20.out.compact(); + } + } catch (Exception var9) { + MinecraftServer var10001 = var13.server; + NetworkManager var23; + if((var23 = (NetworkManager)var13.server.m.get(var15)) != null) { + var23.a(var9); } } - } catch (IOException var11) { - throw new RuntimeException("IOException while ticking socketserver", var11); + try { + if(!var15.connected) { + var15.close(); + var13.server.a(var15); + var13.c.remove(var17--); + } + } catch (Exception var8) { + var8.printStackTrace(); + } } } diff --git a/src/com/mojang/net/NetworkHandler.java b/src/com/mojang/net/NetworkHandler.java index 2abb110..80f9287 100644 --- a/src/com/mojang/net/NetworkHandler.java +++ b/src/com/mojang/net/NetworkHandler.java @@ -2,50 +2,40 @@ package com.mojang.net; import com.mojang.minecraft.net.PacketType; import com.mojang.minecraft.server.NetworkManager; -import java.net.Socket; -import java.net.SocketException; + +import net.io.DummyLogger; +import net.io.WebSocketNetworkManager; + import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; import java.util.Arrays; +import org.eclipse.jetty.util.log.Log; + public final class NetworkHandler { public volatile boolean connected; - public SocketChannel channel; public ByteBuffer in = ByteBuffer.allocate(1048576); public ByteBuffer out = ByteBuffer.allocate(1048576); public NetworkManager networkManager; - private Socket socket; private boolean h = false; public String address; private byte[] stringBytes = new byte[64]; - public NetworkHandler(SocketChannel var1) { - try { - this.channel = var1; - this.channel.configureBlocking(false); - System.currentTimeMillis(); - this.socket = this.channel.socket(); - this.connected = true; - this.in.clear(); - this.out.clear(); - this.socket.setTcpNoDelay(true); - this.socket.setTrafficClass(24); - this.socket.setKeepAlive(false); - this.socket.setReuseAddress(false); - this.socket.setSoTimeout(100); - this.address = this.socket.getInetAddress().toString(); - } catch(Exception e) { - e.printStackTrace(); - } + public NetworkHandler(int port) { + Log.setLog(new DummyLogger()); + try { + WebSocketNetworkManager.startServer(port); + } catch (Exception e) { + e.printStackTrace(); + } } public final void close() { try { if(this.out.position() > 0) { this.out.flip(); - this.channel.write(this.out); + this.write(this.out); this.out.compact(); } } catch (Exception var2) { @@ -55,13 +45,10 @@ public final class NetworkHandler { this.connected = false; try { - this.channel.close(); + WebSocketNetworkManager.stopServer(); } catch (Exception var1) { ; } - - this.socket = null; - this.channel = null; } public final void send(PacketType var1, Object ... var2) { @@ -155,4 +142,12 @@ public final class NetworkHandler { } } } + + public void read(ByteBuffer buf) { + WebSocketNetworkManager.read(buf); + } + + public void write(ByteBuffer buf) { + WebSocketNetworkManager.write(buf); + } } diff --git a/src/net/io/DummyLogger.java b/src/net/io/DummyLogger.java new file mode 100644 index 0000000..03ba1f5 --- /dev/null +++ b/src/net/io/DummyLogger.java @@ -0,0 +1,39 @@ +package net.io; + +import org.eclipse.jetty.util.log.Logger; + +public class DummyLogger implements Logger { + + public String getName() { + return "DummyLogger"; + } + + public void warn(String msg, Object... args) {} + + public void warn(Throwable thrown) {} + + public void warn(String msg, Throwable thrown) {} + + public void info(String msg, Object... args) {} + + public void info(Throwable thrown) {} + + public void info(String msg, Throwable thrown) {} + + public boolean isDebugEnabled() {return false; } + + public void setDebugEnabled(boolean enabled) {} + + public void debug(String msg, Object... args) {} + + public void debug(Throwable thrown) {} + + public void debug(String msg, Throwable thrown) {} + + public Logger getLogger(String name) {return this; } + + public void ignore(Throwable ignored) {} + + public void debug(String msg, long value) {} + +} \ No newline at end of file diff --git a/src/net/io/WebSocketNetworkManager.java b/src/net/io/WebSocketNetworkManager.java new file mode 100644 index 0000000..824a14a --- /dev/null +++ b/src/net/io/WebSocketNetworkManager.java @@ -0,0 +1,119 @@ +package net.io; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.*; +import org.eclipse.jetty.websocket.server.WebSocketHandler; +import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; +import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; +import org.eclipse.jetty.websocket.servlet.WebSocketCreator; +import org.eclipse.jetty.websocket.servlet.WebSocketServlet; +import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.*; + +@WebSocket +public class WebSocketNetworkManager extends WebSocketServlet { + private static Set sessions = new HashSet(); + public static int port; + private static Queue receivedBuffers = new ArrayDeque(); + private static ByteBuffer writeBuffer; + + @Override + public void configure(WebSocketServletFactory factory) { + factory.register(WebSocketNetworkManager.class); + } + + @OnWebSocketConnect + public void onConnect(Session session) { + sessions.add(session); + } + + @OnWebSocketMessage + public void onMessage(byte[] data, int offset, int length) { + ByteBuffer buffer = ByteBuffer.wrap(data, offset, length); + receivedBuffers.add(buffer); + } + + @OnWebSocketClose + public void onClose(Session session, int statusCode, String reason) { + sessions.remove(session); + } + + @OnWebSocketError + public void onError(Session session, Throwable throwable) { + System.out.println(throwable.getMessage()); + } + + public static void startServer(int port) throws Exception { + WebSocketNetworkManager.port = port; + + org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server(port); + WebSocketHandler wsHandler = new WebSocketHandler() { + @Override + public void configure(WebSocketServletFactory factory) { + factory.setCreator(new WebSocketCreator() { + public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { + return new WebSocketNetworkManager(); + } + }); + } + }; + server.setHandler(wsHandler); + server.start(); + } + + public static void stopServer() { + for (Session session : sessions) { + session.close(); + } + } + + public static void read(ByteBuffer buf) { + int bytesRead = 0; + while (bytesRead < buf.capacity()) { + if (!receivedBuffers.isEmpty()) { + ByteBuffer receivedBuffer = 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) { + receivedBuffers.poll(); + } + } else { + break; + } + } + } + + public static 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); + for(Session session : sessions) { + try { + session.getRemote().sendBytes(ByteBuffer.wrap(data)); + } catch (IOException e) { + e.printStackTrace(); + } + } + writeBuffer.clear(); + } + + if (buf.remaining() > 0) { + write(buf); + } + } +} \ No newline at end of file