From 77b0a0c73ccbef26c3b77f8f87ab512a1bba18e0 Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Sat, 20 Jan 2024 18:46:50 +0100 Subject: [PATCH] Improved World utility classes --- .../lib/paper/backup/PaperWorldProcess.java | 2 +- .../lib/paper/players/PaperOffPlayer.java | 2 +- .../pandacube/lib/paper/world/ChunkCoord.java | 24 ++++++++++++ .../lib/paper/world/RegionCoord.java | 38 +++++++++++++++++++ .../lib/paper/{util => world}/WorldUtil.java | 34 +++++++++++++++-- 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/ChunkCoord.java create mode 100644 pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/RegionCoord.java rename pandalib-paper/src/main/java/fr/pandacube/lib/paper/{util => world}/WorldUtil.java (65%) diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/backup/PaperWorldProcess.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/backup/PaperWorldProcess.java index a9f5d4f..237664a 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/backup/PaperWorldProcess.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/backup/PaperWorldProcess.java @@ -1,7 +1,7 @@ package fr.pandacube.lib.paper.backup; import fr.pandacube.lib.paper.scheduler.SchedulerUtil; -import fr.pandacube.lib.paper.util.WorldUtil; +import fr.pandacube.lib.paper.world.WorldUtil; import fr.pandacube.lib.util.log.Log; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java index 743f84f..f71f558 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/players/PaperOffPlayer.java @@ -8,7 +8,7 @@ import fr.pandacube.lib.paper.reflect.wrapper.minecraft.SharedConstants; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.NbtIo; import fr.pandacube.lib.paper.util.PlayerDataWrapper; -import fr.pandacube.lib.paper.util.WorldUtil; +import fr.pandacube.lib.paper.world.WorldUtil; import fr.pandacube.lib.players.standalone.AbstractOffPlayer; import fr.pandacube.lib.reflect.wrapper.ReflectWrapper; import org.bukkit.Bukkit; diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/ChunkCoord.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/ChunkCoord.java new file mode 100644 index 0000000..f53c933 --- /dev/null +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/ChunkCoord.java @@ -0,0 +1,24 @@ +package fr.pandacube.lib.paper.world; + +import org.bukkit.Chunk; +import org.bukkit.World; + +public record ChunkCoord(int x, int z) { + + public ChunkCoord(Chunk c) { + this(c.getX(), c.getZ()); + } + + @Override + public String toString() { + return "(" + x + ";" + z + ")"; + } + + public RegionCoord getRegionCoord() { + return new RegionCoord(x >> 5, z >> 5); + } + + public Chunk getChunk(World w) { + return w.getChunkAt(x, z); + } +} diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/RegionCoord.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/RegionCoord.java new file mode 100644 index 0000000..3d15bd5 --- /dev/null +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/RegionCoord.java @@ -0,0 +1,38 @@ +package fr.pandacube.lib.paper.world; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public record RegionCoord(int x, int z) { + + public int distToCenter() { + return Math.max(Math.abs(x), Math.abs(z)); + } + + public String getFileName() { + return "r." + x + "." + z + ".mca"; + } + + public ChunkCoord getMinChunk() { + return new ChunkCoord(x << 5, z << 5); + } + + public ChunkCoord getMaxChunk() { + return new ChunkCoord(x << 5 | 31, z << 5 | 31); + } + + + + private static final Pattern REGION_FILE_NAME_PATTERN = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$"); + + public static RegionCoord fromFileName(String name) { + Matcher m = REGION_FILE_NAME_PATTERN.matcher(name); + if (m.find()) { + int x = Integer.parseInt(m.group(1)); + int z = Integer.parseInt(m.group(2)); + return new RegionCoord(x, z); + } + throw new IllegalArgumentException("Provided string is not a Minecraft region file name."); + } + +} 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/world/WorldUtil.java similarity index 65% rename from pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/WorldUtil.java rename to pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/WorldUtil.java index 5c2350b..f4bdc66 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/util/WorldUtil.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/world/WorldUtil.java @@ -1,4 +1,4 @@ -package fr.pandacube.lib.paper.util; +package fr.pandacube.lib.paper.world; import org.bukkit.Bukkit; import org.bukkit.World; @@ -7,6 +7,7 @@ import org.bukkit.World.Environment; import java.io.File; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; public class WorldUtil { @@ -40,11 +41,38 @@ public class WorldUtil { throw new IllegalStateException("Unable to determine the type of the world " + world + "."); } - + public List getExistingRegions(String world) { + Environment env = determineEnvironment(world); + + File worldFolder = worldDir(world); + + File file = switch (env) { + case NORMAL -> new File(worldFolder, "region"); + case NETHER -> new File(worldFolder, "DIM-1" + File.pathSeparator + "region"); + case THE_END -> new File(worldFolder, "DIM1" + File.pathSeparator + "region"); + case CUSTOM -> throw new IllegalStateException("The provided world '" + world + "' has a custom Environment type. Unable to tell where the region are stored."); + }; + + String[] fileList = file.list(); + if (fileList == null) { + throw new IllegalStateException("The provided world '" + world + "' does not hae a valid region folder."); + } + + return Arrays.stream(fileList) + .map(name -> { + try { + return RegionCoord.fromFileName(name); + } catch (IllegalArgumentException e) { + return null; + } + }) + .filter(Objects::nonNull) + .toList(); + } private static final List REGION_DATA_FILES = Arrays.asList("entities", "poi", "region", "DIM-1", "DIM1"); - public static List regionDataFiles(String world) { + public static List regionDataFolders(String world) { return onlyExisting(worldDir(world), REGION_DATA_FILES); }