diff --git a/shared/src/main/java/me/xginko/aef/utils/reflection/ReflectionUtil.java b/shared/src/main/java/me/xginko/aef/utils/reflection/ReflectionUtil.java index 5252e1d4..7c433662 100644 --- a/shared/src/main/java/me/xginko/aef/utils/reflection/ReflectionUtil.java +++ b/shared/src/main/java/me/xginko/aef/utils/reflection/ReflectionUtil.java @@ -118,6 +118,31 @@ public static boolean hasClass(final @NonNull String className) { return findClass(className) != null; } + /** + * Gets a handle for a class method, regardless of its return type. + * + *
{@link #findMethod} matches on the exact {@link MethodType}, return type included, so it + * cannot look up a method whose return class is not available at compile time. Use this instead + * when only the name and parameters are known.
+ * + * @param holderClass a class + * @param methodName a method name + * @param parameterClasses an array of method parameter classes + * @return a method handle or {@code null} if not found + */ + public static @Nullable MethodHandle findMethodAnyReturn(final @Nullable Class> holderClass, final String methodName, final Class>... parameterClasses) { + if (holderClass == null) return null; + for (final Class> parameterClass : parameterClasses) { + if (parameterClass == null) return null; + } + + try { + return LOOKUP.unreflect(holderClass.getMethod(methodName, parameterClasses)); + } catch (final NoSuchMethodException | IllegalAccessException e) { + return null; + } + } + /** * Gets a handle for a class method. * diff --git a/shared/src/main/java/me/xginko/aef/utils/tickdata/FoliaTickReporter.java b/shared/src/main/java/me/xginko/aef/utils/tickdata/FoliaTickReporter.java index b3a1837d..aadd735e 100644 --- a/shared/src/main/java/me/xginko/aef/utils/tickdata/FoliaTickReporter.java +++ b/shared/src/main/java/me/xginko/aef/utils/tickdata/FoliaTickReporter.java @@ -24,10 +24,11 @@ public FoliaTickReporter(Server server, Duration cacheTime) { this.tps_cache = Caffeine.newBuilder().expireAfterWrite(cacheTime).build(); this.mspt_cache = Caffeine.newBuilder().expireAfterWrite(cacheTime).build(); - this.getTickReport5s = ReflectionUtil.findMethod( + // Returns TickData.TickReportData, which is not on the compile classpath, so the return + // type must not be part of the lookup. + this.getTickReport5s = ReflectionUtil.findMethodAnyReturn( TickRegionScheduler.RegionScheduleHandle.class, "getTickReport5s", - Object.class, long.class ); } @@ -49,10 +50,7 @@ public void disable() { @Override public double getGlobalTPS() { - if (getTickReport5s != null) { - return tps_cache.get(RegionizedServer.getGlobalTickData(), this::extractTpsValue); - } - return server.getTPS()[0]; + return tps_cache.get(RegionizedServer.getGlobalTickData(), this::extractTpsValue); } @Override @@ -60,18 +58,12 @@ public double getTPS() { final ThreadedRegionizer.ThreadedRegion