diff --git a/src/me/libraryaddict/disguise/disguisetypes/FlagType.java b/src/me/libraryaddict/disguise/disguisetypes/FlagType.java index d9d58b77..626161cd 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/FlagType.java +++ b/src/me/libraryaddict/disguise/disguisetypes/FlagType.java @@ -9,6 +9,7 @@ import java.util.UUID; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; + import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.EnumWrappers.Direction; import com.comphenix.protocol.wrappers.Vector3F; diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 77125abe..2a6e85b2 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -56,6 +56,7 @@ import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; +import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets; public class DisguiseUtilities { @@ -1266,18 +1267,23 @@ public class DisguiseUtilities return; } - // Code to stop player pushing in 1.9 + // Code to stop player pushing Scoreboard scoreboard = player.getScoreboard(); Team t; if ((t = scoreboard.getTeam("LDPushing")) == null) { t = scoreboard.registerNewTeam("LDPushing"); - - t.setOption(Option.COLLISION_RULE, OptionStatus.NEVER); } - t.addEntry(player.getName()); + if (t.getOption(Option.COLLISION_RULE) != OptionStatus.NEVER) + { + t.setOption(Option.COLLISION_RULE, OptionStatus.NEVER); + t.setCanSeeFriendlyInvisibles(false); + } + + if (!t.hasEntry(player.getName())) + t.addEntry(player.getName()); // Add himself to his own entity tracker Object trackedPlayersObj = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers") @@ -1411,52 +1417,33 @@ public class DisguiseUtilities /** * Method to send a packet to the self disguise, translate his entity ID to the fake id. */ - private static void sendSelfPacket(final Player player, PacketContainer packet) + private static void sendSelfPacket(final Player player, final PacketContainer packet) { - PacketContainer[][] transformed = PacketsManager.transformPacket(packet, player, player); + final Disguise disguise = DisguiseAPI.getDisguise(player, player); - PacketContainer[] packets = transformed == null ? null : transformed[0]; + // If disguised. + if (disguise == null) + { + return; + } - final PacketContainer[] delayed = transformed == null ? null : transformed[1]; + LibsPackets transformed = PacketsManager.transformPacket(packet, disguise, player, player); try { - if (packets == null) - { - packets = new PacketContainer[] - { - packet - }; - } + if (transformed.isUnhandled()) + transformed.addPacket(packet); - for (PacketContainer p : packets) + transformed.setPacketType(packet.getType()); + + for (PacketContainer p : transformed.getPackets()) { p = p.deepClone(); p.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); ProtocolLibrary.getProtocolManager().sendServerPacket(player, p, false); } - if (delayed != null && delayed.length > 0) - { - Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() - { - @Override - public void run() - { - try - { - for (PacketContainer packet : delayed) - { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - } - catch (InvocationTargetException e) - { - e.printStackTrace(); - } - } - }); - } + transformed.sendDelayed(player); } catch (InvocationTargetException e) { diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index 23ac0d5a..4be0285e 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -1,8 +1,10 @@ package me.libraryaddict.disguise.utilities; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map.Entry; import java.util.UUID; import org.bukkit.Art; @@ -20,6 +22,7 @@ import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.util.Vector; import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.PacketType.Play; import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; @@ -38,6 +41,7 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagType; import me.libraryaddict.disguise.disguisetypes.FlagWatcher; import me.libraryaddict.disguise.disguisetypes.MiscDisguise; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; @@ -51,6 +55,97 @@ import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerViewDis public class PacketsManager { + public static class LibsPackets + { + private ArrayList packets = new ArrayList(); + private HashMap> delayedPackets = new HashMap>(); + private boolean isSpawnPlayer; + private Disguise disguise; + private boolean doNothing; + + public void setUnhandled() + { + doNothing = true; + } + + public boolean isUnhandled() + { + return doNothing; + } + + private LibsPackets(Disguise disguise) + { + this.disguise = disguise; + } + + public Disguise getDisguise() + { + return disguise; + } + + public void setPacketType(PacketType type) + { + isSpawnPlayer = type.name().contains("SPAWN_"); + } + + public void addPacket(PacketContainer packet) + { + packets.add(packet); + } + + public void addDelayedPacket(PacketContainer packet) + { + addDelayedPacket(packet, 2); + } + + public void clear() + { + getPackets().clear(); + } + + public void addDelayedPacket(PacketContainer packet, int ticksDelayed) + { + if (!delayedPackets.containsKey(ticksDelayed)) + delayedPackets.put(ticksDelayed, new ArrayList()); + + delayedPackets.get(ticksDelayed).add(packet); + } + + public ArrayList getPackets() + { + return packets; + } + + public void sendDelayed(final Player observer) + { + for (final Entry> entry : delayedPackets.entrySet()) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() + { + public void run() + { + try + { + for (PacketContainer packet : entry.getValue()) + { + ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); + } + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + + if (isSpawnPlayer) + { + PacketsManager.removeCancel(disguise, observer); + } + } + }, entry.getKey()); + } + } + } + private static PacketListener clientInteractEntityListener; private static PacketListener inventoryListener; private static boolean inventoryModifierEnabled; @@ -60,6 +155,7 @@ public class PacketsManager private static boolean soundsListenerEnabled; private static PacketListener viewDisguisesListener; private static boolean viewDisguisesListenerEnabled; + private static HashMap> _cancelMeta = new HashMap>(); public static void addPacketListeners() { @@ -75,18 +171,33 @@ public class PacketsManager setupMainPacketsListener(); } + public static void removeCancel(Disguise disguise, Player observer) + { + ArrayList cancel; + + if ((cancel = _cancelMeta.get(disguise)) == null) + return; + + cancel.remove(observer.getUniqueId()); + + if (!cancel.isEmpty()) + return; + + _cancelMeta.remove(disguise); + } + /** * Construct the packets I need to spawn in the disguise */ - public static PacketContainer[][] constructSpawnPackets(final Player observer, Disguise disguise, Entity disguisedEntity) + private static LibsPackets constructSpawnPackets(final Player observer, LibsPackets packets, Entity disguisedEntity) { + Disguise disguise = packets.getDisguise(); + if (disguise.getEntity() == null) { disguise.setEntity(disguisedEntity); } - ArrayList packets = new ArrayList<>(); - // This sends the armor packets so that the player isn't naked. // Please note it only sends the packets that wouldn't be sent normally if (DisguiseConfig.isEquipmentPacketsEnabled()) @@ -120,7 +231,7 @@ public class PacketsManager mods.write(1, ReflectionManager.createEnumItemSlot(slot)); mods.write(2, ReflectionManager.getNmsItem(itemstack)); - packets.add(packet); + packets.addPacket(packet); } } @@ -155,18 +266,10 @@ public class PacketsManager packet.getIntegers().write(0, disguisedEntity.getEntityId()); packet.getAttributeCollectionModifier().write(0, attributes); - packets.add(packet); + packets.addPacket(packet); } } - PacketContainer[] spawnPackets = new PacketContainer[2 + packets.size()]; - PacketContainer[] delayedPackets = new PacketContainer[0]; - - for (int i = 0; i < packets.size(); i++) - { - spawnPackets[i + 2] = packets.get(i); - } - Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguisedEntity, disguise), 0); byte yaw = (byte) (int) (loc.getYaw() * 256.0F / 360.0F); @@ -180,9 +283,10 @@ public class PacketsManager if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { - spawnPackets[0] = new PacketContainer(Server.SPAWN_ENTITY_EXPERIENCE_ORB); + PacketContainer spawnOrb = new PacketContainer(Server.SPAWN_ENTITY_EXPERIENCE_ORB); + packets.addPacket(spawnOrb); - StructureModifier mods = spawnPackets[0].getModifier(); + StructureModifier mods = spawnOrb.getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, loc.getX()); @@ -192,9 +296,10 @@ public class PacketsManager } else if (disguise.getType() == DisguiseType.PAINTING) { - spawnPackets[0] = new PacketContainer(Server.SPAWN_ENTITY_PAINTING); + PacketContainer spawnPainting = new PacketContainer(Server.SPAWN_ENTITY_PAINTING); + packets.addPacket(spawnPainting); - StructureModifier mods = spawnPackets[0].getModifier(); + StructureModifier mods = spawnPainting.getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, disguisedEntity.getUniqueId()); @@ -206,9 +311,10 @@ public class PacketsManager mods.write(4, ReflectionManager.getEnumArt(Art.values()[id])); // Make the teleport packet to make it visible.. - spawnPackets[1] = new PacketContainer(Server.ENTITY_TELEPORT); + PacketContainer teleportPainting = new PacketContainer(Server.ENTITY_TELEPORT); + packets.addPacket(teleportPainting); - mods = spawnPackets[1].getModifier(); + mods = teleportPainting.getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, loc.getX()); @@ -237,78 +343,123 @@ public class PacketsManager DisguiseUtilities.getAddedByPlugins().remove(name); } - spawnPackets[0] = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN); + // Send player info along with the disguise + PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO); + packets.addPacket(sendTab); - spawnPackets[0].getIntegers().write(0, entityId); // Id - spawnPackets[0].getModifier().write(1, gameProfile.getUUID()); + // Add player to the list, necessary to spawn them + sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0)); - spawnPackets[0].getDoubles().write(0, loc.getX()); - spawnPackets[0].getDoubles().write(1, loc.getY()); - spawnPackets[0].getDoubles().write(2, loc.getZ()); + List playerList = new ArrayList(); - spawnPackets[0].getBytes().write(0, ((byte) (int) (loc.getYaw() * 256.0F / 360.0F))); - spawnPackets[0].getBytes().write(1, ((byte) (int) (loc.getPitch() * 256.0F / 360.0F))); + playerList.add(ReflectionManager.getPlayerInfoData(sendTab.getHandle(), playerDisguise.getGameProfile())); + sendTab.getModifier().write(1, playerList); - spawnPackets[0].getDataWatcherModifier().write(0, - createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); // watcher, - // duh + // Spawn the player + PacketContainer spawnPlayer = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN); + + spawnPlayer.getIntegers().write(0, entityId); // Id + spawnPlayer.getModifier().write(1, gameProfile.getUUID()); + + Location spawnAt = disguisedEntity.getLocation(); + + boolean selfDisguise = observer == disguisedEntity; + + WrappedDataWatcher newWatcher; + + if (selfDisguise) + { + newWatcher = createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher()); + } + else + { + newWatcher = new WrappedDataWatcher(); + + spawnAt = observer.getLocation(); + spawnAt.add(spawnAt.getDirection().normalize().multiply(20)); + } + + // Spawn him in front of the observer + StructureModifier doubles = spawnPlayer.getDoubles(); + doubles.write(0, spawnAt.getX()); + doubles.write(1, spawnAt.getY()); + doubles.write(2, spawnAt.getZ()); + + StructureModifier bytes = spawnPlayer.getBytes(); + bytes.write(0, ((byte) (int) (loc.getYaw() * 256.0F / 360.0F))); + bytes.write(1, ((byte) (int) (loc.getPitch() * 256.0F / 360.0F))); + + spawnPlayer.getDataWatcherModifier().write(0, newWatcher); + + // Make him invisible + newWatcher.setObject(new WrappedDataWatcherObject(FlagType.ENTITY_META.getIndex(), Registry.get(Byte.class)), + (byte) 32); + + packets.addPacket(spawnPlayer); if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { - PacketContainer[] newPackets = new PacketContainer[spawnPackets.length + 1]; - - System.arraycopy(spawnPackets, 1, newPackets, 2, spawnPackets.length - 1); - - newPackets[0] = spawnPackets[0]; - spawnPackets = newPackets; - PacketContainer[] bedPackets = DisguiseUtilities.getBedPackets( loc.clone().subtract(0, PacketsManager.getYModifier(disguisedEntity, disguise), 0), observer.getLocation(), ((PlayerDisguise) disguise)); - System.arraycopy(bedPackets, 0, spawnPackets, 1, 2); - } - - ArrayList newPackets = new ArrayList(); - newPackets.add(null); - - for (PacketContainer spawnPacket : spawnPackets) - { - if (spawnPacket != null) - { // Get rid of empty packet '1' if it exists. - newPackets.add(spawnPacket); + for (PacketContainer packet : bedPackets) + { + packets.addPacket(packet); } } + else if (!selfDisguise) + { + // Teleport the player back to where he's supposed to be + PacketContainer teleportPacket = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); - // Send player info along with the disguise - spawnPackets = newPackets.toArray(new PacketContainer[newPackets.size()]); - spawnPackets[0] = new PacketContainer(Server.PLAYER_INFO); + doubles = teleportPacket.getDoubles(); - // Add player to the list, necessary to spawn them - spawnPackets[0].getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0)); + teleportPacket.getIntegers().write(0, entityId); // Id + doubles.write(0, loc.getX()); + doubles.write(1, loc.getY()); + doubles.write(2, loc.getZ()); - List playerList = new ArrayList(); + bytes = teleportPacket.getBytes(); + bytes.write(0, ((byte) (int) (loc.getYaw() * 256.0F / 360.0F))); + bytes.write(1, ((byte) (int) (loc.getPitch() * 256.0F / 360.0F))); - playerList.add(ReflectionManager.getPlayerInfoData(spawnPackets[0].getHandle(), playerDisguise.getGameProfile())); - spawnPackets[0].getModifier().write(1, playerList); + packets.addPacket(teleportPacket); + } + + if (!selfDisguise) + { + // Send a metadata packet + PacketContainer metaPacket = new PacketContainer(Play.Server.ENTITY_METADATA); + + newWatcher = createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher()); + newWatcher.setObject(new WrappedDataWatcherObject(FlagType.ENTITY_META.getIndex(), Registry.get(Byte.class)), + (byte) 0); + + metaPacket.getIntegers().write(0, entityId); // Id + metaPacket.getWatchableCollectionModifier().write(0, newWatcher.getWatchableObjects()); + + if (!_cancelMeta.containsKey(disguise)) + _cancelMeta.put(disguise, new ArrayList()); + + _cancelMeta.get(disguise).add(observer.getUniqueId()); + packets.addDelayedPacket(metaPacket, 4); + } // Remove player from the list - PacketContainer delayedPacket = spawnPackets[0].shallowClone(); + PacketContainer deleteTab = sendTab.shallowClone(); + packets.addDelayedPacket(deleteTab, 40); - delayedPacket.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(4)); - - delayedPackets = new PacketContainer[] - { - delayedPacket - }; + deleteTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(4)); } else if (disguise.getType().isMob() || disguise.getType() == DisguiseType.ARMOR_STAND) { Vector vec = disguisedEntity.getVelocity(); - spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + PacketContainer spawnEntity = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + packets.addPacket(spawnEntity); - StructureModifier mods = spawnPackets[0].getModifier(); + StructureModifier mods = spawnEntity.getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, UUID.randomUUID()); @@ -342,7 +493,7 @@ public class PacketsManager mods.write(9, yaw); mods.write(10, pitch); - spawnPackets[0].getDataWatcherModifier().write(0, + spawnEntity.getDataWatcherModifier().write(0, createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); } else if (disguise.getType().isMisc()) @@ -366,46 +517,39 @@ public class PacketsManager Object nmsEntity = ReflectionManager.getNmsEntity(disguisedEntity); - spawnPackets[0] = ProtocolLibrary.getProtocolManager() + PacketContainer spawnEntity = ProtocolLibrary.getProtocolManager() .createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, nmsEntity, objectId, data) .createPacket(nmsEntity, objectId, data); - spawnPackets[0].getModifier().write(8, pitch); - spawnPackets[0].getModifier().write(9, yaw); + packets.addPacket(spawnEntity); + + spawnEntity.getModifier().write(8, pitch); + spawnEntity.getModifier().write(9, yaw); if (disguise.getType() == DisguiseType.ITEM_FRAME) { if (data % 2 == 0) { - spawnPackets[0].getModifier().write(4, loc.getZ() + (data == 0 ? -1 : 1)); + spawnEntity.getModifier().write(4, loc.getZ() + (data == 0 ? -1 : 1)); } else { - spawnPackets[0].getModifier().write(2, loc.getX() + (data == 3 ? -1 : 1)); + spawnEntity.getModifier().write(2, loc.getX() + (data == 3 ? -1 : 1)); } } } - if (spawnPackets[1] == null || disguise.isPlayerDisguise()) + + if (packets.getPackets().size() <= 1 || disguise.isPlayerDisguise()) { - int entry = spawnPackets[1] == null ? 1 : 0; + PacketContainer rotateHead = new PacketContainer(Server.ENTITY_HEAD_ROTATION); + packets.addPacket(rotateHead); - if (entry == 0) - { - entry = spawnPackets.length; - spawnPackets = Arrays.copyOf(spawnPackets, spawnPackets.length + 1); - } - // Make a packet to turn his head! - - spawnPackets[entry] = new PacketContainer(Server.ENTITY_HEAD_ROTATION); - - StructureModifier mods = spawnPackets[entry].getModifier(); + StructureModifier mods = rotateHead.getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, yaw); } - return new PacketContainer[][] - { - spawnPackets, delayedPackets - }; + + return packets; } /** @@ -813,356 +957,355 @@ public class PacketsManager * Transform the packet magically into the one I have always dreamed off. My true luv!!! This will return null if its not * transformed */ - public static PacketContainer[][] transformPacket(PacketContainer sentPacket, Player observer, Entity entity) + public static LibsPackets transformPacket(PacketContainer sentPacket, Disguise disguise, Player observer, Entity entity) { - PacketContainer[] packets = null; - - PacketContainer[] delayedPackets = new PacketContainer[0]; + LibsPackets packets = new LibsPackets(disguise); try { - Disguise disguise = DisguiseAPI.getDisguise(observer, entity); + packets.addPacket(sentPacket); - // If disguised. - if (disguise != null) + // This packet sends attributes + if (sentPacket.getType() == Server.UPDATE_ATTRIBUTES) { - packets = new PacketContainer[] - { - sentPacket - }; - - // This packet sends attributes - if (sentPacket.getType() == Server.UPDATE_ATTRIBUTES) + if (disguise.isMiscDisguise()) { - if (disguise.isMiscDisguise()) - { - packets = new PacketContainer[0]; - } - else - { - List attributes = new ArrayList<>(); + packets.clear(); + } + else + { + List attributes = new ArrayList<>(); - for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) + for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) + { + if (attribute.getAttributeKey().equals("generic.maxHealth")) { - if (attribute.getAttributeKey().equals("generic.maxHealth")) + packets.clear(); + + PacketContainer updateAttributes = new PacketContainer(Server.UPDATE_ATTRIBUTES); + packets.addPacket(updateAttributes); + + Builder builder; + + if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) { - packets[0] = new PacketContainer(Server.UPDATE_ATTRIBUTES); - - Builder builder; - - if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) - { - builder = WrappedAttribute.newBuilder(); - builder.attributeKey("generic.maxHealth"); - builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); - } - else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) - { - builder = WrappedAttribute.newBuilder(attribute); - } - else - { - builder = WrappedAttribute.newBuilder(); - builder.attributeKey("generic.maxHealth"); - builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); - } - - builder.packet(packets[0]); - - attributes.add(builder.build()); - break; + builder = WrappedAttribute.newBuilder(); + builder.attributeKey("generic.maxHealth"); + builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); } - } - - if (!attributes.isEmpty()) - { - packets[0].getIntegers().write(0, entity.getEntityId()); - packets[0].getAttributeCollectionModifier().write(0, attributes); - } - else - { - packets = new PacketContainer[0]; - } - } - } - - // Else if the packet is sending entity metadata - else if (sentPacket.getType() == Server.ENTITY_METADATA) - { - if (DisguiseConfig.isMetadataPacketsEnabled() && !isStaticMetadataDisguiseType(disguise)) - { - List watchableObjects = disguise.getWatcher() - .convert(packets[0].getWatchableCollectionModifier().read(0)); - - packets[0] = new PacketContainer(Server.ENTITY_METADATA); - - StructureModifier newMods = packets[0].getModifier(); - - newMods.write(0, entity.getEntityId()); - - packets[0].getWatchableCollectionModifier().write(0, watchableObjects); - } - else - { - packets = new PacketContainer[0]; - } - } - - // Else if the packet is spawning.. - else if (sentPacket.getType() == Server.NAMED_ENTITY_SPAWN || sentPacket.getType() == Server.SPAWN_ENTITY_LIVING - || sentPacket.getType() == Server.SPAWN_ENTITY_EXPERIENCE_ORB - || sentPacket.getType() == Server.SPAWN_ENTITY || sentPacket.getType() == Server.SPAWN_ENTITY_PAINTING) - { - PacketContainer[][] spawnPackets = constructSpawnPackets(observer, disguise, entity); - - packets = spawnPackets[0]; - delayedPackets = spawnPackets[1]; - } - - // Else if the disguise is attempting to send players a forbidden packet - else if (sentPacket.getType() == Server.ANIMATION) - { - if (disguise.getType().isMisc() || (packets[0].getIntegers().read(1) == 2 && (!disguise.getType().isPlayer() - || (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping())))) - { - packets = new PacketContainer[0]; - } - } - - // Else if the disguise is collecting stuff - else if (sentPacket.getType() == Server.COLLECT) - { - if (disguise.getType().isMisc()) - { - packets = new PacketContainer[0]; - } - - else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer() - && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) - { - PacketContainer newPacket = new PacketContainer(Server.ANIMATION); - - StructureModifier mods = newPacket.getIntegers(); - mods.write(0, disguise.getEntity().getEntityId()); - mods.write(1, 3); - - packets = new PacketContainer[] + else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) { - newPacket, sentPacket - }; - } - } - - // Else if the disguise is moving. - else if (sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK || sentPacket.getType() == Server.ENTITY_LOOK - || sentPacket.getType() == Server.ENTITY_TELEPORT || sentPacket.getType() == Server.REL_ENTITY_MOVE) - { - if (disguise.getType() == DisguiseType.RABBIT && (sentPacket.getType() == Server.REL_ENTITY_MOVE - || sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK)) - { - // Rabbit robbing... - if (entity.getMetadata("LibsRabbitHop").isEmpty() - || System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() < 100 - || System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) - { - if (entity.getMetadata("LibsRabbitHop").isEmpty() - || System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) - { - entity.removeMetadata("LibsRabbitHop", libsDisguises); - entity.setMetadata("LibsRabbitHop", - new FixedMetadataValue(libsDisguises, System.currentTimeMillis())); - } - - packets = Arrays.copyOf(packets, packets.length + 1); - - packets[1] = new PacketContainer(Server.ENTITY_STATUS); - - packets[1].getIntegers().write(0, entity.getEntityId()); - packets[1].getBytes().write(0, (byte) 1); - } - } - - // Stop wither skulls from looking - if (sentPacket.getType() == Server.ENTITY_LOOK && disguise.getType() == DisguiseType.WITHER_SKULL) - { - packets = new PacketContainer[0]; - } - else if (sentPacket.getType() != Server.REL_ENTITY_MOVE) - { - packets[0] = sentPacket.shallowClone(); - - StructureModifier bytes = packets[0].getBytes(); - - byte yawValue = bytes.read(0); - byte pitchValue = bytes.read(1); - - bytes.write(0, getYaw(disguise.getType(), entity.getType(), yawValue)); - bytes.write(1, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue)); - - if (sentPacket.getType() == Server.ENTITY_TELEPORT && disguise.getType() == DisguiseType.ITEM_FRAME) - { - StructureModifier doubles = packets[0].getDoubles(); - - Location loc = entity.getLocation(); - - double data = (((loc.getYaw() % 360) + 720 + 45) / 90) % 4; - - if (data % 2 == 0) - { - if (data % 2 == 0) - { - doubles.write(3, loc.getZ()); - } - else - { - doubles.write(1, loc.getZ()); - } - } - - double y = getYModifier(entity, disguise); - - if (y != 0) - { - doubles.write(2, doubles.read(2) + y); - } - } - } - } - - // Else if the disguise is updating equipment - else if (sentPacket.getType() == Server.ENTITY_EQUIPMENT) - { - EquipmentSlot slot = ReflectionManager.createEquipmentSlot(packets[0].getModifier().read(1)); - - 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 : ReflectionManager.getNmsItem(itemStack))); - } - if (disguise.getWatcher().isRightClicking() && slot == EquipmentSlot.HAND) - { - ItemStack heldItem = packets[0].getItemModifier().read(0); - - if (heldItem != null && heldItem.getType() != Material.AIR) - { - // Convert the datawatcher - List list = new ArrayList<>(); - - if (DisguiseConfig.isMetadataPacketsEnabled() && !isStaticMetadataDisguiseType(disguise)) - { - WrappedWatchableObject watch = ReflectionManager.createWatchable(0, - WrappedDataWatcher.getEntityWatcher(entity).getByte(0)); - - list.add(watch); - - list = disguise.getWatcher().convert(list); + builder = WrappedAttribute.newBuilder(attribute); } else { - for (WrappedWatchableObject obj : disguise.getWatcher().getWatchableObjects()) - { - if (obj.getIndex() == 0) - { - list.add(obj); - break; - } - } + builder = WrappedAttribute.newBuilder(); + builder.attributeKey("generic.maxHealth"); + builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); } - // Construct the packets to return - PacketContainer packetBlock = new PacketContainer(Server.ENTITY_METADATA); + builder.packet(updateAttributes); - packetBlock.getModifier().write(0, entity.getEntityId()); - packetBlock.getWatchableCollectionModifier().write(0, list); + attributes.add(builder.build()); + break; + } + } - PacketContainer packetUnblock = packetBlock.deepClone(); - // Make a packet to send the 'unblock' - for (WrappedWatchableObject watcher : packetUnblock.getWatchableCollectionModifier().read(0)) + if (!attributes.isEmpty()) + { + packets.getPackets().get(0).getIntegers().write(0, entity.getEntityId()); + packets.getPackets().get(0).getAttributeCollectionModifier().write(0, attributes); + } + else + { + packets.clear(); + } + } + } + + // Else if the packet is sending entity metadata + else if (sentPacket.getType() == Server.ENTITY_METADATA) + { + packets.clear(); + + if (DisguiseConfig.isMetadataPacketsEnabled() && !isStaticMetadataDisguiseType(disguise) + && (!_cancelMeta.containsKey(disguise) || !_cancelMeta.get(disguise).contains(observer.getUniqueId()))) + { + List watchableObjects = disguise.getWatcher() + .convert(sentPacket.getWatchableCollectionModifier().read(0)); + + PacketContainer metaPacket = new PacketContainer(Server.ENTITY_METADATA); + + packets.addPacket(metaPacket); + + StructureModifier newMods = metaPacket.getModifier(); + + newMods.write(0, entity.getEntityId()); + + metaPacket.getWatchableCollectionModifier().write(0, watchableObjects); + } + } + + // Else if the packet is spawning.. + else if (sentPacket.getType() == Server.NAMED_ENTITY_SPAWN || sentPacket.getType() == Server.SPAWN_ENTITY_LIVING + || sentPacket.getType() == Server.SPAWN_ENTITY_EXPERIENCE_ORB || sentPacket.getType() == Server.SPAWN_ENTITY + || sentPacket.getType() == Server.SPAWN_ENTITY_PAINTING) + { + packets.clear(); + + constructSpawnPackets(observer, packets, entity); + } + + // Else if the disguise is attempting to send players a forbidden packet + else if (sentPacket.getType() == Server.ANIMATION) + { + if (disguise.getType().isMisc() || (sentPacket.getIntegers().read(1) == 2 && (!disguise.getType().isPlayer() + || (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping())))) + { + packets.clear(); + } + } + + // Else if the disguise is collecting stuff + else if (sentPacket.getType() == Server.COLLECT) + { + if (disguise.getType().isMisc()) + { + packets.clear(); + } + + else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer() + && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) + { + PacketContainer newPacket = new PacketContainer(Server.ANIMATION); + + StructureModifier mods = newPacket.getIntegers(); + mods.write(0, disguise.getEntity().getEntityId()); + mods.write(1, 3); + + packets.clear(); + + packets.addPacket(newPacket); + packets.addPacket(sentPacket); + } + } + + // Else if the disguise is moving. + else if (sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK || sentPacket.getType() == Server.ENTITY_LOOK + || sentPacket.getType() == Server.ENTITY_TELEPORT || sentPacket.getType() == Server.REL_ENTITY_MOVE) + { + if (disguise.getType() == DisguiseType.RABBIT && (sentPacket.getType() == Server.REL_ENTITY_MOVE + || sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK)) + { + // Rabbit robbing... + if (entity.getMetadata("LibsRabbitHop").isEmpty() + || System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() < 100 + || System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) + { + if (entity.getMetadata("LibsRabbitHop").isEmpty() + || System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) + { + entity.removeMetadata("LibsRabbitHop", libsDisguises); + entity.setMetadata("LibsRabbitHop", + new FixedMetadataValue(libsDisguises, System.currentTimeMillis())); + } + + PacketContainer statusPacket = new PacketContainer(Server.ENTITY_STATUS); + packets.addPacket(statusPacket); + + statusPacket.getIntegers().write(0, entity.getEntityId()); + statusPacket.getBytes().write(0, (byte) 1); + } + } + + // Stop wither skulls from looking + if (sentPacket.getType() == Server.ENTITY_LOOK && disguise.getType() == DisguiseType.WITHER_SKULL) + { + packets.clear(); + } + else if (sentPacket.getType() != Server.REL_ENTITY_MOVE) + { + packets.clear(); + + PacketContainer movePacket = sentPacket.shallowClone(); + + packets.addPacket(movePacket); + + StructureModifier bytes = movePacket.getBytes(); + + byte yawValue = bytes.read(0); + byte pitchValue = bytes.read(1); + + bytes.write(0, getYaw(disguise.getType(), entity.getType(), yawValue)); + bytes.write(1, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue)); + + if (sentPacket.getType() == Server.ENTITY_TELEPORT && disguise.getType() == DisguiseType.ITEM_FRAME) + { + StructureModifier doubles = movePacket.getDoubles(); + + Location loc = entity.getLocation(); + + double data = (((loc.getYaw() % 360) + 720 + 45) / 90) % 4; + + if (data % 2 == 0) + { + if (data % 2 == 0) { - watcher.setValue((byte) ((byte) watcher.getValue() & ~(1 << 4))); + doubles.write(3, loc.getZ()); } + else + { + doubles.write(1, loc.getZ()); + } + } - // Send the unblock before the itemstack change so that the 2nd metadata packet works. Why? Scheduler - // delay. - packets = new PacketContainer[] - { - packetUnblock, packets[0], packetBlock - }; - // Silly mojang made the right clicking datawatcher value only valid for one use. So I have to reset - // it. + double y = getYModifier(entity, disguise); + + if (y != 0) + { + doubles.write(2, doubles.read(2) + y); } } } + } - // If the entity is going into a bed, stop everything but players from doing this - else if (sentPacket.getType() == Server.BED) + // Else if the disguise is updating equipment + else if (sentPacket.getType() == Server.ENTITY_EQUIPMENT) + { + EquipmentSlot slot = ReflectionManager.createEquipmentSlot(packets.getPackets().get(0).getModifier().read(1)); + + org.bukkit.inventory.ItemStack itemStack = disguise.getWatcher().getItemStack(slot); + + if (itemStack != null) { - if (!disguise.getType().isPlayer()) - { - packets = new PacketContainer[0]; - } + packets.clear(); + + PacketContainer equipPacket = sentPacket.shallowClone(); + + packets.addPacket(equipPacket); + + equipPacket.getModifier().write(2, + (itemStack.getTypeId() == 0 ? null : ReflectionManager.getNmsItem(itemStack))); } - // If the entity is updating their Facebook status, stop them from showing death - else if (sentPacket.getType() == Server.ENTITY_STATUS) + if (disguise.getWatcher().isRightClicking() && slot == EquipmentSlot.HAND) { - if (packets[0].getBytes().read(0) == (byte) 3) + ItemStack heldItem = packets.getPackets().get(0).getItemModifier().read(0); + + if (heldItem != null && heldItem.getType() != Material.AIR) { - packets = new PacketContainer[0]; - } - } + // Convert the datawatcher + List list = new ArrayList<>(); - // If the entity is rotating his head - else if (sentPacket.getType() == Server.ENTITY_HEAD_ROTATION) - { - if (disguise.getType().isPlayer() && entity.getType() != EntityType.PLAYER) - { - Location loc = entity.getLocation(); + if (DisguiseConfig.isMetadataPacketsEnabled() && !isStaticMetadataDisguiseType(disguise)) + { + WrappedWatchableObject watch = ReflectionManager.createWatchable(0, + WrappedDataWatcher.getEntityWatcher(entity).getByte(0)); - byte pitch = getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), - (byte) (int) (loc.getPitch() * 256.0F / 360.0F)); - byte yaw = getYaw(disguise.getType(), entity.getType(), sentPacket.getBytes().read(0)); + list.add(watch); - PacketContainer rotation = new PacketContainer(Server.ENTITY_HEAD_ROTATION); - - StructureModifier mods = rotation.getModifier(); - - mods.write(0, entity.getEntityId()); - mods.write(1, yaw); - - PacketContainer look = new PacketContainer(Server.ENTITY_LOOK); - - look.getIntegers().write(0, entity.getEntityId()); - look.getBytes().write(0, yaw); - look.getBytes().write(1, pitch); - - packets = new PacketContainer[] + list = disguise.getWatcher().convert(list); + } + else + { + for (WrappedWatchableObject obj : disguise.getWatcher().getWatchableObjects()) { - look, rotation - }; + if (obj.getIndex() == 0) + { + list.add(obj); + break; + } + } + } + + // Construct the packets to return + PacketContainer packetBlock = new PacketContainer(Server.ENTITY_METADATA); + + packetBlock.getModifier().write(0, entity.getEntityId()); + packetBlock.getWatchableCollectionModifier().write(0, list); + + PacketContainer packetUnblock = packetBlock.deepClone(); + // Make a packet to send the 'unblock' + for (WrappedWatchableObject watcher : packetUnblock.getWatchableCollectionModifier().read(0)) + { + watcher.setValue((byte) ((byte) watcher.getValue() & ~(1 << 4))); + } + + // Send the unblock before the itemstack change so that the 2nd metadata packet works. Why? Scheduler + // delay. + + PacketContainer packet1 = packets.getPackets().get(0); + + packets.clear(); + + packets.addPacket(packetUnblock); + packets.addPacket(packet1); + packets.addPacket(packetBlock); + // Silly mojang made the right clicking datawatcher value only valid for one use. So I have to reset + // it. } } + } - // Whatever - else + // If the entity is going into a bed, stop everything but players from doing this + else if (sentPacket.getType() == Server.BED) + { + if (!disguise.getType().isPlayer()) { - packets = null; + packets.clear(); } + } + // If the entity is updating their Facebook status, stop them from showing death + else if (sentPacket.getType() == Server.ENTITY_STATUS) + { + if (packets.getPackets().get(0).getBytes().read(0) == (byte) 3) + { + packets.clear(); + } + } + + // If the entity is rotating his head + else if (sentPacket.getType() == Server.ENTITY_HEAD_ROTATION) + { + if (disguise.getType().isPlayer() && entity.getType() != EntityType.PLAYER) + { + Location loc = entity.getLocation(); + + byte pitch = getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), + (byte) (int) (loc.getPitch() * 256.0F / 360.0F)); + byte yaw = getYaw(disguise.getType(), entity.getType(), sentPacket.getBytes().read(0)); + + PacketContainer rotation = new PacketContainer(Server.ENTITY_HEAD_ROTATION); + + StructureModifier mods = rotation.getModifier(); + + mods.write(0, entity.getEntityId()); + mods.write(1, yaw); + + PacketContainer look = new PacketContainer(Server.ENTITY_LOOK); + + look.getIntegers().write(0, entity.getEntityId()); + look.getBytes().write(0, yaw); + look.getBytes().write(1, pitch); + + packets.clear(); + + packets.addPacket(look); + packets.addPacket(rotation); + } + } + else + { + packets.setUnhandled(); } } catch (Exception e) { e.printStackTrace(); } - return packets == null ? null : new PacketContainer[][] - { - packets, delayedPackets - }; + + return packets; } /** diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java index f2f50711..760a6888 100644 --- a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java @@ -24,6 +24,7 @@ import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; + import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.EnumWrappers.Direction; import com.comphenix.protocol.wrappers.MinecraftKey; diff --git a/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java b/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java index 9cdd289a..18fdb65a 100644 --- a/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java +++ b/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java @@ -3,7 +3,6 @@ package me.libraryaddict.disguise.utilities.packetlisteners; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; -import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -16,31 +15,30 @@ import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.utilities.PacketsManager; +import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets; public class PacketListenerMain extends PacketAdapter { - private LibsDisguises libsDisguises; - public PacketListenerMain(LibsDisguises plugin, ArrayList packetsToListen) { super(plugin, ListenerPriority.HIGH, packetsToListen); - - libsDisguises = plugin; } @Override - public void onPacketSending(PacketEvent event) + public void onPacketSending(final PacketEvent event) { if (event.isCancelled()) return; - if (event.getPlayer().getName().contains("UNKNOWN[")) // If the player is temporary - return; - final Player observer = event.getPlayer(); + if (observer.getName().contains("UNKNOWN[")) // If the player is temporary + return; + // First get the entity, the one sending this packet StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); @@ -51,11 +49,16 @@ public class PacketListenerMain extends PacketAdapter if (entity == observer) return; - PacketContainer[][] packets; + final Disguise disguise = DisguiseAPI.getDisguise(observer, entity); + + if (disguise == null) + return; + + LibsPackets packets; try { - packets = PacketsManager.transformPacket(event.getPacket(), event.getPlayer(), entity); + packets = PacketsManager.transformPacket(event.getPacket(), disguise, observer, entity); } catch (Exception ex) { @@ -64,44 +67,23 @@ public class PacketListenerMain extends PacketAdapter return; } - if (packets == null) + if (packets.isUnhandled()) { return; } + packets.setPacketType(event.getPacketType()); + event.setCancelled(true); try { - for (PacketContainer packet : packets[0]) + for (PacketContainer packet : packets.getPackets()) { ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); } - final PacketContainer[] delayed = packets[1]; - - if (delayed.length == 0) - { - return; - } - - Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() - { - public void run() - { - try - { - for (PacketContainer packet : delayed) - { - ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); - } - } - catch (InvocationTargetException e) - { - e.printStackTrace(); - } - } - }, 2); + packets.sendDelayed(observer); } catch (InvocationTargetException ex) { diff --git a/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewDisguises.java b/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewDisguises.java index 1c5859f0..66e0a1b8 100644 --- a/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewDisguises.java +++ b/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewDisguises.java @@ -4,7 +4,6 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import com.comphenix.protocol.PacketType.Play.Server; @@ -20,24 +19,21 @@ import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.utilities.PacketsManager; +import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets; import me.libraryaddict.disguise.utilities.ReflectionManager; public class PacketListenerViewDisguises extends PacketAdapter { - private LibsDisguises libsDisguises; - public PacketListenerViewDisguises(LibsDisguises plugin) { super(plugin, ListenerPriority.HIGH, Server.NAMED_ENTITY_SPAWN, Server.ATTACH_ENTITY, Server.REL_ENTITY_MOVE, Server.REL_ENTITY_MOVE_LOOK, Server.ENTITY_LOOK, Server.ENTITY_TELEPORT, Server.ENTITY_HEAD_ROTATION, Server.ENTITY_METADATA, Server.ENTITY_EQUIPMENT, Server.ANIMATION, Server.BED, Server.ENTITY_EFFECT, Server.ENTITY_VELOCITY, Server.UPDATE_ATTRIBUTES, Server.ENTITY_STATUS); - - libsDisguises = plugin; } @Override - public void onPacketSending(PacketEvent event) + public void onPacketSending(final PacketEvent event) { if (event.isCancelled()) return; @@ -59,22 +55,22 @@ public class PacketListenerViewDisguises extends PacketAdapter return; } + final Disguise disguise = DisguiseAPI.getDisguise(observer, observer); + + if (disguise == null) + return; + // Here I grab the packets to convert them to, So I can display them as if the disguise sent them. - PacketContainer[][] transformed = PacketsManager.transformPacket(event.getPacket(), observer, observer); + LibsPackets transformed = PacketsManager.transformPacket(event.getPacket(), disguise, observer, observer); - PacketContainer[] packets = transformed == null ? null : transformed[0]; - - final PacketContainer[] delayedPackets = transformed == null ? null : transformed[1]; - - if (packets == null) + if (transformed.isUnhandled()) { - packets = new PacketContainer[] - { - event.getPacket() - }; + transformed.getPackets().add(event.getPacket()); } - for (PacketContainer packet : packets) + transformed.setPacketType(event.getPacketType()); + + for (PacketContainer packet : transformed.getPackets()) { if (packet.getType() != Server.PLAYER_INFO) { @@ -96,26 +92,7 @@ public class PacketListenerViewDisguises extends PacketAdapter } } - if (delayedPackets != null && delayedPackets.length > 0) - { - Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() - { - public void run() - { - try - { - for (PacketContainer packet : delayedPackets) - { - ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); - } - } - catch (InvocationTargetException e) - { - e.printStackTrace(); - } - } - }, 2); - } + transformed.sendDelayed(observer); if (event.getPacketType() == Server.ENTITY_METADATA) { @@ -182,8 +159,6 @@ public class PacketListenerViewDisguises extends PacketAdapter } else if (event.getPacketType() == Server.ENTITY_STATUS) { - Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer(), event.getPlayer()); - if (disguise.isSelfDisguiseSoundsReplaced() && !disguise.getType().isPlayer() && event.getPacket().getBytes().read(0) == 2) {