forked from BLOCKFANTASY/LOOHP-Limbo
Made packet intercepting possible
This commit is contained in:
parent
00600647ae
commit
4353859951
4
pom.xml
4
pom.xml
|
|
@ -5,7 +5,7 @@
|
|||
<groupId>com.loohp</groupId>
|
||||
<artifactId>Limbo</artifactId>
|
||||
<name>Limbo</name>
|
||||
<version>0.6.10-ALPHA</version>
|
||||
<version>0.6.11-ALPHA</version>
|
||||
|
||||
<description>Standalone Limbo Minecraft Server.</description>
|
||||
<url>https://github.com/LOOHP/Limbo</url>
|
||||
|
|
@ -230,7 +230,7 @@
|
|||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-chat</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<version>1.18-R0.1-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
|
|
|||
|
|
@ -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<Pair<NamespacedKey, ChannelPacketHandler>> 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<NamespacedKey, ChannelPacketHandler> 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<NamespacedKey, ChannelPacketHandler> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -114,8 +115,7 @@ public class ClientConnection extends Thread {
|
|||
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;
|
||||
}
|
||||
|
|
@ -166,6 +167,10 @@ public class ClientConnection extends Thread {
|
|||
return client_socket;
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
|
@ -175,12 +180,10 @@ 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();
|
||||
if (channel.writePacket(packet)) {
|
||||
setLastPacketTimestamp(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect(BaseComponent[] reason) {
|
||||
disconnect(BungeecordAdventureConversionUtils.toComponent(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);
|
||||
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<PlayerMoveEvent, Location, IOException> 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<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>();
|
||||
|
||||
matches.addAll(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList()));
|
||||
List<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>(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) {
|
||||
|
|
|
|||
|
|
@ -4,71 +4,71 @@ import java.util.Map;
|
|||
|
||||
public class Packet {
|
||||
|
||||
private static Map<Integer, Class<? extends PacketIn>> HandshakeIn;
|
||||
private static Map<Integer, Class<? extends PacketIn>> handshakeIn;
|
||||
|
||||
private static Map<Integer, Class<? extends PacketIn>> StatusIn;
|
||||
private static Map<Class<? extends PacketOut>, Integer> StatusOut;
|
||||
private static Map<Integer, Class<? extends PacketIn>> statusIn;
|
||||
private static Map<Class<? extends PacketOut>, Integer> statusOut;
|
||||
|
||||
private static Map<Integer, Class<? extends PacketIn>> LoginIn;
|
||||
private static Map<Class<? extends PacketOut>, Integer> LoginOut;
|
||||
private static Map<Integer, Class<? extends PacketIn>> loginIn;
|
||||
private static Map<Class<? extends PacketOut>, Integer> loginOut;
|
||||
|
||||
private static Map<Integer, Class<? extends PacketIn>> PlayIn;
|
||||
private static Map<Class<? extends PacketOut>, Integer> PlayOut;
|
||||
private static Map<Integer, Class<? extends PacketIn>> playIn;
|
||||
private static Map<Class<? extends PacketOut>, Integer> playOut;
|
||||
|
||||
public static Map<Integer, Class<? extends PacketIn>> getHandshakeIn() {
|
||||
return HandshakeIn;
|
||||
return handshakeIn;
|
||||
}
|
||||
|
||||
public static void setHandshakeIn(Map<Integer, Class<? extends PacketIn>> handshakeIn) {
|
||||
HandshakeIn = handshakeIn;
|
||||
Packet.handshakeIn = handshakeIn;
|
||||
}
|
||||
|
||||
public static Map<Integer, Class<? extends PacketIn>> getStatusIn() {
|
||||
return StatusIn;
|
||||
return statusIn;
|
||||
}
|
||||
|
||||
public static void setStatusIn(Map<Integer, Class<? extends PacketIn>> statusIn) {
|
||||
StatusIn = statusIn;
|
||||
Packet.statusIn = statusIn;
|
||||
}
|
||||
|
||||
public static Map<Class<? extends PacketOut>, Integer> getStatusOut() {
|
||||
return StatusOut;
|
||||
return statusOut;
|
||||
}
|
||||
|
||||
public static void setStatusOut(Map<Class<? extends PacketOut>, Integer> statusOut) {
|
||||
StatusOut = statusOut;
|
||||
Packet.statusOut = statusOut;
|
||||
}
|
||||
|
||||
public static Map<Integer, Class<? extends PacketIn>> getLoginIn() {
|
||||
return LoginIn;
|
||||
return loginIn;
|
||||
}
|
||||
|
||||
public static void setLoginIn(Map<Integer, Class<? extends PacketIn>> loginIn) {
|
||||
LoginIn = loginIn;
|
||||
Packet.loginIn = loginIn;
|
||||
}
|
||||
|
||||
public static Map<Class<? extends PacketOut>, Integer> getLoginOut() {
|
||||
return LoginOut;
|
||||
return loginOut;
|
||||
}
|
||||
|
||||
public static void setLoginOut(Map<Class<? extends PacketOut>, Integer> loginOut) {
|
||||
LoginOut = loginOut;
|
||||
Packet.loginOut = loginOut;
|
||||
}
|
||||
|
||||
public static Map<Integer, Class<? extends PacketIn>> getPlayIn() {
|
||||
return PlayIn;
|
||||
return playIn;
|
||||
}
|
||||
|
||||
public static void setPlayIn(Map<Integer, Class<? extends PacketIn>> playIn) {
|
||||
PlayIn = playIn;
|
||||
Packet.playIn = playIn;
|
||||
}
|
||||
|
||||
public static Map<Class<? extends PacketOut>, Integer> getPlayOut() {
|
||||
return PlayOut;
|
||||
return playOut;
|
||||
}
|
||||
|
||||
public static void setPlayOut(Map<Class<? extends PacketOut>, Integer> playOut) {
|
||||
PlayOut = playOut;
|
||||
Packet.playOut = playOut;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.loohp.limbo.utils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Pair<F, S> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue