Improved World utility classes

This commit is contained in:
Marc Baloup 2024-01-20 18:46:50 +01:00
parent 93960b83c2
commit 77b0a0c73c
5 changed files with 95 additions and 5 deletions

View File

@ -1,7 +1,7 @@
package fr.pandacube.lib.paper.backup; package fr.pandacube.lib.paper.backup;
import fr.pandacube.lib.paper.scheduler.SchedulerUtil; 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 fr.pandacube.lib.util.log.Log;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;

View File

@ -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.CompoundTag;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.NbtIo; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.NbtIo;
import fr.pandacube.lib.paper.util.PlayerDataWrapper; 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.players.standalone.AbstractOffPlayer;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper; import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;

View File

@ -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);
}
}

View File

@ -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.");
}
}

View File

@ -1,4 +1,4 @@
package fr.pandacube.lib.paper.util; package fr.pandacube.lib.paper.world;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
@ -7,6 +7,7 @@ import org.bukkit.World.Environment;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class WorldUtil { public class WorldUtil {
@ -40,11 +41,38 @@ public class WorldUtil {
throw new IllegalStateException("Unable to determine the type of the world " + world + "."); throw new IllegalStateException("Unable to determine the type of the world " + world + ".");
} }
public List<RegionCoord> 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<String> REGION_DATA_FILES = Arrays.asList("entities", "poi", "region", "DIM-1", "DIM1"); private static final List<String> REGION_DATA_FILES = Arrays.asList("entities", "poi", "region", "DIM-1", "DIM1");
public static List<File> regionDataFiles(String world) { public static List<File> regionDataFolders(String world) {
return onlyExisting(worldDir(world), REGION_DATA_FILES); return onlyExisting(worldDir(world), REGION_DATA_FILES);
} }