From 4cffdd4f6468717e2e1843fa8271681e76145269 Mon Sep 17 00:00:00 2001 From: Mats Date: Sun, 8 May 2016 20:49:13 +0200 Subject: [PATCH] Don't call PlayerInteractEvent twice and fix the gamemode message (#390) * Experimental feature to fix the 'Your gamemode has been updated to ' message * Don't fire PlayerInteractEvent twice, fix #326 --- .../protocol1_9to1_8/Protocol1_9TO1_8.java | 11 ++-- .../protocol1_9to1_8/chat/ChatRewriter.java | 25 +++++++++ .../protocol1_9to1_8/chat/GameMode.java | 23 ++++++++ .../packets/PlayerPackets.java | 53 ++++++++++++++++++- .../packets/WorldPackets.java | 34 +++--------- .../storage/EntityTracker.java | 3 ++ .../storage/PlaceBlockTracker.java | 26 +++++++++ 7 files changed, 141 insertions(+), 34 deletions(-) create mode 100644 src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java create mode 100644 src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java create mode 100644 src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java index abdc74868..82ef3e771 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java @@ -16,10 +16,7 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.*; import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.InventoryTracker; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.*; import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.MetadataListType; import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.MetadataType; @@ -62,9 +59,9 @@ public class Protocol1_9TO1_8 extends Protocol { } public static Item getHandItem(final UserConnection info) { - if(HandItemCache.CACHE){ + if (HandItemCache.CACHE) { return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid()); - }else { + } else { try { return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable() { @Override @@ -133,5 +130,7 @@ public class Protocol1_9TO1_8 extends Protocol { userConnection.put(new MovementTracker(userConnection)); // Inventory tracker userConnection.put(new InventoryTracker(userConnection)); + // Place block tracker + userConnection.put(new PlaceBlockTracker(userConnection)); } } diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java new file mode 100644 index 000000000..ad757c201 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java @@ -0,0 +1,25 @@ +package us.myles.ViaVersion.protocols.protocol1_9to1_8.chat; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; + +public class ChatRewriter { + public static void toClient(JsonObject obj, UserConnection user) { + //Check gamemode change + if (obj.get("translate") != null && obj.get("translate").getAsString().equals("gameMode.changed")) { + String gameMode = user.get(EntityTracker.class).getGameMode().getText(); + + JsonObject gameModeObject = new JsonObject(); + gameModeObject.addProperty("text", gameMode); + gameModeObject.addProperty("color", "gray"); + gameModeObject.addProperty("italic", true); + + JsonArray array = new JsonArray(); + array.add(gameModeObject); + + obj.add("with", array); + } + } +} diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java new file mode 100644 index 000000000..d3e31c239 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java @@ -0,0 +1,23 @@ +package us.myles.ViaVersion.protocols.protocol1_9to1_8.chat; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum GameMode { + SURVIVAL(0, "Survival Mode"), + CREATIVE(1, "Creative Mode"), + ADVENTURE(2, "Adventure Mode"), + SPECTATOR(3, "Spectator Mode"); + + private final int id; + private final String text; + + public static GameMode getById(int id) { + for (GameMode gm : GameMode.values()) + if (gm.getId() == id) + return gm; + return null; + } +} diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java index 66c718072..6e14bae8f 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java @@ -1,5 +1,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.bukkit.Material; import org.bukkit.entity.EntityType; import us.myles.ViaVersion.ViaVersionPlugin; @@ -16,6 +18,8 @@ import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion.protocols.protocol1_9to1_8.PlayerMovementMapper; import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.ChatRewriter; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.GameMode; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; @@ -27,6 +31,19 @@ public class PlayerPackets { public void registerMap() { map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 0 - Chat Message (json) map(Type.BYTE); // 1 - Chat Positon + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + try { + JsonObject obj = (JsonObject) new JsonParser().parse(wrapper.get(Type.STRING, 0)); + ChatRewriter.toClient(obj, wrapper.user()); + wrapper.set(Type.STRING, 0, obj.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); } }); @@ -160,6 +177,14 @@ 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 { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + tracker.setGameMode(GameMode.getById(wrapper.get(Type.UNSIGNED_BYTE, 0))); //Set player gamemode + } + }); } }); @@ -283,6 +308,11 @@ public class PlayerPackets { protocol.registerOutgoing(State.PLAY, 0x07, 0x33, new PacketRemapper() { @Override public void registerMap() { + map(Type.INT); // 0 - Dimension + map(Type.UNSIGNED_BYTE); // 1 - Difficulty + map(Type.UNSIGNED_BYTE); // 2 - GameMode + map(Type.STRING); // 3 - Level Type + handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { @@ -290,6 +320,28 @@ public class PlayerPackets { ClientChunks cc = wrapper.user().get(ClientChunks.class); cc.getBulkChunks().clear(); cc.getLoadedChunks().clear(); + + int gamemode = wrapper.get(Type.UNSIGNED_BYTE, 0); + wrapper.user().get(EntityTracker.class).setGameMode(GameMode.getById(gamemode)); + } + }); + } + }); + + // Change Game State Packet + protocol.registerOutgoing(State.PLAY, 0x2B, 0x1E, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); //0 - Reason + map(Type.FLOAT); //1 - Value + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 3) { //Change gamemode + int gamemode = wrapper.get(Type.FLOAT, 0).intValue(); + wrapper.user().get(EntityTracker.class).setGameMode(GameMode.getById(gamemode)); + } } }); } @@ -333,7 +385,6 @@ public class PlayerPackets { protocol.registerOutgoing(State.PLAY, 0x00, 0x1F); // Keep Alive Packet protocol.registerOutgoing(State.PLAY, 0x48, 0x32); // Resource Pack Send Packet protocol.registerOutgoing(State.PLAY, 0x43, 0x36); // Camera Packet - protocol.registerOutgoing(State.PLAY, 0x2B, 0x1E); // Change Game State Packet protocol.registerOutgoing(State.PLAY, 0x3D, 0x38); // Display Scoreboard Packet protocol.registerOutgoing(State.PLAY, 0x3B, 0x3F); // Scoreboard Objective Packet diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java index 9fa71b7a7..5a683888b 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java @@ -14,13 +14,13 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.remapper.ValueCreator; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.ArmorType; import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect; import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.PlaceBlockTracker; import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.ChunkType; public class WorldPackets { @@ -349,32 +349,12 @@ public class WorldPackets { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { - Item item = wrapper.get(Type.ITEM, 0); - if (item != null) { - Material m = Material.getMaterial(item.getId()); - if (m != null) { - // Prevent special items from sending certain info - // Books - boolean special = m == Material.WRITTEN_BOOK; - // Buckets - special = special || m == Material.WATER_BUCKET || m == Material.LAVA_BUCKET || m == Material.BUCKET; - // Food - special = special || m.isEdible(); - // Potions - special = special || m == Material.POTION || m == Material.GLASS_BOTTLE; - // Projectiles - special = special || m == Material.BOW; - special = special || m == Material.SNOW_BALL || m == Material.EGG || m == Material.EXP_BOTTLE || m == Material.ENDER_PEARL || m == Material.EYE_OF_ENDER; - // Armour - special = special || ArmorType.isArmor(m); - // Don't send data if special - if (special && m != Material.AIR) { - EntityTracker tracker = wrapper.user().get(EntityTracker.class); - tracker.setLastPlaceBlock(wrapper.user().getReceivedPackets()); - } - - } - } + Position position = wrapper.get(Type.POSITION, 0); + PlaceBlockTracker tracker = wrapper.user().get(PlaceBlockTracker.class); + if (tracker.getLastPlacedPosition() != null && tracker.getLastPlacedPosition().equals(position) && !tracker.isExpired(50)) + wrapper.cancel(); + tracker.updateTime(); + tracker.setLastPlacedPosition(position); } }); diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java index cc5217c46..3caf9e55c 100644 --- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java @@ -22,6 +22,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.GameMode; import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType; import java.util.*; @@ -47,6 +48,8 @@ public class EntityTracker extends StoredObject { @Setter private Position currentlyDigging = null; private boolean teamExists = false; + @Setter + private GameMode gameMode; public EntityTracker(UserConnection user) { super(user); diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java new file mode 100644 index 000000000..6aff45cc4 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java @@ -0,0 +1,26 @@ +package us.myles.ViaVersion.protocols.protocol1_9to1_8.storage; + +import lombok.Getter; +import lombok.Setter; +import us.myles.ViaVersion.api.data.StoredObject; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.Position; + +@Getter +public class PlaceBlockTracker extends StoredObject { + private long lastPlaceTimestamp = System.currentTimeMillis(); + @Setter + private Position lastPlacedPosition = null; + + public PlaceBlockTracker(UserConnection user) { + super(user); + } + + public boolean isExpired(int ms) { + return System.currentTimeMillis() > (lastPlaceTimestamp + ms); + } + + public void updateTime() { + lastPlaceTimestamp = System.currentTimeMillis(); + } +}