diff --git a/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassMappings.java b/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassMappings.java new file mode 100644 index 00000000..6ad67aa7 --- /dev/null +++ b/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassMappings.java @@ -0,0 +1,48 @@ +package me.libraryaddict.disguise.utilities.reflection; + +import java.util.HashMap; + +public class ClassMappings { + private static HashMap classLocations = new HashMap<>(); + + private static final String[] packages = getPackages(); + + public static String getClass(String packageHint, String className) { + String location = classLocations.get(className); + if (location != null) + return location; + location = className; + String[] arrayOfString; + int i; + byte b; + for (arrayOfString = packages, i = arrayOfString.length, b = 0; b < i; ) { + String pack = arrayOfString[b]; + if (!pack.startsWith(packageHint)) { + b++; + continue; + } + String toTry = pack + "." + className; + try { + Class.forName(toTry); + location = pack + "." + className; + break; + } catch (Throwable throwable) { + b++; + } + } + classLocations.put(className, location); + return location; + } + + private static String[] getPackages() { + String[] s = { + "net.minecraft.core", "net.minecraft.core.particles", "net.minecraft.nbt", "net.minecraft.network.chat", "net.minecraft.network.protocol.game", "net.minecraft.network.syncher", "net.minecraft.resources", "net.minecraft.server.level", "net.minecraft.server", "net.minecraft.server.network", + "net.minecraft.sounds", "net.minecraft.world.damagesource", "net.minecraft.world.effect", "net.minecraft.world.entity.ambient", "net.minecraft.world.entity.animal.axolotl", "net.minecraft.world.entity.animal", "net.minecraft.world.entity.animal.goat", "net.minecraft.world.entity.animal.horse", "net.minecraft.world.entity.boss.enderdragon", "net.minecraft.world.entity.boss.wither", + "net.minecraft.world.entity.decoration", "net.minecraft.world.entity", "net.minecraft.world.entity.item", "net.minecraft.world.entity.monster", "net.minecraft.world.entity.monster.hoglin", "net.minecraft.world.entity.monster.piglin", "net.minecraft.world.entity.npc", "net.minecraft.world.entity.player", "net.minecraft.world.entity.projectile", "net.minecraft.world.entity.vehicle", + "net.minecraft.world.inventory", "net.minecraft.world.item", "net.minecraft.world.level.block", "net.minecraft.world.level.block.state", "net.minecraft.world.level", "net.minecraft.world.phys", "org.bukkit.craftbukkit.$version$.block.data", "org.bukkit.craftbukkit.$version$", "org.bukkit.craftbukkit.$version$.entity", "org.bukkit.craftbukkit.$version$.inventory", + "org.bukkit.craftbukkit.$version$.util" }; + for (int i = 0; i < s.length; i++) + s[i] = s[i].replace("$version$", ReflectionManager.getBukkitVersion()); + return s; + } +} \ No newline at end of file diff --git a/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java b/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java index de2ce3d9..91c307fe 100644 --- a/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java +++ b/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManager.java @@ -117,7 +117,15 @@ public class ReflectionManager { public static void init() { try { - v1_18ReflectionManager = getReflectionManager(NmsVersion.v1_18); + // Load first because its necessary for 1.18+ + if (NmsVersion.v1_14.isSupported()) { + entityPoseClass = getNmsClass("EntityPose"); + } + + if (NmsVersion.v1_18.isSupported()) { + v1_18ReflectionManager = getReflectionManager(NmsVersion.v1_18); + return; + } boundingBoxConstructor = getNmsConstructor("AxisAlignedBB", double.class, double.class, double.class, double.class, double.class, double.class); setBoundingBoxMethod = getNmsMethod("Entity", "a", getNmsClass("AxisAlignedBB")); @@ -199,7 +207,6 @@ public class ReflectionManager { entityTypesAMethod = getNmsMethod("EntityTypes", "a", String.class); if (NmsVersion.v1_14.isSupported()) { - entityPoseClass = getNmsClass("EntityPose"); registryBlocksGetMethod = getNmsMethod("RegistryBlocks", "get", getNmsClass("MinecraftKey")); villagerDataConstructor = getNmsConstructor("VillagerData", getNmsClass("VillagerType"), getNmsClass("VillagerProfession"), int.class); @@ -348,6 +355,7 @@ public class ReflectionManager { if (NmsVersion.v1_18.isSupported()) { return v1_18ReflectionManager.getIncrementedStateId(player); } + try { Object container = playerInventoryContainer.get(getNmsEntity(player)); @@ -924,13 +932,7 @@ public class ReflectionManager { } public static WrappedGameProfile getGameProfile(UUID uuid, String playerName) { - try { - return new WrappedGameProfile(uuid != null ? uuid : getRandomUUID(), - playerName == null || playerName.length() < 17 ? playerName : playerName.substring(0, 16)); - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; + return ReflectionManagerAbstract.getGameProfile(uuid == null ? getRandomUUID() : uuid, playerName); } public static WrappedGameProfile getClonedProfile(WrappedGameProfile gameProfile) { @@ -968,6 +970,10 @@ public class ReflectionManager { } private static String getLocation(String pack, String className) { + if (NmsVersion.v1_18.isSupported()) { + return ClassMappings.getClass(pack, className); + } + String toReturn = classLocations.get(className); if (toReturn != null) { @@ -1677,6 +1683,10 @@ public class ReflectionManager { public static Object createDataWatcherItem(MetaIndex id, Object value) { WrappedDataWatcherObject watcherObject = createDataWatcherObject(id, value); + if (NmsVersion.v1_18.isSupported()) { + return v1_18ReflectionManager.createDataWatcherItem(watcherObject, convertInvalidMeta(value)); + } + try { return dataWatcherItemConstructor.newInstance(watcherObject.getHandle(), convertInvalidMeta(value)); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { @@ -2253,7 +2263,7 @@ public class ReflectionManager { return; } - Object nmsEntity = ReflectionManager.createEntityInstance(disguiseType, nmsEntityName); + Object nmsEntity = ReflectionManager.createEntityInstance(disguiseType, NmsVersion.v1_18.isSupported() ? disguiseType.getEntityType().getKey().getKey() : nmsEntityName); if (nmsEntity == null) { DisguiseUtilities.getLogger().warning("Entity not found! (" + nmsEntityName + ")"); diff --git a/shared/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManagerAbstract.java b/shared/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManagerAbstract.java index bbef2db8..9a1ef310 100644 --- a/shared/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManagerAbstract.java +++ b/shared/src/main/java/me/libraryaddict/disguise/utilities/reflection/ReflectionManagerAbstract.java @@ -1,6 +1,7 @@ package me.libraryaddict.disguise.utilities.reflection; import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.mojang.authlib.ProfileLookupCallback; import org.bukkit.*; @@ -17,6 +18,7 @@ import org.bukkit.util.Vector; import java.util.Map; import java.util.Optional; +import java.util.UUID; public interface ReflectionManagerAbstract { boolean hasInvul(Entity entity); @@ -107,6 +109,8 @@ public interface ReflectionManagerAbstract { Object getVillagerProfession(Villager.Profession profession); + Object createDataWatcherItem(WrappedDataWatcher.WrappedDataWatcherObject wrappedDataWatcherObject, T metaItem); + @Deprecated Object createSoundEffect(String minecraftKey); @@ -137,4 +141,13 @@ public interface ReflectionManagerAbstract { Object getWorldServer(World w); ItemMeta getDeserializedItemMeta(Map meta); + + static WrappedGameProfile getGameProfile(UUID uuid, String playerName) { + try { + return new WrappedGameProfile(uuid, playerName == null || playerName.length() < 17 ? playerName : playerName.substring(0, 16)); + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } } diff --git a/v1_18_R1/src/main/java/me/libraryaddict/disguise/v1_18/utilities/reflection/ReflectionManager.java b/v1_18_R1/src/main/java/me/libraryaddict/disguise/v1_18/utilities/reflection/ReflectionManager.java index 6974cf1a..2106d68c 100644 --- a/v1_18_R1/src/main/java/me/libraryaddict/disguise/v1_18/utilities/reflection/ReflectionManager.java +++ b/v1_18_R1/src/main/java/me/libraryaddict/disguise/v1_18/utilities/reflection/ReflectionManager.java @@ -2,6 +2,7 @@ package me.libraryaddict.disguise.v1_18.utilities.reflection; import com.comphenix.protocol.wrappers.*; import com.comphenix.protocol.wrappers.EnumWrappers.Direction; +import com.comphenix.protocol.wrappers.nbt.NbtWrapper; import com.mojang.authlib.Agent; import com.mojang.authlib.GameProfile; import com.mojang.authlib.ProfileLookupCallback; @@ -10,8 +11,11 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import me.libraryaddict.disguise.utilities.reflection.ReflectionManagerAbstract; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.Vector3f; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.*; @@ -26,6 +30,8 @@ import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.entity.npc.VillagerData; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerType; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.entity.projectile.ThrownEnderpearl; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; @@ -102,7 +108,18 @@ public class ReflectionManager implements ReflectionManagerAbstract { if (optional.isPresent()) { net.minecraft.world.entity.EntityType entityType = optional.get(); ServerLevel world = getWorldServer(Bukkit.getWorlds().get(0)); - net.minecraft.world.entity.Entity entity = entityType.create(world); + net.minecraft.world.entity.Entity entity; + if (entityType == net.minecraft.world.entity.EntityType.PLAYER) { + WrappedGameProfile gameProfile = ReflectionManagerAbstract.getGameProfile(new UUID(0, 0), "Steve"); + entity = new ServerPlayer(getMinecraftServer(), world, (GameProfile) gameProfile.getHandle()); + }/* else if (entityType == net.minecraft.world.entity.EntityType.ENDER_PEARL) { + entity = new ThrownEnderpearl(world, (net.minecraft.world.entity.LivingEntity) createEntityInstance("cow")); + } else if (entityType == net.minecraft.world.entity.EntityType.FISHING_BOBBER) { + entity = new FishingHook((net.minecraft.world.entity.player.Player) createEntityInstance("player"), world, 0, 0); + }*/ else { + entity = entityType.create(world); + } + // Workaround for paper being 2 smart 4 me entity.setPos(1.0, 1.0, 1.0); entity.setPos(0.0, 0.0, 0.0); @@ -291,13 +308,13 @@ public class ReflectionManager implements ReflectionManagerAbstract { return Optional.empty(); } - public Vec3 convertVec3(Object object) { + public Vector3f convertVec3(Object object) { if (object instanceof Vector3F) { Vector3F vector3F = (Vector3F) object; - return new Vec3(vector3F.getX(), vector3F.getY(), vector3F.getZ()); + return new Vector3f(vector3F.getX(), vector3F.getY(), vector3F.getZ()); } else if (object instanceof EulerAngle) { EulerAngle eulerAngle = (EulerAngle) object; - return new Vec3(eulerAngle.getX(), eulerAngle.getY(), eulerAngle.getZ()); + return new Vector3f((float) eulerAngle.getX(), (float) eulerAngle.getY(), (float) eulerAngle.getZ()); } return null; @@ -334,6 +351,10 @@ public class ReflectionManager implements ReflectionManagerAbstract { return Registry.VILLAGER_PROFESSION.get(CraftNamespacedKey.toMinecraft(profession.getKey())); } + public SynchedEntityData.DataItem createDataWatcherItem(WrappedDataWatcher.WrappedDataWatcherObject wrappedDataWatcherObject, T metaItem) { + return new SynchedEntityData.DataItem<>((EntityDataAccessor) wrappedDataWatcherObject.getHandle(), metaItem); + } + @Deprecated public SoundEvent createSoundEffect(String minecraftKey) { return new SoundEvent(new ResourceLocation(minecraftKey));