From 2947e9acff9495b8f54c125cf946a6a0d63761d1 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 30 Dec 2020 14:47:43 +0300 Subject: [PATCH] Add world persistence because I can This is terribly inefficient both storage- and TPS-wise. Enable/disable with ru.windcorp.progressia.test.TestWorldDiskIO.ENABLE --- .../progressia/server/ChunkManager.java | 12 ++- .../progressia/test/TestWorldDiskIO.java | 96 +++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java diff --git a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java index 4810e3a..2705c8e 100644 --- a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java @@ -12,6 +12,7 @@ import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.generic.ChunkSet; import ru.windcorp.progressia.common.world.generic.ChunkSets; import ru.windcorp.progressia.test.TestContent; +import ru.windcorp.progressia.test.TestWorldDiskIO; public class ChunkManager { @@ -120,8 +121,12 @@ public class ChunkManager { WorldData world = getServer().getWorld().getData(); - ChunkData chunk = new ChunkData(chunkPos, world); - TestContent.generateChunk(chunk); + ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world); + if (chunk == null) { + chunk = new ChunkData(chunkPos, world); + TestContent.generateChunk(chunk); + } + world.addChunk(chunk); } @@ -137,8 +142,11 @@ public class ChunkManager { chunkPos.x, chunkPos.y, chunkPos.z )); } + world.removeChunk(chunk); + TestWorldDiskIO.saveChunk(chunk); + } public void sendChunk(Player player, Vec3i chunkPos) { diff --git a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java new file mode 100644 index 0000000..7971260 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java @@ -0,0 +1,96 @@ +package ru.windcorp.progressia.test; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.io.ChunkIO; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.WorldData; + +public class TestWorldDiskIO { + + private static final Path SAVE_DIR = Paths.get("tmp_world"); + private static final Logger LOG = LogManager.getLogger("TestWorldDiskIO"); + + private static final boolean ENABLE = true; + + public static void saveChunk(ChunkData chunk) { + if (!ENABLE) return; + + try { + LOG.debug( + "Saving {} {} {}", + chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z + ); + + Files.createDirectories(SAVE_DIR); + + Path path = SAVE_DIR.resolve(String.format( + "chunk_%+d_%+d_%+d.progressia_chunk", + chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z + )); + + try (OutputStream output = new DeflaterOutputStream(new BufferedOutputStream(Files.newOutputStream(path)))) { + ChunkIO.save(chunk, output); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static ChunkData tryToLoad(Vec3i chunkPos, WorldData world) { + if (!ENABLE) return null; + + Path path = SAVE_DIR.resolve(String.format( + "chunk_%+d_%+d_%+d.progressia_chunk", + chunkPos.x, chunkPos.y, chunkPos.z + )); + + if (!Files.exists(path)) { + LOG.debug( + "Not found {} {} {}", + chunkPos.x, chunkPos.y, chunkPos.z + ); + + return null; + } + + try { + ChunkData result = load(path, chunkPos, world); + + LOG.debug( + "Loaded {} {} {}", + chunkPos.x, chunkPos.y, chunkPos.z + ); + + return result; + } catch (Exception e) { + e.printStackTrace(); + LOG.debug( + "Could not load {} {} {}", + chunkPos.x, chunkPos.y, chunkPos.z + ); + return null; + } + } + + private static ChunkData load(Path path, Vec3i chunkPos, WorldData world) throws IOException, DecodingException { + try (InputStream input = new InflaterInputStream(new BufferedInputStream(Files.newInputStream(path)))) { + return ChunkIO.load(world, chunkPos, input); + } + } + +}