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
+ 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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {

View File

@ -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 {