diff --git a/config.yml b/config.yml index c801f202..9427d2e4 100644 --- a/config.yml +++ b/config.yml @@ -27,4 +27,17 @@ RemoveHeldItem: true # If you set a disguise to burning, it will no longer be able to be shown as sneaking or invisible. # Set this to true if you want the disguise to get the animations of the disguised entity. Such as invisible, on fire, sprinting, sneaking, blocking # This is only valid if you set a animation on the disguise itself. Because the entitys animations are applied otherwise. -AddEntityAnimations: true \ No newline at end of file +AddEntityAnimations: true +# If all players who can see a targeted disguise (Only advalible to plugins) have quit. +# Does the plugin remove that disguise from valid disguises? If your plugin handles this. Then thats good. +# Else its a memory leak. This loops through all disguise to see if anyone else is online who can see that disguise. +RemoveUnusedDisguises: true +# This is only called into action when the disguise is constructed using the commands. +# And when the disguise supports that. This will not be used at all for plugins constructing the disguises for instance. +# Such as prophunt. Its also false because its kind of a retarded feature. +# This is pretty simple. It shows the players displayname (Name as it appears in chat) above their head. +# This also overrides any custom name they have set in their disguise options. +ShowNamesAboveDisguises: false +# This supports the above option. +# If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not. +NameAboveHeadAlwaysVisible: true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 329017a3..c485527f 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,11 @@ Comphenix Repository http://repo.comphenix.net/content/groups/public + + comphenix-snapshot-rep + Comphenix Snapshot Repository + http://repo.comphenix.net/content/repositories/snapshots/ + bukkit-repo http://repo.bukkit.org/content/groups/public @@ -56,7 +61,7 @@ com.comphenix.protocol ProtocolLib - 2.7.0 + 3.0.0-SNAPSHOT 7.7.5-SNAPSHOT diff --git a/src/me/libraryaddict/disguise/DisguiseAPI.java b/src/me/libraryaddict/disguise/DisguiseAPI.java index d230d7af..ba9a2b3e 100644 --- a/src/me/libraryaddict/disguise/DisguiseAPI.java +++ b/src/me/libraryaddict/disguise/DisguiseAPI.java @@ -1,7 +1,12 @@ package me.libraryaddict.disguise; import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; + import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import me.libraryaddict.disguise.events.DisguiseEvent; import me.libraryaddict.disguise.events.UndisguiseEvent; import me.libraryaddict.disguise.utilities.DisguiseUtilities; @@ -10,42 +15,24 @@ import me.libraryaddict.disguise.utilities.ReflectionManager; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; public class DisguiseAPI { private static boolean hearSelfDisguise; private static boolean hidingArmor; private static boolean hidingHeldItem; private static boolean isEntityAnimationsAdded; + private static boolean removeUnseenDisguises; private static boolean sendVelocity; + private static boolean showNameAboveHead; + private static boolean showNameAboveHeadAlwaysVisible; @Deprecated public static boolean canHearSelfDisguise() { return hearSelfDisguise; } - /** - * Disguise the next entity to spawn with this disguise. This may not work however if the entity doesn't actually spawn. - */ - public static void disguiseNextEntity(Disguise disguise) { - if (disguise == null) - return; - if (disguise.getEntity() != null || DisguiseUtilities.getDisguises().containsValue(disguise)) { - disguise = disguise.clone(); - } - try { - Field field = ReflectionManager.getNmsClass("Entity").getDeclaredField("entityCount"); - field.setAccessible(true); - int id = field.getInt(null); - DisguiseUtilities.getDisguises().put(id, disguise); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - /** - * Disguise this entity with this disguise - */ - public static void disguiseToAll(Entity entity, Disguise disguise) { + public static void disguiseEntity(Entity entity, Disguise disguise) { // If they are trying to disguise a null entity or use a null disguise // Just return. if (entity == null || disguise == null) @@ -67,28 +54,95 @@ public class DisguiseAPI { } // Set the disguise's entity disguise.setEntity(entity); - } // If there was a old disguise - Disguise oldDisguise = getDisguise(entity); + } // Stick the disguise in the disguises bin - DisguiseUtilities.getDisguises().put(entity.getEntityId(), disguise); + DisguiseUtilities.addDisguise(entity.getEntityId(), (TargetedDisguise) disguise); // Resend the disguised entity's packet - DisguiseUtilities.refreshTrackers(entity); + DisguiseUtilities.refreshTrackers((TargetedDisguise) disguise); // If he is a player, then self disguise himself DisguiseUtilities.setupFakeDisguise(disguise); - // Discard the disguise - if (oldDisguise != null) - oldDisguise.removeDisguise(); + } + + public static void disguiseIgnorePlayers(Entity entity, Disguise disguise, List playersToNotSeeDisguise) { + ((TargetedDisguise) disguise).setDisguiseTarget(TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS); + for (String name : playersToNotSeeDisguise) { + ((TargetedDisguise) disguise).addPlayer(name); + } + disguiseEntity(entity, disguise); + } + + public static void disguiseIgnorePlayers(Entity entity, Disguise disguise, String... playersToNotSeeDisguise) { + disguiseIgnorePlayers(entity, disguise, Arrays.asList(playersToNotSeeDisguise)); + } + + /** + * Disguise the next entity to spawn with this disguise. This may not work however if the entity doesn't actually spawn. + */ + public static void disguiseNextEntity(Disguise disguise) { + if (disguise == null) + return; + if (disguise.getEntity() != null || DisguiseUtilities.getDisguises().containsValue(disguise)) { + disguise = disguise.clone(); + } + try { + Field field = ReflectionManager.getNmsClass("Entity").getDeclaredField("entityCount"); + field.setAccessible(true); + int id = field.getInt(null); + DisguiseUtilities.addDisguise(id, (TargetedDisguise) disguise); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /** + * Disguise this entity with this disguise + */ + public static void disguiseToAll(Entity entity, Disguise disguise) { + // You called the disguiseToAll method foolish mortal! Prepare to have your custom settings wiped!!! + ((TargetedDisguise) disguise).setDisguiseTarget(TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS); + for (String observer : ((TargetedDisguise) disguise).getObservers()) + ((TargetedDisguise) disguise).removePlayer(observer); + disguiseEntity(entity, disguise); + } + + public static void disguiseToPlayers(Entity entity, Disguise disguise, List playersToViewDisguise) { + ((TargetedDisguise) disguise).setDisguiseTarget(TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS); + for (String name : playersToViewDisguise) { + ((TargetedDisguise) disguise).addPlayer(name); + } + disguiseEntity(entity, disguise); + } + + public static void disguiseToPlayers(Entity entity, Disguise disguise, String... playersToViewDisguise) { + disguiseToPlayers(entity, disguise, Arrays.asList(playersToViewDisguise)); } /** * Get the disguise of a entity */ + @Deprecated public static Disguise getDisguise(Entity disguised) { if (disguised == null) return null; - if (DisguiseUtilities.getDisguises().containsKey(disguised.getEntityId())) - return DisguiseUtilities.getDisguises().get(disguised.getEntityId()); - return null; + return DisguiseUtilities.getDisguise(disguised.getEntityId()); + } + + /** + * Get the disguise of a entity + */ + public static Disguise getDisguise(Player observer, Entity disguised) { + if (disguised == null) + return null; + return DisguiseUtilities.getDisguise(observer, disguised.getEntityId()); + } + + /** + * Get the disguises of a entity + */ + public static Disguise[] getDisguises(Entity disguised) { + if (disguised == null) + return null; + return DisguiseUtilities.getDisguises(disguised.getEntityId()); } /** @@ -103,10 +157,22 @@ public class DisguiseAPI { /** * Is this entity disguised */ + @Deprecated public static boolean isDisguised(Entity disguised) { return getDisguise(disguised) != null; } + /** + * Is this entity disguised + */ + public static boolean isDisguised(Player observer, Entity disguised) { + return getDisguise(observer, disguised) != null; + } + + public static boolean isDisguiseInUse(Disguise disguise) { + return DisguiseUtilities.isDisguiseInUse(disguise); + } + public static boolean isEntityAnimationsAdded() { return isEntityAnimationsAdded; } @@ -125,8 +191,12 @@ public class DisguiseAPI { return hidingHeldItem; } - public static boolean isInventoryListenerEnabled() { - return PacketsManager.isInventoryListenerEnabled(); + public static boolean isNameAboveHeadAlwaysVisible() { + return showNameAboveHeadAlwaysVisible; + } + + public static boolean isNameOfPlayerShownAboveDisguise() { + return showNameAboveHead; } public static boolean isSelfDisguisesSoundsReplaced() { @@ -140,6 +210,10 @@ public class DisguiseAPI { return PacketsManager.isHearDisguisesEnabled(); } + public static boolean isUnusedDisguisesRemoved() { + return removeUnseenDisguises; + } + /** * Is the velocity packets sent */ @@ -173,6 +247,7 @@ public class DisguiseAPI { public static void setHideArmorFromSelf(boolean hideArmor) { if (hidingArmor != hideArmor) { hidingArmor = hideArmor; + PacketsManager.setInventoryListenerEnabled(isHidingHeldItemFromSelf() || isHidingArmorFromSelf()); } } @@ -182,13 +257,16 @@ public class DisguiseAPI { public static void setHideHeldItemFromSelf(boolean hideHelditem) { if (hidingHeldItem != hideHelditem) { hidingHeldItem = hideHelditem; + PacketsManager.setInventoryListenerEnabled(isHidingHeldItemFromSelf() || isHidingArmorFromSelf()); } } - public static void setInventoryListenerEnabled(boolean inventoryListenerEnabled) { - if (PacketsManager.isInventoryListenerEnabled() != inventoryListenerEnabled) { - PacketsManager.setInventoryListenerEnabled(inventoryListenerEnabled); - } + public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) { + showNameAboveHeadAlwaysVisible = alwaysVisible; + } + + public static void setNameOfPlayerShownAboveDisguise(boolean showNames) { + showNameAboveHead = showNames; } /** @@ -198,6 +276,10 @@ public class DisguiseAPI { PacketsManager.setHearDisguisesListener(isSoundsEnabled); } + public static void setUnusedDisguisesRemoved(boolean remove) { + removeUnseenDisguises = remove; + } + /** * Disable velocity packets being sent for w/e reason. Maybe you want every ounce of performance you can get? */ @@ -214,14 +296,14 @@ public class DisguiseAPI { * the world. */ public static void undisguiseToAll(Entity entity) { - Disguise disguise = getDisguise(entity); - if (disguise == null) - return; - UndisguiseEvent event = new UndisguiseEvent(entity, disguise); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) - return; - disguise.removeDisguise(); + Disguise[] disguises = getDisguises(entity); + for (Disguise disguise : disguises) { + UndisguiseEvent event = new UndisguiseEvent(entity, disguise); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) + continue; + disguise.removeDisguise(); + } } private DisguiseAPI() { diff --git a/src/me/libraryaddict/disguise/DisguiseListener.java b/src/me/libraryaddict/disguise/DisguiseListener.java index b3f60fe7..be0871ee 100644 --- a/src/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/me/libraryaddict/disguise/DisguiseListener.java @@ -3,6 +3,8 @@ package me.libraryaddict.disguise; import java.util.HashMap; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.UpdateChecker; @@ -14,6 +16,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.scheduler.BukkitRunnable; @@ -66,6 +69,15 @@ public class DisguiseListener implements Listener { p.sendMessage(String.format(updateMessage, currentVersion, latestVersion)); } + @EventHandler + public void onQuit(PlayerQuitEvent event) { + if (DisguiseAPI.isUnusedDisguisesRemoved()) { + for (TargetedDisguise disguise : DisguiseUtilities.getSeenDisguises(event.getPlayer().getName())) { + disguise.removeDisguise(); + } + } + } + @EventHandler public void onRightClick(PlayerInteractEntityEvent event) { if (disguiseSlap.containsKey(event.getPlayer().getName())) { @@ -74,6 +86,15 @@ public class DisguiseListener implements Listener { disguiseRunnable.remove(event.getPlayer().getName()).cancel(); String entityName = event.getRightClicked().getType().name().toLowerCase().replace("_", " "); if (disguise != null) { + if (event.getRightClicked() instanceof Player && DisguiseAPI.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { + ((LivingWatcher) disguise.getWatcher()) + .setCustomName(((Player) event.getRightClicked()).getDisplayName()); + if (DisguiseAPI.isNameAboveHeadAlwaysVisible()) { + ((LivingWatcher) disguise.getWatcher()).setCustomNameVisible(true); + } + } + } DisguiseAPI.disguiseToAll(event.getRightClicked(), disguise); event.getPlayer().sendMessage( ChatColor.RED + "Disguised the " + entityName + " as a " @@ -92,8 +113,7 @@ public class DisguiseListener implements Listener { public void onVechileEnter(VehicleEnterEvent event) { if (event.isCancelled()) return; - Disguise disguise = DisguiseAPI.getDisguise(event.getEntered()); - if (disguise != null && event.getEntered() instanceof Player) { + if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) { DisguiseUtilities.removeSelfDisguise((Player) event.getEntered()); ((Player) event.getEntered()).updateInventory(); } @@ -103,14 +123,16 @@ public class DisguiseListener implements Listener { public void onVechileLeave(VehicleExitEvent event) { if (event.isCancelled()) return; - final Disguise disguise = DisguiseAPI.getDisguise(event.getExited()); - if (disguise != null && event.getExited() instanceof Player) { - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - public void run() { - DisguiseUtilities.setupFakeDisguise(disguise); - ((Player) disguise.getEntity()).updateInventory(); - } - }); + if (event.getExited() instanceof Player) { + final Disguise disguise = DisguiseAPI.getDisguise((Player) event.getExited(), event.getExited()); + if (disguise != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + DisguiseUtilities.setupFakeDisguise(disguise); + ((Player) disguise.getEntity()).updateInventory(); + } + }); + } } } diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index 60820715..3f033f17 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -64,9 +64,8 @@ public class LibsDisguises extends JavaPlugin { DisguiseAPI.setHideArmorFromSelf(getConfig().getBoolean("RemoveArmor")); DisguiseAPI.setHideHeldItemFromSelf(getConfig().getBoolean("RemoveHeldItem")); DisguiseAPI.setAddEntityAnimations(getConfig().getBoolean("AddEntityAnimations")); - if (DisguiseAPI.isHidingArmorFromSelf() || DisguiseAPI.isHidingHeldItemFromSelf()) { - DisguiseAPI.setInventoryListenerEnabled(true); - } + DisguiseAPI.setNameOfPlayerShownAboveDisguise(getConfig().getBoolean("ShowNamesAboveDisguises")); + DisguiseAPI.setNameAboveHeadAlwaysVisible(getConfig().getBoolean("NameAboveHeadAlwaysVisible")); try { // Here I use reflection to set the plugin for Disguise.. // Kind of stupid but I don't want open API calls for a commonly used object. diff --git a/src/me/libraryaddict/disguise/commands/DisguiseCommand.java b/src/me/libraryaddict/disguise/commands/DisguiseCommand.java index c71244b3..ef05a279 100644 --- a/src/me/libraryaddict/disguise/commands/DisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/DisguiseCommand.java @@ -3,6 +3,7 @@ package me.libraryaddict.disguise.commands; import java.util.ArrayList; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.BaseDisguiseCommand; import org.apache.commons.lang.StringUtils; @@ -30,6 +31,14 @@ public class DisguiseCommand extends BaseDisguiseCommand { } return true; } + if (DisguiseAPI.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { + ((LivingWatcher) disguise.getWatcher()).setCustomName(((Player) sender).getDisplayName()); + if (DisguiseAPI.isNameAboveHeadAlwaysVisible()) { + ((LivingWatcher) disguise.getWatcher()).setCustomNameVisible(true); + } + } + } DisguiseAPI.disguiseToAll((Player) sender, disguise); sender.sendMessage(ChatColor.RED + "Now disguised as a " + disguise.getType().toReadable()); return true; diff --git a/src/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java b/src/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java index 4618a970..7130272d 100644 --- a/src/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java +++ b/src/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java @@ -3,6 +3,7 @@ package me.libraryaddict.disguise.commands; import java.util.ArrayList; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.BaseDisguiseCommand; import org.apache.commons.lang.StringUtils; @@ -49,6 +50,14 @@ public class DisguisePlayerCommand extends BaseDisguiseCommand { } return true; } + if (DisguiseAPI.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { + ((LivingWatcher) disguise.getWatcher()).setCustomName(((Player) player).getDisplayName()); + if (DisguiseAPI.isNameAboveHeadAlwaysVisible()) { + ((LivingWatcher) disguise.getWatcher()).setCustomNameVisible(true); + } + } + } DisguiseAPI.disguiseToAll(player, disguise); sender.sendMessage(ChatColor.RED + "Successfully disguised " + player.getName() + " as a " + disguise.getType().toReadable() + "!"); diff --git a/src/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java b/src/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java index 178daeb6..c1f885c5 100644 --- a/src/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java +++ b/src/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java @@ -3,6 +3,7 @@ package me.libraryaddict.disguise.commands; import java.util.ArrayList; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.BaseDisguiseCommand; import org.apache.commons.lang.StringUtils; @@ -66,6 +67,15 @@ public class DisguiseRadiusCommand extends BaseDisguiseCommand { for (Entity entity : ((Player) sender).getNearbyEntities(radius, radius, radius)) { if (entity == sender) continue; + disguise = disguise.clone(); + if (entity instanceof Player && DisguiseAPI.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { + ((LivingWatcher) disguise.getWatcher()).setCustomName(((Player) entity).getDisplayName()); + if (DisguiseAPI.isNameAboveHeadAlwaysVisible()) { + ((LivingWatcher) disguise.getWatcher()).setCustomNameVisible(true); + } + } + } DisguiseAPI.disguiseToAll(entity, disguise); disguisedEntitys++; } diff --git a/src/me/libraryaddict/disguise/disguisetypes/AnimalColor.java b/src/me/libraryaddict/disguise/disguisetypes/AnimalColor.java index c1021d00..08a1fa5a 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/AnimalColor.java +++ b/src/me/libraryaddict/disguise/disguisetypes/AnimalColor.java @@ -10,6 +10,9 @@ public enum AnimalColor { value = newValue; } + /** + * The color ID as defined by nms internals. + */ public int getId() { return value; } diff --git a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java index edbba176..f7a5c21d 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -22,7 +22,7 @@ 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.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; @@ -48,12 +48,15 @@ public abstract class Disguise { @Override public abstract Disguise clone(); + /** + * Seems I do this method so I can make cleaner constructors on disguises.. + */ protected void createDisguise(DisguiseType newType, boolean doSounds) { if (getWatcher() != null) return; if (newType.getEntityType() == null) { throw new RuntimeException("DisguiseType " + newType - + " was used to attempt to construct a disguise, but this version of craftbukkit does not have that entity"); + + " was used in a futile attempt to construct a disguise, but this version of craftbukkit does not have that entity"); } // Set the disguise type disguiseType = newType; @@ -61,7 +64,7 @@ public abstract class Disguise { setReplaceSounds(doSounds); // Get if they are a adult now.. boolean isAdult = true; - if (this instanceof MobDisguise) { + if (isMobDisguise()) { isAdult = ((MobDisguise) this).isAdult(); } try { @@ -175,6 +178,7 @@ public abstract class Disguise { final boolean sendMovementPacket = movement; final double vectorY = fallSpeed; final boolean alwaysSendVelocity = alwaysSend; + final TargetedDisguise disguise=(TargetedDisguise) this; // A scheduler to clean up any unused disguises. velocityRunnable = new BukkitRunnable() { private int i = 0; @@ -185,11 +189,11 @@ public abstract class Disguise { DisguiseAPI.undisguiseToAll(getEntity()); } else { // If the disguise type is tnt, we need to resend the entity packet else it will turn invisible - if (getType() == DisguiseType.PRIMED_TNT) { + if (getType() == DisguiseType.PRIMED_TNT || getType() == DisguiseType.FIREWORK) { i++; if (i % 40 == 0) { i = 0; - DisguiseUtilities.refreshTrackers(getEntity()); + DisguiseUtilities.refreshTrackers(disguise); if (getEntity() instanceof Player && isSelfDisguiseVisible()) { DisguiseUtilities.sendSelfDisguise((Player) getEntity()); } @@ -206,7 +210,7 @@ public abstract class Disguise { if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) { PacketContainer lookPacket = null; if (getType() == DisguiseType.WITHER_SKULL) { - lookPacket = new PacketContainer(Packets.Server.ENTITY_LOOK); + lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK); StructureModifier mods = lookPacket.getModifier(); mods.write(0, getEntity().getEntityId()); Location loc = getEntity().getLocation(); @@ -229,7 +233,7 @@ public abstract class Disguise { try { Field ping = ReflectionManager.getNmsClass("EntityPlayer").getField("ping"); for (Player player : getPerverts()) { - PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_VELOCITY); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_VELOCITY); StructureModifier mods = packet.getModifier(); if (getEntity() == player) { if (!isSelfDisguiseVisible()) { @@ -256,7 +260,7 @@ public abstract class Disguise { } // If we need to send more packets because else it still 'sinks' if (sendMovementPacket) { - PacketContainer packet = new PacketContainer(Packets.Server.REL_ENTITY_MOVE); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE); StructureModifier mods = packet.getModifier(); mods.write(0, getEntity().getEntityId()); for (Player player : getPerverts()) { @@ -283,7 +287,7 @@ public abstract class Disguise { } /** - * Get all EntityPlayers who have this entity in their Entity Tracker + * Get all EntityPlayers who have this entity in their Entity Tracker And they are in the targetted disguise. */ protected ArrayList getPerverts() { ArrayList players = new ArrayList(); @@ -297,7 +301,10 @@ public abstract class Disguise { HashSet trackedPlayers = (HashSet) entityTrackerEntry.getClass().getField("trackedPlayers") .get(entityTrackerEntry); for (Object p : trackedPlayers) { - players.add((Player) ReflectionManager.getBukkitEntity(p)); + Player player = (Player) ReflectionManager.getBukkitEntity(p); + if (((TargetedDisguise) this).canSee(player)) { + players.add(player); + } } } } catch (Exception ex) { @@ -329,15 +336,15 @@ public abstract class Disguise { } public boolean isMiscDisguise() { - return this instanceof MiscDisguise; + return false; } public boolean isMobDisguise() { - return this instanceof MobDisguise; + return false; } public boolean isPlayerDisguise() { - return this instanceof PlayerDisguise; + return false; } public boolean isSelfDisguiseSoundsReplaced() { @@ -368,22 +375,19 @@ public abstract class Disguise { velocityRunnable.cancel(); } catch (Exception ex) { } - HashMap disguises = DisguiseUtilities.getDisguises(); + HashMap> disguises = DisguiseUtilities.getDisguises(); // If this disguise has a entity set if (getEntity() != null) { // If the entity is valid if (getEntity().isValid()) { // If this disguise is active - if (disguises.containsKey(getEntity().getEntityId()) && disguises.get(getEntity().getEntityId()) == this) { - // Now remove the disguise from the current disguises. - disguises.remove(getEntity().getEntityId()); - // Gotta do reflection, copy code or open up calls. - // Reflection is the cleanest? + // Remove the disguise from the current disguises. + if (DisguiseUtilities.removeDisguise((TargetedDisguise) this)) { if (getEntity() instanceof Player) { DisguiseUtilities.removeSelfDisguise((Player) getEntity()); } // Better refresh the entity to undisguise it - DisguiseUtilities.refreshTrackers(getEntity()); + DisguiseUtilities.refreshTrackers((TargetedDisguise) this); } } } else { @@ -391,7 +395,7 @@ public abstract class Disguise { Iterator itel = disguises.keySet().iterator(); while (itel.hasNext()) { int id = itel.next(); - if (disguises.get(id) == this) { + if (disguises.get(id).remove(this) && disguises.get(id).isEmpty()) { itel.remove(); } } @@ -550,7 +554,7 @@ public abstract class Disguise { if (this.viewSelfDisguise != viewSelfDisguise) { this.viewSelfDisguise = viewSelfDisguise; if (getEntity() != null && getEntity() instanceof Player) { - if (DisguiseAPI.getDisguise(getEntity()) == this) { + if (DisguiseAPI.getDisguise((Player) getEntity(), getEntity()) == this) { if (viewSelfDisguise) { DisguiseUtilities.setupFakeDisguise(this); } else diff --git a/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java index 4a3de874..dc79010f 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java @@ -12,7 +12,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.EntityEquipment; -import com.comphenix.protocol.Packets; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; @@ -42,14 +42,14 @@ public class FlagWatcher { * This is the entity values I need to add else it could crash them.. */ private HashMap backupEntityValues = new HashMap(); - private Disguise disguise; + private TargetedDisguise disguise; private HashMap entityValues = new HashMap(); private boolean hasDied; private org.bukkit.inventory.ItemStack[] items = new org.bukkit.inventory.ItemStack[5]; private HashSet modifiedEntityAnimations = new HashSet(); public FlagWatcher(Disguise disguise) { - this.disguise = disguise; + this.disguise = (TargetedDisguise) disguise; } @Override @@ -67,6 +67,7 @@ public class FlagWatcher { cloned.entityValues = (HashMap) entityValues.clone(); cloned.items = items.clone(); cloned.modifiedEntityAnimations = (HashSet) modifiedEntityAnimations.clone(); + cloned.addEntityAnimations = addEntityAnimations; return cloned; } @@ -129,7 +130,8 @@ public class FlagWatcher { } } // Here we check for if there is a health packet that says they died. - if (disguise.isSelfDisguiseVisible() && getDisguise().getEntity() != null && getDisguise().getEntity() instanceof Player) { + if (getDisguise().isSelfDisguiseVisible() && getDisguise().getEntity() != null + && getDisguise().getEntity() instanceof Player) { for (WrappedWatchableObject watch : newList) { // Its a health packet if (watch.getIndex() == 6) { @@ -157,7 +159,7 @@ public class FlagWatcher { return armor; } - protected Disguise getDisguise() { + protected TargetedDisguise getDisguise() { return disguise; } @@ -165,7 +167,12 @@ public class FlagWatcher { return ((Byte) getValue(0, (byte) 0) & 1 << i) != 0; } + @Deprecated public org.bukkit.inventory.ItemStack getHeldItem() { + return getItemInHand(); + } + + public org.bukkit.inventory.ItemStack getItemInHand() { return getItemStack(SlotType.HELD_ITEM); } @@ -217,7 +224,7 @@ public class FlagWatcher { } protected void sendData(int data) { - if (disguise.getWatcher() == null || DisguiseAPI.getDisguise(disguise.getEntity()) != disguise) + if (getDisguise().getWatcher() == null || !DisguiseAPI.isDisguiseInUse(getDisguise())) return; if (!entityValues.containsKey(data) || entityValues.get(data) == null) return; @@ -225,7 +232,7 @@ public class FlagWatcher { Object value = entityValues.get(data); List list = new ArrayList(); list.add(new WrappedWatchableObject(data, value)); - PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_METADATA); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); StructureModifier mods = packet.getModifier(); mods.write(0, entity.getEntityId()); packet.getWatchableCollectionModifier().write(0, list); @@ -270,8 +277,9 @@ public class FlagWatcher { } } + @Deprecated public void setHeldItem(org.bukkit.inventory.ItemStack itemstack) { - setItemStack(SlotType.HELD_ITEM, itemstack); + setItemInHand(itemstack); } public void setInvisible(boolean setInvis) { @@ -279,11 +287,15 @@ public class FlagWatcher { sendData(0); } + public void setItemInHand(org.bukkit.inventory.ItemStack itemstack) { + setItemStack(SlotType.HELD_ITEM, itemstack); + } + 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) { + if (getDisguise().getEntity() instanceof LivingEntity) { EntityEquipment enquipment = ((LivingEntity) getDisguise().getEntity()).getEquipment(); if (slot == 0) { itemStack = enquipment.getItemInHand(); @@ -299,12 +311,12 @@ public class FlagWatcher { if (itemStack != null && itemStack.getTypeId() != 0) itemToSend = ReflectionManager.getNmsItem(itemStack); items[slot] = itemStack; - if (DisguiseAPI.getDisguise(disguise.getEntity()) != disguise) + if (!DisguiseAPI.isDisguiseInUse(getDisguise())) return; slot++; if (slot > 4) slot = 0; - PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_EQUIPMENT); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT); StructureModifier mods = packet.getModifier(); mods.write(0, getDisguise().getEntity().getEntityId()); mods.write(1, slot); diff --git a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java index 0ea7942f..d8df35fd 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java @@ -11,7 +11,7 @@ import org.bukkit.Art; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; -public class MiscDisguise extends Disguise { +public class MiscDisguise extends TargetedDisguise { private int data = -1; private int id = -1; @@ -141,4 +141,8 @@ public class MiscDisguise extends Disguise { return id; } + public boolean isMiscDisguise() { + return true; + } + } \ No newline at end of file diff --git a/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java index b4bca238..c8519478 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java @@ -5,7 +5,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; import org.bukkit.entity.EntityType; -public class MobDisguise extends Disguise { +public class MobDisguise extends TargetedDisguise { private boolean isAdult; @@ -21,12 +21,14 @@ public class MobDisguise extends Disguise { this.isAdult = isAdult; createDisguise(disguiseType, replaceSounds); } + @Deprecated public MobDisguise(EntityType entityType) { this(entityType, true); } + @Deprecated public MobDisguise(EntityType entityType, boolean isAdult) { this(entityType, isAdult, true); @@ -68,4 +70,8 @@ public class MobDisguise extends Disguise { } return isAdult; } + + public boolean isMobDisguise() { + return true; + } } \ No newline at end of file diff --git a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index 00c7036b..f3dd8db8 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.disguisetypes; -public class PlayerDisguise extends Disguise { +public class PlayerDisguise extends TargetedDisguise { private String playerName; public PlayerDisguise(String name) { @@ -30,4 +30,9 @@ public class PlayerDisguise extends Disguise { return playerName; } + @Override + public boolean isPlayerDisguise() { + return true; + } + } \ No newline at end of file diff --git a/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java new file mode 100644 index 00000000..bb912ff7 --- /dev/null +++ b/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java @@ -0,0 +1,87 @@ +package me.libraryaddict.disguise.disguisetypes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; + +import org.bukkit.entity.Player; + +public abstract class TargetedDisguise extends Disguise { + public enum TargetType { + HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS, SHOW_TO_EVERYONE_BUT_THESE_PLAYERS; + } + + private List disguiseViewers = new ArrayList(); + + private TargetType targetType = TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS; + + public void addPlayer(Player player) { + addPlayer(player.getName()); + } + + public void addPlayer(String playername) { + if (!disguiseViewers.contains(playername)) { + disguiseViewers.add(playername); + if (DisguiseAPI.isDisguiseInUse(this)) { + DisguiseUtilities.checkConflicts(this, playername); + DisguiseUtilities.refreshTracker(this, playername); + } + } + } + + public boolean canSee(Player player) { + return canSee(player.getName()); + } + + public boolean canSee(String playername) { + boolean hasPlayer = disguiseViewers.contains(playername); + if (targetType == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { + return !hasPlayer; + } + return hasPlayer; + } + + public TargetType getDisguiseTarget() { + return targetType; + } + + public List getObservers() { + return Collections.unmodifiableList(disguiseViewers); + } + + public void removePlayer(Player player) { + removePlayer(player.getName()); + } + + public void removePlayer(String playername) { + if (disguiseViewers.contains(playername)) { + disguiseViewers.remove(playername); + if (DisguiseAPI.isDisguiseInUse(this)) { + DisguiseUtilities.checkConflicts(this, playername); + DisguiseUtilities.refreshTracker(this, playername); + } + } + } + + public void setDisguiseTarget(TargetType newTargetType) { + if (DisguiseUtilities.isDisguiseInUse(this)) { + throw new RuntimeException("Cannot set the disguise target after the entity has been disguised"); + } + targetType = newTargetType; + } + + public void silentlyAddPlayer(String playername) { + if (!disguiseViewers.contains(playername)) { + disguiseViewers.add(playername); + } + } + + public void silentlyRemovePlayer(String playername) { + if (disguiseViewers.contains(playername)) { + disguiseViewers.remove(playername); + } + } +} diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/AgeableWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/AgeableWatcher.java index 731de581..ad320608 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/AgeableWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/AgeableWatcher.java @@ -12,6 +12,7 @@ public class AgeableWatcher extends LivingWatcher { return (Integer) getValue(12, 0); } + @Deprecated public boolean isAdult() { return !isBaby(); } @@ -20,6 +21,7 @@ public class AgeableWatcher extends LivingWatcher { return (Integer) getValue(12, 0) < 0; } + @Deprecated public void setAdult(boolean isAdult) { setBaby(!isAdult); } diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/CreeperWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/CreeperWatcher.java index feb112e0..71ad3c85 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/CreeperWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/CreeperWatcher.java @@ -8,6 +8,7 @@ public class CreeperWatcher extends LivingWatcher { super(disguise); } + @Deprecated public boolean isFused() { return (Byte) getValue(16, (byte) 0) == 1; } @@ -26,6 +27,7 @@ public class CreeperWatcher extends LivingWatcher { sendData(16); } + @Deprecated public void setFused(boolean isFused) { setValue(16, (byte) (isFused ? 1 : -1)); sendData(16); diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/EndermanWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/EndermanWatcher.java index 80e46fe9..c7c60659 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/EndermanWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/EndermanWatcher.java @@ -21,7 +21,13 @@ public class EndermanWatcher extends LivingWatcher { } @Override + @Deprecated public ItemStack getHeldItem() { + return getItemInHand(); + } + + @Override + public ItemStack getItemInHand() { return new ItemStack((Byte) getValue(16, (byte) 0), 1, ((Byte) getValue(17, (byte) 0))); } @@ -49,7 +55,13 @@ public class EndermanWatcher extends LivingWatcher { } @Override + @Deprecated public void setHeldItem(ItemStack itemstack) { + setItemInHand(itemstack); + } + + @Override + public void setItemInHand(ItemStack itemstack) { setValue(16, (byte) (itemstack.getTypeId() & 255)); setValue(17, (byte) (itemstack.getDurability() & 255)); } diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/FallingBlockWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/FallingBlockWatcher.java index 11d6797f..5a823c61 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/FallingBlockWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/FallingBlockWatcher.java @@ -27,7 +27,7 @@ public class FallingBlockWatcher extends FlagWatcher { public void setBlock(ItemStack block) { this.block = block; if (getDisguise().getEntity() != null && getDisguise().getWatcher() == this) { - DisguiseUtilities.refreshTrackers(getDisguise().getEntity()); + DisguiseUtilities.refreshTrackers(getDisguise()); } } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/PaintingWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/PaintingWatcher.java index 3ae3ee1b..1c27ede2 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/PaintingWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/PaintingWatcher.java @@ -26,7 +26,7 @@ public class PaintingWatcher extends FlagWatcher { public void setArt(Art newPainting) { this.painting = newPainting; if (getDisguise().getEntity() != null && getDisguise().getWatcher() == this) { - DisguiseUtilities.refreshTrackers(getDisguise().getEntity()); + DisguiseUtilities.refreshTrackers(getDisguise()); } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/SplashPotionWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/SplashPotionWatcher.java index 44d1c45c..21ff5919 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/SplashPotionWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/SplashPotionWatcher.java @@ -25,7 +25,7 @@ public class SplashPotionWatcher extends FlagWatcher { public void setPotionId(int newPotionId) { this.potionId = newPotionId; if (getDisguise().getEntity() != null && getDisguise().getWatcher() == this) { - DisguiseUtilities.refreshTrackers(getDisguise().getEntity()); + DisguiseUtilities.refreshTrackers(getDisguise()); } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/ZombieWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/ZombieWatcher.java index f96e40c6..97d44a11 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/ZombieWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/ZombieWatcher.java @@ -8,16 +8,26 @@ public class ZombieWatcher extends LivingWatcher { super(disguise); } + @Deprecated public boolean isAdult() { return (Byte) getValue(12, (byte) 0) == 0; } + public boolean isBaby() { + return (Byte) getValue(12, (byte) 0) == 1; + } + public boolean isVillager() { return (Byte) getValue(13, (byte) 0) == 1; } + @Deprecated public void setAdult(boolean adult) { - setValue(12, (byte) (adult ? 0 : 1)); + setBaby(!adult); + } + + public void setBaby(boolean baby) { + setValue(12, (byte) (baby ? 1 : 0)); sendData(12); } diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 15aa569c..41876296 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -2,12 +2,17 @@ package me.libraryaddict.disguise.utilities; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; +import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -18,22 +23,169 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.util.Vector; -import com.comphenix.protocol.Packets; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedDataWatcher; public class DisguiseUtilities { - // Store the entity IDs instead of entitys because then I can disguise entitys even before they exist - private static HashMap disguises = new HashMap(); private static LibsDisguises libsDisguises; // A internal storage of fake entity ID's I can use. // Realistically I could probably use a ID like "4" for everyone, seeing as no one shares the ID private static HashMap selfDisguisesIds = new HashMap(); + // Store the entity IDs instead of entitys because then I can disguise entitys even before they exist + private static HashMap> targetedDisguises = new HashMap>(); - public static HashMap getDisguises() { - return disguises; + public static void addDisguise(int entityId, TargetedDisguise disguise) { + // TODO Make sure that the disguised entity doesn't have the player looking at other girls + // ^ Done? + if (!getDisguises().containsKey(entityId)) { + getDisguises().put(entityId, new HashSet()); + } + getDisguises().get(entityId).add(disguise); + checkConflicts(disguise, null); + } + + /** + * If name isn't null. Make sure that the name doesn't see any other disguise. Else if name is null. Make sure that the + * observers in the disguise don't see any other disguise. + */ + public static void checkConflicts(TargetedDisguise disguise, String name) { + // If the disguise is being used.. Else we may accidentally undisguise something else + if (DisguiseAPI.isDisguiseInUse(disguise)) { + Iterator disguiseItel = getDisguises().get(disguise.getEntity().getEntityId()).iterator(); + // Iterate through the disguises + while (disguiseItel.hasNext()) { + TargetedDisguise d = disguiseItel.next(); + // Make sure the disguise isn't the same thing + if (d != disguise) { + // If the loop'd disguise is hiding the disguise to everyone in its list + if (d.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) { + // If player is a observer in the loop + if (disguise.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) { + // If player is a observer in the disguise + // Remove them from the loop + if (name != null) { + d.removePlayer(name); + } else { + for (String playername : disguise.getObservers()) { + d.silentlyRemovePlayer(playername); + } + } + } else if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { + // If player is not a observer in the loop + if (name != null) { + if (!disguise.getObservers().contains(name)) { + d.removePlayer(name); + } + } else { + for (String playername : d.getObservers()) { + if (!disguise.getObservers().contains(playername)) { + d.silentlyRemovePlayer(playername); + } + } + } + } + } else if (d.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { + // Here you add it to the loop if they see the disguise + if (disguise.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) { + // Everyone who is in the disguise needs to be added to the loop + if (name != null) { + d.addPlayer(name); + } else { + for (String playername : disguise.getObservers()) { + d.silentlyAddPlayer(playername); + } + } + } else if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { + // This here is a paradox. + // If fed a name. I can do this. + // But the rest of the time.. Its going to conflict. + // The below is debug output. Most people wouldn't care for it. + + // System.out.print("Cannot set more than one " + TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS + // + " on a entity. Removed the old disguise."); + + disguiseItel.remove(); + /* if (name != null) { + if (!disguise.getObservers().contains(name)) { + d.setViewDisguise(name); + } + } else { + for (String playername : d.getObservers()) { + if (!disguise.getObservers().contains(playername)) { + d.setViewDisguise(playername); + } + } + }*/ + } + } + } + } + } + } + + @Deprecated + public static TargetedDisguise getDisguise(int entityId) { + TargetedDisguise toReturn = null; + if (getDisguises().containsKey(entityId)) { + for (TargetedDisguise disguise : getDisguises().get(entityId)) { + if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS + && disguise.getObservers().isEmpty()) { + return disguise; + } + if (toReturn == null) { + toReturn = disguise; + } + } + } + return toReturn; + } + + public static TargetedDisguise getDisguise(Player observer, int entityId) { + if (getDisguises().containsKey(entityId)) { + for (TargetedDisguise disguise : getDisguises().get(entityId)) { + if (disguise.canSee(observer)) { + return disguise; + } + } + } + return null; + } + + public static HashMap> getDisguises() { + return targetedDisguises; + } + + public static TargetedDisguise[] getDisguises(int entityId) { + if (getDisguises().containsKey(entityId)) { + return getDisguises().get(entityId).toArray(new TargetedDisguise[getDisguises().get(entityId).size()]); + } + return new TargetedDisguise[0]; + } + + public static List getSeenDisguises(String viewer) { + List dis = new ArrayList(); + for (HashSet disguises : getDisguises().values()) { + for (TargetedDisguise disguise : disguises) { + if (disguise.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) { + if (disguise.canSee(viewer)) { + boolean add = true; + for (String observer : disguise.getObservers()) { + if (!observer.equals(viewer) && Bukkit.getPlayerExact(observer) != null) { + add = false; + break; + } + } + if (add) { + dis.add(disguise); + } + } + } + } + } + return dis; } public static HashMap getSelfDisguisesIds() { @@ -44,17 +196,25 @@ public class DisguiseUtilities { libsDisguises = disguises; } + public static boolean isDisguiseInUse(Disguise disguise) { + if (disguise.getEntity() != null && getDisguises().containsKey(disguise.getEntity().getEntityId()) + && getDisguises().get(disguise.getEntity().getEntityId()).contains(disguise)) { + return true; + } + return false; + } + /** * @param Resends * the entity to all the watching players, which is where the magic begins */ - public static void refreshTrackers(Entity entity) { + public static void refreshTracker(TargetedDisguise disguise, String player) { try { - Object world = ReflectionManager.getWorld(entity.getWorld()); + Object world = ReflectionManager.getWorld(disguise.getEntity().getWorld()); Object tracker = world.getClass().getField("tracker").get(world); Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker); Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class) - .invoke(trackedEntities, entity.getEntityId()); + .invoke(trackedEntities, disguise.getEntity().getEntityId()); if (entityTrackerEntry != null) { HashSet trackedPlayers = (HashSet) entityTrackerEntry.getClass().getField("trackedPlayers") .get(entityTrackerEntry); @@ -62,11 +222,12 @@ public class DisguiseUtilities { Method updatePlayer = entityTrackerEntry.getClass().getMethod("updatePlayer", ReflectionManager.getNmsClass("EntityPlayer")); HashSet cloned = (HashSet) trackedPlayers.clone(); - for (Object player : cloned) { - if (entity instanceof Player && !((Player) ReflectionManager.getBukkitEntity(player)).canSee((Player) entity)) - continue; - clear.invoke(entityTrackerEntry, player); - updatePlayer.invoke(entityTrackerEntry, player); + for (Object p : cloned) { + if (player.equals(((Player) ReflectionManager.getBukkitEntity(p)).getName())) { + clear.invoke(entityTrackerEntry, p); + updatePlayer.invoke(entityTrackerEntry, p); + break; + } } } } catch (Exception ex) { @@ -74,10 +235,55 @@ public class DisguiseUtilities { } } + /** + * @param Resends + * the entity to all the watching players, which is where the magic begins + */ + public static void refreshTrackers(TargetedDisguise disguise) { + try { + Object world = ReflectionManager.getWorld(disguise.getEntity().getWorld()); + Object tracker = world.getClass().getField("tracker").get(world); + Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker); + Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class) + .invoke(trackedEntities, disguise.getEntity().getEntityId()); + if (entityTrackerEntry != null) { + HashSet trackedPlayers = (HashSet) entityTrackerEntry.getClass().getField("trackedPlayers") + .get(entityTrackerEntry); + Method clear = entityTrackerEntry.getClass().getMethod("clear", ReflectionManager.getNmsClass("EntityPlayer")); + Method updatePlayer = entityTrackerEntry.getClass().getMethod("updatePlayer", + ReflectionManager.getNmsClass("EntityPlayer")); + HashSet cloned = (HashSet) trackedPlayers.clone(); + for (Object p : cloned) { + Player player = (Player) ReflectionManager.getBukkitEntity(p); + // if (entity instanceof Player && !((Player) ReflectionManager.getBukkitEntity(player)).canSee((Player) + // entity)) + // continue; + if (disguise.canSee(player.getName())) { + clear.invoke(entityTrackerEntry, p); + updatePlayer.invoke(entityTrackerEntry, p); + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static boolean removeDisguise(TargetedDisguise disguise) { + int entityId = disguise.getEntity().getEntityId(); + if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) { + if (getDisguises().get(entityId).isEmpty()) { + getDisguises().remove(entityId); + } + return true; + } + return false; + } + public static void removeSelfDisguise(Player player) { if (selfDisguisesIds.containsKey(player.getEntityId())) { // Send a packet to destroy the fake entity - PacketContainer packet = new PacketContainer(Packets.Server.DESTROY_ENTITY); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); packet.getModifier().write(0, new int[] { selfDisguisesIds.get(player.getEntityId()) }); try { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); @@ -108,7 +314,7 @@ public class DisguiseUtilities { player, ProtocolLibrary .getProtocolManager() - .createPacketConstructor(Packets.Server.ENTITY_METADATA, player.getEntityId(), + .createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(), WrappedDataWatcher.getEntityWatcher(player), true) .createPacket(player.getEntityId(), WrappedDataWatcher.getEntityWatcher(player), true)); } catch (Exception ex) { @@ -147,11 +353,11 @@ public class DisguiseUtilities { .getNmsEntity(player)); ProtocolManager manager = ProtocolLibrary.getProtocolManager(); // Send the player a packet with himself being spawned - manager.sendServerPacket(player, manager.createPacketConstructor(Packets.Server.NAMED_ENTITY_SPAWN, player) + manager.sendServerPacket(player, manager.createPacketConstructor(PacketType.Play.Server.NAMED_ENTITY_SPAWN, player) .createPacket(player)); manager.sendServerPacket( player, - manager.createPacketConstructor(Packets.Server.ENTITY_METADATA, player.getEntityId(), + manager.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(), WrappedDataWatcher.getEntityWatcher(player), true).createPacket(player.getEntityId(), WrappedDataWatcher.getEntityWatcher(player), true)); @@ -168,19 +374,19 @@ public class DisguiseUtilities { Vector velocity = player.getVelocity(); manager.sendServerPacket( player, - manager.createPacketConstructor(Packets.Server.ENTITY_VELOCITY, player.getEntityId(), velocity.getX(), - velocity.getY(), velocity.getZ()).createPacket(player.getEntityId(), velocity.getX(), - velocity.getY(), velocity.getZ())); + manager.createPacketConstructor(PacketType.Play.Server.ENTITY_VELOCITY, player.getEntityId(), + velocity.getX(), velocity.getY(), velocity.getZ()).createPacket(player.getEntityId(), + velocity.getX(), velocity.getY(), velocity.getZ())); } // Why the hell would he even need this. Meh. if (player.getVehicle() != null && player.getEntityId() > player.getVehicle().getEntityId()) { manager.sendServerPacket(player, - manager.createPacketConstructor(Packets.Server.ATTACH_ENTITY, 0, player, player.getVehicle()) + manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player, player.getVehicle()) .createPacket(0, player, player.getVehicle())); } else if (player.getPassenger() != null && player.getEntityId() > player.getPassenger().getEntityId()) { manager.sendServerPacket(player, - manager.createPacketConstructor(Packets.Server.ATTACH_ENTITY, 0, player.getPassenger(), player) + manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player.getPassenger(), player) .createPacket(0, player.getPassenger(), player)); } @@ -194,9 +400,10 @@ public class DisguiseUtilities { } if (item != null && item.getType() != Material.AIR) { - manager.sendServerPacket(player, - manager.createPacketConstructor(Packets.Server.ENTITY_EQUIPMENT, player.getEntityId(), i, item) - .createPacket(player.getEntityId(), i, item)); + manager.sendServerPacket( + player, + manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EQUIPMENT, player.getEntityId(), i, + item).createPacket(player.getEntityId(), i, item)); } } Location loc = player.getLocation(); @@ -204,9 +411,8 @@ public class DisguiseUtilities { if (player.isSleeping()) { manager.sendServerPacket( player, - manager.createPacketConstructor(Packets.Server.ENTITY_LOCATION_ACTION, player, 0, loc.getBlockX(), - loc.getBlockY(), loc.getBlockZ()).createPacket(player, 0, loc.getBlockX(), loc.getBlockY(), - loc.getBlockZ())); + manager.createPacketConstructor(PacketType.Play.Server.BED, player, 0, loc.getBlockX(), loc.getBlockY(), + loc.getBlockZ()).createPacket(player, 0, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); } // Resend any active potion effects @@ -214,7 +420,7 @@ public class DisguiseUtilities { while (iterator.hasNext()) { PotionEffect potionEffect = (PotionEffect) iterator.next(); manager.sendServerPacket(player, - manager.createPacketConstructor(Packets.Server.MOB_EFFECT, player.getEntityId(), potionEffect) + manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EFFECT, player.getEntityId(), potionEffect) .createPacket(player.getEntityId(), potionEffect)); } } catch (Exception ex) { @@ -226,15 +432,23 @@ public class DisguiseUtilities { * Setup it so he can see himself when disguised */ public static void setupFakeDisguise(final Disguise disguise) { + Entity e = disguise.getEntity(); // If the disguises entity is null, or the disguised entity isn't a player return - if (disguise.getEntity() == null || !(disguise.getEntity() instanceof Player) || !disguises.containsValue(disguise)) + if (e == null || !(e instanceof Player) || !getDisguises().containsKey(e.getEntityId()) + || !getDisguises().get(e.getEntityId()).contains(disguise)) { return; - Player player = (Player) disguise.getEntity(); + } + Player player = (Player) e; + // Check if he can even see this.. + if (!((TargetedDisguise) disguise).canSee(player)) { + return; + } // Remove the old disguise, else we have weird disguises around the place DisguiseUtilities.removeSelfDisguise(player); // If the disguised player can't see himself. Return - if (!disguise.isSelfDisguiseVisible() || !PacketsManager.isViewDisguisesListenerEnabled() || player.getVehicle() != null) + if (!disguise.isSelfDisguiseVisible() || !PacketsManager.isViewDisguisesListenerEnabled() || player.getVehicle() != null) { return; + } try { // Grab the entity ID the fake disguise will use Field field = ReflectionManager.getNmsClass("Entity").getDeclaredField("entityCount"); diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseValues.java b/src/me/libraryaddict/disguise/utilities/DisguiseValues.java index 0a3cb7c4..c9cdbda2 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseValues.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseValues.java @@ -87,7 +87,8 @@ public class DisguiseValues { } return (int) Math.ceil(paramDouble * 32.0D); - case 6: + default: + break; } if (d > 0.0D) { return (int) Math.ceil(paramDouble * 32.0D); diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index ae8e4ebb..f2653097 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -33,10 +33,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; -import com.comphenix.protocol.Packets; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.ConnectionSide; import com.comphenix.protocol.events.ListenerPriority; import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; @@ -59,18 +58,21 @@ public class PacketsManager { public static void addPacketListeners(JavaPlugin libsDisguises) { ProtocolManager manager = ProtocolLibrary.getProtocolManager(); - manager.addPacketListener(new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.HIGH, - 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_EQUIPMENT, Packets.Server.BED, Packets.Server.ENTITY_STATUS) { + manager.addPacketListener(new PacketAdapter(libsDisguises, ListenerPriority.HIGH, + PacketType.Play.Server.NAMED_ENTITY_SPAWN, PacketType.Play.Server.ENTITY_METADATA, + PacketType.Play.Server.ANIMATION, PacketType.Play.Server.ENTITY_MOVE_LOOK, PacketType.Play.Server.ENTITY_LOOK, + PacketType.Play.Server.ENTITY_TELEPORT, PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB, + PacketType.Play.Server.SPAWN_ENTITY, PacketType.Play.Server.SPAWN_ENTITY_LIVING, + PacketType.Play.Server.SPAWN_ENTITY_PAINTING, PacketType.Play.Server.COLLECT, + PacketType.Play.Server.UPDATE_ATTRIBUTES, PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.BED, + PacketType.Play.Server.ENTITY_STATUS) { @Override public void onPacketSending(PacketEvent event) { final Player observer = event.getPlayer(); // First get the entity, the one sending this packet StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); - org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == event.getPacketID() ? 1 : 0)); + org.bukkit.entity.Entity entity = entityModifer.read((PacketType.Play.Server.COLLECT == event.getPacketType() ? 1 + : 0)); // If the entity is the same as the sender. Don't disguise! // Prevents problems and there is no advantage to be gained. if (entity == observer) @@ -103,16 +105,14 @@ 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. // Because it kicks you for hacking. - manager.addPacketListener(new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.NORMAL, - Packets.Client.USE_ENTITY) { + manager.addPacketListener(new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) { @Override public void onPacketReceiving(PacketEvent event) { try { Player observer = event.getPlayer(); StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); - org.bukkit.entity.Entity entity = entityModifer.read(1); - if (DisguiseAPI.isDisguised(entity) - && (entity instanceof ExperienceOrb || entity instanceof Item || entity instanceof Arrow)) { + org.bukkit.entity.Entity entity = entityModifer.read(ReflectionManager.isAfter17() ? 0 : 1); + if (entity instanceof ExperienceOrb || entity instanceof Item || entity instanceof Arrow) { event.setCancelled(true); } } catch (Exception e) { @@ -146,7 +146,7 @@ public class PacketsManager { } } if (item == null || item.getType() == Material.AIR) { - PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_EQUIPMENT); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT); StructureModifier mods = packet.getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, nmsSlot); @@ -164,7 +164,7 @@ public class PacketsManager { if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { - spawnPackets[0] = new PacketContainer(Packets.Server.ADD_EXP_ORB); + spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); StructureModifier mods = spawnPackets[0].getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, (int) Math.floor(loc.getX() * 32)); @@ -173,7 +173,7 @@ public class PacketsManager { mods.write(4, 1); } else if (disguise.getType() == DisguiseType.PAINTING) { - spawnPackets[0] = new PacketContainer(Packets.Server.ENTITY_PAINTING); + spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); StructureModifier mods = spawnPackets[0].getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, loc.getBlockX()); @@ -184,7 +184,7 @@ public class PacketsManager { mods.write(5, ReflectionManager.getEnumArt(Art.values()[id])); // Make the teleport packet to make it visible.. - spawnPackets[1] = new PacketContainer(Packets.Server.ENTITY_TELEPORT); + spawnPackets[1] = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); mods = spawnPackets[1].getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, (int) Math.floor(loc.getX() * 32D)); @@ -195,10 +195,14 @@ public class PacketsManager { } else if (disguise.getType().isPlayer()) { - spawnPackets[0] = new PacketContainer(Packets.Server.NAMED_ENTITY_SPAWN); + spawnPackets[0] = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN); StructureModifier stringMods = spawnPackets[0].getStrings(); - for (int i = 0; i < stringMods.size(); i++) { - stringMods.write(i, ((PlayerDisguise) disguise).getName()); + if (stringMods.size() > 0) { + for (int i = 0; i < stringMods.size(); i++) { + stringMods.write(i, ((PlayerDisguise) disguise).getName()); + } + } else { + spawnPackets[0].getModifier().write(1, ReflectionManager.getGameProfile(((PlayerDisguise) disguise).getName())); } StructureModifier intMods = spawnPackets[0].getIntegers(); intMods.write(0, disguisedEntity.getEntityId()); @@ -222,7 +226,7 @@ public class PacketsManager { DisguiseValues values = DisguiseValues.getDisguiseValues(disguise.getType()); Vector vec = disguisedEntity.getVelocity(); - spawnPackets[0] = new PacketContainer(Packets.Server.MOB_SPAWN); + spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING); StructureModifier mods = spawnPackets[0].getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, (int) disguise.getType().getEntityType().getTypeId()); @@ -274,12 +278,13 @@ public class PacketsManager { data = -data; }*/ spawnPackets[0] = ProtocolLibrary.getProtocolManager() - .createPacketConstructor(Packets.Server.VEHICLE_SPAWN, nmsEntity, id, data).createPacket(nmsEntity, id, data); + .createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, nmsEntity, id, data) + .createPacket(nmsEntity, id, data); spawnPackets[0].getModifier().write(2, (int) Math.floor(loc.getY() * 32D)); spawnPackets[0].getModifier().write(8, yaw); // Make the teleport packet to make it visible.. - spawnPackets[1] = new PacketContainer(Packets.Server.ENTITY_TELEPORT); + spawnPackets[1] = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); StructureModifier mods = spawnPackets[1].getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, (int) Math.floor(loc.getX() * 32D)); @@ -291,7 +296,7 @@ public class PacketsManager { } if (spawnPackets[1] == null) { // Make a packet to turn his head! - spawnPackets[1] = new PacketContainer(Packets.Server.ENTITY_HEAD_ROTATION); + spawnPackets[1] = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION); StructureModifier mods = spawnPackets[1].getModifier(); mods.write(0, disguisedEntity.getEntityId()); mods.write(1, yaw); @@ -453,23 +458,25 @@ public class PacketsManager { */ public 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) { + soundsListener = new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, PacketType.Play.Server.NAMED_SOUND_EFFECT, + PacketType.Play.Server.ENTITY_STATUS) { @Override public void onPacketSending(PacketEvent event) { if (event.isCancelled()) return; StructureModifier mods = event.getPacket().getModifier(); Player observer = event.getPlayer(); - if (event.getPacketID() == Packets.Server.NAMED_SOUND_EFFECT) { + if (event.getPacketType() == PacketType.Play.Server.NAMED_SOUND_EFFECT) { String soundName = (String) mods.read(0); SoundType soundType = null; Location soundLoc = new Location(observer.getWorld(), ((Integer) mods.read(1)) / 8D, ((Integer) mods.read(2)) / 8D, ((Integer) mods.read(3)) / 8D); Entity disguisedEntity = null; DisguiseSound entitySound = null; + Disguise disguise = null; for (Entity entity : soundLoc.getChunk().getEntities()) { - if (DisguiseAPI.isDisguised(entity)) { + Disguise entityDisguise = DisguiseAPI.getDisguise(observer, entity); + if (entityDisguise != null) { Location loc = entity.getLocation(); loc = new Location(observer.getWorld(), ((int) (loc.getX() * 8)) / 8D, ((int) (loc.getY() * 8)) / 8D, ((int) (loc.getZ() * 8)) / 8D); @@ -507,6 +514,7 @@ public class PacketsManager { soundType = entitySound.getType(soundName, !hasInvun); } if (soundType != null) { + disguise = entityDisguise; disguisedEntity = entity; break; } @@ -514,7 +522,6 @@ public class PacketsManager { } } } - Disguise disguise = DisguiseAPI.getDisguise(disguisedEntity); if (disguise != null) { if (disguise.isSelfDisguiseSoundsReplaced() || disguisedEntity != event.getPlayer()) { if (disguise.isSoundsReplaced()) { @@ -530,7 +537,14 @@ public class PacketsManager { int typeId = soundLoc.getWorld().getBlockTypeIdAt(soundLoc.getBlockX(), soundLoc.getBlockY() - 1, soundLoc.getBlockZ()); Class blockClass = ReflectionManager.getNmsClass("Block"); - Object block = ((Object[]) blockClass.getField("byId").get(null))[typeId]; + Object block; + if (ReflectionManager.isAfter17()) { + block = ReflectionManager.getNmsClass("RegistryMaterials") + .getMethod("a", int.class) + .invoke(blockClass.getField("REGISTRY").get(null), typeId); + } else { + block = ((Object[]) blockClass.getField("byId").get(null))[typeId]; + } if (block != null) { Object step = blockClass.getField("stepSound").get(block); mods.write(0, step.getClass().getMethod("getStepSound").invoke(step)); @@ -596,11 +610,11 @@ public class PacketsManager { } } } - } else if (event.getPacketID() == Packets.Server.ENTITY_STATUS) { - if ((Byte) mods.read(1) == 1) { + } else if (event.getPacketType() == PacketType.Play.Server.ENTITY_STATUS) { + if ((Byte) mods.read(1) == (ReflectionManager.isAfter17() ? 2 : 1)) { // It made a damage animation Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0); - Disguise disguise = DisguiseAPI.getDisguise(entity); + Disguise disguise = DisguiseAPI.getDisguise(observer, entity); if (disguise != null && (disguise.isSelfDisguiseSoundsReplaced() || entity != event.getPlayer())) { DisguiseSound disSound = DisguiseSound.getType(entity.getType().name()); if (disSound == null) @@ -634,7 +648,7 @@ public class PacketsManager { String sound = disSound.getSound(soundType); if (sound != null) { Location loc = entity.getLocation(); - PacketContainer packet = new PacketContainer(Packets.Server.NAMED_SOUND_EFFECT); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.NAMED_SOUND_EFFECT); mods = packet.getModifier(); mods.write(0, sound); mods.write(1, (int) (loc.getX() * 8D)); @@ -667,12 +681,14 @@ public class PacketsManager { } } }; - viewDisguisesListener = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.HIGH, - Packets.Server.NAMED_ENTITY_SPAWN, Packets.Server.ATTACH_ENTITY, Packets.Server.REL_ENTITY_MOVE, - Packets.Server.REL_ENTITY_MOVE_LOOK, Packets.Server.ENTITY_LOOK, Packets.Server.ENTITY_TELEPORT, - Packets.Server.ENTITY_HEAD_ROTATION, Packets.Server.ENTITY_METADATA, Packets.Server.ENTITY_EQUIPMENT, - Packets.Server.ARM_ANIMATION, Packets.Server.ENTITY_LOCATION_ACTION, Packets.Server.MOB_EFFECT, - Packets.Server.ENTITY_VELOCITY, Packets.Server.UPDATE_ATTRIBUTES) { + viewDisguisesListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGH, + PacketType.Play.Server.NAMED_ENTITY_SPAWN, PacketType.Play.Server.ATTACH_ENTITY, + PacketType.Play.Server.REL_ENTITY_MOVE, PacketType.Play.Server.ENTITY_MOVE_LOOK, + PacketType.Play.Server.ENTITY_LOOK, PacketType.Play.Server.ENTITY_TELEPORT, + PacketType.Play.Server.ENTITY_HEAD_ROTATION, PacketType.Play.Server.ENTITY_METADATA, + PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.ANIMATION, PacketType.Play.Server.BED, + PacketType.Play.Server.ENTITY_EFFECT, PacketType.Play.Server.ENTITY_VELOCITY, + PacketType.Play.Server.UPDATE_ATTRIBUTES, PacketType.Play.Server.ENTITY_STATUS) { @Override public void onPacketSending(PacketEvent event) { final Player observer = event.getPlayer(); @@ -711,8 +727,7 @@ public class PacketsManager { }); } - switch (event.getPacketID()) { - case Packets.Server.ENTITY_METADATA: + if (event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) { event.setPacket(event.getPacket().deepClone()); Iterator itel = event.getPacket().getWatchableCollectionModifier().read(0) .iterator(); @@ -726,9 +741,8 @@ public class PacketsManager { watch.setValue(a); } } - break; - case Packets.Server.NAMED_ENTITY_SPAWN: - PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_METADATA); + } else if (event.getPacketType() == PacketType.Play.Server.NAMED_ENTITY_SPAWN) { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); StructureModifier mods = packet.getModifier(); mods.write(0, observer.getEntityId()); List watchableList = new ArrayList(); @@ -738,50 +752,46 @@ public class PacketsManager { watchableList.add(new WrappedWatchableObject(0, b)); packet.getWatchableCollectionModifier().write(0, watchableList); event.setPacket(packet); - break; - case Packets.Server.ATTACH_ENTITY: - case Packets.Server.REL_ENTITY_MOVE: - case Packets.Server.REL_ENTITY_MOVE_LOOK: - case Packets.Server.ENTITY_LOOK: - case Packets.Server.ENTITY_TELEPORT: - case Packets.Server.ENTITY_HEAD_ROTATION: - case Packets.Server.MOB_EFFECT: - case Packets.Server.ENTITY_EQUIPMENT: + } else if (event.getPacketType() == PacketType.Play.Server.ATTACH_ENTITY + || event.getPacketType() == PacketType.Play.Server.REL_ENTITY_MOVE + || event.getPacketType() == PacketType.Play.Server.ENTITY_MOVE_LOOK + || event.getPacketType() == PacketType.Play.Server.ENTITY_LOOK + || event.getPacketType() == PacketType.Play.Server.ENTITY_TELEPORT + || event.getPacketType() == PacketType.Play.Server.ENTITY_HEAD_ROTATION + || event.getPacketType() == PacketType.Play.Server.ENTITY_EFFECT + || event.getPacketType() == PacketType.Play.Server.ENTITY_EQUIPMENT) { event.setCancelled(true); - break; + } - /* case Packets.Server.ENTITY_STATUS: - if (DisguiseAPI.getDisguise(entity).canHearSelfDisguise() - && (Byte) event.getPacket().getModifier().read(1) == 1) { - event.setCancelled(true); - } - break;*/ - default: - break; + else if (event.getPacketType() == PacketType.Play.Server.ENTITY_STATUS) { + if (DisguiseAPI.getDisguise(event.getPlayer(), event.getPlayer()).isSelfDisguiseSoundsReplaced() + && (Byte) event.getPacket().getModifier().read(1) == (ReflectionManager.isAfter17() ? 2 : 1)) { + event.setCancelled(true); + } } } } } }; // TODO Potentionally combine both listeners. - inventoryListenerServer = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.HIGHEST, - Packets.Server.SET_SLOT, Packets.Server.WINDOW_ITEMS) { + inventoryListenerServer = new PacketAdapter(libsDisguises, ListenerPriority.HIGHEST, PacketType.Play.Server.SET_SLOT, + PacketType.Play.Server.WINDOW_ITEMS) { @Override public void onPacketSending(PacketEvent event) { // If the inventory is the players inventory - if (event.getPlayer().getVehicle() == null && event.getPacket().getIntegers().read(0) == 0) { - Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer()); + if (event.getPlayer().isOnline() && event.getPlayer().getVehicle() == null + && event.getPacket().getIntegers().read(0) == 0) { + Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer(), event.getPlayer()); // If the player is disguised, views self disguises and is hiding a item. if (disguise != null && disguise.isSelfDisguiseVisible() && (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 /** * Done */ - case Packets.Server.SET_SLOT: { + if (event.getPacketType() == PacketType.Play.Server.SET_SLOT) { // The raw slot // nms code has the start of the hotbar being 36. int slot = event.getPacket().getIntegers().read(1); @@ -813,12 +823,7 @@ public class PacketsManager { } } } - break; - } - /** - * Done - */ - case Packets.Server.WINDOW_ITEMS: { + } else if (event.getPacketType() == PacketType.Play.Server.WINDOW_ITEMS) { event.setPacket(event.getPacket().deepClone()); StructureModifier mods = event.getPacket().getItemArrayModifier(); ItemStack[] items = mods.read(0); @@ -847,34 +852,30 @@ public class PacketsManager { } } mods.write(0, items); - break; - } - default: - break; } } } } }; - inventoryListenerClient = new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.HIGHEST, - Packets.Client.BLOCK_ITEM_SWITCH, Packets.Client.SET_CREATIVE_SLOT, Packets.Client.WINDOW_CLICK) { + inventoryListenerClient = new PacketAdapter(libsDisguises, ListenerPriority.HIGHEST, + PacketType.Play.Client.HELD_ITEM_SLOT, PacketType.Play.Client.SET_CREATIVE_SLOT, + PacketType.Play.Client.WINDOW_CLICK) { @Override public void onPacketReceiving(final PacketEvent event) { if (event.getPlayer().getVehicle() == null) { - Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer()); + Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer(), event.getPlayer()); // If player is disguised, views self disguises and has a inventory modifier if (disguise != null && disguise.isSelfDisguiseVisible() && (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { - switch (event.getPacketID()) { // If they are in creative and clicked on a slot - case Packets.Client.SET_CREATIVE_SLOT: { + if (event.getPacketType() == PacketType.Play.Client.SET_CREATIVE_SLOT) { int slot = event.getPacket().getIntegers().read(0); if (slot >= 5 && slot <= 8) { if (disguise.isHidingArmorFromSelf()) { int armorSlot = Math.abs((slot - 5) - 3); 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); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT); StructureModifier mods = packet.getModifier(); mods.write(0, 0); mods.write(1, slot); @@ -893,7 +894,7 @@ public class PacketsManager { 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); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT); StructureModifier mods = packet.getModifier(); mods.write(0, 0); mods.write(1, slot); @@ -908,10 +909,9 @@ public class PacketsManager { } } } - break; } // If the player switched item, aka he moved from slot 1 to slot 2 - case Packets.Client.BLOCK_ITEM_SWITCH: { + else if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_SLOT) { 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 @@ -920,7 +920,7 @@ public class PacketsManager { 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); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT); StructureModifier mods = packet.getModifier(); mods.write(0, 0); mods.write(1, event.getPlayer().getInventory().getHeldItemSlot() + 36); @@ -935,7 +935,7 @@ public class PacketsManager { .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); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT); StructureModifier mods = packet.getModifier(); mods.write(0, 0); mods.write(1, event.getPacket().getIntegers().read(0) + 36); @@ -947,10 +947,7 @@ public class PacketsManager { } } } - break; - } - - case Packets.Client.WINDOW_CLICK: { + } else if (event.getPacketType() == PacketType.Play.Client.WINDOW_CLICK) { int slot = event.getPacket().getIntegers().read(1); org.bukkit.inventory.ItemStack clickedItem; if (event.getPacket().getIntegers().read(3) == 1) { @@ -978,7 +975,7 @@ public class PacketsManager { // If the slot is a armor slot if (slot >= 5 && slot <= 8) { if (disguise.isHidingArmorFromSelf()) { - PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT); StructureModifier mods = packet.getModifier(); mods.write(0, 0); mods.write(1, slot); @@ -996,7 +993,7 @@ public class PacketsManager { 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); + PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT); StructureModifier mods = packet.getModifier(); mods.write(0, 0); mods.write(1, slot); @@ -1011,11 +1008,6 @@ public class PacketsManager { } } } - break; - } - - default: - break; } } } @@ -1057,7 +1049,7 @@ public class PacketsManager { ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListenerServer); } for (Player player : Bukkit.getOnlinePlayers()) { - Disguise disguise = DisguiseAPI.getDisguise(player); + Disguise disguise = DisguiseAPI.getDisguise(player, player); if (disguise != null) { if (viewDisguisesListenerEnabled && disguise.isSelfDisguiseVisible() && (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { @@ -1077,7 +1069,7 @@ public class PacketsManager { ProtocolLibrary.getProtocolManager().removePacketListener(viewDisguisesListener); } for (Player player : Bukkit.getOnlinePlayers()) { - Disguise disguise = DisguiseAPI.getDisguise(player); + Disguise disguise = DisguiseAPI.getDisguise(player, player); if (disguise != null) { if (disguise.isSelfDisguiseVisible()) { if (enabled) { @@ -1102,74 +1094,55 @@ public class PacketsManager { 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); + org.bukkit.entity.Entity entity = entityModifer + .read((PacketType.Play.Server.COLLECT == sentPacket.getType() ? 1 : 0)); + Disguise disguise = DisguiseAPI.getDisguise(observer, entity); // If disguised. if (disguise != null) { - // If packet is Packets.Server.UPDATE_ATTRIBUTES + // If packet is PacketType.Play.Server.UPDATE_ATTRIBUTES // This packet sends attributes - - switch (sentPacket.getID()) { - - case Packets.Server.UPDATE_ATTRIBUTES: - - { - + if (sentPacket.getType() == PacketType.Play.Server.UPDATE_ATTRIBUTES) { packets = new PacketContainer[0]; - break; } // Else if the packet is sending entity metadata - case Packets.Server.ENTITY_METADATA: - - { + else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_METADATA) { List watchableObjects = disguise.getWatcher().convert( packets[0].getWatchableCollectionModifier().read(0)); - packets[0] = new PacketContainer(sentPacket.getID()); + packets[0] = new PacketContainer(sentPacket.getType()); StructureModifier newMods = packets[0].getModifier(); newMods.write(0, entity.getEntityId()); packets[0].getWatchableCollectionModifier().write(0, 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: - - { + else if (sentPacket.getType() == PacketType.Play.Server.NAMED_ENTITY_SPAWN + || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_LIVING + || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB + || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY + || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_PAINTING) { packets = constructSpawnPackets(disguise, entity); - break; } // Else if the disguise is attempting to send players a forbidden packet - case Packets.Server.ARM_ANIMATION: - - { + else if (sentPacket.getType() == PacketType.Play.Server.ANIMATION) { if (disguise.getType().isMisc() || (packets[0].getIntegers().read(1) == 3 && !disguise.getType().isPlayer())) { packets = new PacketContainer[0]; } - break; - } - case Packets.Server.COLLECT: - - { - if (disguise.getType().isMisc()) + else if (sentPacket.getType() == PacketType.Play.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: - { - if (sentPacket.getID() == Packets.Server.ENTITY_LOOK && disguise.getType() == DisguiseType.WITHER_SKULL) { + // Else if the disguise is moving. + else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_MOVE_LOOK + || sentPacket.getType() == PacketType.Play.Server.ENTITY_LOOK + || sentPacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT) { + if (sentPacket.getType() == PacketType.Play.Server.ENTITY_LOOK + && disguise.getType() == DisguiseType.WITHER_SKULL) { packets = new PacketContainer[0]; } else { packets[0] = sentPacket.shallowClone(); @@ -1178,7 +1151,7 @@ public class PacketsManager { mods.write(4, getYaw(disguise.getType(), entity.getType(), yawValue)); byte pitchValue = (Byte) mods.read(5); mods.write(5, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue)); - if (sentPacket.getID() == Packets.Server.ENTITY_TELEPORT) { + if (sentPacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT) { double y = getYModifier(entity, disguise.getType()); if (y != 0) { y *= 32; @@ -1186,12 +1159,9 @@ public class PacketsManager { } } } - break; } - case Packets.Server.ENTITY_EQUIPMENT: - - { + else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_EQUIPMENT) { int slot = (Integer) packets[0].getModifier().read(1) - 1; if (slot < 0) slot = 4; @@ -1201,29 +1171,19 @@ public class PacketsManager { packets[0].getModifier().write(2, (itemstack.getTypeId() == 0 ? null : ReflectionManager.getNmsItem(itemstack))); } - break; } - case Packets.Server.ENTITY_LOCATION_ACTION: - - { + else if (sentPacket.getType() == PacketType.Play.Server.BED) { if (!disguise.getType().isPlayer()) { packets = new PacketContainer[0]; } - break; } - case Packets.Server.ENTITY_STATUS: - - { + else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_STATUS) { if (packets[0].getBytes().read(0) == (byte) 3) { packets = new PacketContainer[0]; } } - - default: - break; - } } } catch (Exception e) { e.printStackTrace(); diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java index 8892e00e..c3a6a0f9 100644 --- a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java @@ -12,6 +12,7 @@ import org.bukkit.entity.Entity; import org.bukkit.inventory.ItemStack; public class ReflectionManager { + private static boolean after17 = true; private static String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3]; private static Class itemClass; private static Method soundMethod; @@ -43,6 +44,15 @@ public class ReflectionManager { } catch (Exception e) { e.printStackTrace(); } + if (bukkitVersion.startsWith("v1_")) { + try { + if (Integer.parseInt(bukkitVersion.split("_")[1]) < 7) { + after17 = false; + } + } catch (Exception ex) { + + } + } } public static Object createEntityInstance(String entityName) { @@ -54,9 +64,16 @@ public class ReflectionManager { Object minecraftServer = getNmsClass("MinecraftServer").getMethod("getServer").invoke(null); Object playerinteractmanager = getNmsClass("PlayerInteractManager").getConstructor(getNmsClass("World")) .newInstance(world); - entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("World"), String.class, - playerinteractmanager.getClass()).newInstance(minecraftServer, world, "LibsDisguises", - playerinteractmanager); + if (isAfter17()) { + Object gameProfile = getGameProfile("LibsDisguises"); + entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"), + gameProfile.getClass(), playerinteractmanager.getClass()).newInstance(minecraftServer, world, + gameProfile, playerinteractmanager); + } else { + entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("World"), String.class, + playerinteractmanager.getClass()).newInstance(minecraftServer, world, "LibsDisguises", + playerinteractmanager); + } } else { entityObject = entityClass.getConstructor(getNmsClass("World")).newInstance(world); } @@ -120,6 +137,16 @@ public class ReflectionManager { return null; } + public static Object getGameProfile(String playerName) { + try { + return Class.forName("net.minecraft.util.com.mojang.authlib.GameProfile").getConstructor(String.class, String.class) + .newInstance(playerName, playerName); + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + public static Class getNmsClass(String className) { try { return Class.forName("net.minecraft.server." + bukkitVersion + "." + className); @@ -165,4 +192,8 @@ public class ReflectionManager { return null; } + public static boolean isAfter17() { + return after17; + } + }