summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java
diff options
context:
space:
mode:
authorKeuin <[email protected]>2020-04-23 10:45:28 +0800
committerkeuin <[email protected]>2020-04-23 10:45:28 +0800
commitb2d161cee43b9b1af04416486d6df82621b03ae3 (patch)
treee102ea567d7e7f0f7a90acd16b34ac147ed9338e /src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java
parentb582ad31ed8d44aa60b2eab22b2d927519297eeb (diff)
Version 1.0.0-dev1.0.0-dev
TODO: Optimize ZipUtil
Diffstat (limited to 'src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java129
1 files changed, 88 insertions, 41 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java b/src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java
index c1d176c..33d0f43 100644
--- a/src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java
+++ b/src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java
@@ -1,15 +1,13 @@
package com.keuin.kbackupfabric;
+import com.keuin.kbackupfabric.util.PostProgressRestoreThread;
import com.keuin.kbackupfabric.util.ZipUtil;
import com.keuin.kbackupfabric.util.ZipUtilException;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
-import net.minecraft.text.LiteralText;
import net.minecraft.world.World;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
@@ -18,15 +16,19 @@ import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
+import static com.keuin.kbackupfabric.util.IO.debug;
+import static com.keuin.kbackupfabric.util.IO.message;
+
public class KBCommandHandler {
- private static final Logger LOGGER = LogManager.getLogger();
+
private static final int SUCCESS = 1;
private static final int FAILED = -1;
- private static final boolean printDebugMessages = true;
- private static final boolean printErrorMessages = true;
+
private static final String backupSaveDirectoryName = "backups";
private static final String backupFileNamePrefix = "kbackup-";
+ private static final HashMap<Integer, String> backupIndexNameMapper = new HashMap<>(); // index -> backupName
+ private static String restoreBackupNameToBeConfirmed = null;
/**
* Print the help menu.
@@ -49,9 +51,14 @@ public class KBCommandHandler {
File[] files = getBackupSaveDirectory(server).listFiles(
(dir, name) -> dir.isDirectory() && name.toLowerCase().endsWith(".zip") && name.toLowerCase().startsWith(backupFileNamePrefix)
);
+ backupIndexNameMapper.clear();
if (files != null) {
+ int i = 0;
for (File file : files) {
- message(context, file.getName());
+ ++i;
+ String backupName = getBackupName(file.getName());
+ backupIndexNameMapper.put(i, backupName);
+ message(context, String.format("[%d] %s, size: %.1fMB", i, backupName, file.length() * 1.0 / 1024 / 1024));
}
}
return SUCCESS;
@@ -65,10 +72,44 @@ public class KBCommandHandler {
*/
public static int backup(CommandContext<ServerCommandSource> context) {
//KBMain.backup("name")
- return doBackup(context, StringArgumentType.getString(context, "backupName"));
+ String backupName = StringArgumentType.getString(context, "backupName");
+ if (backupName.matches("[0-9]*")) {
+ // Numeric param is not allowed
+ backupName = String.format("a%s", backupName);
+ message(context, String.format("Pure numeric name is not allowed. Renamed to %s", backupName));
+ }
+ return doBackup(context, backupName);
}
/**
+ * Restore with context parameter backupName.
+ * Simply set the pending backupName to given backupName, for the second confirmation.
+ *
+ * @param context the context.
+ * @return stat code.
+ */
+ public static int restore(CommandContext<ServerCommandSource> context) {
+ //KBMain.restore("name")
+ String backupName = StringArgumentType.getString(context, "backupName");
+
+ if (backupName.matches("[0-9]*")) {
+ // If numeric input
+ Integer index = Integer.parseInt(backupName);
+ String realBackupName = backupIndexNameMapper.get(index);
+ if (realBackupName == null) {
+ return list(context); // Show the list and return
+ }
+ backupName = realBackupName; // Replace input number with real backup name.
+ }
+
+ // Update confirm pending variable
+ restoreBackupNameToBeConfirmed = backupName;
+ message(context, String.format("WARNING: You will LOST YOUR CURRENT WORLD COMPLETELY! It will be replaced with the backup %s . Please use /kb confirm to proceed executing.", restoreBackupNameToBeConfirmed), true);
+ return SUCCESS;
+ }
+
+
+ /**
* Backup with default name.
*
* @param context the context.
@@ -84,7 +125,7 @@ public class KBCommandHandler {
private static int doBackup(CommandContext<ServerCommandSource> context, String backupName) {
String destPathFolderName = "";
try {
- message(context, String.format("Making backup %s ...", backupName), true);
+ message(context, String.format("Making backup %s, please wait ...", backupName), true);
Map<World, Boolean> oldWorldsSavingDisabled = new HashMap<>(); // old switch stat
// Get server
@@ -104,9 +145,6 @@ public class KBCommandHandler {
//// Do our main backup logic
- // Get the level folder
- File sourcePathFile = new File(server.getRunDirectory(), server.getLevelName());
-
// Create backup saving directory
File destPathFile = getBackupSaveDirectory(server);
destPathFolderName = destPathFile.getName();
@@ -116,9 +154,9 @@ public class KBCommandHandler {
}
// Make zip
- debug(String.format("zip(srcPath=%s, destPath=%s)", sourcePathFile.getAbsolutePath(), destPathFile.toString()));
- ZipUtil.zip(sourcePathFile.getAbsolutePath(), destPathFile.toString(), backupFileNamePrefix + backupName + ".zip");
-
+ String levelPath = getLevelPath(server);
+ debug(String.format("zip(srcPath=%s, destPath=%s)", levelPath, destPathFile.toString()));
+ ZipUtil.zip(levelPath, destPathFile.toString(), getBackupFileName(backupName));
// Restore old autosave switch stat
server.getWorlds().forEach(world -> world.savingDisabled = oldWorldsSavingDisabled.getOrDefault(world, true));
@@ -134,51 +172,60 @@ public class KBCommandHandler {
}
}
+ private static String getBackupFileName(String backupName) {
+ return backupFileNamePrefix + backupName + ".zip";
+ }
+
+ private static String getBackupName(String backupFileName) {
+ try {
+ if (backupFileName.matches(backupFileNamePrefix + ".+\\.zip"))
+ return backupFileName.substring(backupFileNamePrefix.length(), backupFileName.length() - 4);
+ } catch (IndexOutOfBoundsException ignored) {
+ }
+ return backupFileName;
+ }
+
private static File getBackupSaveDirectory(MinecraftServer server) {
return new File(server.getRunDirectory(), backupSaveDirectoryName);
}
+ private static String getLevelPath(MinecraftServer server) {
+ return (new File(server.getRunDirectory(), server.getLevelName())).getAbsolutePath();
+ }
+
/**
* Restore with context parameter backupName.
*
* @param context the context.
* @return stat code.
*/
- public static int restore(CommandContext<ServerCommandSource> context) {
- //KBMain.restore("name")
- String backupName = StringArgumentType.getString(context, "backupName");
- message(context, String.format("Restoring worlds to %s ...", backupName), true);
+ public static int confirm(CommandContext<ServerCommandSource> context) {
+ if (restoreBackupNameToBeConfirmed == null) {
+ message(context, "Nothing to be confirmed. Please execute /kb restore <backup_name> first.");
+ return FAILED;
+ }
+
// do restore to backupName
+ String backupName = restoreBackupNameToBeConfirmed;
+ message(context, String.format("Restoring worlds to %s ...", backupName), true);
- message(context, "Done.", true);
+ // Get server
+ MinecraftServer server = context.getSource().getMinecraftServer();
+ String backupFileName = getBackupFileName(backupName);
+ debug("Backup file name: " + backupFileName);
+ File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
+ PostProgressRestoreThread postProgressRestoreThread = new PostProgressRestoreThread(server.getThread(), backupFile.getPath(), getLevelPath(server));
+ Thread postThread = new Thread(postProgressRestoreThread, "PostProgressRestoreThread");
+ postThread.start();
+ server.stop(false);
+ message(context, "Decompressing archive data. Server will shutdown to replace level data. Please do not restart the server.", true);
return SUCCESS;
}
- private static CommandContext<ServerCommandSource> message(CommandContext<ServerCommandSource> context, String messageText) {
- return message(context, messageText, false);
- }
-
- private static CommandContext<ServerCommandSource> message(CommandContext<ServerCommandSource> context, String messageText, boolean broadcastToOps) {
- context.getSource().sendFeedback(new LiteralText("[KBackup] " + messageText), broadcastToOps);
- return context;
- }
-
static boolean opPermissionValidator(ServerCommandSource commandSource) {
return commandSource.hasPermissionLevel(4);
}
- private static void debug(String debugMessage) {
- if (printDebugMessages) {
- System.out.println(String.format("[DEBUG] [KBackup] %s", debugMessage));
- LOGGER.debug(debugMessage);
- }
- }
- private static void error(String errorMessage) {
- if (printErrorMessages) {
- System.out.println(String.format("[ERROR] [KBackup] %s", errorMessage));
- LOGGER.error(errorMessage);
- }
- }
}