diff --git a/src/main/java/net/szum123321/textile_backup/Globals.java b/src/main/java/net/szum123321/textile_backup/Globals.java
index 62f04d3..26beea8 100644
--- a/src/main/java/net/szum123321/textile_backup/Globals.java
+++ b/src/main/java/net/szum123321/textile_backup/Globals.java
@@ -23,7 +23,6 @@ import net.szum123321.textile_backup.core.digest.BalticHash;
import net.szum123321.textile_backup.core.digest.Hash;
import net.szum123321.textile_backup.core.Utilities;
-import net.szum123321.textile_backup.core.create.MakeBackupRunnable;
import net.szum123321.textile_backup.core.restore.AwaitThread;
import org.apache.commons.io.FileUtils;
@@ -70,8 +69,8 @@ public class Globals {
if(!executorService.awaitTermination(timeout, TimeUnit.MICROSECONDS)) {
log.error("Timeout occurred while waiting for currently running backups to finish!");
executorService.shutdownNow().stream()
- .filter(r -> r instanceof MakeBackupRunnable)
- .map(r -> (MakeBackupRunnable)r)
+ // .filter(r -> r instanceof ExecutableBackup)
+ // .map(r -> (ExecutableBackup)r)
.forEach(r -> log.error("Dropping: {}", r.toString()));
if(!executorService.awaitTermination(1000, TimeUnit.MICROSECONDS))
log.error("Couldn't shut down the executor!");
diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java
index 853aa3e..4d10e03 100644
--- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java
+++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java
@@ -39,9 +39,8 @@ import net.szum123321.textile_backup.commands.restore.RestoreBackupCommand;
import net.szum123321.textile_backup.config.ConfigHelper;
import net.szum123321.textile_backup.config.ConfigPOJO;
import net.szum123321.textile_backup.core.ActionInitiator;
-import net.szum123321.textile_backup.core.create.BackupContext;
import net.szum123321.textile_backup.core.create.BackupScheduler;
-import net.szum123321.textile_backup.core.create.MakeBackupRunnableFactory;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import net.szum123321.textile_backup.test.BalticHashTest;
public class TextileBackup implements ModInitializer {
@@ -82,14 +81,14 @@ public class TextileBackup implements ModInitializer {
if (config.get().shutdownBackup && Globals.INSTANCE.globalShutdownBackupFlag.get()) {
try {
- MakeBackupRunnableFactory.create(
- BackupContext.Builder
+ ExecutableBackup.Builder
.newBackupContextBuilder()
.setServer(server)
.setInitiator(ActionInitiator.Shutdown)
.setComment("shutdown")
+ .announce()
.build()
- ).call();
+ .call();
} catch (Exception ignored) {}
}
});
diff --git a/src/main/java/net/szum123321/textile_backup/TextileLogger.java b/src/main/java/net/szum123321/textile_backup/TextileLogger.java
index 2e77da9..0a38389 100644
--- a/src/main/java/net/szum123321/textile_backup/TextileLogger.java
+++ b/src/main/java/net/szum123321/textile_backup/TextileLogger.java
@@ -23,7 +23,7 @@ import net.minecraft.text.Text;
import net.minecraft.text.MutableText;
import net.minecraft.util.Formatting;
import net.szum123321.textile_backup.core.Utilities;
-import net.szum123321.textile_backup.core.create.BackupContext;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -112,7 +112,7 @@ public class TextileLogger {
sendFeedback(Level.INFO, source, msg, args);
}
- public void sendInfo(BackupContext context, String msg, Object... args) {
+ public void sendInfo(ExecutableBackup context, String msg, Object... args) {
sendInfo(context.commandSource(), msg, args);
}
@@ -120,7 +120,8 @@ public class TextileLogger {
sendFeedback(Level.ERROR, source, msg, args);
}
- public void sendError(BackupContext context, String msg, Object... args) {
+
+ public void sendError(ExecutableBackup context, String msg, Object... args) {
sendError(context.commandSource(), msg, args);
}
@@ -134,7 +135,7 @@ public class TextileLogger {
sendToPlayerAndLog(Level.INFO, source, msg, args);
}
- public void sendInfoAL(BackupContext context, String msg, Object... args) {
+ public void sendInfoAL(ExecutableBackup context, String msg, Object... args) {
sendInfoAL(context.commandSource(), msg, args);
}
@@ -142,7 +143,7 @@ public class TextileLogger {
sendToPlayerAndLog(Level.ERROR, source, msg, args);
}
- public void sendErrorAL(BackupContext context, String msg, Object... args) {
+ public void sendErrorAL(ExecutableBackup context, String msg, Object... args) {
sendErrorAL(context.commandSource(), msg, args);
}
}
diff --git a/src/main/java/net/szum123321/textile_backup/commands/create/StartBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/create/StartBackupCommand.java
index 1ec744f..7964c5a 100644
--- a/src/main/java/net/szum123321/textile_backup/commands/create/StartBackupCommand.java
+++ b/src/main/java/net/szum123321/textile_backup/commands/create/StartBackupCommand.java
@@ -25,8 +25,7 @@ import net.minecraft.server.command.ServerCommandSource;
import net.szum123321.textile_backup.Globals;
import net.szum123321.textile_backup.TextileBackup;
import net.szum123321.textile_backup.TextileLogger;
-import net.szum123321.textile_backup.core.create.BackupContext;
-import net.szum123321.textile_backup.core.create.MakeBackupRunnableFactory;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import javax.annotation.Nullable;
@@ -42,15 +41,13 @@ public class StartBackupCommand {
private static int execute(ServerCommandSource source, @Nullable String comment) {
Globals.INSTANCE.getQueueExecutor().submit(
- MakeBackupRunnableFactory.create(
- BackupContext.Builder
- .newBackupContextBuilder()
- .setCommandSource(source)
- .setComment(comment)
- .guessInitiator()
- .saveServer()
- .build()
- )
+ ExecutableBackup.Builder
+ .newBackupContextBuilder()
+ .setCommandSource(source)
+ .setComment(comment)
+ .guessInitiator()
+ .saveServer()
+ .build()
);
return 1;
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java
deleted file mode 100644
index d626695..0000000
--- a/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * A simple backup mod for Fabric
- * Copyright (C) 2022 Szum123321
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package net.szum123321.textile_backup.core.create;
-
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.command.ServerCommandSource;
-import net.szum123321.textile_backup.core.ActionInitiator;
-import net.szum123321.textile_backup.core.Utilities;
-import org.jetbrains.annotations.NotNull;
-
-import java.time.LocalDateTime;
-import java.util.NoSuchElementException;
-
-public record BackupContext(@NotNull MinecraftServer server,
- ServerCommandSource commandSource,
- ActionInitiator initiator,
- boolean save,
- boolean cleanup,
- String comment,
- LocalDateTime startDate) {
-
- public boolean startedByPlayer() {
- return initiator == ActionInitiator.Player;
- }
-
- public boolean shouldSave() {
- return save;
- }
-
- public static class Builder {
- private MinecraftServer server;
- private ServerCommandSource commandSource;
- private ActionInitiator initiator;
- private boolean save;
- private boolean cleanup;
- private String comment;
-
- private boolean guessInitiator;
-
- public Builder() {
- this.server = null;
- this.commandSource = null;
- this.initiator = null;
- this.save = false;
- cleanup = true; //defaults
- this.comment = null;
-
- guessInitiator = false;
- }
-
- public static Builder newBackupContextBuilder() {
- return new Builder();
- }
-
- public Builder setCommandSource(ServerCommandSource commandSource) {
- this.commandSource = commandSource;
- return this;
- }
-
- public Builder setServer(MinecraftServer server) {
- this.server = server;
- return this;
- }
-
- public Builder setInitiator(ActionInitiator initiator) {
- this.initiator = initiator;
- return this;
- }
-
- public Builder setComment(String comment) {
- this.comment = comment;
- return this;
- }
-
- public Builder guessInitiator() {
- this.guessInitiator = true;
- return this;
- }
-
- public Builder saveServer() {
- this.save = true;
- return this;
- }
-
- public Builder dontCleanup() {
- this.cleanup = false;
- return this;
- }
-
- public BackupContext build() {
- if (guessInitiator) {
- initiator = Utilities.wasSentByPlayer(commandSource) ? ActionInitiator.Player : ActionInitiator.ServerConsole;
- } else if (initiator == null) throw new NoSuchElementException("No initiator provided!");
-
- if (server == null) {
- if (commandSource != null) setServer(commandSource.getServer());
- else throw new RuntimeException("Neither MinecraftServer or ServerCommandSource were provided!");
- }
-
- return new BackupContext(server, commandSource, initiator, save, cleanup, comment, LocalDateTime.now());
- }
- }
-}
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupScheduler.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupScheduler.java
index 3359db9..55a13f3 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/BackupScheduler.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupScheduler.java
@@ -53,14 +53,13 @@ public class BackupScheduler {
if(nextBackup <= now) {
//It's time to run
Globals.INSTANCE.getQueueExecutor().submit(
- MakeBackupRunnableFactory.create(
- BackupContext.Builder
- .newBackupContextBuilder()
- .setServer(server)
- .setInitiator(ActionInitiator.Timer)
- .saveServer()
- .build()
- )
+ ExecutableBackup.Builder
+ .newBackupContextBuilder()
+ .setServer(server)
+ .setInitiator(ActionInitiator.Timer)
+ .saveServer()
+ .announce()
+ .build()
);
nextBackup = now + config.get().backupInterval;
@@ -76,14 +75,13 @@ public class BackupScheduler {
if(scheduled && nextBackup <= now) {
//Verify we hadn't done the final one, and it's time to do so
Globals.INSTANCE.getQueueExecutor().submit(
- MakeBackupRunnableFactory.create(
- BackupContext.Builder
- .newBackupContextBuilder()
- .setServer(server)
- .setInitiator(ActionInitiator.Timer)
- .saveServer()
- .build()
- )
+ ExecutableBackup.Builder
+ .newBackupContextBuilder()
+ .setServer(server)
+ .setInitiator(ActionInitiator.Timer)
+ .saveServer()
+ .announce()
+ .build()
);
scheduled = false;
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/ExecutableBackup.java b/src/main/java/net/szum123321/textile_backup/core/create/ExecutableBackup.java
new file mode 100644
index 0000000..9f5071f
--- /dev/null
+++ b/src/main/java/net/szum123321/textile_backup/core/create/ExecutableBackup.java
@@ -0,0 +1,232 @@
+package net.szum123321.textile_backup.core.create;
+
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.command.ServerCommandSource;
+import net.szum123321.textile_backup.Globals;
+import net.szum123321.textile_backup.TextileBackup;
+import net.szum123321.textile_backup.TextileLogger;
+import net.szum123321.textile_backup.config.ConfigHelper;
+import net.szum123321.textile_backup.core.ActionInitiator;
+import net.szum123321.textile_backup.core.Cleanup;
+import net.szum123321.textile_backup.core.Utilities;
+import net.szum123321.textile_backup.core.create.compressors.ParallelZipCompressor;
+import net.szum123321.textile_backup.core.create.compressors.ZipCompressor;
+import net.szum123321.textile_backup.core.create.compressors.tar.AbstractTarArchiver;
+import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.LocalDateTime;
+import java.util.NoSuchElementException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+public record ExecutableBackup(@NotNull MinecraftServer server,
+ ServerCommandSource commandSource,
+ ActionInitiator initiator,
+ boolean save,
+ boolean cleanup,
+ String comment,
+ LocalDateTime startDate) implements Callable {
+
+ private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
+ private final static ConfigHelper config = ConfigHelper.INSTANCE;
+
+ public boolean startedByPlayer() {
+ return initiator == ActionInitiator.Player;
+ }
+
+ public void announce() {
+ if(config.get().broadcastBackupStart) {
+ Utilities.notifyPlayers(server,
+ "Warning! Server backup will begin shortly. You may experience some lag."
+ );
+ } else {
+ log.sendInfoAL(this, "Warning! Server backup will begin shortly. You may experience some lag.");
+ }
+
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("Backup started ");
+
+ builder.append(initiator.getPrefix());
+
+ if(startedByPlayer())
+ builder.append(commandSource.getDisplayName().getString());
+ else
+ builder.append(initiator.getName());
+
+ builder.append(" on: ");
+ builder.append(Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
+
+ log.info(builder.toString());
+ }
+ @Override
+ public Void call() throws IOException, ExecutionException, InterruptedException {
+ if (save) { //save the world
+ log.sendInfoAL(this, "Saving server...");
+ server.saveAll(true, true, false);
+ }
+
+ Path outFile = Utilities.getBackupRootPath(Utilities.getLevelName(server)).resolve(getFileName());
+
+ log.trace("Outfile is: {}", outFile);
+
+ try {
+ //I think I should synchronise these two next calls...
+ Utilities.disableWorldSaving(server);
+ Globals.INSTANCE.disableWatchdog = true;
+
+ Globals.INSTANCE.updateTMPFSFlag(server);
+
+ log.sendInfoAL(this, "Starting backup");
+
+ Path world = Utilities.getWorldFolder(server);
+
+ log.trace("Minecraft world is: {}", world);
+
+ Files.createDirectories(outFile.getParent());
+ Files.createFile(outFile);
+
+ int coreCount;
+
+ if (config.get().compressionCoreCountLimit <= 0) coreCount = Runtime.getRuntime().availableProcessors();
+ else
+ coreCount = Math.min(config.get().compressionCoreCountLimit, Runtime.getRuntime().availableProcessors());
+
+ log.trace("Running compression on {} threads. Available cores: {}", coreCount, Runtime.getRuntime().availableProcessors());
+
+ switch (config.get().format) {
+ case ZIP -> {
+ if (coreCount > 1 && !Globals.INSTANCE.disableTMPFS()) {
+ log.trace("Using PARALLEL Zip Compressor. Threads: {}", coreCount);
+ ParallelZipCompressor.getInstance().createArchive(world, outFile, this, coreCount);
+ } else {
+ log.trace("Using REGULAR Zip Compressor.");
+ ZipCompressor.getInstance().createArchive(world, outFile, this, coreCount);
+ }
+ }
+ case GZIP -> ParallelGzipCompressor.getInstance().createArchive(world, outFile, this, coreCount);
+ case TAR -> new AbstractTarArchiver().createArchive(world, outFile, this, coreCount);
+ }
+
+ if(cleanup) new Cleanup(commandSource, Utilities.getLevelName(server)).call();
+
+ if (config.get().broadcastBackupDone) Utilities.notifyPlayers(server, "Done!");
+ else log.sendInfoAL(this, "Done!");
+
+ } catch (Throwable e) {
+ //ExecutorService swallows exception, so I need to catch everything
+ log.error("An exception occurred when trying to create new backup file!", e);
+
+ if (ConfigHelper.INSTANCE.get().integrityVerificationMode.isStrict()) {
+ try {
+ Files.delete(outFile);
+ } catch (IOException ex) {
+ log.error("An exception occurred while trying go delete: {}", outFile, ex);
+ }
+ }
+
+ if (initiator == ActionInitiator.Player)
+ log.sendError(this, "An exception occurred when trying to create new backup file!");
+
+ throw e;
+ } finally {
+ Utilities.enableWorldSaving(server);
+ Globals.INSTANCE.disableWatchdog = false;
+ }
+
+ return null;
+ }
+
+ private String getFileName() {
+ return Utilities.getDateTimeFormatter().format(startDate) +
+ (comment != null ? "#" + comment.replaceAll("[\\\\/:*?\"<>|#]", "") : "") +
+ config.get().format.getCompleteString();
+ }
+ public static class Builder {
+ private MinecraftServer server;
+ private ServerCommandSource commandSource;
+ private ActionInitiator initiator;
+ private boolean save;
+ private boolean cleanup;
+ private String comment;
+ private boolean announce;
+
+ private boolean guessInitiator;
+
+ public Builder() {
+ this.server = null;
+ this.commandSource = null;
+ this.initiator = null;
+ this.save = false;
+ cleanup = true; //defaults
+ this.comment = null;
+ this.announce = false;
+
+ guessInitiator = false;
+ }
+
+ public static ExecutableBackup.Builder newBackupContextBuilder() {
+ return new ExecutableBackup.Builder();
+ }
+
+ public ExecutableBackup.Builder setCommandSource(ServerCommandSource commandSource) {
+ this.commandSource = commandSource;
+ return this;
+ }
+
+ public ExecutableBackup.Builder setServer(MinecraftServer server) {
+ this.server = server;
+ return this;
+ }
+
+ public ExecutableBackup.Builder setInitiator(ActionInitiator initiator) {
+ this.initiator = initiator;
+ return this;
+ }
+
+ public ExecutableBackup.Builder setComment(String comment) {
+ this.comment = comment;
+ return this;
+ }
+
+ public ExecutableBackup.Builder guessInitiator() {
+ this.guessInitiator = true;
+ return this;
+ }
+
+ public ExecutableBackup.Builder saveServer() {
+ this.save = true;
+ return this;
+ }
+
+ public ExecutableBackup.Builder noCleanup() {
+ this.cleanup = false;
+ return this;
+ }
+
+ public ExecutableBackup.Builder announce() {
+ this.announce = true;
+ return this;
+ }
+
+ public ExecutableBackup build() {
+ if (guessInitiator) {
+ initiator = Utilities.wasSentByPlayer(commandSource) ? ActionInitiator.Player : ActionInitiator.ServerConsole;
+ } else if (initiator == null) throw new NoSuchElementException("No initiator provided!");
+
+ if (server == null) {
+ if (commandSource != null) setServer(commandSource.getServer());
+ else throw new RuntimeException("Neither MinecraftServer or ServerCommandSource were provided!");
+ }
+
+ ExecutableBackup v = new ExecutableBackup(server, commandSource, initiator, save, cleanup, comment, LocalDateTime.now());
+
+ if(announce) v.announce();
+ return v;
+ }
+ }
+}
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java
deleted file mode 100644
index 03d98a6..0000000
--- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * A simple backup mod for Fabric
- * Copyright (C) 2022 Szum123321
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package net.szum123321.textile_backup.core.create;
-
-import net.szum123321.textile_backup.Globals;
-import net.szum123321.textile_backup.TextileBackup;
-import net.szum123321.textile_backup.TextileLogger;
-import net.szum123321.textile_backup.config.ConfigHelper;
-import net.szum123321.textile_backup.core.ActionInitiator;
-import net.szum123321.textile_backup.core.Cleanup;
-import net.szum123321.textile_backup.core.Utilities;
-import net.szum123321.textile_backup.core.create.compressors.ParallelZipCompressor;
-import net.szum123321.textile_backup.core.create.compressors.ZipCompressor;
-import net.szum123321.textile_backup.core.create.compressors.tar.AbstractTarArchiver;
-import net.szum123321.textile_backup.core.create.compressors.tar.ParallelBZip2Compressor;
-import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-
-/**
- * The actual object responsible for creating the backup
- */
-public class MakeBackupRunnable implements Callable {
- private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
- private final static ConfigHelper config = ConfigHelper.INSTANCE;
-
- private final BackupContext context;
-
- public MakeBackupRunnable(BackupContext context) {
- this.context = context;
- }
-
- @Override
- public Void call() throws IOException, ExecutionException, InterruptedException {
- Path outFile = Utilities.getBackupRootPath(Utilities.getLevelName(context.server())).resolve(getFileName());
-
- log.trace("Outfile is: {}", outFile);
-
- try {
- //I think I should synchronise these two next calls...
- Utilities.disableWorldSaving(context.server());
- Globals.INSTANCE.disableWatchdog = true;
-
- Globals.INSTANCE.updateTMPFSFlag(context.server());
-
- log.sendInfoAL(context, "Starting backup");
-
- Path world = Utilities.getWorldFolder(context.server());
-
- log.trace("Minecraft world is: {}", world);
-
- Files.createDirectories(outFile.getParent());
- Files.createFile(outFile);
-
- int coreCount;
-
- if (config.get().compressionCoreCountLimit <= 0) coreCount = Runtime.getRuntime().availableProcessors();
- else
- coreCount = Math.min(config.get().compressionCoreCountLimit, Runtime.getRuntime().availableProcessors());
-
- log.trace("Running compression on {} threads. Available cores: {}", coreCount, Runtime.getRuntime().availableProcessors());
-
- switch (config.get().format) {
- case ZIP -> {
- if (coreCount > 1 && !Globals.INSTANCE.disableTMPFS()) {
- log.trace("Using PARALLEL Zip Compressor. Threads: {}", coreCount);
- ParallelZipCompressor.getInstance().createArchive(world, outFile, context, coreCount);
- } else {
- log.trace("Using REGULAR Zip Compressor.");
- ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount);
- }
- }
- case BZIP2 -> ParallelBZip2Compressor.getInstance().createArchive(world, outFile, context, coreCount);
- case GZIP -> ParallelGzipCompressor.getInstance().createArchive(world, outFile, context, coreCount);
- /* case LZMA -> new AbstractTarArchiver() {
- protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException {
- return new LZMACompressorOutputStream(stream);
- }
- }.createArchive(world, outFile, context, coreCount);*/
- case TAR -> new AbstractTarArchiver().createArchive(world, outFile, context, coreCount);
- }
-
- if(context.cleanup())
- new Cleanup(context.commandSource(), Utilities.getLevelName(context.server())).call();
-
- if (config.get().broadcastBackupDone) Utilities.notifyPlayers(context.server(), "Done!");
- else log.sendInfoAL(context, "Done!");
-
- } catch (Throwable e) {
- //ExecutorService swallows exception, so I need to catch everything
- log.error("An exception occurred when trying to create new backup file!", e);
-
- if (ConfigHelper.INSTANCE.get().integrityVerificationMode.isStrict()) {
- try {
- Files.delete(outFile);
- } catch (IOException ex) {
- log.error("An exception occurred while trying go delete: {}", outFile, ex);
- }
- }
-
- if (context.initiator() == ActionInitiator.Player)
- log.sendError(context, "An exception occurred when trying to create new backup file!");
-
- throw e;
- } finally {
- Utilities.enableWorldSaving(context.server());
- Globals.INSTANCE.disableWatchdog = false;
- }
-
- return null;
- }
-
- private String getFileName() {
- return Utilities.getDateTimeFormatter().format(context.startDate()) +
- (context.comment() != null ? "#" + context.comment().replaceAll("[\\\\/:*?\"<>|#]", "") : "") +
- config.get().format.getCompleteString();
- }
-}
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnableFactory.java b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnableFactory.java
deleted file mode 100644
index 099d17c..0000000
--- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnableFactory.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * A simple backup mod for Fabric
- * Copyright (C) 2022 Szum123321
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package net.szum123321.textile_backup.core.create;
-
-import net.szum123321.textile_backup.TextileBackup;
-import net.szum123321.textile_backup.TextileLogger;
-import net.szum123321.textile_backup.config.ConfigHelper;
-import net.szum123321.textile_backup.core.Utilities;
-
-import java.time.LocalDateTime;
-import java.util.concurrent.Callable;
-
-public class MakeBackupRunnableFactory {
- private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
- private final static ConfigHelper config = ConfigHelper.INSTANCE;
-
- public static Callable create(BackupContext ctx) {
- if(config.get().broadcastBackupStart) {
- Utilities.notifyPlayers(ctx.server(),
- "Warning! Server backup will begin shortly. You may experience some lag."
- );
- } else {
- log.sendInfoAL(ctx, "Warning! Server backup will begin shortly. You may experience some lag.");
- }
-
- StringBuilder builder = new StringBuilder();
-
- builder.append("Backup started ");
-
- builder.append(ctx.initiator().getPrefix());
-
- if(ctx.startedByPlayer())
- builder.append(ctx.commandSource().getDisplayName().getString());
- else
- builder.append(ctx.initiator().getName());
-
- builder.append(" on: ");
- builder.append(Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
-
- log.info(builder.toString());
-
- if (ctx.shouldSave()) {
- log.sendInfoAL(ctx, "Saving server...");
-
- ctx.server().saveAll(true, true, false);
- }
-
- return new MakeBackupRunnable(ctx);
- }
-}
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java
index f5f6815..108c6e5 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java
@@ -23,8 +23,8 @@ import net.szum123321.textile_backup.TextileBackup;
import net.szum123321.textile_backup.TextileLogger;
import net.szum123321.textile_backup.config.ConfigHelper;
import net.szum123321.textile_backup.core.*;
-import net.szum123321.textile_backup.core.create.BackupContext;
import net.szum123321.textile_backup.core.create.BrokenFileHandler;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import net.szum123321.textile_backup.core.create.FileInputStreamSupplier;
import net.szum123321.textile_backup.core.create.InputSupplier;
import net.szum123321.textile_backup.core.digest.FileTreeHashBuilder;
@@ -44,7 +44,7 @@ import java.util.stream.Stream;
public abstract class AbstractCompressor {
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
- public void createArchive(Path inputFile, Path outputFile, BackupContext ctx, int coreLimit) throws IOException, ExecutionException, InterruptedException {
+ public void createArchive(Path inputFile, Path outputFile, ExecutableBackup ctx, int coreLimit) throws IOException, ExecutionException, InterruptedException {
Instant start = Instant.now();
BrokenFileHandler brokenFileHandler = new BrokenFileHandler(); //Basically a hashmap storing files and their respective exceptions
@@ -106,7 +106,7 @@ public abstract class AbstractCompressor {
log.sendInfoAL(ctx, "Compression took: {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now())));
}
- protected abstract OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException;
+ protected abstract OutputStream createArchiveOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) throws IOException;
protected abstract void addEntry(InputSupplier inputSupplier, OutputStream arc) throws IOException;
protected void finish(OutputStream arc) throws InterruptedException, ExecutionException, IOException {
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelZipCompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelZipCompressor.java
index 3632179..7ed67a1 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelZipCompressor.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelZipCompressor.java
@@ -21,7 +21,7 @@ package net.szum123321.textile_backup.core.create.compressors;
import net.szum123321.textile_backup.TextileBackup;
import net.szum123321.textile_backup.TextileLogger;
import net.szum123321.textile_backup.core.NoSpaceLeftOnDeviceException;
-import net.szum123321.textile_backup.core.create.BackupContext;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import net.szum123321.textile_backup.core.create.InputSupplier;
import org.apache.commons.compress.archivers.zip.*;
@@ -61,7 +61,7 @@ public class ParallelZipCompressor extends ZipCompressor {
}
@Override
- protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) {
+ protected OutputStream createArchiveOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) {
scatterZipCreator = new ParallelScatterZipCreator(Executors.newFixedThreadPool(coreLimit));
return super.createArchiveOutputStream(stream, ctx, coreLimit);
}
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ZipCompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/ZipCompressor.java
index 5a39bab..a1b224b 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ZipCompressor.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/ZipCompressor.java
@@ -20,7 +20,7 @@ package net.szum123321.textile_backup.core.create.compressors;
import net.szum123321.textile_backup.config.ConfigHelper;
import net.szum123321.textile_backup.core.Utilities;
-import net.szum123321.textile_backup.core.create.BackupContext;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import net.szum123321.textile_backup.core.create.InputSupplier;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
@@ -43,7 +43,7 @@ public class ZipCompressor extends AbstractCompressor {
}
@Override
- protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) {
+ protected OutputStream createArchiveOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) {
ZipArchiveOutputStream arc = new ZipArchiveOutputStream(stream);
arc.setMethod(ZipArchiveOutputStream.DEFLATED);
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/AbstractTarArchiver.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/AbstractTarArchiver.java
index 4ae84a3..52e86e5 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/AbstractTarArchiver.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/AbstractTarArchiver.java
@@ -18,7 +18,7 @@
package net.szum123321.textile_backup.core.create.compressors.tar;
-import net.szum123321.textile_backup.core.create.BackupContext;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import net.szum123321.textile_backup.core.create.compressors.AbstractCompressor;
import net.szum123321.textile_backup.core.create.InputSupplier;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -28,12 +28,12 @@ import org.apache.commons.compress.utils.IOUtils;
import java.io.*;
public class AbstractTarArchiver extends AbstractCompressor {
- protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException {
+ protected OutputStream getCompressorOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) throws IOException {
return stream;
}
@Override
- protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException {
+ protected OutputStream createArchiveOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) throws IOException {
TarArchiveOutputStream tar = new TarArchiveOutputStream(getCompressorOutputStream(stream, ctx, coreLimit));
tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java
index 76d96fe..2bd2840 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java
@@ -18,7 +18,7 @@
package net.szum123321.textile_backup.core.create.compressors.tar;
-import net.szum123321.textile_backup.core.create.BackupContext;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import org.at4j.comp.bzip2.BZip2OutputStream;
import org.at4j.comp.bzip2.BZip2OutputStreamSettings;
@@ -30,7 +30,7 @@ public class ParallelBZip2Compressor extends AbstractTarArchiver {
}
@Override
- protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException {
+ protected OutputStream getCompressorOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) throws IOException {
return new BZip2OutputStream(stream, new BZip2OutputStreamSettings().setNumberOfEncoderThreads(coreLimit));
}
}
\ No newline at end of file
diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java
index 0a59638..94b9da6 100644
--- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java
+++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java
@@ -18,7 +18,7 @@
package net.szum123321.textile_backup.core.create.compressors.tar;
-import net.szum123321.textile_backup.core.create.BackupContext;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import org.anarres.parallelgzip.ParallelGZIPOutputStream;
import java.io.*;
@@ -33,7 +33,7 @@ public class ParallelGzipCompressor extends AbstractTarArchiver {
}
@Override
- protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException {
+ protected OutputStream getCompressorOutputStream(OutputStream stream, ExecutableBackup ctx, int coreLimit) throws IOException {
executorService = Executors.newFixedThreadPool(coreLimit);
return new ParallelGZIPOutputStream(stream, executorService);
diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreBackupRunnable.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreBackupRunnable.java
index 6f705eb..b3520fc 100644
--- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreBackupRunnable.java
+++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreBackupRunnable.java
@@ -26,8 +26,7 @@ import net.szum123321.textile_backup.config.ConfigPOJO;
import net.szum123321.textile_backup.core.ActionInitiator;
import net.szum123321.textile_backup.core.CompressionStatus;
import net.szum123321.textile_backup.core.Utilities;
-import net.szum123321.textile_backup.core.create.BackupContext;
-import net.szum123321.textile_backup.core.create.MakeBackupRunnableFactory;
+import net.szum123321.textile_backup.core.create.ExecutableBackup;
import net.szum123321.textile_backup.core.restore.decompressors.GenericTarDecompressor;
import net.szum123321.textile_backup.core.restore.decompressors.ZipDecompressor;
import net.szum123321.textile_backup.mixin.MinecraftServerSessionAccessor;
@@ -78,20 +77,19 @@ public class RestoreBackupRunnable implements Runnable {
ctx.server().getThread().join(); //wait for server thread to die and save all its state
if(config.get().backupOldWorlds) {
- return MakeBackupRunnableFactory.create (
- BackupContext.Builder
+ return ExecutableBackup.Builder
.newBackupContextBuilder()
.setServer(ctx.server())
.setInitiator(ActionInitiator.Restore)
- .dontCleanup()
+ .noCleanup()
.setComment("Old_World" + (ctx.comment() != null ? "_" + ctx.comment() : ""))
- .build()
- ).call();
+ .announce()
+ .build().call();
}
-
return null;
});
+ //run the thread.
new Thread(waitForShutdown, "Server shutdown wait thread").start();
try {
@@ -106,7 +104,7 @@ public class RestoreBackupRunnable implements Runnable {
log.info("Waiting for server to fully terminate...");
- //locks until the backup is finished
+ //locks until the backup is finished and the server is dead
waitForShutdown.get();
Optional errorMsg;
@@ -127,8 +125,8 @@ public class RestoreBackupRunnable implements Runnable {
if (errorMsg.isEmpty()) log.info("Backup valid. Restoring");
else log.info("Backup is damaged, but verification is disabled [{}]. Restoring", errorMsg.get());
- ((MinecraftServerSessionAccessor) ctx.server())
- .getSession().close();
+ //Disables write lock to override world file
+ ((MinecraftServerSessionAccessor) ctx.server()).getSession().close();
Utilities.deleteDirectory(worldFile);
Files.move(tmp, worldFile);