feat: implement backup system with compression and bundling

- Add zstd-jni dependency for compression support
- Define Backup record with name, key, incremental, and size fields
- Implement BackupManager with backup listing, deletion, and creation methods
- Create BackupWorker to handle backup operations with server state coordination
- Refactor WorldDir to simplify dimension handling and file listing
- Introduce bundling system with SerialBundlerReader^[[1;5P/Writer for efficient storage
- Add BackupStrategy interface with LocalBackupStrategy implementation
- Support both compressed and uncompressed backup formats
- Add config option for parallel backup operations
- Remove old backup implementation from JustBackupMod
- Update backup file format with metadata footer and magic number validation
This commit is contained in:
iceBear67 committed 2025-09-21 22:03:46 +08:00
1 parent bc9fab8d22
commit 6a2642ab93
14 files changed
+460 -72

No files matched your search

@@ -0,0 +1,45 @@
package io.ib67.sfcraft;
import io.ib67.sfcraft.mixin.LevelStorageAccessor;
import io.ib67.sfcraft.strategy.BackupStrategy;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import net.minecraft.server.MinecraftServer;
import java.nio.file.Path;
import static io.ib67.sfcraft.JustBackupMod.PERFORMING_BACKUP;
@Log4j2
public record BackupWorker(
MinecraftServer server,
BackupManager manager
) implements Runnable {
@Override
@SneakyThrows
public void run() {
if (server == null) {
log.warn("MinecraftServer is not initialized yet, not doing backup");
return;
}
int i = 0;
while (!PERFORMING_BACKUP.compareAndSet(false, true)) {
if (i++ % 10 == 0) log.info("Server is saving world while performing backup! waiting...");
Thread.sleep(2000);
}
// performing backup is now true
try {
if (i == 0) {
// not saved yet.
server.saveAll(true, true, false);
}
var session = ((LevelStorageAccessor) server).getSession();
var path = session.getDirectory().getRootPath();
manager.performBackup();
strategy.createBackup(new WorldDir(Path.of(path)));
} finally {
PERFORMING_BACKUP.set(false);
}
}
}