Make Sound handling more robust
Fixes aadnk#119
Dieser Commit ist enthalten in:
Ursprung
27047f83a5
Commit
540a5e53c4
@ -1847,6 +1847,10 @@ public class MinecraftReflection {
|
|||||||
return getMinecraftClass("NonNullList");
|
return getMinecraftClass("NonNullList");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class<?> getCraftSoundClass() {
|
||||||
|
return getCraftBukkitClass("CraftSound");
|
||||||
|
}
|
||||||
|
|
||||||
// ---- ItemStack conversions
|
// ---- ItemStack conversions
|
||||||
|
|
||||||
private static Method asNMSCopy = null;
|
private static Method asNMSCopy = null;
|
||||||
|
@ -29,6 +29,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -964,10 +965,21 @@ public class BukkitConverters {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodAccessor soundGetter = null;
|
private static MethodAccessor getSound = null;
|
||||||
|
private static MethodAccessor getSoundEffect = null;
|
||||||
private static FieldAccessor soundKey = null;
|
private static FieldAccessor soundKey = null;
|
||||||
|
|
||||||
|
private static Map<String, Sound> soundIndex = null;
|
||||||
|
|
||||||
public static EquivalentConverter<Sound> getSoundConverter() {
|
public static EquivalentConverter<Sound> getSoundConverter() {
|
||||||
|
if (getSound == null || getSoundEffect == null) {
|
||||||
|
Class<?> craftSound = MinecraftReflection.getCraftSoundClass();
|
||||||
|
FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftSound, true);
|
||||||
|
getSound = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSound", String.class, new Class<?>[] { Sound.class }));
|
||||||
|
getSoundEffect = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSoundEffect",
|
||||||
|
MinecraftReflection.getSoundEffectClass(), new Class<?>[] { String.class }));
|
||||||
|
}
|
||||||
|
|
||||||
return new IgnoreNullConverter<Sound>() {
|
return new IgnoreNullConverter<Sound>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -977,26 +989,42 @@ public class BukkitConverters {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getGenericValue(Class<?> genericType, Sound specific) {
|
protected Object getGenericValue(Class<?> genericType, Sound specific) {
|
||||||
if (soundGetter == null) {
|
// Getting the SoundEffect is easy, Bukkit provides us the methods
|
||||||
Class<?> soundEffects = MinecraftReflection.getMinecraftClass("SoundEffects");
|
String key = (String) getSound.invoke(null, specific);
|
||||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffects, true);
|
return getSoundEffect.invoke(null, key);
|
||||||
soundGetter = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSound", MinecraftReflection.getSoundEffectClass(), new Class<?>[] { String.class }));
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftKey key = MinecraftKey.fromEnum(specific);
|
|
||||||
return soundGetter.invoke(null, key.getFullKey());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Sound getSpecificValue(Object generic) {
|
protected Sound getSpecificValue(Object generic) {
|
||||||
|
// Getting the Sound is a bit more complicated...
|
||||||
if (soundKey == null) {
|
if (soundKey == null) {
|
||||||
Class<?> soundEffect = generic.getClass();
|
Class<?> soundEffect = generic.getClass();
|
||||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffect, true);
|
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffect, true);
|
||||||
soundKey = Accessors.getFieldAccessor(fuzzy.getFieldByType("key", MinecraftReflection.getMinecraftKeyClass()));
|
soundKey = Accessors.getFieldAccessor(fuzzy.getFieldByType("key", MinecraftReflection.getMinecraftKeyClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
MinecraftKey key = MinecraftKey.fromHandle(soundKey.get(generic));
|
MinecraftKey minecraftKey = MinecraftKey.fromHandle(soundKey.get(generic));
|
||||||
return Sound.valueOf(key.getEnumFormat());
|
String key = minecraftKey.getKey();
|
||||||
|
|
||||||
|
// Use our index if it already exists
|
||||||
|
if (soundIndex != null) {
|
||||||
|
return soundIndex.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it doesn't, try to guess the enum name
|
||||||
|
try {
|
||||||
|
return Sound.valueOf(minecraftKey.getEnumFormat());
|
||||||
|
} catch (IllegalArgumentException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Worst case we index all the sounds and use it later
|
||||||
|
soundIndex = new ConcurrentHashMap<>();
|
||||||
|
for (Sound sound : Sound.values()) {
|
||||||
|
String index = (String) getSound.invoke(null, sound);
|
||||||
|
soundIndex.put(index, sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundIndex.get(key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,9 @@ public class MinecraftKey {
|
|||||||
* is lower case, with underscores replaced by periods.
|
* is lower case, with underscores replaced by periods.
|
||||||
* @param value The value
|
* @param value The value
|
||||||
* @return The resulting key
|
* @return The resulting key
|
||||||
|
* @deprecated This isn't accurate in all cases
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static MinecraftKey fromEnum(Enum<?> value) {
|
public static MinecraftKey fromEnum(Enum<?> value) {
|
||||||
return new MinecraftKey(value.name().toLowerCase(Locale.ENGLISH).replace("_", "."));
|
return new MinecraftKey(value.name().toLowerCase(Locale.ENGLISH).replace("_", "."));
|
||||||
}
|
}
|
||||||
@ -103,7 +105,9 @@ public class MinecraftKey {
|
|||||||
* Returns this key back into Enum format, upper case with periods replaced
|
* Returns this key back into Enum format, upper case with periods replaced
|
||||||
* by underscores.
|
* by underscores.
|
||||||
* @return The enum format
|
* @return The enum format
|
||||||
|
* @deprecated This isn't accurate in all cases
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getEnumFormat() {
|
public String getEnumFormat() {
|
||||||
return key.toUpperCase(Locale.ENGLISH).replace(".", "_");
|
return key.toUpperCase(Locale.ENGLISH).replace(".", "_");
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren