@@ -22,6 +22,38 @@ public boolean isCancelled() {
2222 }
2323 };
2424
25+ private static final ClassValue <ServerCapabilities > SERVER_CAPABILITIES = new ClassValue <>() {
26+ @ Override
27+ protected ServerCapabilities computeValue (Class <?> type ) {
28+ return new ServerCapabilities (
29+ findMethod (type , "getGlobalRegionScheduler" ),
30+ findMethod (type , "getRegionScheduler" )
31+ );
32+ }
33+ };
34+ private static final ClassValue <EntityCapabilities > ENTITY_CAPABILITIES = new ClassValue <>() {
35+ @ Override
36+ protected EntityCapabilities computeValue (Class <?> type ) {
37+ return new EntityCapabilities (
38+ findMethod (type , "getScheduler" )
39+ );
40+ }
41+ };
42+ private static final ClassValue <SchedulerCapabilities > SCHEDULER_CAPABILITIES = new ClassValue <>() {
43+ @ Override
44+ protected SchedulerCapabilities computeValue (Class <?> type ) {
45+ return new SchedulerCapabilities (
46+ findMethod (type , "run" , Plugin .class , Consumer .class ),
47+ findMethod (type , "runDelayed" , Plugin .class , Consumer .class , long .class ),
48+ findMethod (type , "runAtFixedRate" , Plugin .class , Consumer .class , long .class , long .class ),
49+ findMethod (type , "run" , Plugin .class , Location .class , Consumer .class ),
50+ findMethod (type , "runDelayed" , Plugin .class , Location .class , Consumer .class , long .class ),
51+ findMethod (type , "runAtFixedRate" , Plugin .class , Location .class , Consumer .class , long .class , long .class ),
52+ findMethod (type , "run" , Plugin .class , Consumer .class , Runnable .class ),
53+ findMethod (type , "runDelayed" , Plugin .class , Consumer .class , Runnable .class , long .class )
54+ );
55+ }
56+ };
2557 private final Plugin plugin ;
2658
2759 public ServerScheduler (Plugin plugin ) {
@@ -34,10 +66,10 @@ public PluginTask runGlobal(Runnable runnable) {
3466 }
3567 Object scheduler = this .globalRegionScheduler ();
3668 if (scheduler != null ) {
69+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).globalRun ();
3770 PluginTask task = this .invokeSchedulerTask (
3871 scheduler ,
39- "run" ,
40- new Class <?>[] {Plugin .class , Consumer .class },
72+ method ,
4173 this .plugin ,
4274 taskConsumer (runnable )
4375 );
@@ -54,10 +86,10 @@ public PluginTask runGlobalDelayed(Runnable runnable, long delayTicks) {
5486 }
5587 Object scheduler = this .globalRegionScheduler ();
5688 if (scheduler != null ) {
89+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).globalDelayed ();
5790 PluginTask task = this .invokeSchedulerTask (
5891 scheduler ,
59- "runDelayed" ,
60- new Class <?>[] {Plugin .class , Consumer .class , long .class },
92+ method ,
6193 this .plugin ,
6294 taskConsumer (runnable ),
6395 delayTicks
@@ -75,10 +107,10 @@ public PluginTask runGlobalTimer(Runnable runnable, long delayTicks, long period
75107 }
76108 Object scheduler = this .globalRegionScheduler ();
77109 if (scheduler != null ) {
110+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).globalTimer ();
78111 PluginTask task = this .invokeSchedulerTask (
79112 scheduler ,
80- "runAtFixedRate" ,
81- new Class <?>[] {Plugin .class , Consumer .class , long .class , long .class },
113+ method ,
82114 this .plugin ,
83115 taskConsumer (runnable ),
84116 delayTicks ,
@@ -97,10 +129,10 @@ public PluginTask runRegion(Location location, Runnable runnable) {
97129 }
98130 Object scheduler = this .regionScheduler ();
99131 if (scheduler != null ) {
132+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).regionRun ();
100133 PluginTask task = this .invokeSchedulerTask (
101134 scheduler ,
102- "run" ,
103- new Class <?>[] {Plugin .class , Location .class , Consumer .class },
135+ method ,
104136 this .plugin ,
105137 location ,
106138 taskConsumer (runnable )
@@ -118,10 +150,10 @@ public PluginTask runRegionDelayed(Location location, Runnable runnable, long de
118150 }
119151 Object scheduler = this .regionScheduler ();
120152 if (scheduler != null ) {
153+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).regionDelayed ();
121154 PluginTask task = this .invokeSchedulerTask (
122155 scheduler ,
123- "runDelayed" ,
124- new Class <?>[] {Plugin .class , Location .class , Consumer .class , long .class },
156+ method ,
125157 this .plugin ,
126158 location ,
127159 taskConsumer (runnable ),
@@ -140,10 +172,10 @@ public PluginTask runRegionTimer(Location location, Runnable runnable, long dela
140172 }
141173 Object scheduler = this .regionScheduler ();
142174 if (scheduler != null ) {
175+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).regionTimer ();
143176 PluginTask task = this .invokeSchedulerTask (
144177 scheduler ,
145- "runAtFixedRate" ,
146- new Class <?>[] {Plugin .class , Location .class , Consumer .class , long .class , long .class },
178+ method ,
147179 this .plugin ,
148180 location ,
149181 taskConsumer (runnable ),
@@ -163,10 +195,10 @@ public PluginTask runEntity(Entity entity, Runnable runnable) {
163195 }
164196 Object scheduler = this .entityScheduler (entity );
165197 if (scheduler != null ) {
198+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).entityRun ();
166199 PluginTask task = this .invokeSchedulerTask (
167200 scheduler ,
168- "run" ,
169- new Class <?>[] {Plugin .class , Consumer .class , Runnable .class },
201+ method ,
170202 this .plugin ,
171203 taskConsumer (runnable ),
172204 NO_OP_RUNNABLE
@@ -184,10 +216,10 @@ public PluginTask runEntityDelayed(Entity entity, Runnable runnable, long delayT
184216 }
185217 Object scheduler = this .entityScheduler (entity );
186218 if (scheduler != null ) {
219+ Method method = SCHEDULER_CAPABILITIES .get (scheduler .getClass ()).entityDelayed ();
187220 PluginTask task = this .invokeSchedulerTask (
188221 scheduler ,
189- "runDelayed" ,
190- new Class <?>[] {Plugin .class , Consumer .class , Runnable .class , long .class },
222+ method ,
191223 this .plugin ,
192224 taskConsumer (runnable ),
193225 NO_OP_RUNNABLE ,
@@ -246,40 +278,44 @@ public PluginTask removeEntity(Entity entity, long delayTicks) {
246278 }
247279
248280 private Object globalRegionScheduler () {
249- return this .invokeNoArgs (this .plugin .getServer (), "getGlobalRegionScheduler" );
281+ Object server = this .plugin .getServer ();
282+ Method method = server == null ? null : SERVER_CAPABILITIES .get (server .getClass ()).globalRegionScheduler ();
283+ return this .invokeNoArgs (server , method );
250284 }
251285
252286 private Object regionScheduler () {
253- return this .invokeNoArgs (this .plugin .getServer (), "getRegionScheduler" );
287+ Object server = this .plugin .getServer ();
288+ Method method = server == null ? null : SERVER_CAPABILITIES .get (server .getClass ()).regionScheduler ();
289+ return this .invokeNoArgs (server , method );
254290 }
255291
256292 private Object entityScheduler (Entity entity ) {
257- return this .invokeNoArgs (entity , "getScheduler" );
293+ Method method = entity == null ? null : ENTITY_CAPABILITIES .get (entity .getClass ()).scheduler ();
294+ return this .invokeNoArgs (entity , method );
258295 }
259296
260297 private boolean isPluginEnabled () {
261298 return this .plugin .isEnabled ();
262299 }
263300
264- private Object invokeNoArgs (Object target , String methodName ) {
265- if (target == null ) {
301+ private Object invokeNoArgs (Object target , Method method ) {
302+ if (target == null || method == null ) {
266303 return null ;
267304 }
268305 try {
269- Method method = target .getClass ().getMethod (methodName );
270- method .setAccessible (true );
271306 return method .invoke (target );
272- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | RuntimeException exception ) {
307+ } catch (IllegalAccessException | InvocationTargetException | RuntimeException exception ) {
273308 return null ;
274309 }
275310 }
276311
277- private PluginTask invokeSchedulerTask (Object scheduler , String methodName , Class <?>[] parameterTypes , Object ... args ) {
312+ private PluginTask invokeSchedulerTask (Object scheduler , Method method , Object ... args ) {
313+ if (method == null ) {
314+ return null ;
315+ }
278316 try {
279- Method method = scheduler .getClass ().getMethod (methodName , parameterTypes );
280- method .setAccessible (true );
281317 return wrap (method .invoke (scheduler , args ));
282- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | RuntimeException exception ) {
318+ } catch (IllegalAccessException | InvocationTargetException | RuntimeException exception ) {
283319 return null ;
284320 }
285321 }
@@ -334,7 +370,34 @@ private static Object invokeTaskMethod(Object task, String methodName) {
334370 }
335371 }
336372
373+ private static Method findMethod (Class <?> type , String methodName , Class <?>... parameterTypes ) {
374+ try {
375+ Method method = type .getMethod (methodName , parameterTypes );
376+ method .setAccessible (true );
377+ return method ;
378+ } catch (NoSuchMethodException | RuntimeException exception ) {
379+ return null ;
380+ }
381+ }
382+
383+ private record ServerCapabilities (Method globalRegionScheduler , Method regionScheduler ) {
384+ }
385+
386+ private record EntityCapabilities (Method scheduler ) {
387+ }
388+
389+ private record SchedulerCapabilities (
390+ Method globalRun ,
391+ Method globalDelayed ,
392+ Method globalTimer ,
393+ Method regionRun ,
394+ Method regionDelayed ,
395+ Method regionTimer ,
396+ Method entityRun ,
397+ Method entityDelayed
398+ ) {
399+ }
400+
337401 private static final Runnable NO_OP_RUNNABLE = () -> {
338402 };
339403}
340-
0 commit comments