diff --git a/pandalib-paper-reflect/src/main/java/fr/pandacube/lib/paper/reflect/util/PrimaryWorlds.java b/pandalib-paper-reflect/src/main/java/fr/pandacube/lib/paper/reflect/util/PrimaryWorlds.java new file mode 100644 index 0000000..978e886 --- /dev/null +++ b/pandalib-paper-reflect/src/main/java/fr/pandacube/lib/paper/reflect/util/PrimaryWorlds.java @@ -0,0 +1,40 @@ +package fr.pandacube.lib.paper.reflect.util; + +import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer; +import fr.pandacube.lib.reflect.wrapper.ReflectWrapper; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Utility method to get the list of the primary world of the Bukkit/Paper server. + * The primary worlds are the world that are loaded by the server at the startup, that the plugins cannot unload. + */ +public class PrimaryWorlds { + + /** + * An unmodifiable list containing the names of the primary worlds of this server instance, in the order they are + * loaded. This list can be accessed even if the corresponding worlds are not yet loaded, for instance in the + * {@link Plugin#onLoad()} method. + */ + public static final List PRIMARY_WORLDS; + + + static { + List primaryWorlds = new ArrayList<>(3); + + String world = ReflectWrapper.wrapTyped(Bukkit.getServer(), CraftServer.class).getServer().getLevelIdName(); + + primaryWorlds.add(world); + if (Bukkit.getAllowNether()) primaryWorlds.add(world + "_nether"); + if (Bukkit.getAllowEnd()) primaryWorlds.add(world + "_the_end"); + + PRIMARY_WORLDS = Collections.unmodifiableList(primaryWorlds); + } + + + +} diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/WorldUtil.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/WorldUtil.java new file mode 100644 index 0000000..84bc954 --- /dev/null +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/WorldUtil.java @@ -0,0 +1,75 @@ +package fr.pandacube.lib.paper.util; + +import org.bukkit.Bukkit; +import org.bukkit.World.Environment; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +public class WorldUtil { + + + + + public static Environment determineEnvironment(String world) { + if (Bukkit.getWorld(world) != null) { + return Bukkit.getWorld(world).getEnvironment(); + } + + File worldFolder = worldDir(world); + + if (!worldFolder.isDirectory()) + throw new IllegalStateException("The world " + world + " is not a valid world (directory not found)."); + + if (!new File(worldFolder, "level.dat").isFile()) + throw new IllegalStateException("The world " + world + " is not a valid world (level.dat not found)."); + + if (new File(worldFolder, "region").isDirectory()) + return Environment.NORMAL; + + if (new File(worldFolder, "DIM-1" + File.pathSeparator + "region").isDirectory()) + return Environment.NETHER; + + if (new File(worldFolder, "DIM1" + File.pathSeparator + "region").isDirectory()) + return Environment.THE_END; + + throw new IllegalStateException("Unable to determine the type of the world " + world + "."); + } + + + + private static final List REGION_DATA_FILES = Arrays.asList("entities", "poi", "region", "DIM-1", "DIM1"); + + public static List regionDataFiles(String world) { + return onlyExistents(worldDir(world), REGION_DATA_FILES); + } + + public static List mapFiles(String world) { + Pattern mapFilePattern = Pattern.compile("map_\\d+.dat"); + return List.of(dataDir(world).listFiles((dir, name) -> mapFilePattern.matcher(name).find() || "idcounts.dat".equals(name))); + } + + private static List onlyExistents(File worldDir, List searchList) { + return searchList.stream() + .map(f -> new File(worldDir, f)) + .filter(File::exists) + .toList(); + } + + public static File worldDir(String world) { + return new File(Bukkit.getWorldContainer(), world); + } + + public static File dataDir(String world) { + return new File(worldDir(world), "data"); + } + + public static boolean isValidWorld(String world) { + File d = worldDir(world); + return d.isDirectory() && new File(d, "level.dat").isFile(); + } + + +}