forked from BLOCKFANTASY/LOOHP-Limbo
Changes to ChannelRead
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package com.loohp.limbo.network;
|
||||
|
||||
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;
|
||||
@@ -10,24 +9,20 @@ 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;
|
||||
protected final DataInputStream input;
|
||||
protected final DataOutputStream output;
|
||||
|
||||
public Channel(ClientConnection clientConnection, DataOutputStream output, DataInputStream input) {
|
||||
this.clientConnection = clientConnection;
|
||||
this.output = output;
|
||||
public Channel(DataInputStream input, DataOutputStream output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.handlers = new CopyOnWriteArrayList<>();
|
||||
this.valid = new AtomicBoolean(true);
|
||||
}
|
||||
@@ -54,55 +49,20 @@ public class Channel implements AutoCloseable {
|
||||
return readPacket(-1);
|
||||
}
|
||||
|
||||
protected PacketIn readPacket(int size) throws Exception {
|
||||
protected PacketIn readPacket(int size) throws IOException {
|
||||
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);
|
||||
ChannelPacketRead read = new ChannelPacketRead(size, packetId, input);
|
||||
for (Pair<NamespacedKey, ChannelPacketHandler> pair : handlers) {
|
||||
read = pair.getSecond().read(read);
|
||||
if (read == null) {
|
||||
packet = null;
|
||||
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!");
|
||||
}
|
||||
}
|
||||
packet = read.getReadPacket();
|
||||
}
|
||||
size = -1;
|
||||
} while (packet == null);
|
||||
@@ -111,30 +71,12 @@ public class Channel implements AutoCloseable {
|
||||
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user