summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeuin <[email protected]>2020-04-24 17:48:26 +0800
committerkeuin <[email protected]>2020-04-24 17:48:26 +0800
commit474609422202ae33e1c941f67f000f9d88aa297c (patch)
tree02f303e2c94ec4d2ce6c887bd268406482ae09dd
parentea01faf3947814fe7ecaa3705e5fbf0f171f7e48 (diff)
Version 1.3.1-dev (BugFix)1.3.1-dev
Improve some info output. BugFix: Deleted backup won't immediately disappear in the suggestion list.
-rw-r--r--README.md7
-rw-r--r--gradle.properties2
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBCommands.java10
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBPluginEvents.java3
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java4
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/BackupNameSuggestionProvider.java25
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java20
-rw-r--r--src/main/java/com/keuin/kbackupfabric/worker/BackupWorker.java15
8 files changed, 61 insertions, 25 deletions
diff --git a/README.md b/README.md
index 5441653..fb79f72 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,13 @@ commands:
To-Do List:
+- Refactor code.
- More thorough test.
-- Enhance ZipUtil for hashing sub-files and generating incremental diff-table. (A:Add, M:Modification, D:Deletion)
+- Implement incremental backup.
+ + Restore: trace-back (recursively, then generate file dependence tree)
+ - Implement unZipRecursively (unzip a .zip.inc file recursively until reaches the root (i.e. the last full backup).)
+ + Backup: base-diff (select most recently backup as the base, then diff)
+ - Implement zipDiff (make a new zip with the latest backup as the base, store diff-table in zip comment (A:Add, M:Modification, D:Deletion))
- Optimize help menu. (colored command help menu)
- Add op login hint in the next start after restoring.
- Implement incremental backup.
diff --git a/gradle.properties b/gradle.properties
index aba6679..77a15c7 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@ minecraft_version=1.14.4
yarn_mappings=1.14.4+build.16
loader_version=0.8.2+build.194
# Mod Properties
-mod_version=1.3.0-dev
+mod_version=1.3.1-dev
maven_group=com.keuin.kbackupfabric
archives_base_name=kbackup-fabric
# Dependencies
diff --git a/src/main/java/com/keuin/kbackupfabric/KBCommands.java b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
index f2671ad..8a1a7cc 100644
--- a/src/main/java/com/keuin/kbackupfabric/KBCommands.java
+++ b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
@@ -4,6 +4,7 @@ import com.keuin.kbackupfabric.metadata.BackupMetadata;
import com.keuin.kbackupfabric.metadata.MetadataHolder;
import com.keuin.kbackupfabric.operation.AbstractConfirmableOperation;
import com.keuin.kbackupfabric.util.BackupFilesystemUtil;
+import com.keuin.kbackupfabric.util.BackupNameSuggestionProvider;
import com.keuin.kbackupfabric.util.BackupNameTimeFormatter;
import com.keuin.kbackupfabric.util.PrintUtil;
import com.keuin.kbackupfabric.worker.BackupWorker;
@@ -209,9 +210,16 @@ public final class KBCommands {
msgWarn(context, "Nothing to be confirmed. Please execute /kb restore <backup_name> first.");
return FAILED;
}
+
AbstractConfirmableOperation operation = pendingOperation;
pendingOperation = null;
- return operation.confirm() ? SUCCESS : FAILED; // block compiler's complain.
+
+ boolean returnValue = operation.confirm();
+
+ // By the way, update suggestion list.
+ BackupNameSuggestionProvider.updateCandidateList();
+
+ return returnValue ? SUCCESS : FAILED; // block compiler's complain.
}
/**
diff --git a/src/main/java/com/keuin/kbackupfabric/KBPluginEvents.java b/src/main/java/com/keuin/kbackupfabric/KBPluginEvents.java
index f3a3b07..79105b2 100644
--- a/src/main/java/com/keuin/kbackupfabric/KBPluginEvents.java
+++ b/src/main/java/com/keuin/kbackupfabric/KBPluginEvents.java
@@ -38,6 +38,9 @@ public final class KBPluginEvents implements ModInitializer, ServerStartCallback
public void onStartServer(MinecraftServer server) {
PrintUtil.debug("Initializing ...");
+ // Initialize player manager reference
+ PrintUtil.setPlayerManager(server.getPlayerManager());
+
// Update backup suggestion list
BackupNameSuggestionProvider.setBackupSaveDirectory(BackupFilesystemUtil.getBackupSaveDirectory(server).getPath());
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java
index 2d0c403..4b129d9 100644
--- a/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java
+++ b/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java
@@ -25,7 +25,7 @@ class RestoreOperation extends AbstractConfirmableOperation {
public boolean confirm() {
// do restore to backupName
MinecraftServer server = context.getSource().getMinecraftServer();
- PrintUtil.msgInfo(context, String.format("Restoring to previous world %s ...", backupName), true);
+ PrintUtil.broadcast(String.format("Restoring to previous world %s ...", backupName));
String backupFileName = getBackupFileName(backupName);
PrintUtil.debug("Backup file name: " + backupFileName);
@@ -41,7 +41,7 @@ class RestoreOperation extends AbstractConfirmableOperation {
} catch (InterruptedException ignored) {
}
}
- PrintUtil.msgInfo(context, "Shutting down ...", true);
+ PrintUtil.broadcast("Shutting down ...");
RestoreWorker.invoke(server, backupFile.getPath(), getLevelPath(server));
return true;
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/BackupNameSuggestionProvider.java b/src/main/java/com/keuin/kbackupfabric/util/BackupNameSuggestionProvider.java
index 7e87815..ff122b9 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/BackupNameSuggestionProvider.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/BackupNameSuggestionProvider.java
@@ -15,8 +15,8 @@ public class BackupNameSuggestionProvider {
private static final List<String> candidateCacheList = new ArrayList<>();
private static final Object syncSetDirectory = new Object();
- private static final Object syncUpdate = new Object();
- private static final long CACHE_TTL = 10000;
+ private static final Object syncCache = new Object();
+ private static final long CACHE_TTL = 8000;
private static String backupSaveDirectory;
private static long cacheUpdateTime = 0;
@@ -24,12 +24,12 @@ public class BackupNameSuggestionProvider {
synchronized (syncSetDirectory) {
BackupNameSuggestionProvider.backupSaveDirectory = backupSaveDirectory;
}
- // Immediately perform a update
+ // Immediately perform an update
updateCandidateList();
}
public static void updateCandidateList() {
- synchronized (syncUpdate) {
+ synchronized (syncCache) {
try {
File file = new File(backupSaveDirectory);
candidateCacheList.clear();
@@ -57,20 +57,21 @@ public class BackupNameSuggestionProvider {
if (isCacheExpired())
updateCandidateList();
String remaining = builder.getRemaining().toLowerCase(Locale.ROOT);
+ synchronized (syncCache) {
+ if (candidateCacheList.isEmpty()) { // If the list is empty then return no suggestions
+ return Suggestions.empty(); // No suggestions
+ }
- if (candidateCacheList.isEmpty()) { // If the list is empty then return no suggestions
- return Suggestions.empty(); // No suggestions
- }
-
- for (String string : candidateCacheList) { // Iterate through the supplied list
- if (string.toLowerCase(Locale.ROOT).startsWith(remaining)) {
- builder.suggest(string); // Add every single entry to suggestions list.
+ for (String string : candidateCacheList) { // Iterate through the supplied list
+ if (string.toLowerCase(Locale.ROOT).startsWith(remaining)) {
+ builder.suggest(string); // Add every single entry to suggestions list.
+ }
}
}
return builder.buildFuture(); // Create the CompletableFuture containing all the suggestions
}
private static boolean isCacheExpired() {
- return System.currentTimeMillis() - cacheUpdateTime > CACHE_TTL;
+ return System.currentTimeMillis() - cacheUpdateTime > CACHE_TTL || cacheUpdateTime == 0;
}
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java b/src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java
index 11995e7..8839993 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java
@@ -1,6 +1,7 @@
package com.keuin.kbackupfabric.util;
import com.mojang.brigadier.context.CommandContext;
+import net.minecraft.server.PlayerManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Style;
@@ -13,13 +14,30 @@ import org.apache.logging.log4j.Logger;
public final class PrintUtil {
private static final Object syncMessage = new Object();
+ private static final Object syncBroadcast = new Object();
+ private static final Style broadcastStyle = new Style().setColor(Formatting.AQUA);
private static final Style infoStyle = new Style().setColor(Formatting.WHITE);
- private static final Style stressStyle = new Style().setColor(Formatting.AQUA).setBold(true);
+ private static final Style stressStyle = new Style().setColor(Formatting.AQUA);
private static final Style warnStyle = new Style().setColor(Formatting.YELLOW);
private static final Style errorStyle = new Style().setColor(Formatting.DARK_RED);
private static final Logger LOGGER = LogManager.getLogger();
+ private static PlayerManager fuckMojang = null;
+
+ public static void setPlayerManager(PlayerManager playerManager) {
+ if (fuckMojang == null)
+ fuckMojang = playerManager;
+ }
+
+ public static void broadcast(String message) {
+ synchronized (syncBroadcast) {
+ if (fuckMojang != null)
+ fuckMojang.sendToAll(new LiteralText(message).setStyle(broadcastStyle));
+ else
+ PrintUtil.error("Error in PrintUtil.broadcast: PlayerManager is not initialized.");
+ }
+ }
public static CommandContext<ServerCommandSource> msgStress(CommandContext<ServerCommandSource> context, String messageText) {
return msgStress(context, messageText, false);
diff --git a/src/main/java/com/keuin/kbackupfabric/worker/BackupWorker.java b/src/main/java/com/keuin/kbackupfabric/worker/BackupWorker.java
index e972b4d..d6db636 100644
--- a/src/main/java/com/keuin/kbackupfabric/worker/BackupWorker.java
+++ b/src/main/java/com/keuin/kbackupfabric/worker/BackupWorker.java
@@ -41,7 +41,7 @@ public final class BackupWorker implements Runnable {
public static void invoke(CommandContext<ServerCommandSource> context, String backupName, BackupMetadata backupMetadata) {
//// Save world, save old autosave configs
- PrintUtil.msgInfo(context, String.format("Making backup %s, please wait ...", backupName), true);
+ PrintUtil.broadcast(String.format("Making backup %s, please wait ...", backupName));
Map<World, Boolean> oldWorldsSavingDisabled = new HashMap<>(); // old switch stat
// Get server
@@ -54,9 +54,9 @@ public final class BackupWorker implements Runnable {
});
// Force to save all player data and worlds
- PrintUtil.info("Saving players ...");
+ PrintUtil.msgInfo(context, "Saving players ...");
server.getPlayerManager().saveAllPlayerData();
- PrintUtil.info("Saving worlds ...");
+ PrintUtil.msgInfo(context, "Saving worlds ...");
server.save(true, true, true);
// Start threaded worker
@@ -83,7 +83,7 @@ public final class BackupWorker implements Runnable {
// Make zip
String levelPath = getLevelPath(server);
String backupFileName = getBackupFileName(backupName);
- PrintUtil.debug(String.format("zip(srcPath=%s, destPath=%s)", levelPath, backupSaveDirectoryFile.toString()));
+ PrintUtil.info(String.format("zip(srcPath=%s, destPath=%s)", levelPath, backupSaveDirectoryFile.toString()));
PrintUtil.info("Compressing level ...");
ZipUtil.makeBackupZip(levelPath, backupSaveDirectoryFile.toString(), backupFileName, backupMetadata);
File backupZipFile = new File(backupSaveDirectoryFile, backupFileName);
@@ -92,12 +92,13 @@ public final class BackupWorker implements Runnable {
server.getWorlds().forEach(world -> world.savingDisabled = oldWorldsSavingDisabled.getOrDefault(world, true));
// Print finish message: time elapsed and file size
- long timeEscapedMillis = System.currentTimeMillis() - startTime;
- msgInfo(context, String.format("Backup finished. (%.2fs)", timeEscapedMillis / 1000.0), true);
+ long timeElapsedMillis = System.currentTimeMillis() - startTime;
+ String msgText = String.format("Backup finished. Time elapsed: %.2fs.", timeElapsedMillis / 1000.0);
try {
- msgInfo(context, String.format("File size: %s", humanFileSize(backupZipFile.length())));
+ msgText += String.format(" File size: %s.", humanFileSize(backupZipFile.length()));
} catch (SecurityException ignored) {
}
+ PrintUtil.msgInfo(context, msgText, true);
} catch (SecurityException e) {
msgInfo(context, String.format("Failed to create backup saving directory: %s. Failed to backup.", backupSaveDirectory));