From 80b40852044c89e2e5333dbbfd06ca784898035f Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Wed, 30 Nov 2016 17:08:12 +1300 Subject: [PATCH] Now able to hide disguised players from tab, show player disguises tab --- config.yml | 6 + .../disguise/DisguiseConfig.java | 270 +++++------- .../disguise/DisguiseListener.java | 383 ++++++++---------- .../libraryaddict/disguise/LibsDisguises.java | 8 +- .../disguise/disguisetypes/Disguise.java | 214 +++++++--- .../disguisetypes/PlayerDisguise.java | 215 +++++----- .../disguisetypes/TargetedDisguise.java | 119 ++++-- .../disguisetypes/watchers/PlayerWatcher.java | 149 +++---- .../disguise/utilities/DisguiseUtilities.java | 2 - .../disguise/utilities/PacketsManager.java | 14 +- .../utilities/ReflectionFlagWatchers.java | 2 +- .../PacketListenerTabList.java | 65 +++ 12 files changed, 759 insertions(+), 688 deletions(-) create mode 100644 src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java diff --git a/config.yml b/config.yml index 8006c8d1..e5010d1e 100644 --- a/config.yml +++ b/config.yml @@ -98,6 +98,12 @@ UndisguiseOnWorldChange: false # Contact Mojang's servers? Disabling this option will disable player skin disguises! ContactMojangServers: true +# Hide players in tab when disguised? This means a disguised player cannot be seen when you press tab! This can be toggled on/off per disguise +HideDisguisedPlayersTab: false + +# Always show player disguises in tab? The names will continue to appear in tab until the disguise is removed. +ShowPlayerDisguisesTab: false + # This will help performance, especially with CPU # Due to safety reasons, self disguises can never have their packets disabled. PacketsEnabled: diff --git a/src/me/libraryaddict/disguise/DisguiseConfig.java b/src/me/libraryaddict/disguise/DisguiseConfig.java index 70b3a2bd..c8721dd8 100644 --- a/src/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/me/libraryaddict/disguise/DisguiseConfig.java @@ -5,8 +5,7 @@ import org.bukkit.configuration.ConfigurationSection; import me.libraryaddict.disguise.utilities.PacketsManager; -public class DisguiseConfig -{ +public class DisguiseConfig { private static boolean animationEnabled; private static boolean bedEnabled; @@ -44,40 +43,50 @@ public class DisguiseConfig + ", the new version is " + ChatColor.RED + "%s" + ChatColor.DARK_RED + "!"; private static String updateNotificationPermission; private static boolean witherSkullEnabled; + private static boolean hideDisguisedPlayers; + private static boolean displayPlayerDisguisesInTab; - public static String getDisguiseBlownMessage() - { + public static void setHideDisguisedPlayers(boolean hideDisguisedPlayersInTab) { + hideDisguisedPlayers = hideDisguisedPlayersInTab; + } + + public static void setShowDisguisedPlayersInTab(boolean displayPlayerDisguisesInTablist) { + displayPlayerDisguisesInTab = displayPlayerDisguisesInTablist; + } + + public static boolean isHideDisguisedPlayers() { + return hideDisguisedPlayers; + } + + public static boolean isShowDisguisedPlayersInTab() { + return displayPlayerDisguisesInTab; + } + + public static String getDisguiseBlownMessage() { return disguiseBlownMessage; } - public static int getDisguiseCloneExpire() - { + public static int getDisguiseCloneExpire() { return disguiseCloneExpire; } - public static int getDisguiseEntityExpire() - { + public static int getDisguiseEntityExpire() { return disguiseEntityExpire; } - public static int getMaxClonedDisguises() - { + public static int getMaxClonedDisguises() { return maxClonedDisguises; } - public static String getUpdateMessage() - { + public static String getUpdateMessage() { return updateMessage; } - public static String getUpdateNotificationPermission() - { + public static String getUpdateNotificationPermission() { return updateNotificationPermission; } - public static void initConfig(ConfigurationSection config) - { - + public static void initConfig(ConfigurationSection config) { setSoundsEnabled(config.getBoolean("DisguiseSounds")); setVelocitySent(config.getBoolean("SendVelocity")); setViewDisguises(config.getBoolean("ViewSelfDisguises")); // Since we can now toggle, the view disguises listener must @@ -114,134 +123,112 @@ public class DisguiseConfig setUndisguiseOnWorldChange(config.getBoolean("UndisguiseOnWorldChange")); setUpdateNotificationPermission(config.getString("Permission")); setStopShulkerDisguisesFromMoving(config.getBoolean("StopShulkerDisguisesFromMoving", true)); + setHideDisguisedPlayers(config.getBoolean("HideDisguisedPlayersFromTab")); + setShowDisguisedPlayersInTab(config.getBoolean("ShowPlayerDisguisesInTab")); } - public static boolean isAnimationPacketsEnabled() - { + public static boolean isAnimationPacketsEnabled() { return animationEnabled; } - public static boolean isBedPacketsEnabled() - { + public static boolean isBedPacketsEnabled() { return bedEnabled; } - public static boolean isCollectPacketsEnabled() - { + public static boolean isCollectPacketsEnabled() { return collectEnabled; } - public static boolean isDisguiseBlownOnAttack() - { + public static boolean isDisguiseBlownOnAttack() { return blowDisguisesOnAttack; } - public static boolean isEntityAnimationsAdded() - { + public static boolean isEntityAnimationsAdded() { return entityAnimationsAdded; } - public static boolean isEntityStatusPacketsEnabled() - { + public static boolean isEntityStatusPacketsEnabled() { return entityStatusEnabled; } - public static boolean isEquipmentPacketsEnabled() - { + public static boolean isEquipmentPacketsEnabled() { return equipmentEnabled; } /** * Is the plugin modifying the inventory packets so that players when self disguised, do not see their armor floating around */ - public static boolean isHidingArmorFromSelf() - { + public static boolean isHidingArmorFromSelf() { return hidingArmor; } /** * Does the plugin appear to remove the item they are holding, to prevent a floating sword when they are viewing self disguise */ - public static boolean isHidingHeldItemFromSelf() - { + public static boolean isHidingHeldItemFromSelf() { return hidingHeldItem; } - public static boolean isKeepDisguiseOnEntityDespawn() - { + public static boolean isKeepDisguiseOnEntityDespawn() { return keepDisguiseEntityDespawn; } - public static boolean isKeepDisguiseOnPlayerDeath() - { + public static boolean isKeepDisguiseOnPlayerDeath() { return keepDisguisePlayerDeath; } - public static boolean isKeepDisguiseOnPlayerLogout() - { + public static boolean isKeepDisguiseOnPlayerLogout() { return keepDisguisePlayerLogout; } - public static boolean isMaxHealthDeterminedByDisguisedEntity() - { + public static boolean isMaxHealthDeterminedByDisguisedEntity() { return maxHealthIsDisguisedEntity; } - public static boolean isMetadataPacketsEnabled() - { + public static boolean isMetadataPacketsEnabled() { return sendsEntityMetadata; } - public static boolean isMiscDisguisesForLivingEnabled() - { + public static boolean isMiscDisguisesForLivingEnabled() { return miscDisguisesForLivingEnabled; } - public static boolean isModifyBoundingBox() - { + public static boolean isModifyBoundingBox() { return modifyBoundingBox; } - public static boolean isMonstersIgnoreDisguises() - { + public static boolean isMonstersIgnoreDisguises() { return targetDisguises; } - public static boolean isMovementPacketsEnabled() - { + public static boolean isMovementPacketsEnabled() { return movementEnabled; } - public static boolean isNameAboveHeadAlwaysVisible() - { + public static boolean isNameAboveHeadAlwaysVisible() { return showNameAboveHeadAlwaysVisible; } - public static boolean isNameOfPlayerShownAboveDisguise() - { + public static boolean isNameOfPlayerShownAboveDisguise() { return showNameAboveHead; } - public static boolean isSelfDisguisesSoundsReplaced() - { + public static boolean isSelfDisguisesSoundsReplaced() { return hearSelfDisguise; } - public static boolean isSheepDyeable() - { + public static boolean isSheepDyeable() { return colorizeSheep; } /** * Is the sound packets caught and modified */ - public static boolean isSoundEnabled() - { + public static boolean isSoundEnabled() { return PacketsManager.isHearDisguisesEnabled(); } - public static boolean isUndisguiseOnWorldChange() - { + public static boolean isUndisguiseOnWorldChange() { return undisguiseSwitchWorlds; } @@ -250,8 +237,7 @@ public class DisguiseConfig * * @return */ - public static boolean isVelocitySent() - { + public static boolean isVelocitySent() { return sendVelocity; } @@ -260,90 +246,72 @@ public class DisguiseConfig * * @return */ - public static boolean isViewDisguises() - { + public static boolean isViewDisguises() { return viewSelfDisguise; } - public static boolean isWitherSkullPacketsEnabled() - { + public static boolean isWitherSkullPacketsEnabled() { return witherSkullEnabled; } - public static boolean isWolfDyeable() - { + public static boolean isWolfDyeable() { return colorizeWolf; } - public static void setAddEntityAnimations(boolean isEntityAnimationsAdded) - { + public static void setAddEntityAnimations(boolean isEntityAnimationsAdded) { entityAnimationsAdded = isEntityAnimationsAdded; } - public static void setAnimationPacketsEnabled(boolean enabled) - { - if (enabled != isAnimationPacketsEnabled()) - { + public static void setAnimationPacketsEnabled(boolean enabled) { + if (enabled != isAnimationPacketsEnabled()) { animationEnabled = enabled; PacketsManager.setupMainPacketsListener(); } } - public static void setBedPacketsEnabled(boolean enabled) - { - if (enabled != isBedPacketsEnabled()) - { + public static void setBedPacketsEnabled(boolean enabled) { + if (enabled != isBedPacketsEnabled()) { bedEnabled = enabled; PacketsManager.setupMainPacketsListener(); } } - public static void setCollectPacketsEnabled(boolean enabled) - { - if (enabled != isCollectPacketsEnabled()) - { + public static void setCollectPacketsEnabled(boolean enabled) { + if (enabled != isCollectPacketsEnabled()) { collectEnabled = enabled; PacketsManager.setupMainPacketsListener(); } } - public static void setDisguiseBlownMessage(String newMessage) - { + public static void setDisguiseBlownMessage(String newMessage) { disguiseBlownMessage = newMessage; } - public static void setDisguiseBlownOnAttack(boolean blowDisguise) - { + public static void setDisguiseBlownOnAttack(boolean blowDisguise) { blowDisguisesOnAttack = blowDisguise; } - public static void setDisguiseCloneExpire(int newExpires) - { + public static void setDisguiseCloneExpire(int newExpires) { disguiseCloneExpire = newExpires; } - public static void setDisguiseEntityExpire(int newExpires) - { + public static void setDisguiseEntityExpire(int newExpires) { disguiseEntityExpire = newExpires; } - public static void setEntityStatusPacketsEnabled(boolean enabled) - { - if (enabled != isEntityStatusPacketsEnabled()) - { + public static void setEntityStatusPacketsEnabled(boolean enabled) { + if (enabled != isEntityStatusPacketsEnabled()) { entityStatusEnabled = enabled; PacketsManager.setupMainPacketsListener(); } } - public static void setEquipmentPacketsEnabled(boolean enabled) - { - if (enabled != isEquipmentPacketsEnabled()) - { + public static void setEquipmentPacketsEnabled(boolean enabled) { + if (enabled != isEquipmentPacketsEnabled()) { equipmentEnabled = enabled; PacketsManager.setupMainPacketsListener(); @@ -353,10 +321,8 @@ public class DisguiseConfig /** * Can players hear their own disguises */ - public static void setHearSelfDisguise(boolean replaceSound) - { - if (hearSelfDisguise != replaceSound) - { + public static void setHearSelfDisguise(boolean replaceSound) { + if (hearSelfDisguise != replaceSound) { hearSelfDisguise = replaceSound; } } @@ -364,10 +330,8 @@ public class DisguiseConfig /** * Set the plugin to hide self disguises armor from theirselves */ - public static void setHideArmorFromSelf(boolean hideArmor) - { - if (hidingArmor != hideArmor) - { + public static void setHideArmorFromSelf(boolean hideArmor) { + if (hidingArmor != hideArmor) { hidingArmor = hideArmor; PacketsManager.setInventoryListenerEnabled(isHidingHeldItemFromSelf() || isHidingArmorFromSelf()); @@ -377,121 +341,98 @@ public class DisguiseConfig /** * Does the plugin appear to remove the item they are holding, to prevent a floating sword when they are viewing self disguise */ - public static void setHideHeldItemFromSelf(boolean hideHelditem) - { - if (hidingHeldItem != hideHelditem) - { + public static void setHideHeldItemFromSelf(boolean hideHelditem) { + if (hidingHeldItem != hideHelditem) { hidingHeldItem = hideHelditem; PacketsManager.setInventoryListenerEnabled(isHidingHeldItemFromSelf() || isHidingArmorFromSelf()); } } - public static void setKeepDisguiseOnEntityDespawn(boolean keepDisguise) - { + public static void setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { keepDisguiseEntityDespawn = keepDisguise; } - public static void setKeepDisguiseOnPlayerDeath(boolean keepDisguise) - { + public static void setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { keepDisguisePlayerDeath = keepDisguise; } - public static void setKeepDisguiseOnPlayerLogout(boolean keepDisguise) - { + public static void setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { keepDisguisePlayerLogout = keepDisguise; } - public static void setMaxClonedDisguises(int newMax) - { + public static void setMaxClonedDisguises(int newMax) { maxClonedDisguises = newMax; } - public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) - { + public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) { maxHealthIsDisguisedEntity = isDetermined; } - public static void setMetadataPacketsEnabled(boolean enabled) - { + public static void setMetadataPacketsEnabled(boolean enabled) { sendsEntityMetadata = enabled; } - public static void setMiscDisguisesForLivingEnabled(boolean enabled) - { - if (enabled != isMiscDisguisesForLivingEnabled()) - { + public static void setMiscDisguisesForLivingEnabled(boolean enabled) { + if (enabled != isMiscDisguisesForLivingEnabled()) { miscDisguisesForLivingEnabled = enabled; PacketsManager.setupMainPacketsListener(); } } - public static void setModifyBoundingBox(boolean modifyBounding) - { + public static void setModifyBoundingBox(boolean modifyBounding) { modifyBoundingBox = modifyBounding; } - public static void setMonstersIgnoreDisguises(boolean ignore) - { + public static void setMonstersIgnoreDisguises(boolean ignore) { targetDisguises = ignore; } - public static void setMovementPacketsEnabled(boolean enabled) - { - if (enabled != isMovementPacketsEnabled()) - { + public static void setMovementPacketsEnabled(boolean enabled) { + if (enabled != isMovementPacketsEnabled()) { movementEnabled = enabled; PacketsManager.setupMainPacketsListener(); } } - public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) - { + public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) { showNameAboveHeadAlwaysVisible = alwaysVisible; } - public static void setNameOfPlayerShownAboveDisguise(boolean showNames) - { + public static void setNameOfPlayerShownAboveDisguise(boolean showNames) { showNameAboveHead = showNames; } - public static void setSheepDyeable(boolean color) - { + public static void setSheepDyeable(boolean color) { colorizeSheep = color; } /** * Set if the disguises play sounds when hurt */ - public static void setSoundsEnabled(boolean isSoundsEnabled) - { + public static void setSoundsEnabled(boolean isSoundsEnabled) { PacketsManager.setHearDisguisesListener(isSoundsEnabled); } - public static void setUndisguiseOnWorldChange(boolean isUndisguise) - { + public static void setUndisguiseOnWorldChange(boolean isUndisguise) { undisguiseSwitchWorlds = isUndisguise; } - public static void setUpdateMessage(String newMessage) - { + public static void setUpdateMessage(String newMessage) { updateMessage = newMessage; } - public static void setUpdateNotificationPermission(String newPermission) - { + public static void setUpdateNotificationPermission(String newPermission) { updateNotificationPermission = newPermission; } - public static void setStopShulkerDisguisesFromMoving(boolean stopShulkerDisguisesFromMoving) - { + public static void setStopShulkerDisguisesFromMoving(boolean stopShulkerDisguisesFromMoving) { DisguiseConfig.stopShulkerDisguisesFromMoving = stopShulkerDisguisesFromMoving; } - public static boolean isStopShulkerDisguisesFromMoving() - { + public static boolean isStopShulkerDisguisesFromMoving() { return stopShulkerDisguisesFromMoving; } @@ -500,27 +441,22 @@ public class DisguiseConfig * * @param sendVelocityPackets */ - public static void setVelocitySent(boolean sendVelocityPackets) - { + public static void setVelocitySent(boolean sendVelocityPackets) { sendVelocity = sendVelocityPackets; } - public static void setViewDisguises(boolean seeOwnDisguise) - { + public static void setViewDisguises(boolean seeOwnDisguise) { viewSelfDisguise = seeOwnDisguise; } - public static void setWitherSkullPacketsEnabled(boolean enabled) - { + public static void setWitherSkullPacketsEnabled(boolean enabled) { witherSkullEnabled = enabled; } - public static void setWolfDyeable(boolean color) - { + public static void setWolfDyeable(boolean color) { colorizeWolf = color; } - private DisguiseConfig() - { + private DisguiseConfig() { } } diff --git a/src/me/libraryaddict/disguise/DisguiseListener.java b/src/me/libraryaddict/disguise/DisguiseListener.java index 92b63c38..c77a0a65 100644 --- a/src/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/me/libraryaddict/disguise/DisguiseListener.java @@ -1,6 +1,7 @@ package me.libraryaddict.disguise; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -27,8 +28,13 @@ import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; +import com.comphenix.protocol.wrappers.PlayerInfoData; +import com.comphenix.protocol.wrappers.WrappedChatComponent; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; @@ -39,8 +45,7 @@ import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.ReflectionManager; import me.libraryaddict.disguise.utilities.UpdateChecker; -public class DisguiseListener implements Listener -{ +public class DisguiseListener implements Listener { private String currentVersion; private HashMap disguiseClone = new HashMap<>(); @@ -50,42 +55,32 @@ public class DisguiseListener implements Listener private LibsDisguises plugin; private BukkitTask updaterTask; - public DisguiseListener(LibsDisguises libsDisguises) - { + public DisguiseListener(LibsDisguises libsDisguises) { plugin = libsDisguises; - if (plugin.getConfig().getBoolean("NotifyUpdate")) - { + if (plugin.getConfig().getBoolean("NotifyUpdate")) { currentVersion = plugin.getDescription().getVersion(); - updaterTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() - { + updaterTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() { @Override - public void run() - { - try - { + public void run() { + try { UpdateChecker updateChecker = new UpdateChecker(); updateChecker.checkUpdate("v" + currentVersion); latestVersion = updateChecker.getLatestVersion(); - if (latestVersion == null) - { + if (latestVersion == null) { return; } latestVersion = "v" + latestVersion; - Bukkit.getScheduler().runTask(plugin, new Runnable() - { + Bukkit.getScheduler().runTask(plugin, new Runnable() { @Override - public void run() - { - for (Player p : Bukkit.getOnlinePlayers()) - { - if (!p.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) - { + public void run() { + for (Player p : Bukkit.getOnlinePlayers()) { + if (!p.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) { continue; } @@ -95,8 +90,7 @@ public class DisguiseListener implements Listener } }); } - catch (Exception ex) - { + catch (Exception ex) { System.out.print(String.format("[LibsDisguises] Failed to check for update: %s", ex.getMessage())); } } @@ -105,15 +99,12 @@ public class DisguiseListener implements Listener } } - public void cleanup() - { - for (BukkitRunnable r : disguiseRunnable.values()) - { + public void cleanup() { + for (BukkitRunnable r : disguiseRunnable.values()) { r.cancel(); } - for (Disguise d : disguiseEntity.values()) - { + for (Disguise d : disguiseEntity.values()) { d.removeDisguise(); } @@ -121,37 +112,28 @@ public class DisguiseListener implements Listener updaterTask.cancel(); } - private void checkPlayerCanBlowDisguise(Player entity) - { + private void checkPlayerCanBlowDisguise(Player entity) { Disguise[] disguises = DisguiseAPI.getDisguises(entity); - if (disguises.length > 0) - { + if (disguises.length > 0) { DisguiseAPI.undisguiseToAll(entity); - if (DisguiseConfig.getDisguiseBlownMessage().length() > 0) - { + if (DisguiseConfig.getDisguiseBlownMessage().length() > 0) { entity.sendMessage(DisguiseConfig.getDisguiseBlownMessage()); } } } - private void chunkMove(Player player, Location newLoc, Location oldLoc) - { - try - { + private void chunkMove(Player player, Location newLoc, Location oldLoc) { + try { // Resend the bed chunks - for (PacketContainer packet : DisguiseUtilities.getBedChunkPacket(newLoc, oldLoc)) - { + for (PacketContainer packet : DisguiseUtilities.getBedChunkPacket(newLoc, oldLoc)) { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); } - if (newLoc != null) - { - for (HashSet list : DisguiseUtilities.getDisguises().values()) - { - for (TargetedDisguise disguise : list) - { + if (newLoc != null) { + for (HashSet list : DisguiseUtilities.getDisguises().values()) { + for (TargetedDisguise disguise : list) { if (disguise.getEntity() == null) continue; @@ -171,87 +153,120 @@ public class DisguiseListener implements Listener disguise.getEntity() == player ? newLoc : disguise.getEntity().getLocation(), newLoc, (PlayerDisguise) disguise); - if (disguise.getEntity() == player) - { - for (PacketContainer packet : packets) - { + if (disguise.getEntity() == player) { + for (PacketContainer packet : packets) { packet.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); } } - for (PacketContainer packet : packets) - { + for (PacketContainer packet : packets) { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); } } } } } - catch (InvocationTargetException e) - { + catch (InvocationTargetException e) { e.printStackTrace(); } } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onAttack(EntityDamageByEntityEvent event) - { - if (DisguiseConfig.isDisguiseBlownOnAttack()) - { - if (event.getEntity() instanceof Player) - { + public void onAttack(EntityDamageByEntityEvent event) { + if (DisguiseConfig.isDisguiseBlownOnAttack()) { + if (event.getEntity() instanceof Player) { checkPlayerCanBlowDisguise((Player) event.getEntity()); } - if (event.getDamager() instanceof Player) - { + if (event.getDamager() instanceof Player) { checkPlayerCanBlowDisguise((Player) event.getDamager()); } } } @EventHandler - public void onJoin(PlayerJoinEvent event) - { + public void onJoin(PlayerJoinEvent event) { Player p = event.getPlayer(); - if (latestVersion != null && p.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) - { + if (latestVersion != null && p.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) { p.sendMessage(String.format(DisguiseConfig.getUpdateMessage(), currentVersion, latestVersion)); } - if (DisguiseConfig.isBedPacketsEnabled()) - { + if (DisguiseConfig.isBedPacketsEnabled()) { chunkMove(p, p.getLocation(), null); } + + for (HashSet disguiseList : DisguiseUtilities.getDisguises().values()) { + for (TargetedDisguise targetedDisguise : disguiseList) { + if (targetedDisguise.getEntity() == null) + continue; + + if (!targetedDisguise.canSee(p)) + continue; + + // Don't need this as we have a packet listener doing that for us + /*if (targetedDisguise.isPlayerHiddenInTab() && targetedDisguise.getEntity() instanceof Player) { + try { + PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + Player player = (Player) targetedDisguise.getEntity(); + + addTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); + addTab.getPlayerInfoDataLists() + .write(0, + Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile(player), 0, + NativeGameMode.SURVIVAL, + WrappedChatComponent.fromText(player.getDisplayName())))); + + ProtocolLibrary.getProtocolManager().sendServerPacket(p, addTab); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + }*/ + + if (!(targetedDisguise instanceof PlayerDisguise)) + continue; + + PlayerDisguise disguise = (PlayerDisguise) targetedDisguise; + + if (disguise.isDisplayedInTab()) { + try { + PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + + addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); + addTab.getPlayerInfoDataLists().write(0, Arrays.asList(new PlayerInfoData(disguise.getGameProfile(), 0, + NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(disguise.getGameProfile().getName())))); + + ProtocolLibrary.getProtocolManager().sendServerPacket(p, addTab); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } } /** * Most likely faster if we don't bother doing checks if he sees a player disguise */ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onMove(PlayerMoveEvent event) - { - if (DisguiseConfig.isBedPacketsEnabled()) - { + public void onMove(PlayerMoveEvent event) { + if (DisguiseConfig.isBedPacketsEnabled()) { Location to = event.getTo(); Location from = event.getFrom(); if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(from.getBlockX()) - || DisguiseUtilities.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) - { + || DisguiseUtilities.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) { chunkMove(event.getPlayer(), to, from); } } - if (DisguiseConfig.isStopShulkerDisguisesFromMoving()) - { + if (DisguiseConfig.isStopShulkerDisguisesFromMoving()) { Disguise disguise; - if ((disguise = DisguiseAPI.getDisguise(event.getPlayer())) != null) - { - if (disguise.getType() == DisguiseType.SHULKER) - { // Stop Shulker disguises from moving their coordinates + if ((disguise = DisguiseAPI.getDisguise(event.getPlayer())) != null) { + if (disguise.getType() == DisguiseType.SHULKER) { // Stop Shulker disguises from moving their coordinates Location from = event.getFrom(); Location to = event.getTo(); @@ -265,35 +280,28 @@ public class DisguiseListener implements Listener } @EventHandler - public void onQuit(PlayerQuitEvent event) - { + public void onQuit(PlayerQuitEvent event) { ReflectionManager.removePlayer(event.getPlayer()); } @EventHandler - public void onRespawn(PlayerRespawnEvent event) - { + public void onRespawn(PlayerRespawnEvent event) { Disguise[] disguises = DisguiseAPI.getDisguises(event.getPlayer()); - for (Disguise disguise : disguises) - { - if (disguise.isRemoveDisguiseOnDeath()) - { + for (Disguise disguise : disguises) { + if (disguise.isRemoveDisguiseOnDeath()) { disguise.removeDisguise(); } } - if (DisguiseConfig.isBedPacketsEnabled()) - { + if (DisguiseConfig.isBedPacketsEnabled()) { final Player player = event.getPlayer(); chunkMove(event.getPlayer(), null, player.getLocation()); - Bukkit.getScheduler().runTask(plugin, new Runnable() - { + Bukkit.getScheduler().runTask(plugin, new Runnable() { @Override - public void run() - { + public void run() { chunkMove(player, player.getLocation(), null); } }); @@ -301,10 +309,8 @@ public class DisguiseListener implements Listener } @EventHandler - public void onRightClick(PlayerInteractEntityEvent event) - { - if (disguiseEntity.containsKey(event.getPlayer().getName()) || disguiseClone.containsKey(event.getPlayer().getName())) - { + public void onRightClick(PlayerInteractEntityEvent event) { + if (disguiseEntity.containsKey(event.getPlayer().getName()) || disguiseClone.containsKey(event.getPlayer().getName())) { Player p = event.getPlayer(); event.setCancelled(true); @@ -313,27 +319,22 @@ public class DisguiseListener implements Listener Entity entity = event.getRightClicked(); String entityName; - if (entity instanceof Player && !disguiseClone.containsKey(p.getName())) - { + if (entity instanceof Player && !disguiseClone.containsKey(p.getName())) { entityName = entity.getName(); } - else - { + else { entityName = DisguiseType.getType(entity).toReadable(); } - if (disguiseClone.containsKey(p.getName())) - { + if (disguiseClone.containsKey(p.getName())) { Boolean[] options = disguiseClone.remove(p.getName()); Disguise disguise = DisguiseAPI.getDisguise(p, entity); - if (disguise == null) - { + if (disguise == null) { disguise = DisguiseAPI.constructDisguise(entity, options[0], options[1], options[2]); } - else - { + else { disguise = disguise.clone(); } @@ -343,54 +344,42 @@ public class DisguiseListener implements Listener int referenceLength = Math.max(2, (int) Math.ceil((0.1D + DisguiseConfig.getMaxClonedDisguises()) / 26D)); int attempts = 0; - while (reference == null && attempts++ < 1000) - { + while (reference == null && attempts++ < 1000) { reference = "@"; - for (int i = 0; i < referenceLength; i++) - { + for (int i = 0; i < referenceLength; i++) { reference += alphabet[DisguiseUtilities.random.nextInt(alphabet.length)]; } - if (DisguiseUtilities.getClonedDisguise(reference) != null) - { + if (DisguiseUtilities.getClonedDisguise(reference) != null) { reference = null; } } - if (reference != null && DisguiseUtilities.addClonedDisguise(reference, disguise)) - { + if (reference != null && DisguiseUtilities.addClonedDisguise(reference, disguise)) { p.sendMessage(ChatColor.RED + "Constructed a " + entityName + " disguise! Your reference is " + reference); p.sendMessage(ChatColor.RED + "Example usage: /disguise " + reference); } - else - { + else { p.sendMessage( ChatColor.RED + "Failed to store the reference due to lack of size. Please set this in the config"); } } - else if (disguiseEntity.containsKey(p.getName())) - { + else if (disguiseEntity.containsKey(p.getName())) { Disguise disguise = disguiseEntity.remove(p.getName()); - if (disguise != null) - { + if (disguise != null) { if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() - && entity instanceof LivingEntity) - { + && entity instanceof LivingEntity) { p.sendMessage(ChatColor.RED + "Can't disguise a living entity as a misc disguise. This has been disabled in the config!"); } - else - { - if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) - { - if (disguise.getWatcher() instanceof LivingWatcher) - { + else { + if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { disguise.getWatcher().setCustomName(((Player) entity).getDisplayName()); - if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) - { + if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { disguise.getWatcher().setCustomNameVisible(true); } } @@ -400,37 +389,30 @@ public class DisguiseListener implements Listener String disguiseName = "a "; - if (disguise instanceof PlayerDisguise) - { + if (disguise instanceof PlayerDisguise) { disguiseName = "the player " + ((PlayerDisguise) disguise).getName(); } - else - { + else { disguiseName += disguise.getType().toReadable(); } - if (disguise.isDisguiseInUse()) - { + if (disguise.isDisguiseInUse()) { p.sendMessage(ChatColor.RED + "Disguised " + (entity instanceof Player ? "" : "the ") + entityName + " as " + disguiseName + "!"); } - else - { + else { p.sendMessage(ChatColor.RED + "Failed to disguise " + (entity instanceof Player ? "" : "the ") + entityName + " as " + disguiseName + "!"); } } } - else - { - if (DisguiseAPI.isDisguised(entity)) - { + else { + if (DisguiseAPI.isDisguised(entity)) { DisguiseAPI.undisguiseToAll(entity); p.sendMessage(ChatColor.RED + "Undisguised " + (entity instanceof Player ? "" : "the ") + entityName); } - else - { + else { p.sendMessage(ChatColor.RED + (entity instanceof Player ? "" : "the") + entityName + " isn't disguised!"); } } @@ -439,13 +421,10 @@ public class DisguiseListener implements Listener } @EventHandler - public void onTarget(EntityTargetEvent event) - { + public void onTarget(EntityTargetEvent event) { if (DisguiseConfig.isMonstersIgnoreDisguises() && event.getTarget() != null && event.getTarget() instanceof Player - && DisguiseAPI.isDisguised(event.getTarget())) - { - switch (event.getReason()) - { + && DisguiseAPI.isDisguised(event.getTarget())) { + switch (event.getReason()) { case TARGET_ATTACKED_ENTITY: case TARGET_ATTACKED_OWNER: case OWNER_ATTACKED_TARGET: @@ -459,50 +438,40 @@ public class DisguiseListener implements Listener } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onTeleport(PlayerTeleportEvent event) - { + public void onTeleport(PlayerTeleportEvent event) { final Player player = event.getPlayer(); Location to = event.getTo(); Location from = event.getFrom(); - if (DisguiseConfig.isBedPacketsEnabled()) - { + if (DisguiseConfig.isBedPacketsEnabled()) { if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(from.getBlockX()) - || DisguiseUtilities.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) - { + || DisguiseUtilities.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) { chunkMove(player, null, from); - Bukkit.getScheduler().runTask(plugin, new Runnable() - { + Bukkit.getScheduler().runTask(plugin, new Runnable() { @Override - public void run() - { + public void run() { chunkMove(player, player.getLocation(), null); } }); } } - if (!DisguiseAPI.isDisguised(player)) - { + if (!DisguiseAPI.isDisguised(player)) { return; } if (DisguiseConfig.isUndisguiseOnWorldChange() && to.getWorld() != null && from.getWorld() != null - && to.getWorld() != from.getWorld()) - { - for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) - { + && to.getWorld() != from.getWorld()) { + for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { disguise.removeDisguise(); } } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onVehicleEnter(VehicleEnterEvent event) - { - if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) - { + public void onVehicleEnter(VehicleEnterEvent event) { + if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) { DisguiseUtilities.removeSelfDisguise((Player) event.getEntered()); ((Player) event.getEntered()).updateInventory(); @@ -510,19 +479,14 @@ public class DisguiseListener implements Listener } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onVehicleLeave(VehicleExitEvent event) - { - if (event.getExited() instanceof Player) - { + public void onVehicleLeave(VehicleExitEvent event) { + if (event.getExited() instanceof Player) { final Disguise disguise = DisguiseAPI.getDisguise((Player) event.getExited(), event.getExited()); - if (disguise != null) - { - Bukkit.getScheduler().runTask(plugin, new Runnable() - { + if (disguise != null) { + Bukkit.getScheduler().runTask(plugin, new Runnable() { @Override - public void run() - { + public void run() { DisguiseUtilities.setupFakeDisguise(disguise); ((Player) disguise.getEntity()).updateInventory(); @@ -533,41 +497,32 @@ public class DisguiseListener implements Listener } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onWorldSwitch(final PlayerChangedWorldEvent event) - { - if (DisguiseConfig.isBedPacketsEnabled()) - { + public void onWorldSwitch(final PlayerChangedWorldEvent event) { + if (DisguiseConfig.isBedPacketsEnabled()) { chunkMove(event.getPlayer(), event.getPlayer().getLocation(), null); } - if (!DisguiseAPI.isDisguised(event.getPlayer())) - { + if (!DisguiseAPI.isDisguised(event.getPlayer())) { return; } - if (DisguiseConfig.isUndisguiseOnWorldChange()) - { - for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) - { + if (DisguiseConfig.isUndisguiseOnWorldChange()) { + for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { disguise.removeDisguise(); } } - else - { + else { // Stupid hack to fix worldswitch invisibility bug final boolean viewSelfToggled = DisguiseAPI.isViewSelfToggled(event.getPlayer()); - if (viewSelfToggled) - { + if (viewSelfToggled) { final Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer()); disguise.setViewSelfDisguise(false); - Bukkit.getScheduler().runTaskLater(plugin, new Runnable() - { + Bukkit.getScheduler().runTaskLater(plugin, new Runnable() { @Override - public void run() - { + public void run() { disguise.setViewSelfDisguise(true); } }, 20L); // I wish I could use lambdas here, so badly @@ -575,20 +530,16 @@ public class DisguiseListener implements Listener } } - public void setDisguiseClone(final String player, Boolean[] options) - { - if (disguiseRunnable.containsKey(player)) - { + public void setDisguiseClone(final String player, Boolean[] options) { + if (disguiseRunnable.containsKey(player)) { BukkitRunnable run = disguiseRunnable.remove(player); run.cancel(); run.run(); } - BukkitRunnable runnable = new BukkitRunnable() - { + BukkitRunnable runnable = new BukkitRunnable() { @Override - public void run() - { + public void run() { disguiseClone.remove(player); disguiseRunnable.remove(player); } @@ -600,20 +551,16 @@ public class DisguiseListener implements Listener disguiseClone.put(player, options); } - public void setDisguiseEntity(final String player, Disguise disguise) - { - if (disguiseRunnable.containsKey(player)) - { + public void setDisguiseEntity(final String player, Disguise disguise) { + if (disguiseRunnable.containsKey(player)) { BukkitRunnable run = disguiseRunnable.remove(player); run.cancel(); run.run(); } - BukkitRunnable runnable = new BukkitRunnable() - { + BukkitRunnable runnable = new BukkitRunnable() { @Override - public void run() - { + public void run() { disguiseEntity.remove(player); disguiseRunnable.remove(player); } diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index ddf76e44..544768ae 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -23,12 +23,12 @@ import com.comphenix.protocol.wrappers.WrappedWatchableObject; import me.libraryaddict.disguise.commands.DisguiseCloneCommand; import me.libraryaddict.disguise.commands.DisguiseCommand; -import me.libraryaddict.disguise.commands.DisguiseHelpCommand; -import me.libraryaddict.disguise.commands.DisguiseViewSelfCommand; import me.libraryaddict.disguise.commands.DisguiseEntityCommand; -import me.libraryaddict.disguise.commands.LibsDisguisesCommand; +import me.libraryaddict.disguise.commands.DisguiseHelpCommand; import me.libraryaddict.disguise.commands.DisguisePlayerCommand; import me.libraryaddict.disguise.commands.DisguiseRadiusCommand; +import me.libraryaddict.disguise.commands.DisguiseViewSelfCommand; +import me.libraryaddict.disguise.commands.LibsDisguisesCommand; import me.libraryaddict.disguise.commands.UndisguiseCommand; import me.libraryaddict.disguise.commands.UndisguiseEntityCommand; import me.libraryaddict.disguise.commands.UndisguisePlayerCommand; @@ -73,7 +73,7 @@ public class LibsDisguises extends JavaPlugin { } try { - ReflectionManager.getNmsClass("EntityShulker").getName(); + ReflectionManager.getNmsClass("EntityEvoker").getName(); } catch (Exception ex) { System.err.println("[LibsDisguises] Lib's Disguises failed to startup, outdated server!"); diff --git a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java index dc33c557..0850e24d 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -2,6 +2,7 @@ package me.libraryaddict.disguise.disguisetypes; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -16,10 +17,15 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; import org.bukkit.util.Vector; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; +import com.comphenix.protocol.wrappers.PlayerInfoData; +import com.comphenix.protocol.wrappers.WrappedChatComponent; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseConfig; @@ -35,6 +41,17 @@ import me.libraryaddict.disguise.utilities.PacketsManager; import me.libraryaddict.disguise.utilities.ReflectionManager; public abstract class Disguise { + private static List viewSelf = new ArrayList<>(); + + /** + * Returns the list of people who have /disguiseViewSelf toggled on + * + * @return + */ + public static List getViewSelf() { + return viewSelf; + } + private boolean disguiseInUse; private DisguiseType disguiseType; private Entity entity; @@ -45,15 +62,14 @@ public abstract class Disguise { private boolean keepDisguisePlayerDeath = DisguiseConfig.isKeepDisguiseOnPlayerDeath(); private boolean keepDisguisePlayerLogout = DisguiseConfig.isKeepDisguiseOnPlayerLogout(); private boolean modifyBoundingBox = DisguiseConfig.isModifyBoundingBox(); + private boolean playerHiddenFromTab = DisguiseConfig.isHideDisguisedPlayers(); private boolean replaceSounds = DisguiseConfig.isSoundEnabled(); + private boolean showName; private BukkitTask task; private Runnable velocityRunnable; private boolean velocitySent = DisguiseConfig.isVelocitySent(); private boolean viewSelfDisguise = DisguiseConfig.isViewDisguises(); private FlagWatcher watcher; - private boolean showName = false; - - private static List viewSelf = new ArrayList<>(); @Override public abstract Disguise clone(); @@ -398,6 +414,13 @@ public abstract class Disguise { return disguiseInUse; } + /** + * Will a disguised player appear in tab + */ + public boolean isHidePlayer() { + return playerHiddenFromTab; + } + public boolean isHidingArmorFromSelf() { return hideArmorFromSelf; } @@ -456,14 +479,6 @@ public abstract class Disguise { return viewSelfDisguise; } - public boolean isSoundsReplaced() { - return replaceSounds; - } - - public boolean isVelocitySent() { - return velocitySent; - } - /** * Returns true if the entity's name is showing through the disguise * @@ -473,6 +488,14 @@ public abstract class Disguise { return showName; } + public boolean isSoundsReplaced() { + return replaceSounds; + } + + public boolean isVelocitySent() { + return velocitySent; + } + /** * Removes the disguise and undisguises the entity if its using this disguise. * @@ -496,6 +519,51 @@ public abstract class Disguise { // If this disguise has a entity set if (getEntity() != null) { + if (this instanceof PlayerDisguise) { + PlayerDisguise disguise = (PlayerDisguise) this; + + if (disguise.isDisplayedInTab()) { + PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); + deleteTab.getPlayerInfoDataLists().write(0, + Arrays.asList(new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL, + WrappedChatComponent.fromText(disguise.getName())))); + + try { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!((TargetedDisguise) this).canSee(player)) + continue; + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, deleteTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + + if (isHidePlayer() && getEntity() instanceof Player) { + PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); + deleteTab.getPlayerInfoDataLists().write(0, + Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, + NativeGameMode.SURVIVAL, + WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName())))); + + try { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!((TargetedDisguise) this).canSee(player)) + continue; + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, deleteTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + // If this disguise is active // Remove the disguise from the current disguises. if (DisguiseUtilities.removeDisguise((TargetedDisguise) this)) { @@ -546,6 +614,7 @@ public abstract class Disguise { return true; } } + return false; } @@ -556,7 +625,7 @@ public abstract class Disguise { * @return disguise */ public Disguise setEntity(Entity entity) { - if (this.getEntity() != null) { + if (getEntity() != null) { if (getEntity() == entity) { return this; } @@ -576,12 +645,6 @@ public abstract class Disguise { return this; } - public Disguise setShowName(boolean showName) { - this.showName = showName; - - return this; - } - public Disguise setHearSelfDisguise(boolean hearSelfDisguise) { this.hearSelfDisguise = hearSelfDisguise; @@ -608,6 +671,13 @@ public abstract class Disguise { return this; } + public void setHidePlayer(boolean hidePlayerInTab) { + if (isDisguiseInUse()) + throw new IllegalStateException("Cannot set this while disguise is in use!"); // Cos I'm lazy + + playerHiddenFromTab = hidePlayerInTab; + } + public Disguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { this.keepDisguiseEntityDespawn = keepDisguise; @@ -649,6 +719,12 @@ public abstract class Disguise { return this; } + public Disguise setShowName(boolean showName) { + this.showName = showName; + + return this; + } + /** * Sets up the FlagWatcher with the entityclass, it creates all the data it needs to prevent conflicts when sending the * datawatcher. @@ -733,44 +809,82 @@ public abstract class Disguise { // If they cancelled this disguise event. No idea why. // Just return. - if (!event.isCancelled()) { - disguiseInUse = true; - - task = Bukkit.getScheduler().runTaskTimer(LibsDisguises.getInstance(), velocityRunnable, 1, 1); - - // Stick the disguise in the disguises bin - DisguiseUtilities.addDisguise(entity.getUniqueId(), (TargetedDisguise) this); - - if (isSelfDisguiseVisible() && getEntity() instanceof Player) { - DisguiseUtilities.removeSelfDisguise((Player) getEntity()); - } - - // Resend the disguised entity's packet - DisguiseUtilities.refreshTrackers((TargetedDisguise) this); - - // If he is a player, then self disguise himself - Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() { - @Override - public void run() { - DisguiseUtilities.setupFakeDisguise(Disguise.this); - } - }, 2); - return true; + if (event.isCancelled()) { + return false; } + + disguiseInUse = true; + + task = Bukkit.getScheduler().runTaskTimer(LibsDisguises.getInstance(), velocityRunnable, 1, 1); + + if (this instanceof PlayerDisguise) { + PlayerDisguise disguise = (PlayerDisguise) this; + + if (disguise.isDisplayedInTab()) { + PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); + addTab.getPlayerInfoDataLists().write(0, Arrays.asList(new PlayerInfoData(disguise.getGameProfile(), 0, + NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(disguise.getName())))); + + try { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!((TargetedDisguise) this).canSee(player)) + continue; + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, addTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + + // Stick the disguise in the disguises bin + DisguiseUtilities.addDisguise(entity.getUniqueId(), (TargetedDisguise) this); + + if (isSelfDisguiseVisible() && getEntity() instanceof Player) { + DisguiseUtilities.removeSelfDisguise((Player) getEntity()); + } + + // Resend the disguised entity's packet + DisguiseUtilities.refreshTrackers((TargetedDisguise) this); + + // If he is a player, then self disguise himself + Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() { + @Override + public void run() { + DisguiseUtilities.setupFakeDisguise(Disguise.this); + } + }, 2); + + if (isHidePlayer() && getEntity() instanceof Player) { + PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + addTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); + addTab.getPlayerInfoDataLists().write(0, + Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, + NativeGameMode.SURVIVAL, WrappedChatComponent.fromText("")))); + + try { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!((TargetedDisguise) this).canSee(player)) + continue; + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, addTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + return true; } + return false; } public boolean stopDisguise() { return removeDisguise(); } - - /** - * Returns the list of people who have /disguiseViewSelf toggled on - * - * @return - */ - public static List getViewSelf() { - return viewSelf; - } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index 57ae731f..7fbfc948 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -1,9 +1,21 @@ package me.libraryaddict.disguise.disguisetypes; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.UUID; + import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; +import com.comphenix.protocol.wrappers.PlayerInfoData; +import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedGameProfile; import me.libraryaddict.disguise.LibsDisguises; @@ -12,58 +24,51 @@ import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsProfileLookup; import me.libraryaddict.disguise.utilities.ReflectionManager; -public class PlayerDisguise extends TargetedDisguise -{ +public class PlayerDisguise extends TargetedDisguise { private LibsProfileLookup currentLookup; private WrappedGameProfile gameProfile; private String playerName; private String skinToUse; + private UUID uuid = UUID.randomUUID(); - private PlayerDisguise() - { + private PlayerDisguise() { // Internal usage only } - public PlayerDisguise(Player player) - { + public PlayerDisguise(Player player) { this(ReflectionManager.getGameProfile(player)); } - public PlayerDisguise(Player player, Player skinToUse) - { + public PlayerDisguise(Player player, Player skinToUse) { this(ReflectionManager.getGameProfile(player), ReflectionManager.getGameProfile(skinToUse)); } - public PlayerDisguise(String name) - { + public PlayerDisguise(String name) { setName(name); setSkin(name); createDisguise(DisguiseType.PLAYER); } - public PlayerDisguise(String name, String skinToUse) - { + public PlayerDisguise(String name, String skinToUse) { setName(name); setSkin(skinToUse); createDisguise(DisguiseType.PLAYER); } - public PlayerDisguise(WrappedGameProfile gameProfile) - { + public PlayerDisguise(WrappedGameProfile gameProfile) { setName(gameProfile.getName()); - this.gameProfile = gameProfile; + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile); createDisguise(DisguiseType.PLAYER); } - public PlayerDisguise(WrappedGameProfile gameProfile, WrappedGameProfile skinToUse) - { + public PlayerDisguise(WrappedGameProfile gameProfile, WrappedGameProfile skinToUse) { setName(gameProfile.getName()); - this.gameProfile = gameProfile; + this.gameProfile = ReflectionManager.getGameProfile(uuid, gameProfile.getName()); setSkin(skinToUse); @@ -71,31 +76,27 @@ public class PlayerDisguise extends TargetedDisguise } @Override - public PlayerDisguise addPlayer(Player player) - { + public PlayerDisguise addPlayer(Player player) { return (PlayerDisguise) super.addPlayer(player); } @Override - public PlayerDisguise addPlayer(String playername) - { + public PlayerDisguise addPlayer(String playername) { return (PlayerDisguise) super.addPlayer(playername); } @Override - public PlayerDisguise clone() - { + public PlayerDisguise clone() { PlayerDisguise disguise = new PlayerDisguise(); disguise.playerName = getName(); - if (disguise.currentLookup == null && disguise.gameProfile != null) - { + if (disguise.currentLookup == null && disguise.gameProfile != null) { disguise.skinToUse = getSkin(); - disguise.gameProfile = ReflectionManager.getClonedProfile(getGameProfile()); + disguise.gameProfile = ReflectionManager.getGameProfileWithThisSkin(disguise.uuid, getGameProfile().getName(), + getGameProfile()); } - else - { + else { disguise.setSkin(getSkin()); } @@ -107,8 +108,7 @@ public class PlayerDisguise extends TargetedDisguise disguise.setVelocitySent(isVelocitySent()); disguise.setModifyBoundingBox(isModifyBoundingBox()); - if (getWatcher() != null) - { + if (getWatcher() != null) { disguise.setWatcher(getWatcher().clone(disguise)); } @@ -117,17 +117,13 @@ public class PlayerDisguise extends TargetedDisguise return disguise; } - public WrappedGameProfile getGameProfile() - { - if (gameProfile == null) - { - if (getSkin() != null) - { - gameProfile = ReflectionManager.getGameProfile(null, getName()); + public WrappedGameProfile getGameProfile() { + if (gameProfile == null) { + if (getSkin() != null) { + gameProfile = ReflectionManager.getGameProfile(uuid, getName()); } - else - { - gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, getName(), + else { + gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), DisguiseUtilities.getProfileFromMojang(this)); } } @@ -135,103 +131,93 @@ public class PlayerDisguise extends TargetedDisguise return gameProfile; } - public String getName() - { + public String getName() { return playerName; } - public String getSkin() - { + public String getSkin() { return skinToUse; } @Override - public PlayerWatcher getWatcher() - { + public PlayerWatcher getWatcher() { return (PlayerWatcher) super.getWatcher(); } + public boolean isDisplayedInTab() { + return getWatcher().isDisplayedInTab(); + } + @Override - public boolean isPlayerDisguise() - { + public boolean isPlayerDisguise() { return true; } @Override - public PlayerDisguise removePlayer(Player player) - { + public PlayerDisguise removePlayer(Player player) { return (PlayerDisguise) super.removePlayer(player); } @Override - public PlayerDisguise removePlayer(String playername) - { + public PlayerDisguise removePlayer(String playername) { return (PlayerDisguise) super.removePlayer(playername); } @Override - public PlayerDisguise setDisguiseTarget(TargetType newTargetType) - { + public PlayerDisguise setDisguiseTarget(TargetType newTargetType) { return (PlayerDisguise) super.setDisguiseTarget(newTargetType); } + public void setDisplayedInTab(boolean showPlayerInTab) { + getWatcher().setDisplayedInTab(showPlayerInTab); + } + @Override - public PlayerDisguise setEntity(Entity entity) - { + public PlayerDisguise setEntity(Entity entity) { return (PlayerDisguise) super.setEntity(entity); } - public void setGameProfile(WrappedGameProfile gameProfile) - { - this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, gameProfile.getName(), gameProfile); + public void setGameProfile(WrappedGameProfile gameProfile) { + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile); } @Override - public PlayerDisguise setHearSelfDisguise(boolean hearSelfDisguise) - { + public PlayerDisguise setHearSelfDisguise(boolean hearSelfDisguise) { return (PlayerDisguise) super.setHearSelfDisguise(hearSelfDisguise); } @Override - public PlayerDisguise setHideArmorFromSelf(boolean hideArmor) - { + public PlayerDisguise setHideArmorFromSelf(boolean hideArmor) { return (PlayerDisguise) super.setHideArmorFromSelf(hideArmor); } @Override - public PlayerDisguise setHideHeldItemFromSelf(boolean hideHeldItem) - { + public PlayerDisguise setHideHeldItemFromSelf(boolean hideHeldItem) { return (PlayerDisguise) super.setHideHeldItemFromSelf(hideHeldItem); } @Override - public PlayerDisguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) - { + public PlayerDisguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { return (PlayerDisguise) super.setKeepDisguiseOnEntityDespawn(keepDisguise); } @Override - public PlayerDisguise setKeepDisguiseOnPlayerDeath(boolean keepDisguise) - { + public PlayerDisguise setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { return (PlayerDisguise) super.setKeepDisguiseOnPlayerDeath(keepDisguise); } @Override - public PlayerDisguise setKeepDisguiseOnPlayerLogout(boolean keepDisguise) - { + public PlayerDisguise setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { return (PlayerDisguise) super.setKeepDisguiseOnPlayerLogout(keepDisguise); } @Override - public PlayerDisguise setModifyBoundingBox(boolean modifyBox) - { + public PlayerDisguise setModifyBoundingBox(boolean modifyBox) { return (PlayerDisguise) super.setModifyBoundingBox(modifyBox); } - private void setName(String name) - { - if (name.length() > 16) - { + private void setName(String name) { + if (name.length() > 16) { name = name.substring(0, 16); } @@ -239,32 +225,25 @@ public class PlayerDisguise extends TargetedDisguise } @Override - public PlayerDisguise setReplaceSounds(boolean areSoundsReplaced) - { + public PlayerDisguise setReplaceSounds(boolean areSoundsReplaced) { return (PlayerDisguise) super.setReplaceSounds(areSoundsReplaced); } - public PlayerDisguise setSkin(String newSkin) - { + public PlayerDisguise setSkin(String newSkin) { skinToUse = newSkin; - if (newSkin == null) - { + if (newSkin == null) { currentLookup = null; gameProfile = null; } - else - { - if (newSkin.length() > 16) - { + else { + if (newSkin.length() > 16) { skinToUse = newSkin.substring(0, 16); } - currentLookup = new LibsProfileLookup() - { + currentLookup = new LibsProfileLookup() { @Override - public void onLookup(WrappedGameProfile gameProfile) - { + public void onLookup(WrappedGameProfile gameProfile) { if (currentLookup != this || gameProfile == null) return; @@ -277,8 +256,7 @@ public class PlayerDisguise extends TargetedDisguise WrappedGameProfile gameProfile = DisguiseUtilities.getProfileFromMojang(this.skinToUse, currentLookup, LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); - if (gameProfile != null) - { + if (gameProfile != null) { setSkin(gameProfile); } } @@ -293,10 +271,8 @@ public class PlayerDisguise extends TargetedDisguise * GameProfile * @return */ - public PlayerDisguise setSkin(WrappedGameProfile gameProfile) - { - if (gameProfile == null) - { + public PlayerDisguise setSkin(WrappedGameProfile gameProfile) { + if (gameProfile == null) { this.gameProfile = null; this.skinToUse = null; return this; @@ -307,10 +283,32 @@ public class PlayerDisguise extends TargetedDisguise currentLookup = null; this.skinToUse = gameProfile.getName(); - this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, getName(), gameProfile); + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile); + + if (DisguiseUtilities.isDisguiseInUse(this)) { + if (isDisplayedInTab()) { + PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); + addTab.getPlayerInfoDataLists().write(0, Arrays.asList(new PlayerInfoData(getGameProfile(), 0, + NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(getName())))); + + PacketContainer deleteTab = addTab.shallowClone(); + deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); + + try { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!((TargetedDisguise) this).canSee(player)) + continue; + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, deleteTab); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, addTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } - if (DisguiseUtilities.isDisguiseInUse(this)) - { DisguiseUtilities.refreshTrackers(this); } @@ -318,32 +316,27 @@ public class PlayerDisguise extends TargetedDisguise } @Override - public PlayerDisguise setVelocitySent(boolean sendVelocity) - { + public PlayerDisguise setVelocitySent(boolean sendVelocity) { return (PlayerDisguise) super.setVelocitySent(sendVelocity); } @Override - public PlayerDisguise setViewSelfDisguise(boolean viewSelfDisguise) - { + public PlayerDisguise setViewSelfDisguise(boolean viewSelfDisguise) { return (PlayerDisguise) super.setViewSelfDisguise(viewSelfDisguise); } @Override - public PlayerDisguise setWatcher(FlagWatcher newWatcher) - { + public PlayerDisguise setWatcher(FlagWatcher newWatcher) { return (PlayerDisguise) super.setWatcher(newWatcher); } @Override - public PlayerDisguise silentlyAddPlayer(String playername) - { + public PlayerDisguise silentlyAddPlayer(String playername) { return (PlayerDisguise) super.silentlyAddPlayer(playername); } @Override - public PlayerDisguise silentlyRemovePlayer(String playername) - { + public PlayerDisguise silentlyRemovePlayer(String playername) { return (PlayerDisguise) super.silentlyRemovePlayer(playername); } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java index 357632c2..f45a050a 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java @@ -1,102 +1,141 @@ package me.libraryaddict.disguise.disguisetypes; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; +import com.comphenix.protocol.wrappers.PlayerInfoData; +import com.comphenix.protocol.wrappers.WrappedChatComponent; + import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.ReflectionManager; -public abstract class TargetedDisguise extends Disguise -{ +public abstract class TargetedDisguise extends Disguise { - public enum TargetType - { + 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 TargetedDisguise addPlayer(Player player) - { + public TargetedDisguise addPlayer(Player player) { addPlayer(player.getName()); return this; } - public TargetedDisguise addPlayer(String playername) - { - if (!disguiseViewers.contains(playername)) - { + public TargetedDisguise addPlayer(String playername) { + if (!disguiseViewers.contains(playername)) { disguiseViewers.add(playername); - if (DisguiseAPI.isDisguiseInUse(this)) - { + if (DisguiseAPI.isDisguiseInUse(this)) { DisguiseUtilities.checkConflicts(this, playername); DisguiseUtilities.refreshTracker(this, playername); + + if (isHidePlayer() && getEntity() instanceof Player) { + try { + Player player = Bukkit.getPlayerExact(playername); + + if (player != null) { + PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + + deleteTab.getPlayerInfoAction().write(0, + canSee(player) ? PlayerInfoAction.REMOVE_PLAYER : PlayerInfoAction.ADD_PLAYER); + deleteTab.getPlayerInfoDataLists().write(0, + Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, + NativeGameMode.SURVIVAL, + WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName())))); + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, deleteTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } } } return this; } - public boolean canSee(Player player) - { + public boolean canSee(Player player) { return canSee(player.getName()); } - public boolean canSee(String playername) - { + public boolean canSee(String playername) { boolean hasPlayer = disguiseViewers.contains(playername); - if (targetType == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) - { + if (targetType == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { return !hasPlayer; } return hasPlayer; } - public TargetType getDisguiseTarget() - { + public TargetType getDisguiseTarget() { return targetType; } - public List getObservers() - { + public List getObservers() { return Collections.unmodifiableList(disguiseViewers); } - public TargetedDisguise removePlayer(Player player) - { + public TargetedDisguise removePlayer(Player player) { removePlayer(player.getName()); return this; } - public TargetedDisguise removePlayer(String playername) - { - if (disguiseViewers.contains(playername)) - { + public TargetedDisguise removePlayer(String playername) { + if (disguiseViewers.contains(playername)) { disguiseViewers.remove(playername); - if (DisguiseAPI.isDisguiseInUse(this)) - { + if (DisguiseAPI.isDisguiseInUse(this)) { DisguiseUtilities.checkConflicts(this, playername); DisguiseUtilities.refreshTracker(this, playername); + + if (isHidePlayer() && getEntity() instanceof Player) { + try { + Player player = Bukkit.getPlayerExact(playername); + + if (player != null) { + PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + + deleteTab.getPlayerInfoAction().write(0, + canSee(player) ? PlayerInfoAction.ADD_PLAYER : PlayerInfoAction.REMOVE_PLAYER); + deleteTab.getPlayerInfoDataLists().write(0, + Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, + NativeGameMode.SURVIVAL, + WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName())))); + + ProtocolLibrary.getProtocolManager().sendServerPacket(player, deleteTab); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } } } return this; } - public TargetedDisguise setDisguiseTarget(TargetType newTargetType) - { - if (DisguiseUtilities.isDisguiseInUse(this)) - { + public TargetedDisguise setDisguiseTarget(TargetType newTargetType) { + if (DisguiseUtilities.isDisguiseInUse(this)) { throw new RuntimeException("Cannot set the disguise target after the entity has been disguised"); } @@ -105,20 +144,16 @@ public abstract class TargetedDisguise extends Disguise return this; } - public TargetedDisguise silentlyAddPlayer(String playername) - { - if (!disguiseViewers.contains(playername)) - { + public TargetedDisguise silentlyAddPlayer(String playername) { + if (!disguiseViewers.contains(playername)) { disguiseViewers.add(playername); } return this; } - public TargetedDisguise silentlyRemovePlayer(String playername) - { - if (disguiseViewers.contains(playername)) - { + public TargetedDisguise silentlyRemovePlayer(String playername) { + if (disguiseViewers.contains(playername)) { disguiseViewers.remove(playername); } diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java index 15e2b2c3..8357342c 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java @@ -17,48 +17,53 @@ import me.libraryaddict.disguise.disguisetypes.FlagType; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -public class PlayerWatcher extends LivingWatcher -{ +public class PlayerWatcher extends LivingWatcher { private boolean isInBed; private BlockFace sleepingDirection; + private boolean alwaysShowInTab = DisguiseConfig.isShowDisguisedPlayersInTab(); - public PlayerWatcher(Disguise disguise) - { + public PlayerWatcher(Disguise disguise) { super(disguise); setData(FlagType.PLAYER_SKIN, FlagType.PLAYER_SKIN.getDefault()); } + public boolean isDisplayedInTab() { + return alwaysShowInTab; + } + + public void setDisplayedInTab(boolean showPlayerInTab) { + if (getDisguise().isDisguiseInUse()) + throw new IllegalStateException("Cannot set this while disguise is in use!"); + + alwaysShowInTab = showPlayerInTab; + } + @Override - public PlayerWatcher clone(Disguise disguise) - { + public PlayerWatcher clone(Disguise disguise) { PlayerWatcher watcher = (PlayerWatcher) super.clone(disguise); watcher.isInBed = isInBed; + watcher.sleepingDirection = sleepingDirection; + watcher.alwaysShowInTab = alwaysShowInTab; return watcher; } - public void setMainHand(MainHand mainHand) - { + public void setMainHand(MainHand mainHand) { setData(FlagType.PLAYER_HAND, (byte) mainHand.ordinal()); sendData(FlagType.PLAYER_HAND); } - public MainHand getMainHand() - { + public MainHand getMainHand() { return MainHand.values()[getData(FlagType.PLAYER_HAND)]; } - public BlockFace getSleepingDirection() - { - if (sleepingDirection == null) - { - if (this.getDisguise().getEntity() != null && isSleeping()) - { + public BlockFace getSleepingDirection() { + if (sleepingDirection == null) { + if (this.getDisguise().getEntity() != null && isSleeping()) { this.sleepingDirection = BlockFace .values()[Math.round(this.getDisguise().getEntity().getLocation().getYaw() / 90F) & 0x3]; } - else - { + else { return BlockFace.EAST; } } @@ -73,117 +78,97 @@ public class PlayerWatcher extends LivingWatcher // Bit 5 (0x20): Right Pants Leg enabled // Bit 6 (0x40): Hat enabled - private boolean isSkinFlag(int i) - { + private boolean isSkinFlag(int i) { return ((byte) getData(FlagType.PLAYER_SKIN) & 1 << i) != 0; } - public boolean isCapeEnabled() - { + public boolean isCapeEnabled() { return isSkinFlag(1); } - public boolean isJackedEnabled() - { + public boolean isJackedEnabled() { return isSkinFlag(2); } - public boolean isLeftSleeveEnabled() - { + public boolean isLeftSleeveEnabled() { return isSkinFlag(3); } - public boolean isRightSleeveEnabled() - { + public boolean isRightSleeveEnabled() { return isSkinFlag(4); } - public boolean isLeftPantsEnabled() - { + public boolean isLeftPantsEnabled() { return isSkinFlag(5); } - public boolean isRightPantsEnabled() - { + public boolean isRightPantsEnabled() { return isSkinFlag(6); } - public boolean isHatEnabled() - { + public boolean isHatEnabled() { return isSkinFlag(7); } - public void setCapeEnabled(boolean enabled) - { + public void setCapeEnabled(boolean enabled) { setSkinFlags(1, enabled); sendData(FlagType.PLAYER_SKIN); } - public void setJackedEnabled(boolean enabled) - { + public void setJacketEnabled(boolean enabled) { setSkinFlags(2, enabled); sendData(FlagType.PLAYER_SKIN); } - public void setLeftSleeveEnabled(boolean enabled) - { + public void setLeftSleeveEnabled(boolean enabled) { setSkinFlags(3, enabled); sendData(FlagType.PLAYER_SKIN); } - public void setRightSleeveEnabled(boolean enabled) - { + public void setRightSleeveEnabled(boolean enabled) { setSkinFlags(4, enabled); sendData(FlagType.PLAYER_SKIN); } - public void setLeftPantsEnabled(boolean enabled) - { + public void setLeftPantsEnabled(boolean enabled) { setSkinFlags(5, enabled); sendData(FlagType.PLAYER_SKIN); } - public void setRightPantsEnabled(boolean enabled) - { + public void setRightPantsEnabled(boolean enabled) { setSkinFlags(6, enabled); sendData(FlagType.PLAYER_SKIN); } - public void setHatEnabled(boolean enabled) - { + public void setHatEnabled(boolean enabled) { setSkinFlags(7, enabled); sendData(FlagType.PLAYER_SKIN); } - public boolean isSleeping() - { + public boolean isSleeping() { return isInBed; } - public void setSkin(String playerName) - { + public void setSkin(String playerName) { ((PlayerDisguise) getDisguise()).setSkin(playerName); } - public void setSkin(WrappedGameProfile profile) - { + public void setSkin(WrappedGameProfile profile) { ((PlayerDisguise) getDisguise()).setSkin(profile); } - public void setSleeping(BlockFace sleepingDirection) - { + public void setSleeping(BlockFace sleepingDirection) { setSleeping(true, sleepingDirection); } - public void setSleeping(boolean sleep) - { + public void setSleeping(boolean sleep) { setSleeping(sleep, null); } @@ -193,30 +178,22 @@ public class PlayerWatcher extends LivingWatcher * @param sleeping * @param sleepingDirection */ - public void setSleeping(boolean sleeping, BlockFace sleepingDirection) - { - if (sleepingDirection != null) - { + public void setSleeping(boolean sleeping, BlockFace sleepingDirection) { + if (sleepingDirection != null) { this.sleepingDirection = BlockFace.values()[sleepingDirection.ordinal() % 4]; } isInBed = sleeping; - if (DisguiseConfig.isBedPacketsEnabled() && DisguiseUtilities.isDisguiseInUse(getDisguise())) - { - try - { - if (isSleeping()) - { - for (Player player : DisguiseUtilities.getPerverts(getDisguise())) - { + if (DisguiseConfig.isBedPacketsEnabled() && DisguiseUtilities.isDisguiseInUse(getDisguise())) { + try { + if (isSleeping()) { + for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { PacketContainer[] packets = DisguiseUtilities.getBedPackets(getDisguise().getEntity().getLocation(), player.getLocation(), (PlayerDisguise) getDisguise()); - if (getDisguise().getEntity() == player) - { - for (PacketContainer packet : packets) - { + if (getDisguise().getEntity() == player) { + for (PacketContainer packet : packets) { packet = packet.shallowClone(); packet.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); @@ -224,17 +201,14 @@ public class PlayerWatcher extends LivingWatcher ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); } } - else - { - for (PacketContainer packet : packets) - { + else { + for (PacketContainer packet : packets) { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); } } } } - else - { + else { PacketContainer packet = new PacketContainer(Server.ANIMATION); StructureModifier mods = packet.getIntegers(); @@ -242,29 +216,24 @@ public class PlayerWatcher extends LivingWatcher mods.write(0, getDisguise().getEntity().getEntityId()); mods.write(1, 3); - for (Player player : DisguiseUtilities.getPerverts(getDisguise())) - { + for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); } } } - catch (Exception ex) - { + catch (Exception ex) { ex.printStackTrace(); } } } - private void setSkinFlags(int i, boolean flag) - { + private void setSkinFlags(int i, boolean flag) { byte b0 = (byte) getData(FlagType.PLAYER_SKIN); - if (flag) - { + if (flag) { setData(FlagType.PLAYER_SKIN, (byte) (b0 | 1 << i)); } - else - { + else { setData(FlagType.PLAYER_SKIN, (byte) (b0 & (~1 << i))); } } diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 771dba17..e80a2cfe 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -278,8 +278,6 @@ public class DisguiseUtilities { // 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(); d.removeDisguise(); } diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index 3f12abd0..18bd8fd6 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -52,6 +52,7 @@ import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerClientI import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerInventory; import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerMain; import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerSounds; +import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerTabList; import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerViewDisguises; public class PacketsManager { @@ -139,6 +140,7 @@ public class PacketsManager { private static PacketListener soundsListener; private static boolean soundsListenerEnabled; private static PacketListener viewDisguisesListener; + private static PacketListener tabListListener; private static boolean viewDisguisesListenerEnabled; private static HashMap> _cancelMeta = new HashMap>(); @@ -148,8 +150,10 @@ public class PacketsManager { // Because it kicks you for hacking. clientInteractEntityListener = new PacketListenerClientInteract(libsDisguises); + tabListListener = new PacketListenerTabList(libsDisguises); ProtocolLibrary.getProtocolManager().addPacketListener(clientInteractEntityListener); + ProtocolLibrary.getProtocolManager().addPacketListener(tabListListener); // Now I call this and the main listener is registered! setupMainPacketsListener(); @@ -310,7 +314,9 @@ public class PacketsManager { // Send player info along with the disguise PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO); - packets.addPacket(sendTab); + + if (!((PlayerDisguise) disguise).isDisplayedInTab()) + packets.addPacket(sendTab); // Add player to the list, necessary to spawn them sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0)); @@ -405,9 +411,11 @@ public class PacketsManager { // Remove player from the list PacketContainer deleteTab = sendTab.shallowClone(); - packets.addDelayedPacket(deleteTab, 40); - deleteTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(4)); + + if (!((PlayerDisguise) disguise).isDisplayedInTab()) { + packets.addDelayedPacket(deleteTab, 40); + } } else if (disguise.getType().isMob() || disguise.getType() == DisguiseType.ARMOR_STAND) { Vector vec = disguisedEntity.getVelocity(); diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java b/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java index e115c660..ebbd1bfe 100644 --- a/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java +++ b/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java @@ -225,7 +225,7 @@ public class ReflectionFlagWatchers { } for (String methodName : new String[] { - "setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf", "setHearSelfDisguise" + "setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf", "setHearSelfDisguise", "setHidePlayer" }) { try { methods.add(Disguise.class.getMethod(methodName, boolean.class)); diff --git a/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java b/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java new file mode 100644 index 00000000..81efb04b --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java @@ -0,0 +1,65 @@ +package me.libraryaddict.disguise.utilities.packetlisteners; + +import java.util.Iterator; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; +import com.comphenix.protocol.wrappers.PlayerInfoData; + +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; + +public class PacketListenerTabList extends PacketAdapter { + public PacketListenerTabList(LibsDisguises plugin) { + super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO); + } + + @Override + public void onPacketSending(final PacketEvent event) { + if (event.isCancelled()) + return; + + Player observer = event.getPlayer(); + + if (event.getPacket().getPlayerInfoAction().read(0) != PlayerInfoAction.ADD_PLAYER) + return; + + List list = event.getPacket().getPlayerInfoDataLists().read(0); + Iterator itel = list.iterator(); + + while (itel.hasNext()) { + PlayerInfoData data = itel.next(); + + Player player = Bukkit.getPlayer(data.getProfile().getUUID()); + + if (player == null) + continue; + + Disguise disguise = DisguiseAPI.getDisguise(observer, player); + + if (disguise == null) + continue; + + if (!disguise.isHidePlayer()) + continue; + + itel.remove(); + } + + if (list.isEmpty()) { + event.setCancelled(true); + } + else { + event.getPacket().getPlayerInfoDataLists().write(0, list); + } + } + +}