From ece905ec6e27bab3f9f13d9df099bf185acd9950 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 4 Feb 2025 21:11:08 +0100 Subject: [PATCH] fix registry lookup failing on some server versions --- .../iris/util/data/registry/RegistryUtil.java | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java b/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java index 0dc17c5ad..b3377ebe8 100644 --- a/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java +++ b/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java @@ -1,15 +1,18 @@ package com.volmit.iris.util.data.registry; import com.volmit.iris.core.nms.container.Pair; +import com.volmit.iris.engine.data.cache.AtomicCache; import lombok.NonNull; import org.bukkit.Bukkit; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.Registry; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -20,6 +23,7 @@ import java.util.stream.Collectors; @SuppressWarnings("unchecked") public class RegistryUtil { + private static final AtomicCache registryLookup = new AtomicCache<>(); private static final Map, Map> KEYED_REGISTRY = new HashMap<>(); private static final Map, Map> ENUM_REGISTRY = new HashMap<>(); private static final Map, Registry> REGISTRY = new HashMap<>(); @@ -43,7 +47,7 @@ public class RegistryUtil { if (keys.length == 0) throw new IllegalArgumentException("Need at least one key"); Registry registry = null; if (Keyed.class.isAssignableFrom(typeClass)) { - registry = Bukkit.getRegistry(typeClass.asSubclass(Keyed.class)); + registry = getRegistry(typeClass.asSubclass(Keyed.class)); } if (registry == null) { registry = REGISTRY.computeIfAbsent(typeClass, t -> Arrays.stream(Registry.class.getDeclaredFields()) @@ -150,4 +154,56 @@ public class RegistryUtil { }; } } + + @Nullable + private static Registry getRegistry(@NotNull Class type) { + RegistryLookup lookup = registryLookup.aquire(() -> { + RegistryLookup bukkit; + try { + bukkit = Bukkit::getRegistry; + } catch (Throwable ignored) { + bukkit = null; + } + return new DefaultRegistryLookup(bukkit); + }); + return lookup.find(type); + } + + private interface RegistryLookup { + @Nullable + Registry find(@NonNull Class type); + } + + private static class DefaultRegistryLookup implements RegistryLookup { + private final RegistryLookup bukkit; + private final Map registries; + + private DefaultRegistryLookup(RegistryLookup bukkit) { + this.bukkit = bukkit; + registries = Arrays.stream(Registry.class.getDeclaredFields()) + .filter(field -> Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) + .filter(field -> Registry.class.isAssignableFrom(field.getType())) + .map(field -> { + var type = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; + try { + return new Pair<>(type, field.get(null)); + } catch (Throwable e) { + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toMap(Pair::getA, Pair::getB, (a, b) -> a)); + } + + @Nullable + @Override + public Registry find(@NonNull Class type) { + if (bukkit == null) return (Registry) registries.get(type); + try { + return bukkit.find(type); + } catch (Throwable e) { + return (Registry) registries.get(type); + } + } + } }