Added file comment option and ported to 20w12a
							parent
							
								
									f54f5abed2
								
							
						
					
					
						commit
						a1bb7ed8f3
					
				|  | @ -1,14 +1,14 @@ | |||
| # Done to increase the memory available to gradle. | ||||
| org.gradle.jvmargs=-Xmx1G | ||||
| 
 | ||||
| 	minecraft_version=1.15.2 | ||||
| 	yarn_mappings=1.15.2+build.14 | ||||
| 	loader_version=0.7.8+build.184 | ||||
| minecraft_version=20w12a | ||||
| yarn_mappings=20w12a+build.18 | ||||
| loader_version=0.7.8+build.189 | ||||
| 
 | ||||
| 	#Fabric api | ||||
| 	fabric_version=0.4.32+build.292-1.15 | ||||
| #Fabric api | ||||
| fabric_version=0.5.5+build.311-1.16 | ||||
| 
 | ||||
| # Mod Properties | ||||
| 	mod_version = 1.0.3-1.15 | ||||
| 	mod_version = 1.0.4-1.16 | ||||
| 	maven_group = net.szum123321 | ||||
| 	archives_base_name = textile_backup | ||||
|  | @ -36,7 +36,7 @@ public class ConfigHandler { | |||
|     public String path = "backup/"; | ||||
| 
 | ||||
|     @Comment("\nMaximum number of backups to keep. if 0 then no backup will be deleted\n") | ||||
|     public int backupsToKeep = 0; | ||||
|     public int backupsToKeep = 10; | ||||
| 
 | ||||
|     @Comment("\nMaximum age of backups to keep in seconds.\n if 0 then backups will not be deleted based on age \n") | ||||
|     public int maxAge = 0; | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /* | ||||
|   `A simple backup mod for Fabric | ||||
|     A simple backup mod for Fabric | ||||
|     Copyright (C) 2020  Szum123321 | ||||
| 
 | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|  | @ -21,7 +21,6 @@ package net.szum123321.textile_backup.commands; | |||
| import com.mojang.brigadier.builder.LiteralArgumentBuilder; | ||||
| import net.minecraft.server.command.CommandManager; | ||||
| import net.minecraft.server.command.ServerCommandSource; | ||||
| import net.minecraft.text.TranslatableText; | ||||
| import net.szum123321.textile_backup.core.BackupHelper; | ||||
| 
 | ||||
| public class CleanupCommand { | ||||
|  |  | |||
|  | @ -18,7 +18,9 @@ | |||
| 
 | ||||
| package net.szum123321.textile_backup.commands; | ||||
| 
 | ||||
| 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.core.BackupHelper; | ||||
|  | @ -27,11 +29,19 @@ public class StartBackupCommand { | |||
|     public static LiteralArgumentBuilder<ServerCommandSource> register(){ | ||||
|         return CommandManager.literal("start") | ||||
|                 .requires(ctx -> ctx.hasPermissionLevel(4)) | ||||
|                 .executes(ctx -> execute(ctx.getSource())); | ||||
|                 .then(CommandManager.argument("Comment", StringArgumentType.word()) | ||||
|                         .executes(StartBackupCommand::executeWithComment) | ||||
|                 ).executes(ctx -> execute(ctx.getSource())); | ||||
|     } | ||||
| 
 | ||||
|     private static int executeWithComment(CommandContext<ServerCommandSource> source){ | ||||
|         BackupHelper.create(source.getSource().getMinecraftServer(), source.getSource(), true, StringArgumentType.getString(source, "Comment")); | ||||
| 
 | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     private static int execute(ServerCommandSource source){ | ||||
|         BackupHelper.create(source.getMinecraftServer(), source, true); | ||||
|         BackupHelper.create(source.getMinecraftServer(), source, true, null); | ||||
| 
 | ||||
|         return 1; | ||||
|     } | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| package net.szum123321.textile_backup.core; | ||||
| 
 | ||||
| import jdk.internal.jline.internal.Nullable; | ||||
| import net.fabricmc.loader.api.FabricLoader; | ||||
| import net.minecraft.server.MinecraftServer; | ||||
| import net.minecraft.server.command.ServerCommandSource; | ||||
|  | @ -29,8 +30,92 @@ import java.time.LocalDateTime; | |||
| import java.time.ZoneOffset; | ||||
| import java.time.format.DateTimeFormatter; | ||||
| import java.util.Arrays; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| public class BackupHelper { | ||||
| 
 | ||||
|     public static void log(String s, ServerCommandSource ctx){ | ||||
|         if(ctx != null) | ||||
|             ctx.sendFeedback(new TranslatableText(s), true); | ||||
| 
 | ||||
|         if(TextileBackup.config.log) | ||||
|             TextileBackup.logger.info(s); | ||||
|     } | ||||
| 
 | ||||
|     public static void error(String s, ServerCommandSource ctx){ | ||||
|         if(ctx != null) | ||||
|             ctx.sendFeedback(new TranslatableText(s), true); | ||||
| 
 | ||||
|         if(TextileBackup.config.log) | ||||
|             TextileBackup.logger.error(s); | ||||
|     } | ||||
| 
 | ||||
|     public static void create(MinecraftServer server, ServerCommandSource ctx, boolean save, @Nullable String comment) { | ||||
|         LocalDateTime now = LocalDateTime.now(); | ||||
| 
 | ||||
|         StringBuilder builder = new StringBuilder(); | ||||
|         builder.append("Backup started by: "); | ||||
| 
 | ||||
|         if( ctx != null ) | ||||
|             builder.append(ctx.getName()); | ||||
|         else | ||||
|             builder.append("SERVER"); | ||||
| 
 | ||||
|         builder.append(" on: "); | ||||
|         builder.append(getDateTimeFormatter().format(now)); | ||||
| 
 | ||||
|         log(builder.toString(), null); | ||||
| 
 | ||||
|         log("Saving server...", ctx); | ||||
| 
 | ||||
|         if(save) | ||||
|             server.save(true, false, false); | ||||
| 
 | ||||
|         MakeBackupThread thread = new MakeBackupThread(server, ctx, comment); | ||||
| 
 | ||||
|         thread.start(); | ||||
| 
 | ||||
|         executeFileLimit(ctx); | ||||
|     } | ||||
| 
 | ||||
|     public static void executeFileLimit(ServerCommandSource ctx){ | ||||
|         File root = getBackupRootPath(); | ||||
| 
 | ||||
|         if(root.isDirectory() && root.exists()){ | ||||
|             if(TextileBackup.config.maxAge > 0){ | ||||
|                 LocalDateTime now = LocalDateTime.now(); | ||||
| 
 | ||||
|                 for(File f: Objects.requireNonNull(root.listFiles())){ | ||||
|                     if(f.exists() && f.isFile()){ | ||||
|                         LocalDateTime creationTime = LocalDateTime.from( | ||||
|                                 getDateTimeFormatter().parse( | ||||
|                                         f.getName().split(".zip")[0].split("#")[0] | ||||
|                                 ) | ||||
|                         ); | ||||
| 
 | ||||
|                         if(now.toEpochSecond(ZoneOffset.UTC) - creationTime.toEpochSecond(ZoneOffset.UTC) > TextileBackup.config.maxAge) { | ||||
|                             log("Deleting: " + f.getName(), ctx); | ||||
|                             f.delete(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if(TextileBackup.config.backupsToKeep > 0 && Objects.requireNonNull(root.listFiles()).length > TextileBackup.config.backupsToKeep){ | ||||
|                 int var1 = Objects.requireNonNull(root.listFiles()).length - TextileBackup.config.backupsToKeep; | ||||
| 
 | ||||
|                 File[] files = root.listFiles(); | ||||
|                 assert files != null; | ||||
|                 Arrays.sort(files); | ||||
| 
 | ||||
|                 for(int i = 0; i < var1; i++) { | ||||
|                     log("Deleting: " + files[i].getName(), ctx); | ||||
|                     files[i].delete(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static File getBackupRootPath(){ | ||||
|         File path = new File(TextileBackup.config.path); | ||||
| 
 | ||||
|  | @ -52,85 +137,6 @@ public class BackupHelper { | |||
|         return path; | ||||
|     } | ||||
| 
 | ||||
|     public static void log(String s, ServerCommandSource ctx){ | ||||
|         if(ctx != null) | ||||
|             ctx.sendFeedback(new TranslatableText(s), true); | ||||
| 
 | ||||
|         if(TextileBackup.config.log) | ||||
|             TextileBackup.logger.info(s); | ||||
|     } | ||||
| 
 | ||||
|     public static void error(String s, ServerCommandSource ctx){ | ||||
|         if(ctx != null) | ||||
|             ctx.sendFeedback(new TranslatableText(s), true); | ||||
| 
 | ||||
|         if(TextileBackup.config.log) | ||||
|             TextileBackup.logger.error(s); | ||||
|     } | ||||
| 
 | ||||
|     public static void create(MinecraftServer server, ServerCommandSource ctx, boolean save) { | ||||
|         LocalDateTime now = LocalDateTime.now(); | ||||
| 
 | ||||
|         StringBuilder builder = new StringBuilder(); | ||||
|         builder.append("Backup started by: "); | ||||
| 
 | ||||
|         if( ctx != null ) | ||||
|             builder.append(ctx.getName()); | ||||
|         else | ||||
|             builder.append("SERVER"); | ||||
| 
 | ||||
|         builder.append(" on: "); | ||||
|         builder.append(getDateTimeFormatter().format(now)); | ||||
| 
 | ||||
|         log(builder.toString(), null); | ||||
| 
 | ||||
|         log("Saving server...", ctx); | ||||
| 
 | ||||
|         if(save) | ||||
|             server.save(true, false, false); | ||||
| 
 | ||||
|         MakeBackupThread thread = new MakeBackupThread(server, ctx); | ||||
| 
 | ||||
|         thread.start(); | ||||
| 
 | ||||
|         executeFileLimit(ctx); | ||||
|     } | ||||
| 
 | ||||
|     public static void executeFileLimit(ServerCommandSource ctx){ | ||||
|         File root = getBackupRootPath(); | ||||
|          | ||||
|         if(root.isDirectory()){ | ||||
|             if(TextileBackup.config.maxAge > 0){ | ||||
|                 LocalDateTime now = LocalDateTime.now(); | ||||
| 
 | ||||
|                 for(File f: root.listFiles()){ | ||||
|                     if(f.exists() && f.isFile()){ | ||||
|                         LocalDateTime time = LocalDateTime.from( | ||||
|                                 getDateTimeFormatter().parse( | ||||
|                                         f.getName().split(".zip")[0] | ||||
|                                 ) | ||||
|                         ); | ||||
| 
 | ||||
|                         if(now.toEpochSecond(ZoneOffset.UTC) - time.toEpochSecond(ZoneOffset.UTC) > TextileBackup.config.maxAge) | ||||
|                             f.delete(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if(TextileBackup.config.backupsToKeep > 0 && root.listFiles().length > TextileBackup.config.backupsToKeep){ | ||||
|                 int var1 = root.listFiles().length - TextileBackup.config.backupsToKeep; | ||||
| 
 | ||||
|                 File[] file = root.listFiles(); | ||||
|                 Arrays.sort(file); | ||||
| 
 | ||||
|                 for(int i = 0; i < var1; i++){ | ||||
|                     file[i].delete(); | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static DateTimeFormatter getDateTimeFormatter(){ | ||||
|            String os = System.getProperty("os.name"); | ||||
|         if (os.toLowerCase().startsWith("win")) { | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ import java.io.File; | |||
| import java.io.FileInputStream; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.util.Objects; | ||||
| import java.util.zip.ZipEntry; | ||||
| import java.util.zip.ZipOutputStream; | ||||
| 
 | ||||
|  | @ -53,7 +54,7 @@ public class Compressor { | |||
|             IOUtils.copy(new FileInputStream(file), out); | ||||
|             out.closeEntry(); | ||||
|         }else if(file.isDirectory() && file.listFiles() != null){ | ||||
|             for(File f: file.listFiles()){ | ||||
|             for(File f: Objects.requireNonNull(file.listFiles())){ | ||||
|                 if(f != null){ | ||||
|                     addToArchive(out, f, name); | ||||
|                 } | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| package net.szum123321.textile_backup.core; | ||||
| 
 | ||||
| import jdk.internal.jline.internal.Nullable; | ||||
| import net.minecraft.server.MinecraftServer; | ||||
| import net.minecraft.server.command.ServerCommandSource; | ||||
| import net.minecraft.world.dimension.DimensionType; | ||||
|  | @ -29,10 +30,12 @@ import java.time.LocalDateTime; | |||
| public class MakeBackupThread extends Thread { | ||||
|     MinecraftServer server; | ||||
|     ServerCommandSource ctx; | ||||
|     @Nullable String comment; | ||||
| 
 | ||||
|     public MakeBackupThread(MinecraftServer server, ServerCommandSource ctx){ | ||||
|     public MakeBackupThread(MinecraftServer server, ServerCommandSource ctx, @Nullable String comment){ | ||||
|         this.server = server; | ||||
|         this.ctx = ctx; | ||||
|         this.comment = comment; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -41,6 +44,7 @@ public class MakeBackupThread extends Thread { | |||
|                 .getWorld(DimensionType.OVERWORLD) | ||||
|                 .getSaveHandler() | ||||
|                 .getWorldDir(); | ||||
| 
 | ||||
|         File outFile = BackupHelper | ||||
|                 .getBackupRootPath() | ||||
|                 .toPath() | ||||
|  | @ -66,6 +70,6 @@ public class MakeBackupThread extends Thread { | |||
|     private String getFileName(){ | ||||
|         LocalDateTime now = LocalDateTime.now(); | ||||
| 
 | ||||
|         return BackupHelper.getDateTimeFormatter().format(now) + ".zip"; | ||||
|         return BackupHelper.getDateTimeFormatter().format(now) + (comment != null ? "#" + comment.replace("#", ""): "") + ".zip"; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -44,13 +44,13 @@ public abstract class MinecraftServerMixin { | |||
| 
 | ||||
|             lastBackup = timeReference; | ||||
| 
 | ||||
|             BackupHelper.create((MinecraftServer)(Object)this, null, true); | ||||
|             BackupHelper.create((MinecraftServer)(Object)this, null, true, null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Inject(method = "shutdown", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;save(ZZZ)Z")) | ||||
|     public void onShutdown(CallbackInfo ci){ | ||||
|         if(TextileBackup.config.shutdownBackup) | ||||
|             BackupHelper.create((MinecraftServer)(Object)this, null, false); | ||||
|             BackupHelper.create((MinecraftServer)(Object)this, null, false, null); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -29,6 +29,6 @@ | |||
|   "depends": { | ||||
|     "fabricloader": ">=0.7.2", | ||||
|     "fabric": "*", | ||||
|     "minecraft": "1.15.*" | ||||
|     "minecraft": "1.16.*" | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue