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)
This commit is contained in:
Myles 2016-03-14 18:05:29 +00:00
parent fce7f1740e
commit 89427cb2da
8 changed files with 94 additions and 37 deletions

View File

@ -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<Pair<Type, Object>> readableObjects = new LinkedList<>();
private List<Pair<Type, Object>> 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> T read(Type<T> 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<Type, Object> 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<Type, Object> 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);
}
}

View File

@ -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<Pair<State, Integer>, ProtocolPacket> incoming = new HashMap<>();
private Map<Pair<State, Integer>, 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<State, Integer> statePacket = new Pair<>(state, packetID);
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
Pair<State, Integer> statePacket = new Pair<>(state, packetWrapper.getId());
Map<Pair<State, Integer>, 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

View File

@ -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<Protocol> 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);
}
}

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -197,9 +197,7 @@ public class SpawnPackets {
});
map(Type.STRING); // 2 - Title
map(Type.POSITION); // 3 - Position
map(Type.BYTE); // 4 - Direction
}
});