From b6a7d5f91de90686095d6399e31c6f391c2c2d0c Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Sat, 8 Jun 2024 13:45:17 -0500 Subject: [PATCH] Fix some more Mojang mappings --- .../reflect/cloning/ImmutableDetector.java | 4 +- .../protocol/utility/MinecraftReflection.java | 53 ++++++++++++----- .../protocol/wrappers/BukkitConverters.java | 58 +++++++++++-------- .../protocol/wrappers/EnumWrappers.java | 25 ++++---- .../protocol/wrappers/WrappedParticle.java | 14 +++-- .../protocol/wrappers/nbt/NbtFactory.java | 33 ++++++----- 6 files changed, 114 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java b/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java index 6af2e5ba..eb7761d2 100644 --- a/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java +++ b/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java @@ -62,12 +62,12 @@ public class ImmutableDetector implements Cloner { add(MinecraftReflection::getDataWatcherSerializerClass); add(MinecraftReflection::getBlockClass); add(MinecraftReflection::getItemClass); - add("sounds.SoundEffect", "sounds.SoundEvents", "SoundEffect"); + add(MinecraftReflection::getSoundEffectClass); if (MinecraftVersion.AQUATIC_UPDATE.atOrAbove()) { add(MinecraftReflection::getFluidTypeClass); add(MinecraftReflection::getParticleTypeClass); - add("core.particles.Particle","core.particles.ParticleType", "Particle"); + add(MinecraftReflection::getParticleClass); } if (MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index 6d977e85..15c1570e 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -32,12 +32,6 @@ import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLogger; import com.comphenix.protocol.injector.BukkitUnwrapper; @@ -54,6 +48,11 @@ import com.comphenix.protocol.wrappers.EnumWrappers; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; /** * Methods and constants specifically used in conjuction with reflecting Minecraft object. @@ -117,7 +116,7 @@ public final class MinecraftReflection { private static MethodAccessor asCraftMirror = null; private static MethodAccessor isEmpty = null; - private static boolean isMojangMapped = false; + private static Boolean isMojangMapped = null; private MinecraftReflection() { // No need to make this constructable. @@ -208,9 +207,6 @@ public final class MinecraftReflection { } } - // for now, we're going to say that it's Mojang mapped if the nms world was renamed to ServerLevel - isMojangMapped = getNmsWorldClass().getName().contains("ServerLevel"); - return MINECRAFT_FULL_PACKAGE; } catch (NoSuchMethodException exception) { throw new IllegalStateException("Cannot find getHandle() in CraftEntity", exception); @@ -685,10 +681,12 @@ public final class MinecraftReflection { * @return The serializer class. */ public static Class getStyleSerializerClass() { - return getMinecraftClass("network.chat.ChatModifier$ChatModifierSerializer", "ChatModifier$ChatModifierSerializer"); + return getMinecraftClass( + "network.chat.Style$Serializer", + "network.chat.ChatModifier$ChatModifierSerializer", + "ChatModifier$ChatModifierSerializer"); } - /** * Retrieve the ServerPing class. * @@ -1036,7 +1034,21 @@ public final class MinecraftReflection { * @return The team parameters class. */ public static Optional> getTeamParametersClass() { - return getOptionalNMS("network.protocol.game.PacketPlayOutScoreboardTeam$b"); + Optional> clazz = getOptionalNMS( + "network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters", + "network.protocol.game.PacketPlayOutScoreboardTeam$b" + ); + + if (!clazz.isPresent()) { + try { + Class clazz1 = PacketType.Play.Server.SCOREBOARD_TEAM.getPacketClass().getClasses()[0]; + setMinecraftClass("network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters", clazz1); + return Optional.of(clazz1); + } catch (Exception ignored) { + } + } + + return clazz; } /** @@ -1045,7 +1057,11 @@ public final class MinecraftReflection { * @return The component style class. */ public static Class getComponentStyleClass() { - return getMinecraftClass("network.chat.ChatModifier", "ChatModifier"); + return getMinecraftClass( + "network.chat.Style", + "network.chat.ChatModifier", + "ChatModifier" + ); } /** @@ -1180,8 +1196,8 @@ public final class MinecraftReflection { } } - static Class getOrInferMinecraftClass(String className, Supplier> supplier) { - return getOptionalNMS(className).orElseGet(() -> { + static Class getOrInferMinecraftClass(String className, Supplier> supplier, String... aliases) { + return getOptionalNMS(className, aliases).orElseGet(() -> { Class clazz = supplier.get(); return setMinecraftClass(className, clazz); }); @@ -1854,6 +1870,11 @@ public final class MinecraftReflection { } public static boolean isMojangMapped() { + if (isMojangMapped == null) { + String craftServerName = Bukkit.getServer().getClass().getName(); + isMojangMapped = !craftServerName.contains(".v") && !craftServerName.contains("_R"); + } + return isMojangMapped; } } diff --git a/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java b/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java index 0b29f2e1..c0dfb42d 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java +++ b/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java @@ -16,14 +16,22 @@ */ package com.comphenix.protocol.wrappers; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.Either.Left; -import com.comphenix.protocol.wrappers.Either.Right; -import com.comphenix.protocol.wrappers.WrappedProfilePublicKey.WrappedProfileKeyData; import java.lang.ref.WeakReference; -import java.lang.reflect.*; -import java.util.*; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -32,6 +40,7 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLogger; import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.injector.BukkitUnwrapper; import com.comphenix.protocol.injector.PacketConstructor; import com.comphenix.protocol.injector.PacketConstructor.Unwrapper; @@ -47,8 +56,11 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.Either.Left; +import com.comphenix.protocol.wrappers.Either.Right; import com.comphenix.protocol.wrappers.EnumWrappers.Dimension; import com.comphenix.protocol.wrappers.EnumWrappers.FauxEnumConverter; +import com.comphenix.protocol.wrappers.WrappedProfilePublicKey.WrappedProfileKeyData; import com.comphenix.protocol.wrappers.nbt.NbtBase; import com.comphenix.protocol.wrappers.nbt.NbtFactory; @@ -56,7 +68,6 @@ import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; - import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -1116,29 +1127,30 @@ public class BukkitConverters { static MethodAccessor getSoundEffect = null; static FieldAccessor soundKey = null; - static MethodAccessor getSoundEffectBySound = null; - static MethodAccessor getSoundByEffect = null; + static MethodAccessor bukkitToMinecraft = null; + static MethodAccessor minecraftToBukkit = null; static Map soundIndex = null; public static EquivalentConverter getSoundConverter() { // Try to create sound converter for new versions greater 1.16.4 if (MinecraftVersion.NETHER_UPDATE_4.atOrAbove()) { - if (getSoundEffectBySound == null || getSoundByEffect == null) { + if (bukkitToMinecraft == null && minecraftToBukkit == null) { Class craftSound = MinecraftReflection.getCraftSoundClass(); - FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftSound, true); + Class soundEvent = MinecraftReflection.getSoundEffectClass(); + FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftSound, false); - getSoundEffectBySound = Accessors.getMethodAccessor(fuzzy.getMethodByReturnTypeAndParameters( - "getSoundEffect", - MinecraftReflection.getSoundEffectClass(), - Sound.class - )); + bukkitToMinecraft = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder() + .returnTypeExact(soundEvent) + .parameterExactArray(Sound.class) + .requireModifier(Modifier.STATIC) + .build())); - getSoundByEffect = Accessors.getMethodAccessor(fuzzy.getMethodByReturnTypeAndParameters( - "getBukkit", - Sound.class, - MinecraftReflection.getSoundEffectClass() - )); + minecraftToBukkit = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder() + .returnTypeExact(Sound.class) + .parameterExactArray(soundEvent) + .requireModifier(Modifier.STATIC) + .build())); } return ignoreNull(new EquivalentConverter() { @@ -1150,13 +1162,13 @@ public class BukkitConverters { @Override public Object getGeneric(Sound specific) { - return getSoundEffectBySound.invoke(null, specific); + return bukkitToMinecraft.invoke(null, specific); } @Override public Sound getSpecific(Object generic) { try { - return (Sound) getSoundByEffect.invoke(null, generic); + return (Sound) minecraftToBukkit.invoke(null, generic); } catch (IllegalStateException ex) { if (ex.getCause() instanceof NullPointerException || ex.getCause() instanceof NoSuchElementException) { // "null" sounds cause NPEs inside getSoundByEffect diff --git a/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java b/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java index e697fff5..48cd3125 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java +++ b/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java @@ -1,5 +1,16 @@ package com.comphenix.protocol.wrappers; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.ProtocolLogger; @@ -11,21 +22,11 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; + import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.GameMode; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - /** * Represents a generic enum converter. * @author Kristian @@ -737,7 +738,7 @@ public abstract class EnumWrappers { ENTITY_POSE_CLASS = MinecraftReflection.getNullableNMS("world.entity.EntityPose", "world.entity.Pose", "EntityPose"); DISPLAY_SLOT_CLASS = MinecraftReflection.getNullableNMS("world.scores.DisplaySlot"); RENDER_TYPE_CLASS = MinecraftReflection.getNullableNMS("world.scores.criteria.IScoreboardCriteria$EnumScoreboardHealthDisplay", "IScoreboardCriteria$EnumScoreboardHealthDisplay"); - CHAT_FORMATTING_CLASS = MinecraftReflection.getNullableNMS("EnumChatFormat"); + CHAT_FORMATTING_CLASS = MinecraftReflection.getNullableNMS("ChatFormatting", "EnumChatFormat"); associate(PROTOCOL_CLASS, Protocol.class, getProtocolConverter()); associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter()); diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java index 3f327683..eeef01b4 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java @@ -9,6 +9,8 @@ import com.comphenix.protocol.reflect.accessors.MethodAccessor; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; + +import com.google.common.base.Preconditions; import org.bukkit.Color; import org.bukkit.Particle; import org.bukkit.block.data.BlockData; @@ -30,22 +32,26 @@ public class WrappedParticle { return; } + Class particleType = MinecraftReflection.isMojangMapped() + ? MinecraftReflection.getParticleTypeClass() + : MinecraftReflection.getParticleClass(); + + Preconditions.checkNotNull(particleType, "Cannot find ParticleType class (MojMap: " + MinecraftReflection.isMojangMapped() + ")"); + FuzzyReflection fuzzy = FuzzyReflection.fromClass(MinecraftReflection.getCraftBukkitClass("CraftParticle")); if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { FuzzyMethodContract contract = FuzzyMethodContract .newBuilder() .requireModifier(Modifier.STATIC) .returnTypeExact(Particle.class) - .parameterExactArray(MinecraftReflection.isMojangMapped() - ? MinecraftReflection.getParticleTypeClass() - : MinecraftReflection.getParticleClass()) + .parameterExactArray(particleType) .build(); toBukkit = Accessors.getMethodAccessor(fuzzy.getMethod(contract)); FuzzyReflection particleParam = FuzzyReflection.fromClass(MinecraftReflection.getParticleParam(), false); contract = FuzzyMethodContract .newBuilder() - .returnTypeExact(MinecraftReflection.getParticleClass()) + .returnTypeExact(particleType) .parameterCount(0) .build(); getType = Accessors.getMethodAccessor(particleParam.getMethod(contract)); diff --git a/src/main/java/com/comphenix/protocol/wrappers/nbt/NbtFactory.java b/src/main/java/com/comphenix/protocol/wrappers/nbt/NbtFactory.java index d6e10a50..26ff3cc4 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/nbt/NbtFactory.java +++ b/src/main/java/com/comphenix/protocol/wrappers/nbt/NbtFactory.java @@ -17,22 +17,6 @@ package com.comphenix.protocol.wrappers.nbt; -import com.comphenix.protocol.reflect.FieldAccessException; -import com.comphenix.protocol.reflect.FuzzyReflection; -import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; -import com.comphenix.protocol.reflect.instances.DefaultInstances; -import com.comphenix.protocol.utility.MinecraftReflection; -import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.BukkitConverters; -import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer; -import com.google.common.base.Preconditions; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.inventory.ItemStack; - -import javax.annotation.Nonnull; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; @@ -47,6 +31,23 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import javax.annotation.Nonnull; + +import com.comphenix.protocol.reflect.FieldAccessException; +import com.comphenix.protocol.reflect.FuzzyReflection; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; +import com.comphenix.protocol.reflect.instances.DefaultInstances; +import com.comphenix.protocol.utility.MinecraftReflection; +import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.BukkitConverters; +import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer; + +import com.google.common.base.Preconditions; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.inventory.ItemStack; /** * Factory methods for creating NBT elements, lists and compounds.