diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java index 2e14d8ee..1bb8799d 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java @@ -68,6 +68,15 @@ public class DisguiseConfig { private static boolean warnScoreboardConflict; private static boolean explicitDisguisePermissions; private static boolean disableCommands; + private static int uuidGeneratedVersion; + + public static int getUUIDGeneratedVersion() { + return uuidGeneratedVersion; + } + + public static void setUUIDGeneratedVersion(int uuidVersion) { + uuidGeneratedVersion = uuidVersion; + } /** * No setter provided as this cannot be changed after startup @@ -245,6 +254,7 @@ public class DisguiseConfig { setWarnScoreboardConflict(config.getBoolean("Scoreboard.WarnConflict")); disableCommands = config.getBoolean("DisableCommands"); setExplicitDisguisePermissions(config.getBoolean("Permissions.ExplictDisguises")); + setUUIDGeneratedVersion(config.getInt("UUIDVersion")); if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) { DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!"); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java index e246130c..7e01a0b2 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java @@ -6,6 +6,7 @@ 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.bukkit.*; import org.bukkit.entity.*; @@ -14,6 +15,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import java.lang.reflect.*; +import java.nio.ByteBuffer; import java.util.Optional; import java.util.UUID; @@ -384,7 +386,7 @@ public class ReflectionManager { public static WrappedGameProfile getGameProfile(UUID uuid, String playerName) { try { - return new WrappedGameProfile(uuid != null ? uuid : UUID.randomUUID(), playerName); + return new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), playerName); } catch (Exception ex) { ex.printStackTrace(); @@ -399,8 +401,7 @@ public class ReflectionManager { public static WrappedGameProfile getGameProfileWithThisSkin(UUID uuid, String playerName, WrappedGameProfile profileWithSkin) { try { - WrappedGameProfile gameProfile = new WrappedGameProfile(uuid != null ? uuid : UUID.randomUUID(), - playerName); + WrappedGameProfile gameProfile = new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), playerName); if (profileWithSkin != null) { gameProfile.getProperties().putAll(profileWithSkin.getProperties()); @@ -415,6 +416,32 @@ public class ReflectionManager { 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); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index cbe7bb59..01b03df3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -213,4 +213,8 @@ PacketsEnabled: # 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 \ No newline at end of file + WitherSkull: true + +# Added to support a Chinese Minecraft Server which uses their own skin server unless the UUID is not version 4. +# Changing this from 4 to say, 3. Means their server will fetch skins from Mojang instead. +UUIDVersion: 4 \ No newline at end of file