diff --git a/src/main/java/us/myles/ViaVersion/ViaIdleThread.java b/src/main/java/us/myles/ViaVersion/ViaIdleThread.java index 31ce146db..6cf782ada 100644 --- a/src/main/java/us/myles/ViaVersion/ViaIdleThread.java +++ b/src/main/java/us/myles/ViaVersion/ViaIdleThread.java @@ -3,15 +3,19 @@ package us.myles.ViaVersion; import org.bukkit.scheduler.BukkitRunnable; import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.util.ReflectionUtil; +import us.myles.ViaVersion2.api.data.UserConnection; +import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; +import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.MovementTracker; import java.util.Map; import java.util.UUID; public class ViaIdleThread extends BukkitRunnable { - private final Map portedPlayers; + private final Map portedPlayers; private final Class idlePacketClass; - public ViaIdleThread(Map portedPlayers) { + public ViaIdleThread(Map portedPlayers) { this.portedPlayers = portedPlayers; try { this.idlePacketClass = ReflectionUtil.nms("PacketPlayInFlying"); @@ -22,19 +26,21 @@ public class ViaIdleThread extends BukkitRunnable { @Override public void run() { - for(ConnectionInfo info : portedPlayers.values()) { - long nextIdleUpdate = info.getNextIdlePacket(); - if(nextIdleUpdate <= System.currentTimeMillis()) { - try { - Object packet = idlePacketClass.newInstance(); - info.getChannel().pipeline().fireChannelRead(packet); - } catch(InstantiationException | IllegalAccessException e) { - System.out.println("Failed to create idle packet."); - if(ViaVersion.getInstance().isDebug()) { - e.printStackTrace(); + for(UserConnection info : portedPlayers.values()) { + if(info.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) { + long nextIdleUpdate = info.get(MovementTracker.class).getNextIdlePacket(); + if (nextIdleUpdate <= System.currentTimeMillis()) { + try { + Object packet = idlePacketClass.newInstance(); + info.getChannel().pipeline().fireChannelRead(packet); + } catch (InstantiationException | IllegalAccessException e) { + System.out.println("Failed to create idle packet."); + if (ViaVersion.getInstance().isDebug()) { + e.printStackTrace(); + } + } finally { + info.get(MovementTracker.class).incrementIdlePacket(); } - } finally { - info.incrementIdlePacket(); } } } diff --git a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index 3457228d7..3dbe21463 100644 --- a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -27,6 +27,8 @@ import us.myles.ViaVersion.update.UpdateUtil; import us.myles.ViaVersion.util.Configuration; import us.myles.ViaVersion.util.ListWrapper; import us.myles.ViaVersion.util.ReflectionUtil; +import us.myles.ViaVersion2.api.data.UserConnection; +import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; import java.io.File; import java.lang.reflect.Field; @@ -41,7 +43,7 @@ import java.util.concurrent.TimeUnit; public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { - private final Map portedPlayers = new ConcurrentHashMap<>(); + private final Map portedPlayers = new ConcurrentHashMap<>(); private boolean debug = false; public static ItemStack getHandItem(final ConnectionInfo info) { @@ -212,7 +214,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { @Override public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException { if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not on 1.9"); - ConnectionInfo ci = portedPlayers.get(uuid); + UserConnection ci = portedPlayers.get(uuid); ci.sendRawPacket(packet); } @@ -269,8 +271,8 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { return getConfig().getBoolean("auto-team", true); } - public void addPortedClient(ConnectionInfo info) { - portedPlayers.put(info.getUUID(), info); + public void addPortedClient(UserConnection info) { + portedPlayers.put(info.get(ProtocolInfo.class).getUuid(), info); } public void removePortedClient(UUID clientID) { diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 3339d840d..d1c18b47a 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -313,7 +313,7 @@ public class OutgoingTransformer { PacketUtil.writeString(uuid, output); UUID uniqueId = UUID.fromString(uuid); info.setUUID(uniqueId); - plugin.addPortedClient(info); + // plugin.addPortedClient(info); String username = PacketUtil.readString(input); info.setUsername(username); PacketUtil.writeString(username, output); diff --git a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java index 631c7a7cd..fa387d17f 100644 --- a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java +++ b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java @@ -94,7 +94,7 @@ public class PacketWrapper { System.out.println("writing: " + packetValue.getKey().getTypeName() + " value: " + packetValue.getValue() + " ID: " + getId()); try { Object value = packetValue.getValue(); - if(value != null) { + if (value != null) { if (!value.getClass().equals(packetValue.getKey().getOutputClass())) { // attempt conversion if (packetValue.getKey() instanceof TypeConverter) { @@ -105,20 +105,25 @@ public class PacketWrapper { } } packetValue.getKey().write(buffer, value); - }catch (Exception e){ + } catch (Exception e) { System.out.println(getId() + " Index: " + index + " Type: " + packetValue.getKey().getTypeName()); throw e; } index++; } - if(packetValues.size() != 0){ - if(inputBuffer != null){ + if (packetValues.size() != 0) { + if (inputBuffer != null) { System.out.println(">> Writing remaining: " + inputBuffer.readableBytes() + " ID: " + getId()); } } writeRemaining(buffer); } + public void clearInputBuffer() { + if (inputBuffer != null) + inputBuffer.clear(); + } + private void writeRemaining(ByteBuf output) { if (inputBuffer != null) { output.writeBytes(inputBuffer); 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 cbf372164..1a5065f73 100644 --- a/src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java +++ b/src/main/java/us/myles/ViaVersion2/api/data/UserConnection.java @@ -14,6 +14,7 @@ public class UserConnection { @Getter @Setter private boolean active = true; + @Getter private final SocketChannel channel; @Getter @Setter diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java index 873645337..79ab84421 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java @@ -62,4 +62,11 @@ public class ProtocolPipeline extends Protocol { super.transform(direction, state, packetWrapper); System.out.println("--> Sending Packet ID: " + packetWrapper.getId() + " " + state + " " + direction); } + + public boolean contains(Class pipeClass){ + for(Protocol protocol:protocolList){ + if(protocol.getClass().equals(pipeClass)) return true; + } + return false; + } } 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 2aded92f8..ae1b50e9a 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 @@ -3,6 +3,8 @@ package us.myles.ViaVersion2.api.protocol.base; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; +import us.myles.ViaVersion.ViaVersionPlugin; +import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion2.api.PacketWrapper; @@ -57,12 +59,14 @@ public class BaseProtocol extends Protocol { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) { - System.out.println("play state"); ProtocolInfo info = wrapper.user().get(ProtocolInfo.class); info.setState(State.PLAY); + // Save other info UUID uuid = UUID.fromString(wrapper.get(Type.STRING, 0)); info.setUuid(uuid); info.setUsername(wrapper.get(Type.STRING, 1)); + // Add to ported clients + ((ViaVersionPlugin) ViaVersion.getInstance()).addPortedClient(wrapper.user()); } }); } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/ItemRewriter.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/ItemRewriter.java new file mode 100644 index 000000000..ffc3091d0 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/ItemRewriter.java @@ -0,0 +1,251 @@ +package us.myles.ViaVersion2.api.protocol1_9to1_8; + +import org.bukkit.Material; +import org.spacehq.opennbt.tag.builtin.CompoundTag; +import org.spacehq.opennbt.tag.builtin.ListTag; +import org.spacehq.opennbt.tag.builtin.StringTag; +import org.spacehq.opennbt.tag.builtin.Tag; +import us.myles.ViaVersion.transformers.OutgoingTransformer; +import us.myles.ViaVersion2.api.item.Item; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class ItemRewriter { + + private static final Map ENTTIY_NAME_TO_ID = new HashMap<>(); + private static final Map ENTTIY_ID_TO_NAME = new HashMap<>(); + private static final Map POTION_NAME_TO_ID = new HashMap<>(); + private static final Map POTION_ID_TO_NAME = new HashMap<>(); + + static { + /* Entities */ + registerEntity(1, "Item"); + registerEntity(2, "XPOrb"); + registerEntity(7, "ThrownEgg"); + registerEntity(8, "LeashKnot"); + registerEntity(9, "Painting"); + registerEntity(10, "Arrow"); + registerEntity(11, "Snowball"); + registerEntity(12, "Fireball"); + registerEntity(13, "SmallFireball"); + registerEntity(14, "ThrownEnderpearl"); + registerEntity(15, "EyeOfEnderSignal"); + registerEntity(16, "ThrownPotion"); + registerEntity(17, "ThrownExpBottle"); + registerEntity(18, "ItemFrame"); + registerEntity(19, "WitherSkull"); + registerEntity(20, "PrimedTnt"); + registerEntity(21, "FallingSand"); + registerEntity(22, "FireworksRocketEntity"); + registerEntity(30, "ArmorStand"); + registerEntity(40, "MinecartCommandBlock"); + registerEntity(41, "Boat"); + registerEntity(42, "MinecartRideable"); + registerEntity(43, "MinecartChest"); + registerEntity(44, "MinecartFurnace"); + registerEntity(45, "MinecartTNT"); + registerEntity(46, "MinecartHopper"); + registerEntity(47, "MinecartSpawner"); + registerEntity(48, "Mob"); + registerEntity(49, "Monster"); + registerEntity(50, "Creeper"); + registerEntity(51, "Skeleton"); + registerEntity(52, "Spider"); + registerEntity(53, "Giant"); + registerEntity(54, "Zombie"); + registerEntity(55, "Slime"); + registerEntity(56, "Ghast"); + registerEntity(57, "PigZombie"); + registerEntity(58, "Enderman"); + registerEntity(59, "CaveSpider"); + registerEntity(60, "Silverfish"); + registerEntity(61, "Blaze"); + registerEntity(62, "LavaSlime"); + registerEntity(63, "EnderDragon"); + registerEntity(64, "WitherBoss"); + registerEntity(65, "Bat"); + registerEntity(66, "Witch"); + registerEntity(67, "Endermite"); + registerEntity(68, "Guardian"); + registerEntity(90, "Pig"); + registerEntity(91, "Sheep"); + registerEntity(92, "Cow"); + registerEntity(93, "Chicken"); + registerEntity(94, "Squid"); + registerEntity(95, "Wolf"); + registerEntity(96, "MushroomCow"); + registerEntity(97, "SnowMan"); + registerEntity(98, "Ozelot"); + registerEntity(99, "VillagerGolem"); + registerEntity(100, "EntityHorse"); + registerEntity(101, "Rabbit"); + registerEntity(120, "Villager"); + registerEntity(200, "EnderCrystal"); + + /* Potions */ + registerPotion(0, "water"); + registerPotion(64, "mundane"); + registerPotion(32, "thick"); + registerPotion(16, "awkward"); + + registerPotion(8198, "night_vision"); + registerPotion(8262, "long_night_vision"); + + registerPotion(8206, "invisibility"); + registerPotion(8270, "long_invisibility"); + + registerPotion(8203, "leaping"); + registerPotion(8267, "long_leaping"); + registerPotion(8235, "strong_leaping"); + + registerPotion(8195, "fire_resistance"); + registerPotion(8259, "long_fire_resistance"); + + registerPotion(8194, "swiftness"); + registerPotion(8258, "long_swiftness"); + registerPotion(8226, "strong_swiftness"); + + registerPotion(8202, "slowness"); + registerPotion(8266, "long_slowness"); + + registerPotion(8205, "water_breathing"); + registerPotion(8269, "long_water_breathing"); + + registerPotion(8197, "healing"); + registerPotion(8229, "strong_healing"); + + registerPotion(8204, "harming"); + registerPotion(8236, "strong_harming"); + + registerPotion(8196, "poison"); + registerPotion(8260, "long_poison"); + registerPotion(8228, "strong_poison"); + + registerPotion(8193, "regeneration"); + registerPotion(8257, "long_regeneration"); + registerPotion(8225, "strong_regeneration"); + + registerPotion(8201, "strength"); + registerPotion(8265, "long_strength"); + registerPotion(8233, "strong_strength"); + + registerPotion(8200, "weakness"); + registerPotion(8264, "long_weakness"); + + } + + public static void toServer(Item item) { + if (item != null) { + if (item.getId() == Material.MONSTER_EGG.getId() && item.getData() == 0) { + CompoundTag tag = item.getTag(); + int data = 0; + if (tag != null && tag.get("EntityTag") instanceof CompoundTag) { + CompoundTag entityTag = tag.get("EntityTag"); + if (entityTag.get("id") instanceof StringTag) { + StringTag id = entityTag.get("id"); + if (ENTTIY_NAME_TO_ID.containsKey(id.getValue())) + data = ENTTIY_NAME_TO_ID.get(id.getValue()); + } + } + item.setTag(null); + item.setData((short) data); + } + if (item.getId() == Material.POTION.getId()) { + CompoundTag tag = item.getTag(); + int data = 0; + if (tag != null && tag.get("Potion") instanceof StringTag) { + StringTag potion = tag.get("Potion"); + String potionName = potion.getValue().replace("minecraft:", ""); + if (POTION_NAME_TO_ID.containsKey(potionName)) { + data = POTION_NAME_TO_ID.get(potionName); + } + } + item.setTag(null); + item.setData((short) data); + } + if (item.getId() == 438) { + CompoundTag tag = item.getTag(); + int data = 0; + item.setId((short) Material.POTION.getId()); + if (tag != null && tag.get("Potion") instanceof StringTag) { + StringTag potion = tag.get("Potion"); + String potionName = potion.getValue().replace("minecraft:", ""); + if (POTION_NAME_TO_ID.containsKey(potionName)) { + data = POTION_NAME_TO_ID.get(potionName) + 8192; + } + } + item.setTag(null); + item.setData((short) data); + } + } + } + + public static void toClient(Item item) { + if (item != null) { + if (item.getId() == Material.MONSTER_EGG.getId() && item.getData() != 0) { + CompoundTag tag = item.getTag(); + if (tag == null) { + tag = new CompoundTag("tag"); + } + CompoundTag entityTag = new CompoundTag("EntityTag"); + if (ENTTIY_ID_TO_NAME.containsKey((int) item.getData())) { + StringTag id = new StringTag("id", ENTTIY_ID_TO_NAME.get((int) item.getData())); + entityTag.put(id); + tag.put(entityTag); + } + item.setTag(tag); + item.setData((short) 0); + } + if (item.getId() == Material.POTION.getId()) { + CompoundTag tag = item.getTag(); + if (tag == null) { + tag = new CompoundTag("tag"); + } + if (item.getData() >= 16384) { + item.setId((short) 438); // splash id + item.setData((short) (item.getData() - 8192)); + } + if (POTION_ID_TO_NAME.containsKey((int) item.getData())) { + String name = POTION_ID_TO_NAME.get((int) item.getData()); + StringTag potion = new StringTag("Potion", "minecraft:" + name); + tag.put(potion); + } + item.setTag(tag); + item.setData((short) 0); + } + if (item.getId() == Material.WRITTEN_BOOK.getId()) { + CompoundTag tag = item.getTag(); + if (tag == null) { + tag = new CompoundTag("tag"); + } + ListTag pages = tag.get("pages"); + if (pages == null) { + pages = new ListTag("pages", Collections.singletonList(new StringTag(OutgoingTransformer.fixJson("")))); + tag.put(pages); + item.setTag(tag); + return; + } + + for (int i = 0; i < pages.size(); i++) { + if (!(pages.get(i) instanceof StringTag)) + continue; + StringTag page = pages.get(i); + page.setValue(OutgoingTransformer.fixJson(page.getValue())); + } + item.setTag(tag); + } + } + } + + private static void registerEntity(Integer id, String name) { + ENTTIY_ID_TO_NAME.put(id, name); + ENTTIY_NAME_TO_ID.put(name, id); + } + + private static void registerPotion(Integer id, String name) { + POTION_ID_TO_NAME.put(id, name); + POTION_NAME_TO_ID.put(name, id); + } +} diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/PlayerMovementMapper.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/PlayerMovementMapper.java new file mode 100644 index 000000000..ad8e8069a --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/PlayerMovementMapper.java @@ -0,0 +1,18 @@ +package us.myles.ViaVersion2.api.protocol1_9to1_8; + +import us.myles.ViaVersion2.api.PacketWrapper; +import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.MovementTracker; +import us.myles.ViaVersion2.api.remapper.PacketHandler; +import us.myles.ViaVersion2.api.remapper.PacketRemapper; + +public class PlayerMovementMapper extends PacketRemapper { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.user().get(MovementTracker.class).incrementIdlePacket(); + } + }); + } +} diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java index b8b06ed1f..af067fb2b 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java @@ -9,6 +9,7 @@ import us.myles.ViaVersion2.api.protocol.Protocol; import us.myles.ViaVersion2.api.protocol1_9to1_8.packets.*; import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.ClientChunks; import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.MovementTracker; import us.myles.ViaVersion2.api.protocol1_9to1_8.types.MetadataListType; import us.myles.ViaVersion2.api.protocol1_9to1_8.types.MetadataType; import us.myles.ViaVersion2.api.remapper.ValueTransformer; @@ -61,5 +62,7 @@ public class Protocol1_9TO1_8 extends Protocol { userConnection.put(new EntityTracker()); // Chunk tracker userConnection.put(new ClientChunks()); + // Movement tracker + userConnection.put(new MovementTracker()); } } 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 c4aa30eb3..9e0cf40f2 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 @@ -4,8 +4,10 @@ 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.item.Item; import us.myles.ViaVersion2.api.metadata.Metadata; import us.myles.ViaVersion2.api.protocol.Protocol; +import us.myles.ViaVersion2.api.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion2.api.protocol1_9to1_8.metadata.MetadataRewriter; import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker; @@ -172,7 +174,13 @@ public class EntityPackets { // TODO - Blocking patch - // TODO - ItemStack rewriter + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.ITEM, 0); + ItemRewriter.toClient(stack); + } + }); } }); // Entity Metadata Packet diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java index 71e18961e..c8d6dc92d 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java @@ -2,7 +2,9 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.packets; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.PacketWrapper; +import us.myles.ViaVersion2.api.item.Item; import us.myles.ViaVersion2.api.protocol.Protocol; +import us.myles.ViaVersion2.api.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion2.api.remapper.PacketHandler; import us.myles.ViaVersion2.api.remapper.PacketRemapper; @@ -47,7 +49,13 @@ public class InventoryPackets { map(Type.SHORT); // 1 - Slot ID map(Type.ITEM); // 2 - Slot Value // TODO Brewing patch - // TODO - ItemStack rewriter + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.ITEM, 0); + ItemRewriter.toClient(stack); + } + }); } }); // Window Set Slots Packet @@ -59,7 +67,14 @@ public class InventoryPackets { map(Type.ITEM_ARRAY); // 1 - Window Values // TODO Brewing patch - // TODO - ItemStack rewriter + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0); + for (Item stack : stacks) + ItemRewriter.toClient(stack); + } + }); } }); // Close Window Packet @@ -103,7 +118,13 @@ public class InventoryPackets { public void registerMap() { map(Type.SHORT); map(Type.ITEM); - // TODO: Transform Item Patch + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.ITEM, 0); + ItemRewriter.toServer(stack); + } + }); } }); @@ -118,7 +139,13 @@ public class InventoryPackets { map(Type.SHORT); map(Type.BYTE); map(Type.ITEM); - // TODO: Transform Item Patch + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.ITEM, 0); + ItemRewriter.toServer(stack); + } + }); // TODO: Throw elytra and brewing patch } }); @@ -132,10 +159,6 @@ public class InventoryPackets { } }); - - - // TODO Use Item - /* Packets which do not have any field remapping or handlers */ protocol.registerIncoming(State.PLAY, 0x0F, 0x05); // Confirm Transaction Packet 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 ba7de7d7a..2786195f7 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 @@ -6,6 +6,7 @@ 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.PlayerMovementMapper; 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; @@ -225,8 +226,6 @@ public class PlayerPackets { protocol.registerOutgoing(State.PLAY, 0x06, 0x3E); // Update Health Packet protocol.registerOutgoing(State.PLAY, 0x0D, 0x49); // Collect Item Packet - protocol.registerOutgoing(State.PLAY, 0x3F, 0x18); // Plugin Message - // TODO: // Server Difficulty - Activate Auto-Team @@ -301,16 +300,28 @@ public class PlayerPackets { } }); - // Use Item TODO + // Use Item Packet protocol.registerIncoming(State.PLAY, -1, 0x1D, new PacketRemapper() { @Override public void registerMap() { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { - wrapper.cancel(); + // Wipe the input buffer + wrapper.clearInputBuffer(); + // First set this packet ID to Block placement + wrapper.setId(0x08); + wrapper.write(Type.LONG, -1L); + wrapper.write(Type.BYTE, (byte) 255); + // Write item in hand + wrapper.write(Type.SHORT, (short) -1); // TODO + + wrapper.write(Type.BYTE, (byte) 0); + wrapper.write(Type.BYTE, (byte) 0); + wrapper.write(Type.BYTE, (byte) 0); } }); + } }); @@ -323,10 +334,10 @@ public class PlayerPackets { protocol.registerIncoming(State.PLAY, 0x00, 0x0B); // Keep Alive Request Packet - protocol.registerIncoming(State.PLAY, 0x04, 0x0C); // Player Position Packet - protocol.registerIncoming(State.PLAY, 0x06, 0x0D); // Player Move & Look Packet - protocol.registerIncoming(State.PLAY, 0x05, 0x0E); // Player Look Packet - protocol.registerIncoming(State.PLAY, 0x03, 0x0F); // Player Packet + protocol.registerIncoming(State.PLAY, 0x04, 0x0C, new PlayerMovementMapper()); // Player Position Packet + protocol.registerIncoming(State.PLAY, 0x06, 0x0D, new PlayerMovementMapper()); // Player Move & Look Packet + protocol.registerIncoming(State.PLAY, 0x05, 0x0E, new PlayerMovementMapper()); // Player Look Packet + protocol.registerIncoming(State.PLAY, 0x03, 0x0F, new PlayerMovementMapper()); // Player Packet // TODO Plugin Channels :( protocol.registerIncoming(State.PLAY, 0x17, 0x09); // plugin message incoming 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 5fce89129..4ce3417dc 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 @@ -170,7 +170,7 @@ public class SpawnPackets { map(Type.SHORT); // 11 - Velocity Z map(Protocol1_9TO1_8.METADATA_LIST); - + // TODO: Metadata detector for bossbars, wither stuff. handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { @@ -267,7 +267,6 @@ public class SpawnPackets { for (Integer entity : entities) { // EntityTracker wrapper.user().get(EntityTracker.class).removeEntity(entity); - // TODO: When holograms added and bossbars, remove too } } }); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java new file mode 100644 index 000000000..7a44dc37b --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java @@ -0,0 +1,17 @@ +package us.myles.ViaVersion2.api.protocol1_9to1_8.storage; + +import lombok.Getter; +import us.myles.ViaVersion2.api.data.StoredObject; + +public class MovementTracker extends StoredObject{ + private static final long IDLE_PACKET_DELAY = 50L; // Update every 50ms (20tps) + private static final long IDLE_PACKET_LIMIT = 20; // Max 20 ticks behind + @Getter + private long nextIdlePacket = 0L; + + public void incrementIdlePacket() { + // Notify of next update + // Allow a maximum lag spike of 1 second (20 ticks/updates) + this.nextIdlePacket = Math.max(nextIdlePacket + IDLE_PACKET_DELAY, System.currentTimeMillis() - IDLE_PACKET_DELAY * IDLE_PACKET_LIMIT); + } +} diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java index 3321f35a2..29670a0d3 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java @@ -24,6 +24,10 @@ public class ByteType extends Type implements TypeConverter { if (o instanceof Number) { return ((Number) o).byteValue(); } + if(o instanceof Boolean){ + if(o == true) return 1; + if(o == false) return 0; + } return (Byte) o; } }