Fix some more Mojang mappings

This commit is contained in:
Dan Mulloy 2024-06-08 13:45:17 -05:00
parent f6b3af4221
commit b6a7d5f91d
No known key found for this signature in database
GPG Key ID: 3C5AD5D866D1539A
6 changed files with 114 additions and 73 deletions

View File

@ -62,12 +62,12 @@ public class ImmutableDetector implements Cloner {
add(MinecraftReflection::getDataWatcherSerializerClass); add(MinecraftReflection::getDataWatcherSerializerClass);
add(MinecraftReflection::getBlockClass); add(MinecraftReflection::getBlockClass);
add(MinecraftReflection::getItemClass); add(MinecraftReflection::getItemClass);
add("sounds.SoundEffect", "sounds.SoundEvents", "SoundEffect"); add(MinecraftReflection::getSoundEffectClass);
if (MinecraftVersion.AQUATIC_UPDATE.atOrAbove()) { if (MinecraftVersion.AQUATIC_UPDATE.atOrAbove()) {
add(MinecraftReflection::getFluidTypeClass); add(MinecraftReflection::getFluidTypeClass);
add(MinecraftReflection::getParticleTypeClass); add(MinecraftReflection::getParticleTypeClass);
add("core.particles.Particle","core.particles.ParticleType", "Particle"); add(MinecraftReflection::getParticleClass);
} }
if (MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { if (MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) {

View File

@ -32,12 +32,6 @@ import java.util.logging.Level;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; 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.PacketType;
import com.comphenix.protocol.ProtocolLogger; import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.injector.BukkitUnwrapper; 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.ByteBuf;
import io.netty.buffer.Unpooled; 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. * 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 asCraftMirror = null;
private static MethodAccessor isEmpty = null; private static MethodAccessor isEmpty = null;
private static boolean isMojangMapped = false; private static Boolean isMojangMapped = null;
private MinecraftReflection() { private MinecraftReflection() {
// No need to make this constructable. // 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; return MINECRAFT_FULL_PACKAGE;
} catch (NoSuchMethodException exception) { } catch (NoSuchMethodException exception) {
throw new IllegalStateException("Cannot find getHandle() in CraftEntity", exception); throw new IllegalStateException("Cannot find getHandle() in CraftEntity", exception);
@ -685,10 +681,12 @@ public final class MinecraftReflection {
* @return The serializer class. * @return The serializer class.
*/ */
public static Class<?> getStyleSerializerClass() { 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. * Retrieve the ServerPing class.
* *
@ -1036,7 +1034,21 @@ public final class MinecraftReflection {
* @return The team parameters class. * @return The team parameters class.
*/ */
public static Optional<Class<?>> getTeamParametersClass() { public static Optional<Class<?>> getTeamParametersClass() {
return getOptionalNMS("network.protocol.game.PacketPlayOutScoreboardTeam$b"); Optional<Class<?>> 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. * @return The component style class.
*/ */
public static Class<?> getComponentStyleClass() { 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<Class<?>> supplier) { static Class<?> getOrInferMinecraftClass(String className, Supplier<Class<?>> supplier, String... aliases) {
return getOptionalNMS(className).orElseGet(() -> { return getOptionalNMS(className, aliases).orElseGet(() -> {
Class<?> clazz = supplier.get(); Class<?> clazz = supplier.get();
return setMinecraftClass(className, clazz); return setMinecraftClass(className, clazz);
}); });
@ -1854,6 +1870,11 @@ public final class MinecraftReflection {
} }
public static boolean isMojangMapped() { public static boolean isMojangMapped() {
if (isMojangMapped == null) {
String craftServerName = Bukkit.getServer().getClass().getName();
isMojangMapped = !craftServerName.contains(".v") && !craftServerName.contains("_R");
}
return isMojangMapped; return isMojangMapped;
} }
} }

View File

@ -16,14 +16,22 @@
*/ */
package com.comphenix.protocol.wrappers; 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.ref.WeakReference;
import java.lang.reflect.*; import java.lang.reflect.Array;
import java.util.*; 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.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -32,6 +40,7 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolLogger; import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.injector.BukkitUnwrapper; import com.comphenix.protocol.injector.BukkitUnwrapper;
import com.comphenix.protocol.injector.PacketConstructor; import com.comphenix.protocol.injector.PacketConstructor;
import com.comphenix.protocol.injector.PacketConstructor.Unwrapper; 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.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion; 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.Dimension;
import com.comphenix.protocol.wrappers.EnumWrappers.FauxEnumConverter; 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.NbtBase;
import com.comphenix.protocol.wrappers.nbt.NbtFactory; 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.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -1116,29 +1127,30 @@ public class BukkitConverters {
static MethodAccessor getSoundEffect = null; static MethodAccessor getSoundEffect = null;
static FieldAccessor soundKey = null; static FieldAccessor soundKey = null;
static MethodAccessor getSoundEffectBySound = null; static MethodAccessor bukkitToMinecraft = null;
static MethodAccessor getSoundByEffect = null; static MethodAccessor minecraftToBukkit = null;
static Map<String, Sound> soundIndex = null; static Map<String, Sound> soundIndex = null;
public static EquivalentConverter<Sound> getSoundConverter() { public static EquivalentConverter<Sound> getSoundConverter() {
// Try to create sound converter for new versions greater 1.16.4 // Try to create sound converter for new versions greater 1.16.4
if (MinecraftVersion.NETHER_UPDATE_4.atOrAbove()) { if (MinecraftVersion.NETHER_UPDATE_4.atOrAbove()) {
if (getSoundEffectBySound == null || getSoundByEffect == null) { if (bukkitToMinecraft == null && minecraftToBukkit == null) {
Class<?> craftSound = MinecraftReflection.getCraftSoundClass(); 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( bukkitToMinecraft = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
"getSoundEffect", .returnTypeExact(soundEvent)
MinecraftReflection.getSoundEffectClass(), .parameterExactArray(Sound.class)
Sound.class .requireModifier(Modifier.STATIC)
)); .build()));
getSoundByEffect = Accessors.getMethodAccessor(fuzzy.getMethodByReturnTypeAndParameters( minecraftToBukkit = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
"getBukkit", .returnTypeExact(Sound.class)
Sound.class, .parameterExactArray(soundEvent)
MinecraftReflection.getSoundEffectClass() .requireModifier(Modifier.STATIC)
)); .build()));
} }
return ignoreNull(new EquivalentConverter<Sound>() { return ignoreNull(new EquivalentConverter<Sound>() {
@ -1150,13 +1162,13 @@ public class BukkitConverters {
@Override @Override
public Object getGeneric(Sound specific) { public Object getGeneric(Sound specific) {
return getSoundEffectBySound.invoke(null, specific); return bukkitToMinecraft.invoke(null, specific);
} }
@Override @Override
public Sound getSpecific(Object generic) { public Sound getSpecific(Object generic) {
try { try {
return (Sound) getSoundByEffect.invoke(null, generic); return (Sound) minecraftToBukkit.invoke(null, generic);
} catch (IllegalStateException ex) { } catch (IllegalStateException ex) {
if (ex.getCause() instanceof NullPointerException || ex.getCause() instanceof NoSuchElementException) { if (ex.getCause() instanceof NullPointerException || ex.getCause() instanceof NoSuchElementException) {
// "null" sounds cause NPEs inside getSoundByEffect // "null" sounds cause NPEs inside getSoundByEffect

View File

@ -1,5 +1,16 @@
package com.comphenix.protocol.wrappers; 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;
import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.ProtocolLogger; 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.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.utility.MinecraftVersion;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.GameMode; 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. * Represents a generic enum converter.
* @author Kristian * @author Kristian
@ -737,7 +738,7 @@ public abstract class EnumWrappers {
ENTITY_POSE_CLASS = MinecraftReflection.getNullableNMS("world.entity.EntityPose", "world.entity.Pose", "EntityPose"); ENTITY_POSE_CLASS = MinecraftReflection.getNullableNMS("world.entity.EntityPose", "world.entity.Pose", "EntityPose");
DISPLAY_SLOT_CLASS = MinecraftReflection.getNullableNMS("world.scores.DisplaySlot"); DISPLAY_SLOT_CLASS = MinecraftReflection.getNullableNMS("world.scores.DisplaySlot");
RENDER_TYPE_CLASS = MinecraftReflection.getNullableNMS("world.scores.criteria.IScoreboardCriteria$EnumScoreboardHealthDisplay", "IScoreboardCriteria$EnumScoreboardHealthDisplay"); 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(PROTOCOL_CLASS, Protocol.class, getProtocolConverter());
associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter()); associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter());

View File

@ -9,6 +9,8 @@ import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.base.Preconditions;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
@ -30,22 +32,26 @@ public class WrappedParticle<T> {
return; 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")); FuzzyReflection fuzzy = FuzzyReflection.fromClass(MinecraftReflection.getCraftBukkitClass("CraftParticle"));
if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) {
FuzzyMethodContract contract = FuzzyMethodContract FuzzyMethodContract contract = FuzzyMethodContract
.newBuilder() .newBuilder()
.requireModifier(Modifier.STATIC) .requireModifier(Modifier.STATIC)
.returnTypeExact(Particle.class) .returnTypeExact(Particle.class)
.parameterExactArray(MinecraftReflection.isMojangMapped() .parameterExactArray(particleType)
? MinecraftReflection.getParticleTypeClass()
: MinecraftReflection.getParticleClass())
.build(); .build();
toBukkit = Accessors.getMethodAccessor(fuzzy.getMethod(contract)); toBukkit = Accessors.getMethodAccessor(fuzzy.getMethod(contract));
FuzzyReflection particleParam = FuzzyReflection.fromClass(MinecraftReflection.getParticleParam(), false); FuzzyReflection particleParam = FuzzyReflection.fromClass(MinecraftReflection.getParticleParam(), false);
contract = FuzzyMethodContract contract = FuzzyMethodContract
.newBuilder() .newBuilder()
.returnTypeExact(MinecraftReflection.getParticleClass()) .returnTypeExact(particleType)
.parameterCount(0) .parameterCount(0)
.build(); .build();
getType = Accessors.getMethodAccessor(particleParam.getMethod(contract)); getType = Accessors.getMethodAccessor(particleParam.getMethod(contract));

View File

@ -17,22 +17,6 @@
package com.comphenix.protocol.wrappers.nbt; 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.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -47,6 +31,23 @@ import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; 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. * Factory methods for creating NBT elements, lists and compounds.