diff --git a/config.yml b/config.yml index 863bd1ca..3219c0cc 100644 --- a/config.yml +++ b/config.yml @@ -61,6 +61,34 @@ BlownDisguiseMessage: '&cYour disguise was blown!' # These disguises, as normal will not persist after a server restart. # There is also no EntityDeath option as entities do not revive after death. KeepDisguises: + EntityDespawn: false PlayerDeath: false PlayerLogout: false - EntityDespawn: false \ No newline at end of file + +# This here is a option to turn off misc disguises. +# This means you can not have a living entity disguise as a non-living entity. +# This disables the Attributes packet, Non-living entities can still disguise as other non-living +MiscDisguisesForLiving: true + +# This will help performance, especially with CPU +# Due to safety reasons, self disguises can never have their packets disabled. +PacketsEnabled: + # This disables the animation packet. If a disguised entity sends a animation packet and they are using a non-living disguise. People will crash. + # Disabling this also means that if a player disguised as a non-player leaves a bug. People will crash + Animation: true + # Disabling this means that you can't use the setSleeping option on a player disguise. Also you will crash anyone watching when you try to sleep in a bed + Bed: true + # This disguises the collect packet. If a living entity disguised as a non-living entity picks up a item. People will crash. This fixes it + # This also fixes people crashing if a item disguised as a sleeping player is picked up - Only true if Bed is enabled as well + Collect: true + # This disables a fix for when a disguised entity wearing armor dies, if the disguise can wear armor. It drops unpickupable items to anyone watching. + EntityStatus: true + # Entity enquipment is the packets that are sent to ensure that a disguise has or doesn't have armor, and their held item. + # Disabling this means that any disguises which can wear armor or hold items will show the armor/held item that the disguised is wearing. + Enquipment: true + # Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up + Movement: true + # Disable this if you don't mind crashing everytime you see someone riding something disguised as a non-living entity + Riding: true + # When disguised as a wither skull, it sends a look packet every tick so that the wither skull is facing the right way. + WitherSkull: true diff --git a/pom.xml b/pom.xml index 7a84d561..9428bd21 100644 --- a/pom.xml +++ b/pom.xml @@ -3,6 +3,8 @@ 4.0.0 LibsDisguises LibsDisguises + 8.2.0-SNAPSHOT + src clean package @@ -84,7 +86,6 @@ 3.1.0 - 8.2.0-SNAPSHOT diff --git a/src/me/libraryaddict/disguise/DisguiseConfig.java b/src/me/libraryaddict/disguise/DisguiseConfig.java index 7f07306b..aa84deea 100644 --- a/src/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/me/libraryaddict/disguise/DisguiseConfig.java @@ -3,34 +3,63 @@ package me.libraryaddict.disguise; import me.libraryaddict.disguise.utilities.PacketsManager; public class DisguiseConfig { + private static boolean animationEnabled; + private static boolean bedEnabled; private static boolean blowDisguisesOnAttack; + private static boolean collectEnabled; private static String disguiseBlownMessage; + private static boolean enquipmentEnabled; private static boolean entityAnimationsAdded; + private static boolean entityStatusEnabled; private static boolean hearSelfDisguise; private static boolean hidingArmor; private static boolean hidingHeldItem; private static boolean keepDisguiseEntityDespawn; private static boolean keepDisguisePlayerDeath; private static boolean keepDisguisePlayerLogout; + private static boolean miscDisguisesForLivingEnabled; private static boolean modifyBoundingBox; + private static boolean movementEnabled; private static boolean removeUnseenDisguises; + private static boolean ridingEnabled; private static boolean sendVelocity; private static boolean showNameAboveHead; private static boolean showNameAboveHeadAlwaysVisible; private static boolean targetDisguises; + private static boolean witherSkullEnabled; public static String getDisguiseBlownMessage() { return disguiseBlownMessage; } + public static boolean isAnimationPacketsEnabled() { + return animationEnabled; + } + + public static boolean isBedPacketsEnabled() { + return bedEnabled; + } + + public static boolean isCollectPacketsEnabled() { + return collectEnabled; + } + public static boolean isDisguiseBlownOnAttack() { return blowDisguisesOnAttack; } + public static boolean isEnquipmentPacketsEnabled() { + return enquipmentEnabled; + } + public static boolean isEntityAnimationsAdded() { return entityAnimationsAdded; } + public static boolean isEntityStatusPacketsEnabled() { + return entityStatusEnabled; + } + /** * Is the plugin modifying the inventory packets so that players when self disguised, do not see their armor floating around */ @@ -57,6 +86,10 @@ public class DisguiseConfig { return keepDisguisePlayerLogout; } + public static boolean isMiscDisguisesForLivingEnabled() { + return miscDisguisesForLivingEnabled; + } + public static boolean isModifyBoundingBox() { return modifyBoundingBox; } @@ -65,6 +98,10 @@ public class DisguiseConfig { return targetDisguises; } + public static boolean isMovementPacketsEnabled() { + return movementEnabled; + } + public static boolean isNameAboveHeadAlwaysVisible() { return showNameAboveHeadAlwaysVisible; } @@ -73,6 +110,10 @@ public class DisguiseConfig { return showNameAboveHead; } + public static boolean isRidingPacketsEnabled() { + return ridingEnabled; + } + public static boolean isSelfDisguisesSoundsReplaced() { return hearSelfDisguise; } @@ -102,10 +143,35 @@ public class DisguiseConfig { return PacketsManager.isViewDisguisesListenerEnabled(); } + public static boolean isWitherSkullPacketsEnabled() { + return witherSkullEnabled; + } + public static void setAddEntityAnimations(boolean isEntityAnimationsAdded) { entityAnimationsAdded = isEntityAnimationsAdded; } + public static void setAnimationPacketsEnabled(boolean enabled) { + if (enabled != isAnimationPacketsEnabled()) { + animationEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + + public static void setBedPacketsEnabled(boolean enabled) { + if (enabled != isBedPacketsEnabled()) { + bedEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + + public static void setCollectPacketsEnabled(boolean enabled) { + if (enabled != isCollectPacketsEnabled()) { + collectEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + public static void setDisguiseBlownMessage(String newMessage) { disguiseBlownMessage = newMessage; } @@ -114,6 +180,20 @@ public class DisguiseConfig { blowDisguisesOnAttack = blowDisguise; } + public static void setEnquipmentPacketsEnabled(boolean enabled) { + if (enabled != isEnquipmentPacketsEnabled()) { + enquipmentEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + + public static void setEntityStatusPacketsEnabled(boolean enabled) { + if (enabled != isEntityStatusPacketsEnabled()) { + entityStatusEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + /** * Can players hear their own disguises */ @@ -155,6 +235,13 @@ public class DisguiseConfig { keepDisguisePlayerLogout = keepDisguise; } + public static void setMiscDisguisesForLivingEnabled(boolean enabled) { + if (enabled != isMiscDisguisesForLivingEnabled()) { + miscDisguisesForLivingEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + public static void setModifyBoundingBox(boolean modifyBounding) { modifyBoundingBox = modifyBounding; } @@ -163,6 +250,13 @@ public class DisguiseConfig { targetDisguises = ignore; } + public static void setMovementPacketsEnabled(boolean enabled) { + if (enabled != isMovementPacketsEnabled()) { + movementEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) { showNameAboveHeadAlwaysVisible = alwaysVisible; } @@ -171,6 +265,13 @@ public class DisguiseConfig { showNameAboveHead = showNames; } + public static void setRidingPacketsEnabled(boolean enabled) { + if (enabled != isRidingPacketsEnabled()) { + ridingEnabled = enabled; + PacketsManager.setupMainPacketsListener(); + } + } + /** * Set if the disguises play sounds when hurt */ @@ -193,6 +294,10 @@ public class DisguiseConfig { PacketsManager.setViewDisguisesListener(seeOwnDisguise); } + public static void setWitherSkullPacketsEnabled(boolean enabled) { + witherSkullEnabled = enabled; + } + private DisguiseConfig() { } diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index 359a837a..1a34e41c 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -23,6 +23,7 @@ import me.libraryaddict.disguise.utilities.DisguiseValues; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Ageable; @@ -46,14 +47,16 @@ public class LibsDisguises extends JavaPlugin { stream = getClassLoader().getResource("config.yml").openStream(); YamlConfiguration internalConfig = YamlConfiguration.loadConfiguration(stream); for (String option : internalConfig.getKeys(false)) { - if (!config.contains(option)) { - if (internalConfig.isConfigurationSection(option)) { - for (String secondOption : internalConfig.getConfigurationSection(option).getKeys(false)) { - config.set(option, getConfig().get(option + "." + secondOption)); + if (internalConfig.isConfigurationSection(option)) { + ConfigurationSection section = internalConfig.getConfigurationSection(option); + for (String secondOption : section.getKeys(false)) { + if (!config.contains(secondOption)) { + config.set(option + "." + secondOption, section.get(secondOption)); + needToSaveConfig = true; } - } else { - config.set(option, getConfig().get(option)); } + } else if (!config.contains(option)) { + config.set(option, getConfig().get(option)); needToSaveConfig = true; } } @@ -94,6 +97,15 @@ public class LibsDisguises extends JavaPlugin { DisguiseConfig.setKeepDisguiseOnPlayerDeath(getConfig().getBoolean("KeepDisguises.PlayerDeath")); DisguiseConfig.setKeepDisguiseOnPlayerLogout(getConfig().getBoolean("KeepDisguises.PlayerLogout")); DisguiseConfig.setKeepDisguiseOnEntityDespawn(getConfig().getBoolean("KeepDisguises.EntityDespawn")); + DisguiseConfig.setMiscDisguisesForLivingEnabled(getConfig().getBoolean("MiscDisguisesForLiving")); + DisguiseConfig.setMovementPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Movement")); + DisguiseConfig.setWitherSkullPacketsEnabled(getConfig().getBoolean("PacketsEnabled.WitherSkull")); + DisguiseConfig.setEnquipmentPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Enquipment")); + DisguiseConfig.setAnimationPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Animation")); + DisguiseConfig.setBedPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Bed")); + DisguiseConfig.setRidingPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Riding")); + DisguiseConfig.setEntityStatusPacketsEnabled(getConfig().getBoolean("PacketsEnabled.EntityStatus")); + DisguiseConfig.setCollectPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Collect")); 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. @@ -103,7 +115,7 @@ public class LibsDisguises extends JavaPlugin { } catch (Exception ex) { ex.printStackTrace(); } - PacketsManager.addPacketListeners(this); + PacketsManager.addPacketListeners(); DisguiseListener listener = new DisguiseListener(this); Bukkit.getPluginManager().registerEvents(listener, this); getCommand("disguise").setExecutor(new DisguiseCommand()); diff --git a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java index 0d7d8d53..b06907e6 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -21,6 +21,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Horse.Variant; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; @@ -227,7 +228,7 @@ public abstract class Disguise { // If disguise isn't a experience orb, or the entity isn't standing on the ground if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) { PacketContainer lookPacket = null; - if (getType() == DisguiseType.WITHER_SKULL) { + if (getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) { lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK); StructureModifier mods = lookPacket.getModifier(); mods.write(0, getEntity().getEntityId()); @@ -454,6 +455,10 @@ public abstract class Disguise { return; throw new RuntimeException("This disguise is already in use! Try .clone()"); } + if (this.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) { + throw new RuntimeException( + "Cannot disguise a living entity with a misc disguise. Renable MiscDisguisesForLiving in the config to do this"); + } this.entity = entity; setupWatcher(); taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, velocityRunnable, 1, 1); diff --git a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java index 4978f666..cd23bd37 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java @@ -102,11 +102,6 @@ public class MiscDisguise extends TargetedDisguise { this(entityType, -1, -1); } - @Deprecated - public MiscDisguise(EntityType entityType, int id) { - this(entityType, id, -1); - } - @Deprecated public MiscDisguise(EntityType entityType, boolean replaceSounds) { this(entityType, replaceSounds, -1, -1); @@ -117,6 +112,11 @@ public class MiscDisguise extends TargetedDisguise { this(DisguiseType.getType(entityType), replaceSounds, id, data); } + @Deprecated + public MiscDisguise(EntityType entityType, int id) { + this(entityType, id, -1); + } + @Deprecated public MiscDisguise(EntityType disguiseType, int id, int data) { this(DisguiseType.getType(disguiseType), id, data); diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java index 9db8a8bc..038024d8 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java @@ -8,6 +8,7 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; @@ -44,7 +45,7 @@ public class PlayerWatcher extends LivingWatcher { public void setSleeping(boolean sleep) { if (sleep != isSleeping()) { isInBed = sleep; - if (DisguiseUtilities.isDisguiseInUse(getDisguise())) { + if (DisguiseConfig.isBedPacketsEnabled() && DisguiseUtilities.isDisguiseInUse(getDisguise())) { PacketContainer packet; if (isSleeping()) { packet = new PacketContainer(PacketType.Play.Server.BED); diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 98328700..94df0fe6 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -43,6 +43,10 @@ public class DisguiseUtilities { * the plugin to do that. */ private static HashSet addedByPlugins = new HashSet(); + /** + * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use + **/ + private static HashMap> disguisesInUse = new HashMap>(); /** * Disguises which are stored ready for a entity to be seen by a player Preferably, disguises in this should only stay in for * a max of a second. @@ -58,10 +62,6 @@ public class DisguiseUtilities { * seeing as no one sees each others entity ID **/ private static HashMap selfDisguisesIds = new HashMap(); - /** - * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use - **/ - private static HashMap> disguisesInUse = new HashMap>(); public static void addDisguise(UUID entityId, TargetedDisguise disguise) { if (!getDisguises().containsKey(entityId)) { diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index 4c6582fb..e9872069 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Random; import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; @@ -32,12 +33,10 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Zombie; import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.ListenerPriority; import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; @@ -57,50 +56,18 @@ public class PacketsManager { private static PacketListener inventoryListenerServer; private static boolean inventoryModifierEnabled; private static LibsDisguises libsDisguises; + private static PacketListener mainListener; private static PacketListener soundsListener; + private static PacketListener useEntityListener; private static boolean soundsListenerEnabled; private static PacketListener viewDisguisesListener; private static boolean viewDisguisesListenerEnabled; - public static void addPacketListeners(JavaPlugin libsDisguises) { - ProtocolManager manager = ProtocolLibrary.getProtocolManager(); - 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_HEAD_ROTATION, 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, - PacketType.Play.Server.ATTACH_ENTITY) { - @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((PacketType.Play.Server.COLLECT == event.getPacketType() - || PacketType.Play.Server.ATTACH_ENTITY == 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) - return; - PacketContainer[] packets = transformPacket(event.getPacket(), event.getPlayer(), entity); - if (packets != null) { - event.setCancelled(true); - try { - for (PacketContainer packet : packets) { - ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); - } - } catch (InvocationTargetException ex) { - ex.printStackTrace(); - } - } - } - }); - // Now add a client listener to cancel them interacting with uninteractable disguised entitys. + public static void addPacketListeners() { + // 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, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) { + useEntityListener = new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) { @Override public void onPacketReceiving(PacketEvent event) { try { @@ -115,7 +82,10 @@ public class PacketsManager { e.printStackTrace(); } } - }); + }; + ProtocolLibrary.getProtocolManager().addPacketListener(useEntityListener); + // Now I call this and the main listener is registered! + setupMainPacketsListener(); } /** @@ -156,9 +126,12 @@ public class PacketsManager { spawnPackets[i + 2] = packets.get(i); } Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguise), 0); - byte yaw = getYaw(disguise.getType(), disguisedEntity.getType(), (byte) (int) (loc.getYaw() * 256.0F / 360.0F)); - byte pitch = getPitch(disguise.getType(), DisguiseType.getType(disguisedEntity.getType()), - (byte) (int) (loc.getPitch() * 256.0F / 360.0F)); + byte yaw = (byte) (int) (loc.getYaw() * 256.0F / 360.0F); + byte pitch = (byte) (int) (loc.getPitch() * 256.0F / 360.0F); + if (DisguiseConfig.isMovementPacketsEnabled()) { + yaw = getYaw(disguise.getType(), disguisedEntity.getType(), yaw); + pitch = getPitch(disguise.getType(), DisguiseType.getType(disguisedEntity.getType()), pitch); + } if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { @@ -230,7 +203,7 @@ public class PacketsManager { spawnPackets[0].getDataWatcherModifier().write(0, createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); - if (((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + if (((PlayerWatcher) disguise.getWatcher()).isSleeping() && DisguiseConfig.isBedPacketsEnabled()) { spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED); StructureModifier mods = spawnPackets[1].getIntegers(); mods.write(0, disguisedEntity.getEntityId()); @@ -463,7 +436,7 @@ public class PacketsManager { case WITHER_SKULL: return 0.7; case PLAYER: - if (((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { return 0.35; } break; @@ -1078,6 +1051,85 @@ public class PacketsManager { } } + public static void setupMainPacketsListener() { + if (useEntityListener != null) { + if (mainListener != null) { + ProtocolLibrary.getProtocolManager().removePacketListener(mainListener); + } + List packetsToListen = new ArrayList(); + // Add spawn packets + { + packetsToListen.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN); + packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); + packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY); + packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); + } + // Add packets that always need to be enabled to ensure safety + { + packetsToListen.add(PacketType.Play.Server.ENTITY_METADATA); + } + if (DisguiseConfig.isRidingPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.ATTACH_ENTITY); + } + if (DisguiseConfig.isCollectPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.COLLECT); + } + if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) { + packetsToListen.add(PacketType.Play.Server.UPDATE_ATTRIBUTES); + } + // The bed packet. + if (DisguiseConfig.isBedPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.BED); + } + // Add movement packets + if (DisguiseConfig.isMovementPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.ENTITY_LOOK); + packetsToListen.add(PacketType.Play.Server.ENTITY_MOVE_LOOK); + packetsToListen.add(PacketType.Play.Server.ENTITY_HEAD_ROTATION); + packetsToListen.add(PacketType.Play.Server.ENTITY_TELEPORT); + } + // Add enquipment packet + if (DisguiseConfig.isEnquipmentPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.ENTITY_EQUIPMENT); + } + // Add the packet that ensures if they are sleeping or not + if (DisguiseConfig.isAnimationPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.ANIMATION); + } + // Add the packet that makes sure that entities with armor do not send unpickupable armor on death + if (DisguiseConfig.isEntityStatusPacketsEnabled()) { + packetsToListen.add(PacketType.Play.Server.ENTITY_STATUS); + } + mainListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGH, packetsToListen) { + @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((PacketType.Play.Server.COLLECT == event.getPacketType() + || PacketType.Play.Server.ATTACH_ENTITY == 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) + return; + PacketContainer[] packets = transformPacket(event.getPacket(), event.getPlayer(), entity); + if (packets != null) { + event.setCancelled(true); + try { + for (PacketContainer packet : packets) { + ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); + } + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } + } + } + }; + ProtocolLibrary.getProtocolManager().addPacketListener(mainListener); + } + } + public static void setViewDisguisesListener(boolean enabled) { if (viewDisguisesListenerEnabled != enabled) { viewDisguisesListenerEnabled = enabled; @@ -1151,7 +1203,8 @@ public class PacketsManager { else if (sentPacket.getType() == PacketType.Play.Server.ANIMATION) { if (disguise.getType().isMisc() || (packets[0].getIntegers().read(1) == (LibVersion.is1_7() ? 2 : 3) && (!disguise.getType() - .isPlayer() || ((PlayerWatcher) disguise.getWatcher()).isSleeping()))) { + .isPlayer() || (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise + .getWatcher()).isSleeping())))) { packets = new PacketContainer[0]; } } @@ -1159,7 +1212,8 @@ public class PacketsManager { else if (sentPacket.getType() == PacketType.Play.Server.COLLECT) { if (disguise.getType().isMisc()) { packets = new PacketContainer[0]; - } else if (disguise.getType().isPlayer() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + } else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer() + && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ANIMATION); StructureModifier mods = newPacket.getIntegers(); mods.write(0, disguise.getEntity().getEntityId());