Use reflection to test for Paper and check if it is safe to load or unload worlds

Note: this code was designed under the assumption that PaperMC/Paper#8316 will be accepted, so it won't work unless the commit from that PR is included in the Paper build.
This commit is contained in:
BuildTools 2022-08-19 17:32:48 -04:00 committed by willkroboth
parent 9ea2037910
commit 200a461b03
1 changed files with 20 additions and 2 deletions

View File

@ -37,6 +37,8 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -1035,8 +1037,7 @@ public class WorldManager implements MVWorldManager {
* {@inheritDoc}
*/
public void addOrRemoveWorldSafely(String worldName, String operationName, Runnable worldModification) {
// TODO: Find real way to tell if worlds are being ticked
if (!worldName.equals("testWorld")) {
if (safeToAddOrRemoveWorld()) {
// Operation is fine to do now
worldModification.run();
} else {
@ -1050,4 +1051,21 @@ public class WorldManager implements MVWorldManager {
}.runTask(plugin);
}
}
private boolean safeToAddOrRemoveWorld(){
Method isTickingWorlds;
try {
isTickingWorlds = Bukkit.class.getMethod("isTickingWorlds");
} catch (NoSuchMethodException e) {
// Paper fixes aren't active, so it is always considered safe to proceed
return true;
}
// Paper fixes are active, so we need to and can check Bukkit.isTickingWorlds
try {
return !(boolean) isTickingWorlds.invoke(null);
} catch (InvocationTargetException | IllegalAccessException e) {
// Shouldn't happen, I know I'm using the method correctly
throw new RuntimeException(e);
}
}
}