Test Commit
This commit is contained in:
		| @@ -17,4 +17,10 @@ DisguiseSounds: true | ||||
| HearSelfDisguise: false | ||||
| # Shall I send the velocity packets? I REALLY recommend you don't disable. | ||||
| # This is the only thing allowing the mobs to fly without glitching out. | ||||
| SendVelocity: true | ||||
| SendVelocity: true | ||||
| # For self disguises, they need to have the armor and the held item removed | ||||
| # Else they see floating armor, floating held items. | ||||
| # However! This doesn't actually remove the armor! | ||||
| # It just makes the client think the armor was removed so that it doesn't render it! | ||||
| RemoveArmor: true | ||||
| RemoveHeldItem: true | ||||
| @@ -238,6 +238,8 @@ public class DisguiseAPI { | ||||
|             } catch (Exception ex) { | ||||
|                 ex.printStackTrace(); | ||||
|             } | ||||
|             // TODO Restore their currently held item | ||||
|             // TODO Restore their armor | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -288,23 +290,6 @@ public class DisguiseAPI { | ||||
|         // If the disguised player can't see himself. Return | ||||
|         if (!disguise.viewSelfDisguise()) | ||||
|             return; | ||||
|         // Grab the entity player | ||||
|         EntityPlayer entityplayer = ((CraftPlayer) player).getHandle(); | ||||
|         EntityTrackerEntry tracker = (EntityTrackerEntry) ((WorldServer) entityplayer.world).tracker.trackedEntities.get(player | ||||
|                 .getEntityId()); | ||||
|         if (tracker == null) { | ||||
|             // A check incase the tracker is null. | ||||
|             // If it is, then this method will be run again in one tick. Which is when it should be constructed. | ||||
|             // Else its going to run in a infinite loop hue hue hue.. | ||||
|             Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() { | ||||
|                 public void run() { | ||||
|                     setupPlayerFakeDisguise(disguise); | ||||
|                 } | ||||
|             }); | ||||
|             return; | ||||
|         } | ||||
|         // Add himself to his own entity tracker | ||||
|         tracker.trackedPlayers.add(entityplayer); | ||||
|         try { | ||||
|             // Grab the entity ID the fake disguise will use | ||||
|             Field field = net.minecraft.server.v1_6_R3.Entity.class.getDeclaredField("entityCount"); | ||||
| @@ -316,81 +301,7 @@ public class DisguiseAPI { | ||||
|         } catch (Exception ex) { | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|         // Send the player a packet with himself being spawned | ||||
|         Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) entityplayer); | ||||
|         entityplayer.playerConnection.sendPacket(packet); | ||||
|         if (!tracker.tracker.getDataWatcher().d()) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet40EntityMetadata(player.getEntityId(), tracker.tracker | ||||
|                     .getDataWatcher(), true)); | ||||
|         } | ||||
|         // Send himself some entity attributes | ||||
|         if (tracker.tracker instanceof EntityLiving) { | ||||
|             AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) tracker.tracker).aX(); | ||||
|             Collection collection = attributemapserver.c(); | ||||
| 
 | ||||
|             if (!collection.isEmpty()) { | ||||
|                 entityplayer.playerConnection.sendPacket(new Packet44UpdateAttributes(player.getEntityId(), collection)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Why do we even have this? | ||||
|         tracker.j = tracker.tracker.motX; | ||||
|         tracker.k = tracker.tracker.motY; | ||||
|         tracker.l = tracker.tracker.motZ; | ||||
|         boolean isMoving = false; | ||||
|         try { | ||||
|             Field field = EntityTrackerEntry.class.getDeclaredField("isMoving"); | ||||
|             field.setAccessible(true); | ||||
|             isMoving = field.getBoolean(tracker); | ||||
|         } catch (Exception ex) { | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|         // Send the velocity packets | ||||
|         if (isMoving) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet28EntityVelocity(player.getEntityId(), tracker.tracker.motX, | ||||
|                     tracker.tracker.motY, tracker.tracker.motZ)); | ||||
|         } | ||||
| 
 | ||||
|         // Why the hell would he even need this. Meh. | ||||
|         if (tracker.tracker.vehicle != null && player.getEntityId() > tracker.tracker.vehicle.id) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker, tracker.tracker.vehicle)); | ||||
|         } else if (tracker.tracker.passenger != null && player.getEntityId() > tracker.tracker.passenger.id) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker.passenger, tracker.tracker)); | ||||
|         } | ||||
| 
 | ||||
|         if (tracker.tracker instanceof EntityInsentient && ((EntityInsentient) tracker.tracker).getLeashHolder() != null) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(1, tracker.tracker, | ||||
|                     ((EntityInsentient) tracker.tracker).getLeashHolder())); | ||||
|         } | ||||
| 
 | ||||
