18
18
import com .onarandombox .MultiverseCore .api .WorldPurger ;
19
19
import com .onarandombox .MultiverseCore .event .MVWorldDeleteEvent ;
20
20
import org .bukkit .Bukkit ;
21
- import org .bukkit .ChatColor ;
22
21
import org .bukkit .GameRule ;
23
22
import org .bukkit .Location ;
24
- import org .bukkit .Server ;
25
23
import org .bukkit .World ;
26
24
import org .bukkit .World .Environment ;
27
25
import org .bukkit .WorldCreator ;
39
37
import java .io .File ;
40
38
import java .io .FilenameFilter ;
41
39
import java .io .IOException ;
42
- import java .lang .reflect .Field ;
43
40
import java .lang .reflect .InvocationTargetException ;
44
41
import java .lang .reflect .Method ;
45
42
import java .util .ArrayList ;
54
51
import java .util .Stack ;
55
52
import java .util .concurrent .Callable ;
56
53
import java .util .concurrent .ConcurrentHashMap ;
57
- import java .util .regex .Pattern ;
58
54
import java .util .stream .Collectors ;
59
55
60
56
/**
@@ -1041,12 +1037,13 @@ public Collection<String> getPotentialWorlds() {
1041
1037
*/
1042
1038
@ Override
1043
1039
public void addOrRemoveWorldSafely (String worldName , String operationName , Runnable worldModification ) {
1040
+ Logging .finest ("Checking if it is safe to perform world modification" );
1044
1041
if (safeToAddOrRemoveWorld ()) {
1045
1042
// Operation is fine to do now
1043
+ Logging .finest ("Clear to modify worlds" );
1046
1044
worldModification .run ();
1047
1045
} else {
1048
1046
// Operation needs to be delayed until worlds are not being ticked
1049
-
1050
1047
Logging .fine ("Worlds were being ticked while attempting to %s %s. Trying again in the next tick" , operationName , worldName );
1051
1048
new BukkitRunnable () {
1052
1049
public void run () {
@@ -1057,30 +1054,22 @@ public void run() {
1057
1054
}
1058
1055
1059
1056
private boolean safeToAddOrRemoveWorld (){
1060
- Server server = Bukkit . getServer ( );
1061
- Logging . finest ( "Using reflection to test for Paper build after PR #7653" ) ;
1057
+ Logging . finest ( "Checking for Paper" );
1058
+ Method isTickingWorlds ;
1062
1059
try {
1063
- // basically doing ((CraftServer) Bukkit.getServer()).getServer().isIteratingOverLevels;
1064
- Method getConsole = server .getClass ().getMethod ("getServer" );
1065
- Object console = getConsole .invoke (server );
1066
-
1067
- Field isTickingWorlds = console .getClass ().getField ("isIteratingOverLevels" );
1068
- boolean isTicking = isTickingWorlds .getBoolean (console );
1069
-
1070
- Logging .finest ("Paper fix active" );
1071
- return !isTicking ;
1072
- } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e ) {
1073
- Logging .finest ("%sUnexpected exception: %s" , ChatColor .RED , e .getMessage ());
1074
- Logging .finest ("Assuming Paper fix is inactive" );
1075
- // If the Paper fix actually is active it should become obvious when Paper complains
1076
- // about a world being loaded/unloaded while being ticked
1077
- // If that happens, this method needs to be fixed
1078
- return true ;
1079
- } catch (NoSuchFieldException ignored ) {
1080
- // Expected to fail when field isIteratingOverLevels doesn't exist
1081
- // Therefore, Paper fixes aren't active, so it is always considered safe to proceed
1082
- Logging .finest ("Paper fix inactive" );
1060
+ isTickingWorlds = Bukkit .class .getMethod ("isTickingWorlds" );
1061
+ } catch (NoSuchMethodException e ) {
1062
+ // Paper fixes aren't active, so it is always considered safe to proceed
1063
+ Logging .finest ("Paper fixes inactive" );
1083
1064
return true ;
1084
1065
}
1066
+ // Paper fixes are active, and Paper wants us to check Bukkit.isTickingWorlds()
1067
+ Logging .finest ("Paper fixes active" );
1068
+ try {
1069
+ return !(boolean ) isTickingWorlds .invoke (null );
1070
+ } catch (InvocationTargetException | IllegalAccessException e ) {
1071
+ // Shouldn't happen, I know I'm using the method correctly
1072
+ throw new RuntimeException (e );
1073
+ }
1085
1074
}
1086
1075
}
0 commit comments