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());
}
/**
* 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.
* @return A modifier for SoundEffect enum fields.
*/
public StructureModifier<Sound> getSoundEffects() {
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
return getHolders(MinecraftReflection.getSoundEffectClass(), BukkitConverters.getSoundConverter());
}
// Convert to and from Bukkit
return structureModifier.withType(
MinecraftReflection.getSoundEffectClass(),

View File

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

View File

@ -15,11 +15,19 @@
package com.comphenix.protocol.wrappers;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
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;
/**
@ -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.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.Field;
@ -24,6 +25,8 @@ public class WrappedRegistry {
private static final MethodAccessor GET_ID;
private static final MethodAccessor GET_KEY;
private static final MethodAccessor GET_HOLDER;
static {
Map<Class<?>, WrappedRegistry> regMap = new HashMap<>();
@ -100,6 +103,22 @@ public class WrappedRegistry {
.parameterCount(1)
.returnTypeExact(MinecraftReflection.getMinecraftKeyClass())
.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;
@ -132,6 +151,10 @@ public class WrappedRegistry {
return (int) GET_ID.invoke(this.handle, entry);
}
public Object getHolder(Object generic) {
return GET_HOLDER.invoke(handle, generic);
}
public static WrappedRegistry getAttributeRegistry() {
return getRegistry(MinecraftReflection.getAttributeBase());
}
@ -140,6 +163,10 @@ public class WrappedRegistry {
return getRegistry(MinecraftReflection.getDimensionManager());
}
public static WrappedRegistry getSoundRegistry() {
return getRegistry(MinecraftReflection.getSoundEffectClass());
}
public static WrappedRegistry getRegistry(Class<?> type) {
return REGISTRY.get(type);
}

View File

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