diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java b/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java index e19ae7a1..2e214b5e 100644 --- a/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java +++ b/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java @@ -6,20 +6,36 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import org.bukkit.craftbukkit.v1_6_R2.inventory.CraftItemStack; import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.inventory.EntityEquipment; import com.comphenix.protocol.Packets; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.DisguiseAPI; import net.minecraft.server.v1_6_R2.ChunkCoordinates; import net.minecraft.server.v1_6_R2.EntityPlayer; import net.minecraft.server.v1_6_R2.ItemStack; import net.minecraft.server.v1_6_R2.WatchableObject; public class FlagWatcher { + public enum SlotType { + BOOTS(0), CHESTPLATE(2), HELD_ITEM(4), HELMET(3), LEGGINGS(1); + private int slotNo = 0; + + private SlotType(int no) { + slotNo = no; + } + + public int getSlot() { + return slotNo; + } + } private static HashMap classTypes = new HashMap(); static { @@ -33,6 +49,7 @@ public class FlagWatcher { } private Disguise disguise; private HashMap entityValues = new HashMap(); + private org.bukkit.inventory.ItemStack[] items = new org.bukkit.inventory.ItemStack[5]; public FlagWatcher(Disguise disguise) { this.disguise = disguise; @@ -95,6 +112,14 @@ public class FlagWatcher { return ((Byte) getValue(0, (byte) 0) & 1 << i) != 0; } + public org.bukkit.inventory.ItemStack getItemStack(int slot) { + return items[slot]; + } + + public org.bukkit.inventory.ItemStack getItemStack(SlotType slot) { + return getItemStack(slot.getSlot()); + } + protected Object getValue(int no, Object backup) { if (entityValues.containsKey(no)) return entityValues.get(no); @@ -130,7 +155,7 @@ public class FlagWatcher { } protected void sendData(int data) { - if (disguise.getWatcher() == null) + if (disguise.getWatcher() == null || !DisguiseAPI.isDisguised(disguise.getEntity())) return; Entity entity = disguise.getEntity(); Object value = entityValues.get(data); @@ -178,6 +203,50 @@ public class FlagWatcher { } } + public void setItemStack(int slot, org.bukkit.inventory.ItemStack itemStack) { + // Itemstack which is null means that its not replacing the disguises itemstack. + if (itemStack == null) { + // Find the item to replace it with + if (disguise.getEntity() instanceof LivingEntity) { + EntityEquipment enquipment = ((LivingEntity) disguise.getEntity()).getEquipment(); + if (slot == 4) { + itemStack = enquipment.getItemInHand(); + } else { + itemStack = enquipment.getArmorContents()[slot]; + } + if (itemStack != null && itemStack.getTypeId() == 0) + itemStack = null; + } + } + + ItemStack itemToSend = null; + if (itemStack != null && itemStack.getTypeId() != 0) + itemToSend = CraftItemStack.asNMSCopy(itemStack); + items[slot] = itemStack; + slot++; + if (slot > 4) + slot = 0; + PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_EQUIPMENT); + StructureModifier mods = packet.getModifier(); + mods.write(0, disguise.getEntity().getEntityId()); + mods.write(1, slot); + mods.write(2, itemToSend); + for (EntityPlayer player : disguise.getPerverts()) { + Player p = player.getBukkitEntity(); + if (p != disguise.getEntity()) { + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(p, packet); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + + public void setItemStack(SlotType slot, org.bukkit.inventory.ItemStack itemStack) { + setItemStack(slot.getSlot(), itemStack); + } + public void setRiding(boolean setRiding) { if (isSprinting() != setRiding) { setFlag(0, 2, true); diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index e4533889..8b1a9c60 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -84,7 +84,8 @@ public class LibsDisguises extends JavaPlugin { Packets.Server.NAMED_ENTITY_SPAWN, Packets.Server.ENTITY_METADATA, Packets.Server.ARM_ANIMATION, Packets.Server.REL_ENTITY_MOVE_LOOK, Packets.Server.ENTITY_LOOK, Packets.Server.ENTITY_TELEPORT, Packets.Server.ADD_EXP_ORB, Packets.Server.VEHICLE_SPAWN, Packets.Server.MOB_SPAWN, - Packets.Server.ENTITY_PAINTING, Packets.Server.COLLECT, Packets.Server.UPDATE_ATTRIBUTES) { + Packets.Server.ENTITY_PAINTING, Packets.Server.COLLECT, Packets.Server.UPDATE_ATTRIBUTES, + Packets.Server.ENTITY_EQUIPMENT) { @Override public void onPacketSending(PacketEvent event) { Player observer = event.getPlayer(); @@ -128,12 +129,36 @@ public class LibsDisguises extends JavaPlugin { } protected PacketContainer[] constructPacket(Disguise disguise, Entity disguisedEntity) { - PacketContainer[] spawnPackets = new PacketContainer[2]; ProtocolManager manager = ProtocolLibrary.getProtocolManager(); net.minecraft.server.v1_6_R2.Entity nmsEntity = ((CraftEntity) disguisedEntity).getHandle(); + ArrayList packets = new ArrayList(); + for (int i = 0; i < 5; i++) { + int slot = i - 1; + if (slot < 0) + slot = 4; + org.bukkit.inventory.ItemStack itemstack = disguise.getWatcher().getItemStack(slot); + if (itemstack != null && itemstack.getTypeId() != 0) { + ItemStack item = null; + if (nmsEntity instanceof EntityLiving) + item = ((EntityLiving) nmsEntity).getEquipment(i); + if (item == null) { + PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_EQUIPMENT); + StructureModifier mods = packet.getModifier(); + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, i); + mods.write(2, CraftItemStack.asNMSCopy(itemstack)); + packets.add(packet); + } + } + } + PacketContainer[] spawnPackets = new PacketContainer[2 + packets.size()]; + for (int i = 0; i < packets.size(); i++) { + spawnPackets[i + 2] = packets.get(i); + } Location loc = disguisedEntity.getLocation(); byte yaw = getYaw(disguise.getType(), DisguiseType.getType(disguise.getEntity().getType()), (byte) (int) (loc.getYaw() * 256.0F / 360.0F)); + if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { spawnPackets[0] = manager.createPacket(Packets.Server.ADD_EXP_ORB); @@ -301,99 +326,6 @@ public class LibsDisguises extends JavaPlugin { } - protected PacketContainer[] transformPacket(PacketContainer sentPacket, Player observer) { - PacketContainer[] packets = new PacketContainer[] { sentPacket }; - try { - // First get the entity, the one sending this packet - StructureModifier entityModifer = sentPacket.getEntityModifier(observer.getWorld()); - org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == sentPacket.getID() ? 1 : 0)); - Disguise disguise = DisguiseAPI.getDisguise(entity); - // If disguised. - if (disguise != null) { - // If packet is Packets.Server.UPDATE_ATTRIBUTES - For some reason maven doesn't let me.. - // This packet sends attributes - - switch (sentPacket.getID()) { - case Packets.Server.UPDATE_ATTRIBUTES: - - { - // Grab the values which are 'approved' to be sent for this entity - HashMap values = Values.getAttributesValues(disguise.getType()); - Collection collection = new ArrayList(); - for (AttributeSnapshot att : (List) sentPacket.getModifier().read(1)) { - if (values.containsKey(att.a())) { - collection.add(new AttributeSnapshot(null, att.a(), values.get(att.a()), att.c())); - } - } - if (collection.size() > 0) { - packets[0] = new PacketContainer(sentPacket.getID()); - StructureModifier mods = packets[0].getModifier(); - mods.write(0, entity.getEntityId()); - mods.write(1, collection); - } else { - packets = new PacketContainer[0]; - } - break; - } - - // Else if the packet is sending entity metadata - case Packets.Server.ENTITY_METADATA: - - { - List watchableObjects = disguise.getWatcher().convert( - (List) packets[0].getModifier().read(1)); - packets[0] = new PacketContainer(sentPacket.getID()); - StructureModifier newMods = packets[0].getModifier(); - newMods.write(0, entity.getEntityId()); - newMods.write(1, watchableObjects); - break; - } - - // Else if the packet is spawning.. - case Packets.Server.NAMED_ENTITY_SPAWN: - case Packets.Server.MOB_SPAWN: - case Packets.Server.ADD_EXP_ORB: - case Packets.Server.VEHICLE_SPAWN: - case Packets.Server.ENTITY_PAINTING: - - { - packets = constructPacket(disguise, entity); - break; - } - - // Else if the disguise is attempting to send players a forbidden packet - case Packets.Server.ARM_ANIMATION: - case Packets.Server.COLLECT: - - { - if (disguise.getType().isMisc()) - packets = new PacketContainer[0]; - break; - - } - // Else if the disguise is moving. - case Packets.Server.REL_ENTITY_MOVE_LOOK: - case Packets.Server.ENTITY_LOOK: - case Packets.Server.ENTITY_TELEPORT: - - { - packets[0] = sentPacket.shallowClone(); - StructureModifier mods = packets[0].getModifier(); - byte value = (Byte) mods.read(4); - mods.write(4, getYaw(disguise.getType(), DisguiseType.getType(entity.getType()), value)); - break; - } - - default: - break; - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return packets; - } - private byte getYaw(DisguiseType disguiseType, DisguiseType entityType, byte value) { switch (disguiseType) { case ENDER_DRAGON: @@ -619,4 +551,111 @@ public class LibsDisguises extends JavaPlugin { } return builder.toString(); } + + protected PacketContainer[] transformPacket(PacketContainer sentPacket, Player observer) { + PacketContainer[] packets = new PacketContainer[] { sentPacket }; + try { + // First get the entity, the one sending this packet + StructureModifier entityModifer = sentPacket.getEntityModifier(observer.getWorld()); + org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == sentPacket.getID() ? 1 : 0)); + Disguise disguise = DisguiseAPI.getDisguise(entity); + // If disguised. + if (disguise != null) { + // If packet is Packets.Server.UPDATE_ATTRIBUTES - For some reason maven doesn't let me.. + // This packet sends attributes + + switch (sentPacket.getID()) { + case Packets.Server.UPDATE_ATTRIBUTES: + + { + // Grab the values which are 'approved' to be sent for this entity + HashMap values = Values.getAttributesValues(disguise.getType()); + Collection collection = new ArrayList(); + for (AttributeSnapshot att : (List) sentPacket.getModifier().read(1)) { + if (values.containsKey(att.a())) { + collection.add(new AttributeSnapshot(null, att.a(), values.get(att.a()), att.c())); + } + } + if (collection.size() > 0) { + packets[0] = new PacketContainer(sentPacket.getID()); + StructureModifier mods = packets[0].getModifier(); + mods.write(0, entity.getEntityId()); + mods.write(1, collection); + } else { + packets = new PacketContainer[0]; + } + break; + } + + // Else if the packet is sending entity metadata + case Packets.Server.ENTITY_METADATA: + + { + List watchableObjects = disguise.getWatcher().convert( + (List) packets[0].getModifier().read(1)); + packets[0] = new PacketContainer(sentPacket.getID()); + StructureModifier newMods = packets[0].getModifier(); + newMods.write(0, entity.getEntityId()); + newMods.write(1, watchableObjects); + break; + } + + // Else if the packet is spawning.. + case Packets.Server.NAMED_ENTITY_SPAWN: + case Packets.Server.MOB_SPAWN: + case Packets.Server.ADD_EXP_ORB: + case Packets.Server.VEHICLE_SPAWN: + case Packets.Server.ENTITY_PAINTING: + + { + packets = constructPacket(disguise, entity); + break; + } + + // Else if the disguise is attempting to send players a forbidden packet + case Packets.Server.ARM_ANIMATION: + case Packets.Server.COLLECT: + + { + if (disguise.getType().isMisc()) + packets = new PacketContainer[0]; + break; + + } + // Else if the disguise is moving. + case Packets.Server.REL_ENTITY_MOVE_LOOK: + case Packets.Server.ENTITY_LOOK: + case Packets.Server.ENTITY_TELEPORT: + + { + packets[0] = sentPacket.shallowClone(); + StructureModifier mods = packets[0].getModifier(); + byte value = (Byte) mods.read(4); + mods.write(4, getYaw(disguise.getType(), DisguiseType.getType(entity.getType()), value)); + break; + } + + case Packets.Server.ENTITY_EQUIPMENT: + + { + int slot = (Integer) packets[0].getModifier().read(1) - 1; + if (slot < 0) + slot = 4; + org.bukkit.inventory.ItemStack itemstack = disguise.getWatcher().getItemStack(slot); + if (itemstack != null) { + packets[0] = packets[0].shallowClone(); + packets[0].getModifier().write(2, + (itemstack.getTypeId() == 0 ? null : CraftItemStack.asNMSCopy(itemstack))); + } + } + + default: + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return packets; + } } \ No newline at end of file