From 59c691bd591ee6d400c3deb715a5da544bded0bf Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:15:59 +0100 Subject: [PATCH 01/52] Dependency update + version bump --- gradle.properties | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index f3bec91..7ffa42c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,14 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G -minecraft_version=1.16.3 -yarn_mappings=1.16.3+build.47 -loader_version=0.10.5+build.213 +minecraft_version=1.16.4 +yarn_mappings=1.16.4+build.7 +loader_version=0.10.8 #Fabric api -fabric_version=0.24.3+build.414-1.16 +fabric_version=0.26.3+1.16 # Mod Properties -mod_version = 2.0.2 +mod_version = 2.1.0 maven_group = net.szum123321 archives_base_name = textile_backup \ No newline at end of file From ccd87ee942693560cc61f7a0e4cac039da21a795 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:16:34 +0100 Subject: [PATCH 02/52] Added contributors list --- src/main/resources/fabric.mod.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a601935..aa800fb 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -8,6 +8,12 @@ "authors": [ "Szum123321" ], + "contributors": [ + "1a2s3d4f1", + "pm709", + "Harveykang", + "66Leo66" + ], "contact": { "homepage": "https://www.curseforge.com/minecraft/mc-mods/textile-backup", "issues": "https://github.com/Szum123321/textile_backup/issues", From ead057d916b7e1ab2c6638e08905e568c99cfdd0 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:17:39 +0100 Subject: [PATCH 03/52] Added custom thread names --- .../textile_backup/core/restore/AwaitThread.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java b/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java index 27bb8cc..0783c65 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java @@ -20,14 +20,20 @@ package net.szum123321.textile_backup.core.restore; import net.szum123321.textile_backup.Statics; +import java.util.concurrent.atomic.AtomicInteger; + /* This thread waits some amount of time and then starts a new, independent thread */ public class AwaitThread extends Thread { + private final static AtomicInteger threadCounter = new AtomicInteger(0); + private final int delay; + private final int thisThreadId = threadCounter.getAndIncrement(); private final Runnable taskRunnable; public AwaitThread(int delay, Runnable taskRunnable) { + this.setName("Textile Backup await thread nr. " + thisThreadId); this.delay = delay; this.taskRunnable = taskRunnable; } @@ -49,6 +55,6 @@ public class AwaitThread extends Thread { But still it's farewell And maybe we'll come back */ - new Thread(taskRunnable).start(); + new Thread(taskRunnable, "Textile Backup restore thread nr. " + thisThreadId).start(); } } From 2a211065a39ec603ad1b9f532b686bec27a44c4c Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:18:35 +0100 Subject: [PATCH 04/52] Solves #48 --- .../core/create/BackupHelper.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index 6facc0f..3c015eb 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -18,7 +18,10 @@ package net.szum123321.textile_backup.core.create; +import net.minecraft.network.MessageType; import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.MutableText; +import net.minecraft.util.Util; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.Utilities; import org.apache.commons.io.FileUtils; @@ -29,10 +32,13 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; public class BackupHelper { public static Runnable create(BackupContext ctx) { + notifyPlayers(ctx); + StringBuilder builder = new StringBuilder(); builder.append("Backup started "); @@ -62,6 +68,20 @@ public class BackupHelper { return new MakeBackupRunnable(ctx); } + private static void notifyPlayers(BackupContext ctx) { + MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); + message.append("Warning! Server backup will begin shortly. You may experience some lag."); + + UUID uuid; + + if(ctx.getCommandSource().getEntity() != null) + uuid = ctx.getCommandSource().getEntity().getUuid(); + else + uuid = Util.NIL_UUID; + + ctx.getServer().getPlayerManager().broadcastChatMessage(message, MessageType.GAME_INFO, uuid); + } + public static int executeFileLimit(ServerCommandSource ctx, String worldName) { File root = Utilities.getBackupRootPath(worldName); AtomicInteger deletedFiles = new AtomicInteger(); From 335ab845cf14f4392adf003ed2119aaa5e3876c5 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:19:27 +0100 Subject: [PATCH 05/52] Added getPrefix method, changed prefixText from Text to MutableText --- .../textile_backup/core/CustomLogger.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java index 7bd7daf..44b5977 100644 --- a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java +++ b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java @@ -21,7 +21,7 @@ package net.szum123321.textile_backup.core; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; +import net.minecraft.text.MutableText; import net.minecraft.util.Formatting; import net.szum123321.textile_backup.core.create.BackupContext; import org.apache.logging.log4j.Level; @@ -32,7 +32,7 @@ import org.apache.logging.log4j.message.ParameterizedMessageFactory; import org.apache.logging.log4j.spi.StandardLevel; /* - This is practically just a copy-pate of Cotton's ModLogger with few changes + This is practically just a copy-pate of Cotton's ModLogger with a few changes */ public class CustomLogger { private final boolean isDev = FabricLoader.getInstance().isDevelopmentEnvironment(); @@ -41,7 +41,7 @@ public class CustomLogger { private final Logger logger; private final String prefix; - private final Text prefixText; + private final MutableText prefixText; public CustomLogger(String name, String prefix) { this.messageFactory = ParameterizedMessageFactory.INSTANCE; @@ -50,6 +50,10 @@ public class CustomLogger { this.prefixText = new LiteralText(this.prefix).formatted(Formatting.AQUA); } + public MutableText getPrefixText() { + return prefixText; + } + public void log(Level level, String msg, Object... data) { logger.log(level, prefix + msg, data); } @@ -117,14 +121,14 @@ public class CustomLogger { sendToPlayer(Level.INFO, source, msg, args); } - public void sendError(ServerCommandSource source, String msg, Object... args) { - sendToPlayer(Level.ERROR, source, msg, args); - } - public void sendInfo(BackupContext context, String msg, Object... args) { sendInfo(context.getCommandSource(), msg, args); } + public void sendError(ServerCommandSource source, String msg, Object... args) { + sendToPlayer(Level.ERROR, source, msg, args); + } + public void sendError(BackupContext context, String msg, Object... args) { sendError(context.getCommandSource(), msg, args); } From 0ef89c2a88031088bebe029db143a30c427d0fb0 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:20:21 +0100 Subject: [PATCH 06/52] Added missing dot --- .../textile_backup/commands/restore/KillRestoreCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java index 12081a3..3824fba 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java @@ -30,7 +30,7 @@ public class KillRestoreCommand { if(Statics.restoreAwaitThread != null && Statics.restoreAwaitThread.isAlive()) { Statics.restoreAwaitThread.interrupt(); Statics.globalShutdownBackupFlag.set(true); - Statics.LOGGER.sendInfo(ctx.getSource(), "Backup restoration successfully stopped"); + Statics.LOGGER.sendInfo(ctx.getSource(), "Backup restoration successfully stopped."); Statics.LOGGER.info("{} cancelled backup restoration.", ctx.getSource().getEntity() != null ? "Player: " + ctx.getSource().getName() : "SERVER" From aac63d45ac8f071ed2a7804f68f2316999649f84 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:25:16 +0100 Subject: [PATCH 07/52] Partial redesign of RestoreHelper. It now uses RestoreableFile everywhere. RestoreableFile is now comparable --- .../core/restore/RestoreHelper.java | 64 ++++++++++++++----- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index 9fada41..4a91416 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -18,10 +18,14 @@ package net.szum123321.textile_backup.core.restore; +import net.minecraft.network.MessageType; import net.minecraft.server.MinecraftServer; -import net.minecraft.text.LiteralText; +import net.minecraft.text.MutableText; +import net.minecraft.util.Util; +import net.szum123321.textile_backup.ConfigHandler; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.Utilities; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.time.LocalDateTime; @@ -30,24 +34,28 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; public class RestoreHelper { - public static Optional findFileAndLockIfPresent(LocalDateTime backupTime, MinecraftServer server) { + public static Optional findFileAndLockIfPresent(LocalDateTime backupTime, MinecraftServer server) { File root = Utilities.getBackupRootPath(Utilities.getLevelName(server)); - Optional optionalFile = Arrays.stream(root.listFiles()) - .filter(Utilities::isValidBackup) - .filter(file -> Utilities.getFileCreationTime(file).get().equals(backupTime)) + Optional optionalFile = Arrays.stream(root.listFiles()) + .map(RestoreableFile::newInstance) + .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) + .filter(rf -> rf.getCreationTime().equals(backupTime)) .findFirst(); - optionalFile.ifPresent(file -> Statics.untouchableFile = file); + optionalFile.ifPresent(file -> Statics.untouchableFile = file.getFile()); return optionalFile; } - public static AwaitThread create(File backupFile, MinecraftServer server, String comment) { - server.getPlayerManager().getPlayerList() - .forEach(serverPlayerEntity -> serverPlayerEntity.sendMessage(new LiteralText("Warning! The server is going to shut down in " + Statics.CONFIG.restoreDelay + " seconds!"), false)); + public static AwaitThread create(RestoreableFile backupFile, MinecraftServer server, String comment) { + MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); + message.append("Warning! The server is going to shut down in " + Statics.CONFIG.restoreDelay + " seconds!"); + + server.getPlayerManager().broadcastChatMessage(message, MessageType.GAME_INFO, Util.NIL_UUID); Statics.globalShutdownBackupFlag.set(false); @@ -62,17 +70,22 @@ public class RestoreHelper { return Arrays.stream(root.listFiles()) .filter(Utilities::isValidBackup) - .map(RestoreableFile::new) + .map(RestoreableFile::newInstance) + .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) .collect(Collectors.toList()); } - public static class RestoreableFile { + public static class RestoreableFile implements Comparable { + private final File file; + private final ConfigHandler.ArchiveFormat archiveFormat; private final LocalDateTime creationTime; private final String comment; - protected RestoreableFile(File file) { - String extension = Utilities.getFileExtension(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file extention")).getString(); - this.creationTime = Utilities.getFileCreationTime(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file creation time.")); + private RestoreableFile(File file) throws NoSuchElementException { + this.file = file; + archiveFormat = Utilities.getArchiveExtension(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file extension!")); + String extension = archiveFormat.getString(); + creationTime = Utilities.getFileCreationTime(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file creation time!")); final String filename = file.getName(); @@ -83,6 +96,22 @@ public class RestoreHelper { } } + public static Optional newInstance(File file) { + try { + return Optional.of(new RestoreableFile(file)); + } catch (NoSuchElementException ignored) {} + + return Optional.empty(); + } + + public File getFile() { + return file; + } + + public ConfigHandler.ArchiveFormat getArchiveFormat() { + return archiveFormat; + } + public LocalDateTime getCreationTime() { return creationTime; } @@ -91,8 +120,13 @@ public class RestoreHelper { return comment; } + @Override + public int compareTo(@NotNull RestoreHelper.RestoreableFile o) { + return creationTime.compareTo(o.creationTime); + } + public String toString() { return this.getCreationTime().format(Statics.defaultDateTimeFormatter) + (comment != null ? "#" + comment : ""); } } -} +} \ No newline at end of file From a5114b49cc569cb2a0c521696ac99fede3f02f3b Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:27:26 +0100 Subject: [PATCH 08/52] Renamed getFileExtension -> getArchiveExtension Some stylistic improvements --- .../textile_backup/core/Utilities.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/Utilities.java b/src/main/java/net/szum123321/textile_backup/core/Utilities.java index fcefdc4..a23a0ab 100644 --- a/src/main/java/net/szum123321/textile_backup/core/Utilities.java +++ b/src/main/java/net/szum123321/textile_backup/core/Utilities.java @@ -32,10 +32,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.FileTime; -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.ZoneOffset; +import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Optional; @@ -52,17 +49,15 @@ public class Utilities { public static void disableWorldSaving(MinecraftServer server) { for (ServerWorld serverWorld : server.getWorlds()) { - if (serverWorld != null && !serverWorld.savingDisabled) { + if (serverWorld != null && !serverWorld.savingDisabled) serverWorld.savingDisabled = true; - } } } public static void enableWorldSaving(MinecraftServer server) { for (ServerWorld serverWorld : server.getWorlds()) { - if (serverWorld != null && serverWorld.savingDisabled) { + if (serverWorld != null && serverWorld.savingDisabled) serverWorld.savingDisabled = false; - } } } @@ -86,7 +81,7 @@ public class Utilities { return false; } - public static Optional getFileExtension(String fileName) { + public static Optional getArchiveExtension(String fileName) { String[] parts = fileName.split("\\."); switch (parts[parts.length - 1]) { @@ -104,15 +99,15 @@ public class Utilities { } } - public static Optional getFileExtension(File f) { - return getFileExtension(f.getName()); + public static Optional getArchiveExtension(File f) { + return getArchiveExtension(f.getName()); } public static Optional getFileCreationTime(File file) { LocalDateTime creationTime = null; - if(getFileExtension(file).isPresent()) { - String fileExtension = getFileExtension(file).get().getString(); + if(getArchiveExtension(file).isPresent()) { + String fileExtension = getArchiveExtension(file).get().getString(); try { creationTime = LocalDateTime.from( @@ -157,10 +152,12 @@ public class Utilities { } public static boolean isValidBackup(File f) { - return getFileExtension(f).isPresent() && getFileCreationTime(f).isPresent() && isFileOk(f); + return getArchiveExtension(f).isPresent() && getFileCreationTime(f).isPresent() && isFileOk(f); } - public static boolean isFileOk(File f) {return f.exists() && f.isFile(); } + public static boolean isFileOk(File f) { + return f.exists() && f.isFile(); + } public static DateTimeFormatter getDateTimeFormatter() { return DateTimeFormatter.ofPattern(Statics.CONFIG.dateTimeFormat); From 3b522e2881a4f9924b3c028c36ecd0fc8c4fc9dc Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:32:22 +0100 Subject: [PATCH 09/52] Redesign of Compression an archival logic. Added ZipCompressor Permanently fixed java.util.concurrent.ExecutionException: java.io.IOException: No space left on device. --- .../szum123321/textile_backup/Statics.java | 2 + .../textile_backup/TextileBackup.java | 9 +++ .../textile_backup/core/Utilities.java | 22 ++++++ .../core/create/MakeBackupRunnable.java | 16 +++-- ...ompressor.java => AbstractCompressor.java} | 41 +++++------ .../compressors/ParallelZipCompressor.java | 71 +++++++------------ .../create/compressors/ZipCompressor.java | 70 ++++++++++++++++++ .../compressors/tar/AbstractTarArchiver.java | 56 +++++++++++++++ .../compressors/{ => tar}/LZMACompressor.java | 13 ++-- .../{ => tar}/ParallelBZip2Compressor.java | 13 ++-- .../{ => tar}/ParallelGzipCompressor.java | 22 ++++-- 11 files changed, 246 insertions(+), 89 deletions(-) rename src/main/java/net/szum123321/textile_backup/core/create/compressors/{AbstractTarCompressor.java => AbstractCompressor.java} (65%) create mode 100644 src/main/java/net/szum123321/textile_backup/core/create/compressors/ZipCompressor.java create mode 100644 src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/AbstractTarArchiver.java rename src/main/java/net/szum123321/textile_backup/core/create/compressors/{ => tar}/LZMACompressor.java (69%) rename src/main/java/net/szum123321/textile_backup/core/create/compressors/{ => tar}/ParallelBZip2Compressor.java (65%) rename src/main/java/net/szum123321/textile_backup/core/create/compressors/{ => tar}/ParallelGzipCompressor.java (54%) diff --git a/src/main/java/net/szum123321/textile_backup/Statics.java b/src/main/java/net/szum123321/textile_backup/Statics.java index 2f8c50a..995a40c 100644 --- a/src/main/java/net/szum123321/textile_backup/Statics.java +++ b/src/main/java/net/szum123321/textile_backup/Statics.java @@ -42,4 +42,6 @@ public class Statics { public static final AtomicBoolean globalShutdownBackupFlag = new AtomicBoolean(true); public static AwaitThread restoreAwaitThread = null; public static File untouchableFile; + + public static boolean tmpAvailable; } diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index 1e675b3..a8e5fcd 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -52,6 +52,15 @@ public class TextileBackup implements ModInitializer { System.exit(1); } + if(Statics.CONFIG.format == ConfigHandler.ArchiveFormat.ZIP) { + Statics.tmpAvailable = Utilities.isTmpAvailable(); + if(!Statics.tmpAvailable) { + Statics.LOGGER.warn("WARNING! It seems like the temporary folder is not accessible on this system!\n" + + "This will cause problems with multithreaded zip compression, so a normal one will be used instead.\n" + + "For more info please read: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"); + } + } + if(Statics.CONFIG.backupInterval > 0) ServerTickEvents.END_SERVER_TICK.register(Statics.scheduler::tick); diff --git a/src/main/java/net/szum123321/textile_backup/core/Utilities.java b/src/main/java/net/szum123321/textile_backup/core/Utilities.java index a23a0ab..39898f8 100644 --- a/src/main/java/net/szum123321/textile_backup/core/Utilities.java +++ b/src/main/java/net/szum123321/textile_backup/core/Utilities.java @@ -46,6 +46,28 @@ public class Utilities { .getSession() .getWorldDirectory(RegistryKey.of(Registry.DIMENSION, DimensionType.OVERWORLD_REGISTRY_KEY.getValue())); } + + public static File getBackupRootPath(String worldName) { + File path = new File(Statics.CONFIG.path).getAbsoluteFile(); + + if (Statics.CONFIG.perWorldBackup) + path = path.toPath().resolve(worldName).toFile(); + + if (!path.exists()) { + path.mkdirs(); + } + + return path; + } + + public static boolean isTmpAvailable() { + try { + File tmp = File.createTempFile("textile_backup_tmp_test", String.valueOf(Instant.now().getEpochSecond())); + return tmp.delete(); + } catch (IOException ignored) {} + + return false; + } public static void disableWorldSaving(MinecraftServer server) { for (ServerWorld serverWorld : server.getWorlds()) { 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 index fc0e049..0455c21 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -21,6 +21,10 @@ package net.szum123321.textile_backup.core.create; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.create.compressors.*; import net.szum123321.textile_backup.core.Utilities; +import net.szum123321.textile_backup.core.create.compressors.tar.LZMACompressor; +import net.szum123321.textile_backup.core.create.compressors.tar.ParallelBZip2Compressor; +import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor; +import net.szum123321.textile_backup.core.create.compressors.ParallelZipCompressor; import java.io.File; import java.io.IOException; @@ -70,12 +74,16 @@ public class MakeBackupRunnable implements Runnable { coreCount = Math.min(Statics.CONFIG.compressionCoreCountLimit, Runtime.getRuntime().availableProcessors()); } - Statics.LOGGER.trace("Running compression on {} threads. Available cores = {}", coreCount, Runtime.getRuntime().availableProcessors()); + Statics.LOGGER.trace("Running compression on {} threads. Available cores: {}", coreCount, Runtime.getRuntime().availableProcessors()); switch (Statics.CONFIG.format) { - case ZIP: - ParallelZipCompressor.createArchive(world, outFile, context, coreCount); + case ZIP: { + if(Statics.tmpAvailable && coreCount > 1) + ParallelZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); + else + ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); break; + } case BZIP2: ParallelBZip2Compressor.getInstance().createArchive(world, outFile, context, coreCount); @@ -93,7 +101,7 @@ public class MakeBackupRunnable implements Runnable { Statics.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", Statics.CONFIG.format); Statics.LOGGER.sendError(context.getCommandSource(), "Error! No correct compression format specified! Using default compressor!"); - ParallelZipCompressor.createArchive(world, outFile, context, coreCount); + ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); break; } diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractTarCompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java similarity index 65% rename from src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractTarCompressor.java rename to src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java index 06bea66..b75a813 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractTarCompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/AbstractCompressor.java @@ -21,53 +21,54 @@ package net.szum123321.textile_backup.core.create.compressors; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.BackupContext; -import org.apache.commons.compress.archivers.ArchiveEntry; -import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; -import org.apache.commons.compress.utils.IOUtils; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.time.Duration; import java.time.Instant; +import java.util.concurrent.ExecutionException; -public abstract class AbstractTarCompressor { - protected abstract OutputStream openCompressorStream(OutputStream outputStream, int coreCountLimit) throws IOException; - +public abstract class AbstractCompressor { public void createArchive(File inputFile, File outputFile, BackupContext ctx, int coreLimit) { - Statics.LOGGER.sendInfo(ctx, "Starting compression..."); - Instant start = Instant.now(); try (FileOutputStream outStream = new FileOutputStream(outputFile); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outStream); - OutputStream compressorOutputStream = openCompressorStream(bufferedOutputStream, coreLimit); - TarArchiveOutputStream arc = new TarArchiveOutputStream(compressorOutputStream)) { - arc.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); - arc.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX); + OutputStream arc = createArchiveOutputStream(bufferedOutputStream, ctx, coreLimit)) { Files.walk(inputFile.toPath()) .filter(path -> !Utilities.isBlacklisted(inputFile.toPath().relativize(path))) .map(Path::toFile) .filter(File::isFile) .forEach(file -> { - try (FileInputStream fileInputStream = new FileInputStream(file)){ - ArchiveEntry entry = arc.createArchiveEntry(file, inputFile.toPath().relativize(file.toPath()).toString()); - arc.putArchiveEntry(entry); - - IOUtils.copy(fileInputStream, arc); - - arc.closeArchiveEntry(); + try { + addEntry(file, inputFile.toPath().relativize(file.toPath()).toString(), arc); } catch (IOException e) { Statics.LOGGER.error("An exception occurred while trying to compress: {}", file.getName(), e); Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); } }); - } catch (IOException e) { + + finish(arc); + } catch (IOException | InterruptedException | ExecutionException e) { Statics.LOGGER.error("An exception occurred!", e); Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); } + close(); + Statics.LOGGER.sendInfo(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 void addEntry(File file, String entryName, OutputStream arc) throws IOException; + + protected void finish(OutputStream arc) throws InterruptedException, ExecutionException, IOException { + ;//Basically this function is only needed for the ParallelZipCompressor to write out ParallelScatterZipCreator + } + + protected void close() { + ;//Same as above, just for ParallelGzipCompressor to shutdown ExecutorService + } } 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 6923424..b66bd8e 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 @@ -19,17 +19,11 @@ package net.szum123321.textile_backup.core.create.compressors; import net.szum123321.textile_backup.Statics; -import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.BackupContext; import org.apache.commons.compress.archivers.zip.*; import org.apache.commons.compress.parallel.InputStreamSupplier; import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; import java.util.concurrent.*; import java.util.zip.ZipEntry; @@ -39,53 +33,40 @@ import java.util.zip.ZipEntry; answer by: https://stackoverflow.com/users/2987755/dkb */ -public class ParallelZipCompressor { - public static void createArchive(File inputFile, File outputFile, BackupContext ctx, int coreLimit) { - Statics.LOGGER.sendInfo(ctx, "Starting compression..."); +public class ParallelZipCompressor extends ZipCompressor { + private ParallelScatterZipCreator scatterZipCreator; - Instant start = Instant.now(); + public static ParallelZipCompressor getInstance() { + return new ParallelZipCompressor(); + } - Path rootPath = inputFile.toPath(); + @Override + protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { + scatterZipCreator = new ParallelScatterZipCreator(Executors.newFixedThreadPool(coreLimit)); + return super.createArchiveOutputStream(stream, ctx, coreLimit); + } - try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile); - BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); - ZipArchiveOutputStream arc = new ZipArchiveOutputStream(bufferedOutputStream)) { + @Override + protected void addEntry(File file, String entryName, OutputStream arc) throws IOException { + ZipArchiveEntry entry = (ZipArchiveEntry)((ZipArchiveOutputStream)arc).createArchiveEntry(file, entryName); - ParallelScatterZipCreator scatterZipCreator = new ParallelScatterZipCreator(Executors.newFixedThreadPool(coreLimit)); + if(ZipCompressor.isDotDat(file.getName())) + entry.setMethod(ZipEntry.STORED); + else + entry.setMethod(ZipEntry.DEFLATED); - arc.setMethod(ZipArchiveOutputStream.DEFLATED); - arc.setUseZip64(Zip64Mode.AsNeeded); - arc.setLevel(Statics.CONFIG.compression); - arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now())); + entry.setTime(System.currentTimeMillis()); - Files.walk(inputFile.toPath()) - .filter(path -> !Utilities.isBlacklisted(inputFile.toPath().relativize(path))) - .map(Path::toFile) - .filter(File::isFile) - .forEach(file -> { - try { //IOException gets thrown only when arc is closed - ZipArchiveEntry entry = (ZipArchiveEntry)arc.createArchiveEntry(file, rootPath.relativize(file.toPath()).toString()); + scatterZipCreator.addArchiveEntry(entry, new FileInputStreamSupplier(file)); + } - entry.setMethod(ZipEntry.DEFLATED); - scatterZipCreator.addArchiveEntry(entry, new FileInputStreamSupplier(file)); - } catch (IOException e) { - Statics.LOGGER.error("An exception occurred while trying to compress: {}", file.getName(), e); - Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); - } - }); - - scatterZipCreator.writeTo(arc); - } catch (IOException | InterruptedException | ExecutionException e) { - Statics.LOGGER.error("An exception occurred!", e); - Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); - } - - Statics.LOGGER.sendInfo(ctx, "Compression took: {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now()))); + @Override + protected void finish(OutputStream arc) throws InterruptedException, ExecutionException, IOException { + scatterZipCreator.writeTo((ZipArchiveOutputStream) arc); } static class FileInputStreamSupplier implements InputStreamSupplier { private final File sourceFile; - private InputStream stream; FileInputStreamSupplier(File sourceFile) { this.sourceFile = sourceFile; @@ -93,12 +74,12 @@ public class ParallelZipCompressor { public InputStream get() { try { - stream = new BufferedInputStream(new FileInputStream(sourceFile)); + return new FileInputStream(sourceFile); } catch (IOException e) { - Statics.LOGGER.error("An exception occurred while trying to create input stream!", e); + Statics.LOGGER.error("An exception occurred while trying to create input stream from file: {}!", sourceFile.getName(), e); } - return stream; + return null; } } } 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 new file mode 100644 index 0000000..c53fc52 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/ZipCompressor.java @@ -0,0 +1,70 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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.compressors; + +import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.Utilities; +import net.szum123321.textile_backup.core.create.BackupContext; +import org.apache.commons.compress.archivers.zip.Zip64Mode; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.utils.IOUtils; + +import java.io.*; +import java.time.LocalDateTime; + +public class ZipCompressor extends AbstractCompressor { + public static ZipCompressor getInstance() { + return new ZipCompressor(); + } + + @Override + protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { + ZipArchiveOutputStream arc = new ZipArchiveOutputStream(stream); + + arc.setMethod(ZipArchiveOutputStream.DEFLATED); + arc.setUseZip64(Zip64Mode.AsNeeded); + arc.setLevel(Statics.CONFIG.compression); + arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now())); + + return arc; + } + + @Override + protected void addEntry(File file, String entryName, OutputStream arc) throws IOException { + + try (FileInputStream fileInputStream = new FileInputStream(file)){ + ZipArchiveEntry entry = (ZipArchiveEntry)((ZipArchiveOutputStream)arc).createArchiveEntry(file, entryName); + + if(isDotDat(file.getName())) + entry.setMethod(ZipArchiveOutputStream.STORED); + + ((ZipArchiveOutputStream)arc).putArchiveEntry(entry); + + IOUtils.copy(fileInputStream, arc); + + ((ZipArchiveOutputStream)arc).closeArchiveEntry(); + } + } + + protected static boolean isDotDat(String filename) { + String[] arr = filename.split("\\."); + return arr[arr.length - 1].contains("dat"); //includes dat_old + } +} 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 new file mode 100644 index 0000000..e942f43 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/AbstractTarArchiver.java @@ -0,0 +1,56 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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.compressors.tar; + +import net.szum123321.textile_backup.core.create.BackupContext; +import net.szum123321.textile_backup.core.create.compressors.AbstractCompressor; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.utils.IOUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; + +public abstract class AbstractTarArchiver extends AbstractCompressor { + + protected abstract OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException; + + @Override + protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { + TarArchiveOutputStream tar = new TarArchiveOutputStream(getCompressorOutputStream(stream, ctx, coreLimit)); + tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); + tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX); + + return tar; + } + + @Override + protected void addEntry(File file, String entryName, OutputStream arc) throws IOException { + try (FileInputStream fileInputStream = new FileInputStream(file)){ + TarArchiveEntry entry = (TarArchiveEntry)((TarArchiveOutputStream) arc).createArchiveEntry(file, entryName); + ((TarArchiveOutputStream)arc).putArchiveEntry(entry); + + IOUtils.copy(fileInputStream, arc); + + ((TarArchiveOutputStream)arc).closeArchiveEntry(); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/LZMACompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java similarity index 69% rename from src/main/java/net/szum123321/textile_backup/core/create/compressors/LZMACompressor.java rename to src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java index 60e535b..15879b4 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/LZMACompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java @@ -16,21 +16,20 @@ * along with this program. If not, see . */ -package net.szum123321.textile_backup.core.create.compressors; +package net.szum123321.textile_backup.core.create.compressors.tar; +import net.szum123321.textile_backup.core.create.BackupContext; import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream; import java.io.*; -public class LZMACompressor extends AbstractTarCompressor { - private static final LZMACompressor INSTANCE = new LZMACompressor(); - +public class LZMACompressor extends AbstractTarArchiver { public static LZMACompressor getInstance() { - return INSTANCE; + return new LZMACompressor(); } @Override - protected OutputStream openCompressorStream(OutputStream outputStream, int coreCountLimit) throws IOException { - return new XZCompressorOutputStream(outputStream); + protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { + return new XZCompressorOutputStream(stream); } } \ No newline at end of file diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelBZip2Compressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java similarity index 65% rename from src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelBZip2Compressor.java rename to src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java index b938f3f..e3e9e05 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelBZip2Compressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelBZip2Compressor.java @@ -16,22 +16,21 @@ * along with this program. If not, see . */ -package net.szum123321.textile_backup.core.create.compressors; +package net.szum123321.textile_backup.core.create.compressors.tar; +import net.szum123321.textile_backup.core.create.BackupContext; import org.at4j.comp.bzip2.BZip2OutputStream; import org.at4j.comp.bzip2.BZip2OutputStreamSettings; import java.io.*; -public class ParallelBZip2Compressor extends AbstractTarCompressor { - private static final ParallelBZip2Compressor INSTANCE = new ParallelBZip2Compressor(); - +public class ParallelBZip2Compressor extends AbstractTarArchiver { public static ParallelBZip2Compressor getInstance() { - return INSTANCE; + return new ParallelBZip2Compressor(); } @Override - protected OutputStream openCompressorStream(OutputStream outputStream, int coreCountLimit) throws IOException { - return new BZip2OutputStream(outputStream, new BZip2OutputStreamSettings().setNumberOfEncoderThreads(coreCountLimit)); + protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext 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/ParallelGzipCompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java similarity index 54% rename from src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelGzipCompressor.java rename to src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java index 5ba0f3a..983d607 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/ParallelGzipCompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/ParallelGzipCompressor.java @@ -16,22 +16,32 @@ * along with this program. If not, see . */ -package net.szum123321.textile_backup.core.create.compressors; +package net.szum123321.textile_backup.core.create.compressors.tar; +import net.szum123321.textile_backup.core.create.BackupContext; import org.anarres.parallelgzip.ParallelGZIPOutputStream; import java.io.*; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -public class ParallelGzipCompressor extends AbstractTarCompressor { - private static final ParallelGzipCompressor INSTANCE = new ParallelGzipCompressor(); +public class ParallelGzipCompressor extends AbstractTarArchiver { + private ExecutorService executorService; public static ParallelGzipCompressor getInstance() { - return INSTANCE; + return new ParallelGzipCompressor(); } @Override - protected OutputStream openCompressorStream(OutputStream outputStream, int coreCountLimit) throws IOException { - return new ParallelGZIPOutputStream(outputStream, Executors.newFixedThreadPool(coreCountLimit)); + protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { + executorService = Executors.newFixedThreadPool(coreLimit); + + return new ParallelGZIPOutputStream(stream, executorService); + } + + @Override + protected void close() { + //it seems like ParallelGZIPOutputStream doesn't shut down its ExecutorService, so to not leave garbage I shutdown it + executorService.shutdown(); } } From 5d7aaf1938661be5b26c6a0a81ff6b7239020649 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:32:58 +0100 Subject: [PATCH 10/52] Added some more info to Config --- src/main/java/net/szum123321/textile_backup/ConfigHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java index a9e8d89..b7eeca6 100644 --- a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java +++ b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java @@ -71,7 +71,8 @@ public class ConfigHandler { @Comment("\nCompression level \n0 - 9\n Only affects zip compression.\n") public int compression = 7; - @Comment("\nLimit how many cores can be used for compression.\n") + @Comment("\nLimit how many cores can be used for compression.\n" + + "0 means that all available cores will be used\n") public int compressionCoreCountLimit = 0; @Comment(value = "\nAvailable formats are:\n" + From 2de5f4c80b9ff8d482c42015c924f12a390df1ad Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:34:20 +0100 Subject: [PATCH 11/52] Added missing import, removed duplicate method --- .../szum123321/textile_backup/TextileBackup.java | 2 ++ .../szum123321/textile_backup/core/Utilities.java | 13 ------------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index a8e5fcd..7175478 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -33,6 +33,7 @@ import net.szum123321.textile_backup.commands.permission.WhitelistCommand; import net.szum123321.textile_backup.commands.restore.KillRestoreCommand; import net.szum123321.textile_backup.commands.restore.ListBackupsCommand; import net.szum123321.textile_backup.commands.restore.RestoreBackupCommand; +import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.BackupContext; import net.szum123321.textile_backup.core.create.BackupHelper; @@ -64,6 +65,7 @@ public class TextileBackup implements ModInitializer { if(Statics.CONFIG.backupInterval > 0) ServerTickEvents.END_SERVER_TICK.register(Statics.scheduler::tick); + //Restart Executor Service in singleplayer ServerLifecycleEvents.SERVER_STARTING.register(ignored -> { if(Statics.executorService.isShutdown()) Statics.executorService = Executors.newSingleThreadExecutor(); diff --git a/src/main/java/net/szum123321/textile_backup/core/Utilities.java b/src/main/java/net/szum123321/textile_backup/core/Utilities.java index 39898f8..25c2d5b 100644 --- a/src/main/java/net/szum123321/textile_backup/core/Utilities.java +++ b/src/main/java/net/szum123321/textile_backup/core/Utilities.java @@ -160,19 +160,6 @@ public class Utilities { return Optional.ofNullable(creationTime); } - public static File getBackupRootPath(String worldName) { - File path = new File(Statics.CONFIG.path).getAbsoluteFile(); - - if (Statics.CONFIG.perWorldBackup) - path = path.toPath().resolve(worldName).toFile(); - - if (!path.exists()) { - path.mkdirs(); - } - - return path; - } - public static boolean isValidBackup(File f) { return getArchiveExtension(f).isPresent() && getFileCreationTime(f).isPresent() && isFileOk(f); } From 870f1332738bb107d4fa963fffbbbc21578cee9d Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:34:48 +0100 Subject: [PATCH 12/52] Logger.warn -> error --- .../core/restore/decompressors/GenericTarDecompressor.java | 2 +- .../core/restore/decompressors/ZipDecompressor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java index f8985d8..cbe4118 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java @@ -44,7 +44,7 @@ public class GenericTarDecompressor { while ((entry = archiveInputStream.getNextTarEntry()) != null) { if(!archiveInputStream.canReadEntryData(entry)) { - Statics.LOGGER.warn("Something when wrong while trying to decompress {}", entry.getName()); + Statics.LOGGER.error("Something when wrong while trying to decompress {}", entry.getName()); continue; } diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java index 1ba3f2e..79d6a27 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java @@ -40,7 +40,7 @@ public class ZipDecompressor { while ((entry = zipInputStream.getNextZipEntry()) != null) { if(!zipInputStream.canReadEntryData(entry)){ - Statics.LOGGER.warn("Something when wrong while trying to decompress {}", entry.getName()); + Statics.LOGGER.error("Something when wrong while trying to decompress {}", entry.getName()); continue; } From 6f9e98f10440386f3e9ce083f83bc2c014eb3a91 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 10:35:27 +0100 Subject: [PATCH 13/52] File -> RestoreableFile --- .../commands/restore/ListBackupsCommand.java | 6 ++---- .../commands/restore/RestoreBackupCommand.java | 5 ++--- .../core/restore/RestoreBackupRunnable.java | 18 +++++++++--------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java index dfbde8a..390d32e 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java @@ -24,9 +24,7 @@ import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.restore.RestoreHelper; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; +import java.util.*; public class ListBackupsCommand { public static LiteralArgumentBuilder register() { @@ -40,7 +38,7 @@ public class ListBackupsCommand { builder.append("There is only one backup available: "); builder.append(backups.get(0).toString()); } else { - backups.sort(Comparator.comparing(RestoreHelper.RestoreableFile::getCreationTime)); + backups.sort(null); Iterator iterator = backups.iterator(); builder.append("Available backups: "); diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java index c25dc4f..b6dcefd 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java @@ -34,7 +34,6 @@ import net.minecraft.text.LiteralText; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.restore.RestoreHelper; -import java.io.File; import java.time.LocalDateTime; import java.time.format.DateTimeParseException; import java.util.Optional; @@ -88,10 +87,10 @@ public class RestoreBackupCommand { throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message); } - Optional backupFile = RestoreHelper.findFileAndLockIfPresent(dateTime, source.getMinecraftServer()); + Optional backupFile = RestoreHelper.findFileAndLockIfPresent(dateTime, source.getMinecraftServer()); if(backupFile.isPresent()) { - Statics.LOGGER.info("Found file to restore {}", backupFile.get().getName()); + Statics.LOGGER.info("Found file to restore {}", backupFile.get().getFile().getName()); } else { Statics.LOGGER.sendInfo(source, "No file created on {} was found!", dateTime.format(Statics.defaultDateTimeFormatter)); 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 8336591..2b70cc5 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 @@ -29,14 +29,13 @@ import net.szum123321.textile_backup.core.restore.decompressors.GenericTarDecomp import net.szum123321.textile_backup.core.restore.decompressors.ZipDecompressor; import java.io.File; -import java.util.NoSuchElementException; public class RestoreBackupRunnable implements Runnable { private final MinecraftServer server; - private final File backupFile; + private final RestoreHelper.RestoreableFile backupFile; private final String finalBackupComment; - public RestoreBackupRunnable(MinecraftServer server, File backupFile, String finalBackupComment) { + public RestoreBackupRunnable(MinecraftServer server, RestoreHelper.RestoreableFile backupFile, String finalBackupComment) { this.server = server; this.backupFile = backupFile; this.finalBackupComment = finalBackupComment; @@ -45,6 +44,7 @@ public class RestoreBackupRunnable implements Runnable { @Override public void run() { Statics.LOGGER.info("Shutting down server..."); + server.stop(false); awaitServerShutdown(); @@ -61,6 +61,7 @@ public class RestoreBackupRunnable implements Runnable { File worldFile = Utilities.getWorldFolder(server); Statics.LOGGER.info("Deleting old world..."); + if(!deleteDirectory(worldFile)) Statics.LOGGER.error("Something went wrong while deleting old world!"); @@ -68,16 +69,15 @@ public class RestoreBackupRunnable implements Runnable { Statics.LOGGER.info("Starting decompression..."); - if(Utilities.getFileExtension(backupFile).orElseThrow(() -> new NoSuchElementException("Couldn't get file extension!")) == ConfigHandler.ArchiveFormat.ZIP) { - ZipDecompressor.decompress(backupFile, worldFile); - } else { - GenericTarDecompressor.decompress(backupFile, worldFile); - } + if(backupFile.getArchiveFormat() == ConfigHandler.ArchiveFormat.ZIP) + ZipDecompressor.decompress(backupFile.getFile(), worldFile); + else + GenericTarDecompressor.decompress(backupFile.getFile(), worldFile); if(Statics.CONFIG.deleteOldBackupAfterRestore) { Statics.LOGGER.info("Deleting old backup"); - if(!backupFile.delete()) + if(!backupFile.getFile().delete()) Statics.LOGGER.info("Something went wrong while deleting old backup"); } From 8ba3dbc9554172572d9184ec745a1afc38f0d6a0 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 30 Nov 2020 12:00:29 +0100 Subject: [PATCH 14/52] Added comment to isDotDat method --- .../textile_backup/core/create/compressors/ZipCompressor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c53fc52..89ce9af 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 @@ -48,7 +48,6 @@ public class ZipCompressor extends AbstractCompressor { @Override protected void addEntry(File file, String entryName, OutputStream arc) throws IOException { - try (FileInputStream fileInputStream = new FileInputStream(file)){ ZipArchiveEntry entry = (ZipArchiveEntry)((ZipArchiveOutputStream)arc).createArchiveEntry(file, entryName); @@ -63,6 +62,7 @@ public class ZipCompressor extends AbstractCompressor { } } + //*.dat files are already compressed with gzip which uses the same algorithm as zip so there's no point in compressing it again protected static boolean isDotDat(String filename) { String[] arr = filename.split("\\."); return arr[arr.length - 1].contains("dat"); //includes dat_old From d27568c20f581c94510303d156f998743fc27459 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 20:49:49 +0100 Subject: [PATCH 15/52] Renamed BackupInitiator to ActionInitiator and moved it to separate class --- .../textile_backup/core/ActionInitiator.java | 44 +++++++++++++++++++ .../core/create/BackupContext.java | 24 ---------- 2 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 src/main/java/net/szum123321/textile_backup/core/ActionInitiator.java diff --git a/src/main/java/net/szum123321/textile_backup/core/ActionInitiator.java b/src/main/java/net/szum123321/textile_backup/core/ActionInitiator.java new file mode 100644 index 0000000..f965874 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/ActionInitiator.java @@ -0,0 +1,44 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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; + +public enum ActionInitiator { + Player("Player", "by"), + ServerConsole("Server Console", "from"), + Timer("Timer", "by"), + Shutdown("Server Shutdown", "by"), + Restore("Backup Restoration", "because of"), + Null("Null (That shouldn't have happened)", "form"); + + private final String name; + private final String prefix; + + ActionInitiator(String name, String prefix) { + this.name = name; + this.prefix = prefix; + } + + public String getName() { + return name; + } + + public String getPrefix() { + return prefix + ": "; + } +} 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 index b458d3f..ef31c71 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java @@ -128,28 +128,4 @@ public class BackupContext { } } - public enum BackupInitiator { - Player ("Player", "by"), - ServerConsole ("Server Console", "from"), - Timer ("Timer", "by"), - Shutdown ("Server Shutdown", "by"), - Restore ("Backup Restoration", "because of"), - Null ("Null (That shouldn't have happened)", "form"); - - private final String name; - private final String prefix; - - BackupInitiator(String name, String prefix) { - this.name = name; - this.prefix = prefix; - } - - public String getName() { - return name; - } - - public String getPrefix() { - return prefix + ": "; - } - } } From 7c07d2934c417d91ef0eecd78e57100463c2ac90 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 20:57:49 +0100 Subject: [PATCH 16/52] Finally no double output! --- .../textile_backup/TextileBackup.java | 2 +- .../commands/restore/KillRestoreCommand.java | 10 +++- .../restore/RestoreBackupCommand.java | 2 +- .../textile_backup/core/CustomLogger.java | 58 ++++++++++--------- .../core/create/BackupContext.java | 22 ++++--- .../core/create/BackupHelper.java | 23 +++----- .../core/create/BackupScheduler.java | 5 +- .../core/create/MakeBackupRunnable.java | 11 ++-- .../compressors/AbstractCompressor.java | 11 +++- .../core/restore/RestoreHelper.java | 1 + 10 files changed, 84 insertions(+), 61 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index 7175478..791a9fa 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -78,7 +78,7 @@ public class TextileBackup implements ModInitializer { BackupHelper.create( new BackupContext.Builder() .setServer(server) - .setInitiator(BackupContext.BackupInitiator.Shutdown) + .setInitiator(ActionInitiator.Shutdown) .setComment("shutdown") .build() ).run(); diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java index 3824fba..852560e 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java @@ -19,6 +19,7 @@ package net.szum123321.textile_backup.commands.restore; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.Statics; @@ -30,11 +31,16 @@ public class KillRestoreCommand { if(Statics.restoreAwaitThread != null && Statics.restoreAwaitThread.isAlive()) { Statics.restoreAwaitThread.interrupt(); Statics.globalShutdownBackupFlag.set(true); - Statics.LOGGER.sendInfo(ctx.getSource(), "Backup restoration successfully stopped."); - Statics.LOGGER.info("{} cancelled backup restoration.", ctx.getSource().getEntity() != null ? + Statics.untouchableFile = null; + + Statics.LOGGER.info("{} cancelled backup restoration.", ctx.getSource().getEntity() instanceof PlayerEntity ? "Player: " + ctx.getSource().getName() : "SERVER" ); + + if(ctx.getSource().getEntity() instanceof PlayerEntity) + Statics.LOGGER.sendInfo(ctx.getSource(), "Backup restoration successfully stopped."); + } else { Statics.LOGGER.sendInfo(ctx.getSource(), "Failed to stop backup restoration"); } diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java index b6dcefd..aa098e1 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java @@ -124,7 +124,7 @@ public class RestoreBackupCommand { String formattedCreationTime = file.getCreationTime().format(Statics.defaultDateTimeFormatter); if(formattedCreationTime.startsWith(remaining)) { - if(ctx.getSource().getEntity() != null) { //was typed by player + if(ctx.getSource().getEntity() instanceof PlayerEntity) { //was typed by player if(file.getComment() != null) { builder.suggest(formattedCreationTime, new LiteralMessage("Comment: " + file.getComment())); } else { diff --git a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java index 44b5977..1d899f4 100644 --- a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java +++ b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java @@ -18,7 +18,7 @@ package net.szum123321.textile_backup.core; -import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.LiteralText; import net.minecraft.text.MutableText; @@ -35,7 +35,7 @@ import org.apache.logging.log4j.spi.StandardLevel; This is practically just a copy-pate of Cotton's ModLogger with a few changes */ public class CustomLogger { - private final boolean isDev = FabricLoader.getInstance().isDevelopmentEnvironment(); + //private final boolean isDev = FabricLoader.getInstance().isDevelopmentEnvironment(); private final MessageFactory messageFactory; private final Logger logger; @@ -82,38 +82,22 @@ public class CustomLogger { log(Level.FATAL, msg, data); } - public void devError(String msg, Object... data) { - if (isDev) error(msg, data); - } - - public void devWarn(String msg, Object... data) { - if (isDev) warn(msg, data); - } - - public void devInfo(String msg, Object... data) { - if (isDev) info(msg, data); - } - - public void devDebug(String msg, Object... data) { - if (isDev) debug(msg, data); - } - - public void devTrace(String msg, Object... data) { - if(isDev) trace(msg, data); - } - - private void sendToPlayer(Level level, ServerCommandSource source, String msg, Object... args) { - if(source != null && source.getEntity() != null) { + boolean sendToPlayer(Level level, ServerCommandSource source, String msg, Object... args) { + if(source != null && source.getEntity() instanceof PlayerEntity) { LiteralText text = new LiteralText(messageFactory.newMessage(msg, args).getFormattedMessage()); - if(level.intLevel() <= StandardLevel.WARN.intLevel()) + if(level.intLevel() < StandardLevel.WARN.intLevel()) text.formatted(Formatting.RED); else text.formatted(Formatting.WHITE); source.sendFeedback(prefixText.shallowCopy().append(text), false); + + return true; } else { - logger.log(level, msg, args); + log(level, msg, args); + + return false; } } @@ -132,4 +116,26 @@ public class CustomLogger { public void sendError(BackupContext context, String msg, Object... args) { sendError(context.getCommandSource(), msg, args); } + + public void sendToPlayerAndLog(Level level, ServerCommandSource source, String msg, Object... args) { + if(sendToPlayer(level, source, msg, args)) + log(level, msg, args); + } + + //send info and log + public void sendInfoAL(ServerCommandSource source, String msg, Object... args) { + sendToPlayerAndLog(Level.INFO, source, msg, args); + } + + public void sendInfoAL(BackupContext context, String msg, Object... args) { + sendInfoAL(context.getCommandSource(), msg, args); + } + + public void sendErrorAL(ServerCommandSource source, String msg, Object... args) { + sendToPlayerAndLog(Level.ERROR, source, msg, args); + } + + public void sendErrorAL(BackupContext context, String msg, Object... args) { + sendErrorAL(context.getCommandSource(), msg, args); + } } 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 index ef31c71..6a64f92 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java @@ -18,18 +18,20 @@ package net.szum123321.textile_backup.core.create; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ServerCommandSource; +import net.szum123321.textile_backup.core.ActionInitiator; import org.jetbrains.annotations.NotNull; public class BackupContext { private final MinecraftServer server; private final ServerCommandSource commandSource; - private final BackupInitiator initiator; + private final ActionInitiator initiator; private final boolean save; private final String comment; - protected BackupContext(@NotNull MinecraftServer server, ServerCommandSource commandSource, @NotNull BackupInitiator initiator, boolean save, String comment) { + protected BackupContext(@NotNull MinecraftServer server, ServerCommandSource commandSource, @NotNull ActionInitiator initiator, boolean save, String comment) { this.server = server; this.commandSource = commandSource; this.initiator = initiator; @@ -45,12 +47,12 @@ public class BackupContext { return commandSource; } - public BackupInitiator getInitiator() { + public ActionInitiator getInitiator() { return initiator; } public boolean startedByPlayer() { - return initiator == BackupInitiator.Player; + return initiator == ActionInitiator.Player; } public boolean shouldSave() { @@ -64,7 +66,7 @@ public class BackupContext { public static class Builder { private MinecraftServer server; private ServerCommandSource commandSource; - private BackupInitiator initiator; + private ActionInitiator initiator; private boolean save; private String comment; @@ -80,6 +82,10 @@ public class BackupContext { guessInitiator = false; } + public static Builder newBackupContextBuilder() { + return new Builder(); + } + public Builder setCommandSource(ServerCommandSource commandSource) { this.commandSource = commandSource; return this; @@ -90,7 +96,7 @@ public class BackupContext { return this; } - public Builder setInitiator(BackupInitiator initiator) { + public Builder setInitiator(ActionInitiator initiator) { this.initiator = initiator; return this; } @@ -112,9 +118,9 @@ public class BackupContext { public BackupContext build() { if(guessInitiator) { - initiator = commandSource.getEntity() == null ? BackupInitiator.ServerConsole : BackupInitiator.Player; + initiator = commandSource.getEntity() instanceof PlayerEntity ? ActionInitiator.Player : ActionInitiator.ServerConsole; } else if(initiator == null) { - initiator = BackupInitiator.Null; + initiator = ActionInitiator.Null; } if(server == null) { diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index 3c015eb..85f0e9f 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -23,6 +23,7 @@ import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.MutableText; import net.minecraft.util.Util; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.Utilities; import org.apache.commons.io.FileUtils; @@ -32,7 +33,6 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; -import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; public class BackupHelper { @@ -57,8 +57,7 @@ public class BackupHelper { Statics.LOGGER.info(builder.toString()); if (ctx.shouldSave()) { - Statics.LOGGER.sendInfo(ctx.getCommandSource(), "Saving server..."); - Statics.LOGGER.info( "Saving server..."); + Statics.LOGGER.sendInfoAL(ctx, "Saving server..."); ctx.getServer().save(true, true, true); @@ -72,14 +71,11 @@ public class BackupHelper { MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); message.append("Warning! Server backup will begin shortly. You may experience some lag."); - UUID uuid; - - if(ctx.getCommandSource().getEntity() != null) - uuid = ctx.getCommandSource().getEntity().getUuid(); - else - uuid = Util.NIL_UUID; - - ctx.getServer().getPlayerManager().broadcastChatMessage(message, MessageType.GAME_INFO, uuid); + ctx.getServer().getPlayerManager().broadcastChatMessage( + message, + MessageType.GAME_INFO, + ctx.getInitiator() == ActionInitiator.Player ? ctx.getCommandSource().getEntity().getUuid() : Util.NIL_UUID + ); } public static int executeFileLimit(ServerCommandSource ctx, String worldName) { @@ -134,11 +130,10 @@ public class BackupHelper { private static boolean deleteFile(File f, ServerCommandSource ctx) { if(f != Statics.untouchableFile) { if(f.delete()) { - Statics.LOGGER.sendInfo(ctx, "Deleting: {}", f.getName()); - Statics.LOGGER.info("Deleting: {}", f.getName()); + Statics.LOGGER.sendInfoAL(ctx, "Deleting: {}", f.getName()); return true; } else { - Statics.LOGGER.sendError(ctx, "Something went wrong while deleting: {}.", f.getName()); + Statics.LOGGER.sendErrorAL(ctx, "Something went wrong while deleting: {}.", f.getName()); } } 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 753ca94..fc2b417 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 @@ -20,6 +20,7 @@ package net.szum123321.textile_backup.core.create; import net.minecraft.server.MinecraftServer; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.ActionInitiator; import java.time.Instant; @@ -42,7 +43,7 @@ public class BackupScheduler { BackupHelper.create( new BackupContext.Builder() .setServer(server) - .setInitiator(BackupContext.BackupInitiator.Timer) + .setInitiator(ActionInitiator.Timer) .saveServer() .build() ) @@ -60,7 +61,7 @@ public class BackupScheduler { BackupHelper.create( new BackupContext.Builder() .setServer(server) - .setInitiator(BackupContext.BackupInitiator.Timer) + .setInitiator(ActionInitiator.Timer) .saveServer() .build() ) 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 index 0455c21..6272a8c 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -61,7 +61,9 @@ public class MakeBackupRunnable implements Runnable { outFile.createNewFile(); } catch (IOException e) { Statics.LOGGER.error("An exception occurred when trying to create new backup file!", e); - Statics.LOGGER.sendError(context.getCommandSource(), "An exception occurred when trying to create new backup file!"); + + if(context.getInitiator() == ActionInitiator.Player) + Statics.LOGGER.sendError(context, "An exception occurred when trying to create new backup file!"); return; } @@ -99,7 +101,9 @@ public class MakeBackupRunnable implements Runnable { default: Statics.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", Statics.CONFIG.format); - Statics.LOGGER.sendError(context.getCommandSource(), "Error! No correct compression format specified! Using default compressor!"); + + if(context.getInitiator() == ActionInitiator.Player) + Statics.LOGGER.sendError(context.getCommandSource(), "Error! No correct compression format specified! Using default compressor!"); ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); break; @@ -107,8 +111,7 @@ public class MakeBackupRunnable implements Runnable { BackupHelper.executeFileLimit(context.getCommandSource(), Utilities.getLevelName(context.getServer())); - Statics.LOGGER.sendInfo(context, "Done!"); - Statics.LOGGER.info("Done!"); + Statics.LOGGER.sendInfoAL(context, "Done!"); } finally { Utilities.enableWorldSaving(context.getServer()); } 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 b75a813..361f666 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 @@ -19,6 +19,7 @@ package net.szum123321.textile_backup.core.create.compressors; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.BackupContext; @@ -46,19 +47,23 @@ public abstract class AbstractCompressor { addEntry(file, inputFile.toPath().relativize(file.toPath()).toString(), arc); } catch (IOException e) { Statics.LOGGER.error("An exception occurred while trying to compress: {}", file.getName(), e); - Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); + + if(ctx.getInitiator() == ActionInitiator.Player) + Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); } }); finish(arc); } catch (IOException | InterruptedException | ExecutionException e) { Statics.LOGGER.error("An exception occurred!", e); - Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); + + if(ctx.getInitiator() == ActionInitiator.Player) + Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); } close(); - Statics.LOGGER.sendInfo(ctx, "Compression took: {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now()))); + Statics.LOGGER.sendInfoAL(ctx, "Compression took: {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now()))); } protected abstract OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException; diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index 4a91416..95599eb 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -24,6 +24,7 @@ import net.minecraft.text.MutableText; import net.minecraft.util.Util; import net.szum123321.textile_backup.ConfigHandler; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.Utilities; import org.jetbrains.annotations.NotNull; From 163626fb3dda0f0ff4d60f577d50db8c1634bd0a Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 20:59:47 +0100 Subject: [PATCH 17/52] Added RestoreContext for good measure --- .../restore/RestoreBackupCommand.java | 14 +-- .../core/restore/RestoreBackupRunnable.java | 34 +++--- .../core/restore/RestoreContext.java | 106 ++++++++++++++++++ .../core/restore/RestoreHelper.java | 15 ++- 4 files changed, 141 insertions(+), 28 deletions(-) create mode 100644 src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java index aa098e1..257b11a 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java @@ -97,13 +97,13 @@ public class RestoreBackupCommand { return 0; } - if(Statics.restoreAwaitThread == null || !Statics.restoreAwaitThread.isAlive()) { - if(source.getEntity() != null) - Statics.LOGGER.info("Backup restoration was initiated by: {}", source.getName()); - else - Statics.LOGGER.info("Backup restoration was initiated form Server Console"); - - Statics.restoreAwaitThread = RestoreHelper.create(backupFile.get(), source.getMinecraftServer(), comment); + Statics.restoreAwaitThread = RestoreHelper.create( + RestoreContext.Builder.newRestoreContextBuilder() + .setCommandSource(source) + .setFile(backupFile.get()) + .setComment(comment) + .build() + ); Statics.restoreAwaitThread.start(); } else if(Statics.restoreAwaitThread != null && Statics.restoreAwaitThread.isAlive()) { 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 2b70cc5..2318106 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 @@ -20,6 +20,7 @@ package net.szum123321.textile_backup.core.restore; import net.minecraft.server.MinecraftServer; import net.szum123321.textile_backup.ConfigHandler; +import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.LivingServer; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.Utilities; @@ -31,34 +32,31 @@ import net.szum123321.textile_backup.core.restore.decompressors.ZipDecompressor; import java.io.File; public class RestoreBackupRunnable implements Runnable { - private final MinecraftServer server; - private final RestoreHelper.RestoreableFile backupFile; - private final String finalBackupComment; + private final RestoreContext ctx; - public RestoreBackupRunnable(MinecraftServer server, RestoreHelper.RestoreableFile backupFile, String finalBackupComment) { - this.server = server; - this.backupFile = backupFile; - this.finalBackupComment = finalBackupComment; + public RestoreBackupRunnable(RestoreContext ctx) { + this.ctx = ctx; } @Override public void run() { Statics.LOGGER.info("Shutting down server..."); - server.stop(false); + ctx.getServer().stop(false); awaitServerShutdown(); if(Statics.CONFIG.backupOldWorlds) { BackupHelper.create( - new BackupContext.Builder() - .setServer(server) - .setInitiator(BackupContext.BackupInitiator.Restore) - .setComment("Old_World" + (finalBackupComment != null ? "_" + finalBackupComment : "")) + BackupContext.Builder + .newBackupContextBuilder() + .setServer(ctx.getServer()) + .setInitiator(ActionInitiator.Restore) + .setComment("Old_World" + (ctx.getComment() != null ? "_" + ctx.getComment() : "")) .build() ).run(); } - File worldFile = Utilities.getWorldFolder(server); + File worldFile = Utilities.getWorldFolder(ctx.getServer()); Statics.LOGGER.info("Deleting old world..."); @@ -69,15 +67,15 @@ public class RestoreBackupRunnable implements Runnable { Statics.LOGGER.info("Starting decompression..."); - if(backupFile.getArchiveFormat() == ConfigHandler.ArchiveFormat.ZIP) - ZipDecompressor.decompress(backupFile.getFile(), worldFile); + if(ctx.getFile().getArchiveFormat() == ConfigHandler.ArchiveFormat.ZIP) + ZipDecompressor.decompress(ctx.getFile().getFile(), worldFile); else - GenericTarDecompressor.decompress(backupFile.getFile(), worldFile); + GenericTarDecompressor.decompress(ctx.getFile().getFile(), worldFile); if(Statics.CONFIG.deleteOldBackupAfterRestore) { Statics.LOGGER.info("Deleting old backup"); - if(!backupFile.getFile().delete()) + if(!ctx.getFile().getFile().delete()) Statics.LOGGER.info("Something went wrong while deleting old backup"); } @@ -85,7 +83,7 @@ public class RestoreBackupRunnable implements Runnable { } private void awaitServerShutdown() { - while(((LivingServer)server).isAlive()) { + while(((LivingServer)ctx.getServer()).isAlive()) { try { Thread.sleep(100); } catch (InterruptedException e) { diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java new file mode 100644 index 0000000..b7352a2 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java @@ -0,0 +1,106 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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.restore; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.command.ServerCommandSource; +import net.szum123321.textile_backup.core.ActionInitiator; + +import javax.annotation.Nullable; + +public class RestoreContext { + private final RestoreHelper.RestoreableFile file; + private final MinecraftServer server; + @Nullable + private final String comment; + private final ActionInitiator initiator; + private final ServerCommandSource commandSource; + + public RestoreContext(RestoreHelper.RestoreableFile file, MinecraftServer server, @Nullable String comment, ActionInitiator initiator, ServerCommandSource commandSource) { + this.file = file; + this.server = server; + this.comment = comment; + this.initiator = initiator; + this.commandSource = commandSource; + } + + public RestoreHelper.RestoreableFile getFile() { + return file; + } + + public MinecraftServer getServer() { + return server; + } + + @Nullable + public String getComment() { + return comment; + } + + public ActionInitiator getInitiator() { + return initiator; + } + + public ServerCommandSource getCommandSource() { + return commandSource; + } + + public static final class Builder { + private RestoreHelper.RestoreableFile file; + private MinecraftServer server; + private String comment; + private ServerCommandSource serverCommandSource; + + private Builder() { + } + + public static Builder newRestoreContextBuilder() { + return new Builder(); + } + + public Builder setFile(RestoreHelper.RestoreableFile file) { + this.file = file; + return this; + } + + public Builder setServer(MinecraftServer server) { + this.server = server; + return this; + } + + public Builder setComment(@Nullable String comment) { + this.comment = comment; + return this; + } + + public Builder setCommandSource(ServerCommandSource commandSource) { + this.serverCommandSource = commandSource; + return this; + } + + public RestoreContext build() { + if(server == null) server = serverCommandSource.getMinecraftServer(); + + ActionInitiator initiator = serverCommandSource.getEntity() instanceof PlayerEntity ? ActionInitiator.Player : ActionInitiator.ServerConsole; + + return new RestoreContext(file, server, comment, initiator, serverCommandSource); + } + } +} diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index 95599eb..2c1db5d 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -52,17 +52,26 @@ public class RestoreHelper { return optionalFile; } - public static AwaitThread create(RestoreableFile backupFile, MinecraftServer server, String comment) { + public static AwaitThread create(RestoreContext ctx) { + if(ctx.getInitiator() == ActionInitiator.Player) + Statics.LOGGER.info("Backup restoration was initiated by: {}", ctx.getCommandSource().getName()); + else + Statics.LOGGER.info("Backup restoration was initiated form Server Console"); + MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); message.append("Warning! The server is going to shut down in " + Statics.CONFIG.restoreDelay + " seconds!"); - server.getPlayerManager().broadcastChatMessage(message, MessageType.GAME_INFO, Util.NIL_UUID); + ctx.getServer().getPlayerManager().broadcastChatMessage( + message, + MessageType.GAME_INFO, + ctx.getInitiator() == ActionInitiator.Player ? ctx.getCommandSource().getEntity().getUuid() : Util.NIL_UUID + ); Statics.globalShutdownBackupFlag.set(false); return new AwaitThread( Statics.CONFIG.restoreDelay, - new RestoreBackupRunnable(server, backupFile, comment) + new RestoreBackupRunnable(ctx) ); } From 06f80a917536d716e598b31a13146ccc36178220 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 21:00:46 +0100 Subject: [PATCH 18/52] Moved locking world form BackupHelper to MakeBackupRunnable --- .../szum123321/textile_backup/core/create/BackupHelper.java | 2 -- .../textile_backup/core/create/MakeBackupRunnable.java | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index 85f0e9f..5696786 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -60,8 +60,6 @@ public class BackupHelper { Statics.LOGGER.sendInfoAL(ctx, "Saving server..."); ctx.getServer().save(true, true, true); - - Utilities.disableWorldSaving(ctx.getServer()); } return new MakeBackupRunnable(ctx); 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 index 6272a8c..fec0221 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -19,6 +19,7 @@ package net.szum123321.textile_backup.core.create; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.create.compressors.*; import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.compressors.tar.LZMACompressor; @@ -40,8 +41,9 @@ public class MakeBackupRunnable implements Runnable { @Override public void run() { try { - Statics.LOGGER.sendInfo(context.getCommandSource(), "Starting backup"); - Statics.LOGGER.info("Starting backup"); + Utilities.disableWorldSaving(context.getServer()); + + Statics.LOGGER.sendInfoAL(context, "Starting backup"); File world = Utilities.getWorldFolder(context.getServer()); From eba22e846427184937f854a42356b3846d546b59 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 21:05:16 +0100 Subject: [PATCH 19/52] Added newBackupContextBuilder function to BackupContext.Builder and simplified StartBackupCommand --- .../textile_backup/TextileBackup.java | 3 +- .../commands/create/StartBackupCommand.java | 53 ++++++++----------- .../core/create/BackupScheduler.java | 6 ++- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index 791a9fa..bd18788 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -76,7 +76,8 @@ public class TextileBackup implements ModInitializer { if (Statics.CONFIG.shutdownBackup && Statics.globalShutdownBackupFlag.get()) { BackupHelper.create( - new BackupContext.Builder() + BackupContext.Builder + .newBackupContextBuilder() .setServer(server) .setInitiator(ActionInitiator.Shutdown) .setComment("shutdown") 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 5ed374b..bf24c41 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 @@ -20,48 +20,41 @@ package net.szum123321.textile_backup.commands.create; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.create.BackupContext; import net.szum123321.textile_backup.core.create.BackupHelper; +import javax.annotation.Nullable; + public class StartBackupCommand { public static LiteralArgumentBuilder register() { return CommandManager.literal("start") .then(CommandManager.argument("comment", StringArgumentType.string()) - .executes(StartBackupCommand::executeWithComment) - ).executes(ctx -> execute(ctx.getSource())); + .executes(ctx -> execute(ctx.getSource(), StringArgumentType.getString(ctx, "comment"))) + ).executes(ctx -> execute(ctx.getSource(), null)); } - private static int executeWithComment(CommandContext ctx) { - if(!Statics.executorService.isShutdown()) - Statics.executorService.submit( - BackupHelper.create( - new BackupContext.Builder() - .setCommandSource(ctx.getSource()) - .setComment(StringArgumentType.getString(ctx, "comment")) - .guessInitiator() - .saveServer() - .build() - ) - ); - - return 1; - } - - private static int execute(ServerCommandSource source){ - if(!Statics.executorService.isShutdown()) - Statics.executorService.submit( - BackupHelper.create( - new BackupContext.Builder() - .setCommandSource(source) - .guessInitiator() - .saveServer() - .build() - ) - ); + private static int execute(ServerCommandSource source, @Nullable String comment) { + if(!Statics.executorService.isShutdown()) { + try { + Statics.executorService.submit( + BackupHelper.create( + BackupContext.Builder + .newBackupContextBuilder() + .setCommandSource(source) + .setComment(comment) + .guessInitiator() + .saveServer() + .build() + ) + ); + } catch (Exception e) { + Statics.LOGGER.error("Something went wrong while executing command!", e); + throw e; + } + } return 1; } 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 fc2b417..8ff78a9 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 @@ -41,7 +41,8 @@ public class BackupScheduler { if(nextBackup <= now) { Statics.executorService.submit( BackupHelper.create( - new BackupContext.Builder() + BackupContext.Builder + .newBackupContextBuilder() .setServer(server) .setInitiator(ActionInitiator.Timer) .saveServer() @@ -59,7 +60,8 @@ public class BackupScheduler { if(scheduled && nextBackup <= now) { Statics.executorService.submit( BackupHelper.create( - new BackupContext.Builder() + BackupContext.Builder + .newBackupContextBuilder() .setServer(server) .setInitiator(ActionInitiator.Timer) .saveServer() From b68640b37f059eb03ad80e77e42b3a9c100c1c87 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 21:06:46 +0100 Subject: [PATCH 20/52] Added CRC32 calculation to Stored entries in Zip (caused exceptions) --- .../create/compressors/ParallelZipCompressor.java | 14 ++++++++++---- .../core/create/compressors/ZipCompressor.java | 10 +++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) 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 b66bd8e..1cbea1f 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 @@ -24,7 +24,9 @@ import org.apache.commons.compress.archivers.zip.*; import org.apache.commons.compress.parallel.InputStreamSupplier; import java.io.*; +import java.nio.file.Files; import java.util.concurrent.*; +import java.util.zip.CRC32; import java.util.zip.ZipEntry; /* @@ -50,10 +52,14 @@ public class ParallelZipCompressor extends ZipCompressor { protected void addEntry(File file, String entryName, OutputStream arc) throws IOException { ZipArchiveEntry entry = (ZipArchiveEntry)((ZipArchiveOutputStream)arc).createArchiveEntry(file, entryName); - if(ZipCompressor.isDotDat(file.getName())) - entry.setMethod(ZipEntry.STORED); - else - entry.setMethod(ZipEntry.DEFLATED); + if(ZipCompressor.isDotDat(file.getName())) { + entry.setMethod(ZipArchiveOutputStream.STORED); + entry.setSize(file.length()); + entry.setCompressedSize(file.length()); + CRC32 sum = new CRC32(); + sum.update(Files.readAllBytes(file.toPath())); + entry.setCrc(sum.getValue()); + } else entry.setMethod(ZipEntry.DEFLATED); entry.setTime(System.currentTimeMillis()); 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 89ce9af..b46e666 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 @@ -27,7 +27,9 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.utils.IOUtils; import java.io.*; +import java.nio.file.Files; import java.time.LocalDateTime; +import java.util.zip.CRC32; public class ZipCompressor extends AbstractCompressor { public static ZipCompressor getInstance() { @@ -51,8 +53,14 @@ public class ZipCompressor extends AbstractCompressor { try (FileInputStream fileInputStream = new FileInputStream(file)){ ZipArchiveEntry entry = (ZipArchiveEntry)((ZipArchiveOutputStream)arc).createArchiveEntry(file, entryName); - if(isDotDat(file.getName())) + if(isDotDat(file.getName())) { entry.setMethod(ZipArchiveOutputStream.STORED); + entry.setSize(file.length()); + entry.setCompressedSize(file.length()); + CRC32 sum = new CRC32(); + sum.update(Files.readAllBytes(file.toPath())); + entry.setCrc(sum.getValue()); + } ((ZipArchiveOutputStream)arc).putArchiveEntry(entry); From 7e2e39982987d812e1ea54ccb9a32c1eeea6b2fe Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 21:10:48 +0100 Subject: [PATCH 21/52] Improved RestoreBackupCommand --- .../restore/RestoreBackupCommand.java | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java index 257b11a..d2cb2d0 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java @@ -23,23 +23,39 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.LiteralText; +import net.minecraft.text.MutableText; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.restore.RestoreContext; import net.szum123321.textile_backup.core.restore.RestoreHelper; +import javax.annotation.Nullable; import java.time.LocalDateTime; import java.time.format.DateTimeParseException; import java.util.Optional; import java.util.concurrent.CompletableFuture; public class RestoreBackupCommand { + private final static DynamicCommandExceptionType DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE = new DynamicCommandExceptionType(o -> { + DateTimeParseException e = (DateTimeParseException)o; + + MutableText message = new LiteralText("An exception occurred while trying to parse:\n") + .append(e.getParsedString()) + .append("\n"); + + for (int i = 0; i < e.getErrorIndex(); i++) message.append(" "); + + return message.append("^"); + }); + public static LiteralArgumentBuilder register() { return CommandManager.literal("restore") .then(CommandManager.argument("file", StringArgumentType.word()) @@ -63,39 +79,31 @@ public class RestoreBackupCommand { Statics.LOGGER.sendInfo(source, "To restore given backup you have to provide exact creation time in format:"); Statics.LOGGER.sendInfo(source, "[YEAR]-[MONTH]-[DAY]_[HOUR].[MINUTE].[SECOND]"); - Statics.LOGGER.sendInfo(source, "Example: 2020-08-05_10.58.33"); + Statics.LOGGER.sendInfo(source, "Example: /backup restore 2020-08-05_10.58.33"); return 1; }); } - private static int execute(String file, String comment, ServerCommandSource source) throws CommandSyntaxException { - LocalDateTime dateTime; + private static int execute(String file, @Nullable String comment, ServerCommandSource source) throws CommandSyntaxException { + if(Statics.restoreAwaitThread == null || (Statics.restoreAwaitThread != null && !Statics.restoreAwaitThread.isAlive())) { + LocalDateTime dateTime; - try { - dateTime = LocalDateTime.from(Statics.defaultDateTimeFormatter.parse(file)); - } catch (DateTimeParseException e) { - LiteralText message = new LiteralText("An exception occurred while trying to parse:\n"); - message.append(e.getParsedString()) - .append("\n"); + try { + dateTime = LocalDateTime.from(Statics.defaultDateTimeFormatter.parse(file)); + } catch (DateTimeParseException e) { + throw DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE.create(e); + } - for(int i = 0; i < e.getErrorIndex(); i++) - message.append(" "); + Optional backupFile = RestoreHelper.findFileAndLockIfPresent(dateTime, source.getMinecraftServer()); - message.append("^"); + if(backupFile.isPresent()) { + Statics.LOGGER.info("Found file to restore {}", backupFile.get().getFile().getName()); + } else { + Statics.LOGGER.sendInfo(source, "No file created on {} was found!", dateTime.format(Statics.defaultDateTimeFormatter)); - throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message); - } - - Optional backupFile = RestoreHelper.findFileAndLockIfPresent(dateTime, source.getMinecraftServer()); - - if(backupFile.isPresent()) { - Statics.LOGGER.info("Found file to restore {}", backupFile.get().getFile().getName()); - } else { - Statics.LOGGER.sendInfo(source, "No file created on {} was found!", dateTime.format(Statics.defaultDateTimeFormatter)); - - return 0; - } + return 0; + } Statics.restoreAwaitThread = RestoreHelper.create( RestoreContext.Builder.newRestoreContextBuilder() @@ -106,13 +114,13 @@ public class RestoreBackupCommand { ); Statics.restoreAwaitThread.start(); - } else if(Statics.restoreAwaitThread != null && Statics.restoreAwaitThread.isAlive()) { + + return 1; + } else { Statics.LOGGER.sendInfo(source, "Someone has already started another restoration."); return 0; } - - return 1; } private static final class FileSuggestionProvider implements SuggestionProvider { From d29b9049a4e11afc100ad482dc524de40e76e1fb Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 2 Dec 2020 21:12:58 +0100 Subject: [PATCH 22/52] Typos + missing import --- src/main/java/net/szum123321/textile_backup/TextileBackup.java | 2 ++ .../core/create/compressors/ParallelZipCompressor.java | 2 +- .../core/create/compressors/tar/ParallelGzipCompressor.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index bd18788..9887ca3 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -33,6 +33,7 @@ import net.szum123321.textile_backup.commands.permission.WhitelistCommand; import net.szum123321.textile_backup.commands.restore.KillRestoreCommand; import net.szum123321.textile_backup.commands.restore.ListBackupsCommand; import net.szum123321.textile_backup.commands.restore.RestoreBackupCommand; +import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.BackupContext; import net.szum123321.textile_backup.core.create.BackupHelper; @@ -53,6 +54,7 @@ public class TextileBackup implements ModInitializer { System.exit(1); } + //TODO: finish writing wiki if(Statics.CONFIG.format == ConfigHandler.ArchiveFormat.ZIP) { Statics.tmpAvailable = Utilities.isTmpAvailable(); if(!Statics.tmpAvailable) { 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 1cbea1f..03ab145 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 @@ -82,7 +82,7 @@ public class ParallelZipCompressor extends ZipCompressor { try { return new FileInputStream(sourceFile); } catch (IOException e) { - Statics.LOGGER.error("An exception occurred while trying to create input stream from file: {}!", sourceFile.getName(), e); + Statics.LOGGER.error("An exception occurred while trying to create an input stream from file: {}!", sourceFile.getName(), e); } return null; 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 983d607..dcf9f1c 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 @@ -41,7 +41,7 @@ public class ParallelGzipCompressor extends AbstractTarArchiver { @Override protected void close() { - //it seems like ParallelGZIPOutputStream doesn't shut down its ExecutorService, so to not leave garbage I shutdown it + //it seems like ParallelGZIPOutputStream doesn't shut down its ExecutorService, so to not leave garbage I shut it down executorService.shutdown(); } } From 7f82664ae7c80aa1249285e004981c6b39316cef Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 5 Dec 2020 22:17:22 +0100 Subject: [PATCH 23/52] Added Delete command. Rearranged command package --- .../textile_backup/TextileBackup.java | 8 +- .../commands/CommandExceptions.java | 39 +++++++++ .../commands/FileSuggestionProvider.java | 67 +++++++++++++++ .../BlacklistCommand.java | 2 +- .../commands/manage/DeleteCommand.java | 84 +++++++++++++++++++ .../ListBackupsCommand.java | 2 +- .../WhitelistCommand.java | 2 +- .../restore/RestoreBackupCommand.java | 57 ++----------- 8 files changed, 203 insertions(+), 58 deletions(-) create mode 100644 src/main/java/net/szum123321/textile_backup/commands/CommandExceptions.java create mode 100644 src/main/java/net/szum123321/textile_backup/commands/FileSuggestionProvider.java rename src/main/java/net/szum123321/textile_backup/commands/{permission => manage}/BlacklistCommand.java (98%) create mode 100644 src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java rename src/main/java/net/szum123321/textile_backup/commands/{restore => manage}/ListBackupsCommand.java (97%) rename src/main/java/net/szum123321/textile_backup/commands/{permission => manage}/WhitelistCommand.java (98%) diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index 9887ca3..c8d75a9 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -28,10 +28,11 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.commands.create.CleanupCommand; import net.szum123321.textile_backup.commands.create.StartBackupCommand; -import net.szum123321.textile_backup.commands.permission.BlacklistCommand; -import net.szum123321.textile_backup.commands.permission.WhitelistCommand; +import net.szum123321.textile_backup.commands.manage.BlacklistCommand; +import net.szum123321.textile_backup.commands.manage.DeleteCommand; +import net.szum123321.textile_backup.commands.manage.WhitelistCommand; import net.szum123321.textile_backup.commands.restore.KillRestoreCommand; -import net.szum123321.textile_backup.commands.restore.ListBackupsCommand; +import net.szum123321.textile_backup.commands.manage.ListBackupsCommand; import net.szum123321.textile_backup.commands.restore.RestoreBackupCommand; import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.Utilities; @@ -108,6 +109,7 @@ public class TextileBackup implements ModInitializer { .then(BlacklistCommand.register()) .then(RestoreBackupCommand.register()) .then(ListBackupsCommand.register()) + .then(DeleteCommand.register()) .then(KillRestoreCommand.register()) )); } diff --git a/src/main/java/net/szum123321/textile_backup/commands/CommandExceptions.java b/src/main/java/net/szum123321/textile_backup/commands/CommandExceptions.java new file mode 100644 index 0000000..42accf0 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/commands/CommandExceptions.java @@ -0,0 +1,39 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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.commands; + +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import net.minecraft.text.LiteralText; +import net.minecraft.text.MutableText; + +import java.time.format.DateTimeParseException; + +public class CommandExceptions { + public static final DynamicCommandExceptionType DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE = new DynamicCommandExceptionType(o -> { + DateTimeParseException e = (DateTimeParseException)o; + + MutableText message = new LiteralText("An exception occurred while trying to parse:\n") + .append(e.getParsedString()) + .append("\n"); + + for (int i = 0; i < e.getErrorIndex(); i++) message.append(" "); + + return message.append("^"); + }); +} diff --git a/src/main/java/net/szum123321/textile_backup/commands/FileSuggestionProvider.java b/src/main/java/net/szum123321/textile_backup/commands/FileSuggestionProvider.java new file mode 100644 index 0000000..eb2534f --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/commands/FileSuggestionProvider.java @@ -0,0 +1,67 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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.commands; + +import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.command.ServerCommandSource; +import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.restore.RestoreHelper; +import org.lwjgl.system.CallbackI; + +import java.util.concurrent.CompletableFuture; + +public final class FileSuggestionProvider implements SuggestionProvider { + private static final FileSuggestionProvider INSTANCE = new FileSuggestionProvider(); + + public static FileSuggestionProvider Instance() { + return INSTANCE; + } + + @Override + public CompletableFuture getSuggestions(CommandContext ctx, SuggestionsBuilder builder) throws CommandSyntaxException { + String remaining = builder.getRemaining(); + + for (RestoreHelper.RestoreableFile file : RestoreHelper.getAvailableBackups(ctx.getSource().getMinecraftServer())) { + String formattedCreationTime = file.getCreationTime().format(Statics.defaultDateTimeFormatter); + + if (formattedCreationTime.startsWith(remaining)) { + if (ctx.getSource().getEntity() instanceof PlayerEntity) { //was typed by player + if (file.getComment() != null) { + builder.suggest(formattedCreationTime, new LiteralMessage("Comment: " + file.getComment())); + } else { + builder.suggest(formattedCreationTime); + } + } else { //was typed from server console + if (file.getComment() != null) { + builder.suggest(file.getCreationTime() + "#" + file.getComment()); + } else { + builder.suggest(formattedCreationTime); + } + } + } + } + return builder.buildFuture(); + } +} diff --git a/src/main/java/net/szum123321/textile_backup/commands/permission/BlacklistCommand.java b/src/main/java/net/szum123321/textile_backup/commands/manage/BlacklistCommand.java similarity index 98% rename from src/main/java/net/szum123321/textile_backup/commands/permission/BlacklistCommand.java rename to src/main/java/net/szum123321/textile_backup/commands/manage/BlacklistCommand.java index cc6baf4..b8960b3 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/permission/BlacklistCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/manage/BlacklistCommand.java @@ -1,4 +1,4 @@ -package net.szum123321.textile_backup.commands.permission; +package net.szum123321.textile_backup.commands.manage; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; diff --git a/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java b/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java new file mode 100644 index 0000000..48ce7ac --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java @@ -0,0 +1,84 @@ +/* + * A simple backup mod for Fabric + * Copyright (C) 2020 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.commands.manage; + +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.szum123321.textile_backup.commands.CommandExceptions; +import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.commands.FileSuggestionProvider; +import net.szum123321.textile_backup.core.Utilities; + +import java.io.File; +import java.time.LocalDateTime; +import java.time.format.DateTimeParseException; +import java.util.Arrays; +import java.util.Optional; + +public class DeleteCommand { + public static LiteralArgumentBuilder register() { + return CommandManager.literal("delete") + .then(CommandManager.argument("file", StringArgumentType.word()) + .suggests(FileSuggestionProvider.Instance()) + .executes(ctx -> execute(ctx.getSource(), StringArgumentType.getString(ctx, "file"))) + ); + } + + private static int execute(ServerCommandSource source, String fileName) throws CommandSyntaxException { + LocalDateTime dateTime; + + try { + dateTime = LocalDateTime.from(Statics.defaultDateTimeFormatter.parse(fileName)); + } catch (DateTimeParseException e) { + throw CommandExceptions.DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE.create(e); + } + + File root = Utilities.getBackupRootPath(Utilities.getLevelName(source.getMinecraftServer())); + + Optional optionalFile = Arrays.stream(root.listFiles()) + .filter(Utilities::isValidBackup) + .filter(file -> Utilities.getFileCreationTime(file).orElse(LocalDateTime.MIN).equals(dateTime)) + .findFirst(); + + if(optionalFile.isPresent()) { + if(Statics.untouchableFile == null || (Statics.untouchableFile != null && !Statics.untouchableFile.equals(optionalFile.get()))) { + if(optionalFile.get().delete()) { + Statics.LOGGER.sendInfo(source, "File {} successfully deleted!", optionalFile.get().getName()); + + if(source.getEntity() instanceof PlayerEntity) + Statics.LOGGER.info("Player {} deleted {}.", source.getPlayer().getName(), optionalFile.get().getName()); + } else { + Statics.LOGGER.sendError(source, "Something went wrong while deleting file!"); + } + } else { + Statics.LOGGER.sendError(source, "Couldn't delete the file because it's being restored right now."); + Statics.LOGGER.sendHint(source, "If you want to abort restoration then use: /backup killR"); + } + } else { + Statics.LOGGER.sendError(source, "Couldn't find file by this name."); + Statics.LOGGER.sendHint(source, "Maybe try /backup list"); + } + + return 0; + } +} diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java b/src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java similarity index 97% rename from src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java rename to src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java index 390d32e..076770e 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/ListBackupsCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.szum123321.textile_backup.commands.restore; +package net.szum123321.textile_backup.commands.manage; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import net.minecraft.server.command.CommandManager; diff --git a/src/main/java/net/szum123321/textile_backup/commands/permission/WhitelistCommand.java b/src/main/java/net/szum123321/textile_backup/commands/manage/WhitelistCommand.java similarity index 98% rename from src/main/java/net/szum123321/textile_backup/commands/permission/WhitelistCommand.java rename to src/main/java/net/szum123321/textile_backup/commands/manage/WhitelistCommand.java index e2bf0a2..8f5cc8f 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/permission/WhitelistCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/manage/WhitelistCommand.java @@ -1,4 +1,4 @@ -package net.szum123321.textile_backup.commands.permission; +package net.szum123321.textile_backup.commands.manage; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java index d2cb2d0..ad516f3 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/RestoreBackupCommand.java @@ -18,22 +18,15 @@ package net.szum123321.textile_backup.commands.restore; -import com.mojang.brigadier.LiteralMessage; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.suggestion.SuggestionProvider; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.LiteralText; -import net.minecraft.text.MutableText; +import net.szum123321.textile_backup.commands.CommandExceptions; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.commands.FileSuggestionProvider; import net.szum123321.textile_backup.core.restore.RestoreContext; import net.szum123321.textile_backup.core.restore.RestoreHelper; @@ -41,32 +34,19 @@ import javax.annotation.Nullable; import java.time.LocalDateTime; import java.time.format.DateTimeParseException; import java.util.Optional; -import java.util.concurrent.CompletableFuture; public class RestoreBackupCommand { - private final static DynamicCommandExceptionType DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE = new DynamicCommandExceptionType(o -> { - DateTimeParseException e = (DateTimeParseException)o; - - MutableText message = new LiteralText("An exception occurred while trying to parse:\n") - .append(e.getParsedString()) - .append("\n"); - - for (int i = 0; i < e.getErrorIndex(); i++) message.append(" "); - - return message.append("^"); - }); - public static LiteralArgumentBuilder register() { return CommandManager.literal("restore") .then(CommandManager.argument("file", StringArgumentType.word()) - .suggests(new FileSuggestionProvider()) + .suggests(FileSuggestionProvider.Instance()) .executes(ctx -> execute( StringArgumentType.getString(ctx, "file"), null, ctx.getSource() )) ).then(CommandManager.argument("file", StringArgumentType.word()) - .suggests(new FileSuggestionProvider()) + .suggests(FileSuggestionProvider.Instance()) .then(CommandManager.argument("comment", StringArgumentType.word()) .executes(ctx -> execute( StringArgumentType.getString(ctx, "file"), @@ -92,7 +72,7 @@ public class RestoreBackupCommand { try { dateTime = LocalDateTime.from(Statics.defaultDateTimeFormatter.parse(file)); } catch (DateTimeParseException e) { - throw DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE.create(e); + throw CommandExceptions.DATE_TIME_PARSE_COMMAND_EXCEPTION_TYPE.create(e); } Optional backupFile = RestoreHelper.findFileAndLockIfPresent(dateTime, source.getMinecraftServer()); @@ -123,31 +103,4 @@ public class RestoreBackupCommand { } } - private static final class FileSuggestionProvider implements SuggestionProvider { - @Override - public CompletableFuture getSuggestions(CommandContext ctx, SuggestionsBuilder builder) throws CommandSyntaxException { - String remaining = builder.getRemaining(); - - for(RestoreHelper.RestoreableFile file : RestoreHelper.getAvailableBackups(ctx.getSource().getMinecraftServer())) { - String formattedCreationTime = file.getCreationTime().format(Statics.defaultDateTimeFormatter); - - if(formattedCreationTime.startsWith(remaining)) { - if(ctx.getSource().getEntity() instanceof PlayerEntity) { //was typed by player - if(file.getComment() != null) { - builder.suggest(formattedCreationTime, new LiteralMessage("Comment: " + file.getComment())); - } else { - builder.suggest(formattedCreationTime); - } - } else { //was typed from server console - if(file.getComment() != null) { - builder.suggest(file.getCreationTime() + "#" + file.getComment()); - } else { - builder.suggest(formattedCreationTime); - } - } - } - } - return builder.buildFuture(); - } - } } From 445f7a5613d3d1f548d7a2d09629a44366ce2768 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 5 Dec 2020 23:14:35 +0100 Subject: [PATCH 24/52] Some improvements to logging, Player data now gets saved. Few other things... --- .../textile_backup/core/CustomLogger.java | 17 +++++++++++------ .../core/create/BackupHelper.java | 5 ++++- .../core/restore/RestoreBackupRunnable.java | 3 ++- .../core/restore/RestoreHelper.java | 16 +++++++++------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java index 1d899f4..35d1a6b 100644 --- a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java +++ b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java @@ -29,7 +29,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.MessageFactory; import org.apache.logging.log4j.message.ParameterizedMessageFactory; -import org.apache.logging.log4j.spi.StandardLevel; /* This is practically just a copy-pate of Cotton's ModLogger with a few changes @@ -82,11 +81,13 @@ public class CustomLogger { log(Level.FATAL, msg, data); } - boolean sendToPlayer(Level level, ServerCommandSource source, String msg, Object... args) { + boolean sendFeedback(Level level, ServerCommandSource source, String msg, Object... args) { if(source != null && source.getEntity() instanceof PlayerEntity) { LiteralText text = new LiteralText(messageFactory.newMessage(msg, args).getFormattedMessage()); - if(level.intLevel() < StandardLevel.WARN.intLevel()) + if(level.intLevel() == Level.TRACE.intLevel()) + text.formatted(Formatting.GREEN); + else if(level.intLevel() <= Level.WARN.intLevel()) text.formatted(Formatting.RED); else text.formatted(Formatting.WHITE); @@ -101,8 +102,12 @@ public class CustomLogger { } } + public void sendHint(ServerCommandSource source, String msg, Object... args) { + sendFeedback(Level.TRACE, source, msg, args); + } + public void sendInfo(ServerCommandSource source, String msg, Object... args) { - sendToPlayer(Level.INFO, source, msg, args); + sendFeedback(Level.INFO, source, msg, args); } public void sendInfo(BackupContext context, String msg, Object... args) { @@ -110,7 +115,7 @@ public class CustomLogger { } public void sendError(ServerCommandSource source, String msg, Object... args) { - sendToPlayer(Level.ERROR, source, msg, args); + sendFeedback(Level.ERROR, source, msg, args); } public void sendError(BackupContext context, String msg, Object... args) { @@ -118,7 +123,7 @@ public class CustomLogger { } public void sendToPlayerAndLog(Level level, ServerCommandSource source, String msg, Object... args) { - if(sendToPlayer(level, source, msg, args)) + if(sendFeedback(level, source, msg, args)) log(level, msg, args); } diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index 5696786..bae4a1d 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -20,7 +20,9 @@ package net.szum123321.textile_backup.core.create; import net.minecraft.network.MessageType; import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.LiteralText; import net.minecraft.text.MutableText; +import net.minecraft.util.Formatting; import net.minecraft.util.Util; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.ActionInitiator; @@ -59,6 +61,7 @@ public class BackupHelper { if (ctx.shouldSave()) { Statics.LOGGER.sendInfoAL(ctx, "Saving server..."); + ctx.getServer().getPlayerManager().saveAllPlayerData(); ctx.getServer().save(true, true, true); } @@ -67,7 +70,7 @@ public class BackupHelper { private static void notifyPlayers(BackupContext ctx) { MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); - message.append("Warning! Server backup will begin shortly. You may experience some lag."); + message.append(new LiteralText("Warning! Server backup will begin shortly. You may experience some lag.").formatted(Formatting.WHITE)); ctx.getServer().getPlayerManager().broadcastChatMessage( message, 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 2318106..7e2b39a 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 @@ -18,7 +18,6 @@ package net.szum123321.textile_backup.core.restore; -import net.minecraft.server.MinecraftServer; import net.szum123321.textile_backup.ConfigHandler; import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.LivingServer; @@ -40,6 +39,8 @@ public class RestoreBackupRunnable implements Runnable { @Override public void run() { + Statics.globalShutdownBackupFlag.set(false); + Statics.LOGGER.info("Shutting down server..."); ctx.getServer().stop(false); diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index 2c1db5d..d7a14e3 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -58,6 +58,15 @@ public class RestoreHelper { else Statics.LOGGER.info("Backup restoration was initiated form Server Console"); + notifyPlayer(ctx); + + return new AwaitThread( + Statics.CONFIG.restoreDelay, + new RestoreBackupRunnable(ctx) + ); + } + + private static void notifyPlayer(RestoreContext ctx) { MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); message.append("Warning! The server is going to shut down in " + Statics.CONFIG.restoreDelay + " seconds!"); @@ -66,13 +75,6 @@ public class RestoreHelper { MessageType.GAME_INFO, ctx.getInitiator() == ActionInitiator.Player ? ctx.getCommandSource().getEntity().getUuid() : Util.NIL_UUID ); - - Statics.globalShutdownBackupFlag.set(false); - - return new AwaitThread( - Statics.CONFIG.restoreDelay, - new RestoreBackupRunnable(ctx) - ); } public static List getAvailableBackups(MinecraftServer server) { From 8506bef30b3f029b62e03bc4a2910f8d2731aa96 Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 6 Dec 2020 19:19:16 +0100 Subject: [PATCH 25/52] Added error catching --- .../textile_backup/core/create/BackupHelper.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index bae4a1d..aeff137 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -62,7 +62,14 @@ public class BackupHelper { Statics.LOGGER.sendInfoAL(ctx, "Saving server..."); ctx.getServer().getPlayerManager().saveAllPlayerData(); - ctx.getServer().save(true, true, true); + + try { + ctx.getServer().save(false, true, true); + } catch (Exception e) { + Statics.LOGGER.error("An exception occurred when trying to save world!"); + Statics.LOGGER.error("This is known issue (See https://github.com/Szum123321/textile_backup/issues/42)"); + Statics.LOGGER.error("Please let me know about this situation (include below error, mod's config, additional mods, where is the server running etc.", e); + } } return new MakeBackupRunnable(ctx); From 39d3c3dacd247f6c15222f08269375f26a50eb8a Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 6 Dec 2020 21:26:11 +0100 Subject: [PATCH 26/52] Improved error catching --- .../core/create/BackupHelper.java | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index aeff137..ab3c869 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -20,6 +20,8 @@ package net.szum123321.textile_backup.core.create; import net.minecraft.network.MessageType; import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; import net.minecraft.text.LiteralText; import net.minecraft.text.MutableText; import net.minecraft.util.Formatting; @@ -66,8 +68,44 @@ public class BackupHelper { try { ctx.getServer().save(false, true, true); } catch (Exception e) { - Statics.LOGGER.error("An exception occurred when trying to save world!"); - Statics.LOGGER.error("This is known issue (See https://github.com/Szum123321/textile_backup/issues/42)"); + Statics.LOGGER.sendErrorAL(ctx,"An exception occurred when trying to save the world!\n" + + "But don't worry, backup will continue, although data may be not up-to-date." + ); + + MutableText text = Statics.LOGGER.getPrefixText() + .shallowCopy() + .append(new LiteralText("In order for backup to be up-to-date call ").formatted(Formatting.WHITE)) + .append( + new LiteralText("[/save-all flush]") + .styled( + style -> style + .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/save-all flush")) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new LiteralText("Click!"))) + .withColor(Formatting.BLUE) + ) + ) + .append(new LiteralText(" and then re-run the backup.").formatted(Formatting.WHITE)); + + ctx.getCommandSource().sendFeedback(text, false); + + text = Statics.LOGGER.getPrefixText() + .shallowCopy() + .append(new LiteralText("This is known issue (See ").formatted(Formatting.WHITE)) + .append( + new LiteralText("https://github.com/Szum123321/textile_backup/issues/42") + .styled( + style -> style + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/Szum123321/textile_backup/issues/42")) + .withColor(Formatting.BLUE) + ) + ) + .append(new LiteralText(")").formatted(Formatting.WHITE)); + + ctx.getCommandSource().sendFeedback(text, false); + + if(ctx.startedByPlayer()) + Statics.LOGGER.sendError(ctx, "If you have access to server console please take a look at it."); + Statics.LOGGER.error("Please let me know about this situation (include below error, mod's config, additional mods, where is the server running etc.", e); } } From 7e7280bb82e03fd5475ade4cc2ecd39b378539d2 Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 6 Dec 2020 21:56:23 +0100 Subject: [PATCH 27/52] v --- .../net/szum123321/textile_backup/core/create/BackupHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index ab3c869..920e3d9 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -106,7 +106,7 @@ public class BackupHelper { if(ctx.startedByPlayer()) Statics.LOGGER.sendError(ctx, "If you have access to server console please take a look at it."); - Statics.LOGGER.error("Please let me know about this situation (include below error, mod's config, additional mods, where is the server running etc.", e); + Statics.LOGGER.error("Please let me know about this situation, include below error, mod's config, additional mods, where is the server running etc.", e); } } From 1b321b7a6498cc98eaf067214158682674fa14b6 Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 6 Dec 2020 22:09:19 +0100 Subject: [PATCH 28/52] Changed default dateTimeFormat to ISO standard --- src/main/java/net/szum123321/textile_backup/ConfigHandler.java | 2 +- src/main/java/net/szum123321/textile_backup/TextileBackup.java | 3 +-- .../szum123321/textile_backup/core/restore/AwaitThread.java | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java index b7eeca6..fca059d 100644 --- a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java +++ b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java @@ -98,7 +98,7 @@ public class ConfigHandler { "Remember not to use '#' symbol or any other character that is not allowed by your operating system such as:\n" + "':', '\\', etc...\n" + "For more info: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html\n") - public String dateTimeFormat = "dd.MM.yyyy_HH-mm-ss"; + public String dateTimeFormat = "yyyy.MM.dd_HH-mm-ss"; public Optional sanitize() { if(compressionCoreCountLimit > Runtime.getRuntime().availableProcessors()) diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index c8d75a9..3cca231 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -70,8 +70,7 @@ public class TextileBackup implements ModInitializer { //Restart Executor Service in singleplayer ServerLifecycleEvents.SERVER_STARTING.register(ignored -> { - if(Statics.executorService.isShutdown()) - Statics.executorService = Executors.newSingleThreadExecutor(); + if(Statics.executorService.isShutdown()) Statics.executorService = Executors.newSingleThreadExecutor(); }); ServerLifecycleEvents.SERVER_STOPPED.register(server -> { diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java b/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java index 0783c65..6c60ab7 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/AwaitThread.java @@ -44,7 +44,7 @@ public class AwaitThread extends Thread { // 𝄞 This is final count down! Tu ruru Tu, Tu Ru Tu Tu ♪ try { - Thread.sleep(delay * 1000); + Thread.sleep(delay * 1000L); } catch (InterruptedException e) { Statics.LOGGER.info("Backup restoration cancelled."); return; From e92ef1fb2845a3b441d5b129545dc45571998c5d Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 7 Dec 2020 00:02:54 +0100 Subject: [PATCH 29/52] Version bump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7ffa42c..f7ab039 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,6 @@ loader_version=0.10.8 fabric_version=0.26.3+1.16 # Mod Properties -mod_version = 2.1.0 +mod_version = 2.1.0-prev maven_group = net.szum123321 archives_base_name = textile_backup \ No newline at end of file From 75eec3e040d68faabfba37622c03d85af80abea9 Mon Sep 17 00:00:00 2001 From: Szum123321 <38787606+Szum123321@users.noreply.github.com> Date: Mon, 7 Dec 2020 00:05:53 +0100 Subject: [PATCH 30/52] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 134bdfd..cfb4598 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,11 @@ Commands look like that: `/backup [args]` Available operations are: * start - just starts backup. You can add comment* to file by just typing it after command. For example: `/backup start FabricIsGreat` - * restore - restores backup. Note that the current world will be backuped, and you can add comment to it. `/backup restore [comment]` + * restore - restores backup. Note that the current world will be backuped, and you can add comment to it. `/backup restore [comment]` * killR - terminate current restoration. * list - lists all avaliable backups. * cleanup - forces cleanup procedure (deletes old backups according to config) + * delete - delets given file, usage the same as restore * whitelist - here you can add, remove and list player that are allowed to run any operation within this mod despite not having high enough permission level* * blacklist - here you can add, remove and list player that are not allowed to run any operation within this mod despite having high enough permission level* From 09b809de8f5a1526079dd73ee6fa10fe09125ea4 Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 13 Dec 2020 12:30:58 +0100 Subject: [PATCH 31/52] Fixed #52 --- .../net/szum123321/textile_backup/core/create/BackupHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index 920e3d9..a2f8bd4 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -174,7 +174,7 @@ public class BackupHelper { } private static boolean deleteFile(File f, ServerCommandSource ctx) { - if(f != Statics.untouchableFile) { + if(!Statics.untouchableFile.equals(f)) { if(f.delete()) { Statics.LOGGER.sendInfoAL(ctx, "Deleting: {}", f.getName()); return true; From 927638e0b6daeafd679f760753e1a150137ab4ca Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 14 Dec 2020 12:56:36 +0100 Subject: [PATCH 32/52] consistency --- .../restore/decompressors/ZipDecompressor.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java index 79d6a27..a07e952 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/ZipDecompressor.java @@ -51,14 +51,15 @@ public class ZipDecompressor { } else { File parent = file.getParentFile(); - if (!parent.isDirectory() && !parent.mkdirs()) - throw new IOException("Failed to create directory " + parent); - - try (OutputStream outputStream = Files.newOutputStream(file.toPath()); - BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) { - IOUtils.copy(zipInputStream, bufferedOutputStream); - } catch (IOException e) { - Statics.LOGGER.error("An exception occurred while trying to decompress file: {}", file.getName(), e); + if (!parent.isDirectory() && !parent.mkdirs()) { + Statics.LOGGER.error("Failed to create {}", parent); + } else { + try (OutputStream outputStream = Files.newOutputStream(file.toPath()); + BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) { + IOUtils.copy(zipInputStream, bufferedOutputStream); + } catch (IOException e) { + Statics.LOGGER.error("An exception occurred while trying to decompress file: {}", file.getName(), e); + } } } } From c344e01c267afd4e61434ecb1b8b2a35c2610fc9 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 14 Dec 2020 13:18:16 +0100 Subject: [PATCH 33/52] Better CRC32 --- .../compressors/ParallelZipCompressor.java | 4 +--- .../create/compressors/ZipCompressor.java | 21 +++++++++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) 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 03ab145..dc6fd84 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 @@ -56,9 +56,7 @@ public class ParallelZipCompressor extends ZipCompressor { entry.setMethod(ZipArchiveOutputStream.STORED); entry.setSize(file.length()); entry.setCompressedSize(file.length()); - CRC32 sum = new CRC32(); - sum.update(Files.readAllBytes(file.toPath())); - entry.setCrc(sum.getValue()); + entry.setCrc(getCRC(file)); } else entry.setMethod(ZipEntry.DEFLATED); entry.setTime(System.currentTimeMillis()); 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 b46e666..41b830b 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 @@ -30,6 +30,7 @@ import java.io.*; import java.nio.file.Files; import java.time.LocalDateTime; import java.util.zip.CRC32; +import java.util.zip.Checksum; public class ZipCompressor extends AbstractCompressor { public static ZipCompressor getInstance() { @@ -37,7 +38,7 @@ public class ZipCompressor extends AbstractCompressor { } @Override - protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { + protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { ZipArchiveOutputStream arc = new ZipArchiveOutputStream(stream); arc.setMethod(ZipArchiveOutputStream.DEFLATED); @@ -57,9 +58,7 @@ public class ZipCompressor extends AbstractCompressor { entry.setMethod(ZipArchiveOutputStream.STORED); entry.setSize(file.length()); entry.setCompressedSize(file.length()); - CRC32 sum = new CRC32(); - sum.update(Files.readAllBytes(file.toPath())); - entry.setCrc(sum.getValue()); + entry.setCrc(getCRC(file)); } ((ZipArchiveOutputStream)arc).putArchiveEntry(entry); @@ -75,4 +74,18 @@ public class ZipCompressor extends AbstractCompressor { String[] arr = filename.split("\\."); return arr[arr.length - 1].contains("dat"); //includes dat_old } + + protected static long getCRC(File file) throws IOException { + Checksum sum = new CRC32(); + byte[] buffer = new byte[8192]; + int len; + + try (InputStream stream = new FileInputStream(file)) { + while ((len = stream.read(buffer)) != -1) sum.update(buffer, 0, len); + } catch (IOException e) { + throw new IOException("Error while calculating CRC of: " + file.getAbsolutePath(), e); + } + + return sum.getValue(); + } } From acba0d0cb82dfdd522ca29d3e69dffe2e1eaed90 Mon Sep 17 00:00:00 2001 From: szymon Date: Fri, 25 Dec 2020 19:34:36 +0100 Subject: [PATCH 34/52] File names now end with minecraft minor version and should not contain patch id. --- build.gradle | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2b9302d..610e8da 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 archivesBaseName = project.archives_base_name -version = "${project.mod_version}-${project.minecraft_version}" +version = "${project.mod_version}-${getMcMinor(project.minecraft_version)}" group = project.maven_group minecraft { @@ -95,3 +95,9 @@ publishing { // mavenLocal() } } + +static def getMcMinor(ver) { + String[] arr = ((String)ver).split("\\."); + + return (String)(arr[0] + "." + arr[1]); +} From 3c5976f19830f2a0c216b9ac99ad82c7acc92726 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 2 Jan 2021 17:20:12 +0100 Subject: [PATCH 35/52] Added uncompressed option --- .../textile_backup/ConfigHandler.java | 40 ++++++++++++------- .../textile_backup/core/Utilities.java | 19 +++------ .../core/create/MakeBackupRunnable.java | 12 +++++- .../core/restore/RestoreHelper.java | 2 +- .../decompressors/GenericTarDecompressor.java | 29 ++++++++++++-- 5 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java index fca059d..6ef018d 100644 --- a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java +++ b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java @@ -23,9 +23,7 @@ import io.github.cottonmc.cotton.config.annotations.ConfigFile; import java.io.File; import java.time.format.DateTimeFormatter; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; +import java.util.*; @ConfigFile(name = Statics.MOD_ID) public class ConfigHandler { @@ -53,7 +51,7 @@ public class ConfigHandler { @Comment("\nThis setting allows you to exclude files form being backedup.\n"+ "Be very careful when setting it, as it is easy corrupt your world!\n") - public Set fileBlacklist = new HashSet<>(); + public List fileBlacklist = new ArrayList<>(); @Comment("\nShould backups be deleted after being restored?\n") public boolean deleteOldBackupAfterRestore = true; @@ -79,7 +77,8 @@ public class ConfigHandler { "ZIP - normal zip archive using standard deflate compression\n" + "GZIP - tar.gz using gzip compression\n" + "BZIP2 - tar.bz2 archive using bzip2 compression\n" + - "LZMA - tar.xz using lzma compression\n") + "LZMA - tar.xz using lzma compression\n" + + "TAR - .tar with no compression\n") public ArchiveFormat format = ArchiveFormat.ZIP; @Comment("\nMinimal permission level required to run commands\n") @@ -124,19 +123,32 @@ public class ConfigHandler { } public enum ArchiveFormat { - ZIP(".zip"), - GZIP(".tar.gz"), - BZIP2(".tar.bz2"), - LZMA(".tar.xz"); + ZIP("zip"), + GZIP("tar", "gz"), + BZIP2("tar", "bz2"), + LZMA("tar", "xz"), + TAR("tar"); - private final String extension; + private final List extensionPieces; - private ArchiveFormat(String extension){ - this.extension = extension; + ArchiveFormat(String... extensionParts) { + extensionPieces = Arrays.asList(extensionParts); } - public String getString() { - return extension; + public String getCompleteString() { + StringBuilder builder = new StringBuilder(); + + extensionPieces.forEach(s -> builder.append('.').append(s)); + + return builder.toString(); + } + + boolean isMultipart() { + return extensionPieces.size() > 1; + } + + public String getLastPiece() { + return extensionPieces.get(extensionPieces.size() - 1); } } } diff --git a/src/main/java/net/szum123321/textile_backup/core/Utilities.java b/src/main/java/net/szum123321/textile_backup/core/Utilities.java index 25c2d5b..d494358 100644 --- a/src/main/java/net/szum123321/textile_backup/core/Utilities.java +++ b/src/main/java/net/szum123321/textile_backup/core/Utilities.java @@ -34,6 +34,7 @@ import java.nio.file.Path; import java.nio.file.attribute.FileTime; import java.time.*; import java.time.format.DateTimeFormatter; +import java.util.Arrays; import java.util.Optional; public class Utilities { @@ -106,19 +107,9 @@ public class Utilities { public static Optional getArchiveExtension(String fileName) { String[] parts = fileName.split("\\."); - switch (parts[parts.length - 1]) { - case "zip": - return Optional.of(ConfigHandler.ArchiveFormat.ZIP); - case "bz2": - return Optional.of(ConfigHandler.ArchiveFormat.BZIP2); - case "gz": - return Optional.of(ConfigHandler.ArchiveFormat.GZIP); - case "xz": - return Optional.of(ConfigHandler.ArchiveFormat.LZMA); - - default: - return Optional.empty(); - } + return Arrays.stream(ConfigHandler.ArchiveFormat.values()) + .filter(format -> format.getLastPiece().equals(parts[parts.length - 1])) + .findAny(); } public static Optional getArchiveExtension(File f) { @@ -129,7 +120,7 @@ public class Utilities { LocalDateTime creationTime = null; if(getArchiveExtension(file).isPresent()) { - String fileExtension = getArchiveExtension(file).get().getString(); + String fileExtension = getArchiveExtension(file).get().getCompleteString(); try { creationTime = LocalDateTime.from( 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 index fec0221..0231a06 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -22,6 +22,7 @@ import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.create.compressors.*; import net.szum123321.textile_backup.core.Utilities; +import net.szum123321.textile_backup.core.create.compressors.tar.AbstractTarArchiver; import net.szum123321.textile_backup.core.create.compressors.tar.LZMACompressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelBZip2Compressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor; @@ -29,6 +30,7 @@ import net.szum123321.textile_backup.core.create.compressors.ParallelZipCompress import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.time.LocalDateTime; public class MakeBackupRunnable implements Runnable { @@ -101,6 +103,14 @@ public class MakeBackupRunnable implements Runnable { LZMACompressor.getInstance().createArchive(world, outFile, context, coreCount); break; + case TAR: + new AbstractTarArchiver() { + protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { + return stream; + } + }.createArchive(world, outFile, context, coreCount); + break; + default: Statics.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", Statics.CONFIG.format); @@ -124,6 +134,6 @@ public class MakeBackupRunnable implements Runnable { return Utilities.getDateTimeFormatter().format(now) + (context.getComment() != null ? "#" + context.getComment().replace("#", "") : "") + - Statics.CONFIG.format.getString(); + Statics.CONFIG.format.getCompleteString(); } } diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index d7a14e3..cb89e0d 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -96,7 +96,7 @@ public class RestoreHelper { private RestoreableFile(File file) throws NoSuchElementException { this.file = file; archiveFormat = Utilities.getArchiveExtension(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file extension!")); - String extension = archiveFormat.getString(); + String extension = archiveFormat.getCompleteString(); creationTime = Utilities.getFileCreationTime(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file creation time!")); final String filename = file.getName(); diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java index cbe4118..a305b5b 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java @@ -23,7 +23,6 @@ import net.szum123321.textile_backup.core.Utilities; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.CompressorException; -import org.apache.commons.compress.compressors.CompressorInputStream; import org.apache.commons.compress.compressors.CompressorStreamFactory; import org.apache.commons.compress.utils.IOUtils; @@ -36,9 +35,9 @@ public class GenericTarDecompressor { public static void decompress(File input, File target) { Instant start = Instant.now(); - try (FileInputStream fileInputStream = new FileInputStream(input); - BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); - CompressorInputStream compressorInputStream = new CompressorStreamFactory().createCompressorInputStream(bufferedInputStream); + try (InputStream fileInputStream = new FileInputStream(input); + InputStream bufferedInputStream = new BufferedInputStream(fileInputStream); + InputStream compressorInputStream = getCompressorInputStream(bufferedInputStream); TarArchiveInputStream archiveInputStream = new TarArchiveInputStream(compressorInputStream)) { TarArchiveEntry entry; @@ -73,4 +72,26 @@ public class GenericTarDecompressor { Statics.LOGGER.info("Decompression took {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now()))); } + + private static InputStream getCompressorInputStream(InputStream inputStream) throws CompressorException { + try { + return new CompressorStreamFactory().createCompressorInputStream(inputStream); + } catch (CompressorException e) { + final byte[] tarHeader = new byte[512]; + int signatureLength; + + inputStream.mark(tarHeader.length); + + try { + signatureLength = IOUtils.readFully(inputStream, tarHeader); + inputStream.reset(); + } catch (IOException e1) { + throw new CompressorException("IOException while reading tar signature", e1); + } + + if(TarArchiveInputStream.matches(tarHeader, signatureLength)) return inputStream; + + throw e; + } + } } \ No newline at end of file From f3982d78c090f33c67301cdd7f34deb8f2064e22 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 2 Jan 2021 17:20:56 +0100 Subject: [PATCH 36/52] . --- .../szum123321/textile_backup/core/Utilities.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/Utilities.java b/src/main/java/net/szum123321/textile_backup/core/Utilities.java index d494358..5a72687 100644 --- a/src/main/java/net/szum123321/textile_backup/core/Utilities.java +++ b/src/main/java/net/szum123321/textile_backup/core/Utilities.java @@ -96,10 +96,7 @@ public class Utilities { } } - for(String i : Statics.CONFIG.fileBlacklist) { - if(path.startsWith(i)) - return true; - } + for(String i : Statics.CONFIG.fileBlacklist) if(path.startsWith(i)) return true; return false; } @@ -170,12 +167,9 @@ public class Utilities { public static String formatDuration(Duration duration) { DateTimeFormatter formatter; - if(duration.toHours() > 0) - formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS"); - else if(duration.toMinutes() > 0) - formatter = DateTimeFormatter.ofPattern("mm:ss.SSS"); - else - formatter = DateTimeFormatter.ofPattern("ss.SSS"); + if(duration.toHours() > 0) formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS"); + else if(duration.toMinutes() > 0) formatter = DateTimeFormatter.ofPattern("mm:ss.SSS"); + else formatter = DateTimeFormatter.ofPattern("ss.SSS"); return LocalTime.ofNanoOfDay(duration.toNanos()).format(formatter); } From 18e8860f429bec9fb3fd5d62b2435ed09d6ec25d Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 13 Jun 2021 21:25:52 +0200 Subject: [PATCH 37/52] 1.17 update --- build.gradle | 45 +++++++++--------- gradle.properties | 8 ++-- gradle/wrapper/gradle-wrapper.jar | Bin 58694 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- .../textile_backup/core/Utilities.java | 6 +-- 5 files changed, 29 insertions(+), 32 deletions(-) diff --git a/build.gradle b/build.gradle index 610e8da..9f323bd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.5-SNAPSHOT' + id 'fabric-loom' version '0.8-SNAPSHOT' id 'maven-publish' } @@ -14,7 +14,7 @@ minecraft { } repositories{ - maven { url 'http://server.bbkr.space:8081/artifactory/libs-release' } + maven { url 'https://server.bbkr.space/artifactory/libs-release' } maven { url 'https://jitpack.io' } } @@ -22,38 +22,33 @@ dependencies { //to change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modCompile "net.fabricmc:fabric-loader:${project.loader_version}" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" // Fabric API. This is technically optional, but you probably want it anyway. - modCompile "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modCompile "io.github.cottonmc.cotton:cotton-config:1.0.0-rc.7" + modImplementation "io.github.cottonmc.cotton:cotton-config:1.0.0-rc.7" include "io.github.cottonmc:Jankson-Fabric:3.0.0+j1.2.0" include "io.github.cottonmc.cotton:cotton-logging:1.0.0-rc.4" include "io.github.cottonmc.cotton:cotton-config:1.0.0-rc.7" - modCompile "org.apache.commons:commons-compress:1.19" + modImplementation "org.apache.commons:commons-compress:1.19" include "org.apache.commons:commons-compress:1.19" - modCompile "org.tukaani:xz:1.8" + modImplementation "org.tukaani:xz:1.8" include "org.tukaani:xz:1.8" - modCompile 'com.github.shevek:parallelgzip:master-SNAPSHOT' + modImplementation 'com.github.shevek:parallelgzip:master-SNAPSHOT' include 'com.github.shevek:parallelgzip:master-SNAPSHOT' } processResources { inputs.property "version", project.version - from(sourceSets.main.resources.srcDirs) { - include "fabric.mod.json" + filesMatching("fabric.mod.json") { expand "version": project.version } - - from(sourceSets.main.resources.srcDirs) { - exclude "fabric.mod.json" - } } // ensure that the encoding is set to UTF-8, no matter what the system default is @@ -63,18 +58,18 @@ tasks.withType(JavaCompile) { options.encoding = "UTF-8" } -// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task -// if it is present. -// If you remove this task, sources will not be generated. -task sourcesJar(type: Jar, dependsOn: classes) { - classifier = "sources" - from sourceSets.main.allSource +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() } jar { - from "LICENSE" + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } } - // configure the maven publication publishing { publications { @@ -92,7 +87,11 @@ publishing { // select the repositories you want to publish to repositories { // uncomment to publish to the local maven - // mavenLocal() + + maven { + name = 'myRepo' + url = layout.buildDirectory.dir("repo") + } } } diff --git a/gradle.properties b/gradle.properties index f7ab039..4e94c3b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,12 +1,12 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G -minecraft_version=1.16.4 -yarn_mappings=1.16.4+build.7 -loader_version=0.10.8 +minecraft_version=1.17 +yarn_mappings=1.17+build.10 +loader_version=0.11.5 #Fabric api -fabric_version=0.26.3+1.16 +fabric_version=0.35.1+1.17 # Mod Properties mod_version = 2.1.0-prev diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 490fda8577df6c95960ba7077c43220e5bb2c0d9..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 6763 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 Date: Sun, 13 Jun 2021 21:26:57 +0200 Subject: [PATCH 38/52] Make it compile and a bit of cleanup --- .../textile_backup/core/create/MakeBackupRunnable.java | 2 -- .../core/create/compressors/ParallelZipCompressor.java | 2 -- .../textile_backup/core/create/compressors/ZipCompressor.java | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) 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 index 0231a06..49fefde 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -26,8 +26,6 @@ import net.szum123321.textile_backup.core.create.compressors.tar.AbstractTarArch import net.szum123321.textile_backup.core.create.compressors.tar.LZMACompressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelBZip2Compressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor; -import net.szum123321.textile_backup.core.create.compressors.ParallelZipCompressor; - import java.io.File; import java.io.IOException; import java.io.OutputStream; 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 dc6fd84..d943588 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 @@ -24,9 +24,7 @@ import org.apache.commons.compress.archivers.zip.*; import org.apache.commons.compress.parallel.InputStreamSupplier; import java.io.*; -import java.nio.file.Files; import java.util.concurrent.*; -import java.util.zip.CRC32; import java.util.zip.ZipEntry; /* 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 41b830b..46f2c35 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 @@ -38,7 +38,7 @@ public class ZipCompressor extends AbstractCompressor { } @Override - protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { + protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { ZipArchiveOutputStream arc = new ZipArchiveOutputStream(stream); arc.setMethod(ZipArchiveOutputStream.DEFLATED); From 5cfb5c393a9e989b05503c88c0fd6f7ec807153c Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 13 Jun 2021 21:27:08 +0200 Subject: [PATCH 39/52] Version bump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 4e94c3b..f2c252a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,6 @@ loader_version=0.11.5 fabric_version=0.35.1+1.17 # Mod Properties -mod_version = 2.1.0-prev +mod_version = 2.1.0-prev2 maven_group = net.szum123321 archives_base_name = textile_backup \ No newline at end of file From 95653d066d9144353f17a748f99fba479ddf09fb Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 13 Jun 2021 21:44:38 +0200 Subject: [PATCH 40/52] Added slightly more graceful error handling for THE ISSUE --- .../core/create/compressors/ParallelZipCompressor.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 d943588..b3a2725 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 @@ -64,7 +64,14 @@ public class ParallelZipCompressor extends ZipCompressor { @Override protected void finish(OutputStream arc) throws InterruptedException, ExecutionException, IOException { - scatterZipCreator.writeTo((ZipArchiveOutputStream) arc); + try { + scatterZipCreator.writeTo((ZipArchiveOutputStream) arc); + } catch (IOException e) { + if(e.getMessage().equals("No space left on device")) { + Statics.LOGGER.error("Don't panic! This is a known issue! For help see: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"); + throw e; + } + } } static class FileInputStreamSupplier implements InputStreamSupplier { From 2ba6ba444cc853279ee7dc0019371c6b77217ccc Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 13 Jun 2021 22:26:05 +0200 Subject: [PATCH 41/52] Changed chat message prefix color to match mod's theme. Slightly improved functions notifyPlayer in BackupHelper and RestoreHelper --- .../textile_backup/core/CustomLogger.java | 4 +-- .../core/create/BackupHelper.java | 16 +++++++--- .../core/restore/RestoreHelper.java | 32 +++++++++++++------ 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java index 35d1a6b..b40fea2 100644 --- a/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java +++ b/src/main/java/net/szum123321/textile_backup/core/CustomLogger.java @@ -46,11 +46,11 @@ public class CustomLogger { this.messageFactory = ParameterizedMessageFactory.INSTANCE; this.logger = LogManager.getLogger(name, messageFactory); this.prefix = "[" + prefix + "]" + " "; - this.prefixText = new LiteralText(this.prefix).formatted(Formatting.AQUA); + this.prefixText = new LiteralText(this.prefix).styled(style -> style.withColor(0x5B23DA)); } public MutableText getPrefixText() { - return prefixText; + return prefixText.shallowCopy(); } public void log(Level level, String msg, Object... data) { diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index a2f8bd4..4063861 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -37,6 +37,7 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; public class BackupHelper { @@ -73,7 +74,6 @@ public class BackupHelper { ); MutableText text = Statics.LOGGER.getPrefixText() - .shallowCopy() .append(new LiteralText("In order for backup to be up-to-date call ").formatted(Formatting.WHITE)) .append( new LiteralText("[/save-all flush]") @@ -89,7 +89,6 @@ public class BackupHelper { ctx.getCommandSource().sendFeedback(text, false); text = Statics.LOGGER.getPrefixText() - .shallowCopy() .append(new LiteralText("This is known issue (See ").formatted(Formatting.WHITE)) .append( new LiteralText("https://github.com/Szum123321/textile_backup/issues/42") @@ -114,13 +113,20 @@ public class BackupHelper { } private static void notifyPlayers(BackupContext ctx) { - MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); + MutableText message = Statics.LOGGER.getPrefixText(); message.append(new LiteralText("Warning! Server backup will begin shortly. You may experience some lag.").formatted(Formatting.WHITE)); + UUID uuid; + + if(ctx.getInitiator().equals(ActionInitiator.Player) && ctx.getCommandSource().getEntity() != null) + uuid = ctx.getCommandSource().getEntity().getUuid(); + else + uuid = Util.NIL_UUID; + ctx.getServer().getPlayerManager().broadcastChatMessage( message, - MessageType.GAME_INFO, - ctx.getInitiator() == ActionInitiator.Player ? ctx.getCommandSource().getEntity().getUuid() : Util.NIL_UUID + MessageType.SYSTEM, + uuid ); } diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index cb89e0d..c8265e9 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -20,7 +20,9 @@ package net.szum123321.textile_backup.core.restore; import net.minecraft.network.MessageType; import net.minecraft.server.MinecraftServer; +import net.minecraft.text.LiteralText; import net.minecraft.text.MutableText; +import net.minecraft.util.Formatting; import net.minecraft.util.Util; import net.szum123321.textile_backup.ConfigHandler; import net.szum123321.textile_backup.Statics; @@ -30,10 +32,7 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -58,7 +57,7 @@ public class RestoreHelper { else Statics.LOGGER.info("Backup restoration was initiated form Server Console"); - notifyPlayer(ctx); + notifyPlayers(ctx); return new AwaitThread( Statics.CONFIG.restoreDelay, @@ -66,14 +65,27 @@ public class RestoreHelper { ); } - private static void notifyPlayer(RestoreContext ctx) { - MutableText message = Statics.LOGGER.getPrefixText().shallowCopy(); - message.append("Warning! The server is going to shut down in " + Statics.CONFIG.restoreDelay + " seconds!"); + private static void notifyPlayers(RestoreContext ctx) { + MutableText message = Statics.LOGGER.getPrefixText(); + message.append( + new LiteralText( + "Warning! The server is going to shut down in " + + Statics.CONFIG.restoreDelay + + " seconds!" + ).formatted(Formatting.WHITE) + ); + + UUID uuid; + + if(ctx.getInitiator().equals(ActionInitiator.Player) && ctx.getCommandSource().getEntity() != null) + uuid = ctx.getCommandSource().getEntity().getUuid(); + else + uuid = Util.NIL_UUID; ctx.getServer().getPlayerManager().broadcastChatMessage( message, - MessageType.GAME_INFO, - ctx.getInitiator() == ActionInitiator.Player ? ctx.getCommandSource().getEntity().getUuid() : Util.NIL_UUID + MessageType.SYSTEM, + uuid ); } From d322f6dc26689f4d08110f4cfd2acecd944d734c Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 13 Jun 2021 22:26:17 +0200 Subject: [PATCH 42/52] Mc version bump --- src/main/resources/fabric.mod.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index aa800fb..10552dd 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -34,9 +34,9 @@ ], "depends": { - "fabricloader": ">=0.8.8", + "fabricloader": ">=0.11", "fabric": "*", - "minecraft": "1.16.*" + "minecraft": "1.17.*" }, "custom": { From 24455d2e5c83454741142e5267c1f8c3c88ac1f2 Mon Sep 17 00:00:00 2001 From: szymon Date: Mon, 14 Jun 2021 23:08:56 +0200 Subject: [PATCH 43/52] Last version didn't work with different system languages. This now works but basically depends on a regex --- .../core/NoSpaceLeftOnDeviceException.java | 12 ++++ .../compressors/AbstractCompressor.java | 17 ++++- .../compressors/ParallelZipCompressor.java | 67 +++++++++++++++++-- 3 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/szum123321/textile_backup/core/NoSpaceLeftOnDeviceException.java diff --git a/src/main/java/net/szum123321/textile_backup/core/NoSpaceLeftOnDeviceException.java b/src/main/java/net/szum123321/textile_backup/core/NoSpaceLeftOnDeviceException.java new file mode 100644 index 0000000..b9158c2 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/NoSpaceLeftOnDeviceException.java @@ -0,0 +1,12 @@ +package net.szum123321.textile_backup.core; + +import java.io.IOException; + +/** + * Wrapper for specific IOException. Temporary way to get more info about issue #51 + */ +public class NoSpaceLeftOnDeviceException extends IOException { + public NoSpaceLeftOnDeviceException(Throwable cause) { + super(cause); + } +} 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 361f666..87b9b5c 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 @@ -20,6 +20,7 @@ package net.szum123321.textile_backup.core.create.compressors; import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.ActionInitiator; +import net.szum123321.textile_backup.core.NoSpaceLeftOnDeviceException; import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.BackupContext; @@ -44,19 +45,31 @@ public abstract class AbstractCompressor { .filter(File::isFile) .forEach(file -> { try { + //hopefully bad broken file won't spoil the whole archive addEntry(file, inputFile.toPath().relativize(file.toPath()).toString(), arc); } catch (IOException e) { Statics.LOGGER.error("An exception occurred while trying to compress: {}", file.getName(), e); - if(ctx.getInitiator() == ActionInitiator.Player) + if (ctx.getInitiator() == ActionInitiator.Player) Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); } }); finish(arc); + } catch(NoSpaceLeftOnDeviceException e) { + Statics.LOGGER.error("CRITICAL ERROR OCCURRED!"); + Statics.LOGGER.error("The backup is corrupted."); + Statics.LOGGER.error("Don't panic! This is a known issue!"); + Statics.LOGGER.error("For help see: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"); + Statics.LOGGER.error("In case this isn't it here's also the exception itself!", e); + + if(ctx.getInitiator() == ActionInitiator.Player) { + Statics.LOGGER.sendError(ctx, "Backup failed. The file is corrupt."); + Statics.LOGGER.error("For help see: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"); + } } catch (IOException | InterruptedException | ExecutionException e) { Statics.LOGGER.error("An exception occurred!", e); - + } catch (Exception e) { if(ctx.getInitiator() == ActionInitiator.Player) Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); } 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 b3a2725..6db0238 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 @@ -19,11 +19,13 @@ package net.szum123321.textile_backup.core.create.compressors; import net.szum123321.textile_backup.Statics; +import net.szum123321.textile_backup.core.NoSpaceLeftOnDeviceException; import net.szum123321.textile_backup.core.create.BackupContext; import org.apache.commons.compress.archivers.zip.*; import org.apache.commons.compress.parallel.InputStreamSupplier; import java.io.*; +import java.util.Objects; import java.util.concurrent.*; import java.util.zip.ZipEntry; @@ -34,6 +36,19 @@ import java.util.zip.ZipEntry; https://stackoverflow.com/users/2987755/dkb */ public class ParallelZipCompressor extends ZipCompressor { + //These fields are used to discriminate against the issue #51 + private final static SimpleStackTraceElement[] STACKTRACE = { + new SimpleStackTraceElement("sun.nio.ch.FileDispatcherImpl", "write0", true), + new SimpleStackTraceElement("sun.nio.ch.FileDispatcherImpl", "write", false), + new SimpleStackTraceElement("sun.nio.ch.IOUtil", "writeFromNativeBuffer", false), + new SimpleStackTraceElement("sun.nio.ch.IOUtil", "write", false), + new SimpleStackTraceElement("sun.nio.ch.FileChannelImpl", "write", false), + new SimpleStackTraceElement("java.nio.channels.Channels", "writeFullyImpl", false), + new SimpleStackTraceElement("java.nio.channels.Channels", "writeFully", false), + new SimpleStackTraceElement("java.nio.channels.Channels$1", "write", false), + new SimpleStackTraceElement("org.apache.commons.compress.parallel.FileBasedScatterGatherBackingStore", "writeOut", false) + }; + private ParallelScatterZipCreator scatterZipCreator; public static ParallelZipCompressor getInstance() { @@ -63,14 +78,56 @@ public class ParallelZipCompressor extends ZipCompressor { } @Override - protected void finish(OutputStream arc) throws InterruptedException, ExecutionException, IOException { + protected void finish(OutputStream arc) throws InterruptedException, IOException, ExecutionException { + /* + This is perhaps the most dreadful line of this whole mess + This line causes the infamous Out of space error + */ try { scatterZipCreator.writeTo((ZipArchiveOutputStream) arc); - } catch (IOException e) { - if(e.getMessage().equals("No space left on device")) { - Statics.LOGGER.error("Don't panic! This is a known issue! For help see: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"); - throw e; + } catch (ExecutionException e) { + Throwable cause; + if((cause = e.getCause()).getClass().equals(IOException.class)) { + //The out of space exception is thrown at sun.nio.ch.FileDispatcherImpl.write0(Native Method) + boolean match = (cause.getStackTrace().length >= STACKTRACE.length); + if(match) { + for(int i = 0; i < STACKTRACE.length && match; i++) + if(!STACKTRACE[i].equals(cause.getStackTrace()[i])) { + //Statics.LOGGER.error("Mismatch at: {}, classname: {}, methodname: {}, {}", i, cause.getStackTrace()[i].getClassName(), cause.getStackTrace()[i].getMethodName()); + match = false; + } + + //For clarity sake let's not throw the ExecutionException itself rather only the cause, as the EE is just the wrapper + if(match) throw new NoSpaceLeftOnDeviceException(cause); + } } + + throw e; + } + } + + private static class SimpleStackTraceElement { + private final String className; + private final String methodName; + private final boolean isNative; + + public SimpleStackTraceElement(String className, String methodName, boolean isNative) { + this.className = className; + this.methodName = methodName; + this.isNative = isNative; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if(o.getClass() == StackTraceElement.class) { + StackTraceElement that = (StackTraceElement) o; + return (isNative == that.isNativeMethod()) && Objects.equals(className, that.getClassName()) && Objects.equals(methodName, that.getMethodName()); + } + if(getClass() != o.getClass()) return false; + SimpleStackTraceElement that = (SimpleStackTraceElement) o; + return isNative == that.isNative && Objects.equals(className, that.className) && Objects.equals(methodName, that.methodName); } } From adc14273d097690bbb8645f2a4de683ce205b929 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 16 Jun 2021 22:42:11 +0200 Subject: [PATCH 44/52] Java 16 update --- build.gradle | 4 +- .../textile_backup/TextileBackup.java | 7 +-- .../core/create/BackupContext.java | 21 ++++----- .../core/create/MakeBackupRunnable.java | 45 +++++++------------ .../compressors/ParallelZipCompressor.java | 24 +++------- .../compressors/tar/AbstractTarArchiver.java | 7 +-- .../core/restore/RestoreContext.java | 14 +++--- .../core/restore/RestoreHelper.java | 5 +-- src/main/resources/fabric.mod.json | 3 +- src/main/resources/textile_backup.mixins.json | 2 +- 10 files changed, 50 insertions(+), 82 deletions(-) diff --git a/build.gradle b/build.gradle index 9f323bd..3d42bd6 100644 --- a/build.gradle +++ b/build.gradle @@ -3,8 +3,8 @@ plugins { id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = JavaVersion.VERSION_16 +targetCompatibility = JavaVersion.VERSION_16 archivesBaseName = project.archives_base_name version = "${project.mod_version}-${getMcMinor(project.minecraft_version)}" diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index 3cca231..e2ffd7b 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -59,9 +59,10 @@ public class TextileBackup implements ModInitializer { if(Statics.CONFIG.format == ConfigHandler.ArchiveFormat.ZIP) { Statics.tmpAvailable = Utilities.isTmpAvailable(); if(!Statics.tmpAvailable) { - Statics.LOGGER.warn("WARNING! It seems like the temporary folder is not accessible on this system!\n" + - "This will cause problems with multithreaded zip compression, so a normal one will be used instead.\n" + - "For more info please read: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"); + Statics.LOGGER.warn(""" + WARNING! It seems like the temporary folder is not accessible on this system! + This will cause problems with multithreaded zip compression, so a normal one will be used instead. + For more info please read: https://github.com/Szum123321/textile_backup/wiki/ZIP-Problems"""); } } 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 index 6a64f92..ac729bc 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupContext.java @@ -24,14 +24,11 @@ import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.core.ActionInitiator; import org.jetbrains.annotations.NotNull; -public class BackupContext { - private final MinecraftServer server; - private final ServerCommandSource commandSource; - private final ActionInitiator initiator; - private final boolean save; - private final String comment; - - protected BackupContext(@NotNull MinecraftServer server, ServerCommandSource commandSource, @NotNull ActionInitiator initiator, boolean save, String comment) { +public record BackupContext(MinecraftServer server, + ServerCommandSource commandSource, + ActionInitiator initiator, boolean save, + String comment) { + public BackupContext(@NotNull MinecraftServer server, ServerCommandSource commandSource, @NotNull ActionInitiator initiator, boolean save, String comment) { this.server = server; this.commandSource = commandSource; this.initiator = initiator; @@ -117,14 +114,14 @@ public class BackupContext { } public BackupContext build() { - if(guessInitiator) { + if (guessInitiator) { initiator = commandSource.getEntity() instanceof PlayerEntity ? ActionInitiator.Player : ActionInitiator.ServerConsole; - } else if(initiator == null) { + } else if (initiator == null) { initiator = ActionInitiator.Null; } - if(server == null) { - if(commandSource != null) + if (server == null) { + if (commandSource != null) setServer(commandSource.getMinecraftServer()); else throw new RuntimeException("Both MinecraftServer and ServerCommandSource weren't provided!"); 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 index 49fefde..3bf1520 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -23,9 +23,10 @@ import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.create.compressors.*; import net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.create.compressors.tar.AbstractTarArchiver; -import net.szum123321.textile_backup.core.create.compressors.tar.LZMACompressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelBZip2Compressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor; +import org.apache.commons.compress.compressors.lzma.LZMACompressorOutputStream; + import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -81,42 +82,26 @@ public class MakeBackupRunnable implements Runnable { Statics.LOGGER.trace("Running compression on {} threads. Available cores: {}", coreCount, Runtime.getRuntime().availableProcessors()); switch (Statics.CONFIG.format) { - case ZIP: { - if(Statics.tmpAvailable && coreCount > 1) + case ZIP -> { + if (Statics.tmpAvailable && coreCount > 1) ParallelZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); else ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); - break; } - - case BZIP2: - ParallelBZip2Compressor.getInstance().createArchive(world, outFile, context, coreCount); - break; - - case GZIP: - ParallelGzipCompressor.getInstance().createArchive(world, outFile, context, coreCount); - break; - - case LZMA: - LZMACompressor.getInstance().createArchive(world, outFile, context, coreCount); - break; - - case TAR: - new AbstractTarArchiver() { - protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { - return stream; - } - }.createArchive(world, outFile, context, coreCount); - break; - - default: + 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); + default -> { Statics.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", Statics.CONFIG.format); - - if(context.getInitiator() == ActionInitiator.Player) + if (context.getInitiator() == ActionInitiator.Player) Statics.LOGGER.sendError(context.getCommandSource(), "Error! No correct compression format specified! Using default compressor!"); - ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount); - break; + } } BackupHelper.executeFileLimit(context.getCommandSource(), Utilities.getLevelName(context.getServer())); 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 6db0238..b7a0c9e 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 @@ -106,17 +106,11 @@ public class ParallelZipCompressor extends ZipCompressor { } } - private static class SimpleStackTraceElement { - private final String className; - private final String methodName; - private final boolean isNative; - - public SimpleStackTraceElement(String className, String methodName, boolean isNative) { - this.className = className; - this.methodName = methodName; - this.isNative = isNative; - } - + private static record SimpleStackTraceElement ( + String className, + String methodName, + boolean isNative + ) { @Override public boolean equals(Object o) { if (this == o) return true; @@ -131,13 +125,7 @@ public class ParallelZipCompressor extends ZipCompressor { } } - static class FileInputStreamSupplier implements InputStreamSupplier { - private final File sourceFile; - - FileInputStreamSupplier(File sourceFile) { - this.sourceFile = sourceFile; - } - + record FileInputStreamSupplier(File sourceFile) implements InputStreamSupplier { public InputStream get() { try { return new FileInputStream(sourceFile); 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 e942f43..fe066bb 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 @@ -29,9 +29,10 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; -public abstract class AbstractTarArchiver extends AbstractCompressor { - - protected abstract OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException; +public class AbstractTarArchiver extends AbstractCompressor { + protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { + return stream; + } @Override protected OutputStream createArchiveOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java index b7352a2..a3719bd 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreContext.java @@ -25,14 +25,10 @@ import net.szum123321.textile_backup.core.ActionInitiator; import javax.annotation.Nullable; -public class RestoreContext { - private final RestoreHelper.RestoreableFile file; - private final MinecraftServer server; - @Nullable - private final String comment; - private final ActionInitiator initiator; - private final ServerCommandSource commandSource; - +public record RestoreContext(RestoreHelper.RestoreableFile file, + MinecraftServer server, @Nullable String comment, + ActionInitiator initiator, + ServerCommandSource commandSource) { public RestoreContext(RestoreHelper.RestoreableFile file, MinecraftServer server, @Nullable String comment, ActionInitiator initiator, ServerCommandSource commandSource) { this.file = file; this.server = server; @@ -96,7 +92,7 @@ public class RestoreContext { } public RestoreContext build() { - if(server == null) server = serverCommandSource.getMinecraftServer(); + if (server == null) server = serverCommandSource.getMinecraftServer(); ActionInitiator initiator = serverCommandSource.getEntity() instanceof PlayerEntity ? ActionInitiator.Player : ActionInitiator.ServerConsole; diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index c8265e9..7ceec62 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -34,7 +34,6 @@ import java.io.File; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.Stream; public class RestoreHelper { public static Optional findFileAndLockIfPresent(LocalDateTime backupTime, MinecraftServer server) { @@ -42,7 +41,7 @@ public class RestoreHelper { Optional optionalFile = Arrays.stream(root.listFiles()) .map(RestoreableFile::newInstance) - .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) + .flatMap(Optional::stream) .filter(rf -> rf.getCreationTime().equals(backupTime)) .findFirst(); @@ -95,7 +94,7 @@ public class RestoreHelper { return Arrays.stream(root.listFiles()) .filter(Utilities::isValidBackup) .map(RestoreableFile::newInstance) - .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) + .flatMap(Optional::stream) .collect(Collectors.toList()); } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 10552dd..d7e5138 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -36,7 +36,8 @@ "depends": { "fabricloader": ">=0.11", "fabric": "*", - "minecraft": "1.17.*" + "minecraft": "1.17.*", + "java": ">=16" }, "custom": { diff --git a/src/main/resources/textile_backup.mixins.json b/src/main/resources/textile_backup.mixins.json index c53eeb8..9260b26 100644 --- a/src/main/resources/textile_backup.mixins.json +++ b/src/main/resources/textile_backup.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "net.szum123321.textile_backup.mixin", - "compatibilityLevel": "JAVA_8", + "compatibilityLevel": "JAVA_16", "mixins": [ "MinecraftServerMixin", "MinecraftServerSessionAccessor" From 78128bc63b4005bdaa7fc823f6da4c678c6be3fe Mon Sep 17 00:00:00 2001 From: szymon Date: Thu, 17 Jun 2021 22:17:55 +0200 Subject: [PATCH 45/52] Slightly beeter logs --- .../textile_backup/commands/manage/ListBackupsCommand.java | 2 +- .../core/create/compressors/AbstractCompressor.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java b/src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java index 076770e..2deb6d8 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/manage/ListBackupsCommand.java @@ -40,7 +40,7 @@ public class ListBackupsCommand { } else { backups.sort(null); Iterator iterator = backups.iterator(); - builder.append("Available backups: "); + builder.append("Available backups:\n"); builder.append(iterator.next()); 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 87b9b5c..a4634d0 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 @@ -45,10 +45,10 @@ public abstract class AbstractCompressor { .filter(File::isFile) .forEach(file -> { try { - //hopefully bad broken file won't spoil the whole archive + //hopefully one broken file won't spoil the whole archive addEntry(file, inputFile.toPath().relativize(file.toPath()).toString(), arc); } catch (IOException e) { - Statics.LOGGER.error("An exception occurred while trying to compress: {}", file.getName(), e); + Statics.LOGGER.error("An exception occurred while trying to compress: {}", inputFile.toPath().relativize(file.toPath()).toString(), e); if (ctx.getInitiator() == ActionInitiator.Player) Statics.LOGGER.sendError(ctx, "Something went wrong while compressing files!"); From 0a5b5e5c541464588d6e4d5c68cbe43277c91aba Mon Sep 17 00:00:00 2001 From: szymon Date: Thu, 17 Jun 2021 22:20:37 +0200 Subject: [PATCH 46/52] Forgot to remove LZMACompressor.java --- .../compressors/tar/LZMACompressor.java | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java diff --git a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java b/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java deleted file mode 100644 index 15879b4..0000000 --- a/src/main/java/net/szum123321/textile_backup/core/create/compressors/tar/LZMACompressor.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * A simple backup mod for Fabric - * Copyright (C) 2020 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.compressors.tar; - -import net.szum123321.textile_backup.core.create.BackupContext; -import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream; - -import java.io.*; - -public class LZMACompressor extends AbstractTarArchiver { - public static LZMACompressor getInstance() { - return new LZMACompressor(); - } - - @Override - protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) throws IOException { - return new XZCompressorOutputStream(stream); - } -} \ No newline at end of file From d0772b44ebe2c7d41285203ad6389965eb38eab2 Mon Sep 17 00:00:00 2001 From: szymon Date: Thu, 17 Jun 2021 22:24:58 +0200 Subject: [PATCH 47/52] i think it's time --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f2c252a..dc60769 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,6 @@ loader_version=0.11.5 fabric_version=0.35.1+1.17 # Mod Properties -mod_version = 2.1.0-prev2 +mod_version = 2.1.0 maven_group = net.szum123321 archives_base_name = textile_backup \ No newline at end of file From af8e14f092ff51dad22bba4abef4205a56afbf91 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 19 Jun 2021 14:42:22 +0200 Subject: [PATCH 48/52] Repaired #42 --- .../net/szum123321/textile_backup/Statics.java | 1 + .../core/create/BackupHelper.java | 8 +++----- .../core/create/MakeBackupRunnable.java | 2 ++ .../mixin/DedicatedServerWatchdogMixin.java | 17 +++++++++++++++++ src/main/resources/textile_backup.mixins.json | 1 + 5 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 src/main/java/net/szum123321/textile_backup/mixin/DedicatedServerWatchdogMixin.java diff --git a/src/main/java/net/szum123321/textile_backup/Statics.java b/src/main/java/net/szum123321/textile_backup/Statics.java index 995a40c..c56212c 100644 --- a/src/main/java/net/szum123321/textile_backup/Statics.java +++ b/src/main/java/net/szum123321/textile_backup/Statics.java @@ -40,6 +40,7 @@ public class Statics { public final static DateTimeFormatter defaultDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss"); public static final AtomicBoolean globalShutdownBackupFlag = new AtomicBoolean(true); + public static boolean disableWatchdog = false; public static AwaitThread restoreAwaitThread = null; public static File untouchableFile; diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index 4063861..deb8157 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -20,8 +20,6 @@ package net.szum123321.textile_backup.core.create; import net.minecraft.network.MessageType; import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; import net.minecraft.text.LiteralText; import net.minecraft.text.MutableText; import net.minecraft.util.Formatting; @@ -69,10 +67,9 @@ public class BackupHelper { try { ctx.getServer().save(false, true, true); } catch (Exception e) { - Statics.LOGGER.sendErrorAL(ctx,"An exception occurred when trying to save the world!\n" - + "But don't worry, backup will continue, although data may be not up-to-date." + Statics.LOGGER.sendErrorAL(ctx,"An exception occurred when trying to save the world!" ); - +/* MutableText text = Statics.LOGGER.getPrefixText() .append(new LiteralText("In order for backup to be up-to-date call ").formatted(Formatting.WHITE)) .append( @@ -106,6 +103,7 @@ public class BackupHelper { Statics.LOGGER.sendError(ctx, "If you have access to server console please take a look at it."); Statics.LOGGER.error("Please let me know about this situation, include below error, mod's config, additional mods, where is the server running etc.", e); + */ } } 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 index 3bf1520..5138a37 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -43,6 +43,7 @@ public class MakeBackupRunnable implements Runnable { public void run() { try { Utilities.disableWorldSaving(context.getServer()); + Statics.disableWatchdog = true; Statics.LOGGER.sendInfoAL(context, "Starting backup"); @@ -109,6 +110,7 @@ public class MakeBackupRunnable implements Runnable { Statics.LOGGER.sendInfoAL(context, "Done!"); } finally { Utilities.enableWorldSaving(context.getServer()); + Statics.disableWatchdog = false; } } diff --git a/src/main/java/net/szum123321/textile_backup/mixin/DedicatedServerWatchdogMixin.java b/src/main/java/net/szum123321/textile_backup/mixin/DedicatedServerWatchdogMixin.java new file mode 100644 index 0000000..91393b2 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/mixin/DedicatedServerWatchdogMixin.java @@ -0,0 +1,17 @@ +package net.szum123321.textile_backup.mixin; + +import net.minecraft.server.dedicated.DedicatedServerWatchdog; +import net.minecraft.util.Util; +import net.szum123321.textile_backup.Statics; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(DedicatedServerWatchdog.class) +public class DedicatedServerWatchdogMixin { + + @ModifyVariable(method = "run()V", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/Util;getMeasuringTimeMs()J"), ordinal = 0, name = "l") + private long redirectedCall(long original) { + return Statics.disableWatchdog ? Util.getMeasuringTimeMs() : original; + } +} diff --git a/src/main/resources/textile_backup.mixins.json b/src/main/resources/textile_backup.mixins.json index 9260b26..82c2d00 100644 --- a/src/main/resources/textile_backup.mixins.json +++ b/src/main/resources/textile_backup.mixins.json @@ -3,6 +3,7 @@ "package": "net.szum123321.textile_backup.mixin", "compatibilityLevel": "JAVA_16", "mixins": [ + "DedicatedServerWatchdogMixin", "MinecraftServerMixin", "MinecraftServerSessionAccessor" ], From 725d4098be27c78ba536abc716081bc30c966319 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 19 Jun 2021 14:44:06 +0200 Subject: [PATCH 49/52] Replaced File with Optional in Statics to make sure I won't forget to check if it exists --- src/main/java/net/szum123321/textile_backup/Statics.java | 3 ++- .../textile_backup/commands/manage/DeleteCommand.java | 2 +- .../textile_backup/commands/restore/KillRestoreCommand.java | 4 +++- .../szum123321/textile_backup/core/create/BackupHelper.java | 2 +- .../szum123321/textile_backup/core/restore/RestoreHelper.java | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/Statics.java b/src/main/java/net/szum123321/textile_backup/Statics.java index c56212c..1cfd42a 100644 --- a/src/main/java/net/szum123321/textile_backup/Statics.java +++ b/src/main/java/net/szum123321/textile_backup/Statics.java @@ -24,6 +24,7 @@ import net.szum123321.textile_backup.core.restore.AwaitThread; import java.io.File; import java.time.format.DateTimeFormatter; +import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; @@ -42,7 +43,7 @@ public class Statics { public static final AtomicBoolean globalShutdownBackupFlag = new AtomicBoolean(true); public static boolean disableWatchdog = false; public static AwaitThread restoreAwaitThread = null; - public static File untouchableFile; + public static Optional untouchableFile = Optional.empty(); public static boolean tmpAvailable; } diff --git a/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java b/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java index 48ce7ac..d98db4c 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/manage/DeleteCommand.java @@ -61,7 +61,7 @@ public class DeleteCommand { .findFirst(); if(optionalFile.isPresent()) { - if(Statics.untouchableFile == null || (Statics.untouchableFile != null && !Statics.untouchableFile.equals(optionalFile.get()))) { + if(Statics.untouchableFile.isEmpty() || !Statics.untouchableFile.get().equals(optionalFile.get())) { if(optionalFile.get().delete()) { Statics.LOGGER.sendInfo(source, "File {} successfully deleted!", optionalFile.get().getName()); diff --git a/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java b/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java index 852560e..c6a474d 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/restore/KillRestoreCommand.java @@ -24,6 +24,8 @@ import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.Statics; +import java.util.Optional; + public class KillRestoreCommand { public static LiteralArgumentBuilder register() { return CommandManager.literal("killR") @@ -31,7 +33,7 @@ public class KillRestoreCommand { if(Statics.restoreAwaitThread != null && Statics.restoreAwaitThread.isAlive()) { Statics.restoreAwaitThread.interrupt(); Statics.globalShutdownBackupFlag.set(true); - Statics.untouchableFile = null; + Statics.untouchableFile = Optional.empty(); Statics.LOGGER.info("{} cancelled backup restoration.", ctx.getSource().getEntity() instanceof PlayerEntity ? "Player: " + ctx.getSource().getName() : diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index deb8157..f722ad6 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -178,7 +178,7 @@ public class BackupHelper { } private static boolean deleteFile(File f, ServerCommandSource ctx) { - if(!Statics.untouchableFile.equals(f)) { + if(Statics.untouchableFile.isEmpty()|| !Statics.untouchableFile.get().equals(f)) { if(f.delete()) { Statics.LOGGER.sendInfoAL(ctx, "Deleting: {}", f.getName()); return true; diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index 7ceec62..44b7c42 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -45,7 +45,7 @@ public class RestoreHelper { .filter(rf -> rf.getCreationTime().equals(backupTime)) .findFirst(); - optionalFile.ifPresent(file -> Statics.untouchableFile = file.getFile()); + Statics.untouchableFile = optionalFile.map(RestoreableFile::getFile); return optionalFile; } From fcc1dca9582bfc0898941a75b7668e672291f514 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 19 Jun 2021 15:39:00 +0200 Subject: [PATCH 50/52] BackupHelper cleanup --- .../core/create/BackupHelper.java | 83 ++++--------------- 1 file changed, 16 insertions(+), 67 deletions(-) diff --git a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java index f722ad6..d590d59 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/BackupHelper.java @@ -34,9 +34,7 @@ import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Arrays; import java.util.Comparator; -import java.util.Iterator; import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; public class BackupHelper { public static Runnable create(BackupContext ctx) { @@ -67,43 +65,7 @@ public class BackupHelper { try { ctx.getServer().save(false, true, true); } catch (Exception e) { - Statics.LOGGER.sendErrorAL(ctx,"An exception occurred when trying to save the world!" - ); -/* - MutableText text = Statics.LOGGER.getPrefixText() - .append(new LiteralText("In order for backup to be up-to-date call ").formatted(Formatting.WHITE)) - .append( - new LiteralText("[/save-all flush]") - .styled( - style -> style - .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/save-all flush")) - .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new LiteralText("Click!"))) - .withColor(Formatting.BLUE) - ) - ) - .append(new LiteralText(" and then re-run the backup.").formatted(Formatting.WHITE)); - - ctx.getCommandSource().sendFeedback(text, false); - - text = Statics.LOGGER.getPrefixText() - .append(new LiteralText("This is known issue (See ").formatted(Formatting.WHITE)) - .append( - new LiteralText("https://github.com/Szum123321/textile_backup/issues/42") - .styled( - style -> style - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/Szum123321/textile_backup/issues/42")) - .withColor(Formatting.BLUE) - ) - ) - .append(new LiteralText(")").formatted(Formatting.WHITE)); - - ctx.getCommandSource().sendFeedback(text, false); - - if(ctx.startedByPlayer()) - Statics.LOGGER.sendError(ctx, "If you have access to server console please take a look at it."); - - Statics.LOGGER.error("Please let me know about this situation, include below error, mod's config, additional mods, where is the server running etc.", e); - */ + Statics.LOGGER.sendErrorAL(ctx,"An exception occurred when trying to save the world!"); } } @@ -118,8 +80,7 @@ public class BackupHelper { if(ctx.getInitiator().equals(ActionInitiator.Player) && ctx.getCommandSource().getEntity() != null) uuid = ctx.getCommandSource().getEntity().getUuid(); - else - uuid = Util.NIL_UUID; + else uuid = Util.NIL_UUID; ctx.getServer().getPlayerManager().broadcastChatMessage( message, @@ -130,51 +91,39 @@ public class BackupHelper { public static int executeFileLimit(ServerCommandSource ctx, String worldName) { File root = Utilities.getBackupRootPath(worldName); - AtomicInteger deletedFiles = new AtomicInteger(); + int deletedFiles = 0; if (root.isDirectory() && root.exists() && root.listFiles() != null) { if (Statics.CONFIG.maxAge > 0) { // delete files older that configured final LocalDateTime now = LocalDateTime.now(); - Arrays.stream(root.listFiles()) + deletedFiles += Arrays.stream(root.listFiles()) .filter(Utilities::isValidBackup)// We check if we can get file's creation date so that the next line won't throw an exception .filter(f -> now.toEpochSecond(ZoneOffset.UTC) - Utilities.getFileCreationTime(f).get().toEpochSecond(ZoneOffset.UTC) > Statics.CONFIG.maxAge) - .forEach(f -> { - if(deleteFile(f, ctx)) - deletedFiles.getAndIncrement(); - }); + .map(f -> deleteFile(f, ctx)) + .filter(b -> b).count(); //a bit awkward } if (Statics.CONFIG.backupsToKeep > 0 && root.listFiles().length > Statics.CONFIG.backupsToKeep) { - int i = root.listFiles().length; - - Iterator it = Arrays.stream(root.listFiles()) + deletedFiles += Arrays.stream(root.listFiles()) .filter(Utilities::isValidBackup) - .sorted(Comparator.comparing(f -> Utilities.getFileCreationTime(f).get())) - .iterator(); - - while(i > Statics.CONFIG.backupsToKeep && it.hasNext()) { - if(deleteFile(it.next(), ctx)) - deletedFiles.getAndIncrement(); - - i--; - } + .sorted(Comparator.comparing(f -> Utilities.getFileCreationTime((File) f).get()).reversed()) + .skip(Statics.CONFIG.backupsToKeep) + .map(f -> deleteFile(f, ctx)) + .filter(b -> b).count(); } if (Statics.CONFIG.maxSize > 0 && FileUtils.sizeOfDirectory(root) / 1024 > Statics.CONFIG.maxSize) { - Iterator it = Arrays.stream(root.listFiles()) + deletedFiles += Arrays.stream(root.listFiles()) .filter(Utilities::isValidBackup) .sorted(Comparator.comparing(f -> Utilities.getFileCreationTime(f).get())) - .iterator(); - - while(FileUtils.sizeOfDirectory(root) / 1024 > Statics.CONFIG.maxSize && it.hasNext()) { - if(deleteFile(it.next(), ctx)) - deletedFiles.getAndIncrement(); - } + .takeWhile(f -> FileUtils.sizeOfDirectory(root) / 1024 > Statics.CONFIG.maxSize) + .map(f -> deleteFile(f, ctx)) + .filter(b -> b).count(); } } - return deletedFiles.get(); + return deletedFiles; } private static boolean deleteFile(File f, ServerCommandSource ctx) { From fee04a994398eb5f52543cab893444ab4138fbcb Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 19 Jun 2021 18:48:46 +0200 Subject: [PATCH 51/52] small correction --- .../textile_backup/core/restore/RestoreBackupRunnable.java | 3 +++ 1 file changed, 3 insertions(+) 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 7e2b39a..5cbaca3 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 @@ -80,6 +80,9 @@ public class RestoreBackupRunnable implements Runnable { Statics.LOGGER.info("Something went wrong while deleting old backup"); } + //in case we're playing on client + Statics.globalShutdownBackupFlag.set(true); + Statics.LOGGER.info("Done!"); } From cc912d322e4bf312a0b9ea0c5d33e87eebb714c5 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 19 Jun 2021 19:03:13 +0200 Subject: [PATCH 52/52] added copyright notice into output jar --- Copyright_Notice.txt => Copyright_Notice | 2 ++ build.gradle | 2 ++ 2 files changed, 4 insertions(+) rename Copyright_Notice.txt => Copyright_Notice (88%) diff --git a/Copyright_Notice.txt b/Copyright_Notice similarity index 88% rename from Copyright_Notice.txt rename to Copyright_Notice index 4740a3f..f6cfe9f 100644 --- a/Copyright_Notice.txt +++ b/Copyright_Notice @@ -3,6 +3,8 @@ This project uses third party libraries as its dependencies and includes them in Cotton config, Cotton logging, and Jankson-Fabric all by Cotton team licensed under MIT license which can be found at https://github.com/CottonMC/Cotton XZ for Java by Tukaani released as public domain. https://tukaani.org/xz/java.html parallelgzip by shevek under Apache 2.0 http://www.apache.org/licenses/ + +To save on space Parallel BZip2 was unpacked Parallel BZip2 compression by Karl Gustafsson at http://at4j.sourceforge.net/ under GPL v3 Some code was partially or fully inspired by: diff --git a/build.gradle b/build.gradle index 3d42bd6..42ed2c0 100644 --- a/build.gradle +++ b/build.gradle @@ -69,6 +69,8 @@ jar { from("LICENSE") { rename { "${it}_${project.archivesBaseName}"} } + + from("Copyright_Notice") } // configure the maven publication publishing {