Fix attributes, a few enums, and some tests

This commit is contained in:
Dan Mulloy 2024-06-03 20:56:56 -05:00
parent 0daf389aff
commit 4afbe845ff
No known key found for this signature in database
GPG Key ID: BFACD592A5F0DFD6
12 changed files with 92 additions and 27 deletions

View File

@ -5,7 +5,7 @@ plugins {
}
group = 'com.comphenix.protocol'
version = '5.2.1-SNAPSHOT'
version = '5.3.0-SNAPSHOT'
description = 'Provides access to the Minecraft protocol'
def isSnapshot = version.endsWith('-SNAPSHOT')
@ -34,8 +34,8 @@ repositories {
dependencies {
implementation 'net.bytebuddy:byte-buddy:1.14.14'
compileOnly 'org.spigotmc:spigot-api:1.20.5-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot:1.20.5-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot:1.20.6-R0.1-SNAPSHOT'
compileOnly 'io.netty:netty-all:4.0.23.Final'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.14.0'
compileOnly 'com.googlecode.json-simple:json-simple:1.1.1'
@ -46,7 +46,7 @@ dependencies {
testImplementation 'org.mockito:mockito-core:5.6.0'
testImplementation 'io.netty:netty-common:4.1.97.Final'
testImplementation 'io.netty:netty-transport:4.1.97.Final'
testImplementation 'org.spigotmc:spigot:1.20.5-R0.1-SNAPSHOT'
testImplementation 'org.spigotmc:spigot:1.20.6-R0.1-SNAPSHOT'
testImplementation 'net.kyori:adventure-text-serializer-gson:4.14.0'
testImplementation 'net.kyori:adventure-text-serializer-plain:4.14.0'
}
@ -74,6 +74,11 @@ test {
}
}
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
processResources {
def includeBuild = isSnapshot && System.getenv('BUILD_NUMBER')
def fullVersion = includeBuild

View File

@ -731,6 +731,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
STATUS("Status", "status"),
LOGIN("Login", "login"),
CONFIGURATION("Configuration", "configuration"),
TRANSFER("Transfer", "transfer"), // TODO are these the right names?
/**
* Only for packets removed in Minecraft 1.7.2

View File

@ -29,6 +29,26 @@ public class FuzzyMatchers {
return (value, parent) -> value.isArray() && componentMatcher.isMatch(value.getComponentType(), parent);
}
public static AbstractFuzzyMatcher<Class<?>> except(Class<?> clazz) {
return (value, parent) -> !clazz.isAssignableFrom(value);
}
public static AbstractFuzzyMatcher<Class<?>> assignable(Class<?> clazz) {
return (value, parent) -> clazz.isAssignableFrom(value);
}
@SafeVarargs
public static AbstractFuzzyMatcher<Class<?>> and(AbstractFuzzyMatcher<Class<?>>... matchers) {
return (value, parent) -> {
for (AbstractFuzzyMatcher<Class<?>> matcher : matchers) {
if (!matcher.isMatch(value, parent)) {
return false;
}
}
return true;
};
}
/**
* Retrieve a fuzzy matcher that will match any class.
*

View File

@ -1470,6 +1470,14 @@ public final class MinecraftReflection {
.orElseThrow(() -> new RuntimeException("Failed to find class: " + className));
}
public static Optional<Class<?>> getOptionalLibraryClass(String className) {
if (libraryPackage == null) {
libraryPackage = new CachedPackage("", getClassSource());
}
return libraryPackage.getPackageClass(className);
}
/**
* Set the class object for the specific library class.
*
@ -1651,9 +1659,13 @@ public final class MinecraftReflection {
try {
return getMinecraftLibraryClass(classname);
} catch (RuntimeException ex) {
Class<?> clazz = getMinecraftLibraryClass("org.bukkit.craftbukkit.libs." + classname);
setMinecraftLibraryClass(classname, clazz);
return clazz;
try {
Class<?> clazz = getMinecraftLibraryClass("org.bukkit.craftbukkit.libs." + classname);
setMinecraftLibraryClass(classname, clazz);
return clazz;
} catch (Exception ignored) {
throw ex;
}
}
}

View File

@ -358,7 +358,8 @@ public abstract class EnumWrappers {
FEET,
LEGS,
CHEST,
HEAD
HEAD,
BODY
}
public enum Hand {

View File

@ -12,6 +12,11 @@ import com.comphenix.protocol.wrappers.collection.ConvertedSet;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.network.protocol.game.PacketPlayOutUpdateAttributes;
import net.minecraft.world.entity.ai.attributes.AttributeBase;
import org.w3c.dom.Attr;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -26,6 +31,8 @@ import java.util.*;
*/
public class WrappedAttribute extends AbstractWrapper {
public static boolean KEY_WRAPPED = MinecraftVersion.NETHER_UPDATE.atOrAbove();
public static boolean IS_STATIC = MinecraftVersion.CAVES_CLIFFS_1.atOrAbove();
public static boolean IS_IN_HOLDER = MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove();
// Shared structure modifier
private static StructureModifier<Object> ATTRIBUTE_MODIFIER;
@ -136,8 +143,13 @@ public class WrappedAttribute extends AbstractWrapper {
*/
public String getAttributeKey() {
if (KEY_WRAPPED) {
WrappedAttributeBase base = modifier.withType(ATTRIBUTE_BASE_CLASS, ATTRIBUTE_BASE).read(0);
return base.key.replace("attribute.name.", ""); // TODO not entirely sure why this happens
StructureModifier<WrappedAttributeBase> typedModifier = IS_IN_HOLDER
? modifier.withParamType(MinecraftReflection.getHolderClass(),
Converters.holder(ATTRIBUTE_BASE, WrappedRegistry.getAttributeRegistry()),
ATTRIBUTE_BASE_CLASS)
: modifier.withType(ATTRIBUTE_BASE_CLASS, ATTRIBUTE_BASE);
WrappedAttributeBase base = typedModifier.read(0);
return base.key.replace("attribute.name.", "");
} else {
return (String) modifier.withType(String.class).read(0);
}
@ -447,12 +459,10 @@ public class WrappedAttribute extends AbstractWrapper {
throw new IllegalStateException("Base value has not been set.");
}
boolean isStatic = MinecraftVersion.CAVES_CLIFFS_1.atOrAbove();
if (ATTRIBUTE_CONSTRUCTOR == null) {
FuzzyReflection ref = FuzzyReflection.fromClass(MinecraftReflection.getAttributeSnapshotClass(), true);
FuzzyMethodContract.Builder contract = FuzzyMethodContract.newBuilder().parameterCount(isStatic ? 3 : 4);
if (!isStatic) {
FuzzyMethodContract.Builder contract = FuzzyMethodContract.newBuilder().parameterCount(IS_STATIC ? 3 : 4);
if (!IS_STATIC) {
contract.parameterDerivedOf(MinecraftReflection.getPacketClass(), 0);
}
contract.parameterExactType(double.class).parameterDerivedOf(Collection.class);
@ -471,13 +481,15 @@ public class WrappedAttribute extends AbstractWrapper {
if (attributeKey == null) {
throw new IllegalArgumentException("Invalid attribute name: " + this.attributeKey);
}
attributeKey = registry.getHolder(attributeKey);
} else {
attributeKey = this.attributeKey;
}
try {
Object handle;
if (isStatic) {
if (IS_STATIC) {
handle = ATTRIBUTE_CONSTRUCTOR.newInstance(attributeKey, baseValue, getUnwrappedModifiers());
} else {
handle = ATTRIBUTE_CONSTRUCTOR.newInstance(packet.getHandle(), attributeKey, baseValue, getUnwrappedModifiers());

View File

@ -3,6 +3,7 @@ package com.comphenix.protocol.wrappers;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
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;
@ -15,6 +16,7 @@ import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
public class WrappedRegistry {
@ -87,7 +89,7 @@ public class WrappedRegistry {
GET = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract
.newBuilder()
.parameterCount(1)
.returnDerivedOf(Object.class)
.returnTypeMatches(FuzzyMatchers.and(FuzzyMatchers.assignable(Object.class), FuzzyMatchers.except(Optional.class)))
.requireModifier(Modifier.ABSTRACT)
.parameterExactType(MinecraftReflection.getMinecraftKeyClass())
.build()));

View File

@ -11,10 +11,16 @@ import java.util.function.Function;
public class WrappedDataResult extends AbstractWrapper {
private final static Class<?> HANDLE_TYPE = MinecraftReflection.getLibraryClass("com.mojang.serialization.DataResult");
private final static Class<?> PARTIAL_DATA_RESULT_CLASS = MinecraftReflection.getLibraryClass("com.mojang.serialization.DataResult$PartialResult");
private final static Optional<Class<?>> PARTIAL_DATA_RESULT_CLASS = MinecraftReflection.getOptionalLibraryClass("com.mojang.serialization.DataResult$PartialResult");
private final static MethodAccessor ERROR_ACCESSOR = Accessors.getMethodAccessor(HANDLE_TYPE, "error");
private final static MethodAccessor RESULT_ACCESSOR = Accessors.getMethodAccessor(HANDLE_TYPE, "result");
private final static MethodAccessor PARTIAL_RESULT_MESSAGE_ACCESSOR = Accessors.getMethodAccessor(PARTIAL_DATA_RESULT_CLASS, "message");
private static MethodAccessor PARTIAL_RESULT_MESSAGE_ACCESSOR;
static {
if (PARTIAL_DATA_RESULT_CLASS.isPresent()) {
PARTIAL_RESULT_MESSAGE_ACCESSOR = Accessors.getMethodAccessor(PARTIAL_DATA_RESULT_CLASS.get(), "message");
}
}
/**
* Construct a new NMS wrapper.
@ -38,13 +44,15 @@ public class WrappedDataResult extends AbstractWrapper {
public Object getOrThrow(Function<String, Throwable> errorHandler) {
Optional<String> err = getErrorMessage();
if(err.isPresent()) {
if (err.isPresent()) {
return errorHandler.apply((String) PARTIAL_RESULT_MESSAGE_ACCESSOR.invoke(err.get()));
}
Optional<Object> result = getResult();
if(result.isPresent()) {
if (result.isPresent()) {
return result.get();
}
throw new NoSuchElementException();
}
}

View File

@ -2,7 +2,7 @@ package com.comphenix.protocol.utility;
public class MinecraftReflectionTestUtil {
public static final String RELEASE_TARGET = "1.20.4";
public static final String RELEASE_TARGET = "1.20.6";
public static final String PACKAGE_VERSION = "v1_20_R4";
public static final String NMS = "net.minecraft";
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;

View File

@ -31,7 +31,7 @@ public class BukkitConvertersTest {
@Test
public void testItemStacks() {
ItemStack item = new ItemStack(Material.DIAMOND_SWORD, 16);
item.addEnchantment(Enchantment.POWER, 4);
item.addEnchantment(Enchantment.SHARPNESS, 4);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.GREEN + "Diamond Sword");
item.setItemMeta(meta);

View File

@ -44,8 +44,9 @@ public class EnumWrappersTest {
assertNotNull(unwrappedValue);
assertEquals(nativeConstant, unwrappedValue);
} catch (Exception exception) {
fail(exception);
} catch (Exception ex) {
fail(ex);
// ex.printStackTrace();
}
}
}

View File

@ -95,9 +95,12 @@ public class WrappedAttributeTest {
modifiers.add((AttributeModifier) wrapper.getHandle());
}
IRegistry<AttributeBase> registry = BuiltInRegistries.u;
AttributeBase base = registry.a(MinecraftKey.a(attribute.getAttributeKey()));
return new AttributeSnapshot(Holder.a(base), attribute.getBaseValue(), modifiers);
IRegistry<AttributeBase> registry = BuiltInRegistries.u;
String attributeKey = attribute.getAttributeKey();
MinecraftKey key = MinecraftKey.a(attributeKey);
AttributeBase base = registry.a(key);
Holder<AttributeBase> holder = registry.e(base);
return new AttributeSnapshot(holder, attribute.getBaseValue(), modifiers);
}
private AttributeModifier getModifierCopy(WrappedAttributeModifier modifier) {