fix terrain+block storage/retrieval
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-04-27 14:31:32 -04:00
parent 85c4cd2b6d
commit 8859b639ca
8 changed files with 41 additions and 26 deletions

View File

@ -16,7 +16,6 @@
- Spawn player in a town with a quest to complete a nearby dungeon - Spawn player in a town with a quest to complete a nearby dungeon
+ bug fixes + bug fixes
- Terrain edits do not save
- Window does not play nice with its minWidth/minHeight being set differently - Window does not play nice with its minWidth/minHeight being set differently
- Interaction block cursor is overwriting fab cursor - Interaction block cursor is overwriting fab cursor

View File

@ -1568,6 +1568,7 @@ Fix block meshgen
(04/27/2025) (04/27/2025)
Fab cursor rotation + actually place rotated fab Fab cursor rotation + actually place rotated fab
Fix terrain and blocks not saving/loading to/from disk

View File

@ -260,6 +260,7 @@ public class Realm {
protected void save(String saveName){ protected void save(String saveName){
dataCellManager.save(saveName); dataCellManager.save(saveName);
serverWorldData.getServerTerrainManager().save(saveName); serverWorldData.getServerTerrainManager().save(saveName);
serverWorldData.getServerBlockManager().save(saveName);
if(serverContentManager.getMacroData() != null){ if(serverContentManager.getMacroData() != null){
serverContentManager.getMacroData().save(saveName); serverContentManager.getMacroData().save(saveName);
} }

View File

@ -139,6 +139,7 @@ public class ServerWorldData {
serverTerrainManager.load(sceneOrSaveName); serverTerrainManager.load(sceneOrSaveName);
serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
serverBlockManager = new ServerBlockManager(serverWorldData); serverBlockManager = new ServerBlockManager(serverWorldData);
serverBlockManager.load(sceneOrSaveName);
} else { } else {
//TODO: Allow loading procedurally generated terrain from disk (the chunk generator is always default currently) //TODO: Allow loading procedurally generated terrain from disk (the chunk generator is always default currently)
serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class); serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class);
@ -146,6 +147,7 @@ public class ServerWorldData {
serverTerrainManager.load(sceneOrSaveName); serverTerrainManager.load(sceneOrSaveName);
serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
serverBlockManager = new ServerBlockManager(serverWorldData); serverBlockManager = new ServerBlockManager(serverWorldData);
serverBlockManager.load(sceneOrSaveName);
} }
serverWorldData.setManagers(serverTerrainManager, serverFluidManager, serverBlockManager); serverWorldData.setManagers(serverTerrainManager, serverFluidManager, serverBlockManager);
return serverWorldData; return serverWorldData;

View File

@ -22,6 +22,16 @@ import electrosphere.util.math.HashUtils;
*/ */
public class ServerBlockChunkDiskMap { 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 * 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){ public static ServerBlockChunkDiskMap init(String saveName){
ServerBlockChunkDiskMap rVal = null; ServerBlockChunkDiskMap rVal = null;
LoggerInterface.loggerEngine.DEBUG("INIT CHUNK MAP " + saveName); LoggerInterface.loggerEngine.DEBUG("INIT CHUNK MAP " + saveName);
if(FileUtils.getSaveFile(saveName, "chunk.map").exists()){ if(FileUtils.getSaveFile(saveName, MAP_FILE_NAME).exists()){
rVal = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", ServerBlockChunkDiskMap.class); rVal = FileUtils.loadObjectFromSavePath(saveName, MAP_FILE_NAME, ServerBlockChunkDiskMap.class);
LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + rVal.worldPosFileMap.keySet()); LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + rVal.worldPosFileMap.keySet());
} else { } else {
rVal = new ServerBlockChunkDiskMap(); rVal = new ServerBlockChunkDiskMap();
@ -79,7 +89,7 @@ public class ServerBlockChunkDiskMap {
* Saves the disk map to disk * Saves the disk map to disk
*/ */
public void save(){ 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)){ if(worldPosFileMap.containsKey(chunkKey)){
fileName = worldPosFileMap.get(chunkKey); fileName = worldPosFileMap.get(chunkKey);
} else { } else {
fileName = chunkKey + "b.dat"; fileName = BLOCK_DATA_DIR + chunkKey + "b.dat";
} }
//generate binary for the file //generate binary for the file
short[] type = chunkData.getType(); short[] type = chunkData.getType();

View File

@ -34,7 +34,9 @@ public class ServerBlockManager {
@Exclude @Exclude
BlockChunkCache chunkCache = new BlockChunkCache(); 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; ServerBlockChunkDiskMap chunkDiskMap = null;
/** /**
@ -52,10 +54,6 @@ public class ServerBlockManager {
this.parent = parent; this.parent = parent;
} }
ServerBlockManager(){
}
/** /**
* Inits the chunk disk map * Inits the chunk disk map
*/ */
@ -69,12 +67,14 @@ public class ServerBlockManager {
*/ */
public void save(String saveName){ public void save(String saveName){
//for each chunk, save via disk map //for each chunk, save via disk map
if(this.chunkDiskMap != null){
for(BlockChunkData chunk : this.chunkCache.getContents()){ for(BlockChunkData chunk : this.chunkCache.getContents()){
chunkDiskMap.saveToDisk(chunk); this.chunkDiskMap.saveToDisk(chunk);
}
} }
//save disk map itself //save disk map itself
if(chunkDiskMap != null){ if(this.chunkDiskMap != null){
chunkDiskMap.save(); this.chunkDiskMap.save();
} }
} }
@ -84,7 +84,7 @@ public class ServerBlockManager {
*/ */
public void load(String saveName){ public void load(String saveName){
//load chunk disk map //load chunk disk map
chunkDiskMap = ServerBlockChunkDiskMap.init(saveName); this.chunkDiskMap = ServerBlockChunkDiskMap.init(saveName);
} }
/** /**

View File

@ -104,7 +104,7 @@ public class ChunkDiskMap {
* Saves the disk map to disk * Saves the disk map to disk
*/ */
public void save(){ 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)){ if(this.containsTerrainAtPosition(worldX, worldY, worldZ)){
//read file //read file
String fileName = worldPosFileMap.get(ChunkDiskMap.getTerrainChunkKey(worldX, worldY, worldZ)); 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 //decompress
byte[] rawData = null; byte[] rawData = null;
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -213,7 +213,7 @@ public class ChunkDiskMap {
if(worldPosFileMap.containsKey(chunkKey)){ if(worldPosFileMap.containsKey(chunkKey)){
fileName = worldPosFileMap.get(chunkKey); fileName = worldPosFileMap.get(chunkKey);
} else { } else {
fileName = chunkKey + ".dat"; fileName = "/terrain/" + chunkKey + ".dat";
} }
//generate binary for the file //generate binary for the file
float[][][] weights = terrainChunk.getWeights(); float[][][] weights = terrainChunk.getWeights();
@ -245,7 +245,7 @@ public class ChunkDiskMap {
deflaterInputStream.flush(); deflaterInputStream.flush();
deflaterInputStream.close(); deflaterInputStream.close();
//write to disk //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 //save to the map of filenames
worldPosFileMap.put(chunkKey,fileName); worldPosFileMap.put(chunkKey,fileName);
} catch (IOException e) { } catch (IOException e) {

View File

@ -365,9 +365,9 @@ public class FileUtils {
*/ */
public static byte[] loadBinaryFromSavePath(String saveName, String pathName){ public static byte[] loadBinaryFromSavePath(String saveName, String pathName){
byte[] rVal = null; byte[] rVal = null;
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = FileUtils.sanitizeFilePath(pathName);
try { try {
rVal = Files.readAllBytes(getSaveFile(saveName,sanitizedFilePath).toPath()); rVal = Files.readAllBytes(FileUtils.getSaveFile(saveName,sanitizedFilePath).toPath());
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@ -382,9 +382,11 @@ public class FileUtils {
* @param data The data to write * @param data The data to write
*/ */
public static void saveBinaryToSavePath(String saveName, String pathName, byte[] data){ public static void saveBinaryToSavePath(String saveName, String pathName, byte[] data){
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = FileUtils.sanitizeFilePath(pathName);
try { 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) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -397,8 +399,8 @@ public class FileUtils {
* @return true if it exists, false otherwise * @return true if it exists, false otherwise
*/ */
public static boolean checkSavePathExists(String saveName, String filePath){ public static boolean checkSavePathExists(String saveName, String filePath){
String sanitizedFilePath = sanitizeFilePath(filePath); String sanitizedFilePath = FileUtils.sanitizeFilePath(filePath);
return getSaveFile(saveName,sanitizedFilePath).exists(); return FileUtils.getSaveFile(saveName,sanitizedFilePath).exists();
} }
/** /**
@ -407,7 +409,7 @@ public class FileUtils {
* @return true if directory exists, false otherwise * @return true if directory exists, false otherwise
*/ */
public static boolean checkFileExists(String fileName){ public static boolean checkFileExists(String fileName){
File targetDir = new File(sanitizeFilePath(fileName)); File targetDir = new File(FileUtils.sanitizeFilePath(fileName));
if(targetDir.exists()){ if(targetDir.exists()){
return true; return true;
} else { } else {