From 8859b639caa6019b2e8ec38d7e4489b6160752a3 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 27 Apr 2025 14:31:32 -0400 Subject: [PATCH] fix terrain+block storage/retrieval --- docs/src/progress/currenttarget.md | 1 - docs/src/progress/renderertodo.md | 1 + .../electrosphere/server/datacell/Realm.java | 1 + .../server/datacell/ServerWorldData.java | 2 ++ .../diskmap/ServerBlockChunkDiskMap.java | 18 +++++++++++++---- .../block/manager/ServerBlockManager.java | 20 +++++++++---------- .../physics/terrain/diskmap/ChunkDiskMap.java | 8 ++++---- .../java/electrosphere/util/FileUtils.java | 16 ++++++++------- 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index 1c2d6df6..4999b68d 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -16,7 +16,6 @@ - Spawn player in a town with a quest to complete a nearby dungeon + bug fixes - - Terrain edits do not save - Window does not play nice with its minWidth/minHeight being set differently - Interaction block cursor is overwriting fab cursor diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 8c712fd9..db411c79 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1568,6 +1568,7 @@ Fix block meshgen (04/27/2025) Fab cursor rotation + actually place rotated fab +Fix terrain and blocks not saving/loading to/from disk diff --git a/src/main/java/electrosphere/server/datacell/Realm.java b/src/main/java/electrosphere/server/datacell/Realm.java index 33bdb768..f48bd075 100644 --- a/src/main/java/electrosphere/server/datacell/Realm.java +++ b/src/main/java/electrosphere/server/datacell/Realm.java @@ -260,6 +260,7 @@ public class Realm { protected void save(String saveName){ dataCellManager.save(saveName); serverWorldData.getServerTerrainManager().save(saveName); + serverWorldData.getServerBlockManager().save(saveName); if(serverContentManager.getMacroData() != null){ serverContentManager.getMacroData().save(saveName); } diff --git a/src/main/java/electrosphere/server/datacell/ServerWorldData.java b/src/main/java/electrosphere/server/datacell/ServerWorldData.java index 54623bd0..61063e17 100644 --- a/src/main/java/electrosphere/server/datacell/ServerWorldData.java +++ b/src/main/java/electrosphere/server/datacell/ServerWorldData.java @@ -139,6 +139,7 @@ public class ServerWorldData { serverTerrainManager.load(sceneOrSaveName); serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); serverBlockManager = new ServerBlockManager(serverWorldData); + serverBlockManager.load(sceneOrSaveName); } else { //TODO: Allow loading procedurally generated terrain from disk (the chunk generator is always default currently) serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class); @@ -146,6 +147,7 @@ public class ServerWorldData { serverTerrainManager.load(sceneOrSaveName); serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); serverBlockManager = new ServerBlockManager(serverWorldData); + serverBlockManager.load(sceneOrSaveName); } serverWorldData.setManagers(serverTerrainManager, serverFluidManager, serverBlockManager); return serverWorldData; diff --git a/src/main/java/electrosphere/server/physics/block/diskmap/ServerBlockChunkDiskMap.java b/src/main/java/electrosphere/server/physics/block/diskmap/ServerBlockChunkDiskMap.java index 059c2a16..ddfd6e66 100644 --- a/src/main/java/electrosphere/server/physics/block/diskmap/ServerBlockChunkDiskMap.java +++ b/src/main/java/electrosphere/server/physics/block/diskmap/ServerBlockChunkDiskMap.java @@ -22,6 +22,16 @@ import electrosphere.util.math.HashUtils; */ public class ServerBlockChunkDiskMap { + /** + * Name of the map file + */ + static final String MAP_FILE_NAME = "blockchunk.json"; + + /** + * Directory that stores block data + */ + static final String BLOCK_DATA_DIR = "/block/"; + /** * The map of world position+chunk type to the file that actually houses that information */ @@ -58,8 +68,8 @@ public class ServerBlockChunkDiskMap { public static ServerBlockChunkDiskMap init(String saveName){ ServerBlockChunkDiskMap rVal = null; LoggerInterface.loggerEngine.DEBUG("INIT CHUNK MAP " + saveName); - if(FileUtils.getSaveFile(saveName, "chunk.map").exists()){ - rVal = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", ServerBlockChunkDiskMap.class); + if(FileUtils.getSaveFile(saveName, MAP_FILE_NAME).exists()){ + rVal = FileUtils.loadObjectFromSavePath(saveName, MAP_FILE_NAME, ServerBlockChunkDiskMap.class); LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + rVal.worldPosFileMap.keySet()); } else { rVal = new ServerBlockChunkDiskMap(); @@ -79,7 +89,7 @@ public class ServerBlockChunkDiskMap { * Saves the disk map to disk */ public void save(){ - FileUtils.serializeObjectToSavePath(Globals.currentSave.getName(), "blockchunk.map", worldPosFileMap); + FileUtils.serializeObjectToSavePath(Globals.currentSave.getName(), MAP_FILE_NAME, this); } /** @@ -171,7 +181,7 @@ public class ServerBlockChunkDiskMap { if(worldPosFileMap.containsKey(chunkKey)){ fileName = worldPosFileMap.get(chunkKey); } else { - fileName = chunkKey + "b.dat"; + fileName = BLOCK_DATA_DIR + chunkKey + "b.dat"; } //generate binary for the file short[] type = chunkData.getType(); diff --git a/src/main/java/electrosphere/server/physics/block/manager/ServerBlockManager.java b/src/main/java/electrosphere/server/physics/block/manager/ServerBlockManager.java index 3ad265de..25ff1b3a 100644 --- a/src/main/java/electrosphere/server/physics/block/manager/ServerBlockManager.java +++ b/src/main/java/electrosphere/server/physics/block/manager/ServerBlockManager.java @@ -34,7 +34,9 @@ public class ServerBlockManager { @Exclude BlockChunkCache chunkCache = new BlockChunkCache(); - //The map of chunk position <-> file on disk containing chunk data + /** + * The map of chunk position <-> file on disk containing chunk data + */ ServerBlockChunkDiskMap chunkDiskMap = null; /** @@ -52,10 +54,6 @@ public class ServerBlockManager { this.parent = parent; } - ServerBlockManager(){ - - } - /** * Inits the chunk disk map */ @@ -69,12 +67,14 @@ public class ServerBlockManager { */ public void save(String saveName){ //for each chunk, save via disk map - for(BlockChunkData chunk : this.chunkCache.getContents()){ - chunkDiskMap.saveToDisk(chunk); + if(this.chunkDiskMap != null){ + for(BlockChunkData chunk : this.chunkCache.getContents()){ + this.chunkDiskMap.saveToDisk(chunk); + } } //save disk map itself - if(chunkDiskMap != null){ - chunkDiskMap.save(); + if(this.chunkDiskMap != null){ + this.chunkDiskMap.save(); } } @@ -84,7 +84,7 @@ public class ServerBlockManager { */ public void load(String saveName){ //load chunk disk map - chunkDiskMap = ServerBlockChunkDiskMap.init(saveName); + this.chunkDiskMap = ServerBlockChunkDiskMap.init(saveName); } /** diff --git a/src/main/java/electrosphere/server/physics/terrain/diskmap/ChunkDiskMap.java b/src/main/java/electrosphere/server/physics/terrain/diskmap/ChunkDiskMap.java index e4dce53d..af3c9b97 100644 --- a/src/main/java/electrosphere/server/physics/terrain/diskmap/ChunkDiskMap.java +++ b/src/main/java/electrosphere/server/physics/terrain/diskmap/ChunkDiskMap.java @@ -104,7 +104,7 @@ public class ChunkDiskMap { * Saves the disk map to disk */ public void save(){ - FileUtils.serializeObjectToSavePath(Globals.currentSave.getName(), "chunk.map", worldPosFileMap); + FileUtils.serializeObjectToSavePath(Globals.currentSave.getName(), "chunk.map", this); } /** @@ -149,7 +149,7 @@ public class ChunkDiskMap { if(this.containsTerrainAtPosition(worldX, worldY, worldZ)){ //read file String fileName = worldPosFileMap.get(ChunkDiskMap.getTerrainChunkKey(worldX, worldY, worldZ)); - byte[] rawDataCompressed = FileUtils.loadBinaryFromSavePath(Globals.currentSave.getName(), "/terrain/" + fileName); + byte[] rawDataCompressed = FileUtils.loadBinaryFromSavePath(Globals.currentSave.getName(), fileName); //decompress byte[] rawData = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -213,7 +213,7 @@ public class ChunkDiskMap { if(worldPosFileMap.containsKey(chunkKey)){ fileName = worldPosFileMap.get(chunkKey); } else { - fileName = chunkKey + ".dat"; + fileName = "/terrain/" + chunkKey + ".dat"; } //generate binary for the file float[][][] weights = terrainChunk.getWeights(); @@ -245,7 +245,7 @@ public class ChunkDiskMap { deflaterInputStream.flush(); deflaterInputStream.close(); //write to disk - FileUtils.saveBinaryToSavePath(Globals.currentSave.getName(), "/terrain/" + fileName, out.toByteArray()); + FileUtils.saveBinaryToSavePath(Globals.currentSave.getName(), fileName, out.toByteArray()); //save to the map of filenames worldPosFileMap.put(chunkKey,fileName); } catch (IOException e) { diff --git a/src/main/java/electrosphere/util/FileUtils.java b/src/main/java/electrosphere/util/FileUtils.java index 95a45fe5..3ba203f2 100644 --- a/src/main/java/electrosphere/util/FileUtils.java +++ b/src/main/java/electrosphere/util/FileUtils.java @@ -365,9 +365,9 @@ public class FileUtils { */ public static byte[] loadBinaryFromSavePath(String saveName, String pathName){ byte[] rVal = null; - String sanitizedFilePath = sanitizeFilePath(pathName); + String sanitizedFilePath = FileUtils.sanitizeFilePath(pathName); try { - rVal = Files.readAllBytes(getSaveFile(saveName,sanitizedFilePath).toPath()); + rVal = Files.readAllBytes(FileUtils.getSaveFile(saveName,sanitizedFilePath).toPath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -382,9 +382,11 @@ public class FileUtils { * @param data The data to write */ public static void saveBinaryToSavePath(String saveName, String pathName, byte[] data){ - String sanitizedFilePath = sanitizeFilePath(pathName); + String sanitizedFilePath = FileUtils.sanitizeFilePath(pathName); try { - Files.write(getSaveFile(saveName,sanitizedFilePath).toPath(), data); + File file = FileUtils.getSaveFile(saveName,sanitizedFilePath); + Files.createDirectories(file.getParentFile().toPath()); + Files.write(file.toPath(), data); } catch (IOException ex) { ex.printStackTrace(); } @@ -397,8 +399,8 @@ public class FileUtils { * @return true if it exists, false otherwise */ public static boolean checkSavePathExists(String saveName, String filePath){ - String sanitizedFilePath = sanitizeFilePath(filePath); - return getSaveFile(saveName,sanitizedFilePath).exists(); + String sanitizedFilePath = FileUtils.sanitizeFilePath(filePath); + return FileUtils.getSaveFile(saveName,sanitizedFilePath).exists(); } /** @@ -407,7 +409,7 @@ public class FileUtils { * @return true if directory exists, false otherwise */ public static boolean checkFileExists(String fileName){ - File targetDir = new File(sanitizeFilePath(fileName)); + File targetDir = new File(FileUtils.sanitizeFilePath(fileName)); if(targetDir.exists()){ return true; } else {