summaryrefslogtreewikicommitdiff
path: root/src/main/java/cat/freya/khs/world
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-09-06 23:11:25 -0400
committerFreya Murphy <freya@freyacat.org>2025-09-06 23:11:25 -0400
commit67aba9081bb73aeaa822b059e8ca6defc8352a2f (patch)
treecba7c5c8c9a0286b491b0b0784a27730ce58696e /src/main/java/cat/freya/khs/world
parentadd wiki for cgit (diff)
downloadkenshinshideandseek-67aba9081bb73aeaa822b059e8ca6defc8352a2f.tar.gz
kenshinshideandseek-67aba9081bb73aeaa822b059e8ca6defc8352a2f.tar.bz2
kenshinshideandseek-67aba9081bb73aeaa822b059e8ca6defc8352a2f.zip
rename pacakges dev.tylerm -> cat.freya
Diffstat (limited to 'src/main/java/cat/freya/khs/world')
-rw-r--r--src/main/java/cat/freya/khs/world/VoidGenerator.java55
-rw-r--r--src/main/java/cat/freya/khs/world/WorldLoader.java155
2 files changed, 210 insertions, 0 deletions
diff --git a/src/main/java/cat/freya/khs/world/VoidGenerator.java b/src/main/java/cat/freya/khs/world/VoidGenerator.java
new file mode 100644
index 0000000..947fddb
--- /dev/null
+++ b/src/main/java/cat/freya/khs/world/VoidGenerator.java
@@ -0,0 +1,55 @@
+package cat.freya.khs.world;
+
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.block.Biome;
+import org.bukkit.generator.BlockPopulator;
+import org.bukkit.generator.ChunkGenerator;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+@SuppressWarnings({"unused"})
+public class VoidGenerator extends ChunkGenerator {
+
+ // 1.14 And On
+ public @NotNull List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean canSpawn(World world, int x, int z) {
+ return true;
+ }
+
+ @Override
+ public Location getFixedSpawnLocation(World world, Random random) {
+ return new Location(world, 0, 100, 0);
+ }
+
+ // 1.13 And Prev
+ public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biome) {
+ ChunkData chunkData = super.createChunkData(world);
+
+ for(int x = 0; x < 16; x++) {
+ for(int z = 0; z < 16; z++) {
+ biome.setBiome(x, z, Biome.PLAINS);
+ }
+ }
+
+ return chunkData;
+ }
+
+ // 1.8
+ public byte[] generate(World world, Random random, int x, int z) {
+ return new byte[world.getMaxHeight() / 16];
+ }
+
+ public byte[][] generateBlockSections(World world, Random random, int x, int z, ChunkGenerator.BiomeGrid biomes) {
+ return new byte[world.getMaxHeight() / 16][];
+ }
+
+
+}
diff --git a/src/main/java/cat/freya/khs/world/WorldLoader.java b/src/main/java/cat/freya/khs/world/WorldLoader.java
new file mode 100644
index 0000000..8460365
--- /dev/null
+++ b/src/main/java/cat/freya/khs/world/WorldLoader.java
@@ -0,0 +1,155 @@
+package cat.freya.khs.world;
+
+import cat.freya.khs.Main;
+import cat.freya.khs.configuration.Map;
+import org.bukkit.Bukkit;
+import org.bukkit.GameRule;
+import org.bukkit.World;
+import org.bukkit.WorldCreator;
+
+import java.io.*;
+import java.nio.file.Files;
+
+import static cat.freya.khs.configuration.Config.*;
+import static cat.freya.khs.configuration.Localization.message;
+
+public class WorldLoader {
+
+ private final Map map;
+
+ public WorldLoader(Map map) {
+ this.map = map;
+ }
+
+ public World getWorld() {
+ return Bukkit.getServer().getWorld(map.getGameSpawnName());
+ }
+
+ public void unloadMap() {
+ World world = Bukkit.getServer().getWorld(map.getGameSpawnName());
+ if (world == null) {
+ Main.getInstance().getLogger().warning(map.getGameSpawnName() + " already unloaded.");
+ return;
+ }
+ world.getPlayers().forEach(player -> exitPosition.teleport(player));
+ Main.getInstance().scheduleTask(() -> {
+ if (Bukkit.getServer().unloadWorld(world, false)) {
+ Main.getInstance().getLogger().info("Successfully unloaded " + map.getGameSpawnName());
+ } else {
+ Main.getInstance().getLogger().severe("COULD NOT UNLOAD " + map.getGameSpawnName());
+ }
+ });
+ }
+
+ public void loadMap() {
+ Main.getInstance().scheduleTask(() -> {
+ Bukkit.getServer().createWorld(new WorldCreator(map.getGameSpawnName()).generator(new VoidGenerator()));
+ World world = Bukkit.getServer().getWorld(map.getGameSpawnName());
+ if (world == null) {
+ Main.getInstance().getLogger().severe("COULD NOT LOAD " + map.getGameSpawnName());
+ return;
+ }
+ world.setAutoSave(false);
+ });
+ }
+
+ public void rollback() {
+ unloadMap();
+ loadMap();
+ }
+
+ public String save() {
+ World world = Bukkit.getServer().getWorld(map.getSpawnName());
+ if(world == null){
+ return errorPrefix + message("MAPSAVE_INVALID").addAmount(map.getSpawnName());
+ }
+ File current = new File(Main.getInstance().getWorldContainer()+File.separator+ map.getSpawnName());
+ if (current.exists()) {
+ try {
+ File destination = new File(Main.getInstance().getWorldContainer()+File.separator+ map.getGameSpawnName());
+ File temp_destination = new File(Main.getInstance().getWorldContainer()+File.separator+"temp_"+ map.getGameSpawnName());
+ copyFileFolder("region",true);
+ copyFileFolder("entities",true);
+ copyFileFolder("datapacks",false);
+ copyFileFolder("data",false);
+ File srcFile = new File(current, "level.dat");
+ File destFile = new File(temp_destination, "level.dat");
+ copyFile(srcFile,destFile);
+ if (destination.exists()) {
+ deleteDirectory(destination);
+ }
+
+ if (!temp_destination.renameTo(destination)) {
+ return errorPrefix + message("MAPSAVE_FAIL_DIR").addAmount(temp_destination.getPath());
+ }
+ } catch(IOException e) {
+ e.printStackTrace();
+ return errorPrefix + message("COMMAND_ERROR");
+ }
+ return messagePrefix + message("MAPSAVE_END");
+ } else {
+ return errorPrefix + message("MAPSAVE_ERROR");
+ }
+ }
+
+ private void copyFileFolder(String name, Boolean isMca) throws IOException {
+ File region = new File(Main.getInstance().getWorldContainer()+File.separator+ map.getSpawnName() +File.separator+name);
+ File temp = new File(Main.getInstance().getWorldContainer()+File.separator+"temp_"+ map.getGameSpawnName() +File.separator+name);
+ if (region.exists() && region.isDirectory()) {
+ if (!temp.exists())
+ if (!temp.mkdirs())
+ throw new IOException("Couldn't create region directory!");
+ String[] files = region.list();
+ if (files == null) {
+ Main.getInstance().getLogger().severe("Region directory is null or cannot be accessed");
+ return;
+ }
+ for (String file : files) {
+ if (isMca) {
+ int minX = (int)Math.floor(map.getBoundsMin().getX() / 512.0);
+ int minZ = (int)Math.floor(map.getBoundsMin().getZ() / 512.0);
+ int maxX = (int)Math.floor(map.getBoundsMax().getX() / 512.0);
+ int maxZ = (int)Math.floor(map.getBoundsMax().getZ() / 512.0);
+
+ String[] parts = file.split("\\.");
+ if (parts.length > 1) {
+ if ( Integer.parseInt(parts[1]) < minX || Integer.parseInt(parts[1]) > maxX || Integer.parseInt(parts[2]) < minZ || Integer.parseInt(parts[2]) > maxZ )
+ continue;
+ }
+ }
+
+ File srcFile = new File(region, file);
+ if (srcFile.isDirectory()) {
+ copyFileFolder(name+File.separator+file, false);
+ } else {
+ File destFile = new File(temp, file);
+ copyFile(srcFile, destFile);
+ }
+ }
+ }
+ }
+
+ private void copyFile(File source, File target) throws IOException {
+ InputStream in = Files.newInputStream(source.toPath());
+ OutputStream out = Files.newOutputStream(target.toPath());
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = in.read(buffer)) > 0)
+ out.write(buffer, 0, length);
+ in.close();
+ out.close();
+ }
+
+ public static void deleteDirectory(File directoryToBeDeleted) {
+ File[] allContents = directoryToBeDeleted.listFiles();
+ if (allContents != null) {
+ for (File file : allContents) {
+ deleteDirectory(file);
+ }
+ }
+ if (!directoryToBeDeleted.delete()) {
+ throw new RuntimeException("Failed to delete directory: "+directoryToBeDeleted.getPath());
+ }
+ }
+
+}