|         // Resend the armor | ||||
|         for (int i = 0; i < 5; ++i) { | ||||
|             ItemStack itemstack = ((EntityLiving) tracker.tracker).getEquipment(i); | ||||
| 
 | ||||
|             if (itemstack != null) { | ||||
|                 entityplayer.playerConnection.sendPacket(new Packet5EntityEquipment(player.getEntityId(), i, itemstack)); | ||||
|             } | ||||
|         } | ||||
|         // If the disguised is sleeping for w/e reason | ||||
|         if (entityplayer.isSleeping()) { | ||||
|             entityplayer.playerConnection | ||||
|                     .sendPacket(new Packet17EntityLocationAction(entityplayer, 0, (int) Math.floor(tracker.tracker.locX), | ||||
|                             (int) Math.floor(tracker.tracker.locY), (int) Math.floor(tracker.tracker.locZ))); | ||||
|         } | ||||
| 
 | ||||
|         // CraftBukkit start - Fix for nonsensical head yaw | ||||
|         tracker.i = (int) Math.floor(tracker.tracker.getHeadRotation() * 256.0F / 360.0F); // tracker.ao() should be | ||||
|         // getHeadRotation | ||||
|         tracker.broadcast(new Packet35EntityHeadRotation(player.getEntityId(), (byte) tracker.i)); | ||||
|         // CraftBukkit end | ||||
| 
 | ||||
|         // Resend any active potion effects | ||||
|         Iterator iterator = entityplayer.getEffects().iterator(); | ||||
|         while (iterator.hasNext()) { | ||||
|             MobEffect mobeffect = (MobEffect) iterator.next(); | ||||
| 
 | ||||
|             entityplayer.playerConnection.sendPacket(new Packet41MobEffect(player.getEntityId(), mobeffect)); | ||||
|         } | ||||
|         PacketsManager.sendSelfDisguise(player); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -18,21 +18,39 @@ import me.libraryaddict.disguise.disguisetypes.MobDisguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.Values; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseSound.SoundType; | ||||
| import net.minecraft.server.v1_6_R3.AttributeMapServer; | ||||
| import net.minecraft.server.v1_6_R3.AttributeSnapshot; | ||||
| import net.minecraft.server.v1_6_R3.Block; | ||||
| import net.minecraft.server.v1_6_R3.DataWatcher; | ||||
| import net.minecraft.server.v1_6_R3.EntityHuman; | ||||
| import net.minecraft.server.v1_6_R3.EntityInsentient; | ||||
| import net.minecraft.server.v1_6_R3.EntityLiving; | ||||
| import net.minecraft.server.v1_6_R3.EntityPlayer; | ||||
| import net.minecraft.server.v1_6_R3.EntityTrackerEntry; | ||||
| import net.minecraft.server.v1_6_R3.EnumArt; | ||||
| import net.minecraft.server.v1_6_R3.EnumEntitySize; | ||||
| import net.minecraft.server.v1_6_R3.ItemStack; | ||||
| import net.minecraft.server.v1_6_R3.MathHelper; | ||||
| import net.minecraft.server.v1_6_R3.MobEffect; | ||||
| import net.minecraft.server.v1_6_R3.Packet17EntityLocationAction; | ||||
| import net.minecraft.server.v1_6_R3.Packet20NamedEntitySpawn; | ||||
| import net.minecraft.server.v1_6_R3.Packet28EntityVelocity; | ||||
| import net.minecraft.server.v1_6_R3.Packet35EntityHeadRotation; | ||||
| import net.minecraft.server.v1_6_R3.Packet39AttachEntity; | ||||
| import net.minecraft.server.v1_6_R3.Packet40EntityMetadata; | ||||
| import net.minecraft.server.v1_6_R3.Packet41MobEffect; | ||||
| import net.minecraft.server.v1_6_R3.Packet44UpdateAttributes; | ||||
| import net.minecraft.server.v1_6_R3.Packet5EntityEquipment; | ||||
| import net.minecraft.server.v1_6_R3.WatchableObject; | ||||
| import net.minecraft.server.v1_6_R3.World; | ||||
| import net.minecraft.server.v1_6_R3.WorldServer; | ||||
| 
 | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity; | ||||
| import org.bukkit.craftbukkit.v1_6_R3.entity.CraftLivingEntity; | ||||
| import org.bukkit.craftbukkit.v1_6_R3.entity.CraftPlayer; | ||||
| import org.bukkit.craftbukkit.v1_6_R3.inventory.CraftItemStack; | ||||
| import org.bukkit.entity.Arrow; | ||||
| import org.bukkit.entity.Entity; | ||||
| @@ -55,10 +73,14 @@ import com.comphenix.protocol.events.PacketListener; | ||||
| import com.comphenix.protocol.reflect.StructureModifier; | ||||
| 
 | ||||
