diff --git a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java index 09b883a55..49816f7e2 100644 --- a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java +++ b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java @@ -1,7 +1,9 @@ package us.myles.ViaVersion2.api; +import com.google.common.base.Preconditions; import io.netty.buffer.ByteBuf; 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; @@ -11,6 +13,7 @@ import java.util.List; public class PacketWrapper { private final ByteBuf inputBuffer; private final UserConnection userConnection; + private boolean send = true; private List> packetValues = new ArrayList<>(); public PacketWrapper(ByteBuf inputBuffer, UserConnection userConnection) { @@ -46,6 +49,7 @@ 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); @@ -70,8 +74,36 @@ public class PacketWrapper { } public void writeRemaining(ByteBuf output) { - System.out.println("Writing remaining: " + output.readableBytes()); - output.writeBytes(inputBuffer); + if (inputBuffer != null) { + System.out.println("Writing remaining: " + output.readableBytes()); + output.writeBytes(inputBuffer); + } + } + + 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(ValueCreator init) throws Exception { + PacketWrapper wrapper = create(); + init.write(wrapper); + return wrapper; + } + + public void cancel() { + this.send = false; + } + + public boolean isCancelled() { + return !this.send; } public UserConnection user() { diff --git a/src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java b/src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java index a1cd97968..9d1206ff6 100644 --- a/src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java +++ b/src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java @@ -1,11 +1,20 @@ package us.myles.ViaVersion2.api.data; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.socket.SocketChannel; + import java.util.ArrayList; import java.util.List; public class UserConnection { + private final SocketChannel channel; List storedObjects = new ArrayList<>(); + public UserConnection(SocketChannel socketChannel) { + this.channel = socketChannel; + } + public T get(Class objectClass) { for (StoredObject o : storedObjects) { if (o.getClass().equals(objectClass)) @@ -25,4 +34,22 @@ public class UserConnection { public void put(StoredObject object) { storedObjects.add(object); } + + public void sendRawPacket(final ByteBuf packet, boolean currentThread) { + final ChannelHandler handler = channel.pipeline().get("encoder"); + if (currentThread) { + channel.pipeline().context(handler).writeAndFlush(packet); + } else { + channel.eventLoop().submit(new Runnable() { + @Override + public void run() { + channel.pipeline().context(handler).writeAndFlush(packet); + } + }); + } + } + + public void sendRawPacket(final ByteBuf packet) { + sendRawPacket(packet, false); + } } 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 0bce245c8..60b68b9a0 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java @@ -3,6 +3,7 @@ package us.myles.ViaVersion2.api.protocol; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Getter; +import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.packets.Direction; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.PacketWrapper; @@ -66,6 +67,8 @@ public abstract class Protocol { // remap if (protocolPacket.getRemapper() != null) { protocolPacket.getRemapper().remap(packetWrapper); + if(packetWrapper.isCancelled()) + throw new CancelException(); // write to output packetWrapper.writeToBuffer(output); } 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 774ac0eb3..4aa1093e9 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 @@ -1,9 +1,12 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.packets; +import us.myles.ViaVersion.ViaVersionPlugin; +import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.protocol.Protocol; import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker; import us.myles.ViaVersion2.api.remapper.PacketHandler; import us.myles.ViaVersion2.api.remapper.PacketRemapper; import us.myles.ViaVersion2.api.remapper.ValueTransformer; @@ -29,9 +32,26 @@ public class EntityPackets { // Leash boolean is removed in new versions map(Type.BOOLEAN, new ValueTransformer(Type.NOTHING) { @Override - public Void transform(PacketWrapper wrapper, Boolean inputValue) { + public Void transform(PacketWrapper wrapper, Boolean inputValue) throws Exception { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); if (!inputValue) { - // TODO: Write Set Passengers packet + int passenger = wrapper.get(Type.VAR_INT, 0); + int vehicle = wrapper.get(Type.VAR_INT, 1); + + wrapper.cancel(); // Don't send current packet + + PacketWrapper passengerPacket = wrapper.create(); + passengerPacket.write(Type.VAR_INT, 0x40); // Passenger Packet ID + if (vehicle == -1) { + if (!tracker.getVehicleMap().containsKey(passenger)) + return null; // Cancel + passengerPacket.write(Type.VAR_INT, tracker.getVehicleMap().remove(passenger)); + passengerPacket.write(Type.VAR_INT_ARRAY, new Integer[]{}); + } else { + passengerPacket.write(Type.VAR_INT, vehicle); + passengerPacket.write(Type.VAR_INT_ARRAY, new Integer[]{passenger}); + } + passengerPacket.send(); // Send the packet } return null; } @@ -53,7 +73,20 @@ public class EntityPackets { map(Type.BOOLEAN); // 6 - On Ground - // TODO: Move holograms up on Y by offset (*32) + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityID = wrapper.get(Type.VAR_INT, 0); + if (((ViaVersionPlugin) ViaVersion.getInstance()).isHologramPatch()) { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + if (tracker.getKnownHolograms().contains(entityID)) { + Double newValue = wrapper.get(Type.DOUBLE, 1); + newValue += (32D * ((ViaVersionPlugin) ViaVersion.getInstance()).getHologramYOffset()); + wrapper.set(Type.DOUBLE, 1, newValue); + } + } + } + }); } }); // Entity Look Move Packet @@ -71,7 +104,20 @@ public class EntityPackets { map(Type.BOOLEAN); // 6 - On Ground - // TODO: Hologram patch moves down by 1 in Y + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityID = wrapper.get(Type.VAR_INT, 0); + if (((ViaVersionPlugin) ViaVersion.getInstance()).isHologramPatch()) { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + if (tracker.getKnownHolograms().contains(entityID)) { + Short newValue = wrapper.get(Type.SHORT, 1); + newValue = (short) (newValue + (((ViaVersionPlugin) ViaVersion.getInstance()).getHologramYOffset())); + wrapper.set(Type.SHORT, 1, newValue); + } + } + } + }); } }); // Entity Relative Move Packet @@ -86,7 +132,20 @@ public class EntityPackets { map(Type.BOOLEAN); // 4 - On Ground - // TODO: Hologram patch moves down by 1 in Y + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int entityID = wrapper.get(Type.VAR_INT, 0); + if (((ViaVersionPlugin) ViaVersion.getInstance()).isHologramPatch()) { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + if (tracker.getKnownHolograms().contains(entityID)) { + Short newValue = wrapper.get(Type.SHORT, 1); + newValue = (short) (newValue + (((ViaVersionPlugin) ViaVersion.getInstance()).getHologramYOffset())); + wrapper.set(Type.SHORT, 1, newValue); + } + } + } + }); } }); // Entity Equipment Packet @@ -158,9 +217,17 @@ public class EntityPackets { map(Type.VAR_INT); // 0 - Player ID map(Type.VAR_INT); // 1 - Action map(Type.VAR_INT); // 2 - Jump - - // TODO: If action is 6 or 8 cancel - // If action is 7 change to 6 + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int action = wrapper.get(Type.VAR_INT, 1); + if (action == 6 || action == 8) + wrapper.cancel(); + if (action == 7) { + wrapper.set(Type.VAR_INT, 1, 6); + } + } + }); } }); 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 544526ea4..0102d75c7 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,8 +136,15 @@ public class PlayerPackets { map(Type.UNSIGNED_BYTE); // 4 - Max Players (Tab) map(Type.STRING); // 5 - Level Type map(Type.BOOLEAN); // 6 - Reduced Debug info - - // TODO Register player ID as self ID + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int myID = wrapper.get(Type.INT, 0); + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + tracker.setEntityID(myID); + } + }); } }); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java index 625da36fa..75366775c 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java @@ -97,8 +97,14 @@ public class WorldPackets { map(Type.UNSIGNED_BYTE); // 0 - Status map(Type.POSITION); // 1 - Position map(Type.UNSIGNED_BYTE); // 2 - Face - - // TODO: Cancel if status == 6 + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int status = wrapper.get(Type.UNSIGNED_BYTE, 0); + if(status == 6) + wrapper.cancel(); + } + }); // TODO: Blocking patch stopped if blocking and 5 } }); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java index 42d85f0a8..10c059636 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java @@ -1,18 +1,23 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.storage; import lombok.Getter; +import lombok.Setter; import org.bukkit.entity.EntityType; +import us.myles.ViaVersion.api.boss.BossBar; import us.myles.ViaVersion2.api.data.StoredObject; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; @Getter public class EntityTracker extends StoredObject{ private final Map uuidMap = new HashMap<>(); private final Map clientEntityTypes = new HashMap<>(); private final Map vehicleMap = new HashMap<>(); + private final Map bossBarMap = new HashMap<>(); + private final Set validBlocking = new HashSet<>(); + private final Set knownHolograms = new HashSet<>(); + @Setter + private int entityID; public UUID getEntityUUID(int id) { if (uuidMap.containsKey(id)) { @@ -26,5 +31,14 @@ public class EntityTracker extends StoredObject{ public void removeEntity(Integer entityID) { clientEntityTypes.remove(entityID); + vehicleMap.remove(entityID); + uuidMap.remove(entityID); + validBlocking.remove(entityID); + knownHolograms.remove(entityID); + + BossBar bar = bossBarMap.remove(entityID); + if (bar != null) { + bar.hide(); + } } } diff --git a/src/main/java/us/myles/ViaVersion2/api/remapper/ValueTransformer.java b/src/main/java/us/myles/ViaVersion2/api/remapper/ValueTransformer.java index e3df6aa20..cf9eea803 100644 --- a/src/main/java/us/myles/ViaVersion2/api/remapper/ValueTransformer.java +++ b/src/main/java/us/myles/ViaVersion2/api/remapper/ValueTransformer.java @@ -10,10 +10,10 @@ public abstract class ValueTransformer implements ValueWriter { this.outputType = outputType; } - public abstract T2 transform(PacketWrapper wrapper, T1 inputValue); + public abstract T2 transform(PacketWrapper wrapper, T1 inputValue) throws Exception; @Override - public void write(PacketWrapper writer, T1 inputValue) { + public void write(PacketWrapper writer, T1 inputValue) throws Exception { writer.write(outputType, transform(writer, inputValue)); } }