From 89427cb2dadd897ba85762da8ef059f61d900681 Mon Sep 17 00:00:00 2001 From: Myles Date: Mon, 14 Mar 2016 18:05:29 +0000 Subject: [PATCH] PacketWrapper now has an ID attached and can be reset so that it can be read from stored values. Removed some parameters from protocol, the ID will now be attached to the PacketWrapper (made more sense) BaseProtocol doesn't handle ProtocolInfo anymore Implement ProtocolPipeline (WIP) --- .../myles/ViaVersion2/api/PacketWrapper.java | 49 ++++++++++++++----- .../ViaVersion2/api/protocol/Protocol.java | 22 ++------- .../api/protocol/ProtocolPipeline.java | 47 ++++++++++++++++++ .../api/protocol/base/BaseProtocol.java | 2 +- .../api/protocol/base/ProtocolInfo.java | 2 + .../packets/EntityPackets.java | 3 +- .../packets/PlayerPackets.java | 4 +- .../packets/SpawnPackets.java | 2 - 8 files changed, 94 insertions(+), 37 deletions(-) create mode 100644 src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java diff --git a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java index 49816f7e2..39bfc9a24 100644 --- a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java +++ b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java @@ -2,21 +2,30 @@ package us.myles.ViaVersion2.api; import com.google.common.base.Preconditions; import io.netty.buffer.ByteBuf; +import lombok.Getter; +import lombok.Setter; import us.myles.ViaVersion2.api.data.UserConnection; import us.myles.ViaVersion2.api.remapper.ValueCreator; import us.myles.ViaVersion2.api.type.Type; import us.myles.ViaVersion2.api.util.Pair; +import java.io.IOException; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; public class PacketWrapper { private final ByteBuf inputBuffer; private final UserConnection userConnection; private boolean send = true; + @Setter + @Getter + private int id = -1; + private LinkedList> readableObjects = new LinkedList<>(); private List> packetValues = new ArrayList<>(); - public PacketWrapper(ByteBuf inputBuffer, UserConnection userConnection) { + public PacketWrapper(int packetID, ByteBuf inputBuffer, UserConnection userConnection) { + this.id = packetID; this.inputBuffer = inputBuffer; this.userConnection = userConnection; } @@ -49,10 +58,19 @@ public class PacketWrapper { } public T read(Type type) throws Exception { - Preconditions.checkNotNull(inputBuffer, "This packet does not have an input buffer."); - System.out.println("Reading: " + type.getTypeName()); - // We could in the future log input read values, but honestly for things like bulk maps, mem waste D: - return type.read(inputBuffer); + if (readableObjects.isEmpty()) { + Preconditions.checkNotNull(inputBuffer, "This packet does not have an input buffer."); + System.out.println("Reading: " + type.getTypeName()); + // We could in the future log input read values, but honestly for things like bulk maps, mem waste D: + return type.read(inputBuffer); + } else { + Pair read = readableObjects.poll(); + if (read.getKey().equals(type)) { + return (T) read.getValue(); + } else { + throw new IOException("Unable to read type " + type.getTypeName() + ", found " + type.getTypeName()); + } + } } @@ -68,12 +86,17 @@ public class PacketWrapper { } public void writeToBuffer(ByteBuf buffer) throws Exception { + if (id != -1) { + Type.VAR_INT.write(buffer, id); + } + for (Pair packetValue : packetValues) { packetValue.getKey().write(buffer, packetValue.getValue()); } + writeRemaining(buffer); } - public void writeRemaining(ByteBuf output) { + private void writeRemaining(ByteBuf output) { if (inputBuffer != null) { System.out.println("Writing remaining: " + output.readableBytes()); output.writeBytes(inputBuffer); @@ -83,17 +106,15 @@ public class PacketWrapper { public void send() throws Exception { ByteBuf output = inputBuffer.alloc().buffer(); writeToBuffer(output); - writeRemaining(output); - user().sendRawPacket(output); } - public PacketWrapper create() throws Exception { - return new PacketWrapper(null, user()); + public PacketWrapper create(int packetID) throws Exception { + return new PacketWrapper(packetID, null, user()); } - public PacketWrapper create(ValueCreator init) throws Exception { - PacketWrapper wrapper = create(); + public PacketWrapper create(int packetID, ValueCreator init) throws Exception { + PacketWrapper wrapper = create(packetID); init.write(wrapper); return wrapper; } @@ -109,4 +130,8 @@ public class PacketWrapper { public UserConnection user() { return this.userConnection; } + + public void resetReader() { + this.readableObjects.addAll(packetValues); + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java b/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java index 60b68b9a0..09c9467a5 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java @@ -1,6 +1,5 @@ package us.myles.ViaVersion2.api.protocol; -import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Getter; import us.myles.ViaVersion.CancelException; @@ -8,17 +7,13 @@ import us.myles.ViaVersion.packets.Direction; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.data.UserConnection; -import us.myles.ViaVersion2.api.protocol.base.BaseProtocol; import us.myles.ViaVersion2.api.remapper.PacketRemapper; -import us.myles.ViaVersion2.api.type.Type; import us.myles.ViaVersion2.api.util.Pair; import java.util.HashMap; import java.util.Map; public abstract class Protocol { - public static final Protocol BASE_PROTOCOL = new BaseProtocol(); - private Map, ProtocolPacket> incoming = new HashMap<>(); private Map, ProtocolPacket> outgoing = new HashMap<>(); @@ -48,32 +43,25 @@ public abstract class Protocol { outgoing.put(new Pair<>(state, oldPacketID), protocolPacket); } - public void transform(Direction direction, State state, int packetID, PacketWrapper packetWrapper, ByteBuf output) throws Exception { - Pair statePacket = new Pair<>(state, packetID); + public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception { + Pair statePacket = new Pair<>(state, packetWrapper.getId()); Map, ProtocolPacket> packetMap = (direction == Direction.OUTGOING ? outgoing : incoming); ProtocolPacket protocolPacket; if (packetMap.containsKey(statePacket)) { protocolPacket = packetMap.get(statePacket); } else { - System.out.println("Packet not found: " + packetID); - // simply translate - Type.VAR_INT.write(output, packetID); - // pass through - packetWrapper.writeRemaining(output); + System.out.println("Packet not found: " + packetWrapper.getId()); return; } // write packet id - Type.VAR_INT.write(output, direction == Direction.OUTGOING ? protocolPacket.getNewID() : protocolPacket.getOldID()); + int newID = direction == Direction.OUTGOING ? protocolPacket.getNewID() : protocolPacket.getOldID(); + packetWrapper.setId(newID); // remap if (protocolPacket.getRemapper() != null) { protocolPacket.getRemapper().remap(packetWrapper); if(packetWrapper.isCancelled()) throw new CancelException(); - // write to output - packetWrapper.writeToBuffer(output); } - // pass through - packetWrapper.writeRemaining(output); } @AllArgsConstructor diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java new file mode 100644 index 000000000..236010455 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java @@ -0,0 +1,47 @@ +package us.myles.ViaVersion2.api.protocol; + +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.CancelException; +import us.myles.ViaVersion.packets.Direction; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion2.api.PacketWrapper; +import us.myles.ViaVersion2.api.data.UserConnection; +import us.myles.ViaVersion2.api.protocol.base.BaseProtocol; +import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; + +import java.util.ArrayList; +import java.util.LinkedList; + +public class ProtocolPipeline extends Protocol { + LinkedList protocolList = new LinkedList<>(); + + @Override + protected void registerPackets() { + // This is a pipeline so we register basic pipes + protocolList.addLast(new BaseProtocol()); + } + + @Override + public void init(UserConnection userConnection) { + ProtocolInfo protocolInfo = new ProtocolInfo(); + protocolInfo.setPipeline(this); + + userConnection.put(protocolInfo); + + /* Init through all our pipes */ + for (Protocol protocol : protocolList) { + protocol.init(userConnection); + } + } + + @Override + public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception { + + for (Protocol protocol : new ArrayList<>(protocolList)) { // Copy to prevent from removal. + protocol.transform(direction, state, packetWrapper); + // Reset the reader for the packetWrapper (So it can be recycled across packets) + packetWrapper.resetReader(); + } + super.transform(direction, state, packetWrapper); + } +} diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java b/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java index 8697450b4..6c967922b 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java @@ -107,6 +107,6 @@ public class BaseProtocol extends Protocol { @Override public void init(UserConnection userConnection) { - userConnection.put(new ProtocolInfo()); + // Nothing gets added, ProtocolPipeline handles ProtocolInfo } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java b/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java index faf2255f7..22157c220 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.Setter; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.data.StoredObject; +import us.myles.ViaVersion2.api.protocol.ProtocolPipeline; import java.util.UUID; @@ -14,4 +15,5 @@ public class ProtocolInfo extends StoredObject{ private int protocolVersion = -1; private String username; private UUID uuid; + private ProtocolPipeline pipeline; } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java index 4aa1093e9..512d7011f 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java @@ -40,8 +40,7 @@ public class EntityPackets { wrapper.cancel(); // Don't send current packet - PacketWrapper passengerPacket = wrapper.create(); - passengerPacket.write(Type.VAR_INT, 0x40); // Passenger Packet ID + PacketWrapper passengerPacket = wrapper.create(0x40); // Passenger Packet ID if (vehicle == -1) { if (!tracker.getVehicleMap().containsKey(passenger)) return null; // Cancel diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java index 0102d75c7..4bde41b18 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java @@ -136,7 +136,7 @@ public class PlayerPackets { map(Type.UNSIGNED_BYTE); // 4 - Max Players (Tab) map(Type.STRING); // 5 - Level Type map(Type.BOOLEAN); // 6 - Reduced Debug info - + handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { @@ -228,9 +228,7 @@ public class PlayerPackets { protocol.registerOutgoing(State.PLAY, 0x3F, 0x18); // Plugin Message // TODO: - // Login Success - Save UUID and Username // Server Difficulty - Activate Auto-Team - // TODO: Status Response, implement? (Might be implemented by a base protocol?) /* Incoming Packets */ diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java index ba747cfd0..7da9a7580 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java @@ -197,9 +197,7 @@ public class SpawnPackets { }); map(Type.STRING); // 2 - Title - map(Type.POSITION); // 3 - Position - map(Type.BYTE); // 4 - Direction } });