diff --git a/pom.xml b/pom.xml
index 37f9238..71de372 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.loohp
Limbo
Limbo
- 0.6.10-ALPHA
+ 0.6.11-ALPHA
Standalone Limbo Minecraft Server.
https://github.com/LOOHP/Limbo
@@ -230,7 +230,7 @@
net.md-5
bungeecord-chat
- 1.17-R0.1-SNAPSHOT
+ 1.18-R0.1-SNAPSHOT
jar
compile
diff --git a/src/main/java/com/loohp/limbo/network/Channel.java b/src/main/java/com/loohp/limbo/network/Channel.java
index 1f96c6e..a50a22a 100644
--- a/src/main/java/com/loohp/limbo/network/Channel.java
+++ b/src/main/java/com/loohp/limbo/network/Channel.java
@@ -1,5 +1,155 @@
package com.loohp.limbo.network;
-public class Channel {
+import com.loohp.limbo.network.protocol.packets.Packet;
+import com.loohp.limbo.network.protocol.packets.PacketIn;
+import com.loohp.limbo.network.protocol.packets.PacketOut;
+import com.loohp.limbo.utils.DataTypeIO;
+import com.loohp.limbo.utils.NamespacedKey;
+import com.loohp.limbo.utils.Pair;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
+
+public class Channel implements AutoCloseable {
+
+ private final ClientConnection clientConnection;
+ private final List> handlers;
+ private final AtomicBoolean valid;
+ protected DataOutputStream output;
+ protected DataInputStream input;
+
+ public Channel(ClientConnection clientConnection, DataOutputStream output, DataInputStream input) {
+ this.clientConnection = clientConnection;
+ this.output = output;
+ this.input = input;
+ this.handlers = new CopyOnWriteArrayList<>();
+ this.valid = new AtomicBoolean(true);
+ }
+
+ private void ensureOpen() {
+ if (!valid.get()) {
+ throw new IllegalStateException("Channel already closed!");
+ }
+ }
+
+ public void addBefore(NamespacedKey key, ChannelPacketHandler handler) {
+ handlers.add(0, new Pair<>(key, handler));
+ }
+
+ public void addAfter(NamespacedKey key, ChannelPacketHandler handler) {
+ handlers.add(new Pair<>(key, handler));
+ }
+
+ public void remove(NamespacedKey key) {
+ handlers.removeIf(each -> each.getFirst().equals(key));
+ }
+
+ protected PacketIn readPacket() throws Exception {
+ return readPacket(-1);
+ }
+
+ protected PacketIn readPacket(int size) throws Exception {
+ PacketIn packet = null;
+ do {
+ ensureOpen();
+ size = size < 0 ? DataTypeIO.readVarInt(input) : size;
+ int packetId = DataTypeIO.readVarInt(input);
+ Class extends PacketIn> packetType;
+ switch (clientConnection.getClientState()) {
+ case HANDSHAKE:
+ packetType = Packet.getHandshakeIn().get(packetId);
+ break;
+ case STATUS:
+ packetType = Packet.getStatusIn().get(packetId);
+ break;
+ case LOGIN:
+ packetType = Packet.getLoginIn().get(packetId);
+ break;
+ case PLAY:
+ packetType = Packet.getPlayIn().get(packetId);
+ break;
+ default:
+ throw new IllegalStateException("Illegal ClientState!");
+ }
+ if (packetType == null) {
+ input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
+ } else {
+ Constructor>[] constructors = packetType.getConstructors();
+ Constructor> constructor = Stream.of(constructors).filter(each -> each.getParameterCount() > 0 && each.getParameterTypes()[0].equals(DataInputStream.class)).findFirst().orElse(null);
+ if (constructor == null) {
+ throw new NoSuchMethodException(packetType + " has no valid constructors!");
+ } else if (constructor.getParameterCount() == 1) {
+ packet = (PacketIn) constructor.newInstance(input);
+ } else if (constructor.getParameterCount() == 3) {
+ packet = (PacketIn) constructor.newInstance(input, size, packetId);
+ } else {
+ throw new NoSuchMethodException(packetType + " has no valid constructors!");
+ }
+ ChannelPacketRead read = new ChannelPacketRead(packetId, packet);
+ for (Pair pair : handlers) {
+ read = pair.getSecond().read(read);
+ if (read == null) {
+ packet = null;
+ break;
+ }
+ packet = read.getPacket();
+ if (!packetType.isInstance(packet)) {
+ throw new IllegalStateException("Packet Handler \"" + pair.getFirst() + "\" changed the packet type illegally!");
+ }
+ }
+ }
+ size = -1;
+ } while (packet == null);
+ return packet;
+ }
+
+ protected boolean writePacket(PacketOut packet) throws IOException {
+ ensureOpen();
+ int packetId;
+ switch (clientConnection.getClientState()) {
+ case STATUS:
+ packetId = Packet.getStatusOut().get(packet.getClass());
+ break;
+ case LOGIN:
+ packetId = Packet.getLoginOut().get(packet.getClass());
+ break;
+ case PLAY:
+ packetId = Packet.getPlayOut().get(packet.getClass());
+ break;
+ default:
+ throw new IllegalStateException("Illegal ClientState!");
+ }
+ Class extends PacketOut> packetType = packet.getClass();
+ ChannelPacketWrite write = new ChannelPacketWrite(packet);
+ for (Pair pair : handlers) {
+ write = pair.getSecond().write(write);
+ if (write == null) {
+ return false;
+ }
+ if (!packetType.isInstance(write.getPacket())) {
+ throw new IllegalStateException("Packet Handler \"" + pair.getFirst() + "\" changed the packet type illegally!");
+ }
+ }
+ packet = write.getPacket();
+ byte[] packetByte = packet.serializePacket();
+ DataTypeIO.writeVarInt(output, packetByte.length);
+ output.write(packetByte);
+ output.flush();
+ return true;
+ }
+
+ @Override
+ public synchronized void close() throws Exception {
+ if (valid.compareAndSet(false, true)) {
+ input.close();
+ output.close();
+ }
+ }
}
diff --git a/src/main/java/com/loohp/limbo/network/ChannelPacketHandler.java b/src/main/java/com/loohp/limbo/network/ChannelPacketHandler.java
new file mode 100644
index 0000000..3212116
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/network/ChannelPacketHandler.java
@@ -0,0 +1,13 @@
+package com.loohp.limbo.network;
+
+public abstract class ChannelPacketHandler {
+
+ public ChannelPacketRead read(ChannelPacketRead read) {
+ return read;
+ }
+
+ public ChannelPacketWrite write(ChannelPacketWrite write) {
+ return write;
+ }
+
+}
diff --git a/src/main/java/com/loohp/limbo/network/ChannelPacketRead.java b/src/main/java/com/loohp/limbo/network/ChannelPacketRead.java
new file mode 100644
index 0000000..29437d0
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/network/ChannelPacketRead.java
@@ -0,0 +1,31 @@
+package com.loohp.limbo.network;
+
+import com.loohp.limbo.network.protocol.packets.PacketIn;
+
+public final class ChannelPacketRead {
+
+ private int packetId;
+ private PacketIn packet;
+
+ protected ChannelPacketRead(int packetId, PacketIn packet) {
+ this.packetId = packetId;
+ this.packet = packet;
+ }
+
+ public int getPacketId() {
+ return packetId;
+ }
+
+ public void setPacketId(int packetId) {
+ this.packetId = packetId;
+ }
+
+ public PacketIn getPacket() {
+ return packet;
+ }
+
+ public void setPacket(PacketIn packet) {
+ this.packet = packet;
+ }
+
+}
diff --git a/src/main/java/com/loohp/limbo/network/ChannelPacketWrite.java b/src/main/java/com/loohp/limbo/network/ChannelPacketWrite.java
new file mode 100644
index 0000000..79e8177
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/network/ChannelPacketWrite.java
@@ -0,0 +1,21 @@
+package com.loohp.limbo.network;
+
+import com.loohp.limbo.network.protocol.packets.PacketOut;
+
+public final class ChannelPacketWrite {
+
+ private PacketOut packet;
+
+ protected ChannelPacketWrite(PacketOut packet) {
+ this.packet = packet;
+ }
+
+ public PacketOut getPacket() {
+ return packet;
+ }
+
+ public void setPacket(PacketOut packet) {
+ this.packet = packet;
+ }
+
+}
diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java
index bd3952e..3063ca9 100644
--- a/src/main/java/com/loohp/limbo/network/ClientConnection.java
+++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java
@@ -19,6 +19,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
+import com.loohp.limbo.network.protocol.packets.PacketIn;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
@@ -113,9 +114,8 @@ public class ClientConnection extends Thread {
private TimerTask keepAliveTask;
private AtomicLong lastPacketTimestamp;
private AtomicLong lastKeepAlivePayLoad;
-
- private DataOutputStream output;
- private DataInputStream input;
+
+ protected Channel channel;
private InetAddress inetAddress;
@@ -126,6 +126,7 @@ public class ClientConnection extends Thread {
this.inetAddress = client_socket.getInetAddress();
this.lastPacketTimestamp = new AtomicLong(-1);
this.lastKeepAlivePayLoad = new AtomicLong(-1);
+ this.channel = new Channel(this, null, null);
this.running = false;
this.ready = false;
}
@@ -165,6 +166,10 @@ public class ClientConnection extends Thread {
public Socket getSocket() {
return client_socket;
}
+
+ public Channel getChannel() {
+ return channel;
+ }
public boolean isRunning() {
return running;
@@ -175,11 +180,9 @@ public class ClientConnection extends Thread {
}
public synchronized void sendPacket(PacketOut packet) throws IOException {
- byte[] packetByte = packet.serializePacket();
- DataTypeIO.writeVarInt(output, packetByte.length);
- output.write(packetByte);
- output.flush();
- setLastPacketTimestamp(System.currentTimeMillis());
+ if (channel.writePacket(packet)) {
+ setLastPacketTimestamp(System.currentTimeMillis());
+ }
}
public void disconnect(BaseComponent[] reason) {
@@ -190,10 +193,10 @@ public class ClientConnection extends Thread {
try {
PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(reason);
sendPacket(packet);
- } catch (IOException e) {}
+ } catch (IOException ignored) {}
try {
client_socket.close();
- } catch (IOException e) {}
+ } catch (IOException ignored) {}
}
private void disconnectDuringLogin(BaseComponent[] reason) {
@@ -204,10 +207,10 @@ public class ClientConnection extends Thread {
try {
PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(reason);
sendPacket(packet);
- } catch (IOException e) {}
+ } catch (IOException ignored) {}
try {
client_socket.close();
- } catch (IOException e) {}
+ } catch (IOException ignored) {}
}
@SuppressWarnings("deprecation")
@@ -217,31 +220,29 @@ public class ClientConnection extends Thread {
state = ClientState.HANDSHAKE;
try {
client_socket.setKeepAlive(true);
- input = new DataInputStream(client_socket.getInputStream());
- output = new DataOutputStream(client_socket.getOutputStream());
- int handShakeSize = DataTypeIO.readVarInt(input);
+ channel.input = new DataInputStream(client_socket.getInputStream());
+ channel.output = new DataOutputStream(client_socket.getOutputStream());
+ int handShakeSize = DataTypeIO.readVarInt(channel.input);
//legacy ping
if (handShakeSize == 0xFE) {
- state = ClientState.LEGACY;
- output.writeByte(255);
+ state = ClientState.LEGACY;
+ channel.output.writeByte(255);
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged");
ServerProperties p = Limbo.getInstance().getServerProperties();
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline());
byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE);
- output.writeShort(response.length());
- output.write(bytes);
-
+ channel.output.writeShort(response.length());
+ channel.output.write(bytes);
+
+ channel.close();
client_socket.close();
state = ClientState.DISCONNECTED;
}
-
- @SuppressWarnings("unused")
- int handShakeId = DataTypeIO.readVarInt(input);
-
- PacketHandshakingIn handshake = new PacketHandshakingIn(input);
+
+ PacketHandshakingIn handshake = (PacketHandshakingIn) channel.readPacket(handShakeSize);
boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord();
boolean isBungeeGuard = Limbo.getInstance().getServerProperties().isBungeeGuard();
@@ -255,24 +256,20 @@ public class ClientConnection extends Thread {
case STATUS:
state = ClientState.STATUS;
while (client_socket.isConnected()) {
- DataTypeIO.readVarInt(input);
- int packetId = DataTypeIO.readVarInt(input);
- Class extends Packet> packetType = Packet.getStatusIn().get(packetId);
- if (packetType == null) {
- //do nothing
- } else if (packetType.equals(PacketStatusInRequest.class)) {
+ PacketIn packetIn = channel.readPacket();
+ if (packetIn instanceof PacketStatusInRequest) {
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) {
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged");
}
ServerProperties p = Limbo.getInstance().getServerProperties();
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
- PacketStatusOutResponse packet = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon()));
- sendPacket(packet);
- } else if (packetType.equals(PacketStatusInPing.class)) {
- PacketStatusInPing ping = new PacketStatusInPing(input);
- PacketStatusOutPong packet = new PacketStatusOutPong(ping.getPayload());
- sendPacket(packet);
+ PacketStatusOutResponse response = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon()));
+ sendPacket(response);
+ } else if (packetIn instanceof PacketStatusInPing) {
+ PacketStatusInPing ping = (PacketStatusInPing) packetIn;
+ PacketStatusOutPong pong = new PacketStatusOutPong(ping.getPayload());
+ sendPacket(pong);
break;
}
}
@@ -318,14 +315,9 @@ public class ClientConnection extends Thread {
int messageId = this.random.nextInt();
while (client_socket.isConnected()) {
- int size = DataTypeIO.readVarInt(input);
- int packetId = DataTypeIO.readVarInt(input);
- Class extends Packet> packetType = Packet.getLoginIn().get(packetId);
-
- if (packetType == null) {
- input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
- } else if (packetType.equals(PacketLoginInLoginStart.class)) {
- PacketLoginInLoginStart start = new PacketLoginInLoginStart(input);
+ PacketIn packetIn = channel.readPacket();
+ if (packetIn instanceof PacketLoginInLoginStart) {
+ PacketLoginInLoginStart start = (PacketLoginInLoginStart) packetIn;
String username = start.getUsername();
if (Limbo.getInstance().getServerProperties().isVelocityModern()) {
@@ -346,8 +338,8 @@ public class ClientConnection extends Thread {
Limbo.getInstance().addPlayer(player);
break;
- } else if (packetType.equals(PacketLoginInPluginMessaging.class)) {
- PacketLoginInPluginMessaging response = new PacketLoginInPluginMessaging(input, size, packetId);
+ } else if (packetIn instanceof PacketLoginInPluginMessaging) {
+ PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn;
if (response.getMessageId() != messageId) {
disconnectDuringLogin(TextComponent.fromLegacyText("Internal error, messageId did not match"));
break;
@@ -375,8 +367,6 @@ public class ClientConnection extends Thread {
Limbo.getInstance().addPlayer(player);
break;
- } else {
- input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
}
}
@@ -388,6 +378,7 @@ public class ClientConnection extends Thread {
break;
}
} catch (Exception e) {
+ channel.close();
client_socket.close();
state = ClientState.DISCONNECTED;
}
@@ -487,10 +478,6 @@ public class ClientConnection extends Thread {
while (client_socket.isConnected()) {
try {
- int size = DataTypeIO.readVarInt(input);
- int packetId = DataTypeIO.readVarInt(input);
- Class extends Packet> packetType = Packet.getPlayIn().get(packetId);
- //Limbo.getInstance().getConsole().sendMessage(packetId + " -> " + packetType);
CheckedBiConsumer processMoveEvent = (event, originalTo) -> {
if (event.isCancelled()) {
Location returnTo = event.getFrom();
@@ -508,10 +495,9 @@ public class ClientConnection extends Thread {
sendPacket(response);
}
};
- if (packetType == null) {
- input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
- } else if (packetType.equals(PacketPlayInPositionAndLook.class)) {
- PacketPlayInPositionAndLook pos = new PacketPlayInPositionAndLook(input);
+ PacketIn packetIn = channel.readPacket();
+ if (packetIn instanceof PacketPlayInPositionAndLook) {
+ PacketPlayInPositionAndLook pos = (PacketPlayInPositionAndLook) packetIn;
Location from = player.getLocation();
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch());
@@ -519,8 +505,8 @@ public class ClientConnection extends Thread {
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
processMoveEvent.consume(event, to);
}
- } else if (packetType.equals(PacketPlayInPosition.class)) {
- PacketPlayInPosition pos = new PacketPlayInPosition(input);
+ } else if (packetIn instanceof PacketPlayInPosition) {
+ PacketPlayInPosition pos = (PacketPlayInPosition) packetIn;
Location from = player.getLocation();
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
@@ -528,8 +514,8 @@ public class ClientConnection extends Thread {
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
processMoveEvent.consume(event, to);
}
- } else if (packetType.equals(PacketPlayInRotation.class)) {
- PacketPlayInRotation pos = new PacketPlayInRotation(input);
+ } else if (packetIn instanceof PacketPlayInRotation) {
+ PacketPlayInRotation pos = (PacketPlayInRotation) packetIn;
Location from = player.getLocation();
Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch());
@@ -537,34 +523,32 @@ public class ClientConnection extends Thread {
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
processMoveEvent.consume(event, to);
}
- } else if (packetType.equals(PacketPlayInKeepAlive.class)) {
- PacketPlayInKeepAlive alive = new PacketPlayInKeepAlive(input);
+ } else if (packetIn instanceof PacketPlayInKeepAlive) {
+ PacketPlayInKeepAlive alive = (PacketPlayInKeepAlive) packetIn;
if (alive.getPayload() != getLastKeepAlivePayLoad()) {
- Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName());
+ Limbo.getInstance().getConsole().sendMessage("Incorrect Payload received in KeepAlive packet for player " + player.getName());
break;
}
- } else if (packetType.equals(PacketPlayInTabComplete.class)) {
- PacketPlayInTabComplete request = new PacketPlayInTabComplete(input);
+ } else if (packetIn instanceof PacketPlayInTabComplete) {
+ PacketPlayInTabComplete request = (PacketPlayInTabComplete) packetIn;
String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1));
- List matches = new ArrayList();
-
- matches.addAll(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList()));
-
+ List matches = new ArrayList(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList()));
+
int start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1) + 1;
int length = command[command.length - 1].length();
PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()]));
sendPacket(response);
- } else if (packetType.equals(PacketPlayInChat.class)) {
- PacketPlayInChat chat = new PacketPlayInChat(input);
+ } else if (packetIn instanceof PacketPlayInChat) {
+ PacketPlayInChat chat = (PacketPlayInChat) packetIn;
if (chat.getMessage().startsWith("/")) {
Limbo.getInstance().dispatchCommand(player, chat.getMessage());
} else {
player.chat(chat.getMessage(), true);
}
- } else if (packetType.equals(PacketPlayInHeldItemChange.class)) {
- PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input);
+ } else if (packetIn instanceof PacketPlayInHeldItemChange) {
+ PacketPlayInHeldItemChange change = (PacketPlayInHeldItemChange) packetIn;
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot()));
if (event.isCancelled()) {
PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot());
@@ -577,17 +561,14 @@ public class ClientConnection extends Thread {
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
}
- } else if (packetType.equals(PacketPlayInResourcePackStatus.class)) {
- PacketPlayInResourcePackStatus rpcheck = new PacketPlayInResourcePackStatus(input);
+ } else if (packetIn instanceof PacketPlayInResourcePackStatus) {
+ PacketPlayInResourcePackStatus rpcheck = (PacketPlayInResourcePackStatus) packetIn;
// Pass on result to the events
Limbo.getInstance().getEventsManager().callEvent(new PlayerResourcePackStatusEvent(player, rpcheck.getLoadedValue()));
if (rpcheck.getLoadedValue().equals(EnumResourcePackStatus.DECLINED) && properties.getResourcePackRequired()) {
player.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"));
}
- } else {
- input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
}
-
} catch (Exception e) {
break;
}
@@ -600,11 +581,12 @@ public class ClientConnection extends Thread {
}
- } catch (Exception e) {}
+ } catch (Exception ignored) {}
try {
+ channel.close();
client_socket.close();
- } catch (IOException e) {}
+ } catch (Exception ignored) {}
state = ClientState.DISCONNECTED;
if (player != null) {
diff --git a/src/main/java/com/loohp/limbo/network/protocol/packets/Packet.java b/src/main/java/com/loohp/limbo/network/protocol/packets/Packet.java
index 5366fc3..ecebc35 100644
--- a/src/main/java/com/loohp/limbo/network/protocol/packets/Packet.java
+++ b/src/main/java/com/loohp/limbo/network/protocol/packets/Packet.java
@@ -4,71 +4,71 @@ import java.util.Map;
public class Packet {
- private static Map> HandshakeIn;
+ private static Map> handshakeIn;
- private static Map> StatusIn;
- private static Map, Integer> StatusOut;
+ private static Map> statusIn;
+ private static Map, Integer> statusOut;
- private static Map> LoginIn;
- private static Map, Integer> LoginOut;
+ private static Map> loginIn;
+ private static Map, Integer> loginOut;
- private static Map> PlayIn;
- private static Map, Integer> PlayOut;
+ private static Map> playIn;
+ private static Map, Integer> playOut;
public static Map> getHandshakeIn() {
- return HandshakeIn;
+ return handshakeIn;
}
public static void setHandshakeIn(Map> handshakeIn) {
- HandshakeIn = handshakeIn;
+ Packet.handshakeIn = handshakeIn;
}
public static Map> getStatusIn() {
- return StatusIn;
+ return statusIn;
}
public static void setStatusIn(Map> statusIn) {
- StatusIn = statusIn;
+ Packet.statusIn = statusIn;
}
public static Map, Integer> getStatusOut() {
- return StatusOut;
+ return statusOut;
}
public static void setStatusOut(Map, Integer> statusOut) {
- StatusOut = statusOut;
+ Packet.statusOut = statusOut;
}
public static Map> getLoginIn() {
- return LoginIn;
+ return loginIn;
}
public static void setLoginIn(Map> loginIn) {
- LoginIn = loginIn;
+ Packet.loginIn = loginIn;
}
public static Map, Integer> getLoginOut() {
- return LoginOut;
+ return loginOut;
}
public static void setLoginOut(Map, Integer> loginOut) {
- LoginOut = loginOut;
+ Packet.loginOut = loginOut;
}
public static Map> getPlayIn() {
- return PlayIn;
+ return playIn;
}
public static void setPlayIn(Map> playIn) {
- PlayIn = playIn;
+ Packet.playIn = playIn;
}
public static Map, Integer> getPlayOut() {
- return PlayOut;
+ return playOut;
}
public static void setPlayOut(Map, Integer> playOut) {
- PlayOut = playOut;
+ Packet.playOut = playOut;
}
}
diff --git a/src/main/java/com/loohp/limbo/network/protocol/packets/PacketPlayInPluginMessaging.java b/src/main/java/com/loohp/limbo/network/protocol/packets/PacketPlayInPluginMessaging.java
index ffd4758..93736bd 100644
--- a/src/main/java/com/loohp/limbo/network/protocol/packets/PacketPlayInPluginMessaging.java
+++ b/src/main/java/com/loohp/limbo/network/protocol/packets/PacketPlayInPluginMessaging.java
@@ -22,7 +22,7 @@ public class PacketPlayInPluginMessaging extends PacketIn {
channel = new NamespacedKey(rawChannel);
int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8);
data = new byte[dataLength];
- in.read(data);
+ in.readFully(data);
}
public NamespacedKey getChannel() {
diff --git a/src/main/java/com/loohp/limbo/utils/DataTypeIO.java b/src/main/java/com/loohp/limbo/utils/DataTypeIO.java
index d9f7331..d858a1e 100644
--- a/src/main/java/com/loohp/limbo/utils/DataTypeIO.java
+++ b/src/main/java/com/loohp/limbo/utils/DataTypeIO.java
@@ -52,7 +52,7 @@ public class DataTypeIO {
public static int getStringLength(String string, Charset charset) throws IOException {
byte[] bytes = string.getBytes(charset);
- return bytes.length;
+ return getVarIntLength(bytes.length) + bytes.length;
}
public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException {
diff --git a/src/main/java/com/loohp/limbo/utils/Pair.java b/src/main/java/com/loohp/limbo/utils/Pair.java
new file mode 100644
index 0000000..47465d5
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/utils/Pair.java
@@ -0,0 +1,40 @@
+package com.loohp.limbo.utils;
+
+import java.util.Objects;
+
+public class Pair {
+
+ private final F first;
+ private final S second;
+
+ public Pair(F first, S second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public F getFirst() {
+ return first;
+ }
+
+ public S getSecond() {
+ return second;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Pair, ?> pair = (Pair, ?>) o;
+ return Objects.equals(first, pair.first) && Objects.equals(second, pair.second);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(first, second);
+ }
+
+}
diff --git a/src/main/resources/mapping.json b/src/main/resources/mapping.json
index af1be8e..d3a9162 100644
--- a/src/main/resources/mapping.json
+++ b/src/main/resources/mapping.json
@@ -46,7 +46,7 @@
"PacketPlayOutHeldItemChange": "0x48",
"PacketPlayOutPlayerListHeaderFooter": "0x5F",
"PacketPlayOutResourcePackSend": "0x3C",
- "ClientboundSetTitlesAnimationPacket": "0x5B",
+ "ClientboundSetTitlesAnimationPacket": "0x5B",
"ClientboundSetTitleTextPacket": "0x5A",
"ClientboundSetSubtitleTextPacket": "0x58",
"ClientboundClearTitlesPacket": "0x10"
@@ -59,4 +59,4 @@
"PacketStatusOutResponse": "0x00",
"PacketStatusOutPong": "0x01"
}
-}
+}
\ No newline at end of file