diff options
author | Keuin <[email protected]> | 2020-04-23 10:45:28 +0800 |
---|---|---|
committer | keuin <[email protected]> | 2020-04-23 10:45:28 +0800 |
commit | b2d161cee43b9b1af04416486d6df82621b03ae3 (patch) | |
tree | e102ea567d7e7f0f7a90acd16b34ac147ed9338e /src/main/java/com/keuin/kbackupfabric/KBCommandHandler.java | |
parent | b582ad31ed8d44aa60b2eab22b2d927519297eeb (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.java | 129 |
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); - } - } } |