Fix sounds in 1.19.3

Fixes #2049
This commit is contained in:
Dan Mulloy 2023-01-10 16:36:01 -05:00
parent 30b69d3ecf
commit 531f28cbaf
No known key found for this signature in database
GPG Key ID: BFACD592A5F0DFD6
5 changed files with 94 additions and 1 deletions

View File

@ -761,11 +761,31 @@ public abstract class AbstractStructure {
EnumWrappers.getSoundCategoryConverter()); EnumWrappers.getSoundCategoryConverter());
} }
/**
* Retrieve a read/write structure for a Holder<T> in 1.19.3.
* @param genericType NMS type of T
* @param converter Converter from genericType to T
* @return A modifier for Holder fields
* @param <T> Bukkit type
*/
public <T> StructureModifier<T> getHolders(Class<?> genericType,
EquivalentConverter<T> converter) {
return structureModifier.withParamType(
MinecraftReflection.getHolderClass(),
Converters.holder(converter, WrappedRegistry.getRegistry(genericType)),
genericType
);
}
/** /**
* Retrieve a read/write structure for the SoundEffect enum in 1.9. * Retrieve a read/write structure for the SoundEffect enum in 1.9.
* @return A modifier for SoundEffect enum fields. * @return A modifier for SoundEffect enum fields.
*/ */
public StructureModifier<Sound> getSoundEffects() { public StructureModifier<Sound> getSoundEffects() {
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
return getHolders(MinecraftReflection.getSoundEffectClass(), BukkitConverters.getSoundConverter());
}
// Convert to and from Bukkit // Convert to and from Bukkit
return structureModifier.withType( return structureModifier.withType(
MinecraftReflection.getSoundEffectClass(), MinecraftReflection.getSoundEffectClass(),

View File

@ -1669,4 +1669,8 @@ public final class MinecraftReflection {
return infoClass; return infoClass;
} }
} }
public static Class<?> getHolderClass() {
return getMinecraftClass("core.Holder");
}
} }

View File

@ -15,11 +15,19 @@
package com.comphenix.protocol.wrappers; package com.comphenix.protocol.wrappers;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function; import java.util.function.Function;
import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.EquivalentConverter;
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.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
/** /**
@ -217,4 +225,39 @@ public class Converters {
} }
}); });
} }
private static MethodAccessor holderGetValue;
public static <T> EquivalentConverter<T> holder(final EquivalentConverter<T> converter,
final WrappedRegistry registry) {
return new EquivalentConverter<T>() {
@Override
public Object getGeneric(T specific) {
Object generic = converter.getGeneric(specific);
return registry.getHolder(generic);
}
@Override
public T getSpecific(Object generic) {
if (holderGetValue == null) {
Class<?> holderClass = MinecraftReflection.getHolderClass();
FuzzyReflection fuzzy = FuzzyReflection.fromClass(holderClass, false);
holderGetValue = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract
.newBuilder()
.parameterCount(0)
.banModifier(Modifier.STATIC)
.returnTypeExact(Object.class)
.build()));
}
Object value = holderGetValue.invoke(generic);
return converter.getSpecific(value);
}
@Override
public Class<T> getSpecificType() {
return converter.getSpecificType();
}
};
}
} }

View File

@ -5,6 +5,7 @@ import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor; 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.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -24,6 +25,8 @@ public class WrappedRegistry {
private static final MethodAccessor GET_ID; private static final MethodAccessor GET_ID;
private static final MethodAccessor GET_KEY; private static final MethodAccessor GET_KEY;
private static final MethodAccessor GET_HOLDER;
static { static {
Map<Class<?>, WrappedRegistry> regMap = new HashMap<>(); Map<Class<?>, WrappedRegistry> regMap = new HashMap<>();
@ -100,6 +103,22 @@ public class WrappedRegistry {
.parameterCount(1) .parameterCount(1)
.returnTypeExact(MinecraftReflection.getMinecraftKeyClass()) .returnTypeExact(MinecraftReflection.getMinecraftKeyClass())
.build())); .build()));
MethodAccessor getHolder;
try {
getHolder = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract
.newBuilder()
.parameterCount(1)
.banModifier(Modifier.STATIC)
.returnTypeExact(MinecraftReflection.getHolderClass())
.requireModifier(Modifier.PUBLIC)
.build()));
} catch (IllegalArgumentException ignored) {
getHolder = null;
}
GET_HOLDER = getHolder;
} }
private final Object handle; private final Object handle;
@ -132,6 +151,10 @@ public class WrappedRegistry {
return (int) GET_ID.invoke(this.handle, entry); return (int) GET_ID.invoke(this.handle, entry);
} }
public Object getHolder(Object generic) {
return GET_HOLDER.invoke(handle, generic);
}
public static WrappedRegistry getAttributeRegistry() { public static WrappedRegistry getAttributeRegistry() {
return getRegistry(MinecraftReflection.getAttributeBase()); return getRegistry(MinecraftReflection.getAttributeBase());
} }
@ -140,6 +163,10 @@ public class WrappedRegistry {
return getRegistry(MinecraftReflection.getDimensionManager()); return getRegistry(MinecraftReflection.getDimensionManager());
} }
public static WrappedRegistry getSoundRegistry() {
return getRegistry(MinecraftReflection.getSoundEffectClass());
}
public static WrappedRegistry getRegistry(Class<?> type) { public static WrappedRegistry getRegistry(Class<?> type) {
return REGISTRY.get(type); return REGISTRY.get(type);
} }

View File

@ -568,7 +568,6 @@ public class PacketContainerTest {
} }
@Test @Test
@Disabled("effect is now wrapped in a holder") // todo
public void testSoundEffects() { public void testSoundEffects() {
PacketContainer container = new PacketContainer(PacketType.Play.Server.NAMED_SOUND_EFFECT); PacketContainer container = new PacketContainer(PacketType.Play.Server.NAMED_SOUND_EFFECT);
container.getSoundEffects().write(0, Sound.ENTITY_CAT_HISS); container.getSoundEffects().write(0, Sound.ENTITY_CAT_HISS);