Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ _✨ MC备份 / 回档模组 ✨_
`/qb` 或 `/quickbackupmulti`均可触发mod

## 特性
- [ ] 定时备份
- [x] 定时备份
- [x] 无限槽位
- [x] Hash对比并仅备份差异文件
- [ ] 个性化设置
Expand Down
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@ subprojects {
minecraft "net.minecraft:minecraft:$rootProject.minecraft_version"
mappings loom.officialMojangMappings()

// incremental storage
implementation("io.github.skydynamic:incremental-storage-lib:$rootProject.incremental_storage_lib_version")
implementation("org.jetbrains.exposed:exposed-core:0.57.0")
implementation("org.jetbrains.exposed:exposed-jdbc:0.57.0")
implementation("com.h2database:h2:2.2.224")

// https://mvnrepository.com/artifact/org.quartz-scheduler/quartz
implementation("org.quartz-scheduler:quartz:2.5.0")

// lombok
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.30")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package io.github.skydynamic.quickbakcupmulti;

import com.mojang.brigadier.CommandDispatcher;
import io.github.skydynamic.quickbakcupmulti.schedule.IModSchedule;
import io.github.skydynamic.quickbakcupmulti.utils.permission.PermissionManager;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.commands.CommandSourceStack;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Setter
@Getter
Expand All @@ -19,11 +23,17 @@ public class ModContainer {
private boolean isRestoringBackup;
private String currentSelectionBackup;

private List<IModSchedule> schedules = new ArrayList<>();

public ModContainer(
CommandDispatcher<CommandSourceStack> dispatcher
) {
this.dispatcher = dispatcher;
}

public ModContainer() {}

public Optional<IModSchedule> getSchedule(String name) {
return schedules.stream().filter(it -> it.getName().equals(name)).findFirst();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.github.skydynamic.increment.storage.lib.utils.StorageManager;
import io.github.skydynamic.quickbakcupmulti.command.ModCommand;
import io.github.skydynamic.quickbakcupmulti.config.ModConfig;
import io.github.skydynamic.quickbakcupmulti.schedule.quartz.DisableQuartzInfoLogger;
import io.github.skydynamic.quickbakcupmulti.translate.Translate;
import io.github.skydynamic.quickbakcupmulti.utils.permission.PermissionManager;
import lombok.Getter;
Expand All @@ -12,6 +13,7 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.text.SimpleDateFormat;

public final class QuickbakcupmultiReforged {
public static final String MOD_ID = "quickbakcupmulti_reforged";
Expand Down Expand Up @@ -45,10 +47,18 @@ public static void init(ModContainer container) {
if (!storagePath.exists()) {
storagePath.mkdirs();
}

// Disable Quartz Info Logger
DisableQuartzInfoLogger.disable();
}

public static void registerCommand() {
if (modContainer.getDispatcher() == null) return;
ModCommand.register(modContainer.getDispatcher());
}

public static String formatTimestamp(long timestamp) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(timestamp);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package io.github.skydynamic.quickbakcupmulti;

import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;

import java.util.List;

public class ServerManager {
private final MinecraftServer server;
Expand All @@ -18,4 +22,12 @@ public void startServer() {
public void stopServer() {
this.server.halt(false);
}

public List<ServerPlayer> getPlayers() {
return this.server.getPlayerList().getPlayers();
}

public CommandSourceStack getCommandSource() {
return this.server.createCommandSourceStack();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import io.github.skydynamic.quickbakcupmulti.DatabaseCache;
import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged;
import io.github.skydynamic.quickbakcupmulti.schedule.ScheduleManager;
import io.github.skydynamic.quickbakcupmulti.utils.BackupManager;
import io.github.skydynamic.quickbakcupmulti.utils.permission.PermissionManager;
import io.github.skydynamic.quickbakcupmulti.utils.permission.PermissionType;
Expand Down Expand Up @@ -32,6 +33,10 @@ public void run() {
if (QuickbakcupmultiReforged.getModConfig().isCacheDatabase()) {
DatabaseCache.updateStorageInfoCaches();
}

if (QuickbakcupmultiReforged.getModConfig().getScheduleBackupConfig().isResetTimerOnBackup() && ScheduleManager.resetTimer("scheduleBackup")) {
QuickbakcupmultiReforged.logger.info("Reset timer for scheduleBackup");
}
QuickbakcupmultiReforged.logger.info("Make Backup thread close => {}ms", System.currentTimeMillis() - l);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.github.skydynamic.quickbakcupmulti.config;

import lombok.Getter;

@SuppressWarnings("FieldMayBeFinal")
@Getter
public class DatabaseConfig {
private ScheduleConfig backup = new ScheduleConfig();

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.skydynamic.increment.storage.lib.manager.IConfig;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -18,7 +19,11 @@

public class ModConfig implements IConfig {
private static final Logger logger = LoggerFactory.getLogger("Qbm-Config");
private static final Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
private static final Gson gson = new GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.serializeNulls()
.create();

@Setter @Getter
private ConfigStorage config = new ConfigStorage();
Expand Down Expand Up @@ -101,8 +106,20 @@ public boolean isCacheDatabase() {
return config.cacheDatabase;
}

public ScheduleBackupConfig getScheduleBackupConfig() {
return config.scheduleBackup;
}

public PruneScheduleConfig getPruneScheduleConfig() {
return config.prune;
}

public DatabaseConfig getDatabaseConfig() {
return config.database;
}

@Override
public String getStoragePath() {
public @NotNull String getStoragePath() {
return config.storagePath;
}

Expand All @@ -127,12 +144,27 @@ public static class ConfigStorage {
private String storagePath = "./QuickBackupMulti";
private boolean cacheDatabase = false;

private ScheduleBackupConfig scheduleBackup = new ScheduleBackupConfig();

private PruneScheduleConfig prune = new PruneScheduleConfig();

private DatabaseConfig database = new DatabaseConfig();

@Override
public String toString() {
return "ConfigStorage [checkUpdate=" + checkUpdate + ", ignoredFiles=" + ignoredFiles
+ ", ignoredFolders=" + ignoredFolders + ", lang=" + lang
+ ", autoRestartMode=" + autoRestartMode + ", storagePath=" + storagePath
+ ", cacheDatabase=" + cacheDatabase + "]";
return "ConfigStorage{" +
"checkUpdate=" + checkUpdate +
", ignoredFiles=" + ignoredFiles +
", ignoredFolders=" + ignoredFolders +
", lang='" + lang + '\'' +
", maxScheduleBackup=" + maxScheduleBackup +
", autoRestartMode=" + autoRestartMode +
", storagePath='" + storagePath + '\'' +
", cacheDatabase=" + cacheDatabase +
", scheduleBackup=" + scheduleBackup +
", prune=" + prune +
", database=" + database +
'}';
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.skydynamic.quickbakcupmulti.config;

import lombok.Getter;

@SuppressWarnings("FieldMayBeFinal")
@Getter
public class PbsConfig {
private boolean enabled = false;
private Integer maxAmount = 10;
private String maxLifeTime = "0s";
private int last = -1;
private int hour = 0;
private int day = 0;
private int week = 0;
private int month = 1;
private int year = 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.github.skydynamic.quickbakcupmulti.config;

import lombok.Getter;

@SuppressWarnings("FieldMayBeFinal")
@Getter
public class PruneScheduleConfig extends ScheduleConfig {
private String timezoneOverride = null;
private PbsConfig regularBackup = new PbsConfig();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.github.skydynamic.quickbakcupmulti.config;

import lombok.Getter;

import java.util.List;

@SuppressWarnings("FieldMayBeFinal")
@Getter
public class ScheduleBackupConfig extends ScheduleConfig {
private boolean resetTimerOnBackup = true;
private boolean requireOnlinePlayers = false;
private boolean requireOnlinePlayersIgnoreCarpetFakePlayer = true;
private List<String> requireOnlinePlayersBlacklist = List.of();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.skydynamic.quickbakcupmulti.config;

public class ScheduleConfig {
public boolean enabled;
public Integer interval = 7200;
public String crontab = null;
public String jitter = "1m";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.github.skydynamic.quickbakcupmulti.event;

import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged;
import io.github.skydynamic.quickbakcupmulti.config.PruneScheduleConfig;
import io.github.skydynamic.quickbakcupmulti.config.ScheduleBackupConfig;
import io.github.skydynamic.quickbakcupmulti.config.ScheduleConfig;
import io.github.skydynamic.quickbakcupmulti.schedule.ScheduleManager;
import io.github.skydynamic.quickbakcupmulti.schedule.runnables.DefaultDatabaseBackupRunnable;
import io.github.skydynamic.quickbakcupmulti.schedule.runnables.DefaultPruneRunnable;
import io.github.skydynamic.quickbakcupmulti.schedule.runnables.DefaultScheduleBackupRunnable;

public class OnLoadedWorldHandler {
public static void handler() {
// Database Schedule backup
ScheduleConfig databaseBackupConfig = QuickbakcupmultiReforged.getModConfig().getDatabaseConfig().getBackup();
if (databaseBackupConfig.enabled) {
Runnable databaseBackupRunnable = new DefaultDatabaseBackupRunnable();
if (databaseBackupConfig.interval != null) {
ScheduleManager.registerSchedule("databaseSchedule", databaseBackupConfig.interval, databaseBackupConfig.jitter, databaseBackupRunnable);
} else if (databaseBackupConfig.crontab != null) {
ScheduleManager.registerSchedule("databaseSchedule", databaseBackupConfig.crontab, databaseBackupConfig.jitter, databaseBackupRunnable);
}
}

// Schedule backup
ScheduleBackupConfig scheduleBackupConfig = QuickbakcupmultiReforged.getModConfig().getScheduleBackupConfig();
if (scheduleBackupConfig.enabled) {
Runnable scheduleBackupRunnable = new DefaultScheduleBackupRunnable();
if (scheduleBackupConfig.interval != null) {
ScheduleManager.registerSchedule("scheduleBackup", scheduleBackupConfig.interval, scheduleBackupConfig.jitter, scheduleBackupRunnable);
} else if (scheduleBackupConfig.crontab != null) {
ScheduleManager.registerSchedule("scheduleBackup", scheduleBackupConfig.crontab, scheduleBackupConfig.jitter, scheduleBackupRunnable);
}
}

// Prune schedule
PruneScheduleConfig pruneScheduleConfig = QuickbakcupmultiReforged.getModConfig().getPruneScheduleConfig();
if (pruneScheduleConfig.enabled) {
Runnable pruneRunnable = new DefaultPruneRunnable();
if (pruneScheduleConfig.interval != null) {
ScheduleManager.registerSchedule("pruneSchedule", pruneScheduleConfig.interval, pruneScheduleConfig.jitter, pruneRunnable);
} else if (pruneScheduleConfig.crontab != null) {
ScheduleManager.registerSchedule("pruneSchedule", pruneScheduleConfig.crontab, pruneScheduleConfig.jitter, pruneRunnable);
}
}

ScheduleManager.startAllSchedule();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.skydynamic.quickbakcupmulti.event;

import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged;
import io.github.skydynamic.quickbakcupmulti.schedule.ScheduleManager;
import io.github.skydynamic.quickbakcupmulti.utils.BackupManager;

public class OnServerStoppedHandler {
Expand All @@ -16,6 +17,7 @@ public static void handle() {
}
} else {
QuickbakcupmultiReforged.getDatabase().closeDatabase();
ScheduleManager.clearAllSchedule();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.github.skydynamic.quickbakcupmulti.DatabaseCache;
import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged;
import io.github.skydynamic.quickbakcupmulti.database.DatabaseManager;
import io.github.skydynamic.quickbakcupmulti.event.OnLoadedWorldHandler;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.Services;
import net.minecraft.server.WorldStem;
Expand Down Expand Up @@ -53,5 +54,7 @@ private void onLoadLevel(CallbackInfoReturnable<Boolean> cir) {
if (QuickbakcupmultiReforged.getModConfig().isCacheDatabase()) {
DatabaseCache.updateStorageInfoCaches();
}

OnLoadedWorldHandler.handler();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public class MixinClientPacketListener {
private void showWarning(ClientboundLoginPacket packet, CallbackInfo ci) {
LocalPlayer player = Minecraft.getInstance().player;
if (player != null) {
player.sendSystemMessage(
player.displayClientMessage(
Component.literal("QuickbackupmultiReforged mod is not supporting clients now!")
.withStyle(ChatFormatting.RED)
.withStyle(ChatFormatting.RED), false
);
}
}
Expand Down
Loading