Skip to content

Commit 540a5e5

Browse files
committed
Make Sound handling more robust
Fixes aadnk#119
1 parent 27047f8 commit 540a5e5

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

modules/API/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,10 @@ public static Class<?> getNonNullListClass() {
18471847
return getMinecraftClass("NonNullList");
18481848
}
18491849

1850+
public static Class<?> getCraftSoundClass() {
1851+
return getCraftBukkitClass("CraftSound");
1852+
}
1853+
18501854
// ---- ItemStack conversions
18511855

18521856
private static Method asNMSCopy = null;

modules/API/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Map;
3030
import java.util.Map.Entry;
3131
import java.util.Set;
32+
import java.util.concurrent.ConcurrentHashMap;
3233

3334
import org.bukkit.Material;
3435
import org.bukkit.Sound;
@@ -964,10 +965,21 @@ protected Vector getSpecificValue(Object generic) {
964965
};
965966
}
966967

967-
private static MethodAccessor soundGetter = null;
968+
private static MethodAccessor getSound = null;
969+
private static MethodAccessor getSoundEffect = null;
968970
private static FieldAccessor soundKey = null;
969971

972+
private static Map<String, Sound> soundIndex = null;
973+
970974
public static EquivalentConverter<Sound> getSoundConverter() {
975+
if (getSound == null || getSoundEffect == null) {
976+
Class<?> craftSound = MinecraftReflection.getCraftSoundClass();
977+
FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftSound, true);
978+
getSound = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSound", String.class, new Class<?>[] { Sound.class }));
979+
getSoundEffect = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSoundEffect",
980+
MinecraftReflection.getSoundEffectClass(), new Class<?>[] { String.class }));
981+
}
982+
971983
return new IgnoreNullConverter<Sound>() {
972984

973985
@Override
@@ -977,26 +989,42 @@ public Class<Sound> getSpecificType() {
977989

978990
@Override
979991
protected Object getGenericValue(Class<?> genericType, Sound specific) {
980-
if (soundGetter == null) {
981-
Class<?> soundEffects = MinecraftReflection.getMinecraftClass("SoundEffects");
982-
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffects, true);
983-
soundGetter = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSound", MinecraftReflection.getSoundEffectClass(), new Class<?>[] { String.class }));
984-
}
985-
986-
MinecraftKey key = MinecraftKey.fromEnum(specific);
987-
return soundGetter.invoke(null, key.getFullKey());
992+
// Getting the SoundEffect is easy, Bukkit provides us the methods
993+
String key = (String) getSound.invoke(null, specific);
994+
return getSoundEffect.invoke(null, key);
988995
}
989996

990997
@Override
991998
protected Sound getSpecificValue(Object generic) {
999+
// Getting the Sound is a bit more complicated...
9921000
if (soundKey == null) {
9931001
Class<?> soundEffect = generic.getClass();
9941002
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffect, true);
9951003
soundKey = Accessors.getFieldAccessor(fuzzy.getFieldByType("key", MinecraftReflection.getMinecraftKeyClass()));
9961004
}
9971005

998-
MinecraftKey key = MinecraftKey.fromHandle(soundKey.get(generic));
999-
return Sound.valueOf(key.getEnumFormat());
1006+
MinecraftKey minecraftKey = MinecraftKey.fromHandle(soundKey.get(generic));
1007+
String key = minecraftKey.getKey();
1008+
1009+
// Use our index if it already exists
1010+
if (soundIndex != null) {
1011+
return soundIndex.get(key);
1012+
}
1013+
1014+
// If it doesn't, try to guess the enum name
1015+
try {
1016+
return Sound.valueOf(minecraftKey.getEnumFormat());
1017+
} catch (IllegalArgumentException ignored) {
1018+
}
1019+
1020+
// Worst case we index all the sounds and use it later
1021+
soundIndex = new ConcurrentHashMap<>();
1022+
for (Sound sound : Sound.values()) {
1023+
String index = (String) getSound.invoke(null, sound);
1024+
soundIndex.put(index, sound);
1025+
}
1026+
1027+
return soundIndex.get(key);
10001028
}
10011029
};
10021030
}

modules/API/src/main/java/com/comphenix/protocol/wrappers/MinecraftKey.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ public static MinecraftKey fromHandle(Object handle) {
6969
* is lower case, with underscores replaced by periods.
7070
* @param value The value
7171
* @return The resulting key
72+
* @deprecated This isn't accurate in all cases
7273
*/
74+
@Deprecated
7375
public static MinecraftKey fromEnum(Enum<?> value) {
7476
return new MinecraftKey(value.name().toLowerCase(Locale.ENGLISH).replace("_", "."));
7577
}
@@ -103,7 +105,9 @@ public String getFullKey() {
103105
* Returns this key back into Enum format, upper case with periods replaced
104106
* by underscores.
105107
* @return The enum format
108+
* @deprecated This isn't accurate in all cases
106109
*/
110+
@Deprecated
107111
public String getEnumFormat() {
108112
return key.toUpperCase(Locale.ENGLISH).replace(".", "_");
109113
}

0 commit comments

Comments
 (0)