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