package com.gmail.nossr50.util.sounds; import static java.lang.String.format; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.util.AttributeMapper; import com.gmail.nossr50.util.LogUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.bukkit.NamespacedKey; import org.bukkit.Sound; import org.jetbrains.annotations.Nullable; public final class SoundRegistryUtils { private static Method registryLookup; private static Object soundReg; public static final String PAPER_SOUND_REGISTRY_FIELD = "SOUND_EVENT"; public static final String SPIGOT_SOUND_REGISTRY_FIELD = "SOUNDS"; public static final String METHOD_GET_OR_THROW_NAME = "getOrThrow"; public static final String METHOD_GET_NAME = "get"; static { boolean foundRegistry = false; Class registry; try { registry = Class.forName(AttributeMapper.ORG_BUKKIT_REGISTRY); try { // First check for Paper's sound registry, held by field SOUND_EVENT soundReg = registry.getField(PAPER_SOUND_REGISTRY_FIELD).get(null); foundRegistry = true; } catch (NoSuchFieldException | IllegalAccessException e) { try { soundReg = registry.getField(SPIGOT_SOUND_REGISTRY_FIELD); foundRegistry = true; } catch (NoSuchFieldException ex) { // ignored } } } catch (ClassNotFoundException e) { // ignored } if (foundRegistry) { try { // getOrThrow isn't in all API versions, but we use it if it exists registryLookup = soundReg.getClass().getMethod(METHOD_GET_OR_THROW_NAME, NamespacedKey.class); } catch (NoSuchMethodException e) { try { registryLookup = soundReg.getClass().getMethod(METHOD_GET_NAME, NamespacedKey.class); } catch (NoSuchMethodException ex) { // ignored exception registryLookup = null; } } } } public static boolean useLegacyLookup() { return registryLookup == null; } public static @Nullable Sound getSound(String id, String fallBackId) { if (registryLookup != null) { try { return (Sound) registryLookup.invoke(soundReg, NamespacedKey.fromString(id)); } catch(InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { if (fallBackId != null) { LogUtils.debug(mcMMO.p.getLogger(), format("Could not find sound with ID '%s', trying fallback ID '%s'", id, fallBackId)); try { return (Sound) registryLookup.invoke(soundReg, NamespacedKey.fromString(fallBackId)); } catch (IllegalAccessException | InvocationTargetException ex) { mcMMO.p.getLogger().severe(format("Could not find sound with ID %s," + " fallback ID of %s also failed.", id, fallBackId)); } } else { mcMMO.p.getLogger().severe(format("Could not find sound with ID %s.", id)); } throw new RuntimeException(e); } } return null; } }