| public class PacketsManager { | ||||
|     private static PacketListener inventoryListenerClient; | ||||
|     private static PacketListener inventoryListenerServer; | ||||
|     private static boolean inventoryModifierEnabled; | ||||
|     private static PacketListener soundsListener; | ||||
|     private static boolean soundsListenerEnabled; | ||||
|     private static PacketListener viewDisguisesListener; | ||||
|     private static boolean viewDisguisesListenerEnabled; | ||||
|     private static LibsDisguises libsDisguises; | ||||
| 
 | ||||
|     protected static void addPacketListeners(final JavaPlugin libsDisguises) { | ||||
|         ProtocolManager manager = ProtocolLibrary.getProtocolManager(); | ||||
| @@ -101,7 +123,7 @@ public class PacketsManager { | ||||
|         }); | ||||
|         // Now add a client listener to cancel them interacting with uninteractable disguised entitys. | ||||
|         // You ain't supposed to be allowed to 'interact' with a item that cannot be clicked. | ||||
|         // Kicks you for hacking. | ||||
|         // Because it kicks you for hacking. | ||||
|         manager.addPacketListener(new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.NORMAL, | ||||
|                 Packets.Client.USE_ENTITY) { | ||||
|             @Override | ||||
| @@ -370,6 +392,9 @@ public class PacketsManager { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the Y level to add to the disguise for realism. | ||||
|      */ | ||||
|     private static double getYModifier(Entity entity, DisguiseType disguiseType) { | ||||
|         switch (disguiseType) { | ||||
|         case BAT: | ||||
| @@ -400,7 +425,11 @@ public class PacketsManager { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     protected static void init(JavaPlugin libsDisguises) { | ||||
|     /** | ||||
|      * Creates the packet listeners | ||||
|      */ | ||||
|     protected static void init(LibsDisguises plugin) { | ||||
|         libsDisguises = plugin; | ||||
|         soundsListener = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL, | ||||
|                 Packets.Server.NAMED_SOUND_EFFECT, Packets.Server.ENTITY_STATUS) { | ||||
|             @Override | ||||
| @@ -652,12 +681,412 @@ public class PacketsManager { | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         // TODO Potentionally combine both listeners. | ||||
|         inventoryListenerServer = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.HIGHEST, | ||||
|                 Packets.Server.SET_SLOT) { | ||||
|             @Override | ||||
|             public void onPacketSending(PacketEvent event) { | ||||
|                 // If the inventory is the players inventory | ||||
|                 if (event.getPacket().getIntegers().read(0) == 0) { | ||||
|                     Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer()); | ||||
|                     // If the player is disguised, views self disguises and is hiding a item. | ||||
|                     if (disguise != null && disguise.viewSelfDisguise() | ||||
|                             && (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { | ||||
|                         switch (event.getPacketID()) { | ||||
|                         // If the server is setting the slot | ||||
|                         // Need to set it to air if its in a place it shouldn't be. | ||||
|                         // Things such as picking up a item, spawned in item. Plugin sets the item. etc. Will fire this | ||||
|                         case Packets.Server.SET_SLOT: { | ||||
|                             // The raw slot | ||||
|                             // nms code has the start of the hotbar being 36. | ||||
|                             int slot = event.getPacket().getIntegers().read(1); | ||||
|                             Bukkit.broadcastMessage("Set slot: " + slot); | ||||
|                             // If the slot is a armor slot | ||||
|                             if (slot >= 5 && slot <= 8) { | ||||
|                                 if (disguise.isHidingArmorFromSelf()) { | ||||
|                                     // Get the bukkit armor slot! | ||||
|                                     int armorSlot = Math.abs((slot - 5) - 3); | ||||
|                                     org.bukkit.inventory.ItemStack item = event.getPlayer().getInventory().getArmorContents()[armorSlot]; | ||||
|                                     if (item != null && item.getType() != Material.AIR) { | ||||
|                                         event.setPacket(event.getPacket().shallowClone()); | ||||
|                                         event.getPacket().getModifier() | ||||
|                                                 .write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 // Else if its a hotbar slot | ||||
|                             } else if (slot >= 36 && slot <= 44) { | ||||
|                                 if (disguise.isHidingHeldItemFromSelf()) { | ||||
|                                     int currentSlot = event.getPlayer().getInventory().getHeldItemSlot(); | ||||
|                                     // Check if the player is on the same slot as the slot that its setting | ||||
|                                     if (slot == currentSlot + 36) { | ||||
|                                         org.bukkit.inventory.ItemStack item = event.getPlayer().getItemInHand(); | ||||
|                                         if (item != null && item.getType() != Material.AIR) { | ||||
|                                             event.setPacket(event.getPacket().shallowClone()); | ||||
|                                             event.getPacket().getModifier() | ||||
|                                                     .write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             break; | ||||
|                         } | ||||
|                         // Don't think that we will ever need this. | ||||
|                         // We will see. | ||||
|                         case Packets.Server.WINDOW_ITEMS: { | ||||
|                             // TODO Find out how this works | ||||
|                             // It seems to 'update' the inventory.. Screw you.. | ||||
|                             break; | ||||
|                         } | ||||
|                         default: | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         // TODO Add a listener for player click event. | ||||
|         // Items placed do not have the server confirm it | ||||
|         // So I need to set the item slot | ||||
|         inventoryListenerClient = new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.HIGHEST, | ||||
|                 Packets.Client.BLOCK_ITEM_SWITCH, Packets.Client.SET_CREATIVE_SLOT, Packets.Client.WINDOW_CLICK) { | ||||
|             @Override | ||||
|             public void onPacketReceiving(PacketEvent event) { | ||||
|                 Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer()); | ||||
|                 // If player is disguised, views self disguises and has a inventory modifier | ||||
|                 if (disguise != null && disguise.viewSelfDisguise() | ||||
|                         && (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { | ||||
|                     switch (event.getPacketID()) { | ||||
|                     // If they are in creative and clicked on a slot | ||||
|                     case Packets.Client.SET_CREATIVE_SLOT: { | ||||
|                         int slot = event.getPacket().getIntegers().read(0); | ||||
|                         if (slot >= 5 && slot <= 8) { | ||||
|                             if (disguise.isHidingArmorFromSelf()) { | ||||
|                                 int armorSlot = Math.abs(slot - 9); | ||||
|                                 org.bukkit.inventory.ItemStack item = event.getPlayer().getInventory().getArmorContents()[armorSlot]; | ||||
|                                 if (item != null && item.getType() != Material.AIR) { | ||||
|                                     PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                     StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                     mods.write(0, 0); | ||||
|                                     mods.write(1, slot); | ||||
|                                     mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                     try { | ||||
|                                         ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false); | ||||
|                                     } catch (InvocationTargetException e) { | ||||
|                                         e.printStackTrace(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } else if (slot >= 36 && slot <= 44) { | ||||
|                             if (disguise.isHidingHeldItemFromSelf()) { | ||||
|                                 int currentSlot = event.getPlayer().getInventory().getHeldItemSlot(); | ||||
|                                 if (slot + 36 == currentSlot) { | ||||
|                                     org.bukkit.inventory.ItemStack item = event.getPlayer().getItemInHand(); | ||||
|                                     if (item != null && item.getType() != Material.AIR) { | ||||
|                                         PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                         StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                         mods.write(0, 0); | ||||
|                                         mods.write(1, slot); | ||||
|                                         mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                         try { | ||||
|                                             ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, | ||||
|                                                     false); | ||||
|                                         } catch (InvocationTargetException e) { | ||||
|                                             e.printStackTrace(); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                     // If the player switched item, aka he moved from slot 1 to slot 2 | ||||
|                     // TODO Listen for this server sided, sometimes it may force him back to a old slot | ||||
|                     // ^ But I think the client sends the packet again.. | ||||
|                     // This currently works fine | ||||
|                     case Packets.Client.BLOCK_ITEM_SWITCH: { | ||||
|                         if (disguise.isHidingHeldItemFromSelf()) { | ||||
|                             // From logging, it seems that both bukkit and nms uses the same thing for the slot switching. | ||||
|                             // 0 1 2 3 - 8 | ||||
|                             // If the packet is coming, then I need to replace the item they are switching to | ||||
|                             // As for the old item, I need to restore it. | ||||
|                             org.bukkit.inventory.ItemStack currentlyHeld = event.getPlayer().getItemInHand(); | ||||
|                             // If his old weapon isn't air | ||||
|                             if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) { | ||||
|                                 PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                 StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                 mods.write(0, 0); | ||||
|                                 mods.write(1, event.getPlayer().getInventory().getHeldItemSlot() + 36); | ||||
|                                 mods.write(2, CraftItemStack.asNMSCopy(currentlyHeld)); | ||||
|                                 try { | ||||
|                                     ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false); | ||||
|                                 } catch (InvocationTargetException e) { | ||||
|                                     e.printStackTrace(); | ||||
|                                 } | ||||
|                             } | ||||
|                             org.bukkit.inventory.ItemStack newHeld = event.getPlayer().getInventory() | ||||
|                                     .getItem(event.getPacket().getIntegers().read(0)); | ||||
|                             // If his new weapon isn't air either! | ||||
|                             if (newHeld != null && newHeld.getType() != Material.AIR) { | ||||
|                                 PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                 StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                 mods.write(0, 0); | ||||
|                                 mods.write(1, event.getPacket().getIntegers().read(0) + 36); | ||||
|                                 mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                 try { | ||||
|                                     ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false); | ||||
|                                 } catch (InvocationTargetException e) { | ||||
|                                     e.printStackTrace(); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
| 
 | ||||
|                     case Packets.Client.WINDOW_CLICK: | ||||
|                     // Seems like the cases are never met.. | ||||
|                     // Probably slot mismatches again | ||||
|                     { | ||||
|                         int slot = event.getPacket().getIntegers().read(1); | ||||
|                         org.bukkit.inventory.ItemStack clickedItem; | ||||
|                         if (event.getPacket().getIntegers().read(3) == 1) { | ||||
|                             // Its a shift click | ||||
|                             clickedItem = event.getPacket().getItemModifier().read(0); | ||||
|                             if (clickedItem != null && clickedItem.getType() != Material.AIR) { | ||||
|                                 org.bukkit.inventory.ItemStack armorItem = null; | ||||
|                                 int armorSlot = 0; | ||||
|                                 switch (clickedItem.getType()) { | ||||
|                                 case LEATHER_BOOTS: | ||||
|                                 case GOLD_BOOTS: | ||||
|                                 case CHAINMAIL_BOOTS: | ||||
|                                 case IRON_BOOTS: | ||||
|                                 case DIAMOND_BOOTS: | ||||
|                                     armorSlot = 8; | ||||
|                                     armorItem = event.getPlayer().getInventory().getBoots(); | ||||
|                                     break; | ||||
|                                 case LEATHER_LEGGINGS: | ||||
|                                 case GOLD_LEGGINGS: | ||||
|                                 case CHAINMAIL_LEGGINGS: | ||||
|                                 case IRON_LEGGINGS: | ||||
|                                 case DIAMOND_LEGGINGS: | ||||
|                                     armorSlot = 7; | ||||
|                                     armorItem = event.getPlayer().getInventory().getLeggings(); | ||||
|                                     break; | ||||
|                                 case LEATHER_CHESTPLATE: | ||||
|                                 case GOLD_CHESTPLATE: | ||||
|                                 case CHAINMAIL_CHESTPLATE: | ||||
|                                 case IRON_CHESTPLATE: | ||||
|                                 case DIAMOND_CHESTPLATE: | ||||
|                                     armorSlot = 6; | ||||
|                                     armorItem = event.getPlayer().getInventory().getChestplate(); | ||||
|                                     break; | ||||
|                                 case LEATHER_HELMET: | ||||
|                                 case GOLD_HELMET: | ||||
|                                 case CHAINMAIL_HELMET: | ||||
|                                 case IRON_HELMET: | ||||
|                                 case DIAMOND_HELMET: | ||||
|                                     armorSlot = 5; | ||||
|                                     armorItem = event.getPlayer().getInventory().getHelmet(); | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     break; | ||||
|                                 } | ||||
|                                 // Its a piece of armor they clicked on.. | ||||
|                                 if (armorSlot > 0) { | ||||
|                                     if (armorItem == null || armorItem.getType() == Material.AIR) { | ||||
|                                         PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                         StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                         mods.write(0, 0); | ||||
|                                         mods.write(1, armorSlot); | ||||
|                                         mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                         try { | ||||
|                                             ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, | ||||
|                                                     false); | ||||
|                                         } catch (InvocationTargetException e) { | ||||
|                                             e.printStackTrace(); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     org.bukkit.inventory.ItemStack heldItem = event.getPlayer().getItemInHand(); | ||||
|                                     // If its not a piece of armor they clicked on | ||||
|                                     // Then it can't go into a armor slot | ||||
|                                     // So it has to go into the held item.. | ||||
|                                     // But the held item is full. | ||||
|                                     if (heldItem == null || heldItem.getType() == Material.AIR) { | ||||
|                                         PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                         StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                         mods.write(0, 0); | ||||
|                                         mods.write(1, 36 + event.getPlayer().getInventory().getHeldItemSlot()); | ||||
|                                         mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                         try { | ||||
|                                             ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, | ||||
|                                                     false); | ||||
|                                         } catch (InvocationTargetException e) { | ||||
|                                             e.printStackTrace(); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             return; | ||||
|                         } else { | ||||
|                             // If its not a player inventory click | ||||
|                             // Shift clicking is exempted for the item in hand.. | ||||
|                             if (event.getPacket().getIntegers().read(0) != 0) { | ||||
|                                 return; | ||||
|                             } | ||||
|                             clickedItem = event.getPlayer().getItemOnCursor(); | ||||
|                         } | ||||
|                         if (clickedItem != null && clickedItem.getType() != Material.AIR) { | ||||
|                             // If the slot is a armor slot | ||||
|                             if (slot >= 5 && slot <= 8) { | ||||
|                                 if (disguise.isHidingArmorFromSelf()) { | ||||
|                                     PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                     StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                     mods.write(0, 0); | ||||
|                                     mods.write(1, slot); | ||||
|                                     mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                     try { | ||||
|                                         ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false); | ||||
|                                     } catch (InvocationTargetException e) { | ||||
|                                         e.printStackTrace(); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 // Else if its a hotbar slot | ||||
|                             } else if (slot >= 36 && slot <= 44) { | ||||
|                                 if (disguise.isHidingHeldItemFromSelf()) { | ||||
|                                     int currentSlot = event.getPlayer().getInventory().getHeldItemSlot(); | ||||
|                                     // Check if the player is on the same slot as the slot that its setting | ||||
|                                     if (slot == currentSlot + 36) { | ||||
|                                         PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); | ||||
|                                         StructureModifier<Object> mods = packet.getModifier(); | ||||
|                                         mods.write(0, 0); | ||||
|                                         mods.write(1, slot); | ||||
|                                         mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0))); | ||||
|                                         try { | ||||
|                                             ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, | ||||
|                                                     false); | ||||
|                                         } catch (InvocationTargetException e) { | ||||
|                                             e.printStackTrace(); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
| 
 | ||||
|                     default: | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sends the self disguise to the player | ||||
|      */ | ||||
|     public static void sendSelfDisguise(final Player player) { | ||||
|         EntityPlayer entityplayer = ((CraftPlayer) player).getHandle(); | ||||
|         EntityTrackerEntry tracker = (EntityTrackerEntry) ((WorldServer) entityplayer.world).tracker.trackedEntities.get(player | ||||
|                 .getEntityId()); | ||||
|         if (tracker == null) { | ||||
|             // A check incase the tracker is null. | ||||
|             // If it is, then this method will be run again in one tick. Which is when it should be constructed. | ||||
|             // Else its going to run in a infinite loop hue hue hue.. | ||||
|             Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() { | ||||
|                 public void run() { | ||||
|                     sendSelfDisguise(player); | ||||
|                 } | ||||
|             }); | ||||
|             return; | ||||
|         } | ||||
|         // Add himself to his own entity tracker | ||||
|         tracker.trackedPlayers.add(entityplayer); | ||||
|         // Send the player a packet with himself being spawned | ||||
|         Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) entityplayer); | ||||
|         entityplayer.playerConnection.sendPacket(packet); | ||||
|         if (!tracker.tracker.getDataWatcher().d()) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet40EntityMetadata(player.getEntityId(), tracker.tracker | ||||
|                     .getDataWatcher(), true)); | ||||
|         } | ||||
|         // Send himself some entity attributes | ||||
|         if (tracker.tracker instanceof EntityLiving) { | ||||
|             AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) tracker.tracker).aX(); | ||||
|             Collection collection = attributemapserver.c(); | ||||
| 
 | ||||
|             if (!collection.isEmpty()) { | ||||
|                 entityplayer.playerConnection.sendPacket(new Packet44UpdateAttributes(player.getEntityId(), collection)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Why do we even have this? | ||||
|         tracker.j = tracker.tracker.motX; | ||||
|         tracker.k = tracker.tracker.motY; | ||||
|         tracker.l = tracker.tracker.motZ; | ||||
|         boolean isMoving = false; | ||||
|         try { | ||||
|             Field field = EntityTrackerEntry.class.getDeclaredField("isMoving"); | ||||
|             field.setAccessible(true); | ||||
|             isMoving = field.getBoolean(tracker); | ||||
|         } catch (Exception ex) { | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|         // Send the velocity packets | ||||
|         if (isMoving) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet28EntityVelocity(player.getEntityId(), tracker.tracker.motX, | ||||
|                     tracker.tracker.motY, tracker.tracker.motZ)); | ||||
|         } | ||||
| 
 | ||||
|         // Why the hell would he even need this. Meh. | ||||
|         if (tracker.tracker.vehicle != null && player.getEntityId() > tracker.tracker.vehicle.id) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker, tracker.tracker.vehicle)); | ||||
|         } else if (tracker.tracker.passenger != null && player.getEntityId() > tracker.tracker.passenger.id) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker.passenger, tracker.tracker)); | ||||
|         } | ||||
| 
 | ||||
|         if (tracker.tracker instanceof EntityInsentient && ((EntityInsentient) tracker.tracker).getLeashHolder() != null) { | ||||
|             entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(1, tracker.tracker, | ||||
|                     ((EntityInsentient) tracker.tracker).getLeashHolder())); | ||||
|         } | ||||
| 
 | ||||
|         // Resend the armor | ||||
|         for (int i = 0; i < 5; ++i) { | ||||
|             ItemStack itemstack = ((EntityLiving) tracker.tracker).getEquipment(i); | ||||
| 
 | ||||
|             if (itemstack != null) { | ||||
|                 entityplayer.playerConnection.sendPacket(new Packet5EntityEquipment(player.getEntityId(), i, itemstack)); | ||||
|             } | ||||
|         } | ||||
|         // If the disguised is sleeping for w/e reason | ||||
|         if (entityplayer.isSleeping()) { | ||||
|             entityplayer.playerConnection | ||||
|                     .sendPacket(new Packet17EntityLocationAction(entityplayer, 0, (int) Math.floor(tracker.tracker.locX), | ||||
|                             (int) Math.floor(tracker.tracker.locY), (int) Math.floor(tracker.tracker.locZ))); | ||||
|         } | ||||
| 
 | ||||
|         // CraftBukkit start - Fix for nonsensical head yaw | ||||
|         tracker.i = (int) Math.floor(tracker.tracker.getHeadRotation() * 256.0F / 360.0F); // tracker.ao() should be | ||||
|         // getHeadRotation | ||||
|         tracker.broadcast(new Packet35EntityHeadRotation(player.getEntityId(), (byte) tracker.i)); | ||||
|         // CraftBukkit end | ||||
| 
 | ||||
|         // Resend any active potion effects | ||||
|         Iterator iterator = entityplayer.getEffects().iterator(); | ||||
|         while (iterator.hasNext()) { | ||||
|             MobEffect mobeffect = (MobEffect) iterator.next(); | ||||
| 
 | ||||
|             entityplayer.playerConnection.sendPacket(new Packet41MobEffect(player.getEntityId(), mobeffect)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isHearDisguisesEnabled() { | ||||
|         return soundsListenerEnabled; | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isInventoryListenerEnabled() { | ||||
|         return inventoryModifierEnabled; | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isViewDisguisesListenerEnabled() { | ||||
|         return viewDisguisesListenerEnabled; | ||||
|     } | ||||
| @@ -673,9 +1102,24 @@ public class PacketsManager { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void setInventoryListenerEnabled(boolean enabled) { | ||||
|         if (inventoryModifierEnabled != enabled) { | ||||
|             inventoryModifierEnabled = enabled; | ||||
|             // TODO Update all disguises to update their inventories. | ||||
|             if (inventoryModifierEnabled) { | ||||
|                 ProtocolLibrary.getProtocolManager().addPacketListener(inventoryListenerClient); | ||||
|                 ProtocolLibrary.getProtocolManager().addPacketListener(inventoryListenerServer); | ||||
|             } else { | ||||
|                 ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListenerClient); | ||||
|                 ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListenerServer); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void setViewDisguisesListener(boolean enabled) { | ||||
|         if (viewDisguisesListenerEnabled != enabled) { | ||||
|             viewDisguisesListenerEnabled = enabled; | ||||
|             // TODO Remove all self disguises, or add them. | ||||
|             if (viewDisguisesListenerEnabled) { | ||||
|                 ProtocolLibrary.getProtocolManager().addPacketListener(viewDisguisesListener); | ||||
|             } else { | ||||
| @@ -26,7 +26,6 @@ import org.bukkit.plugin.java.JavaPlugin; | ||||
| import org.bukkit.scheduler.BukkitRunnable; | ||||
| import org.bukkit.util.Vector; | ||||
| 
 | ||||
| 
 | ||||
| import com.comphenix.protocol.Packets; | ||||
| import com.comphenix.protocol.ProtocolLibrary; | ||||
| import com.comphenix.protocol.events.PacketContainer; | ||||
| @@ -41,12 +40,24 @@ public class Disguise { | ||||
|     private DisguiseType disguiseType; | ||||
|     private org.bukkit.entity.Entity entity; | ||||
|     private boolean hearSelfDisguise = DisguiseAPI.canHearSelfDisguise(); | ||||
|     private boolean replaceSounds; | ||||
|     private boolean hideArmorFromSelf = DisguiseAPI.isHidingArmorFromSelf(); | ||||
|     private boolean hideHeldItemFromSelf = DisguiseAPI.isHidingHeldItemFromSelf(); | ||||
|     private boolean replaceSounds = DisguiseAPI.isSoundEnabled(); | ||||
|     private BukkitRunnable runnable; | ||||
|     private boolean velocitySent = DisguiseAPI.isVelocitySent(); | ||||
|     private boolean viewSelfDisguise = DisguiseAPI.isViewDisguises(); | ||||
|     private FlagWatcher watcher; | ||||
| 
 | ||||
|     public boolean canHearSelfDisguise() { | ||||
|         return hearSelfDisguise; | ||||
|     } | ||||
| 
 | ||||
|     public Disguise clone() { | ||||
|         Disguise disguise = new Disguise().createDisguise(getType(), replaceSounds()); | ||||
|         disguise.setViewSelfDisguise(viewSelfDisguise()); | ||||
|         return disguise; | ||||
|     } | ||||
| 
 | ||||
|     protected Disguise createDisguise(DisguiseType newType, boolean doSounds) { | ||||
|         if (getWatcher() != null) | ||||
|             return this; | ||||
| @@ -55,7 +66,12 @@ public class Disguise { | ||||
|         // Set the option to replace the sounds | ||||
|         setReplaceSounds(doSounds); | ||||
|         // Get if they are a adult now.. | ||||
|         boolean isBaby = !(this instanceof MobDisguise && ((MobDisguise) this).isAdult()); | ||||
|         boolean isBaby = false; | ||||
|         if (this instanceof MobDisguise) { | ||||
|             if (!((MobDisguise) this).isAdult()) { | ||||
|                 isBaby = true; | ||||
|             } | ||||
|         } | ||||
|         try { | ||||
|             // Construct the FlagWatcher from the stored class | ||||
|             setWatcher((FlagWatcher) getType().getWatcherClass().getConstructor(Disguise.class).newInstance(this)); | ||||
| @@ -259,16 +275,6 @@ public class Disguise { | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     public boolean canHearSelfDisguise() { | ||||
|         return hearSelfDisguise; | ||||
|     } | ||||
| 
 | ||||
|     public Disguise clone() { | ||||
|         Disguise disguise = new Disguise().createDisguise(getType(), replaceSounds()); | ||||
|         disguise.setViewSelfDisguise(viewSelfDisguise()); | ||||
|         return disguise; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object obj) { | ||||
|         if (this == obj) | ||||
| @@ -327,6 +333,14 @@ public class Disguise { | ||||
|         return watcher; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isHidingArmorFromSelf() { | ||||
|         return hideArmorFromSelf; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isHidingHeldItemFromSelf() { | ||||
|         return hideHeldItemFromSelf; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isMiscDisguise() { | ||||
|         return this instanceof MiscDisguise; | ||||
|     } | ||||
| @@ -363,7 +377,7 @@ public class Disguise { | ||||
|                     disguises.remove(getEntity().getEntityId()); | ||||
|                     // Gotta do reflection, copy code or open up calls. | ||||
|                     // Reflection is the cleanest? | ||||
|                     if (entity instanceof Player) { | ||||
|                     if (getEntity() instanceof Player) { | ||||
|                         disguiseAPI.removeVisibleDisguise((Player) entity); | ||||
|                     } | ||||
|                     // Better refresh the entity to undisguise it | ||||
| @@ -401,6 +415,16 @@ public class Disguise { | ||||
|         this.hearSelfDisguise = hearSelfDisguise; | ||||
|     } | ||||
| 
 | ||||
|     public void setHideArmorFromSelf(boolean hideArmor) { | ||||
|         this.hideArmorFromSelf = hideArmor; | ||||
|         // TODO Update their armor if player | ||||
|     } | ||||
| 
 | ||||
|     public void setHideHeldItemFromSelf(boolean hideHeldItem) { | ||||
|         this.hideHeldItemFromSelf = hideHeldItem; | ||||
|         // TODO Update their held item if player | ||||
|     } | ||||
| 
 | ||||
|     public void setReplaceSounds(boolean areSoundsReplaced) { | ||||
|         replaceSounds = areSoundsReplaced; | ||||
|     } | ||||
| @@ -22,7 +22,9 @@ public enum DisguiseSound { | ||||
| 
 | ||||
|     CREEPER(Sound.CREEPER_HISS, Sound.STEP_GRASS, Sound.CREEPER_DEATH), | ||||
| 
 | ||||
|     DONKEY(Sound.DONKEY_HIT, Sound.STEP_GRASS, Sound.DONKEY_DEATH, Sound.DONKEY_IDLE, Sound.DONKEY_ANGRY), | ||||
|     DONKEY(Sound.DONKEY_HIT, Sound.STEP_GRASS, Sound.DONKEY_DEATH, Sound.DONKEY_IDLE, Sound.DONKEY_ANGRY, Sound.HORSE_GALLOP, | ||||
|             Sound.HORSE_ANGRY, Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, Sound.HORSE_SOFT, | ||||
|             Sound.HORSE_WOOD), | ||||
| 
 | ||||
|     ENDER_DRAGON(Sound.ENDERDRAGON_HIT, null, Sound.ENDERDRAGON_DEATH, Sound.ENDERDRAGON_GROWL, Sound.ENDERDRAGON_WINGS, | ||||
|             Sound.FALL_BIG, Sound.FALL_SMALL), | ||||
| @@ -35,7 +37,8 @@ public enum DisguiseSound { | ||||
| 
 | ||||
|     GIANT(Sound.HURT_FLESH, Sound.STEP_GRASS), | ||||
| 
 | ||||
|     HORSE(Sound.HORSE_HIT, Sound.STEP_GRASS, "mob.horse.death", Sound.HORSE_IDLE), | ||||
|     HORSE(Sound.HORSE_HIT, Sound.STEP_GRASS, "mob.horse.death", Sound.HORSE_IDLE, Sound.HORSE_GALLOP, Sound.HORSE_ANGRY, | ||||
|             Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, Sound.HORSE_SOFT, Sound.HORSE_WOOD), | ||||
| 
 | ||||
|     IRON_GOLEM(Sound.IRONGOLEM_HIT, Sound.IRONGOLEM_WALK, Sound.IRONGOLEM_DEATH, Sound.IRONGOLEM_THROW), | ||||
| 
 | ||||
| @@ -59,7 +62,9 @@ public enum DisguiseSound { | ||||
| 
 | ||||
|     SKELETON(Sound.SKELETON_HURT, Sound.SKELETON_WALK, Sound.SKELETON_DEATH, Sound.SKELETON_IDLE), | ||||
| 
 | ||||
|     SKELETON_HORSE("mob.horse.skeleton.hit", Sound.STEP_GRASS, Sound.HORSE_SKELETON_DEATH, Sound.HORSE_SKELETON_IDLE), | ||||
|     SKELETON_HORSE("mob.horse.skeleton.hit", Sound.STEP_GRASS, Sound.HORSE_SKELETON_DEATH, Sound.HORSE_SKELETON_IDLE, | ||||
|             Sound.HORSE_GALLOP, Sound.HORSE_ANGRY, Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, | ||||
|             Sound.HORSE_SOFT, Sound.HORSE_WOOD), | ||||
| 
 | ||||
|     SLIME(Sound.SLIME_ATTACK, Sound.SLIME_WALK2, null, null, Sound.SLIME_WALK), | ||||
| 
 | ||||
| @@ -69,7 +74,9 @@ public enum DisguiseSound { | ||||
| 
 | ||||
|     SQUID(), | ||||
| 
 | ||||
|     UNDEAD_HORSE(Sound.HORSE_ZOMBIE_HIT, Sound.STEP_GRASS, Sound.HORSE_ZOMBIE_DEATH, Sound.HORSE_ZOMBIE_IDLE), | ||||
|     UNDEAD_HORSE(Sound.HORSE_ZOMBIE_HIT, Sound.STEP_GRASS, Sound.HORSE_ZOMBIE_DEATH, Sound.HORSE_ZOMBIE_IDLE, Sound.HORSE_GALLOP, | ||||
|             Sound.HORSE_ANGRY, Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, Sound.HORSE_SOFT, | ||||
|             Sound.HORSE_WOOD), | ||||
| 
 | ||||
|     VILLAGER(Sound.VILLAGER_HIT, null, Sound.VILLAGER_DEATH, Sound.VILLAGER_IDLE, Sound.VILLAGER_HAGGLE, Sound.VILLAGER_YES, | ||||
|             Sound.VILLAGER_NO), | ||||
		Reference in New Issue
	
	Block a user