9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 20:39:10 +00:00

添加定时保存

This commit is contained in:
XiaoMoMi
2025-04-24 23:04:31 +08:00
parent 8a912a6a33
commit e2cbf00c98
7 changed files with 30 additions and 9 deletions

View File

@@ -45,7 +45,7 @@ public class SlimeWorldDataStorage implements WorldDataStorage {
@SuppressWarnings("unchecked")
@Override
public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) {
public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) {
SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z);
if (slimeChunk == null) return;
CompoundTag nbt = DefaultChunkSerializer.serialize(chunk);

View File

@@ -344,7 +344,7 @@ light-system:
chunk-system:
# Unloaded chunks may be loaded soon. Delaying serialization can improve performance, especially for those double-dimension mob farms.
delay-serialization: 20 # seconds -1 = disable
delay-serialization: 20 # seconds -1 = disable
# 1 = NONE | Compression Speed | Decompress Speed | Compression Ratio | Memory Usage |
# 2 = DEFLATE | Medium-Slow Medium Moderate Low |
# 3 = GZIP | Medium-Slow Medium Moderate Low |

View File

@@ -200,7 +200,9 @@ public class BukkitWorldManager implements WorldManager, Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onWorldSave(WorldSaveEvent event) {
// TODO Timely saving?
for (CEWorld world : this.worldArray) {
world.save();
}
}
@Override
@@ -275,7 +277,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
CEChunk ceChunk = world.getChunkAtIfLoaded(chunk.getX(), chunk.getZ());
if (ceChunk != null) {
try {
world.worldDataStorage().writeChunkAt(pos, ceChunk);
world.worldDataStorage().writeChunkAt(pos, ceChunk, false);
} catch (IOException e) {
this.plugin.logger().warn("Failed to write chunk tag at " + chunk.getX() + " " + chunk.getZ(), e);
} finally {

View File

@@ -2,11 +2,13 @@ package net.momirealms.craftengine.core.world;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.world.chunk.CEChunk;
import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor;
import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
@@ -41,6 +43,19 @@ public abstract class CEWorld {
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
}
public void save() {
this.loadedChunkMapLock.readLock().lock();
try {
for (Map.Entry<Long, CEChunk> entry : this.loadedChunkMap.entrySet()) {
worldDataStorage.writeChunkAt(new ChunkPos(entry.getKey()), entry.getValue(), true);
}
} catch (IOException e) {
CraftEngine.instance().logger().warn("Failed to save world chunks", e);
} finally {
this.loadedChunkMapLock.readLock().unlock();
}
}
public World world() {
return world;
}

View File

@@ -147,7 +147,7 @@ public class DefaultRegionFileStorage implements WorldDataStorage {
}
@Override
public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException {
public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException {
CompoundTag nbt = DefaultChunkSerializer.serialize(chunk);
writeChunkTagAt(pos, nbt);
}

View File

@@ -26,7 +26,7 @@ public class DelayedDefaultRegionFileStorage extends DefaultRegionFileStorage {
}
if (cause == RemovalCause.EXPIRED || cause == RemovalCause.SIZE) {
try {
super.writeChunkAt(key, value);
super.writeChunkAt(key, value, true);
} catch (IOException e) {
CraftEngine.instance().logger().warn("Failed to write chunk at " + key, e);
}
@@ -45,7 +45,11 @@ public class DelayedDefaultRegionFileStorage extends DefaultRegionFileStorage {
}
@Override
public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException {
public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException {
if (immediately) {
super.writeChunkAt(pos, chunk, true);
return;
}
if (chunk.isEmpty()) {
super.writeChunkTagAt(pos, null);
return;
@@ -62,7 +66,7 @@ public class DelayedDefaultRegionFileStorage extends DefaultRegionFileStorage {
private void saveCache() {
try {
for (var chunk : this.chunkCache.asMap().entrySet()) {
super.writeChunkAt(chunk.getKey(), chunk.getValue());
super.writeChunkAt(chunk.getKey(), chunk.getValue(), true);
}
} catch (IOException e) {
CraftEngine.instance().logger().warn("Failed to save chunks", e);

View File

@@ -12,7 +12,7 @@ public interface WorldDataStorage {
@NotNull
CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException;
void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException;
void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException;
void flush() throws IOException;