From cada0f4f91942e17341020504e6b1475be07c23d Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Thu, 3 Jan 2019 15:13:03 +1300 Subject: [PATCH] Move classes into packages, clean up packet handling into classes, yaw/pitch should be consistent --- .../libraryaddict/disguise/DisguiseAPI.java | 2 +- .../disguise/DisguiseConfig.java | 4 +- .../disguise/DisguiseListener.java | 2 +- .../libraryaddict/disguise/LibsDisguises.java | 216 +- .../commands/DisguiseCloneCommand.java | 2 +- .../disguise/commands/DisguiseCommand.java | 2 +- .../commands/DisguiseEntityCommand.java | 2 +- .../commands/DisguiseHelpCommand.java | 4 +- .../commands/DisguiseModifyCommand.java | 2 +- .../commands/DisguiseModifyEntityCommand.java | 3 +- .../commands/DisguiseModifyPlayerCommand.java | 2 +- .../commands/DisguiseModifyRadiusCommand.java | 4 +- .../commands/DisguisePlayerCommand.java | 2 +- .../commands/DisguiseRadiusCommand.java | 6 +- .../commands/DisguiseViewSelfCommand.java | 4 +- .../commands/LibsDisguisesCommand.java | 2 +- .../disguise/commands/UndisguiseCommand.java | 4 +- .../commands/UndisguiseEntityCommand.java | 4 +- .../commands/UndisguisePlayerCommand.java | 2 +- .../commands/UndisguiseRadiusCommand.java | 4 +- .../disguise/disguisetypes/Disguise.java | 10 +- .../disguise/disguisetypes/DisguiseType.java | 2 +- .../disguise/disguisetypes/FlagWatcher.java | 2 +- .../disguisetypes/PlayerDisguise.java | 4 +- .../disguisetypes/TargetedDisguise.java | 2 +- .../watchers/MinecartWatcher.java | 2 +- .../disguise/utilities/DisguiseSound.java | 1 + .../disguise/utilities/DisguiseUtilities.java | 177 +- .../disguise/utilities/LibsPremium.java | 1 + .../disguise/utilities/PacketsManager.java | 1154 --------- .../utilities/{ => metrics}/Metrics.java | 2 +- .../utilities/metrics/MetricsInitalizer.java | 232 ++ .../utilities/packets/IPacketHandler.java | 16 + .../utilities/packets/LibsPackets.java | 94 + .../utilities/packets/PacketsHandler.java | 98 + .../utilities/packets/PacketsManager.java | 205 ++ .../PacketHandlerAnimation.java | 31 + .../PacketHandlerAttributes.java | 71 + .../packethandlers/PacketHandlerBed.java | 28 + .../packethandlers/PacketHandlerCollect.java | 42 + .../PacketHandlerEntityStatus.java | 28 + .../PacketHandlerEquipment.java | 103 + .../PacketHandlerHeadRotation.java | 53 + .../packethandlers/PacketHandlerMetadata.java | 53 + .../packethandlers/PacketHandlerMovement.java | 103 + .../packethandlers/PacketHandlerSpawn.java | 403 ++++ .../packethandlers/PacketHandlerVelocity.java | 29 + .../PacketListenerClientInteract.java | 224 +- .../PacketListenerInventory.java | 682 +++--- .../packetlisteners/PacketListenerMain.java | 168 +- .../packetlisteners/PacketListenerSounds.java | 694 +++--- .../PacketListenerTabList.java | 130 +- .../PacketListenerViewSelfDisguise.java | 11 +- .../parser/DisguiseParseException.java | 2 +- .../utilities/parser/DisguiseParser.java | 4 +- .../utilities/parser/params/ParamInfo.java | 2 +- .../params/types/base/ParamInfoBoolean.java | 2 +- .../types/custom/ParamInfoItemStack.java | 2 +- .../types/custom/ParamInfoParticle.java | 2 +- .../{ => reflection}/ClassGetter.java | 190 +- .../{ => reflection}/DisguiseValues.java | 124 +- .../{ => reflection}/FakeBoundingBox.java | 2 +- .../{ => reflection}/LibsProfileLookup.java | 18 +- .../LibsProfileLookupCaller.java | 2 +- .../{ => reflection}/ReflectionManager.java | 2146 ++++++++--------- .../utilities/{ => translations}/LibsMsg.java | 3 +- .../{ => translations}/TranslateFiller.java | 3 +- .../{ => translations}/TranslateType.java | 4 +- 68 files changed, 4009 insertions(+), 3625 deletions(-) delete mode 100644 src/main/java/me/libraryaddict/disguise/utilities/PacketsManager.java rename src/main/java/me/libraryaddict/disguise/utilities/{ => metrics}/Metrics.java (99%) create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/IPacketHandler.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsHandler.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsManager.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAnimation.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAttributes.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerBed.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerCollect.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEntityStatus.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEquipment.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMetadata.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerVelocity.java rename src/main/java/me/libraryaddict/disguise/utilities/{ => packets}/packetlisteners/PacketListenerClientInteract.java (96%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => packets}/packetlisteners/PacketListenerInventory.java (97%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => packets}/packetlisteners/PacketListenerMain.java (86%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => packets}/packetlisteners/PacketListenerSounds.java (96%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => packets}/packetlisteners/PacketListenerTabList.java (93%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => packets}/packetlisteners/PacketListenerViewSelfDisguise.java (94%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => reflection}/ClassGetter.java (95%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => reflection}/DisguiseValues.java (93%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => reflection}/FakeBoundingBox.java (88%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => reflection}/LibsProfileLookup.java (73%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => reflection}/LibsProfileLookupCaller.java (91%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => reflection}/ReflectionManager.java (97%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => translations}/LibsMsg.java (99%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => translations}/TranslateFiller.java (97%) rename src/main/java/me/libraryaddict/disguise/utilities/{ => translations}/TranslateType.java (97%) diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java b/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java index 842d8a1b..8d4a903c 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java @@ -6,7 +6,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.AbstractHorseWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.HorseWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.ReflectionManager; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.entity.*; diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java index 47e93a07..1f9c8d85 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java @@ -3,8 +3,8 @@ package me.libraryaddict.disguise; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsPremium; -import me.libraryaddict.disguise.utilities.PacketsManager; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.packets.PacketsManager; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import org.bukkit.Bukkit; diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java index a4f035f3..a1e136be 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java @@ -14,7 +14,7 @@ import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.UpdateChecker; import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; import me.libraryaddict.disguise.utilities.parser.DisguiseParser; diff --git a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java index eb63d1f3..ebf0891d 100644 --- a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java @@ -4,9 +4,16 @@ import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedWatchableObject; import me.libraryaddict.disguise.commands.*; -import me.libraryaddict.disguise.disguisetypes.*; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagWatcher; +import me.libraryaddict.disguise.disguisetypes.MetaIndex; import me.libraryaddict.disguise.disguisetypes.watchers.*; import me.libraryaddict.disguise.utilities.*; +import me.libraryaddict.disguise.utilities.metrics.MetricsInitalizer; +import me.libraryaddict.disguise.utilities.packets.PacketsManager; +import me.libraryaddict.disguise.utilities.reflection.DisguiseValues; +import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.bukkit.Bukkit; @@ -21,9 +28,6 @@ import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; public class LibsDisguises extends JavaPlugin { private static LibsDisguises instance; @@ -89,7 +93,7 @@ public class LibsDisguises extends JavaPlugin { getLogger().info("Commands has been disabled, as per config"); } - infectWithMetrics(); + new MetricsInitalizer(); } @Override @@ -101,208 +105,6 @@ public class LibsDisguises extends JavaPlugin { } } - private void infectWithMetrics() { - String version = getDescription().getVersion(); - - // If a release build, attach build number - if (!isReleaseBuild() || !LibsPremium.isPremium()) { - version += "-"; - - // 9.7.0-SNAPSHOT-b30 - if (isNumberedBuild()) { - version += "b"; - } - // else 9.7.0-SNAPSHOT-unknown - - version += getBuildNo(); - } - - Metrics metrics = new Metrics(this, version); - - final String premium = LibsPremium.isPremium() ? - getDescription().getVersion().contains("SNAPSHOT") ? "Paid Builds" : "Paid Plugin" : "Free Builds"; - - metrics.addCustomChart(new Metrics.SimplePie("premium") { - @Override - public String getValue() { - return premium; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("translations") { - @Override - public String getValue() { - return LibsPremium.isPremium() && DisguiseConfig.isUseTranslations() ? "Yes" : "No"; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("custom_disguises") { - @Override - public String getValue() { - HashMap map = DisguiseConfig.getCustomDisguises(); - - return map.size() + (map.containsKey("libraryaddict") ? -1 : 0) > 0 ? "Yes" : "No"; - } - }); - - metrics.addCustomChart(new Metrics.MultiLineChart("disguised_entities") { - @Override - public HashMap getValues(HashMap hashMap) { - for (HashSet list : DisguiseUtilities.getDisguises().values()) { - for (Disguise disg : list) { - if (disg.getEntity() == null || !disg.isDisguiseInUse()) - continue; - - String name = disg.getEntity().getType().name(); - - hashMap.put(name, hashMap.containsKey(name) ? hashMap.get(name) + 1 : 1); - } - } - - return hashMap; - } - }); - - metrics.addCustomChart(new Metrics.MultiLineChart("disguises_used") { - @Override - public HashMap getValues(HashMap hashMap) { - for (HashSet list : DisguiseUtilities.getDisguises().values()) { - for (Disguise disg : list) { - if (disg.getEntity() == null || !disg.isDisguiseInUse()) - continue; - - String name = disg.getType().name(); - - hashMap.put(name, hashMap.containsKey(name) ? hashMap.get(name) + 1 : 1); - } - } - - return hashMap; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("disguised_using") { - @Override - public String getValue() { - if (DisguiseUtilities.isPluginsUsed()) { - if (DisguiseUtilities.isCommandsUsed()) { - return "Plugins and Commands"; - } - - return "Plugins"; - } else if (DisguiseUtilities.isCommandsUsed()) { - return "Commands"; - } - - return "Unknown"; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("active_disguises") { - @Override - public String getValue() { - int disgs = 0; - - for (HashSet set : DisguiseUtilities.getDisguises().values()) { - disgs += set.size(); - } - - if (disgs == 0) - return "0"; - if (disgs <= 5) - return "1 to 5"; - else if (disgs <= 15) - return "6 to 15"; - else if (disgs <= 30) - return "16 to 30"; - else if (disgs <= 60) - return "30 to 60"; - else if (disgs <= 100) - return "60 to 100"; - else if (disgs <= 200) - return "100 to 200"; - - return "More than 200"; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("self_disguises") { - @Override - public String getValue() { - return DisguiseConfig.isViewDisguises() ? "Yes" : "No"; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("commands") { - @Override - public String getValue() { - return DisguiseConfig.isDisableCommands() ? "Enabled" : "Disabled"; - } - }); - - metrics.addCustomChart(new Metrics.SimplePie("spigot") { - @Override - public String getValue() { - try { - Class.forName("org.spigotmc.SpigotConfig"); - return "Yes"; - } - catch (Exception ex) { - return "No"; - } - } - }); - - final boolean updates = getConfig().getBoolean("NotifyUpdate"); - - metrics.addCustomChart(new Metrics.SimplePie("updates") { - @Override - public String getValue() { - return updates ? "Enabled" : "Disabled"; - } - }); - - if (getBuildNo() != null) { - metrics.addCustomChart(new Metrics.SimplePie("build_number") { - @Override - public String getValue() { - return getBuildNo(); - } - }); - } - - metrics.addCustomChart(new Metrics.SimplePie("targeted_disguises") { - /** - * Store value just to minimize amount of times it's called, and to persist even when not using anymore - */ - private boolean targetedDisguises; - - @Override - public String getValue() { - if (targetedDisguises) { - return "Yes"; - } - - Collection> list = DisguiseUtilities.getDisguises().values(); - - if (list.isEmpty()) - return "Unknown"; - - for (HashSet dList : list) { - for (TargetedDisguise disg : dList) { - if (disg.getObservers().isEmpty()) - continue; - - targetedDisguises = true; - return "Yes"; - } - } - - return "No"; - } - }); - } - public boolean isReleaseBuild() { return !getDescription().getVersion().contains("-SNAPSHOT"); } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java index 4a7c0893..4a57346a 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java @@ -3,7 +3,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java index 48652e59..ccc13b0b 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java @@ -6,7 +6,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java index 027b5d61..728d8d6d 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java @@ -5,7 +5,7 @@ import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java index 92f1e4e0..97710a9e 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java @@ -1,7 +1,7 @@ package me.libraryaddict.disguise.commands; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import me.libraryaddict.disguise.utilities.parser.DisguisePerm; import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java index 7d73a479..22fcc605 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java @@ -4,7 +4,7 @@ import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java index 3fcd08e6..0e56ef06 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java @@ -3,8 +3,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.DisguisePerm; import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java index a3078979..abede4a3 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java @@ -3,7 +3,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java index a8b8b41a..f913c4d1 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java @@ -4,8 +4,8 @@ import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java index 15337183..0c51db14 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java @@ -6,7 +6,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java index 144be047..5c2244b6 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java @@ -5,10 +5,10 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.utilities.ClassGetter; +import me.libraryaddict.disguise.utilities.reflection.ClassGetter; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseViewSelfCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseViewSelfCommand.java index 0b241998..d6b6598e 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseViewSelfCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseViewSelfCommand.java @@ -1,9 +1,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; -import org.bukkit.ChatColor; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java b/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java index f3090a06..34ed0f5d 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java @@ -2,7 +2,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.LibsPremium; import org.bukkit.ChatColor; import org.bukkit.command.Command; diff --git a/src/main/java/me/libraryaddict/disguise/commands/UndisguiseCommand.java b/src/main/java/me/libraryaddict/disguise/commands/UndisguiseCommand.java index 62d000f9..8ef61651 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/UndisguiseCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/UndisguiseCommand.java @@ -1,9 +1,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; -import org.bukkit.ChatColor; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/me/libraryaddict/disguise/commands/UndisguiseEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/UndisguiseEntityCommand.java index 53cfc555..54971029 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/UndisguiseEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/UndisguiseEntityCommand.java @@ -1,9 +1,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; -import org.bukkit.ChatColor; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java index 5c82ed4a..bbdcc817 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java @@ -2,7 +2,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; diff --git a/src/main/java/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java index 948a30cd..36dd5569 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java @@ -1,9 +1,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; -import org.bukkit.ChatColor; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java index 77a0d10a..158159c4 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -19,8 +19,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; import me.libraryaddict.disguise.events.DisguiseEvent; import me.libraryaddict.disguise.events.UndisguiseEvent; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.PacketsManager; -import me.libraryaddict.disguise.utilities.ReflectionManager; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -233,11 +232,10 @@ public abstract class Disguise { lookPacket.getIntegers().write(0, getEntity().getEntityId()); Location loc = getEntity().getLocation(); - mods.write(4, PacketsManager.getYaw(getType(), getEntity().getType(), + mods.write(4, DisguiseUtilities.getYaw(getType(), getEntity().getType(), (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F))); - mods.write(5, PacketsManager - .getPitch(getType(), DisguiseType.getType(getEntity().getType()), - (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F))); + mods.write(5, DisguiseUtilities.getPitch(getType(), getEntity().getType(), + (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F))); if (isSelfDisguiseVisible() && getEntity() instanceof Player) { PacketContainer selfLookPacket = lookPacket.shallowClone(); diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/DisguiseType.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/DisguiseType.java index 34af19eb..83e21541 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/DisguiseType.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/DisguiseType.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.disguisetypes; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import org.apache.commons.lang.StringUtils; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java index 489bc2bb..d259ed8c 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java @@ -13,7 +13,7 @@ import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.ReflectionManager; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index c98d9b73..2f91520a 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -11,8 +11,8 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsProfileLookup; -import me.libraryaddict.disguise.utilities.ReflectionManager; +import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java index 2ce385ee..b1004f21 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java @@ -9,7 +9,7 @@ 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; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.Bukkit; import org.bukkit.entity.Player; diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/watchers/MinecartWatcher.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/watchers/MinecartWatcher.java index e75f6c02..6f428feb 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/watchers/MinecartWatcher.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/watchers/MinecartWatcher.java @@ -3,7 +3,7 @@ package me.libraryaddict.disguise.disguisetypes.watchers; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.FlagWatcher; import me.libraryaddict.disguise.disguisetypes.MetaIndex; -import me.libraryaddict.disguise.utilities.ReflectionManager; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseSound.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseSound.java index 615e2fdc..fee6bdfa 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseSound.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseSound.java @@ -1,5 +1,6 @@ package me.libraryaddict.disguise.utilities; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.Sound; import java.util.Arrays; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 1cfe8b90..29bd8fa9 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -6,10 +6,7 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.BlockPosition; -import com.comphenix.protocol.wrappers.WrappedBlockData; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.comphenix.protocol.wrappers.*; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mojang.authlib.properties.PropertyMap; @@ -22,8 +19,14 @@ import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; -import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets; import me.libraryaddict.disguise.utilities.json.*; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.packets.PacketsManager; +import me.libraryaddict.disguise.utilities.reflection.DisguiseValues; +import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox; +import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.util.Strings; import org.bukkit.Bukkit; @@ -31,10 +34,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.BlockFace; -import org.bukkit.entity.Ageable; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Zombie; +import org.bukkit.entity.*; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; @@ -555,7 +555,7 @@ public class DisguiseUtilities { teleport.getIntegers().write(0, entity); doubles.write(0, sleepingLocation.getX()); - doubles.write(1, PacketsManager.getYModifier(disguise.getEntity(), disguise) + sleepingLocation.getY()); + doubles.write(1, DisguiseUtilities.getYModifier(disguise.getEntity(), disguise) + sleepingLocation.getY()); doubles.write(2, sleepingLocation.getZ()); return new PacketContainer[]{setBed, teleport}; @@ -1649,7 +1649,7 @@ public class DisguiseUtilities { return; } - LibsPackets transformed = PacketsManager.transformPacket(packet, disguise, player, player); + LibsPackets transformed = PacketsManager.getPacketsHandler().transformPacket(packet, disguise, player, player); try { if (transformed.isUnhandled()) @@ -1712,4 +1712,159 @@ public class DisguiseUtilities { } } } + + /** + * Create a new datawatcher but with the 'correct' values + */ + public static WrappedDataWatcher createSanitizedDataWatcher(WrappedDataWatcher entityWatcher, + FlagWatcher disguiseWatcher) { + WrappedDataWatcher newWatcher = new WrappedDataWatcher(); + + try { + List list = DisguiseConfig.isMetadataPacketsEnabled() ? + disguiseWatcher.convert(entityWatcher.getWatchableObjects()) : + disguiseWatcher.getWatchableObjects(); + + for (WrappedWatchableObject watchableObject : list) { + if (watchableObject == null) + continue; + + if (watchableObject.getValue() == null) + continue; + + WrappedDataWatcher.WrappedDataWatcherObject obj = ReflectionManager + .createDataWatcherObject(watchableObject.getIndex(), watchableObject.getValue()); + + newWatcher.setObject(obj, watchableObject.getValue()); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return newWatcher; + } + + public static byte getPitch(DisguiseType disguiseType, EntityType entityType, byte value) { + return getPitch(disguiseType, getPitch(DisguiseType.getType(entityType), value)); + } + + public static byte getPitch(DisguiseType disguiseType, DisguiseType entityType, byte value) { + return getPitch(disguiseType, getPitch(entityType, value)); + } + + public static byte getPitch(DisguiseType disguiseType, byte value) { + if (disguiseType.isMisc()) { + return (byte) -value; + } + + switch (disguiseType) { + case PHANTOM: + return (byte) -value; + default: + return value; + } + } + + public static byte getYaw(DisguiseType disguiseType, EntityType entityType, byte value) { + return getYaw(disguiseType, getYaw(DisguiseType.getType(entityType), value)); + } + + public static byte getYaw(DisguiseType disguiseType, DisguiseType entityType, byte value) { + return getYaw(disguiseType, getYaw(entityType, value)); + } + + /** + * Add the yaw for the disguises + */ + public static byte getYaw(DisguiseType disguiseType, byte value) { + switch (disguiseType) { + case MINECART: + case MINECART_CHEST: + case MINECART_COMMAND: + case MINECART_FURNACE: + case MINECART_HOPPER: + case MINECART_MOB_SPAWNER: + case MINECART_TNT: + return (byte) (value + 64); + case BOAT: + case ENDER_DRAGON: + case WITHER_SKULL: + return (byte) (value - 128); + case ARROW: + case TIPPED_ARROW: + case SPECTRAL_ARROW: + return (byte) -value; + case PAINTING: + case ITEM_FRAME: + return (byte) -(value + 128); + default: + if (disguiseType.isMisc() && disguiseType != DisguiseType.ARMOR_STAND) { + return (byte) (value - 64); + } + + return value; + } + } + + /** + * Get the Y level to add to the disguise for realism. + */ + public static double getYModifier(Entity entity, Disguise disguise) { + double yMod = 0; + + if ((disguise.getType() != DisguiseType.PLAYER || !((PlayerWatcher) disguise.getWatcher()).isSleeping()) && + entity.getType() == EntityType.DROPPED_ITEM) { + yMod -= 0.13; + } + + switch (disguise.getType()) { + case BAT: + if (entity instanceof LivingEntity) + return yMod + ((LivingEntity) entity).getEyeHeight(); + case MINECART: + case MINECART_COMMAND: + case MINECART_CHEST: + case MINECART_FURNACE: + case MINECART_HOPPER: + case MINECART_MOB_SPAWNER: + case MINECART_TNT: + switch (entity.getType()) { + case MINECART: + case MINECART_CHEST: + case MINECART_FURNACE: + case MINECART_HOPPER: + case MINECART_MOB_SPAWNER: + case MINECART_TNT: + return yMod; + default: + return yMod + 0.4; + } + case TIPPED_ARROW: + case SPECTRAL_ARROW: + case BOAT: + case EGG: + case ENDER_PEARL: + case ENDER_SIGNAL: + case FIREWORK: + case PAINTING: + case SMALL_FIREBALL: + case SNOWBALL: + case SPLASH_POTION: + case THROWN_EXP_BOTTLE: + case WITHER_SKULL: + return yMod + 0.7; + case PLAYER: + if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + return yMod + 0.35; + } + + break; + case DROPPED_ITEM: + return yMod + 0.13; + default: + break; + } + return yMod; + } } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java b/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java index aa7eccbc..a52cdc43 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java @@ -1,5 +1,6 @@ package me.libraryaddict.disguise.utilities; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/main/java/me/libraryaddict/disguise/utilities/PacketsManager.java deleted file mode 100644 index 6e388e53..00000000 --- a/src/main/java/me/libraryaddict/disguise/utilities/PacketsManager.java +++ /dev/null @@ -1,1154 +0,0 @@ -package me.libraryaddict.disguise.utilities; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Play; -import com.comphenix.protocol.PacketType.Play.Server; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketListener; -import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.WrappedAttribute; -import com.comphenix.protocol.wrappers.WrappedAttribute.Builder; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; -import com.comphenix.protocol.wrappers.WrappedGameProfile; -import com.comphenix.protocol.wrappers.WrappedWatchableObject; -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.DisguiseConfig; -import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.disguisetypes.*; -import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher; -import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; -import me.libraryaddict.disguise.utilities.packetlisteners.*; -import org.bukkit.Art; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.*; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; -import org.bukkit.util.Vector; - -import java.lang.reflect.InvocationTargetException; -import java.util.*; -import java.util.Map.Entry; - -public class PacketsManager { - public static class LibsPackets { - private ArrayList packets = new ArrayList<>(); - private HashMap> delayedPackets = new HashMap<>(); - private boolean isSpawnPacket; - private Disguise disguise; - private boolean doNothing; - - public void setUnhandled() { - doNothing = true; - } - - public boolean isUnhandled() { - return doNothing; - } - - private LibsPackets(Disguise disguise) { - this.disguise = disguise; - } - - public Disguise getDisguise() { - return disguise; - } - - public void setSpawnPacketCheck(PacketType type) { - isSpawnPacket = type.name().contains("SPAWN") && type.name().contains("ENTITY"); - } - - public void addPacket(PacketContainer packet) { - packets.add(packet); - } - - public void addDelayedPacket(PacketContainer packet) { - addDelayedPacket(packet, 2); - } - - public void clear() { - getPackets().clear(); - } - - public void addDelayedPacket(PacketContainer packet, int ticksDelayed) { - if (!delayedPackets.containsKey(ticksDelayed)) - delayedPackets.put(ticksDelayed, new ArrayList<>()); - - delayedPackets.get(ticksDelayed).add(packet); - } - - public ArrayList getPackets() { - return packets; - } - - public Collection> getDelayedPackets() { - return delayedPackets.values(); - } - - public void sendDelayed(final Player observer) { - for (final Entry> entry : delayedPackets.entrySet()) { - Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() { - public void run() { - try { - for (PacketContainer packet : entry.getValue()) { - ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); - } - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - - if (isSpawnPacket) { - PacketsManager.removeCancel(disguise, observer); - } - } - }, entry.getKey()); - } - } - } - - private static PacketListener clientInteractEntityListener; - private static PacketListener inventoryListener; - private static boolean inventoryModifierEnabled; - private static LibsDisguises libsDisguises; - private static PacketListener mainListener; - private static PacketListener soundsListener; - private static boolean soundsListenerEnabled; - private static PacketListener viewDisguisesListener; - private static boolean viewDisguisesListenerEnabled; - private static HashMap> cancelMeta = new HashMap<>(); - - 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. - - clientInteractEntityListener = new PacketListenerClientInteract(libsDisguises); - PacketListener tabListListener = new PacketListenerTabList(libsDisguises); - - ProtocolLibrary.getProtocolManager().addPacketListener(clientInteractEntityListener); - ProtocolLibrary.getProtocolManager().addPacketListener(tabListListener); - - // Now I call this and the main listener is registered! - setupMainPacketsListener(); - } - - public static void removeCancel(Disguise disguise, Player observer) { - ArrayList cancel; - - if ((cancel = cancelMeta.get(disguise)) == null) - return; - - cancel.remove(observer.getUniqueId()); - - if (!cancel.isEmpty()) - return; - - cancelMeta.remove(disguise); - } - - /** - * Construct the packets I need to spawn in the disguise - */ - private static LibsPackets constructSpawnPackets(final Player observer, LibsPackets packets, - Entity disguisedEntity) { - Disguise disguise = packets.getDisguise(); - - if (disguise.getEntity() == null) { - disguise.setEntity(disguisedEntity); - } - - // This sends the armor packets so that the player isn't naked. - // Please note it only sends the packets that wouldn't be sent normally - if (DisguiseConfig.isEquipmentPacketsEnabled()) { - for (EquipmentSlot slot : EquipmentSlot.values()) { - ItemStack itemstack = disguise.getWatcher().getItemStack(slot); - - if (itemstack == null || itemstack.getType() == Material.AIR) { - continue; - } - - if (disguisedEntity instanceof LivingEntity) { - ItemStack item = ReflectionManager.getEquipment(slot, disguisedEntity); - - if (item != null && item.getType() != Material.AIR) { - continue; - } - } - - PacketContainer packet = new PacketContainer(Server.ENTITY_EQUIPMENT); - - StructureModifier mods = packet.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, ReflectionManager.createEnumItemSlot(slot)); - mods.write(2, ReflectionManager.getNmsItem(itemstack)); - - packets.addDelayedPacket(packet); - } - } - - if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) { - if (disguise.getWatcher() instanceof LivingWatcher) { - - ArrayList attributes = new ArrayList<>(); - - Builder builder = WrappedAttribute.newBuilder().attributeKey("generic.maxHealth"); - - if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) { - builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); - } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity() && - disguisedEntity instanceof Damageable) { - builder.baseValue(((Damageable) disguisedEntity).getMaxHealth()); - } else { - builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); - } - - PacketContainer packet = new PacketContainer(Server.UPDATE_ATTRIBUTES); - - builder.packet(packet); - - attributes.add(builder.build()); - - packet.getIntegers().write(0, disguisedEntity.getEntityId()); - packet.getAttributeCollectionModifier().write(0, attributes); - - packets.addPacket(packet); - } - } - - Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguisedEntity, disguise), 0); - - 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) { - PacketContainer spawnOrb = new PacketContainer(Server.SPAWN_ENTITY_EXPERIENCE_ORB); - packets.addPacket(spawnOrb); - - StructureModifier mods = spawnOrb.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, loc.getX()); - mods.write(2, loc.getY() + 0.06); - mods.write(3, loc.getZ()); - mods.write(4, 1); - } else if (disguise.getType() == DisguiseType.PAINTING) { - PacketContainer spawnPainting = new PacketContainer(Server.SPAWN_ENTITY_PAINTING); - packets.addPacket(spawnPainting); - - StructureModifier mods = spawnPainting.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, disguisedEntity.getUniqueId()); - mods.write(2, ReflectionManager.getBlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); - mods.write(3, ReflectionManager.getEnumDirection(((int) loc.getYaw()) % 4)); - - int id = ((MiscDisguise) disguise).getData(); - - mods.write(4, ReflectionManager.getEnumArt(Art.values()[id])); - - // Make the teleport packet to make it visible.. - PacketContainer teleportPainting = new PacketContainer(Server.ENTITY_TELEPORT); - packets.addPacket(teleportPainting); - - mods = teleportPainting.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, loc.getX()); - mods.write(2, loc.getY()); - mods.write(3, loc.getZ()); - mods.write(4, yaw); - mods.write(5, pitch); - } else if (disguise.getType().isPlayer()) { - PlayerDisguise playerDisguise = (PlayerDisguise) disguise; - - String name = playerDisguise.getName(); - WrappedGameProfile gameProfile = playerDisguise.getGameProfile(); - - int entityId = disguisedEntity.getEntityId(); - - // Send player info along with the disguise - PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO); - - if (!((PlayerDisguise) disguise).isDisplayedInTab()) { - // Add player to the list, necessary to spawn them - sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0)); - - List playerList = Collections - .singletonList(ReflectionManager.getPlayerInfoData(sendTab.getHandle(), gameProfile)); - sendTab.getModifier().write(1, playerList); - - packets.addPacket(sendTab); - } - - // Spawn the player - PacketContainer spawnPlayer = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN); - - spawnPlayer.getIntegers().write(0, entityId); // Id - spawnPlayer.getModifier().write(1, gameProfile.getUUID()); - - Location spawnAt = disguisedEntity.getLocation(); - - boolean selfDisguise = observer == disguisedEntity; - - WrappedDataWatcher newWatcher; - - if (selfDisguise) { - newWatcher = createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), - disguise.getWatcher()); - } else { - newWatcher = new WrappedDataWatcher(); - - spawnAt = observer.getLocation(); - spawnAt.add(spawnAt.getDirection().normalize().multiply(20)); - } - - // Spawn him in front of the observer - StructureModifier doubles = spawnPlayer.getDoubles(); - doubles.write(0, spawnAt.getX()); - doubles.write(1, spawnAt.getY()); - doubles.write(2, spawnAt.getZ()); - - StructureModifier bytes = spawnPlayer.getBytes(); - bytes.write(0, yaw); - bytes.write(1, pitch); - - spawnPlayer.getDataWatcherModifier().write(0, newWatcher); - - // Make him invisible - newWatcher - .setObject(new WrappedDataWatcherObject(MetaIndex.ENTITY_META.getIndex(), Registry.get(Byte.class)), - (byte) 32); - - packets.addPacket(spawnPlayer); - - if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { - PacketContainer[] bedPackets = DisguiseUtilities.getBedPackets( - loc.clone().subtract(0, PacketsManager.getYModifier(disguisedEntity, disguise), 0), - observer.getLocation(), ((PlayerDisguise) disguise)); - - for (PacketContainer packet : bedPackets) { - packets.addPacket(packet); - } - } else if (!selfDisguise) { - // Teleport the player back to where he's supposed to be - PacketContainer teleportPacket = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); - - doubles = teleportPacket.getDoubles(); - - teleportPacket.getIntegers().write(0, entityId); // Id - doubles.write(0, loc.getX()); - doubles.write(1, loc.getY()); - doubles.write(2, loc.getZ()); - - bytes = teleportPacket.getBytes(); - bytes.write(0, yaw); - bytes.write(1, pitch); - - packets.addPacket(teleportPacket); - } - - if (!selfDisguise) { - // Send a metadata packet - PacketContainer metaPacket = new PacketContainer(Play.Server.ENTITY_METADATA); - - newWatcher = createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), - disguise.getWatcher()); - - metaPacket.getIntegers().write(0, entityId); // Id - metaPacket.getWatchableCollectionModifier().write(0, newWatcher.getWatchableObjects()); - - if (!cancelMeta.containsKey(disguise)) - cancelMeta.put(disguise, new ArrayList()); - - cancelMeta.get(disguise).add(observer.getUniqueId()); - - packets.addDelayedPacket(metaPacket, 4); - } - - // Remove player from the list - PacketContainer deleteTab = sendTab.shallowClone(); - 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(); - - PacketContainer spawnEntity = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING); - packets.addPacket(spawnEntity); - - StructureModifier mods = spawnEntity.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, disguisedEntity.getUniqueId()); - mods.write(2, disguise.getType().getTypeId()); - - // region Vector calculations - double d1 = 3.9D; - double d2 = vec.getX(); - double d3 = vec.getY(); - double d4 = vec.getZ(); - if (d2 < -d1) - d2 = -d1; - if (d3 < -d1) - d3 = -d1; - if (d4 < -d1) - d4 = -d1; - if (d2 > d1) - d2 = d1; - if (d3 > d1) - d3 = d1; - if (d4 > d1) - d4 = d1; - // endregion - - mods.write(3, loc.getX()); - mods.write(4, loc.getY()); - mods.write(5, loc.getZ()); - mods.write(6, (int) (d2 * 8000.0D)); - mods.write(7, (int) (d3 * 8000.0D)); - mods.write(8, (int) (d4 * 8000.0D)); - mods.write(9, yaw); - mods.write(10, pitch); - mods.write(11, yaw); - - spawnEntity.getDataWatcherModifier().write(0, - createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); - } else if (disguise.getType().isMisc()) { - int objectId = disguise.getType().getObjectId(); - int data = ((MiscDisguise) disguise).getData(); - - if (disguise.getType() == DisguiseType.FALLING_BLOCK) { - ItemStack block = ((FallingBlockWatcher) disguise.getWatcher()).getBlock(); - - data = ReflectionManager.getCombinedIdByItemStack(block); - } else if (disguise.getType() == DisguiseType.FISHING_HOOK && data == -1) { - // If the MiscDisguise data isn't set. Then no entity id was provided, so default to the owners - // entity id - data = observer.getEntityId(); - } else if (disguise.getType() == DisguiseType.ITEM_FRAME) { - data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4; - } - - Object nmsEntity = ReflectionManager.getNmsEntity(disguisedEntity); - - PacketContainer spawnEntity = ProtocolLibrary.getProtocolManager() - .createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, nmsEntity, objectId, data) - .createPacket(nmsEntity, objectId, data); - packets.addPacket(spawnEntity); - - // If it's not the same type, then highly likely they have different velocity settings which we'd want to - // cancel - if (DisguiseType.getType(disguisedEntity) != disguise.getType()) { - StructureModifier ints = spawnEntity.getIntegers(); - - ints.write(1, 0); - ints.write(2, 0); - ints.write(3, 0); - } - - spawnEntity.getModifier().write(8, pitch); - spawnEntity.getModifier().write(9, yaw); - - if (disguise.getType() == DisguiseType.ITEM_FRAME) { - if (data % 2 == 0) { - spawnEntity.getModifier().write(4, loc.getZ() + (data == 0 ? -1 : 1)); - } else { - spawnEntity.getModifier().write(2, loc.getX() + (data == 3 ? -1 : 1)); - } - } - } - - if (packets.getPackets().size() <= 1 || disguise.isPlayerDisguise()) { - PacketContainer rotateHead = new PacketContainer(Server.ENTITY_HEAD_ROTATION); - packets.addPacket(rotateHead); - - StructureModifier mods = rotateHead.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, yaw); - } - - if (disguise.getType() == DisguiseType.EVOKER_FANGS) { - PacketContainer newPacket = new PacketContainer(Server.ENTITY_STATUS); - - StructureModifier mods = newPacket.getModifier(); - mods.write(0, disguise.getEntity().getEntityId()); - mods.write(1, (byte) 4); - - packets.addPacket(newPacket); - } - - return packets; - } - - /** - * Create a new datawatcher but with the 'correct' values - */ - private static WrappedDataWatcher createDataWatcher(WrappedDataWatcher watcher, FlagWatcher flagWatcher) { - WrappedDataWatcher newWatcher = new WrappedDataWatcher(); - - try { - List list = - DisguiseConfig.isMetadataPacketsEnabled() ? flagWatcher.convert(watcher.getWatchableObjects()) : - flagWatcher.getWatchableObjects(); - - for (WrappedWatchableObject watchableObject : list) { - if (watchableObject == null) - continue; - - if (watchableObject.getValue() == null) - continue; - - WrappedDataWatcherObject obj = ReflectionManager - .createDataWatcherObject(watchableObject.getIndex(), watchableObject.getValue()); - - newWatcher.setObject(obj, watchableObject.getValue()); - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return newWatcher; - } - - public static byte getPitch(DisguiseType disguiseType, DisguiseType entityType, byte value) { - return getPitch(disguiseType, getPitch(entityType, value)); - } - - private static byte getPitch(DisguiseType disguiseType, byte value) { - switch (disguiseType) { - case MINECART: - case MINECART_CHEST: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - case PHANTOM: - return (byte) -value; - default: - return value; - } - } - - /** - * Add the yaw for the disguises - */ - public static byte getYaw(DisguiseType disguiseType, EntityType entityType, byte value) { - switch (disguiseType) { - case MINECART: - case MINECART_CHEST: - case MINECART_COMMAND: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - value += 64; - break; - case BOAT: - case ENDER_DRAGON: - case WITHER_SKULL: - value -= 128; - break; - case ARROW: - case TIPPED_ARROW: - case SPECTRAL_ARROW: - value = (byte) -value; - break; - case PAINTING: - case ITEM_FRAME: - value = (byte) -(value + 128); - break; - default: - if (disguiseType.isMisc() && disguiseType != DisguiseType.ARMOR_STAND) { - value -= 64; - } - - break; - } - switch (entityType) { - case MINECART: - case MINECART_CHEST: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - value -= 64; - break; - case ENDER_DRAGON: - case WITHER_SKULL: - value += 128; - break; - case ARROW: - value = (byte) -value; - break; - case PAINTING: - case ITEM_FRAME: - value = (byte) -(value - 128); - break; - default: - if (!entityType.isAlive()) { - value += 64; - } - - break; - } - - return value; - } - - /** - * Get the Y level to add to the disguise for realism. - */ - public static double getYModifier(Entity entity, Disguise disguise) { - double yMod = 0; - - if ((disguise.getType() != DisguiseType.PLAYER || !((PlayerWatcher) disguise.getWatcher()).isSleeping()) && - entity.getType() == EntityType.DROPPED_ITEM) { - yMod -= 0.13; - } - - switch (disguise.getType()) { - case BAT: - if (entity instanceof LivingEntity) - return yMod + ((LivingEntity) entity).getEyeHeight(); - case MINECART: - case MINECART_COMMAND: - case MINECART_CHEST: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - switch (entity.getType()) { - case MINECART: - case MINECART_CHEST: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - return yMod; - default: - return yMod + 0.4; - } - case TIPPED_ARROW: - case SPECTRAL_ARROW: - case BOAT: - case EGG: - case ENDER_PEARL: - case ENDER_SIGNAL: - case FIREWORK: - case PAINTING: - case SMALL_FIREBALL: - case SNOWBALL: - case SPLASH_POTION: - case THROWN_EXP_BOTTLE: - case WITHER_SKULL: - return yMod + 0.7; - case PLAYER: - if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { - return yMod + 0.35; - } - - break; - case DROPPED_ITEM: - return yMod + 0.13; - default: - break; - } - return yMod; - } - - /** - * Creates the packet listeners - */ - public static void init(LibsDisguises plugin) { - libsDisguises = plugin; - soundsListener = new PacketListenerSounds(libsDisguises); - - // Self disguise (/vsd) listener - viewDisguisesListener = new PacketListenerViewSelfDisguise(libsDisguises); - - inventoryListener = new PacketListenerInventory(libsDisguises); - } - - public static boolean isHearDisguisesEnabled() { - return soundsListenerEnabled; - } - - public static boolean isInventoryListenerEnabled() { - return inventoryModifierEnabled; - } - - public static boolean isViewDisguisesListenerEnabled() { - return viewDisguisesListenerEnabled; - } - - public static void setHearDisguisesListener(boolean enabled) { - if (soundsListenerEnabled != enabled) { - soundsListenerEnabled = enabled; - - if (soundsListenerEnabled) { - ProtocolLibrary.getProtocolManager().addPacketListener(soundsListener); - } else { - ProtocolLibrary.getProtocolManager().removePacketListener(soundsListener); - } - } - } - - public static void setInventoryListenerEnabled(boolean enabled) { - if (inventoryModifierEnabled != enabled) { - inventoryModifierEnabled = enabled; - - if (inventoryModifierEnabled) { - ProtocolLibrary.getProtocolManager().addPacketListener(inventoryListener); - } else { - ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListener); - } - - for (Player player : Bukkit.getOnlinePlayers()) { - Disguise disguise = DisguiseAPI.getDisguise(player, player); - - if (disguise != null) { - if (viewDisguisesListenerEnabled && disguise.isSelfDisguiseVisible() && - (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { - player.updateInventory(); - } - } - } - } - } - - public static void setupMainPacketsListener() { - if (clientInteractEntityListener != null) { - if (mainListener != null) { - ProtocolLibrary.getProtocolManager().removePacketListener(mainListener); - } - - ArrayList packetsToListen = new ArrayList<>(); - // Add spawn packets - { - packetsToListen.add(Server.NAMED_ENTITY_SPAWN); - packetsToListen.add(Server.SPAWN_ENTITY_EXPERIENCE_ORB); - packetsToListen.add(Server.SPAWN_ENTITY); - packetsToListen.add(Server.SPAWN_ENTITY_LIVING); - packetsToListen.add(Server.SPAWN_ENTITY_PAINTING); - } - - // Add packets that always need to be enabled to ensure safety - { - packetsToListen.add(Server.ENTITY_METADATA); - } - - if (DisguiseConfig.isCollectPacketsEnabled()) { - packetsToListen.add(Server.COLLECT); - } - - if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) { - packetsToListen.add(Server.UPDATE_ATTRIBUTES); - } - - // The bed packet. - if (DisguiseConfig.isBedPacketsEnabled()) { - packetsToListen.add(Server.BED); - } - - // Add movement packets - if (DisguiseConfig.isMovementPacketsEnabled()) { - packetsToListen.add(Server.ENTITY_LOOK); - packetsToListen.add(Server.REL_ENTITY_MOVE_LOOK); - packetsToListen.add(Server.ENTITY_HEAD_ROTATION); - packetsToListen.add(Server.ENTITY_TELEPORT); - packetsToListen.add(Server.REL_ENTITY_MOVE); - packetsToListen.add(Server.ENTITY_VELOCITY); - } - - // Add equipment packet - if (DisguiseConfig.isEquipmentPacketsEnabled()) { - packetsToListen.add(Server.ENTITY_EQUIPMENT); - } - - // Add the packet that ensures if they are sleeping or not - if (DisguiseConfig.isAnimationPacketsEnabled()) { - packetsToListen.add(Server.ANIMATION); - } - - // Add the packet that makes sure that entities with armor do not send unpickupable armor on death - if (DisguiseConfig.isEntityStatusPacketsEnabled()) { - packetsToListen.add(Server.ENTITY_STATUS); - } - - mainListener = new PacketListenerMain(libsDisguises, packetsToListen); - - ProtocolLibrary.getProtocolManager().addPacketListener(mainListener); - } - } - - public static void setViewDisguisesListener(boolean enabled) { - if (viewDisguisesListenerEnabled != enabled) { - viewDisguisesListenerEnabled = enabled; - - if (viewDisguisesListenerEnabled) { - ProtocolLibrary.getProtocolManager().addPacketListener(viewDisguisesListener); - } else { - ProtocolLibrary.getProtocolManager().removePacketListener(viewDisguisesListener); - } - - for (Player player : Bukkit.getOnlinePlayers()) { - Disguise disguise = DisguiseAPI.getDisguise(player, player); - - if (disguise != null) { - if (disguise.isSelfDisguiseVisible()) { - if (enabled) { - DisguiseUtilities.setupFakeDisguise(disguise); - } else { - DisguiseUtilities.removeSelfDisguise(player); - } - - if (inventoryModifierEnabled && - (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { - player.updateInventory(); - } - } - } - } - } - } - - /** - * Transform the packet magically into the one I have always dreamed off. My true luv!!! This will return null if - * its not - * transformed - */ - public static LibsPackets transformPacket(PacketContainer sentPacket, Disguise disguise, Player observer, - Entity entity) { - LibsPackets packets = new LibsPackets(disguise); - - try { - packets.addPacket(sentPacket); - - // This packet sends attributes - if (sentPacket.getType() == Server.UPDATE_ATTRIBUTES) { - if (disguise.isMiscDisguise()) { - packets.clear(); - } else { - List attributes = new ArrayList<>(); - - for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) { - if (attribute.getAttributeKey().equals("generic.maxHealth")) { - packets.clear(); - - PacketContainer updateAttributes = new PacketContainer(Server.UPDATE_ATTRIBUTES); - packets.addPacket(updateAttributes); - - Builder builder; - - if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) { - builder = WrappedAttribute.newBuilder(); - builder.attributeKey("generic.maxHealth"); - builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); - } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) { - builder = WrappedAttribute.newBuilder(attribute); - } else { - builder = WrappedAttribute.newBuilder(); - builder.attributeKey("generic.maxHealth"); - builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); - } - - builder.packet(updateAttributes); - - attributes.add(builder.build()); - break; - } - } - - if (!attributes.isEmpty()) { - packets.getPackets().get(0).getIntegers().write(0, entity.getEntityId()); - packets.getPackets().get(0).getAttributeCollectionModifier().write(0, attributes); - } else { - packets.clear(); - } - } - } - - // Else if the packet is sending entity metadata - else if (sentPacket.getType() == Server.ENTITY_METADATA) { - packets.clear(); - - if (DisguiseConfig.isMetadataPacketsEnabled() && (!cancelMeta.containsKey(disguise) || - !cancelMeta.get(disguise).contains(observer.getUniqueId()))) { - List watchableObjects = disguise.getWatcher() - .convert(sentPacket.getWatchableCollectionModifier().read(0)); - - PacketContainer metaPacket = new PacketContainer(Server.ENTITY_METADATA); - - packets.addPacket(metaPacket); - - StructureModifier newMods = metaPacket.getModifier(); - - newMods.write(0, entity.getEntityId()); - - metaPacket.getWatchableCollectionModifier().write(0, watchableObjects); - } - } - - // Else if the packet is spawning.. - else if (sentPacket.getType() == Server.NAMED_ENTITY_SPAWN || - sentPacket.getType() == Server.SPAWN_ENTITY_LIVING || - sentPacket.getType() == Server.SPAWN_ENTITY_EXPERIENCE_ORB || - sentPacket.getType() == Server.SPAWN_ENTITY || - sentPacket.getType() == Server.SPAWN_ENTITY_PAINTING) { - packets.clear(); - - constructSpawnPackets(observer, packets, entity); - } - - // Else if the disguise is attempting to send players a forbidden packet - else if (sentPacket.getType() == Server.ANIMATION) { - if (disguise.getType().isMisc() || (sentPacket.getIntegers().read(1) == 2 && - (!disguise.getType().isPlayer() || (DisguiseConfig.isBedPacketsEnabled() && - ((PlayerWatcher) disguise.getWatcher()).isSleeping())))) { - packets.clear(); - } - } - - // Else if the disguise is collecting stuff - else if (sentPacket.getType() == Server.COLLECT) { - if (disguise.getType().isMisc()) { - packets.clear(); - } else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer() && - ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { - PacketContainer newPacket = new PacketContainer(Server.ANIMATION); - - StructureModifier mods = newPacket.getIntegers(); - mods.write(0, disguise.getEntity().getEntityId()); - mods.write(1, 3); - - packets.clear(); - - packets.addPacket(newPacket); - packets.addPacket(sentPacket); - } - } - - // Else if the disguise is moving. - else if (sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK || - sentPacket.getType() == Server.ENTITY_LOOK || sentPacket.getType() == Server.ENTITY_TELEPORT || - sentPacket.getType() == Server.REL_ENTITY_MOVE) { - if (disguise.getType() == DisguiseType.RABBIT && (sentPacket.getType() == Server.REL_ENTITY_MOVE || - sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK)) { - // When did the rabbit disguise last hop - long lastHop = 999999; - - // If hop meta exists, set the last hop time - if (!entity.getMetadata("LibsRabbitHop").isEmpty()) { - // Last hop was 3 minutes ago, so subtract current time with the last hop time and get 3 - // minutes ago in milliseconds - lastHop = System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong(); - } - - // If last hop was less than 0.1 or more than 0.5 seconds ago - if (lastHop < 100 || lastHop > 500) { - if (lastHop > 500) { - entity.removeMetadata("LibsRabbitHop", libsDisguises); - entity.setMetadata("LibsRabbitHop", - new FixedMetadataValue(libsDisguises, System.currentTimeMillis())); - } - - PacketContainer statusPacket = new PacketContainer(Server.ENTITY_STATUS); - packets.addPacket(statusPacket); - - statusPacket.getIntegers().write(0, entity.getEntityId()); - statusPacket.getBytes().write(0, (byte) 1); - } - } - - // Stop wither skulls from looking - if (sentPacket.getType() == Server.ENTITY_LOOK && disguise.getType() == DisguiseType.WITHER_SKULL) { - packets.clear(); - } else if (sentPacket.getType() != Server.REL_ENTITY_MOVE) { - packets.clear(); - - PacketContainer movePacket = sentPacket.shallowClone(); - - packets.addPacket(movePacket); - - StructureModifier bytes = movePacket.getBytes(); - - byte yawValue = bytes.read(0); - byte pitchValue = bytes.read(1); - - bytes.write(0, getYaw(disguise.getType(), entity.getType(), yawValue)); - bytes.write(1, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue)); - - if (sentPacket.getType() == Server.ENTITY_TELEPORT && - disguise.getType() == DisguiseType.ITEM_FRAME) { - StructureModifier doubles = movePacket.getDoubles(); - - Location loc = entity.getLocation(); - - double data = (((loc.getYaw() % 360) + 720 + 45) / 90) % 4; - - if (data % 2 == 0) { - if (data % 2 == 0) { - doubles.write(3, loc.getZ()); - } else { - doubles.write(1, loc.getZ()); - } - } - - double y = getYModifier(entity, disguise); - - if (y != 0) { - doubles.write(2, doubles.read(2) + y); - } - } - } - } - - // Else if the disguise is updating equipment - else if (sentPacket.getType() == Server.ENTITY_EQUIPMENT) { - EquipmentSlot slot = ReflectionManager - .createEquipmentSlot(packets.getPackets().get(0).getModifier().read(1)); - - org.bukkit.inventory.ItemStack itemStack = disguise.getWatcher().getItemStack(slot); - - if (itemStack != null) { - packets.clear(); - - PacketContainer equipPacket = sentPacket.shallowClone(); - - packets.addPacket(equipPacket); - - equipPacket.getModifier().write(2, - ReflectionManager.getNmsItem(itemStack.getType() == Material.AIR ? null : itemStack)); - } - - if (disguise.getWatcher().isRightClicking() && slot == EquipmentSlot.HAND) { - ItemStack heldItem = packets.getPackets().get(0).getItemModifier().read(0); - - if (heldItem != null && heldItem.getType() != Material.AIR) { - // Convert the datawatcher - List list = new ArrayList<>(); - - if (DisguiseConfig.isMetadataPacketsEnabled()) { - WrappedWatchableObject watch = ReflectionManager - .createWatchable(0, WrappedDataWatcher.getEntityWatcher(entity).getByte(0)); - - if (watch != null) - list.add(watch); - - list = disguise.getWatcher().convert(list); - } else { - for (WrappedWatchableObject obj : disguise.getWatcher().getWatchableObjects()) { - if (obj.getIndex() == 0) { - list.add(obj); - break; - } - } - } - - // Construct the packets to return - PacketContainer packetBlock = new PacketContainer(Server.ENTITY_METADATA); - - packetBlock.getModifier().write(0, entity.getEntityId()); - packetBlock.getWatchableCollectionModifier().write(0, list); - - PacketContainer packetUnblock = packetBlock.deepClone(); - // Make a packet to send the 'unblock' - for (WrappedWatchableObject watcher : packetUnblock.getWatchableCollectionModifier().read(0)) { - watcher.setValue((byte) ((byte) watcher.getValue() & ~(1 << 4))); - } - - // Send the unblock before the itemstack change so that the 2nd metadata packet works. Why? - // Scheduler - // delay. - - PacketContainer packet1 = packets.getPackets().get(0); - - packets.clear(); - - packets.addPacket(packetUnblock); - packets.addPacket(packet1); - packets.addPacket(packetBlock); - // Silly mojang made the right clicking datawatcher value only valid for one use. So I have - // to reset - // it. - } - } - } - - // If the entity is going into a bed, stop everything but players from doing this - else if (sentPacket.getType() == Server.BED) { - if (!disguise.getType().isPlayer()) { - packets.clear(); - } - } - - // If the entity is updating their Facebook status, stop them from showing death - else if (sentPacket.getType() == Server.ENTITY_STATUS) { - if (packets.getPackets().get(0).getBytes().read(0) == (byte) 3) { - packets.clear(); - } - } - - // If the entity is sending velocity and its a falling block - else if (sentPacket.getType() == Server.ENTITY_VELOCITY) { - // If the disguise is a misc and the disguised is not the same type - if (disguise.getType().isMisc() && DisguiseType.getType(entity) != disguise.getType()) { - packets.clear(); - } - } - - // If the entity is rotating his head - else if (sentPacket.getType() == Server.ENTITY_HEAD_ROTATION) { - if (disguise.getType().isPlayer() && entity.getType() != EntityType.PLAYER) { - Location loc = entity.getLocation(); - - byte pitch = getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), - (byte) (int) (loc.getPitch() * 256.0F / 360.0F)); - byte yaw = getYaw(disguise.getType(), entity.getType(), sentPacket.getBytes().read(0)); - - PacketContainer rotation = new PacketContainer(Server.ENTITY_HEAD_ROTATION); - - StructureModifier mods = rotation.getModifier(); - - mods.write(0, entity.getEntityId()); - mods.write(1, yaw); - - PacketContainer look = new PacketContainer(Server.ENTITY_LOOK); - - look.getIntegers().write(0, entity.getEntityId()); - look.getBytes().write(0, yaw); - look.getBytes().write(1, pitch); - - packets.clear(); - - packets.addPacket(look); - packets.addPacket(rotation); - } - } else { - packets.setUnhandled(); - } - } - catch (Exception e) { - e.printStackTrace(); - } - - return packets; - } -} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/Metrics.java b/src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java similarity index 99% rename from src/main/java/me/libraryaddict/disguise/utilities/Metrics.java rename to src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java index 0daa4883..bcd4ad5f 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/Metrics.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java @@ -1,4 +1,4 @@ -package me.libraryaddict.disguise.utilities; +package me.libraryaddict.disguise.utilities.metrics; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java b/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java new file mode 100644 index 00000000..31ab345d --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java @@ -0,0 +1,232 @@ +package me.libraryaddict.disguise.utilities.metrics; + +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.LibsPremium; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class MetricsInitalizer { + private void infectWithMetrics() { + LibsDisguises plugin = LibsDisguises.getInstance(); + + String version = plugin.getDescription().getVersion(); + + // If a release build, attach build number + if (!plugin.isReleaseBuild() || !LibsPremium.isPremium()) { + version += "-"; + + // 9.7.0-SNAPSHOT-b30 + if (plugin.isNumberedBuild()) { + version += "b"; + } + // else 9.7.0-SNAPSHOT-unknown + + version += plugin.getBuildNo(); + } + + Metrics metrics = new Metrics(plugin, version); + final String premiumType; + + if (LibsPremium.isPremium()) { + if (plugin.isReleaseBuild()) { + premiumType = "Paid Plugin"; + } else { + premiumType = "Paid Builds"; + } + } else { + premiumType = "Free Builds"; + } + + metrics.addCustomChart(new Metrics.SimplePie("premium") { + @Override + public String getValue() { + return premiumType; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("translations") { + @Override + public String getValue() { + return LibsPremium.isPremium() && DisguiseConfig.isUseTranslations() ? "Yes" : "No"; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("custom_disguises") { + @Override + public String getValue() { + HashMap map = DisguiseConfig.getCustomDisguises(); + + return map.size() + (map.containsKey("libraryaddict") ? -1 : 0) > 0 ? "Yes" : "No"; + } + }); + + metrics.addCustomChart(new Metrics.MultiLineChart("disguised_entities") { + @Override + public HashMap getValues(HashMap hashMap) { + for (HashSet list : DisguiseUtilities.getDisguises().values()) { + for (Disguise disg : list) { + if (disg.getEntity() == null || !disg.isDisguiseInUse()) + continue; + + String name = disg.getEntity().getType().name(); + + hashMap.put(name, hashMap.containsKey(name) ? hashMap.get(name) + 1 : 1); + } + } + + return hashMap; + } + }); + + metrics.addCustomChart(new Metrics.MultiLineChart("disguises_used") { + @Override + public HashMap getValues(HashMap hashMap) { + for (HashSet list : DisguiseUtilities.getDisguises().values()) { + for (Disguise disg : list) { + if (disg.getEntity() == null || !disg.isDisguiseInUse()) + continue; + + String name = disg.getType().name(); + + hashMap.put(name, hashMap.containsKey(name) ? hashMap.get(name) + 1 : 1); + } + } + + return hashMap; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("disguised_using") { + @Override + public String getValue() { + if (DisguiseUtilities.isPluginsUsed()) { + if (DisguiseUtilities.isCommandsUsed()) { + return "Plugins and Commands"; + } + + return "Plugins"; + } else if (DisguiseUtilities.isCommandsUsed()) { + return "Commands"; + } + + return "Unknown"; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("active_disguises") { + @Override + public String getValue() { + int disgs = 0; + + for (HashSet set : DisguiseUtilities.getDisguises().values()) { + disgs += set.size(); + } + + if (disgs == 0) + return "0"; + if (disgs <= 5) + return "1 to 5"; + else if (disgs <= 15) + return "6 to 15"; + else if (disgs <= 30) + return "16 to 30"; + else if (disgs <= 60) + return "30 to 60"; + else if (disgs <= 100) + return "60 to 100"; + else if (disgs <= 200) + return "100 to 200"; + + return "More than 200"; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("self_disguises") { + @Override + public String getValue() { + return DisguiseConfig.isViewDisguises() ? "Yes" : "No"; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("commands") { + @Override + public String getValue() { + return DisguiseConfig.isDisableCommands() ? "Enabled" : "Disabled"; + } + }); + + metrics.addCustomChart(new Metrics.SimplePie("spigot") { + @Override + public String getValue() { + try { + Class.forName("org.spigotmc.SpigotConfig"); + return "Yes"; + } + catch (Exception ex) { + return "No"; + } + } + }); + + final boolean updates = plugin.getConfig().getBoolean("NotifyUpdate"); + + metrics.addCustomChart(new Metrics.SimplePie("updates") { + @Override + public String getValue() { + return updates ? "Enabled" : "Disabled"; + } + }); + + if (plugin.getBuildNo() != null) { + // Initalize final variable so we don't need to hold onto the plugin variable + final String buildNo = plugin.getBuildNo(); + + metrics.addCustomChart(new Metrics.SimplePie("build_number") { + @Override + public String getValue() { + return buildNo; + } + }); + } + + metrics.addCustomChart(new Metrics.SimplePie("targeted_disguises") { + /** + * Store value just to minimize amount of times it's called, and to persist even when not using anymore + */ + private boolean targetedDisguises; + + @Override + public String getValue() { + if (targetedDisguises) { + return "Yes"; + } + + Collection> list = DisguiseUtilities.getDisguises().values(); + + if (list.isEmpty()) + return "Unknown"; + + for (HashSet dList : list) { + for (TargetedDisguise disg : dList) { + if (disg.getObservers().isEmpty()) + continue; + + targetedDisguises = true; + return "Yes"; + } + } + + return "No"; + } + }); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/IPacketHandler.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/IPacketHandler.java new file mode 100644 index 00000000..d5407e50 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/IPacketHandler.java @@ -0,0 +1,16 @@ +package me.libraryaddict.disguise.utilities.packets; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public interface IPacketHandler { + PacketType[] getHandledPackets(); + + void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, Entity entity); +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java new file mode 100644 index 00000000..ec043366 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java @@ -0,0 +1,94 @@ +package me.libraryaddict.disguise.utilities.packets; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class LibsPackets { + private ArrayList packets = new ArrayList<>(); + private HashMap> delayedPackets = new HashMap<>(); + private boolean isSpawnPacket; + private Disguise disguise; + private boolean doNothing; + + public LibsPackets(Disguise disguise) { + this.disguise = disguise; + } + + public void setUnhandled() { + doNothing = true; + } + + public boolean isUnhandled() { + return doNothing; + } + + public Disguise getDisguise() { + return disguise; + } + + public void setSpawnPacketCheck(PacketType type) { + isSpawnPacket = type.name().contains("SPAWN") && type.name().contains("ENTITY"); + } + + public void addPacket(PacketContainer packet) { + packets.add(packet); + } + + public void addDelayedPacket(PacketContainer packet) { + addDelayedPacket(packet, 2); + } + + public void clear() { + getPackets().clear(); + } + + public void addDelayedPacket(PacketContainer packet, int ticksDelayed) { + if (!delayedPackets.containsKey(ticksDelayed)) + delayedPackets.put(ticksDelayed, new ArrayList<>()); + + delayedPackets.get(ticksDelayed).add(packet); + } + + public ArrayList getPackets() { + return packets; + } + + public Collection> getDelayedPackets() { + return delayedPackets.values(); + } + + public void sendDelayed(final Player observer) { + for (final Map.Entry> entry : delayedPackets.entrySet()) { + Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() { + public void run() { + try { + for (PacketContainer packet : entry.getValue()) { + ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); + } + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + + if (isSpawnPacket) { + PacketsManager.getPacketsHandler().removeCancel(disguise, observer); + } + } + }, entry.getKey()); + } + } +} \ No newline at end of file diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsHandler.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsHandler.java new file mode 100644 index 00000000..dd1b913a --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsHandler.java @@ -0,0 +1,98 @@ +package me.libraryaddict.disguise.utilities.packets; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.packets.packethandlers.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.UUID; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketsHandler { + private HashMap> cancelMeta = new HashMap<>(); + private Collection packetHandlers; + + public PacketsHandler() { + registerPacketHandlers(); + } + + private void registerPacketHandlers() { + packetHandlers = new ArrayList<>(); + + packetHandlers.add(new PacketHandlerAnimation()); + packetHandlers.add(new PacketHandlerAttributes()); + packetHandlers.add(new PacketHandlerBed()); + packetHandlers.add(new PacketHandlerCollect()); + packetHandlers.add(new PacketHandlerEntityStatus()); + packetHandlers.add(new PacketHandlerEquipment()); + packetHandlers.add(new PacketHandlerHeadRotation()); + packetHandlers.add(new PacketHandlerMetadata(this)); + packetHandlers.add(new PacketHandlerMovement()); + packetHandlers.add(new PacketHandlerSpawn(this)); + packetHandlers.add(new PacketHandlerVelocity()); + } + + public boolean isCancelMeta(Disguise disguise, Player observer) { + return cancelMeta.containsKey(disguise) && cancelMeta.get(disguise).contains(observer.getUniqueId()); + } + + public void addCancel(Disguise disguise, Player observer) { + if (!cancelMeta.containsKey(disguise)) { + cancelMeta.put(disguise, new ArrayList()); + } + + cancelMeta.get(disguise).add(observer.getUniqueId()); + } + + public void removeCancel(Disguise disguise, Player observer) { + ArrayList cancel; + + if ((cancel = cancelMeta.get(disguise)) == null) + return; + + cancel.remove(observer.getUniqueId()); + + if (!cancel.isEmpty()) + return; + + cancelMeta.remove(disguise); + } + + /** + * Transform the packet magically into the one I have always dreamed off. My true luv!!! This will return null if + * its not + * transformed + */ + public LibsPackets transformPacket(PacketContainer sentPacket, Disguise disguise, Player observer, Entity entity) { + LibsPackets packets = new LibsPackets(disguise); + + try { + packets.addPacket(sentPacket); + + for (IPacketHandler packetHandler : packetHandlers) { + for (PacketType packetType : packetHandler.getHandledPackets()) { + if (packetType != sentPacket.getType()) { + continue; + } + + packetHandler.handle(disguise, sentPacket, packets, observer, entity); + return packets; + } + } + + packets.setUnhandled(); + } + catch (Exception e) { + e.printStackTrace(); + } + + return packets; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsManager.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsManager.java new file mode 100644 index 00000000..e5ab2179 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/PacketsManager.java @@ -0,0 +1,205 @@ +package me.libraryaddict.disguise.utilities.packets; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.PacketType.Play.Server; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketListener; +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.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.packets.packetlisteners.*; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.ArrayList; + +public class PacketsManager { + private static PacketListener clientInteractEntityListener; + private static PacketListener inventoryListener; + private static boolean inventoryModifierEnabled; + private static LibsDisguises libsDisguises; + private static PacketListener mainListener; + private static PacketListener soundsListener; + private static boolean soundsListenerEnabled; + private static PacketListener viewDisguisesListener; + private static boolean viewDisguisesListenerEnabled; + private static PacketsHandler packetsHandler; + + 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. + + clientInteractEntityListener = new PacketListenerClientInteract(libsDisguises); + PacketListener tabListListener = new PacketListenerTabList(libsDisguises); + + ProtocolLibrary.getProtocolManager().addPacketListener(clientInteractEntityListener); + ProtocolLibrary.getProtocolManager().addPacketListener(tabListListener); + + // Now I call this and the main listener is registered! + setupMainPacketsListener(); + } + + /** + * Creates the packet listeners + */ + public static void init(LibsDisguises plugin) { + libsDisguises = plugin; + soundsListener = new PacketListenerSounds(libsDisguises); + + // Self disguise (/vsd) listener + viewDisguisesListener = new PacketListenerViewSelfDisguise(libsDisguises); + + inventoryListener = new PacketListenerInventory(libsDisguises); + packetsHandler = new PacketsHandler(); + } + + public static PacketsHandler getPacketsHandler() { + return packetsHandler; + } + + public static boolean isHearDisguisesEnabled() { + return soundsListenerEnabled; + } + + public static boolean isInventoryListenerEnabled() { + return inventoryModifierEnabled; + } + + public static boolean isViewDisguisesListenerEnabled() { + return viewDisguisesListenerEnabled; + } + + public static void setHearDisguisesListener(boolean enabled) { + if (soundsListenerEnabled != enabled) { + soundsListenerEnabled = enabled; + + if (soundsListenerEnabled) { + ProtocolLibrary.getProtocolManager().addPacketListener(soundsListener); + } else { + ProtocolLibrary.getProtocolManager().removePacketListener(soundsListener); + } + } + } + + public static void setInventoryListenerEnabled(boolean enabled) { + if (inventoryModifierEnabled != enabled) { + inventoryModifierEnabled = enabled; + + if (inventoryModifierEnabled) { + ProtocolLibrary.getProtocolManager().addPacketListener(inventoryListener); + } else { + ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListener); + } + + for (Player player : Bukkit.getOnlinePlayers()) { + Disguise disguise = DisguiseAPI.getDisguise(player, player); + + if (disguise != null) { + if (viewDisguisesListenerEnabled && disguise.isSelfDisguiseVisible() && + (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { + player.updateInventory(); + } + } + } + } + } + + public static void setupMainPacketsListener() { + if (clientInteractEntityListener != null) { + if (mainListener != null) { + ProtocolLibrary.getProtocolManager().removePacketListener(mainListener); + } + + ArrayList packetsToListen = new ArrayList<>(); + // Add spawn packets + { + packetsToListen.add(Server.NAMED_ENTITY_SPAWN); + packetsToListen.add(Server.SPAWN_ENTITY_EXPERIENCE_ORB); + packetsToListen.add(Server.SPAWN_ENTITY); + packetsToListen.add(Server.SPAWN_ENTITY_LIVING); + packetsToListen.add(Server.SPAWN_ENTITY_PAINTING); + } + + // Add packets that always need to be enabled to ensure safety + { + packetsToListen.add(Server.ENTITY_METADATA); + } + + if (DisguiseConfig.isCollectPacketsEnabled()) { + packetsToListen.add(Server.COLLECT); + } + + if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) { + packetsToListen.add(Server.UPDATE_ATTRIBUTES); + } + + // The bed packet. + if (DisguiseConfig.isBedPacketsEnabled()) { + packetsToListen.add(Server.BED); + } + + // Add movement packets + if (DisguiseConfig.isMovementPacketsEnabled()) { + packetsToListen.add(Server.ENTITY_LOOK); + packetsToListen.add(Server.REL_ENTITY_MOVE_LOOK); + packetsToListen.add(Server.ENTITY_HEAD_ROTATION); + packetsToListen.add(Server.ENTITY_TELEPORT); + packetsToListen.add(Server.REL_ENTITY_MOVE); + packetsToListen.add(Server.ENTITY_VELOCITY); + } + + // Add equipment packet + if (DisguiseConfig.isEquipmentPacketsEnabled()) { + packetsToListen.add(Server.ENTITY_EQUIPMENT); + } + + // Add the packet that ensures if they are sleeping or not + if (DisguiseConfig.isAnimationPacketsEnabled()) { + packetsToListen.add(Server.ANIMATION); + } + + // Add the packet that makes sure that entities with armor do not send unpickupable armor on death + if (DisguiseConfig.isEntityStatusPacketsEnabled()) { + packetsToListen.add(Server.ENTITY_STATUS); + } + + mainListener = new PacketListenerMain(libsDisguises, packetsToListen); + + ProtocolLibrary.getProtocolManager().addPacketListener(mainListener); + } + } + + public static void setViewDisguisesListener(boolean enabled) { + if (viewDisguisesListenerEnabled != enabled) { + viewDisguisesListenerEnabled = enabled; + + if (viewDisguisesListenerEnabled) { + ProtocolLibrary.getProtocolManager().addPacketListener(viewDisguisesListener); + } else { + ProtocolLibrary.getProtocolManager().removePacketListener(viewDisguisesListener); + } + + for (Player player : Bukkit.getOnlinePlayers()) { + Disguise disguise = DisguiseAPI.getDisguise(player, player); + + if (disguise != null) { + if (disguise.isSelfDisguiseVisible()) { + if (enabled) { + DisguiseUtilities.setupFakeDisguise(disguise); + } else { + DisguiseUtilities.removeSelfDisguise(player); + } + + if (inventoryModifierEnabled && + (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { + player.updateInventory(); + } + } + } + } + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAnimation.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAnimation.java new file mode 100644 index 00000000..d6a5128c --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAnimation.java @@ -0,0 +1,31 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerAnimation implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.ANIMATION}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + // Else if the disguise is attempting to send players a forbidden packet + if (disguise.getType().isMisc() || (sentPacket.getIntegers().read(1) == 2 && (!disguise.getType().isPlayer() || + (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping())))) { + packets.clear(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAttributes.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAttributes.java new file mode 100644 index 00000000..4f81d08d --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerAttributes.java @@ -0,0 +1,71 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedAttribute; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.reflection.DisguiseValues; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerAttributes implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.UPDATE_ATTRIBUTES}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + if (disguise.isMiscDisguise()) { + packets.clear(); + } else { + List attributes = new ArrayList<>(); + + for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) { + if (attribute.getAttributeKey().equals("generic.maxHealth")) { + packets.clear(); + + PacketContainer updateAttributes = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES); + packets.addPacket(updateAttributes); + + WrappedAttribute.Builder builder; + + if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) { + builder = WrappedAttribute.newBuilder(); + builder.attributeKey("generic.maxHealth"); + builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); + } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) { + builder = WrappedAttribute.newBuilder(attribute); + } else { + builder = WrappedAttribute.newBuilder(); + builder.attributeKey("generic.maxHealth"); + builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); + } + + builder.packet(updateAttributes); + + attributes.add(builder.build()); + break; + } + } + + if (!attributes.isEmpty()) { + packets.getPackets().get(0).getIntegers().write(0, entity.getEntityId()); + packets.getPackets().get(0).getAttributeCollectionModifier().write(0, attributes); + } else { + packets.clear(); + } + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerBed.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerBed.java new file mode 100644 index 00000000..3b19b4b2 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerBed.java @@ -0,0 +1,28 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerBed implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.BED}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + // If the entity is going into a bed, stop everything but players from doing this + if (!disguise.getType().isPlayer()) { + packets.clear(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerCollect.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerCollect.java new file mode 100644 index 00000000..a8380391 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerCollect.java @@ -0,0 +1,42 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +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.disguisetypes.watchers.PlayerWatcher; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerCollect implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.COLLECT}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + if (disguise.getType().isMisc()) { + packets.clear(); + } 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()); + mods.write(1, 3); + + packets.clear(); + + packets.addPacket(newPacket); + packets.addPacket(sentPacket); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEntityStatus.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEntityStatus.java new file mode 100644 index 00000000..a0fcad34 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEntityStatus.java @@ -0,0 +1,28 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerEntityStatus implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.ENTITY_STATUS}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + // If the entity is updating their status, stop them from showing death + if (packets.getPackets().get(0).getBytes().read(0) == (byte) 3) { + packets.clear(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEquipment.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEquipment.java new file mode 100644 index 00000000..22d9b103 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerEquipment.java @@ -0,0 +1,103 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.comphenix.protocol.wrappers.WrappedWatchableObject; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerEquipment implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.ENTITY_EQUIPMENT}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + // Else if the disguise is updating equipment + + EquipmentSlot slot = ReflectionManager.createEquipmentSlot(packets.getPackets().get(0).getModifier().read(1)); + + org.bukkit.inventory.ItemStack itemStack = disguise.getWatcher().getItemStack(slot); + + if (itemStack != null) { + packets.clear(); + + PacketContainer equipPacket = sentPacket.shallowClone(); + + packets.addPacket(equipPacket); + + equipPacket.getModifier() + .write(2, ReflectionManager.getNmsItem(itemStack.getType() == Material.AIR ? null : itemStack)); + } + + if (disguise.getWatcher().isRightClicking() && slot == EquipmentSlot.HAND) { + ItemStack heldItem = packets.getPackets().get(0).getItemModifier().read(0); + + if (heldItem != null && heldItem.getType() != Material.AIR) { + // Convert the datawatcher + List list = new ArrayList<>(); + + if (DisguiseConfig.isMetadataPacketsEnabled()) { + WrappedWatchableObject watch = ReflectionManager + .createWatchable(0, WrappedDataWatcher.getEntityWatcher(entity).getByte(0)); + + if (watch != null) + list.add(watch); + + list = disguise.getWatcher().convert(list); + } else { + for (WrappedWatchableObject obj : disguise.getWatcher().getWatchableObjects()) { + if (obj.getIndex() == 0) { + list.add(obj); + break; + } + } + } + + // Construct the packets to return + PacketContainer packetBlock = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + + packetBlock.getModifier().write(0, entity.getEntityId()); + packetBlock.getWatchableCollectionModifier().write(0, list); + + PacketContainer packetUnblock = packetBlock.deepClone(); + // Make a packet to send the 'unblock' + for (WrappedWatchableObject watcher : packetUnblock.getWatchableCollectionModifier().read(0)) { + watcher.setValue((byte) ((byte) watcher.getValue() & ~(1 << 4))); + } + + // Send the unblock before the itemstack change so that the 2nd metadata packet works. Why? + // Scheduler + // delay. + + PacketContainer packet1 = packets.getPackets().get(0); + + packets.clear(); + + packets.addPacket(packetUnblock); + packets.addPacket(packet1); + packets.addPacket(packetBlock); + // Silly mojang made the right clicking datawatcher value only valid for one use. So I have + // to reset + // it. + } + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java new file mode 100644 index 00000000..0949e2a7 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java @@ -0,0 +1,53 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerHeadRotation implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.ENTITY_HEAD_ROTATION}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + if (disguise.getType().isPlayer() && entity.getType() != EntityType.PLAYER) { + Location loc = entity.getLocation(); + + byte pitch = DisguiseUtilities + .getPitch(disguise.getType(), entity.getType(), (byte) (int) (loc.getPitch() * 256.0F / 360.0F)); + byte yaw = DisguiseUtilities.getYaw(disguise.getType(), entity.getType(), sentPacket.getBytes().read(0)); + + PacketContainer rotation = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION); + + StructureModifier mods = rotation.getModifier(); + + mods.write(0, entity.getEntityId()); + mods.write(1, yaw); + + PacketContainer look = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK); + + look.getIntegers().write(0, entity.getEntityId()); + look.getBytes().write(0, yaw); + look.getBytes().write(1, pitch); + + packets.clear(); + + packets.addPacket(look); + packets.addPacket(rotation); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMetadata.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMetadata.java new file mode 100644 index 00000000..e1641fbd --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMetadata.java @@ -0,0 +1,53 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.WrappedWatchableObject; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.packets.PacketsHandler; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.List; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerMetadata implements IPacketHandler { + private PacketsHandler packetsHandler; + + public PacketHandlerMetadata(PacketsHandler packetsHandler) { + this.packetsHandler = packetsHandler; + } + + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.ENTITY_METADATA}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + + packets.clear(); + + if (DisguiseConfig.isMetadataPacketsEnabled() && packetsHandler.isCancelMeta(disguise, observer)) { + List watchableObjects = disguise.getWatcher() + .convert(sentPacket.getWatchableCollectionModifier().read(0)); + + PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + + packets.addPacket(metaPacket); + + StructureModifier newMods = metaPacket.getModifier(); + + newMods.write(0, entity.getEntityId()); + + metaPacket.getWatchableCollectionModifier().write(0, watchableObjects); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java new file mode 100644 index 00000000..fea98e91 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java @@ -0,0 +1,103 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.metadata.FixedMetadataValue; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerMovement implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.REL_ENTITY_MOVE_LOOK, PacketType.Play.Server.ENTITY_LOOK, + PacketType.Play.Server.ENTITY_TELEPORT, PacketType.Play.Server.REL_ENTITY_MOVE}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + + if (disguise.getType() == DisguiseType.RABBIT && + (sentPacket.getType() == PacketType.Play.Server.REL_ENTITY_MOVE || + sentPacket.getType() == PacketType.Play.Server.REL_ENTITY_MOVE_LOOK)) { + // When did the rabbit disguise last hop + long lastHop = 999999; + + // If hop meta exists, set the last hop time + if (!entity.getMetadata("LibsRabbitHop").isEmpty()) { + // Last hop was 3 minutes ago, so subtract current time with the last hop time and get 3 + // minutes ago in milliseconds + lastHop = System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong(); + } + + // If last hop was less than 0.1 or more than 0.5 seconds ago + if (lastHop < 100 || lastHop > 500) { + if (lastHop > 500) { + entity.removeMetadata("LibsRabbitHop", LibsDisguises.getInstance()); + entity.setMetadata("LibsRabbitHop", + new FixedMetadataValue(LibsDisguises.getInstance(), System.currentTimeMillis())); + } + + PacketContainer statusPacket = new PacketContainer(PacketType.Play.Server.ENTITY_STATUS); + packets.addPacket(statusPacket); + + statusPacket.getIntegers().write(0, entity.getEntityId()); + statusPacket.getBytes().write(0, (byte) 1); + } + } + + // Stop wither skulls from looking + if (sentPacket.getType() == PacketType.Play.Server.ENTITY_LOOK && + disguise.getType() == DisguiseType.WITHER_SKULL) { + packets.clear(); + } else if (sentPacket.getType() != PacketType.Play.Server.REL_ENTITY_MOVE) { + packets.clear(); + + PacketContainer movePacket = sentPacket.shallowClone(); + + packets.addPacket(movePacket); + + StructureModifier bytes = movePacket.getBytes(); + + byte yawValue = bytes.read(0); + byte pitchValue = bytes.read(1); + + bytes.write(0, DisguiseUtilities.getYaw(disguise.getType(), entity.getType(), yawValue)); + bytes.write(1, DisguiseUtilities.getPitch(disguise.getType(), entity.getType(), pitchValue)); + + if (sentPacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT && + disguise.getType() == DisguiseType.ITEM_FRAME) { + StructureModifier doubles = movePacket.getDoubles(); + + Location loc = entity.getLocation(); + + double data = (((loc.getYaw() % 360) + 720 + 45) / 90) % 4; + + if (data % 2 == 0) { + if (data % 2 == 0) { + doubles.write(3, loc.getZ()); + } else { + doubles.write(1, loc.getZ()); + } + } + + double y = DisguiseUtilities.getYModifier(entity, disguise); + + if (y != 0) { + doubles.write(2, doubles.read(2) + y); + } + } + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java new file mode 100644 index 00000000..2474a3e3 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java @@ -0,0 +1,403 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.WrappedAttribute; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.*; +import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.packets.PacketsHandler; +import me.libraryaddict.disguise.utilities.reflection.DisguiseValues; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; +import org.bukkit.Art; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Damageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerSpawn implements IPacketHandler { + private PacketsHandler packetsHandler; + + public PacketHandlerSpawn(PacketsHandler packetsHandler) { + this.packetsHandler = packetsHandler; + } + + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.NAMED_ENTITY_SPAWN, PacketType.Play.Server.SPAWN_ENTITY_LIVING, + PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB, PacketType.Play.Server.SPAWN_ENTITY, + PacketType.Play.Server.SPAWN_ENTITY_PAINTING}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + + packets.clear(); + + constructSpawnPackets(observer, packets, entity); + } + + /** + * Construct the packets I need to spawn in the disguise + */ + private void constructSpawnPackets(final Player observer, LibsPackets packets, Entity disguisedEntity) { + Disguise disguise = packets.getDisguise(); + + if (disguise.getEntity() == null) { + disguise.setEntity(disguisedEntity); + } + + // This sends the armor packets so that the player isn't naked. + // Please note it only sends the packets that wouldn't be sent normally + if (DisguiseConfig.isEquipmentPacketsEnabled()) { + for (EquipmentSlot slot : EquipmentSlot.values()) { + ItemStack itemstack = disguise.getWatcher().getItemStack(slot); + + if (itemstack == null || itemstack.getType() == Material.AIR) { + continue; + } + + if (disguisedEntity instanceof LivingEntity) { + ItemStack item = ReflectionManager.getEquipment(slot, disguisedEntity); + + if (item != null && item.getType() != Material.AIR) { + continue; + } + } + + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT); + + StructureModifier mods = packet.getModifier(); + + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, ReflectionManager.createEnumItemSlot(slot)); + mods.write(2, ReflectionManager.getNmsItem(itemstack)); + + packets.addDelayedPacket(packet); + } + } + + if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) { + if (disguise.getWatcher() instanceof LivingWatcher) { + + ArrayList attributes = new ArrayList<>(); + + WrappedAttribute.Builder builder = WrappedAttribute.newBuilder().attributeKey("generic.maxHealth"); + + if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) { + builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); + } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity() && + disguisedEntity instanceof Damageable) { + builder.baseValue(((Damageable) disguisedEntity).getMaxHealth()); + } else { + builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); + } + + PacketContainer packet = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES); + + builder.packet(packet); + + attributes.add(builder.build()); + + packet.getIntegers().write(0, disguisedEntity.getEntityId()); + packet.getAttributeCollectionModifier().write(0, attributes); + + packets.addPacket(packet); + } + } + + Location loc = disguisedEntity.getLocation().clone() + .add(0, DisguiseUtilities.getYModifier(disguisedEntity, disguise), 0); + + byte yaw = (byte) (int) (loc.getYaw() * 256.0F / 360.0F); + byte pitch = (byte) (int) (loc.getPitch() * 256.0F / 360.0F); + + if (DisguiseConfig.isMovementPacketsEnabled()) { + yaw = DisguiseUtilities.getYaw(disguise.getType(), disguisedEntity.getType(), yaw); + pitch = DisguiseUtilities.getPitch(disguise.getType(), disguisedEntity.getType(), pitch); + } + + if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { + PacketContainer spawnOrb = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); + packets.addPacket(spawnOrb); + + StructureModifier mods = spawnOrb.getModifier(); + + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, loc.getX()); + mods.write(2, loc.getY() + 0.06); + mods.write(3, loc.getZ()); + mods.write(4, 1); + } else if (disguise.getType() == DisguiseType.PAINTING) { + PacketContainer spawnPainting = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); + packets.addPacket(spawnPainting); + + StructureModifier mods = spawnPainting.getModifier(); + + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, disguisedEntity.getUniqueId()); + mods.write(2, ReflectionManager.getBlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + mods.write(3, ReflectionManager.getEnumDirection(((int) loc.getYaw()) % 4)); + + int id = ((MiscDisguise) disguise).getData(); + + mods.write(4, ReflectionManager.getEnumArt(Art.values()[id])); + + // Make the teleport packet to make it visible.. + PacketContainer teleportPainting = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); + packets.addPacket(teleportPainting); + + mods = teleportPainting.getModifier(); + + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, loc.getX()); + mods.write(2, loc.getY()); + mods.write(3, loc.getZ()); + mods.write(4, yaw); + mods.write(5, pitch); + } else if (disguise.getType().isPlayer()) { + PlayerDisguise playerDisguise = (PlayerDisguise) disguise; + + String name = playerDisguise.getName(); + WrappedGameProfile gameProfile = playerDisguise.getGameProfile(); + + int entityId = disguisedEntity.getEntityId(); + + // Send player info along with the disguise + PacketContainer sendTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + + if (!((PlayerDisguise) disguise).isDisplayedInTab()) { + // Add player to the list, necessary to spawn them + sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0)); + + List playerList = Collections + .singletonList(ReflectionManager.getPlayerInfoData(sendTab.getHandle(), gameProfile)); + sendTab.getModifier().write(1, playerList); + + packets.addPacket(sendTab); + } + + // Spawn the player + PacketContainer spawnPlayer = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN); + + spawnPlayer.getIntegers().write(0, entityId); // Id + spawnPlayer.getModifier().write(1, gameProfile.getUUID()); + + Location spawnAt = disguisedEntity.getLocation(); + + boolean selfDisguise = observer == disguisedEntity; + + WrappedDataWatcher newWatcher; + + if (selfDisguise) { + newWatcher = DisguiseUtilities + .createSanitizedDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), + disguise.getWatcher()); + } else { + newWatcher = new WrappedDataWatcher(); + + spawnAt = observer.getLocation(); + spawnAt.add(spawnAt.getDirection().normalize().multiply(20)); + } + + // Spawn him in front of the observer + StructureModifier doubles = spawnPlayer.getDoubles(); + doubles.write(0, spawnAt.getX()); + doubles.write(1, spawnAt.getY()); + doubles.write(2, spawnAt.getZ()); + + StructureModifier bytes = spawnPlayer.getBytes(); + bytes.write(0, yaw); + bytes.write(1, pitch); + + spawnPlayer.getDataWatcherModifier().write(0, newWatcher); + + // Make him invisible + newWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(MetaIndex.ENTITY_META.getIndex(), + WrappedDataWatcher.Registry.get(Byte.class)), (byte) 32); + + packets.addPacket(spawnPlayer); + + if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + PacketContainer[] bedPackets = DisguiseUtilities.getBedPackets( + loc.clone().subtract(0, DisguiseUtilities.getYModifier(disguisedEntity, disguise), 0), + observer.getLocation(), ((PlayerDisguise) disguise)); + + for (PacketContainer packet : bedPackets) { + packets.addPacket(packet); + } + } else if (!selfDisguise) { + // Teleport the player back to where he's supposed to be + PacketContainer teleportPacket = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); + + doubles = teleportPacket.getDoubles(); + + teleportPacket.getIntegers().write(0, entityId); // Id + doubles.write(0, loc.getX()); + doubles.write(1, loc.getY()); + doubles.write(2, loc.getZ()); + + bytes = teleportPacket.getBytes(); + bytes.write(0, yaw); + bytes.write(1, pitch); + + packets.addPacket(teleportPacket); + } + + if (!selfDisguise) { + // Send a metadata packet + PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + + newWatcher = DisguiseUtilities + .createSanitizedDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), + disguise.getWatcher()); + + metaPacket.getIntegers().write(0, entityId); // Id + metaPacket.getWatchableCollectionModifier().write(0, newWatcher.getWatchableObjects()); + + packetsHandler.addCancel(disguise, observer); + + // Add a delay to remove the entry from 'cancelMeta' + + packets.addDelayedPacket(metaPacket, 4); + } + + // Remove player from the list + PacketContainer deleteTab = sendTab.shallowClone(); + 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(); + + PacketContainer spawnEntity = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + packets.addPacket(spawnEntity); + + StructureModifier mods = spawnEntity.getModifier(); + + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, disguisedEntity.getUniqueId()); + mods.write(2, disguise.getType().getTypeId()); + + // region Vector calculations + double d1 = 3.9D; + double d2 = vec.getX(); + double d3 = vec.getY(); + double d4 = vec.getZ(); + if (d2 < -d1) + d2 = -d1; + if (d3 < -d1) + d3 = -d1; + if (d4 < -d1) + d4 = -d1; + if (d2 > d1) + d2 = d1; + if (d3 > d1) + d3 = d1; + if (d4 > d1) + d4 = d1; + // endregion + + mods.write(3, loc.getX()); + mods.write(4, loc.getY()); + mods.write(5, loc.getZ()); + mods.write(6, (int) (d2 * 8000.0D)); + mods.write(7, (int) (d3 * 8000.0D)); + mods.write(8, (int) (d4 * 8000.0D)); + mods.write(9, yaw); + mods.write(10, pitch); + mods.write(11, yaw); + + spawnEntity.getDataWatcherModifier().write(0, DisguiseUtilities + .createSanitizedDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), + disguise.getWatcher())); + } else if (disguise.getType().isMisc()) { + int objectId = disguise.getType().getObjectId(); + int data = ((MiscDisguise) disguise).getData(); + + if (disguise.getType() == DisguiseType.FALLING_BLOCK) { + ItemStack block = ((FallingBlockWatcher) disguise.getWatcher()).getBlock(); + + data = ReflectionManager.getCombinedIdByItemStack(block); + } else if (disguise.getType() == DisguiseType.FISHING_HOOK && data == -1) { + // If the MiscDisguise data isn't set. Then no entity id was provided, so default to the owners + // entity id + data = observer.getEntityId(); + } else if (disguise.getType() == DisguiseType.ITEM_FRAME) { + data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4; + } + + Object nmsEntity = ReflectionManager.getNmsEntity(disguisedEntity); + + PacketContainer spawnEntity = ProtocolLibrary.getProtocolManager() + .createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, nmsEntity, objectId, data) + .createPacket(nmsEntity, objectId, data); + packets.addPacket(spawnEntity); + + // If it's not the same type, then highly likely they have different velocity settings which we'd want to + // cancel + if (DisguiseType.getType(disguisedEntity) != disguise.getType()) { + StructureModifier ints = spawnEntity.getIntegers(); + + ints.write(1, 0); + ints.write(2, 0); + ints.write(3, 0); + } + + spawnEntity.getModifier().write(8, pitch); + spawnEntity.getModifier().write(9, yaw); + + if (disguise.getType() == DisguiseType.ITEM_FRAME) { + if (data % 2 == 0) { + spawnEntity.getModifier().write(4, loc.getZ() + (data == 0 ? -1 : 1)); + } else { + spawnEntity.getModifier().write(2, loc.getX() + (data == 3 ? -1 : 1)); + } + } + } + + if (packets.getPackets().size() <= 1 || disguise.isPlayerDisguise()) { + PacketContainer rotateHead = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION); + packets.addPacket(rotateHead); + + StructureModifier mods = rotateHead.getModifier(); + + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, yaw); + } + + if (disguise.getType() == DisguiseType.EVOKER_FANGS) { + PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ENTITY_STATUS); + + StructureModifier mods = newPacket.getModifier(); + mods.write(0, disguise.getEntity().getEntityId()); + mods.write(1, (byte) 4); + + packets.addPacket(newPacket); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerVelocity.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerVelocity.java new file mode 100644 index 00000000..9ba65f94 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerVelocity.java @@ -0,0 +1,29 @@ +package me.libraryaddict.disguise.utilities.packets.packethandlers; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.utilities.packets.IPacketHandler; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 3/01/2019. + */ +public class PacketHandlerVelocity implements IPacketHandler { + @Override + public PacketType[] getHandledPackets() { + return new PacketType[]{PacketType.Play.Server.ENTITY_VELOCITY}; + } + + @Override + public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, + Entity entity) { + // If the disguise is a misc and the disguised is not the same type + if (disguise.getType().isMisc() && DisguiseType.getType(entity) != disguise.getType()) { + packets.clear(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerClientInteract.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerClientInteract.java similarity index 96% rename from src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerClientInteract.java rename to src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerClientInteract.java index 1b82e45a..92597b90 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerClientInteract.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerClientInteract.java @@ -1,112 +1,112 @@ -package me.libraryaddict.disguise.utilities.packetlisteners; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.EnumWrappers; -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.DisguiseConfig; -import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.disguisetypes.AnimalColor; -import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; -import me.libraryaddict.disguise.disguisetypes.watchers.SheepWatcher; -import me.libraryaddict.disguise.disguisetypes.watchers.WolfWatcher; -import me.libraryaddict.disguise.events.DisguiseInteractEvent; -import org.bukkit.Bukkit; -import org.bukkit.entity.*; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; - -public class PacketListenerClientInteract extends PacketAdapter { - public PacketListenerClientInteract(LibsDisguises plugin) { - super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY); - } - - @Override - public void onPacketReceiving(PacketEvent event) { - if (event.isCancelled()) - return; - - Player observer = event.getPlayer(); - - if (observer.getName().contains("UNKNOWN[")) // If the player is temporary - return; - - PacketContainer packet = event.getPacket(); - - StructureModifier entityModifer = packet.getEntityModifier(observer.getWorld()); - - Entity entity = entityModifer.read(0); - - if (entity instanceof ExperienceOrb || entity instanceof Item || entity instanceof Arrow || - entity == observer) { - event.setCancelled(true); - } else if (packet.getIntegers().read(0) == DisguiseAPI.getSelfDisguiseId()) { - // If it's a self-interact - event.setCancelled(true); - - Disguise disguise = DisguiseAPI.getDisguise(observer, observer); - - if (disguise != null) { - // The type of interact, we don't care the difference with "Interact_At" however as it's not useful - // for self disguises - EnumWrappers.EntityUseAction interactType = packet.getEntityUseActions().read(0); - EquipmentSlot handUsed = EquipmentSlot.HAND; - - // Attack has a null hand, which throws an error if you attempt to fetch - if (interactType != EnumWrappers.EntityUseAction.ATTACK) { - // If the hand used wasn't their main hand - if (packet.getHands().read(0) == EnumWrappers.Hand.OFF_HAND) { - handUsed = EquipmentSlot.OFF_HAND; - } - } - - DisguiseInteractEvent selfEvent = new DisguiseInteractEvent((TargetedDisguise) disguise, handUsed, - interactType == EnumWrappers.EntityUseAction.ATTACK); - - new BukkitRunnable() { - @Override - public void run() { - Bukkit.getPluginManager().callEvent(selfEvent); - } - }.runTask(LibsDisguises.getInstance()); - } - } - - for (ItemStack item : new ItemStack[]{observer.getInventory().getItemInMainHand(), - observer.getInventory().getItemInOffHand()}) { - if (item == null) { - continue; - } - - AnimalColor color = AnimalColor.getColorByMaterial(item.getType()); - - if (color == null) { - continue; - } - - Disguise disguise = DisguiseAPI.getDisguise(observer, entity); - - if (disguise == null || - (disguise.getType() != DisguiseType.SHEEP && disguise.getType() != DisguiseType.WOLF)) { - continue; - } - - if (disguise.getType() == DisguiseType.SHEEP) { - SheepWatcher watcher = (SheepWatcher) disguise.getWatcher(); - - watcher.setColor(DisguiseConfig.isSheepDyeable() ? color : watcher.getColor()); - } else { - WolfWatcher watcher = (WolfWatcher) disguise.getWatcher(); - - watcher.setCollarColor(DisguiseConfig.isWolfDyeable() ? color : watcher.getCollarColor()); - } - } - } -} +package me.libraryaddict.disguise.utilities.packets.packetlisteners; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.EnumWrappers; +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.AnimalColor; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; +import me.libraryaddict.disguise.disguisetypes.watchers.SheepWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.WolfWatcher; +import me.libraryaddict.disguise.events.DisguiseInteractEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.*; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +public class PacketListenerClientInteract extends PacketAdapter { + public PacketListenerClientInteract(LibsDisguises plugin) { + super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY); + } + + @Override + public void onPacketReceiving(PacketEvent event) { + if (event.isCancelled()) + return; + + Player observer = event.getPlayer(); + + if (observer.getName().contains("UNKNOWN[")) // If the player is temporary + return; + + PacketContainer packet = event.getPacket(); + + StructureModifier entityModifer = packet.getEntityModifier(observer.getWorld()); + + Entity entity = entityModifer.read(0); + + if (entity instanceof ExperienceOrb || entity instanceof Item || entity instanceof Arrow || + entity == observer) { + event.setCancelled(true); + } else if (packet.getIntegers().read(0) == DisguiseAPI.getSelfDisguiseId()) { + // If it's a self-interact + event.setCancelled(true); + + Disguise disguise = DisguiseAPI.getDisguise(observer, observer); + + if (disguise != null) { + // The type of interact, we don't care the difference with "Interact_At" however as it's not useful + // for self disguises + EnumWrappers.EntityUseAction interactType = packet.getEntityUseActions().read(0); + EquipmentSlot handUsed = EquipmentSlot.HAND; + + // Attack has a null hand, which throws an error if you attempt to fetch + if (interactType != EnumWrappers.EntityUseAction.ATTACK) { + // If the hand used wasn't their main hand + if (packet.getHands().read(0) == EnumWrappers.Hand.OFF_HAND) { + handUsed = EquipmentSlot.OFF_HAND; + } + } + + DisguiseInteractEvent selfEvent = new DisguiseInteractEvent((TargetedDisguise) disguise, handUsed, + interactType == EnumWrappers.EntityUseAction.ATTACK); + + new BukkitRunnable() { + @Override + public void run() { + Bukkit.getPluginManager().callEvent(selfEvent); + } + }.runTask(LibsDisguises.getInstance()); + } + } + + for (ItemStack item : new ItemStack[]{observer.getInventory().getItemInMainHand(), + observer.getInventory().getItemInOffHand()}) { + if (item == null) { + continue; + } + + AnimalColor color = AnimalColor.getColorByMaterial(item.getType()); + + if (color == null) { + continue; + } + + Disguise disguise = DisguiseAPI.getDisguise(observer, entity); + + if (disguise == null || + (disguise.getType() != DisguiseType.SHEEP && disguise.getType() != DisguiseType.WOLF)) { + continue; + } + + if (disguise.getType() == DisguiseType.SHEEP) { + SheepWatcher watcher = (SheepWatcher) disguise.getWatcher(); + + watcher.setColor(DisguiseConfig.isSheepDyeable() ? color : watcher.getColor()); + } else { + WolfWatcher watcher = (WolfWatcher) disguise.getWatcher(); + + watcher.setCollarColor(DisguiseConfig.isWolfDyeable() ? color : watcher.getCollarColor()); + } + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerInventory.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerInventory.java similarity index 97% rename from src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerInventory.java rename to src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerInventory.java index 884b1d06..2d565194 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerInventory.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerInventory.java @@ -1,341 +1,341 @@ -package me.libraryaddict.disguise.utilities.packetlisteners; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Play.Server; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.StructureModifier; - -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.utilities.ReflectionManager; - -public class PacketListenerInventory extends PacketAdapter { - private LibsDisguises libsDisguises; - - public PacketListenerInventory(LibsDisguises plugin) { - super(plugin, ListenerPriority.HIGH, Server.SET_SLOT, Server.WINDOW_ITEMS, PacketType.Play.Client.HELD_ITEM_SLOT, - PacketType.Play.Client.SET_CREATIVE_SLOT, PacketType.Play.Client.WINDOW_CLICK); - - libsDisguises = plugin; - } - - @Override - public void onPacketReceiving(final PacketEvent event) { - if (event.isCancelled()) - return; - - final Player player = event.getPlayer(); - - if (player.getName().contains("UNKNOWN[")) // If the player is temporary - return; - - if (player instanceof com.comphenix.net.sf.cglib.proxy.Factory || player.getVehicle() != null) { - return; - } - - Disguise disguise = DisguiseAPI.getDisguise(player, player); - - // If player is disguised, views self disguises and has a inventory modifier - if (disguise != null && disguise.isSelfDisguiseVisible() - && (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { - // If they are in creative and clicked on a slot - if (event.getPacketType() == PacketType.Play.Client.SET_CREATIVE_SLOT) { - int slot = event.getPacket().getIntegers().read(0); - - if (slot >= 5 && slot <= 8) { - if (disguise.isHidingArmorFromSelf()) { - int armorSlot = Math.abs((slot - 5) - 3); - - org.bukkit.inventory.ItemStack item = player.getInventory().getArmorContents()[armorSlot]; - - if (item != null && item.getType() != Material.AIR) { - PacketContainer packet = new PacketContainer(Server.SET_SLOT); - - StructureModifier mods = packet.getModifier(); - - mods.write(0, 0); - mods.write(1, slot); - mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - } - } - else if (slot >= 36 && slot <= 45) { - if (disguise.isHidingHeldItemFromSelf()) { - int currentSlot = player.getInventory().getHeldItemSlot(); - - if (slot + 36 == currentSlot || slot == 45) { - org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand(); - - if (item != null && item.getType() != Material.AIR) { - PacketContainer packet = new PacketContainer(Server.SET_SLOT); - - StructureModifier mods = packet.getModifier(); - mods.write(0, 0); - mods.write(1, slot); - mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - } - } - } - } - // If the player switched item, aka he moved from slot 1 to slot 2 - else if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_SLOT) { - if (disguise.isHidingHeldItemFromSelf()) { - // From logging, it seems that both bukkit and nms uses the same thing for the slot switching. - // 0 1 2 3 - 8 - // If the packet is coming, then I need to replace the item they are switching to - // As for the old item, I need to restore it. - org.bukkit.inventory.ItemStack currentlyHeld = player.getItemInHand(); - // If his old weapon isn't air - if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) { - PacketContainer packet = new PacketContainer(Server.SET_SLOT); - - StructureModifier mods = packet.getModifier(); - - mods.write(0, 0); - mods.write(1, player.getInventory().getHeldItemSlot() + 36); - mods.write(2, ReflectionManager.getNmsItem(currentlyHeld)); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - - org.bukkit.inventory.ItemStack newHeld = player.getInventory() - .getItem(event.getPacket().getIntegers().read(0)); - - // If his new weapon isn't air either! - if (newHeld != null && newHeld.getType() != Material.AIR) { - PacketContainer packet = new PacketContainer(Server.SET_SLOT); - - StructureModifier mods = packet.getModifier(); - - mods.write(0, 0); - mods.write(1, event.getPacket().getIntegers().read(0) + 36); - mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - } - } - else if (event.getPacketType() == PacketType.Play.Client.WINDOW_CLICK) { - int slot = event.getPacket().getIntegers().read(1); - - org.bukkit.inventory.ItemStack clickedItem; - - if (event.getPacket().getShorts().read(0) == 1) { - // Its a shift click - clickedItem = event.getPacket().getItemModifier().read(0); - - if (clickedItem != null && clickedItem.getType() != Material.AIR) { - // Rather than predict the clients actions - // Lets just update the entire inventory.. - Bukkit.getScheduler().runTask(libsDisguises, new Runnable() { - public void run() { - player.updateInventory(); - } - }); - } - - return; - } - else { - // If its not a player inventory click - // Shift clicking is exempted for the item in hand.. - if (event.getPacket().getIntegers().read(0) != 0) { - return; - } - - clickedItem = player.getItemOnCursor(); - } - - if (clickedItem != null && clickedItem.getType() != Material.AIR) { - // If the slot is a armor slot - if (slot >= 5 && slot <= 8) { - if (disguise.isHidingArmorFromSelf()) { - PacketContainer packet = new PacketContainer(Server.SET_SLOT); - - StructureModifier mods = packet.getModifier(); - - mods.write(0, 0); - mods.write(1, slot); - mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - // Else if its a hotbar slot - } - else if (slot >= 36 && slot <= 45) { - if (disguise.isHidingHeldItemFromSelf()) { - int currentSlot = player.getInventory().getHeldItemSlot(); - - // Check if the player is on the same slot as the slot that its setting - if (slot == currentSlot + 36 || slot == 45) { - PacketContainer packet = new PacketContainer(Server.SET_SLOT); - - StructureModifier mods = packet.getModifier(); - mods.write(0, 0); - mods.write(1, slot); - mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - } - } - } - } - } - - } - - @Override - public void onPacketSending(PacketEvent event) { - Player player = event.getPlayer(); - - // If the inventory is the players inventory - if (player instanceof com.comphenix.net.sf.cglib.proxy.Factory || player.getVehicle() != null - || event.getPacket().getIntegers().read(0) != 0) { - return; - } - - Disguise disguise = DisguiseAPI.getDisguise(player, player); - - if (disguise == null || !disguise.isSelfDisguiseVisible() - || (!disguise.isHidingArmorFromSelf() && !disguise.isHidingHeldItemFromSelf())) { - return; - } - - // If the player is disguised, views self disguises and is hiding a item. - - // If the server is setting the slot - // Need to set it to air if its in a place it shouldn't be. - // Things such as picking up a item, spawned in item. Plugin sets the item. etc. Will fire this - /** - * Done - */ - if (event.getPacketType() == Server.SET_SLOT) { - // The raw slot - // nms code has the start of the hotbar being 36. - int slot = event.getPacket().getIntegers().read(1); - - // If the slot is a armor slot - if (slot >= 5 && slot <= 8) { - if (disguise.isHidingArmorFromSelf()) { - // Get the bukkit armor slot! - int armorSlot = Math.abs((slot - 5) - 3); - - org.bukkit.inventory.ItemStack item = player.getInventory().getArmorContents()[armorSlot]; - - if (item != null && item.getType() != Material.AIR) { - event.setPacket(event.getPacket().shallowClone()); - - event.getPacket().getModifier().write(2, - ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - } - } - // Else if its a hotbar slot - } - else if (slot >= 36 && slot <= 45) { - if (disguise.isHidingHeldItemFromSelf()) { - int currentSlot = player.getInventory().getHeldItemSlot(); - - // Check if the player is on the same slot as the slot that its setting - if (slot == currentSlot + 36 || slot == 45) { - org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand(); - - if (item != null && item.getType() != Material.AIR) { - event.setPacket(event.getPacket().shallowClone()); - event.getPacket().getModifier().write(2, - ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); - } - } - } - } - } - else if (event.getPacketType() == Server.WINDOW_ITEMS) { - event.setPacket(event.getPacket().shallowClone()); - - StructureModifier> mods = event.getPacket().getItemListModifier(); - List items = new ArrayList<>(mods.read(0)); - - for (int slot = 0; slot < items.size(); slot++) { - if (slot >= 5 && slot <= 8) { - if (disguise.isHidingArmorFromSelf()) { - // Get the bukkit armor slot! - int armorSlot = Math.abs((slot - 5) - 3); - - ItemStack item = player.getInventory().getArmorContents()[armorSlot]; - - if (item != null && item.getType() != Material.AIR) { - items.set(slot, new ItemStack(Material.AIR)); - } - } - // Else if its a hotbar slot - } - else if (slot >= 36 && slot <= 45) { - if (disguise.isHidingHeldItemFromSelf()) { - int currentSlot = player.getInventory().getHeldItemSlot(); - - // Check if the player is on the same slot as the slot that its setting - if (slot == currentSlot + 36 || slot == 45) { - ItemStack item = player.getInventory().getItemInMainHand(); - - if (item != null && item.getType() != Material.AIR) { - items.set(slot, new ItemStack(Material.AIR)); - } - } - } - } - } - - mods.write(0, items); - } - } - -} +package me.libraryaddict.disguise.utilities.packets.packetlisteners; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.PacketType.Play.Server; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.reflect.StructureModifier; + +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; + +public class PacketListenerInventory extends PacketAdapter { + private LibsDisguises libsDisguises; + + public PacketListenerInventory(LibsDisguises plugin) { + super(plugin, ListenerPriority.HIGH, Server.SET_SLOT, Server.WINDOW_ITEMS, PacketType.Play.Client.HELD_ITEM_SLOT, + PacketType.Play.Client.SET_CREATIVE_SLOT, PacketType.Play.Client.WINDOW_CLICK); + + libsDisguises = plugin; + } + + @Override + public void onPacketReceiving(final PacketEvent event) { + if (event.isCancelled()) + return; + + final Player player = event.getPlayer(); + + if (player.getName().contains("UNKNOWN[")) // If the player is temporary + return; + + if (player instanceof com.comphenix.net.sf.cglib.proxy.Factory || player.getVehicle() != null) { + return; + } + + Disguise disguise = DisguiseAPI.getDisguise(player, player); + + // If player is disguised, views self disguises and has a inventory modifier + if (disguise != null && disguise.isSelfDisguiseVisible() + && (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { + // If they are in creative and clicked on a slot + if (event.getPacketType() == PacketType.Play.Client.SET_CREATIVE_SLOT) { + int slot = event.getPacket().getIntegers().read(0); + + if (slot >= 5 && slot <= 8) { + if (disguise.isHidingArmorFromSelf()) { + int armorSlot = Math.abs((slot - 5) - 3); + + org.bukkit.inventory.ItemStack item = player.getInventory().getArmorContents()[armorSlot]; + + if (item != null && item.getType() != Material.AIR) { + PacketContainer packet = new PacketContainer(Server.SET_SLOT); + + StructureModifier mods = packet.getModifier(); + + mods.write(0, 0); + mods.write(1, slot); + mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + else if (slot >= 36 && slot <= 45) { + if (disguise.isHidingHeldItemFromSelf()) { + int currentSlot = player.getInventory().getHeldItemSlot(); + + if (slot + 36 == currentSlot || slot == 45) { + org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand(); + + if (item != null && item.getType() != Material.AIR) { + PacketContainer packet = new PacketContainer(Server.SET_SLOT); + + StructureModifier mods = packet.getModifier(); + mods.write(0, 0); + mods.write(1, slot); + mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } + } + // If the player switched item, aka he moved from slot 1 to slot 2 + else if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_SLOT) { + if (disguise.isHidingHeldItemFromSelf()) { + // From logging, it seems that both bukkit and nms uses the same thing for the slot switching. + // 0 1 2 3 - 8 + // If the packet is coming, then I need to replace the item they are switching to + // As for the old item, I need to restore it. + org.bukkit.inventory.ItemStack currentlyHeld = player.getItemInHand(); + // If his old weapon isn't air + if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) { + PacketContainer packet = new PacketContainer(Server.SET_SLOT); + + StructureModifier mods = packet.getModifier(); + + mods.write(0, 0); + mods.write(1, player.getInventory().getHeldItemSlot() + 36); + mods.write(2, ReflectionManager.getNmsItem(currentlyHeld)); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + org.bukkit.inventory.ItemStack newHeld = player.getInventory() + .getItem(event.getPacket().getIntegers().read(0)); + + // If his new weapon isn't air either! + if (newHeld != null && newHeld.getType() != Material.AIR) { + PacketContainer packet = new PacketContainer(Server.SET_SLOT); + + StructureModifier mods = packet.getModifier(); + + mods.write(0, 0); + mods.write(1, event.getPacket().getIntegers().read(0) + 36); + mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + else if (event.getPacketType() == PacketType.Play.Client.WINDOW_CLICK) { + int slot = event.getPacket().getIntegers().read(1); + + org.bukkit.inventory.ItemStack clickedItem; + + if (event.getPacket().getShorts().read(0) == 1) { + // Its a shift click + clickedItem = event.getPacket().getItemModifier().read(0); + + if (clickedItem != null && clickedItem.getType() != Material.AIR) { + // Rather than predict the clients actions + // Lets just update the entire inventory.. + Bukkit.getScheduler().runTask(libsDisguises, new Runnable() { + public void run() { + player.updateInventory(); + } + }); + } + + return; + } + else { + // If its not a player inventory click + // Shift clicking is exempted for the item in hand.. + if (event.getPacket().getIntegers().read(0) != 0) { + return; + } + + clickedItem = player.getItemOnCursor(); + } + + if (clickedItem != null && clickedItem.getType() != Material.AIR) { + // If the slot is a armor slot + if (slot >= 5 && slot <= 8) { + if (disguise.isHidingArmorFromSelf()) { + PacketContainer packet = new PacketContainer(Server.SET_SLOT); + + StructureModifier mods = packet.getModifier(); + + mods.write(0, 0); + mods.write(1, slot); + mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + // Else if its a hotbar slot + } + else if (slot >= 36 && slot <= 45) { + if (disguise.isHidingHeldItemFromSelf()) { + int currentSlot = player.getInventory().getHeldItemSlot(); + + // Check if the player is on the same slot as the slot that its setting + if (slot == currentSlot + 36 || slot == 45) { + PacketContainer packet = new PacketContainer(Server.SET_SLOT); + + StructureModifier mods = packet.getModifier(); + mods.write(0, 0); + mods.write(1, slot); + mods.write(2, ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } + } + } + + } + + @Override + public void onPacketSending(PacketEvent event) { + Player player = event.getPlayer(); + + // If the inventory is the players inventory + if (player instanceof com.comphenix.net.sf.cglib.proxy.Factory || player.getVehicle() != null + || event.getPacket().getIntegers().read(0) != 0) { + return; + } + + Disguise disguise = DisguiseAPI.getDisguise(player, player); + + if (disguise == null || !disguise.isSelfDisguiseVisible() + || (!disguise.isHidingArmorFromSelf() && !disguise.isHidingHeldItemFromSelf())) { + return; + } + + // If the player is disguised, views self disguises and is hiding a item. + + // If the server is setting the slot + // Need to set it to air if its in a place it shouldn't be. + // Things such as picking up a item, spawned in item. Plugin sets the item. etc. Will fire this + /** + * Done + */ + if (event.getPacketType() == Server.SET_SLOT) { + // The raw slot + // nms code has the start of the hotbar being 36. + int slot = event.getPacket().getIntegers().read(1); + + // If the slot is a armor slot + if (slot >= 5 && slot <= 8) { + if (disguise.isHidingArmorFromSelf()) { + // Get the bukkit armor slot! + int armorSlot = Math.abs((slot - 5) - 3); + + org.bukkit.inventory.ItemStack item = player.getInventory().getArmorContents()[armorSlot]; + + if (item != null && item.getType() != Material.AIR) { + event.setPacket(event.getPacket().shallowClone()); + + event.getPacket().getModifier().write(2, + ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + } + } + // Else if its a hotbar slot + } + else if (slot >= 36 && slot <= 45) { + if (disguise.isHidingHeldItemFromSelf()) { + int currentSlot = player.getInventory().getHeldItemSlot(); + + // Check if the player is on the same slot as the slot that its setting + if (slot == currentSlot + 36 || slot == 45) { + org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand(); + + if (item != null && item.getType() != Material.AIR) { + event.setPacket(event.getPacket().shallowClone()); + event.getPacket().getModifier().write(2, + ReflectionManager.getNmsItem(new org.bukkit.inventory.ItemStack(Material.AIR))); + } + } + } + } + } + else if (event.getPacketType() == Server.WINDOW_ITEMS) { + event.setPacket(event.getPacket().shallowClone()); + + StructureModifier> mods = event.getPacket().getItemListModifier(); + List items = new ArrayList<>(mods.read(0)); + + for (int slot = 0; slot < items.size(); slot++) { + if (slot >= 5 && slot <= 8) { + if (disguise.isHidingArmorFromSelf()) { + // Get the bukkit armor slot! + int armorSlot = Math.abs((slot - 5) - 3); + + ItemStack item = player.getInventory().getArmorContents()[armorSlot]; + + if (item != null && item.getType() != Material.AIR) { + items.set(slot, new ItemStack(Material.AIR)); + } + } + // Else if its a hotbar slot + } + else if (slot >= 36 && slot <= 45) { + if (disguise.isHidingHeldItemFromSelf()) { + int currentSlot = player.getInventory().getHeldItemSlot(); + + // Check if the player is on the same slot as the slot that its setting + if (slot == currentSlot + 36 || slot == 45) { + ItemStack item = player.getInventory().getItemInMainHand(); + + if (item != null && item.getType() != Material.AIR) { + items.set(slot, new ItemStack(Material.AIR)); + } + } + } + } + } + + mods.write(0, items); + } + } + +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerMain.java similarity index 86% rename from src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java rename to src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerMain.java index 44159722..0cc1eaad 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerMain.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerMain.java @@ -1,86 +1,82 @@ -package me.libraryaddict.disguise.utilities.packetlisteners; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; - -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Play.Server; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.StructureModifier; - -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.utilities.PacketsManager; -import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets; - -public class PacketListenerMain extends PacketAdapter { - public PacketListenerMain(LibsDisguises plugin, ArrayList packetsToListen) { - super(plugin, ListenerPriority.HIGH, packetsToListen); - } - - @Override - public void onPacketSending(final PacketEvent event) { - if (event.isCancelled()) - return; - - final Player observer = event.getPlayer(); - - if (observer.getName().contains("UNKNOWN[")) // If the player is temporary - return; - - // First get the entity, the one sending this packet - StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); - - org.bukkit.entity.Entity entity = entityModifer.read((Server.COLLECT == event.getPacketType() ? 1 : 0)); - - // If the entity is the same as the sender. Don't disguise! - // Prevents problems and there is no advantage to be gained. - if (entity == observer) - return; - - final Disguise disguise = DisguiseAPI.getDisguise(observer, entity); - - if (disguise == null) - return; - - LibsPackets packets; - - try { - packets = PacketsManager.transformPacket(event.getPacket(), disguise, observer, entity); - } - catch (Exception ex) { - ex.printStackTrace(); - event.setCancelled(true); - return; - } - - if (packets.isUnhandled()) { - return; - } - - packets.setSpawnPacketCheck(event.getPacketType()); - - event.setCancelled(true); - - try { - for (PacketContainer packet : packets.getPackets()) { - ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); - } - - packets.sendDelayed(observer); - } - catch (InvocationTargetException ex) { - ex.printStackTrace(); - } - - } - -} +package me.libraryaddict.disguise.utilities.packets.packetlisteners; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.PacketType.Play.Server; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.packets.PacketsManager; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +public class PacketListenerMain extends PacketAdapter { + public PacketListenerMain(LibsDisguises plugin, ArrayList packetsToListen) { + super(plugin, ListenerPriority.HIGH, packetsToListen); + } + + @Override + public void onPacketSending(final PacketEvent event) { + if (event.isCancelled()) + return; + + final Player observer = event.getPlayer(); + + if (observer.getName().contains("UNKNOWN[")) // If the player is temporary + return; + + // First get the entity, the one sending this packet + StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); + + org.bukkit.entity.Entity entity = entityModifer.read((Server.COLLECT == event.getPacketType() ? 1 : 0)); + + // If the entity is the same as the sender. Don't disguise! + // Prevents problems and there is no advantage to be gained. + if (entity == observer) + return; + + final Disguise disguise = DisguiseAPI.getDisguise(observer, entity); + + if (disguise == null) + return; + + LibsPackets packets; + + try { + packets = PacketsManager.getPacketsHandler().transformPacket(event.getPacket(), disguise, observer, entity); + } + catch (Exception ex) { + ex.printStackTrace(); + event.setCancelled(true); + return; + } + + if (packets.isUnhandled()) { + return; + } + + packets.setSpawnPacketCheck(event.getPacketType()); + + event.setCancelled(true); + + try { + for (PacketContainer packet : packets.getPackets()) { + ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); + } + + packets.sendDelayed(observer); + } + catch (InvocationTargetException ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerSounds.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java similarity index 96% rename from src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerSounds.java rename to src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java index e3fefe99..9afd6d91 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerSounds.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java @@ -1,347 +1,347 @@ -package me.libraryaddict.disguise.utilities.packetlisteners; - -import com.comphenix.protocol.PacketType.Play.Server; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.StructureModifier; -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.disguisetypes.MobDisguise; -import me.libraryaddict.disguise.utilities.DisguiseSound; -import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType; -import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.ReflectionManager; -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.entity.*; - -import java.lang.reflect.InvocationTargetException; - -public class PacketListenerSounds extends PacketAdapter { - /** - * This is a fix for the stupidity that is - * "I can't separate the sounds from the sounds the player heard, and the sounds of the entity tracker heard" - */ - private static boolean cancelSound; - private Object stepSoundEffect; - - public PacketListenerSounds(LibsDisguises plugin) { - super(plugin, ListenerPriority.NORMAL, Server.NAMED_SOUND_EFFECT, Server.ENTITY_STATUS); - - stepSoundEffect = ReflectionManager.getCraftSound(Sound.BLOCK_GRASS_STEP); - } - - @Override - public void onPacketSending(PacketEvent event) { - if (event.isCancelled()) { - return; - } - - if (event.isAsync()) { - return; - } - - if (event.getPlayer().getName().contains("UNKNOWN[")) // If the player is temporary - return; - - event.setPacket(event.getPacket().deepClone()); - - StructureModifier mods = event.getPacket().getModifier(); - - Player observer = event.getPlayer(); - - if (event.getPacketType() == Server.NAMED_SOUND_EFFECT) { - SoundType soundType = null; - - int[] soundCords = new int[]{(Integer) mods.read(2), (Integer) mods.read(3), (Integer) mods.read(4)}; - - int chunkX = (int) Math.floor((soundCords[0] / 8D) / 16D); - int chunkZ = (int) Math.floor((soundCords[2] / 8D) / 16D); - - if (!observer.getWorld().isChunkLoaded(chunkX, chunkZ)) { - return; - } - - Entity disguisedEntity = null; - DisguiseSound entitySound = null; - - Disguise disguise = null; - - Object soundEffectObj = mods.read(0); - Entity[] entities = observer.getWorld().getChunkAt(chunkX, chunkZ).getEntities(); - - for (Entity entity : entities) { - Disguise entityDisguise = DisguiseAPI.getDisguise(observer, entity); - - if (entityDisguise != null) { - Location loc = entity.getLocation(); - - int[] entCords = new int[]{(int) (loc.getX() * 8), (int) (loc.getY() * 8), (int) (loc.getZ() * 8)}; - - if (soundCords[0] != entCords[0] || soundCords[1] != entCords[1] || soundCords[2] != entCords[2]) { - continue; - } - - entitySound = DisguiseSound.getType(entity.getType().name()); - - if (entitySound == null) { - continue; - } - - Object obj = null; - - if (entity instanceof LivingEntity) { - try { - // Use reflection so that this works for either int or double methods - obj = LivingEntity.class.getMethod("getHealth").invoke(entity); - - if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) { - soundType = SoundType.DEATH; - } else { - obj = null; - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - if (obj == null) { - boolean hasInvun = false; - - Object nmsEntity = ReflectionManager.getNmsEntity(entity); - - try { - if (entity instanceof LivingEntity) { - hasInvun = ReflectionManager.getNmsField("Entity", "noDamageTicks").getInt(nmsEntity) == - ReflectionManager.getNmsField("EntityLiving", "maxNoDamageTicks") - .getInt(nmsEntity); - } else { - Class clazz = ReflectionManager.getNmsClass("DamageSource"); - - hasInvun = (Boolean) ReflectionManager.getNmsMethod("Entity", "isInvulnerable", clazz) - .invoke(nmsEntity, ReflectionManager.getNmsField(clazz, "GENERIC").get(null)); - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - soundType = entitySound.getType(soundEffectObj, !hasInvun); - } - - if (soundType != null) { - disguise = entityDisguise; - disguisedEntity = entity; - break; - } - } - } - - if (disguise != null && disguise.isSoundsReplaced() && - (disguise.isSelfDisguiseSoundsReplaced() || disguisedEntity != observer)) { - Object sound = null; - - DisguiseSound disguiseSound = DisguiseSound.getType(disguise.getType().name()); - - if (disguiseSound != null) { - sound = disguiseSound.getSound(soundType); - } - - if (sound == null) { - event.setCancelled(true); - } else { - if (sound.equals("step.grass")) { - try { - Block block = observer.getWorld().getBlockAt((int) Math.floor(soundCords[0] / 8D), - (int) Math.floor(soundCords[1] / 8D), (int) Math.floor(soundCords[2] / 8D)); - - if (block != null) { - Object nmsBlock = ReflectionManager.getCraftMethod("block.CraftBlock", "getNMSBlock") - .invoke(block); - - Object step = ReflectionManager.getNmsMethod("Block", "getStepSound").invoke(nmsBlock); - - mods.write(0, ReflectionManager.getNmsMethod(step.getClass(), "d").invoke(step)); - mods.write(1, ReflectionManager.getSoundCategory(disguise.getType())); - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - // There is no else statement. Because seriously. This should never be null. Unless - // someone is - // sending fake sounds. In which case. Why cancel it. - } else { - mods.write(0, sound); - mods.write(1, ReflectionManager.getSoundCategory(disguise.getType())); - - // Time to change the pitch and volume - if (soundType == SoundType.HURT || soundType == SoundType.DEATH || - soundType == SoundType.IDLE) { - // If the volume is the default - if (mods.read(5).equals(entitySound.getDamageAndIdleSoundVolume())) { - mods.write(5, disguiseSound.getDamageAndIdleSoundVolume()); - } - - // Here I assume its the default pitch as I can't calculate if its real. - if (disguise instanceof MobDisguise && disguisedEntity instanceof LivingEntity && - ((MobDisguise) disguise).doesDisguiseAge()) { - boolean baby = false; - - if (disguisedEntity instanceof Zombie) { - baby = ((Zombie) disguisedEntity).isBaby(); - } else if (disguisedEntity instanceof Ageable) { - baby = !((Ageable) disguisedEntity).isAdult(); - } - - if (((MobDisguise) disguise).isAdult() == baby) { - float pitch = (Float) mods.read(6); - - if (baby) { - // If the pitch is not the expected - if (pitch < 1.5 || pitch > 1.7) - return; - - pitch = (DisguiseUtilities.random.nextFloat() - - DisguiseUtilities.random.nextFloat()) * 0.2F + 1.5F; - // Min = 1.5 - // Cap = 97.5 - // Max = 1.7 - // Cap = 110.5 - } else { - // If the pitch is not the expected - if (pitch < 1 || pitch > 1.2) - return; - - pitch = (DisguiseUtilities.random.nextFloat() - - DisguiseUtilities.random.nextFloat()) * 0.2F + 1.0F; - // Min = 1 - // Cap = 63 - // Max = 1.2 - // Cap = 75.6 - } - - /*pitch *= 63; - - if (pitch < 0) - pitch = 0; - - if (pitch > 255) - pitch = 255;*/ - - mods.write(6, pitch); - } - } - } - } - } - } - } else if (event.getPacketType() == Server.ENTITY_STATUS) { - if ((byte) mods.read(1) != 2) { - return; - } - - // It made a damage animation - Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0); - - Disguise disguise = DisguiseAPI.getDisguise(observer, entity); - - if (disguise != null && !disguise.getType().isPlayer() && - (disguise.isSelfDisguiseSoundsReplaced() || entity != event.getPlayer())) { - DisguiseSound disSound = DisguiseSound.getType(entity.getType().name()); - - if (disSound == null) - return; - - SoundType soundType = null; - Object obj = null; - - if (entity instanceof LivingEntity) { - try { - obj = LivingEntity.class.getMethod("getHealth").invoke(entity); - - if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) { - soundType = SoundType.DEATH; - } else { - obj = null; - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - if (obj == null) { - soundType = SoundType.HURT; - } - - if (disSound.getSound(soundType) == null || - (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer())) { - if (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer()) { - cancelSound = !cancelSound; - - if (cancelSound) - return; - } - - disSound = DisguiseSound.getType(disguise.getType().name()); - - if (disSound != null) { - Object sound = disSound.getSound(soundType); - - if (sound != null) { - Location loc = entity.getLocation(); - - PacketContainer packet = new PacketContainer(Server.NAMED_SOUND_EFFECT); - - mods = packet.getModifier(); - - mods.write(0, sound); - mods.write(1, ReflectionManager.getSoundCategory(disguise.getType())); // Meh - mods.write(2, (int) (loc.getX() * 8D)); - mods.write(3, (int) (loc.getY() * 8D)); - mods.write(4, (int) (loc.getZ() * 8D)); - mods.write(5, disSound.getDamageAndIdleSoundVolume()); - - float pitch; - - if (disguise instanceof MobDisguise && !((MobDisguise) disguise).isAdult()) { - pitch = (DisguiseUtilities.random.nextFloat() - DisguiseUtilities.random.nextFloat()) * - 0.2F + 1.5F; - } else - pitch = (DisguiseUtilities.random.nextFloat() - DisguiseUtilities.random.nextFloat()) * - 0.2F + 1.0F; - - if (disguise.getType() == DisguiseType.BAT) - pitch *= 0.95F; - - /* pitch *= 63; - - if (pitch < 0) - pitch = 0; - - if (pitch > 255) - pitch = 255;*/ - - mods.write(6, pitch); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - } - } - } - } - } -} +package me.libraryaddict.disguise.utilities.packets.packetlisteners; + +import com.comphenix.protocol.PacketType.Play.Server; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.reflect.StructureModifier; +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.MobDisguise; +import me.libraryaddict.disguise.utilities.DisguiseSound; +import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.*; + +import java.lang.reflect.InvocationTargetException; + +public class PacketListenerSounds extends PacketAdapter { + /** + * This is a fix for the stupidity that is + * "I can't separate the sounds from the sounds the player heard, and the sounds of the entity tracker heard" + */ + private static boolean cancelSound; + private Object stepSoundEffect; + + public PacketListenerSounds(LibsDisguises plugin) { + super(plugin, ListenerPriority.NORMAL, Server.NAMED_SOUND_EFFECT, Server.ENTITY_STATUS); + + stepSoundEffect = ReflectionManager.getCraftSound(Sound.BLOCK_GRASS_STEP); + } + + @Override + public void onPacketSending(PacketEvent event) { + if (event.isCancelled()) { + return; + } + + if (event.isAsync()) { + return; + } + + if (event.getPlayer().getName().contains("UNKNOWN[")) // If the player is temporary + return; + + event.setPacket(event.getPacket().deepClone()); + + StructureModifier mods = event.getPacket().getModifier(); + + Player observer = event.getPlayer(); + + if (event.getPacketType() == Server.NAMED_SOUND_EFFECT) { + SoundType soundType = null; + + int[] soundCords = new int[]{(Integer) mods.read(2), (Integer) mods.read(3), (Integer) mods.read(4)}; + + int chunkX = (int) Math.floor((soundCords[0] / 8D) / 16D); + int chunkZ = (int) Math.floor((soundCords[2] / 8D) / 16D); + + if (!observer.getWorld().isChunkLoaded(chunkX, chunkZ)) { + return; + } + + Entity disguisedEntity = null; + DisguiseSound entitySound = null; + + Disguise disguise = null; + + Object soundEffectObj = mods.read(0); + Entity[] entities = observer.getWorld().getChunkAt(chunkX, chunkZ).getEntities(); + + for (Entity entity : entities) { + Disguise entityDisguise = DisguiseAPI.getDisguise(observer, entity); + + if (entityDisguise != null) { + Location loc = entity.getLocation(); + + int[] entCords = new int[]{(int) (loc.getX() * 8), (int) (loc.getY() * 8), (int) (loc.getZ() * 8)}; + + if (soundCords[0] != entCords[0] || soundCords[1] != entCords[1] || soundCords[2] != entCords[2]) { + continue; + } + + entitySound = DisguiseSound.getType(entity.getType().name()); + + if (entitySound == null) { + continue; + } + + Object obj = null; + + if (entity instanceof LivingEntity) { + try { + // Use reflection so that this works for either int or double methods + obj = LivingEntity.class.getMethod("getHealth").invoke(entity); + + if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) { + soundType = SoundType.DEATH; + } else { + obj = null; + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + if (obj == null) { + boolean hasInvun = false; + + Object nmsEntity = ReflectionManager.getNmsEntity(entity); + + try { + if (entity instanceof LivingEntity) { + hasInvun = ReflectionManager.getNmsField("Entity", "noDamageTicks").getInt(nmsEntity) == + ReflectionManager.getNmsField("EntityLiving", "maxNoDamageTicks") + .getInt(nmsEntity); + } else { + Class clazz = ReflectionManager.getNmsClass("DamageSource"); + + hasInvun = (Boolean) ReflectionManager.getNmsMethod("Entity", "isInvulnerable", clazz) + .invoke(nmsEntity, ReflectionManager.getNmsField(clazz, "GENERIC").get(null)); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + soundType = entitySound.getType(soundEffectObj, !hasInvun); + } + + if (soundType != null) { + disguise = entityDisguise; + disguisedEntity = entity; + break; + } + } + } + + if (disguise != null && disguise.isSoundsReplaced() && + (disguise.isSelfDisguiseSoundsReplaced() || disguisedEntity != observer)) { + Object sound = null; + + DisguiseSound disguiseSound = DisguiseSound.getType(disguise.getType().name()); + + if (disguiseSound != null) { + sound = disguiseSound.getSound(soundType); + } + + if (sound == null) { + event.setCancelled(true); + } else { + if (sound.equals("step.grass")) { + try { + Block block = observer.getWorld().getBlockAt((int) Math.floor(soundCords[0] / 8D), + (int) Math.floor(soundCords[1] / 8D), (int) Math.floor(soundCords[2] / 8D)); + + if (block != null) { + Object nmsBlock = ReflectionManager.getCraftMethod("block.CraftBlock", "getNMSBlock") + .invoke(block); + + Object step = ReflectionManager.getNmsMethod("Block", "getStepSound").invoke(nmsBlock); + + mods.write(0, ReflectionManager.getNmsMethod(step.getClass(), "d").invoke(step)); + mods.write(1, ReflectionManager.getSoundCategory(disguise.getType())); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + // There is no else statement. Because seriously. This should never be null. Unless + // someone is + // sending fake sounds. In which case. Why cancel it. + } else { + mods.write(0, sound); + mods.write(1, ReflectionManager.getSoundCategory(disguise.getType())); + + // Time to change the pitch and volume + if (soundType == SoundType.HURT || soundType == SoundType.DEATH || + soundType == SoundType.IDLE) { + // If the volume is the default + if (mods.read(5).equals(entitySound.getDamageAndIdleSoundVolume())) { + mods.write(5, disguiseSound.getDamageAndIdleSoundVolume()); + } + + // Here I assume its the default pitch as I can't calculate if its real. + if (disguise instanceof MobDisguise && disguisedEntity instanceof LivingEntity && + ((MobDisguise) disguise).doesDisguiseAge()) { + boolean baby = false; + + if (disguisedEntity instanceof Zombie) { + baby = ((Zombie) disguisedEntity).isBaby(); + } else if (disguisedEntity instanceof Ageable) { + baby = !((Ageable) disguisedEntity).isAdult(); + } + + if (((MobDisguise) disguise).isAdult() == baby) { + float pitch = (Float) mods.read(6); + + if (baby) { + // If the pitch is not the expected + if (pitch < 1.5 || pitch > 1.7) + return; + + pitch = (DisguiseUtilities.random.nextFloat() - + DisguiseUtilities.random.nextFloat()) * 0.2F + 1.5F; + // Min = 1.5 + // Cap = 97.5 + // Max = 1.7 + // Cap = 110.5 + } else { + // If the pitch is not the expected + if (pitch < 1 || pitch > 1.2) + return; + + pitch = (DisguiseUtilities.random.nextFloat() - + DisguiseUtilities.random.nextFloat()) * 0.2F + 1.0F; + // Min = 1 + // Cap = 63 + // Max = 1.2 + // Cap = 75.6 + } + + /*pitch *= 63; + + if (pitch < 0) + pitch = 0; + + if (pitch > 255) + pitch = 255;*/ + + mods.write(6, pitch); + } + } + } + } + } + } + } else if (event.getPacketType() == Server.ENTITY_STATUS) { + if ((byte) mods.read(1) != 2) { + return; + } + + // It made a damage animation + Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0); + + Disguise disguise = DisguiseAPI.getDisguise(observer, entity); + + if (disguise != null && !disguise.getType().isPlayer() && + (disguise.isSelfDisguiseSoundsReplaced() || entity != event.getPlayer())) { + DisguiseSound disSound = DisguiseSound.getType(entity.getType().name()); + + if (disSound == null) + return; + + SoundType soundType = null; + Object obj = null; + + if (entity instanceof LivingEntity) { + try { + obj = LivingEntity.class.getMethod("getHealth").invoke(entity); + + if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) { + soundType = SoundType.DEATH; + } else { + obj = null; + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + if (obj == null) { + soundType = SoundType.HURT; + } + + if (disSound.getSound(soundType) == null || + (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer())) { + if (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer()) { + cancelSound = !cancelSound; + + if (cancelSound) + return; + } + + disSound = DisguiseSound.getType(disguise.getType().name()); + + if (disSound != null) { + Object sound = disSound.getSound(soundType); + + if (sound != null) { + Location loc = entity.getLocation(); + + PacketContainer packet = new PacketContainer(Server.NAMED_SOUND_EFFECT); + + mods = packet.getModifier(); + + mods.write(0, sound); + mods.write(1, ReflectionManager.getSoundCategory(disguise.getType())); // Meh + mods.write(2, (int) (loc.getX() * 8D)); + mods.write(3, (int) (loc.getY() * 8D)); + mods.write(4, (int) (loc.getZ() * 8D)); + mods.write(5, disSound.getDamageAndIdleSoundVolume()); + + float pitch; + + if (disguise instanceof MobDisguise && !((MobDisguise) disguise).isAdult()) { + pitch = (DisguiseUtilities.random.nextFloat() - DisguiseUtilities.random.nextFloat()) * + 0.2F + 1.5F; + } else + pitch = (DisguiseUtilities.random.nextFloat() - DisguiseUtilities.random.nextFloat()) * + 0.2F + 1.0F; + + if (disguise.getType() == DisguiseType.BAT) + pitch *= 0.95F; + + /* pitch *= 63; + + if (pitch < 0) + pitch = 0; + + if (pitch > 255) + pitch = 255;*/ + + mods.write(6, pitch); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerTabList.java similarity index 93% rename from src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java rename to src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerTabList.java index 81efb04b..829c7601 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerTabList.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerTabList.java @@ -1,65 +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); - } - } - -} +package me.libraryaddict.disguise.utilities.packets.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); + } + } + +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewSelfDisguise.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java similarity index 94% rename from src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewSelfDisguise.java rename to src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java index b33f0897..80da250d 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packetlisteners/PacketListenerViewSelfDisguise.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java @@ -1,4 +1,4 @@ -package me.libraryaddict.disguise.utilities.packetlisteners; +package me.libraryaddict.disguise.utilities.packets.packetlisteners; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Play.Server; @@ -12,9 +12,9 @@ import com.comphenix.protocol.wrappers.WrappedWatchableObject; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.utilities.PacketsManager; -import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets; -import me.libraryaddict.disguise.utilities.ReflectionManager; +import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import me.libraryaddict.disguise.utilities.packets.PacketsManager; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.entity.Player; import java.lang.reflect.InvocationTargetException; @@ -67,7 +67,8 @@ public class PacketListenerViewSelfDisguise extends PacketAdapter { } // Here I grab the packets to convert them to, So I can display them as if the disguise sent them. - LibsPackets transformed = PacketsManager.transformPacket(packet, disguise, observer, observer); + LibsPackets transformed = PacketsManager.getPacketsHandler() + .transformPacket(packet, disguise, observer, observer); if (transformed.isUnhandled()) { transformed.getPackets().add(packet); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java index a72fd30a..bd10541b 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.utilities.parser; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; /** * Created by libraryaddict on 7/09/2018. diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java index d7b8cf40..3a69023c 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java @@ -3,8 +3,8 @@ package me.libraryaddict.disguise.utilities.parser; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.disguisetypes.*; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.bukkit.ChatColor; import org.bukkit.Material; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java index 40971b2e..9936abe5 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.utilities.parser.params; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; import java.util.HashMap; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java index 22cb51f3..2037a972 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.utilities.parser.params.types.base; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import java.util.List; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java index 0616f913..ea0c0af1 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.utilities.parser.params.types.custom; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.parser.params.types.ParamInfoEnum; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoParticle.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoParticle.java index d57fc26b..680331fb 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoParticle.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoParticle.java @@ -2,7 +2,7 @@ package me.libraryaddict.disguise.utilities.parser.params.types.custom; import com.comphenix.protocol.wrappers.WrappedBlockData; import com.comphenix.protocol.wrappers.WrappedParticle; -import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; import me.libraryaddict.disguise.utilities.parser.params.types.ParamInfoEnum; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/ClassGetter.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java similarity index 95% rename from src/main/java/me/libraryaddict/disguise/utilities/ClassGetter.java rename to src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java index bf03c904..50976613 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/ClassGetter.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java @@ -1,95 +1,95 @@ -package me.libraryaddict.disguise.utilities; - -import java.net.URL; -import java.net.URLDecoder; -import java.security.CodeSource; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import org.bukkit.entity.Entity; - -/** - * User: Austin Date: 4/22/13 Time: 11:47 PM (c) lazertester - */ -// Code for this taken and slightly modified from -// https://github.com/ddopson/java-class-enumerator -public class ClassGetter -{ - - public static ArrayList> getClassesForPackage(String pkgname) - { - ArrayList> classes = new ArrayList<>(); - // String relPath = pkgname.replace('.', '/'); - - // Get a File object for the package - CodeSource src = Entity.class.getProtectionDomain().getCodeSource(); - - if (src != null) - { - URL resource = src.getLocation(); - resource.getPath(); - processJarfile(resource, pkgname, classes); - } - - return classes; - } - - private static Class loadClass(String className) - { - try - { - return Class.forName(className); - } - catch (ClassNotFoundException e) - { - throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'"); - } - catch (NoClassDefFoundError e) - { - return null; - } - } - - private static void processJarfile(URL resource, String pkgname, ArrayList> classes) - { - try - { - String relPath = pkgname.replace('.', '/'); - String resPath = URLDecoder.decode(resource.getPath(), "UTF-8"); - String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); - - JarFile jarFile = new JarFile(jarPath); - - Enumeration entries = jarFile.entries(); - - while (entries.hasMoreElements()) - { - JarEntry entry = entries.nextElement(); - String entryName = entry.getName(); - String className = null; - if (entryName.endsWith(".class") && entryName.startsWith(relPath) - && entryName.length() > (relPath.length() + "/".length())) - { - className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); - } - if (className != null) - { - Class c = loadClass(className); - - if (c != null) - { - classes.add(c); - } - } - } - - jarFile.close(); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } -} +package me.libraryaddict.disguise.utilities.reflection; + +import java.net.URL; +import java.net.URLDecoder; +import java.security.CodeSource; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.bukkit.entity.Entity; + +/** + * User: Austin Date: 4/22/13 Time: 11:47 PM (c) lazertester + */ +// Code for this taken and slightly modified from +// https://github.com/ddopson/java-class-enumerator +public class ClassGetter +{ + + public static ArrayList> getClassesForPackage(String pkgname) + { + ArrayList> classes = new ArrayList<>(); + // String relPath = pkgname.replace('.', '/'); + + // Get a File object for the package + CodeSource src = Entity.class.getProtectionDomain().getCodeSource(); + + if (src != null) + { + URL resource = src.getLocation(); + resource.getPath(); + processJarfile(resource, pkgname, classes); + } + + return classes; + } + + private static Class loadClass(String className) + { + try + { + return Class.forName(className); + } + catch (ClassNotFoundException e) + { + throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'"); + } + catch (NoClassDefFoundError e) + { + return null; + } + } + + private static void processJarfile(URL resource, String pkgname, ArrayList> classes) + { + try + { + String relPath = pkgname.replace('.', '/'); + String resPath = URLDecoder.decode(resource.getPath(), "UTF-8"); + String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); + + JarFile jarFile = new JarFile(jarPath); + + Enumeration entries = jarFile.entries(); + + while (entries.hasMoreElements()) + { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + String className = null; + if (entryName.endsWith(".class") && entryName.startsWith(relPath) + && entryName.length() > (relPath.length() + "/".length())) + { + className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); + } + if (className != null) + { + Class c = loadClass(className); + + if (c != null) + { + classes.add(c); + } + } + } + + jarFile.close(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseValues.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/DisguiseValues.java similarity index 93% rename from src/main/java/me/libraryaddict/disguise/utilities/DisguiseValues.java rename to src/main/java/me/libraryaddict/disguise/utilities/reflection/DisguiseValues.java index e212f907..76541706 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseValues.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/DisguiseValues.java @@ -1,62 +1,62 @@ -package me.libraryaddict.disguise.utilities; - -import me.libraryaddict.disguise.disguisetypes.DisguiseType; - -import java.util.HashMap; - -public class DisguiseValues { - - private static HashMap values = new HashMap<>(); - - public static DisguiseValues getDisguiseValues(DisguiseType type) { - return values.get(type); - } - - public static Class getNmsEntityClass(DisguiseType type) { - return getDisguiseValues(type).getNmsEntityClass(); - } - - private FakeBoundingBox adultBox; - private FakeBoundingBox babyBox; - private float[] entitySize; - private double maxHealth; - private Class nmsEntityClass; - - public DisguiseValues(DisguiseType type, Class classType, int entitySize, double maxHealth) { - values.put(type, this); - nmsEntityClass = classType; - this.maxHealth = maxHealth; - } - - public FakeBoundingBox getAdultBox() { - return adultBox; - } - - public FakeBoundingBox getBabyBox() { - return babyBox; - } - - public float[] getEntitySize() { - return entitySize; - } - - public double getMaxHealth() { - return maxHealth; - } - - public Class getNmsEntityClass() { - return nmsEntityClass; - } - - public void setAdultBox(FakeBoundingBox newBox) { - adultBox = newBox; - } - - public void setBabyBox(FakeBoundingBox newBox) { - babyBox = newBox; - } - - public void setEntitySize(float[] size) { - this.entitySize = size; - } -} +package me.libraryaddict.disguise.utilities.reflection; + +import me.libraryaddict.disguise.disguisetypes.DisguiseType; + +import java.util.HashMap; + +public class DisguiseValues { + + private static HashMap values = new HashMap<>(); + + public static DisguiseValues getDisguiseValues(DisguiseType type) { + return values.get(type); + } + + public static Class getNmsEntityClass(DisguiseType type) { + return getDisguiseValues(type).getNmsEntityClass(); + } + + private FakeBoundingBox adultBox; + private FakeBoundingBox babyBox; + private float[] entitySize; + private double maxHealth; + private Class nmsEntityClass; + + public DisguiseValues(DisguiseType type, Class classType, int entitySize, double maxHealth) { + values.put(type, this); + nmsEntityClass = classType; + this.maxHealth = maxHealth; + } + + public FakeBoundingBox getAdultBox() { + return adultBox; + } + + public FakeBoundingBox getBabyBox() { + return babyBox; + } + + public float[] getEntitySize() { + return entitySize; + } + + public double getMaxHealth() { + return maxHealth; + } + + public Class getNmsEntityClass() { + return nmsEntityClass; + } + + public void setAdultBox(FakeBoundingBox newBox) { + adultBox = newBox; + } + + public void setBabyBox(FakeBoundingBox newBox) { + babyBox = newBox; + } + + public void setEntitySize(float[] size) { + this.entitySize = size; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/FakeBoundingBox.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/FakeBoundingBox.java similarity index 88% rename from src/main/java/me/libraryaddict/disguise/utilities/FakeBoundingBox.java rename to src/main/java/me/libraryaddict/disguise/utilities/reflection/FakeBoundingBox.java index 781ea698..cbd93bdc 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/FakeBoundingBox.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/FakeBoundingBox.java @@ -1,4 +1,4 @@ -package me.libraryaddict.disguise.utilities; +package me.libraryaddict.disguise.utilities.reflection; public class FakeBoundingBox { diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsProfileLookup.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/LibsProfileLookup.java similarity index 73% rename from src/main/java/me/libraryaddict/disguise/utilities/LibsProfileLookup.java rename to src/main/java/me/libraryaddict/disguise/utilities/reflection/LibsProfileLookup.java index 10dbc70d..af2b6c2a 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/LibsProfileLookup.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/LibsProfileLookup.java @@ -1,9 +1,9 @@ -package me.libraryaddict.disguise.utilities; - -import com.comphenix.protocol.wrappers.WrappedGameProfile; - -public interface LibsProfileLookup { - - void onLookup(WrappedGameProfile gameProfile); - -} +package me.libraryaddict.disguise.utilities.reflection; + +import com.comphenix.protocol.wrappers.WrappedGameProfile; + +public interface LibsProfileLookup { + + void onLookup(WrappedGameProfile gameProfile); + +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsProfileLookupCaller.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/LibsProfileLookupCaller.java similarity index 91% rename from src/main/java/me/libraryaddict/disguise/utilities/LibsProfileLookupCaller.java rename to src/main/java/me/libraryaddict/disguise/utilities/reflection/LibsProfileLookupCaller.java index d904b4f9..8415d0e7 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/LibsProfileLookupCaller.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/LibsProfileLookupCaller.java @@ -1,4 +1,4 @@ -package me.libraryaddict.disguise.utilities; +package me.libraryaddict.disguise.utilities.reflection; import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.mojang.authlib.GameProfile; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java similarity index 97% rename from src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java rename to src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java index 1cae4fd4..16518c29 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java @@ -1,1073 +1,1073 @@ -package me.libraryaddict.disguise.utilities; - -import com.comphenix.protocol.wrappers.*; -import com.comphenix.protocol.wrappers.EnumWrappers.Direction; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; -import com.comphenix.protocol.wrappers.nbt.NbtWrapper; -import me.libraryaddict.disguise.DisguiseConfig; -import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import org.apache.commons.io.IOUtils; -import org.bukkit.*; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.*; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.*; -import java.nio.ByteBuffer; -import java.util.Optional; -import java.util.UUID; - -public class ReflectionManager { - private static final String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3]; - private static final Class craftItemClass; - private static Method damageAndIdleSoundMethod; - private static final Field entitiesField; - private static final Constructor boundingBoxConstructor; - private static final Method setBoundingBoxMethod; - private static final Method ihmGet; - private static final Field pingField; - private static final Field trackerField; - public static final Field entityCountField; - - static { - try { - Object entity = createEntityInstance("Cow"); - - for (Method method : getNmsClass("EntityLiving").getDeclaredMethods()) { - if (method.getReturnType() != float.class) - continue; - - if (!Modifier.isProtected(method.getModifiers())) - continue; - - if (method.getParameterTypes().length != 0) - continue; - - method.setAccessible(true); - - float value = (Float) method.invoke(entity); - - if ((float) method.invoke(entity) != 0.4f) - continue; - - damageAndIdleSoundMethod = method; - break; - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - craftItemClass = getCraftClass("inventory.CraftItemStack"); - - pingField = getNmsField("EntityPlayer", "ping"); - - trackerField = getNmsField("WorldServer", "tracker"); - - entitiesField = getNmsField("EntityTracker", "trackedEntities"); - - ihmGet = getNmsMethod("IntHashMap", "get", int.class); - - boundingBoxConstructor = getNmsConstructor("AxisAlignedBB", double.class, double.class, double.class, - double.class, double.class, double.class); - - setBoundingBoxMethod = getNmsMethod("Entity", "a", getNmsClass("AxisAlignedBB")); - - entityCountField = getNmsField("Entity", "entityCount"); - - entityCountField.setAccessible(true); - } - - public static YamlConfiguration getPluginYaml(ClassLoader loader) { - try (InputStream stream = loader.getResourceAsStream("plugin.yml")) { - YamlConfiguration config = new YamlConfiguration(); - config.loadFromString(IOUtils.toString(stream, "UTF-8")); - - return config; - } - catch (IOException | InvalidConfigurationException e) { - e.printStackTrace(); - } - - return null; - } - - public static int getNewEntityId() { - return getNewEntityId(true); - } - - public static int getNewEntityId(boolean increment) { - try { - int id = entityCountField.getInt(null); - - if (increment) { - entityCountField.set(null, id + 1); - } - - return id; - } - catch (IllegalAccessException e) { - e.printStackTrace(); - } - - return -1; - } - - public static Object createEntityInstance(String entityName) { - try { - Class entityClass = getNmsClass("Entity" + entityName); - Object entityObject; - Object world = getWorldServer(Bukkit.getWorlds().get(0)); - - switch (entityName) { - case "Player": - Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null); - - Object playerinteractmanager = getNmsClass("PlayerInteractManager") - .getDeclaredConstructor(getNmsClass("World")).newInstance(world); - - WrappedGameProfile gameProfile = getGameProfile(new UUID(0, 0), "Steve"); - - entityObject = entityClass - .getDeclaredConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"), - gameProfile.getHandleType(), playerinteractmanager.getClass()) - .newInstance(minecraftServer, world, gameProfile.getHandle(), playerinteractmanager); - break; - case "EnderPearl": - entityObject = entityClass.getDeclaredConstructor(getNmsClass("World"), getNmsClass("EntityLiving")) - .newInstance(world, createEntityInstance("Cow")); - break; - case "Potion": - entityObject = entityClass - .getDeclaredConstructor(getNmsClass("World"), Double.TYPE, Double.TYPE, Double.TYPE, - getNmsClass("ItemStack")) - .newInstance(world, 0d, 0d, 0d, getNmsItem(new ItemStack(Material.SPLASH_POTION))); - break; - case "FishingHook": - entityObject = entityClass.getDeclaredConstructor(getNmsClass("World"), getNmsClass("EntityHuman")) - .newInstance(world, createEntityInstance("Player")); - break; - default: - entityObject = entityClass.getDeclaredConstructor(getNmsClass("World")).newInstance(world); - break; - } - - return entityObject; - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static Object getMobEffectList(int id) { - Method nmsMethod = getNmsMethod("MobEffectList", "fromId", Integer.TYPE); - - try { - return nmsMethod.invoke(null, id); - } - catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - - return null; - } - - public static Object createMobEffect(PotionEffect effect) { - return createMobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), - effect.isAmbient(), effect.hasParticles()); - } - - public static Object createMobEffect(int id, int duration, int amplification, boolean ambient, boolean particles) { - try { - return getNmsClass("MobEffect") - .getDeclaredConstructor(getNmsClass("MobEffectList"), Integer.TYPE, Integer.TYPE, Boolean.TYPE, - Boolean.TYPE) - .newInstance(getMobEffectList(id), duration, amplification, ambient, particles); - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static FakeBoundingBox getBoundingBox(Entity entity) { - try { - Object boundingBox = getNmsMethod("Entity", "getBoundingBox").invoke(getNmsEntity(entity)); - - double x = 0, y = 0, z = 0; - int stage = 0; - - for (Field field : boundingBox.getClass().getDeclaredFields()) { - if (!field.getType().getSimpleName().equals("double")) { - continue; - } - - stage++; - - switch (stage) { - case 1: - x -= field.getDouble(boundingBox); - break; - case 2: - y -= field.getDouble(boundingBox); - break; - case 3: - z -= field.getDouble(boundingBox); - break; - case 4: - x += field.getDouble(boundingBox); - break; - case 5: - y += field.getDouble(boundingBox); - break; - case 6: - z += field.getDouble(boundingBox); - break; - default: - throw new Exception("Error while setting the bounding box, more doubles than I thought??"); - } - } - - return new FakeBoundingBox(x, y, z); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Entity getBukkitEntity(Object nmsEntity) { - try { - return (Entity) getNmsMethod("Entity", "getBukkitEntity").invoke(nmsEntity); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static ItemStack getBukkitItem(Object nmsItem) { - try { - return (ItemStack) craftItemClass.getMethod("asBukkitCopy", getNmsClass("ItemStack")).invoke(null, nmsItem); - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static String getBukkitVersion() { - return bukkitVersion; - } - - public static Class getCraftClass(String className) { - try { - return Class.forName("org.bukkit.craftbukkit." + getBukkitVersion() + "." + className); - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static Constructor getCraftConstructor(Class clazz, Class... parameters) { - try { - Constructor declaredConstructor = clazz.getDeclaredConstructor(parameters); - declaredConstructor.setAccessible(true); - return declaredConstructor; - } - catch (NoSuchMethodException e) { - e.printStackTrace(); - } - - return null; - } - - public static Constructor getCraftConstructor(String className, Class... parameters) { - return getCraftConstructor(getCraftClass(className), parameters); - } - - public static Object getCraftSound(Sound sound) { - try { - return getCraftClass("CraftSound").getMethod("getSoundEffect", String.class) - .invoke(null, getSoundString(sound)); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Object getEntityTrackerEntry(Entity target) throws Exception { - Object world = getWorldServer(target.getWorld()); - Object tracker = trackerField.get(world); - Object trackedEntities = entitiesField.get(tracker); - - return ihmGet.invoke(trackedEntities, target.getEntityId()); - } - - public static Object getMinecraftServer() { - try { - return getCraftMethod("CraftServer", "getServer").invoke(Bukkit.getServer()); - } - catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - return null; - } - - public static String getEnumArt(Art art) { - try { - Object enumArt = getCraftClass("CraftArt").getMethod("BukkitToNotch", Art.class).invoke(null, art); - for (Field field : enumArt.getClass().getDeclaredFields()) { - if (field.getType() == String.class) { - return (String) field.get(enumArt); - } - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Object getBlockPosition(int x, int y, int z) { - try { - return getNmsClass("BlockPosition").getDeclaredConstructor(int.class, int.class, int.class) - .newInstance(x, y, z); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Enum getEnumDirection(int direction) { - try { - return (Enum) getNmsMethod("EnumDirection", "fromType2", int.class).invoke(null, direction); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Enum getEnumPlayerInfoAction(int action) { - try { - return (Enum) getNmsClass("PacketPlayOutPlayerInfo$EnumPlayerInfoAction").getEnumConstants()[action]; - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Object getPlayerInfoData(Object playerInfoPacket, WrappedGameProfile gameProfile) { - try { - Object playerListName = getNmsClass("ChatComponentText").getDeclaredConstructor(String.class) - .newInstance(gameProfile.getName()); - - return getNmsClass("PacketPlayOutPlayerInfo$PlayerInfoData") - .getDeclaredConstructor(getNmsClass("PacketPlayOutPlayerInfo"), gameProfile.getHandleType(), - int.class, getNmsClass("EnumGamemode"), getNmsClass("IChatBaseComponent")) - .newInstance(playerInfoPacket, gameProfile.getHandle(), 0, - getNmsClass("EnumGamemode").getEnumConstants()[1], playerListName); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static WrappedGameProfile getGameProfile(Player player) { - return WrappedGameProfile.fromPlayer(player); - } - - public static WrappedGameProfile getGameProfile(UUID uuid, String playerName) { - try { - return new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), playerName); - } - catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static WrappedGameProfile getClonedProfile(WrappedGameProfile gameProfile) { - return getGameProfileWithThisSkin(null, gameProfile.getName(), gameProfile); - } - - public static WrappedGameProfile getGameProfileWithThisSkin(UUID uuid, String playerName, - WrappedGameProfile profileWithSkin) { - try { - WrappedGameProfile gameProfile = new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), playerName); - - if (profileWithSkin != null) { - gameProfile.getProperties().putAll(profileWithSkin.getProperties()); - } - - return gameProfile; - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - /** - * Used for generating a UUID with a custom version instead of the default 4. Workaround for China's NetEase servers - */ - private static UUID getRandomUUID() { - UUID uuid = UUID.randomUUID(); - - if (DisguiseConfig.getUUIDGeneratedVersion() == 4) { - return uuid; - } - - ByteBuffer bb = ByteBuffer.wrap(new byte[16]); - - bb.putLong(uuid.getMostSignificantBits()); - bb.putLong(uuid.getLeastSignificantBits()); - - bb.put(6, (byte) (bb.get(6) & 0x0f)); // clear version - bb.put(6, (byte) (bb.get(6) | DisguiseConfig.getUUIDGeneratedVersion())); // set to version X (Default 4) - - bb.position(0); - - long firstLong = bb.getLong(); - long secondLong = bb.getLong(); - - return new UUID(firstLong, secondLong); - } - - public static Class getNmsClass(String className) { - try { - return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className); - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static Class getNmsClassIgnoreErrors(String className) { - try { - return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className); - } - catch (Exception ignored) { - } - - return null; - } - - public static Constructor getNmsConstructor(Class clazz, Class... parameters) { - try { - Constructor declaredConstructor = clazz.getDeclaredConstructor(parameters); - declaredConstructor.setAccessible(true); - return declaredConstructor; - } - catch (NoSuchMethodException e) { - e.printStackTrace(); - } - - return null; - } - - public static Constructor getNmsConstructor(String className, Class... parameters) { - return getNmsConstructor(getNmsClass(className), parameters); - } - - public static Object getNmsEntity(Entity entity) { - try { - return getCraftClass("entity.CraftEntity").getMethod("getHandle").invoke(entity); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Field getNmsField(Class clazz, String fieldName) { - try { - Field declaredField = clazz.getDeclaredField(fieldName); - declaredField.setAccessible(true); - - return declaredField; - } - catch (NoSuchFieldException e) { - e.printStackTrace(); - } - - return null; - } - - public static Field getNmsField(String className, String fieldName) { - return getNmsField(getNmsClass(className), fieldName); - } - - public static Object getNmsItem(ItemStack itemstack) { - try { - return craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemstack); - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static Method getCraftMethod(String className, String methodName, Class... parameters) { - return getCraftMethod(getCraftClass(className), methodName, parameters); - } - - public static Method getCraftMethod(Class clazz, String methodName, Class... parameters) { - try { - Method declaredMethod = clazz.getDeclaredMethod(methodName, parameters); - declaredMethod.setAccessible(true); - - return declaredMethod; - } - catch (NoSuchMethodException e) { - e.printStackTrace(); - } - - return null; - } - - public static Method getNmsMethod(Class clazz, String methodName, Class... parameters) { - try { - Method declaredMethod = clazz.getDeclaredMethod(methodName, parameters); - declaredMethod.setAccessible(true); - - return declaredMethod; - } - catch (NoSuchMethodException e) { - e.printStackTrace(); - } - - return null; - } - - public static Method getNmsMethod(String className, String methodName, Class... parameters) { - return getNmsMethod(getNmsClass(className), methodName, parameters); - } - - public static double getPing(Player player) { - try { - return (double) pingField.getInt(ReflectionManager.getNmsEntity(player)); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return 0; - } - - public static float[] getSize(Entity entity) { - try { - float length = getNmsField("Entity", "length").getFloat(getNmsEntity(entity)); - float width = getNmsField("Entity", "width").getFloat(getNmsEntity(entity)); - - float height = (Float) getNmsMethod("Entity", "getHeadHeight").invoke(getNmsEntity(entity)); - return new float[]{length, width, height}; - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static WrappedGameProfile getSkullBlob(WrappedGameProfile gameProfile) { - try { - Object minecraftServer = getMinecraftServer(); - - for (Method method : getNmsClass("MinecraftServer").getMethods()) { - if (method.getReturnType().getSimpleName().equals("MinecraftSessionService")) { - Object session = method.invoke(minecraftServer); - - return WrappedGameProfile.fromHandle(session.getClass() - .getDeclaredMethod("fillProfileProperties", gameProfile.getHandleType(), boolean.class) - .invoke(session, gameProfile.getHandle(), true)); - } - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Float getSoundModifier(Object entity) { - try { - return (Float) damageAndIdleSoundMethod.invoke(entity); - } - catch (Exception ignored) { - } - return null; - } - - public static WrappedGameProfile grabProfileAddUUID(String playername) { - try { - Object minecraftServer = getMinecraftServer(); - - for (Method method : getNmsClass("MinecraftServer").getMethods()) { - if (method.getReturnType().getSimpleName().equals("GameProfileRepository")) { - Object agent = Class.forName("com.mojang.authlib.Agent").getDeclaredField("MINECRAFT").get(null); - - LibsProfileLookupCaller callback = new LibsProfileLookupCaller(); - Object profileRepo = method.invoke(minecraftServer); - - method.getReturnType().getMethod("findProfilesByNames", String[].class, agent.getClass(), - Class.forName("com.mojang.authlib.ProfileLookupCallback")) - .invoke(profileRepo, new String[]{playername}, agent, callback); - - if (callback.getGameProfile() != null) { - return callback.getGameProfile(); - } - - return getGameProfile(null, playername); - } - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static void setBoundingBox(Entity entity, FakeBoundingBox newBox) { - try { - Location loc = entity.getLocation(); - - Object boundingBox = boundingBoxConstructor - .newInstance(loc.getX() - (newBox.getX() / 2), loc.getY(), loc.getZ() - (newBox.getZ() / 2), - loc.getX() + (newBox.getX() / 2), loc.getY() + newBox.getY(), - loc.getZ() + (newBox.getZ() / 2)); - - setBoundingBoxMethod.invoke(getNmsEntity(entity), boundingBox); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static Enum getSoundCategory(String category) { - try { - Method method = getNmsMethod("SoundCategory", "a"); - - for (Enum anEnum : (Enum[]) getNmsClass("SoundCategory").getEnumConstants()) { - if (!category.equals(method.invoke(anEnum))) { - continue; - } - - return anEnum; - } - } - catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static Enum getSoundCategory(DisguiseType disguiseType) { - if (disguiseType == DisguiseType.PLAYER) - return getSoundCategory("player"); - - Class entityClass = disguiseType.getEntityType().getEntityClass(); - - if (Monster.class.isAssignableFrom(entityClass)) - return getSoundCategory("hostile"); - - if (Ambient.class.isAssignableFrom(entityClass)) - return getSoundCategory("ambient"); - - return getSoundCategory("neutral"); - } - - /** - * Creates the NMS object EnumItemSlot from an EquipmentSlot. - * - * @param slot - * @return null if the equipment slot is null - */ - public static Enum createEnumItemSlot(EquipmentSlot slot) { - Class clazz = getNmsClass("EnumItemSlot"); - - Object[] enums = clazz != null ? clazz.getEnumConstants() : null; - - if (enums == null) - return null; - - switch (slot) { - case HAND: - return (Enum) enums[0]; - case OFF_HAND: - return (Enum) enums[1]; - case FEET: - return (Enum) enums[2]; - case LEGS: - return (Enum) enums[3]; - case CHEST: - return (Enum) enums[4]; - case HEAD: - return (Enum) enums[5]; - default: - return null; - } - } - - /** - * Creates the Bukkit object EquipmentSlot from an EnumItemSlot object. - * - * @return null if the object isn't an nms EnumItemSlot - */ - public static EquipmentSlot createEquipmentSlot(Object enumItemSlot) { - try { - Enum nmsSlot = (Enum) enumItemSlot; - - switch (nmsSlot.name()) { - case "MAINHAND": - return EquipmentSlot.HAND; - case "OFFHAND": - return EquipmentSlot.OFF_HAND; - case "FEET": - return EquipmentSlot.FEET; - case "LEGS": - return EquipmentSlot.LEGS; - case "CHEST": - return EquipmentSlot.CHEST; - case "HEAD": - return EquipmentSlot.HEAD; - } - } - catch (Exception e) { - } - - return null; - } - - /** - * Gets equipment from this entity based on the slot given. - * - * @param slot - * @return null if the disguisedEntity is not an instance of a living entity - */ - public static ItemStack getEquipment(EquipmentSlot slot, Entity disguisedEntity) { - if (!(disguisedEntity instanceof LivingEntity)) - return null; - - switch (slot) { - case HAND: - return ((LivingEntity) disguisedEntity).getEquipment().getItemInMainHand(); - case OFF_HAND: - return ((LivingEntity) disguisedEntity).getEquipment().getItemInOffHand(); - case FEET: - return ((LivingEntity) disguisedEntity).getEquipment().getBoots(); - case LEGS: - return ((LivingEntity) disguisedEntity).getEquipment().getLeggings(); - case CHEST: - return ((LivingEntity) disguisedEntity).getEquipment().getChestplate(); - case HEAD: - return ((LivingEntity) disguisedEntity).getEquipment().getHelmet(); - default: - return null; - } - } - - public static Object getSoundString(Sound sound) { - try { - return getCraftMethod("CraftSound", "getSound", Sound.class).invoke(null, sound); - } - catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - - return null; - } - - public static Object convertInvalidMeta(Object value) { - if (value instanceof Optional) { - Optional opt = (Optional) value; - - if (!opt.isPresent()) - return value; - - Object val = opt.get(); - - if (val instanceof BlockPosition) { - BlockPosition pos = (BlockPosition) val; - - try { - return Optional.of(getNmsConstructor("BlockPosition", int.class, int.class, int.class) - .newInstance(pos.getX(), pos.getY(), pos.getZ())); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } else if (val instanceof WrappedBlockData) { - try { - return Optional.of(((WrappedBlockData) val).getHandle()); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } else if (val instanceof ItemStack) { - val = getNmsItem((ItemStack) val); - - if (val == null) - return Optional.empty(); - else - return Optional.of(val); - } else if (val instanceof WrappedChatComponent) { - return Optional.of(((WrappedChatComponent) val).getHandle()); - } - } else if (value instanceof Vector3F) { - Vector3F angle = (Vector3F) value; - - try { - return getNmsConstructor("Vector3f", float.class, float.class, float.class) - .newInstance(angle.getX(), angle.getY(), angle.getZ()); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } else if (value instanceof Direction) { - try { - return getNmsMethod("EnumDirection", "fromType1", int.class) - .invoke(null, ((Direction) value).ordinal()); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } else if (value instanceof BlockPosition) { - BlockPosition pos = (BlockPosition) value; - - try { - return getNmsConstructor("BlockPosition", int.class, int.class, int.class) - .newInstance(pos.getX(), pos.getY(), pos.getZ()); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } else if (value instanceof ItemStack) { - return getNmsItem((ItemStack) value); - } else if (value instanceof Double) { - return ((Double) value).floatValue(); - } else if (value instanceof NbtWrapper) { - return ((NbtWrapper) value).getHandle(); - } else if (value instanceof WrappedParticle) { - return ((WrappedParticle) value).getHandle(); - } - - return value; - } - - public static String getMinecraftVersion() { - String version = Bukkit.getVersion(); - version = version.substring(version.lastIndexOf(" ") + 1, version.length() - 1); - return version; - } - - public static WrappedDataWatcherObject createDataWatcherObject(int id, Object value) { - if (value == null) - return null; - - value = convertInvalidMeta(value); - - Serializer serializer; - - if (value instanceof Optional) { - Optional opt = (Optional) value; - - if (opt.isPresent()) { - Object val = opt.get(); - Class cl; - Class iBlockData = getNmsClass("IBlockData"); - Class iChat = getNmsClass("IChatBaseComponent"); - - if (iBlockData.isInstance(val)) { - cl = iBlockData; - } else if (iChat.isInstance(val)) { - cl = iChat; - } else { - cl = val.getClass(); - } - - serializer = Registry.get(cl, true); - } else { - serializer = Registry.get(UUID.class, true); - } - } else { - serializer = Registry.get(getNmsClass("ParticleParam").isInstance(value) ? getNmsClass("ParticleParam") : - value.getClass()); - } - - if (serializer == null) { - if (value.getClass().getSimpleName().equals("NBTTagCompound")) - return null; // Handle PaperSpigot's bad coding - - throw new IllegalArgumentException("Unable to find Serializer for " + value + - (value instanceof Optional && ((Optional) value).isPresent() ? - " (" + ((Optional) value).get().getClass().getName() + ")" : - value instanceof Optional || value == null ? "" : " " + value.getClass().getName()) + - "! Are you running " + "the latest " + "version of " + "ProtocolLib?"); - } - - return new WrappedDataWatcherObject(id, serializer); - } - - /** - * This creates a DataWatcherItem usable with WrappedWatchableObject - * - * @param id - * @param value - * @return - */ - public static Object createDataWatcherItem(int id, Object value) { - WrappedDataWatcherObject watcherObject = createDataWatcherObject(id, value); - - Constructor construct = getNmsConstructor("DataWatcher$Item", getNmsClass("DataWatcherObject"), Object.class); - - try { - return construct.newInstance(watcherObject.getHandle(), convertInvalidMeta(value)); - } - catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - - return null; - } - - public static Object createMinecraftKey(String name) { - try { - return getNmsClass("MinecraftKey").getConstructor(String.class).newInstance(name); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static int getEntityType(Object nmsEntity) { - try { - Field entityTypesField = null; - - for (Method method : getNmsClass("Entity").getMethods()) { - if (!method.getReturnType().getSimpleName().equals("EntityTypes")) - continue; - - Object entityType = method.invoke(nmsEntity); - Class typesClass = getNmsClass("IRegistry"); - - Object registry = typesClass.getField("ENTITY_TYPE").get(null); - - return (int) registry.getClass().getMethod("a", Object.class).invoke(registry, entityType); - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - throw new IllegalStateException("Failed to find EntityType for " + nmsEntity.getClass().getSimpleName()); - } - - public static WrappedWatchableObject createWatchable(int index, Object obj) { - Object watcherItem = createDataWatcherItem(index, obj); - - if (watcherItem == null) - return null; - - return new WrappedWatchableObject(watcherItem); - } - - public static int getCombinedIdByItemStack(ItemStack itemStack) { - try { - Object nmsItem = getNmsItem(itemStack); - Object item = getNmsMethod("ItemStack", "getItem").invoke(nmsItem); - Class blockClass = getNmsClass("Block"); - - Object nmsBlock = getNmsMethod(blockClass, "asBlock", getNmsClass("Item")).invoke(null, item); - - Object iBlockData = getNmsMethod(blockClass, "getBlockData").invoke(nmsBlock); - - return (int) getNmsMethod("Block", "getCombinedId", getNmsClass("IBlockData")).invoke(null, iBlockData); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return 0; - } - - public static ItemStack getItemStackByCombinedId(int id) { - try { - Method idMethod = getNmsMethod("Block", "getByCombinedId", int.class); - Object iBlockData = idMethod.invoke(null, id); - Class iBlockClass = getNmsClass("IBlockData"); - - Method getBlock = getNmsMethod(iBlockClass, "getBlock"); - Object block = getBlock.invoke(iBlockData); - - Method getItem = getNmsMethod("Block", "t", iBlockClass); - - return getBukkitItem(getItem.invoke(block, iBlockData)); - } - catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Object getWorldServer(World w) { - try { - return getCraftMethod("CraftWorld", "getHandle").invoke(w); - } - catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - - return null; - } - - public static Object getPlayerInteractManager(World w) { - Object worldServer = getWorldServer(w); - - try { - return getNmsConstructor("PlayerInteractManager", getNmsClass("World")).newInstance(worldServer); - } - catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { - e.printStackTrace(); - } - - return null; - } -} +package me.libraryaddict.disguise.utilities.reflection; + +import com.comphenix.protocol.wrappers.*; +import com.comphenix.protocol.wrappers.EnumWrappers.Direction; +import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry; +import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; +import com.comphenix.protocol.wrappers.nbt.NbtWrapper; +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import org.apache.commons.io.IOUtils; +import org.bukkit.*; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.*; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.*; +import java.nio.ByteBuffer; +import java.util.Optional; +import java.util.UUID; + +public class ReflectionManager { + private static final String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3]; + private static final Class craftItemClass; + private static Method damageAndIdleSoundMethod; + private static final Field entitiesField; + private static final Constructor boundingBoxConstructor; + private static final Method setBoundingBoxMethod; + private static final Method ihmGet; + private static final Field pingField; + private static final Field trackerField; + public static final Field entityCountField; + + static { + try { + Object entity = createEntityInstance("Cow"); + + for (Method method : getNmsClass("EntityLiving").getDeclaredMethods()) { + if (method.getReturnType() != float.class) + continue; + + if (!Modifier.isProtected(method.getModifiers())) + continue; + + if (method.getParameterTypes().length != 0) + continue; + + method.setAccessible(true); + + float value = (Float) method.invoke(entity); + + if ((float) method.invoke(entity) != 0.4f) + continue; + + damageAndIdleSoundMethod = method; + break; + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + craftItemClass = getCraftClass("inventory.CraftItemStack"); + + pingField = getNmsField("EntityPlayer", "ping"); + + trackerField = getNmsField("WorldServer", "tracker"); + + entitiesField = getNmsField("EntityTracker", "trackedEntities"); + + ihmGet = getNmsMethod("IntHashMap", "get", int.class); + + boundingBoxConstructor = getNmsConstructor("AxisAlignedBB", double.class, double.class, double.class, + double.class, double.class, double.class); + + setBoundingBoxMethod = getNmsMethod("Entity", "a", getNmsClass("AxisAlignedBB")); + + entityCountField = getNmsField("Entity", "entityCount"); + + entityCountField.setAccessible(true); + } + + public static YamlConfiguration getPluginYaml(ClassLoader loader) { + try (InputStream stream = loader.getResourceAsStream("plugin.yml")) { + YamlConfiguration config = new YamlConfiguration(); + config.loadFromString(IOUtils.toString(stream, "UTF-8")); + + return config; + } + catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + + return null; + } + + public static int getNewEntityId() { + return getNewEntityId(true); + } + + public static int getNewEntityId(boolean increment) { + try { + int id = entityCountField.getInt(null); + + if (increment) { + entityCountField.set(null, id + 1); + } + + return id; + } + catch (IllegalAccessException e) { + e.printStackTrace(); + } + + return -1; + } + + public static Object createEntityInstance(String entityName) { + try { + Class entityClass = getNmsClass("Entity" + entityName); + Object entityObject; + Object world = getWorldServer(Bukkit.getWorlds().get(0)); + + switch (entityName) { + case "Player": + Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null); + + Object playerinteractmanager = getNmsClass("PlayerInteractManager") + .getDeclaredConstructor(getNmsClass("World")).newInstance(world); + + WrappedGameProfile gameProfile = getGameProfile(new UUID(0, 0), "Steve"); + + entityObject = entityClass + .getDeclaredConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"), + gameProfile.getHandleType(), playerinteractmanager.getClass()) + .newInstance(minecraftServer, world, gameProfile.getHandle(), playerinteractmanager); + break; + case "EnderPearl": + entityObject = entityClass.getDeclaredConstructor(getNmsClass("World"), getNmsClass("EntityLiving")) + .newInstance(world, createEntityInstance("Cow")); + break; + case "Potion": + entityObject = entityClass + .getDeclaredConstructor(getNmsClass("World"), Double.TYPE, Double.TYPE, Double.TYPE, + getNmsClass("ItemStack")) + .newInstance(world, 0d, 0d, 0d, getNmsItem(new ItemStack(Material.SPLASH_POTION))); + break; + case "FishingHook": + entityObject = entityClass.getDeclaredConstructor(getNmsClass("World"), getNmsClass("EntityHuman")) + .newInstance(world, createEntityInstance("Player")); + break; + default: + entityObject = entityClass.getDeclaredConstructor(getNmsClass("World")).newInstance(world); + break; + } + + return entityObject; + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static Object getMobEffectList(int id) { + Method nmsMethod = getNmsMethod("MobEffectList", "fromId", Integer.TYPE); + + try { + return nmsMethod.invoke(null, id); + } + catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + + public static Object createMobEffect(PotionEffect effect) { + return createMobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), + effect.isAmbient(), effect.hasParticles()); + } + + public static Object createMobEffect(int id, int duration, int amplification, boolean ambient, boolean particles) { + try { + return getNmsClass("MobEffect") + .getDeclaredConstructor(getNmsClass("MobEffectList"), Integer.TYPE, Integer.TYPE, Boolean.TYPE, + Boolean.TYPE) + .newInstance(getMobEffectList(id), duration, amplification, ambient, particles); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static FakeBoundingBox getBoundingBox(Entity entity) { + try { + Object boundingBox = getNmsMethod("Entity", "getBoundingBox").invoke(getNmsEntity(entity)); + + double x = 0, y = 0, z = 0; + int stage = 0; + + for (Field field : boundingBox.getClass().getDeclaredFields()) { + if (!field.getType().getSimpleName().equals("double")) { + continue; + } + + stage++; + + switch (stage) { + case 1: + x -= field.getDouble(boundingBox); + break; + case 2: + y -= field.getDouble(boundingBox); + break; + case 3: + z -= field.getDouble(boundingBox); + break; + case 4: + x += field.getDouble(boundingBox); + break; + case 5: + y += field.getDouble(boundingBox); + break; + case 6: + z += field.getDouble(boundingBox); + break; + default: + throw new Exception("Error while setting the bounding box, more doubles than I thought??"); + } + } + + return new FakeBoundingBox(x, y, z); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Entity getBukkitEntity(Object nmsEntity) { + try { + return (Entity) getNmsMethod("Entity", "getBukkitEntity").invoke(nmsEntity); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static ItemStack getBukkitItem(Object nmsItem) { + try { + return (ItemStack) craftItemClass.getMethod("asBukkitCopy", getNmsClass("ItemStack")).invoke(null, nmsItem); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static String getBukkitVersion() { + return bukkitVersion; + } + + public static Class getCraftClass(String className) { + try { + return Class.forName("org.bukkit.craftbukkit." + getBukkitVersion() + "." + className); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static Constructor getCraftConstructor(Class clazz, Class... parameters) { + try { + Constructor declaredConstructor = clazz.getDeclaredConstructor(parameters); + declaredConstructor.setAccessible(true); + return declaredConstructor; + } + catch (NoSuchMethodException e) { + e.printStackTrace(); + } + + return null; + } + + public static Constructor getCraftConstructor(String className, Class... parameters) { + return getCraftConstructor(getCraftClass(className), parameters); + } + + public static Object getCraftSound(Sound sound) { + try { + return getCraftClass("CraftSound").getMethod("getSoundEffect", String.class) + .invoke(null, getSoundString(sound)); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Object getEntityTrackerEntry(Entity target) throws Exception { + Object world = getWorldServer(target.getWorld()); + Object tracker = trackerField.get(world); + Object trackedEntities = entitiesField.get(tracker); + + return ihmGet.invoke(trackedEntities, target.getEntityId()); + } + + public static Object getMinecraftServer() { + try { + return getCraftMethod("CraftServer", "getServer").invoke(Bukkit.getServer()); + } + catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + return null; + } + + public static String getEnumArt(Art art) { + try { + Object enumArt = getCraftClass("CraftArt").getMethod("BukkitToNotch", Art.class).invoke(null, art); + for (Field field : enumArt.getClass().getDeclaredFields()) { + if (field.getType() == String.class) { + return (String) field.get(enumArt); + } + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Object getBlockPosition(int x, int y, int z) { + try { + return getNmsClass("BlockPosition").getDeclaredConstructor(int.class, int.class, int.class) + .newInstance(x, y, z); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Enum getEnumDirection(int direction) { + try { + return (Enum) getNmsMethod("EnumDirection", "fromType2", int.class).invoke(null, direction); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Enum getEnumPlayerInfoAction(int action) { + try { + return (Enum) getNmsClass("PacketPlayOutPlayerInfo$EnumPlayerInfoAction").getEnumConstants()[action]; + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Object getPlayerInfoData(Object playerInfoPacket, WrappedGameProfile gameProfile) { + try { + Object playerListName = getNmsClass("ChatComponentText").getDeclaredConstructor(String.class) + .newInstance(gameProfile.getName()); + + return getNmsClass("PacketPlayOutPlayerInfo$PlayerInfoData") + .getDeclaredConstructor(getNmsClass("PacketPlayOutPlayerInfo"), gameProfile.getHandleType(), + int.class, getNmsClass("EnumGamemode"), getNmsClass("IChatBaseComponent")) + .newInstance(playerInfoPacket, gameProfile.getHandle(), 0, + getNmsClass("EnumGamemode").getEnumConstants()[1], playerListName); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static WrappedGameProfile getGameProfile(Player player) { + return WrappedGameProfile.fromPlayer(player); + } + + public static WrappedGameProfile getGameProfile(UUID uuid, String playerName) { + try { + return new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), playerName); + } + catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + public static WrappedGameProfile getClonedProfile(WrappedGameProfile gameProfile) { + return getGameProfileWithThisSkin(null, gameProfile.getName(), gameProfile); + } + + public static WrappedGameProfile getGameProfileWithThisSkin(UUID uuid, String playerName, + WrappedGameProfile profileWithSkin) { + try { + WrappedGameProfile gameProfile = new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), playerName); + + if (profileWithSkin != null) { + gameProfile.getProperties().putAll(profileWithSkin.getProperties()); + } + + return gameProfile; + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + /** + * Used for generating a UUID with a custom version instead of the default 4. Workaround for China's NetEase servers + */ + private static UUID getRandomUUID() { + UUID uuid = UUID.randomUUID(); + + if (DisguiseConfig.getUUIDGeneratedVersion() == 4) { + return uuid; + } + + ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + + bb.putLong(uuid.getMostSignificantBits()); + bb.putLong(uuid.getLeastSignificantBits()); + + bb.put(6, (byte) (bb.get(6) & 0x0f)); // clear version + bb.put(6, (byte) (bb.get(6) | DisguiseConfig.getUUIDGeneratedVersion())); // set to version X (Default 4) + + bb.position(0); + + long firstLong = bb.getLong(); + long secondLong = bb.getLong(); + + return new UUID(firstLong, secondLong); + } + + public static Class getNmsClass(String className) { + try { + return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static Class getNmsClassIgnoreErrors(String className) { + try { + return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className); + } + catch (Exception ignored) { + } + + return null; + } + + public static Constructor getNmsConstructor(Class clazz, Class... parameters) { + try { + Constructor declaredConstructor = clazz.getDeclaredConstructor(parameters); + declaredConstructor.setAccessible(true); + return declaredConstructor; + } + catch (NoSuchMethodException e) { + e.printStackTrace(); + } + + return null; + } + + public static Constructor getNmsConstructor(String className, Class... parameters) { + return getNmsConstructor(getNmsClass(className), parameters); + } + + public static Object getNmsEntity(Entity entity) { + try { + return getCraftClass("entity.CraftEntity").getMethod("getHandle").invoke(entity); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Field getNmsField(Class clazz, String fieldName) { + try { + Field declaredField = clazz.getDeclaredField(fieldName); + declaredField.setAccessible(true); + + return declaredField; + } + catch (NoSuchFieldException e) { + e.printStackTrace(); + } + + return null; + } + + public static Field getNmsField(String className, String fieldName) { + return getNmsField(getNmsClass(className), fieldName); + } + + public static Object getNmsItem(ItemStack itemstack) { + try { + return craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemstack); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static Method getCraftMethod(String className, String methodName, Class... parameters) { + return getCraftMethod(getCraftClass(className), methodName, parameters); + } + + public static Method getCraftMethod(Class clazz, String methodName, Class... parameters) { + try { + Method declaredMethod = clazz.getDeclaredMethod(methodName, parameters); + declaredMethod.setAccessible(true); + + return declaredMethod; + } + catch (NoSuchMethodException e) { + e.printStackTrace(); + } + + return null; + } + + public static Method getNmsMethod(Class clazz, String methodName, Class... parameters) { + try { + Method declaredMethod = clazz.getDeclaredMethod(methodName, parameters); + declaredMethod.setAccessible(true); + + return declaredMethod; + } + catch (NoSuchMethodException e) { + e.printStackTrace(); + } + + return null; + } + + public static Method getNmsMethod(String className, String methodName, Class... parameters) { + return getNmsMethod(getNmsClass(className), methodName, parameters); + } + + public static double getPing(Player player) { + try { + return (double) pingField.getInt(ReflectionManager.getNmsEntity(player)); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return 0; + } + + public static float[] getSize(Entity entity) { + try { + float length = getNmsField("Entity", "length").getFloat(getNmsEntity(entity)); + float width = getNmsField("Entity", "width").getFloat(getNmsEntity(entity)); + + float height = (Float) getNmsMethod("Entity", "getHeadHeight").invoke(getNmsEntity(entity)); + return new float[]{length, width, height}; + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static WrappedGameProfile getSkullBlob(WrappedGameProfile gameProfile) { + try { + Object minecraftServer = getMinecraftServer(); + + for (Method method : getNmsClass("MinecraftServer").getMethods()) { + if (method.getReturnType().getSimpleName().equals("MinecraftSessionService")) { + Object session = method.invoke(minecraftServer); + + return WrappedGameProfile.fromHandle(session.getClass() + .getDeclaredMethod("fillProfileProperties", gameProfile.getHandleType(), boolean.class) + .invoke(session, gameProfile.getHandle(), true)); + } + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Float getSoundModifier(Object entity) { + try { + return (Float) damageAndIdleSoundMethod.invoke(entity); + } + catch (Exception ignored) { + } + return null; + } + + public static WrappedGameProfile grabProfileAddUUID(String playername) { + try { + Object minecraftServer = getMinecraftServer(); + + for (Method method : getNmsClass("MinecraftServer").getMethods()) { + if (method.getReturnType().getSimpleName().equals("GameProfileRepository")) { + Object agent = Class.forName("com.mojang.authlib.Agent").getDeclaredField("MINECRAFT").get(null); + + LibsProfileLookupCaller callback = new LibsProfileLookupCaller(); + Object profileRepo = method.invoke(minecraftServer); + + method.getReturnType().getMethod("findProfilesByNames", String[].class, agent.getClass(), + Class.forName("com.mojang.authlib.ProfileLookupCallback")) + .invoke(profileRepo, new String[]{playername}, agent, callback); + + if (callback.getGameProfile() != null) { + return callback.getGameProfile(); + } + + return getGameProfile(null, playername); + } + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static void setBoundingBox(Entity entity, FakeBoundingBox newBox) { + try { + Location loc = entity.getLocation(); + + Object boundingBox = boundingBoxConstructor + .newInstance(loc.getX() - (newBox.getX() / 2), loc.getY(), loc.getZ() - (newBox.getZ() / 2), + loc.getX() + (newBox.getX() / 2), loc.getY() + newBox.getY(), + loc.getZ() + (newBox.getZ() / 2)); + + setBoundingBoxMethod.invoke(getNmsEntity(entity), boundingBox); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static Enum getSoundCategory(String category) { + try { + Method method = getNmsMethod("SoundCategory", "a"); + + for (Enum anEnum : (Enum[]) getNmsClass("SoundCategory").getEnumConstants()) { + if (!category.equals(method.invoke(anEnum))) { + continue; + } + + return anEnum; + } + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static Enum getSoundCategory(DisguiseType disguiseType) { + if (disguiseType == DisguiseType.PLAYER) + return getSoundCategory("player"); + + Class entityClass = disguiseType.getEntityType().getEntityClass(); + + if (Monster.class.isAssignableFrom(entityClass)) + return getSoundCategory("hostile"); + + if (Ambient.class.isAssignableFrom(entityClass)) + return getSoundCategory("ambient"); + + return getSoundCategory("neutral"); + } + + /** + * Creates the NMS object EnumItemSlot from an EquipmentSlot. + * + * @param slot + * @return null if the equipment slot is null + */ + public static Enum createEnumItemSlot(EquipmentSlot slot) { + Class clazz = getNmsClass("EnumItemSlot"); + + Object[] enums = clazz != null ? clazz.getEnumConstants() : null; + + if (enums == null) + return null; + + switch (slot) { + case HAND: + return (Enum) enums[0]; + case OFF_HAND: + return (Enum) enums[1]; + case FEET: + return (Enum) enums[2]; + case LEGS: + return (Enum) enums[3]; + case CHEST: + return (Enum) enums[4]; + case HEAD: + return (Enum) enums[5]; + default: + return null; + } + } + + /** + * Creates the Bukkit object EquipmentSlot from an EnumItemSlot object. + * + * @return null if the object isn't an nms EnumItemSlot + */ + public static EquipmentSlot createEquipmentSlot(Object enumItemSlot) { + try { + Enum nmsSlot = (Enum) enumItemSlot; + + switch (nmsSlot.name()) { + case "MAINHAND": + return EquipmentSlot.HAND; + case "OFFHAND": + return EquipmentSlot.OFF_HAND; + case "FEET": + return EquipmentSlot.FEET; + case "LEGS": + return EquipmentSlot.LEGS; + case "CHEST": + return EquipmentSlot.CHEST; + case "HEAD": + return EquipmentSlot.HEAD; + } + } + catch (Exception e) { + } + + return null; + } + + /** + * Gets equipment from this entity based on the slot given. + * + * @param slot + * @return null if the disguisedEntity is not an instance of a living entity + */ + public static ItemStack getEquipment(EquipmentSlot slot, Entity disguisedEntity) { + if (!(disguisedEntity instanceof LivingEntity)) + return null; + + switch (slot) { + case HAND: + return ((LivingEntity) disguisedEntity).getEquipment().getItemInMainHand(); + case OFF_HAND: + return ((LivingEntity) disguisedEntity).getEquipment().getItemInOffHand(); + case FEET: + return ((LivingEntity) disguisedEntity).getEquipment().getBoots(); + case LEGS: + return ((LivingEntity) disguisedEntity).getEquipment().getLeggings(); + case CHEST: + return ((LivingEntity) disguisedEntity).getEquipment().getChestplate(); + case HEAD: + return ((LivingEntity) disguisedEntity).getEquipment().getHelmet(); + default: + return null; + } + } + + public static Object getSoundString(Sound sound) { + try { + return getCraftMethod("CraftSound", "getSound", Sound.class).invoke(null, sound); + } + catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + + public static Object convertInvalidMeta(Object value) { + if (value instanceof Optional) { + Optional opt = (Optional) value; + + if (!opt.isPresent()) + return value; + + Object val = opt.get(); + + if (val instanceof BlockPosition) { + BlockPosition pos = (BlockPosition) val; + + try { + return Optional.of(getNmsConstructor("BlockPosition", int.class, int.class, int.class) + .newInstance(pos.getX(), pos.getY(), pos.getZ())); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } else if (val instanceof WrappedBlockData) { + try { + return Optional.of(((WrappedBlockData) val).getHandle()); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } else if (val instanceof ItemStack) { + val = getNmsItem((ItemStack) val); + + if (val == null) + return Optional.empty(); + else + return Optional.of(val); + } else if (val instanceof WrappedChatComponent) { + return Optional.of(((WrappedChatComponent) val).getHandle()); + } + } else if (value instanceof Vector3F) { + Vector3F angle = (Vector3F) value; + + try { + return getNmsConstructor("Vector3f", float.class, float.class, float.class) + .newInstance(angle.getX(), angle.getY(), angle.getZ()); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } else if (value instanceof Direction) { + try { + return getNmsMethod("EnumDirection", "fromType1", int.class) + .invoke(null, ((Direction) value).ordinal()); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } else if (value instanceof BlockPosition) { + BlockPosition pos = (BlockPosition) value; + + try { + return getNmsConstructor("BlockPosition", int.class, int.class, int.class) + .newInstance(pos.getX(), pos.getY(), pos.getZ()); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } else if (value instanceof ItemStack) { + return getNmsItem((ItemStack) value); + } else if (value instanceof Double) { + return ((Double) value).floatValue(); + } else if (value instanceof NbtWrapper) { + return ((NbtWrapper) value).getHandle(); + } else if (value instanceof WrappedParticle) { + return ((WrappedParticle) value).getHandle(); + } + + return value; + } + + public static String getMinecraftVersion() { + String version = Bukkit.getVersion(); + version = version.substring(version.lastIndexOf(" ") + 1, version.length() - 1); + return version; + } + + public static WrappedDataWatcherObject createDataWatcherObject(int id, Object value) { + if (value == null) + return null; + + value = convertInvalidMeta(value); + + Serializer serializer; + + if (value instanceof Optional) { + Optional opt = (Optional) value; + + if (opt.isPresent()) { + Object val = opt.get(); + Class cl; + Class iBlockData = getNmsClass("IBlockData"); + Class iChat = getNmsClass("IChatBaseComponent"); + + if (iBlockData.isInstance(val)) { + cl = iBlockData; + } else if (iChat.isInstance(val)) { + cl = iChat; + } else { + cl = val.getClass(); + } + + serializer = Registry.get(cl, true); + } else { + serializer = Registry.get(UUID.class, true); + } + } else { + serializer = Registry.get(getNmsClass("ParticleParam").isInstance(value) ? getNmsClass("ParticleParam") : + value.getClass()); + } + + if (serializer == null) { + if (value.getClass().getSimpleName().equals("NBTTagCompound")) + return null; // Handle PaperSpigot's bad coding + + throw new IllegalArgumentException("Unable to find Serializer for " + value + + (value instanceof Optional && ((Optional) value).isPresent() ? + " (" + ((Optional) value).get().getClass().getName() + ")" : + value instanceof Optional || value == null ? "" : " " + value.getClass().getName()) + + "! Are you running " + "the latest " + "version of " + "ProtocolLib?"); + } + + return new WrappedDataWatcherObject(id, serializer); + } + + /** + * This creates a DataWatcherItem usable with WrappedWatchableObject + * + * @param id + * @param value + * @return + */ + public static Object createDataWatcherItem(int id, Object value) { + WrappedDataWatcherObject watcherObject = createDataWatcherObject(id, value); + + Constructor construct = getNmsConstructor("DataWatcher$Item", getNmsClass("DataWatcherObject"), Object.class); + + try { + return construct.newInstance(watcherObject.getHandle(), convertInvalidMeta(value)); + } + catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + + public static Object createMinecraftKey(String name) { + try { + return getNmsClass("MinecraftKey").getConstructor(String.class).newInstance(name); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static int getEntityType(Object nmsEntity) { + try { + Field entityTypesField = null; + + for (Method method : getNmsClass("Entity").getMethods()) { + if (!method.getReturnType().getSimpleName().equals("EntityTypes")) + continue; + + Object entityType = method.invoke(nmsEntity); + Class typesClass = getNmsClass("IRegistry"); + + Object registry = typesClass.getField("ENTITY_TYPE").get(null); + + return (int) registry.getClass().getMethod("a", Object.class).invoke(registry, entityType); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + throw new IllegalStateException("Failed to find EntityType for " + nmsEntity.getClass().getSimpleName()); + } + + public static WrappedWatchableObject createWatchable(int index, Object obj) { + Object watcherItem = createDataWatcherItem(index, obj); + + if (watcherItem == null) + return null; + + return new WrappedWatchableObject(watcherItem); + } + + public static int getCombinedIdByItemStack(ItemStack itemStack) { + try { + Object nmsItem = getNmsItem(itemStack); + Object item = getNmsMethod("ItemStack", "getItem").invoke(nmsItem); + Class blockClass = getNmsClass("Block"); + + Object nmsBlock = getNmsMethod(blockClass, "asBlock", getNmsClass("Item")).invoke(null, item); + + Object iBlockData = getNmsMethod(blockClass, "getBlockData").invoke(nmsBlock); + + return (int) getNmsMethod("Block", "getCombinedId", getNmsClass("IBlockData")).invoke(null, iBlockData); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return 0; + } + + public static ItemStack getItemStackByCombinedId(int id) { + try { + Method idMethod = getNmsMethod("Block", "getByCombinedId", int.class); + Object iBlockData = idMethod.invoke(null, id); + Class iBlockClass = getNmsClass("IBlockData"); + + Method getBlock = getNmsMethod(iBlockClass, "getBlock"); + Object block = getBlock.invoke(iBlockData); + + Method getItem = getNmsMethod("Block", "t", iBlockClass); + + return getBukkitItem(getItem.invoke(block, iBlockData)); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + public static Object getWorldServer(World w) { + try { + return getCraftMethod("CraftWorld", "getHandle").invoke(w); + } + catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + + public static Object getPlayerInteractManager(World w) { + Object worldServer = getWorldServer(w); + + try { + return getNmsConstructor("PlayerInteractManager", getNmsClass("World")).newInstance(worldServer); + } + catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java b/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java similarity index 99% rename from src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java rename to src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java index 49b4edea..410bfc93 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java @@ -1,5 +1,6 @@ -package me.libraryaddict.disguise.utilities; +package me.libraryaddict.disguise.utilities.translations; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; import org.apache.commons.lang3.StringUtils; import org.bukkit.ChatColor; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java b/src/main/java/me/libraryaddict/disguise/utilities/translations/TranslateFiller.java similarity index 97% rename from src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java rename to src/main/java/me/libraryaddict/disguise/utilities/translations/TranslateFiller.java index 41319a6c..dfd297d4 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/translations/TranslateFiller.java @@ -1,6 +1,7 @@ -package me.libraryaddict.disguise.utilities; +package me.libraryaddict.disguise.utilities.translations; import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.utilities.reflection.ClassGetter; import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/TranslateType.java b/src/main/java/me/libraryaddict/disguise/utilities/translations/TranslateType.java similarity index 97% rename from src/main/java/me/libraryaddict/disguise/utilities/TranslateType.java rename to src/main/java/me/libraryaddict/disguise/utilities/translations/TranslateType.java index f6aea7c6..795db337 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/TranslateType.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/translations/TranslateType.java @@ -1,6 +1,8 @@ -package me.libraryaddict.disguise.utilities; +package me.libraryaddict.disguise.utilities.translations; import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.LibsPremium; import org.apache.commons.lang.StringEscapeUtils; import org.bukkit.ChatColor; import org.bukkit.configuration.file.YamlConfiguration;