diff --git a/Plugins/Mineplex.Core/src/mineplex/core/TwitchIntegrationFix.java b/Plugins/Mineplex.Core/src/mineplex/core/TwitchIntegrationFix.java new file mode 100644 index 000000000..cd5d97826 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/TwitchIntegrationFix.java @@ -0,0 +1,126 @@ +package mineplex.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.PacketPlayInArmAnimation; +import net.minecraft.server.v1_8_R3.PacketPlayInBlockDig; +import net.minecraft.server.v1_8_R3.PacketPlayInBlockPlace; +import net.minecraft.server.v1_8_R3.PacketPlayInEntityAction; +import net.minecraft.server.v1_8_R3.PacketPlayInFlying; +import net.minecraft.server.v1_8_R3.PacketPlayInHeldItemSlot; +import net.minecraft.server.v1_8_R3.PacketPlayInRightClick; +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutCloseWindow; +import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow; + +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketInfo; + +/** + * Why do we need this you ask? + *

+ * In 1.8.x, Mojang added Twitch integration, and in standard Mojang fashion completely broke inventory handling. + *

+ * Specifically, you are able to close an inventory and not actually trigger an InventoryCloseEvent. This kinda breaks + * literally anything relying on that event. + *

+ * So we just add lots of strict checks to make sure they can't do much without closing the inventory + */ +@ReflectivelyCreateMiniPlugin +public class TwitchIntegrationFix extends MiniPlugin implements IPacketHandler +{ + private final Map _inventoryOpenedAt = new HashMap<>(); + private final Map _inventoryOpenedAtTime = new HashMap<>(); + + private TwitchIntegrationFix() + { + super("Twitch Integration Fix"); + + require(PacketHandler.class).addPacketHandler(this, true, + PacketPlayOutOpenWindow.class, + PacketPlayOutCloseWindow.class, + PacketPlayInRightClick.class, + PacketPlayInBlockPlace.class, + PacketPlayInArmAnimation.class, + PacketPlayInBlockDig.class, + PacketPlayInHeldItemSlot.class, + PacketPlayInUseEntity.class, + PacketPlayInFlying.PacketPlayInPosition.class, + PacketPlayInFlying.PacketPlayInPositionLook.class + ); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + _inventoryOpenedAt.remove(event.getPlayer().getUniqueId()); + _inventoryOpenedAtTime.remove(event.getPlayer().getUniqueId()); + } + + @Override + public void handle(PacketInfo packetInfo) + { + EntityPlayer entityPlayer = ((CraftPlayer) packetInfo.getPlayer()).getHandle(); + if (packetInfo.getPacket() instanceof PacketPlayOutOpenWindow) + { + _inventoryOpenedAt.put(packetInfo.getPlayer().getUniqueId(), packetInfo.getPlayer().getLocation()); + _inventoryOpenedAtTime.put(packetInfo.getPlayer().getUniqueId(), entityPlayer.playerConnection.networkManager.packetCount); + } + else if (packetInfo.getPacket() instanceof PacketPlayOutCloseWindow) + { + _inventoryOpenedAt.remove(packetInfo.getPlayer().getUniqueId()); + _inventoryOpenedAtTime.remove(packetInfo.getPlayer().getUniqueId()); + } + else if (packetInfo.getPacket() instanceof PacketPlayInRightClick || + packetInfo.getPacket() instanceof PacketPlayInBlockPlace || + packetInfo.getPacket() instanceof PacketPlayInArmAnimation || + packetInfo.getPacket() instanceof PacketPlayInBlockDig || + packetInfo.getPacket() instanceof PacketPlayInHeldItemSlot || + packetInfo.getPacket() instanceof PacketPlayInUseEntity + ) + { + // Impossible to do while inventory is open + if (entityPlayer.activeContainer != entityPlayer.defaultContainer && _inventoryOpenedAtTime.containsKey(packetInfo.getPlayer().getUniqueId())) + { + long openedTime = _inventoryOpenedAtTime.get(packetInfo.getPlayer().getUniqueId()); + if (entityPlayer.playerConnection.networkManager.packetCount - openedTime > 5) + { + System.out.println("Impossible packet: " + packetInfo.getPacket().getClass()); + packetInfo.getPlayer().closeInventory(); + } + } + } + else if (packetInfo.getPacket() instanceof PacketPlayInFlying) + { + if (entityPlayer.activeContainer != entityPlayer.defaultContainer) + { + if (_inventoryOpenedAt.containsKey(packetInfo.getPlayer().getUniqueId())) + { + Location openedAt = _inventoryOpenedAt.get(packetInfo.getPlayer().getUniqueId()); + if (!packetInfo.getPlayer().getWorld().equals(openedAt.getWorld())) + { + packetInfo.getPlayer().closeInventory(); + } + else + { + double distance = packetInfo.getPlayer().getLocation().distanceSquared(openedAt); + // You get a 9 block radius before you're considered too far away + if (distance > 9 * 9) + { + packetInfo.getPlayer().closeInventory(); + } + } + } + } + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index eadfe6cfc..aeecb152f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -61,7 +61,7 @@ public class AnimationCarl extends Animation if(((String) _type).contentEquals("RANK")) { for (int i = 50; i < 60; i++) - { + { Item shard = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PRISMARINE_SHARD, (byte) 0, 1, " " + i)); _items.add(shard); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index c21256ce4..05b80b2e6 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -10,6 +10,7 @@ import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.CustomTagFix; import mineplex.core.PacketsInteractionFix; +import mineplex.core.TwitchIntegrationFix; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; import mineplex.core.antihack.AntiHack; @@ -242,6 +243,7 @@ public class Hub extends JavaPlugin implements IRelation { require(AprilFoolsTreasureHunt.class); } + require(TwitchIntegrationFix.class); } @Override diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index 82081472c..68e92af90 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -15,6 +15,7 @@ import mineplex.core.CustomTagFix; import mineplex.core.FoodDupeFix; import mineplex.core.PacketsInteractionFix; import mineplex.core.TimingsFix; +import mineplex.core.TwitchIntegrationFix; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; import mineplex.core.antihack.AntiHack; @@ -202,6 +203,7 @@ public class Arcade extends JavaPlugin require(TwoFactorAuth.class); new WebsiteLinkManager(this, _clientManager); + require(TwitchIntegrationFix.class); AprilFoolsManager.getInstance();