From f498867d5cc8fd0c71428f9302c15156f5b33ce8 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Tue, 14 Jun 2016 21:08:53 +1200 Subject: [PATCH] Fix up player disguises skins --- config.yml | 260 +++++++++--------- .../disguisetypes/PlayerDisguise.java | 129 +++++---- .../disguise/utilities/DisguiseUtilities.java | 62 +++-- .../disguise/utilities/PacketsManager.java | 2 +- .../disguise/utilities/ReflectionManager.java | 7 + 5 files changed, 256 insertions(+), 204 deletions(-) diff --git a/config.yml b/config.yml index 282c1e11..2e89e3a0 100644 --- a/config.yml +++ b/config.yml @@ -1,130 +1,130 @@ -# Shall I notify people of a LibsDisguises update? -NotifyUpdate: true -# Whats the permission to get the notification? -Permission: 'libsdisguises.update' -# Whats the max size allowed for command disguiseradius -DisguiseRadiusMax: 50 -# Whats the max size allowed for command undisguiseradius -UndisguiseRadiusMax: 50 -# Shall the players view their disguises? -# Best used when viewing yourself in 3rd person -ViewSelfDisguises: true -# Shall I disguise the sounds? -# This turns your damage sound into a MOOOO -DisguiseSounds: true -# Shall the disguised hear their disguise sounds or their damage sounds. -# I disable this as it can be a little confusing when not used with self disguises -HearSelfDisguise: true -# Shall I send the velocity packets? I REALLY recommend you don't disable. -# This is the only thing allowing the mobs to fly without glitching out. -SendVelocity: true -# For self disguises, they need to have the armor and the held item removed -# Else they see floating armor, floating held items. -# This turns the items invisible in the disguised players inventory. It does not actually remove them! -RemoveArmor: true -RemoveHeldItem: false -# If you set a disguise to burning, it will no longer be able to be shown as sneaking or invisible. -# Set this to true if you want the disguise to get the animations of the disguised entity. Such as invisible, on fire, sprinting, sneaking, blocking -# This is only valid if you set a animation on the disguise itself. Because the entitys animations are applied otherwise. -AddEntityAnimations: true -# When a sheep or wolf is right clicked with dye. The client automatically assumes it was successful and displays the sheeps wool or the wolfs collar as dyed. -# This is a option that either prevents that happening, or it changes their color officially in the plugin so that everyone sees it changed. -# Its currently set to false which means that the color is not changed and will refresh itself to the player. -# Please note that this will not remove the dye from their hands. This also does not check if the disguised entity is actually a sheep/wolf and wants a say in its color. -DyeableSheep: false -DyeableWolf: false -# This is only called into action when the disguise is constructed using the commands. -# And when the disguise supports that. This will not be used at all for plugins constructing the disguises for instance. -# Such as prophunt. Its also false because its kind of a retarded feature. -# This is pretty simple. It shows the players displayname (Name as it appears in chat) above their head. -# This also overrides any custom name they have set in their disguise options. -ShowNamesAboveDisguises: false -# This supports the above option. -# If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not. -NameAboveHeadAlwaysVisible: true -# This modifys the bounding box, This is stuff like can a arrow hit them. -# If you turn this to true, arrows will act like they hit the disguise in the right place! -# So someone disguised as a enderdragon will easily get shot down by arrows! -# This WILL conflict with NoCheatPlus. Other plugins may also get problems. -# This shouldn't really be enabled for players as it also interferes with their movement because the server thinks the player is larger than he really is. -# That makes the player unable to approach this building because the server thinks he is trying to glitch inside blocks. -ModifyBoundingBox: false -# This prevents disguised players from being targeted by monsters. -# This doesn't prevent their targeting you if already targeting when disguised -# They will just ignore you unless provoked. -MonstersIgnoreDisguises: false -# Sigh. People are going to want this. -# So lets make your disguise blown if you are attacked.. -# Works only for disguised players when attacked by a entity (arrow, monster. etc) -# This will blow all disguises he has on him -BlowDisguises: false -BlownDisguiseMessage: '&cYour disguise was blown!' - -#Stop shulker disguises from moving, they're weird. This option only effects PLAYERS that are disguised, other entities disguised as shulkers will NOT be effected! -StopShulkerDisguisesFromMoving: true - -# A option to choose how many seconds a DisguiseEntity command is valid for people to right click a entity to disguise it before expiring -DisguiseEntityExpire: 10 - -# Another option to choose the same thing for DisguiseClone command -DisguiseCloneExpire: 10 -# Max disguises to store at a time with the DisguiseClone command -DisguiseCloneSize: 3 - -# This I don't really recommend turning on as it can make a memory leak.. -# These disguises, as normal will not persist after a server restart. -# There is also no EntityDeath option as entities do not revive after death. -KeepDisguises: - EntityDespawn: false - PlayerDeath: false - PlayerLogout: false - -# This controls if a entitys max health is determined by the entity, or by the disguise. -# Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health. -# Else it will be 1/20 of the boss bar when he is full health. -# Setting this in LivingWatcher overrides both values. -MaxHealthDeterminedByEntity: true - -# This here is a option to turn off misc disguises. -# This means you can not have a living entity disguise as a non-living entity. -# This disables the Attributes packet, Non-living entities can still disguise as other non-living -# This means that the above option will not work as it uses the attribute packet. -MiscDisguisesForLiving: true - -# Turn this to true to have players undisguised when switching worlds -UndisguiseOnWorldChange: false - -# Contact Mojang's servers? Disabling this option will disable player skin disguises! -ContactMojangServers: true - -# This will help performance, especially with CPU -# Due to safety reasons, self disguises can never have their packets disabled. -PacketsEnabled: - # This disables the animation packet. If a disguised entity sends a animation packet and they are using a non-living disguise. People will crash. - # Disabling this also means that if a player disguised as a non-player leaves a bug. People will crash - Animation: true - # Disabling this means that you can't use the setSleeping option on a player disguise. Also you will crash anyone watching when you try to sleep in a bed if disguised as a non-player - # This also sends a chunk packet at key positions else it doesn't work for 1.8. Lazyness means it does it for older versions too currently. - Bed: true - # This disguises the collect packet. If a living entity disguised as a non-living entity picks up a item. People will crash. This fixes it - # This also fixes people crashing if a item disguised as a sleeping player is picked up - Only true if Bed is enabled as well - Collect: true - # This disables a fix for when a disguised entity wearing armor dies, if the disguise can wear armor. It drops unpickupable items to anyone watching. - EntityStatus: true - # Entity equipment is the packets that are sent to ensure that a disguise has or doesn't have armor, and their held item. - # Disabling this means that any disguises which can wear armor or hold items will show the armor/held item that the disguised is wearing. - Equipment: true - # This doesn't actually disable the packet. It would introduce problems. Instead it does the next best thing and caches the data. - # This means that entity metadata will not change, and will only be sent in the spawn packet. - # This is good if performance is extremely in need. - # This is bad to disable unless you are ONLY going to use the disguises for decorations. - # To be honest. This is basically "Disable entity animations". That option is called 'AddEntityAnimations' in the config but unlike that, this is always in effect. - # Animations set by use of the api or through the disguise command are still in effect. - Metadata: true - # Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up. - # If you are using the Item_Frame disguise, when a packet is sent (Roughly every 2min) the disguise will bug up until they move. - Movement: true - # Disable this if you don't mind crashing everytime you see someone riding something disguised as a non-living entity - Riding: true - # When disguised as a wither skull, it sends a look packet every tick so that the wither skull is facing the right way. - WitherSkull: true +# Shall I notify people of a LibsDisguises update? +NotifyUpdate: true +# Whats the permission to get the notification? +Permission: 'libsdisguises.update' +# Whats the max size allowed for command disguiseradius +DisguiseRadiusMax: 50 +# Whats the max size allowed for command undisguiseradius +UndisguiseRadiusMax: 50 +# Shall the players view their disguises? +# Best used when viewing yourself in 3rd person +ViewSelfDisguises: true +# Shall I disguise the sounds? +# This turns your damage sound into a MOOOO +DisguiseSounds: true +# Shall the disguised hear their disguise sounds or their damage sounds. +# I disable this as it can be a little confusing when not used with self disguises +HearSelfDisguise: true +# Shall I send the velocity packets? I REALLY recommend you don't disable. +# This is the only thing allowing the mobs to fly without glitching out. +SendVelocity: true +# For self disguises, they need to have the armor and the held item removed +# Else they see floating armor, floating held items. +# This turns the items invisible in the disguised players inventory. It does not actually remove them! +RemoveArmor: true +RemoveHeldItem: false +# If you set a disguise to burning, it will no longer be able to be shown as sneaking or invisible. +# Set this to true if you want the disguise to get the animations of the disguised entity. Such as invisible, on fire, sprinting, sneaking, blocking +# This is only valid if you set a animation on the disguise itself. Because the entitys animations are applied otherwise. +AddEntityAnimations: true +# When a sheep or wolf is right clicked with dye. The client automatically assumes it was successful and displays the sheeps wool or the wolfs collar as dyed. +# This is a option that either prevents that happening, or it changes their color officially in the plugin so that everyone sees it changed. +# Its currently set to false which means that the color is not changed and will refresh itself to the player. +# Please note that this will not remove the dye from their hands. This also does not check if the disguised entity is actually a sheep/wolf and wants a say in its color. +DyeableSheep: false +DyeableWolf: false +# This is only called into action when the disguise is constructed using the commands. +# And when the disguise supports that. This will not be used at all for plugins constructing the disguises for instance. +# Such as prophunt. Its also false because its kind of a retarded feature. +# This is pretty simple. It shows the players displayname (Name as it appears in chat) above their head. +# This also overrides any custom name they have set in their disguise options. +ShowNamesAboveDisguises: false +# This supports the above option. +# If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not. +NameAboveHeadAlwaysVisible: true +# This modifys the bounding box, This is stuff like can a arrow hit them. +# If you turn this to true, arrows will act like they hit the disguise in the right place! +# So someone disguised as a enderdragon will easily get shot down by arrows! +# This WILL conflict with NoCheatPlus. Other plugins may also get problems. +# This shouldn't really be enabled for players as it also interferes with their movement because the server thinks the player is larger than he really is. +# That makes the player unable to approach this building because the server thinks he is trying to glitch inside blocks. +ModifyBoundingBox: false +# This prevents disguised players from being targeted by monsters. +# This doesn't prevent their targeting you if already targeting when disguised +# They will just ignore you unless provoked. +MonstersIgnoreDisguises: false +# Sigh. People are going to want this. +# So lets make your disguise blown if you are attacked.. +# Works only for disguised players when attacked by a entity (arrow, monster. etc) +# This will blow all disguises he has on him +BlowDisguises: false +BlownDisguiseMessage: '&cYour disguise was blown!' + +#Stop shulker disguises from moving, they're weird. This option only effects PLAYERS that are disguised, other entities disguised as shulkers will NOT be effected! +StopShulkerDisguisesFromMoving: true + +# A option to choose how many seconds a DisguiseEntity command is valid for people to right click a entity to disguise it before expiring +DisguiseEntityExpire: 10 + +# Another option to choose the same thing for DisguiseClone command +DisguiseCloneExpire: 10 +# Max disguises to store at a time with the DisguiseClone command +DisguiseCloneSize: 3 + +# This I don't really recommend turning on as it can make a memory leak.. +# These disguises, as normal will not persist after a server restart. +# There is also no EntityDeath option as entities do not revive after death. +KeepDisguises: + EntityDespawn: false + PlayerDeath: false + PlayerLogout: false + +# This controls if a entitys max health is determined by the entity, or by the disguise. +# Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health. +# Else it will be 1/20 of the boss bar when he is full health. +# Setting this in LivingWatcher overrides both values. +MaxHealthDeterminedByEntity: true + +# This here is a option to turn off misc disguises. +# This means you can not have a living entity disguise as a non-living entity. +# This disables the Attributes packet, Non-living entities can still disguise as other non-living +# This means that the above option will not work as it uses the attribute packet. +MiscDisguisesForLiving: true + +# Turn this to true to have players undisguised when switching worlds +UndisguiseOnWorldChange: false + +# Contact Mojang's servers? Disabling this option will disable player skin disguises! +ContactMojangServers: true + +# This will help performance, especially with CPU +# Due to safety reasons, self disguises can never have their packets disabled. +PacketsEnabled: + # This disables the animation packet. If a disguised entity sends a animation packet and they are using a non-living disguise. People will crash. + # Disabling this also means that if a player disguised as a non-player leaves a bug. People will crash + Animation: true + # Disabling this means that you can't use the setSleeping option on a player disguise. Also you will crash anyone watching when you try to sleep in a bed if disguised as a non-player + # This also sends a chunk packet at key positions else it doesn't work for 1.8. Lazyness means it does it for older versions too currently. + Bed: true + # This disguises the collect packet. If a living entity disguised as a non-living entity picks up a item. People will crash. This fixes it + # This also fixes people crashing if a item disguised as a sleeping player is picked up - Only true if Bed is enabled as well + Collect: true + # This disables a fix for when a disguised entity wearing armor dies, if the disguise can wear armor. It drops unpickupable items to anyone watching. + EntityStatus: true + # Entity equipment is the packets that are sent to ensure that a disguise has or doesn't have armor, and their held item. + # Disabling this means that any disguises which can wear armor or hold items will show the armor/held item that the disguised is wearing. + Equipment: true + # This doesn't actually disable the packet. It would introduce problems. Instead it does the next best thing and caches the data. + # This means that entity metadata will not change, and will only be sent in the spawn packet. + # This is good if performance is extremely in need. + # This is bad to disable unless you are ONLY going to use the disguises for decorations. + # To be honest. This is basically "Disable entity animations". That option is called 'AddEntityAnimations' in the config but unlike that, this is always in effect. + # Animations set by use of the api or through the disguise command are still in effect. + Metadata: true + # Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up. + # If you are using the Item_Frame disguise, when a packet is sent (Roughly every 2min) the disguise will bug up until they move. + Movement: true + # Disable this if you don't mind crashing everytime you see someone riding something disguised as a non-living entity + Riding: true + # When disguised as a wither skull, it sends a look packet every tick so that the wither skull is facing the right way. + WitherSkull: true diff --git a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index 38674d42..869980e8 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -14,28 +14,14 @@ import me.libraryaddict.disguise.utilities.ReflectionManager; public class PlayerDisguise extends TargetedDisguise { - private LibsProfileLookup currentLookup; private WrappedGameProfile gameProfile; private String playerName; private String skinToUse; - public PlayerDisguise(String name) + private PlayerDisguise() { - if (name.length() > 16) - { - name = name.substring(0, 16); - } - - playerName = name; - createDisguise(DisguiseType.PLAYER); - } - - public PlayerDisguise(String name, String skinToUse) - { - this(name); - - setSkin(skinToUse); + // Internal usage only } public PlayerDisguise(Player player) @@ -48,18 +34,40 @@ public class PlayerDisguise extends TargetedDisguise this(ReflectionManager.getGameProfile(player), ReflectionManager.getGameProfile(skinToUse)); } + public PlayerDisguise(String name) + { + setName(name); + setSkin(name); + + createDisguise(DisguiseType.PLAYER); + } + + public PlayerDisguise(String name, String skinToUse) + { + setName(name); + setSkin(skinToUse); + + createDisguise(DisguiseType.PLAYER); + } + public PlayerDisguise(WrappedGameProfile gameProfile) { - this(gameProfile.getName()); + setName(gameProfile.getName()); this.gameProfile = gameProfile; + + createDisguise(DisguiseType.PLAYER); } public PlayerDisguise(WrappedGameProfile gameProfile, WrappedGameProfile skinToUse) { - this(gameProfile); + setName(gameProfile.getName()); + + this.gameProfile = gameProfile; setSkin(skinToUse); + + createDisguise(DisguiseType.PLAYER); } @Override @@ -77,12 +85,14 @@ public class PlayerDisguise extends TargetedDisguise @Override public PlayerDisguise clone() { - PlayerDisguise disguise = new PlayerDisguise(getName()); + PlayerDisguise disguise = new PlayerDisguise(); + + disguise.playerName = getName(); if (disguise.currentLookup == null && disguise.gameProfile != null) { disguise.skinToUse = getSkin(); - disguise.gameProfile = gameProfile; + disguise.gameProfile = ReflectionManager.getClonedProfile(getGameProfile()); } else { @@ -98,12 +108,9 @@ public class PlayerDisguise extends TargetedDisguise disguise.setModifyBoundingBox(isModifyBoundingBox()); disguise.setWatcher(getWatcher().clone(disguise)); - return disguise; - } + disguise.createDisguise(DisguiseType.PLAYER); - public void setGameProfile(WrappedGameProfile gameProfile) - { - this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, gameProfile.getName(), gameProfile); + return disguise; } public WrappedGameProfile getGameProfile() @@ -170,6 +177,11 @@ public class PlayerDisguise extends TargetedDisguise return (PlayerDisguise) super.setEntity(entity); } + public void setGameProfile(WrappedGameProfile gameProfile) + { + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, gameProfile.getName(), gameProfile); + } + @Override public PlayerDisguise setHearSelfDisguise(boolean hearSelfDisguise) { @@ -212,55 +224,63 @@ public class PlayerDisguise extends TargetedDisguise return (PlayerDisguise) super.setModifyBoundingBox(modifyBox); } + private void setName(String name) + { + if (name.length() > 16) + { + name = name.substring(0, 16); + } + + playerName = name; + } + @Override public PlayerDisguise setReplaceSounds(boolean areSoundsReplaced) { return (PlayerDisguise) super.setReplaceSounds(areSoundsReplaced); } - public PlayerDisguise setSkin(String skinToUse) + public PlayerDisguise setSkin(String newSkin) { - this.skinToUse = skinToUse; + skinToUse = newSkin; - if (skinToUse == null) + if (newSkin == null) { - this.currentLookup = null; - this.gameProfile = null; + currentLookup = null; + gameProfile = null; } else { - if (skinToUse.length() > 16) + if (newSkin.length() > 16) { - this.skinToUse = skinToUse.substring(0, 16); + skinToUse = newSkin.substring(0, 16); } - if (LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)) + currentLookup = new LibsProfileLookup() { - currentLookup = new LibsProfileLookup() + @Override + public void onLookup(WrappedGameProfile gameProfile) { - @Override - public void onLookup(WrappedGameProfile gameProfile) - { - if (currentLookup == this && gameProfile != null) - { - setSkin(gameProfile); + if (currentLookup != this || gameProfile == null) + return; - if (!gameProfile.getProperties().isEmpty() && DisguiseUtilities.isDisguiseInUse(PlayerDisguise.this)) - { - DisguiseUtilities.refreshTrackers(PlayerDisguise.this); - } - - currentLookup = null; - } - } - }; - - WrappedGameProfile gameProfile = DisguiseUtilities.getProfileFromMojang(this.skinToUse, currentLookup); - - if (gameProfile != null) - { setSkin(gameProfile); + + if (!gameProfile.getProperties().isEmpty() && DisguiseUtilities.isDisguiseInUse(PlayerDisguise.this)) + { + DisguiseUtilities.refreshTrackers(PlayerDisguise.this); + } + + currentLookup = null; } + }; + + WrappedGameProfile gameProfile = DisguiseUtilities.getProfileFromMojang(this.skinToUse, currentLookup, + LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); + + if (gameProfile != null) + { + setSkin(gameProfile); } } @@ -286,6 +306,7 @@ public class PlayerDisguise extends TargetedDisguise if (LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)) { Validate.notEmpty(gameProfile.getName(), "Name must be set"); + this.skinToUse = gameProfile.getName(); this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, getName(), gameProfile); } diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 1daae32e..249ecd9f 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -640,6 +640,7 @@ public class DisguiseUtilities public static WrappedGameProfile getProfileFromMojang(final PlayerDisguise disguise) { final String nameToFetch = disguise.getSkin() != null ? disguise.getSkin() : disguise.getName(); + final boolean remove = getAddedByPlugins().contains(nameToFetch.toLowerCase()); return getProfileFromMojang(nameToFetch, new LibsProfileLookup() @@ -662,7 +663,7 @@ public class DisguiseUtilities DisguiseUtilities.refreshTrackers(disguise); } } - }); + }, LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); } /** @@ -688,10 +689,20 @@ public class DisguiseUtilities */ public static WrappedGameProfile getProfileFromMojang(String playerName, LibsProfileLookup runnableIfCantReturn) { - return getProfileFromMojang(playerName, (Object) runnableIfCantReturn); + return getProfileFromMojang(playerName, (Object) runnableIfCantReturn, true); } - private static WrappedGameProfile getProfileFromMojang(final String origName, final Object runnable) + /** + * Thread safe to use. This returns a GameProfile. And if its GameProfile doesn't have a skin blob. Then it does a lookup + * using schedulers. The runnable is run once the GameProfile has been successfully dealt with + */ + public static WrappedGameProfile getProfileFromMojang(String playerName, LibsProfileLookup runnableIfCantReturn, + boolean contactMojang) + { + return getProfileFromMojang(playerName, (Object) runnableIfCantReturn, contactMojang); + } + + private static WrappedGameProfile getProfileFromMojang(final String origName, final Object runnable, boolean contactMojang) { final String playerName = origName.toLowerCase(); @@ -715,6 +726,7 @@ public class DisguiseUtilities if (!gameProfile.getProperties().isEmpty()) { gameProfiles.put(playerName, gameProfile); + return gameProfile; } } @@ -736,25 +748,27 @@ public class DisguiseUtilities @Override public void run() { - if (!gameProfile.getProperties().isEmpty()) + if (gameProfile.getProperties().isEmpty()) { - if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) - { - gameProfiles.put(playerName, gameProfile); - } + return; + } - if (runnables.containsKey(playerName)) + if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) + { + gameProfiles.put(playerName, gameProfile); + } + + if (runnables.containsKey(playerName)) + { + for (Object obj : runnables.remove(playerName)) { - for (Object obj : runnables.remove(playerName)) + if (obj instanceof Runnable) { - if (obj instanceof Runnable) - { - ((Runnable) obj).run(); - } - else if (obj instanceof LibsProfileLookup) - { - ((LibsProfileLookup) obj).onLookup(gameProfile); - } + ((Runnable) obj).run(); + } + else if (obj instanceof LibsProfileLookup) + { + ((LibsProfileLookup) obj).onLookup(gameProfile); } } } @@ -786,6 +800,7 @@ public class DisguiseUtilities { runnables.put(playerName, new ArrayList<>()); } + runnables.get(playerName).add(runnable); } @@ -798,7 +813,16 @@ public class DisguiseUtilities */ public static WrappedGameProfile getProfileFromMojang(String playerName, Runnable runnableIfCantReturn) { - return getProfileFromMojang(playerName, (Object) runnableIfCantReturn); + return getProfileFromMojang(playerName, (Object) runnableIfCantReturn, true); + } + + /** + * Thread safe to use. This returns a GameProfile. And if its GameProfile doesn't have a skin blob. Then it does a lookup + * using schedulers. The runnable is run once the GameProfile has been successfully dealt with + */ + public static WrappedGameProfile getProfileFromMojang(String playerName, Runnable runnableIfCantReturn, boolean contactMojang) + { + return getProfileFromMojang(playerName, (Object) runnableIfCantReturn, contactMojang); } public static HashSet getSelfDisguised() diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index f76cc035..0f01b0fd 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -221,7 +221,7 @@ public class PacketsManager { PlayerDisguise playerDisguise = (PlayerDisguise) disguise; - String name = playerDisguise.getSkin() != null ? playerDisguise.getSkin() : playerDisguise.getName(); + String name = playerDisguise.getName(); int entityId = disguisedEntity.getEntityId(); boolean removeName = false; diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java index 8de7d144..39224760 100644 --- a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java @@ -438,12 +438,19 @@ public class ReflectionManager 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 : UUID.randomUUID(), playerName); + gameProfile.getProperties().putAll(profileWithSkin.getProperties()); + return gameProfile; } catch (Exception ex)