summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/kbackupfabric/util
diff options
context:
space:
mode:
authorKeuin <[email protected]>2020-04-23 14:51:29 +0800
committerkeuin <[email protected]>2020-04-23 14:51:29 +0800
commit720e8ec8eeb69d24afbb6b14068563cde2d470f0 (patch)
tree83b6dee213737b138ede00d83aa1e9d5eab51fa3 /src/main/java/com/keuin/kbackupfabric/util
parent4605445eb90e15a0629cf937452054cab7dd2b85 (diff)
Version 1.1.0-dev:1.1.0-dev
- Optimized backup lag (using async I/O). - Added twice confirmation /kb confirm and cancellation /kb cancel, to avoid mistake. - Added countdown before restoring. - Adjusted some text. - Code optimization.
Diffstat (limited to 'src/main/java/com/keuin/kbackupfabric/util')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/BackupFilesystemUtil.java53
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/PermissionValidator.java9
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/PostProgressRestoreThread.java71
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java (renamed from src/main/java/com/keuin/kbackupfabric/util/IO.java)7
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/ReflectionUtils.java4
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/WorldUtil.java15
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java2
7 files changed, 70 insertions, 91 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/util/BackupFilesystemUtil.java b/src/main/java/com/keuin/kbackupfabric/util/BackupFilesystemUtil.java
new file mode 100644
index 0000000..5b8ba5a
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/BackupFilesystemUtil.java
@@ -0,0 +1,53 @@
+package com.keuin.kbackupfabric.util;
+
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.world.ThreadedAnvilChunkStorage;
+import net.minecraft.world.World;
+
+import java.io.File;
+
+/**
+ * Functions deal with file name, directory name about Minecraft saves.
+ */
+public final class BackupFilesystemUtil {
+
+ private static final String backupSaveDirectoryName = "backups";
+ private static final String backupFileNamePrefix = "kbackup-";
+
+ public static String getBackupFileName(String backupName) {
+ return backupFileNamePrefix + backupName + ".zip";
+ }
+
+ public static String getBackupName(String backupFileName) {
+ try {
+ if (backupFileName.matches(backupFileNamePrefix + ".+\\.zip"))
+ return backupFileName.substring(backupFileNamePrefix.length(), backupFileName.length() - 4);
+ } catch (IndexOutOfBoundsException ignored) {
+ }
+ return backupFileName;
+ }
+
+ public static boolean isBackupNameValid(String backupName, MinecraftServer server) {
+ File backupFile = new File(getBackupSaveDirectory(server), getBackupFileName(backupName));
+ return backupFile.isFile();
+ }
+
+ public static File getBackupSaveDirectory(MinecraftServer server) {
+ return new File(server.getRunDirectory(), backupSaveDirectoryName);
+ }
+
+ public static String getLevelPath(MinecraftServer server) {
+ return (new File(server.getRunDirectory(), server.getLevelName())).getAbsolutePath();
+ }
+
+ public static String getWorldDirectoryName(World world) throws NoSuchFieldException, IllegalAccessException {
+ File saveDir;
+ ThreadedAnvilChunkStorage threadedAnvilChunkStorage = (ThreadedAnvilChunkStorage) ReflectionUtils.getPrivateField(world.getChunkManager(), "threadedAnvilChunkStorage");
+ saveDir = (File) ReflectionUtils.getPrivateField(threadedAnvilChunkStorage, "saveDir");
+ return saveDir.getName();
+ }
+
+ public static String getBackupFileNamePrefix() {
+ return backupFileNamePrefix;
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/PermissionValidator.java b/src/main/java/com/keuin/kbackupfabric/util/PermissionValidator.java
new file mode 100644
index 0000000..9d37901
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/PermissionValidator.java
@@ -0,0 +1,9 @@
+package com.keuin.kbackupfabric.util;
+
+import net.minecraft.server.command.ServerCommandSource;
+
+public class PermissionValidator {
+ public static boolean op(ServerCommandSource commandSource) {
+ return commandSource.hasPermissionLevel(4);
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/PostProgressRestoreThread.java b/src/main/java/com/keuin/kbackupfabric/util/PostProgressRestoreThread.java
deleted file mode 100644
index 8427a2c..0000000
--- a/src/main/java/com/keuin/kbackupfabric/util/PostProgressRestoreThread.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.keuin.kbackupfabric.util;
-
-import java.io.File;
-import java.io.IOException;
-
-import static com.keuin.kbackupfabric.util.IO.*;
-import static org.apache.commons.io.FileUtils.forceDelete;
-
-/**
- * This thread wait the server to be stopped (must invoke stop out of this thread),
- * then delete current level, and restore our backup.
- */
-public class PostProgressRestoreThread implements Runnable {
- private final Thread serverThread;
- private final String backupFilePath;
- private final String levelDirectory;
-
- public PostProgressRestoreThread(Thread serverThread, String backupFilePath, String levelDirectory) {
- this.serverThread = serverThread;
- this.backupFilePath = backupFilePath;
- this.levelDirectory = levelDirectory;
- }
-
- @Override
- public void run() {
- try {
- // Wait server thread die
- debug("Waiting server thread stopping ...");
- while (serverThread.isAlive()) {
- try {
- serverThread.join();
- } catch (InterruptedException ignored) {
- }
- }
-
- debug("Waiting ...");
- try {
- Thread.sleep(5000);
- } catch (InterruptedException ignored) {
- }
- // Delete old level
- debug("Server stopped. Deleting old level ...");
- File levelDirFile = new File(levelDirectory);
-
- int failedCounter = 0;
- final int MAX_RETRY_TIMES = 20;
- while (failedCounter < MAX_RETRY_TIMES) {
- System.gc();
- if (!levelDirFile.delete() && levelDirFile.exists()) {
- System.gc();
- forceDelete(levelDirFile); // Try to force delete.
- }
- if (levelDirFile.exists())
- ++failedCounter;
- else
- break;
- }
- if (levelDirFile.exists()) {
- error(String.format("Cannot restore: failed to delete old level %s .", levelDirFile.getName()));
- return;
- }
-
- // Decompress archive
- debug("Decompressing archived level");
- ZipUtil.unzip(backupFilePath, levelDirectory, false);
- info("Restore complete! Please restart the server manually.");
- } catch (SecurityException | IOException | ZipUtilException e) {
- error("An exception occurred while restoring: " + e.getMessage());
- }
- }
-}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/IO.java b/src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java
index 6d969ba..e76155f 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/IO.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/PrintUtil.java
@@ -6,7 +6,7 @@ import net.minecraft.text.LiteralText;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-public class IO {
+public final class PrintUtil {
private static final Logger LOGGER = LogManager.getLogger();
private static final boolean printDebugMessages = true;
@@ -15,13 +15,16 @@ public class IO {
private static final Object syncDebug = new Object();
private static final Object syncError = new Object();
private static final Object syncInfo = new Object();
+ private static final Object syncMessage = new Object();
public static CommandContext<ServerCommandSource> message(CommandContext<ServerCommandSource> context, String messageText) {
return message(context, messageText, false);
}
public static CommandContext<ServerCommandSource> message(CommandContext<ServerCommandSource> context, String messageText, boolean broadcastToOps) {
- context.getSource().sendFeedback(new LiteralText("[KBackup] " + messageText), broadcastToOps);
+ synchronized (syncMessage) {
+ context.getSource().sendFeedback(new LiteralText("[KBackup] " + messageText), broadcastToOps);
+ }
return context;
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/ReflectionUtils.java b/src/main/java/com/keuin/kbackupfabric/util/ReflectionUtils.java
index f7bc351..2acc562 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/ReflectionUtils.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/ReflectionUtils.java
@@ -7,9 +7,9 @@ import java.lang.reflect.Method;
/**
* @Author 落叶飞翔的蜗牛
* @Date 2018/3/10
- * @Description
+ * @Description 常用反射函数
*/
-public class ReflectionUtils {
+public final class ReflectionUtils {
/**
* 获取私有成员变量的值
diff --git a/src/main/java/com/keuin/kbackupfabric/util/WorldUtil.java b/src/main/java/com/keuin/kbackupfabric/util/WorldUtil.java
deleted file mode 100644
index badc068..0000000
--- a/src/main/java/com/keuin/kbackupfabric/util/WorldUtil.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.keuin.kbackupfabric.util;
-
-import net.minecraft.server.world.ThreadedAnvilChunkStorage;
-import net.minecraft.world.World;
-
-import java.io.File;
-
-public class WorldUtil {
- public static String getWorldDirectoryName(World world) throws NoSuchFieldException, IllegalAccessException {
- File saveDir;
- ThreadedAnvilChunkStorage threadedAnvilChunkStorage = (ThreadedAnvilChunkStorage) ReflectionUtils.getPrivateField(world.getChunkManager(), "threadedAnvilChunkStorage");
- saveDir = (File) ReflectionUtils.getPrivateField(threadedAnvilChunkStorage, "saveDir");
- return saveDir.getName();
- }
-}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java b/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
index 0ab93ca..1ceeb60 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
@@ -4,7 +4,7 @@ import java.io.*;
import java.util.Enumeration;
import java.util.zip.*;
-public class ZipUtil {
+public final class ZipUtil {
/**
* 递归压缩文件夹