diff --git a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java index bfc50ef..9b17cfe 100644 --- a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java +++ b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java @@ -32,7 +32,7 @@ public class ConfigHandler { @Comment("\nShould backups be done even if there are no players?\n") public boolean doBackupsOnEmptyServer = false; - @Comment("\nShould backup be made on server shutdown\n") + @Comment("\nShould backup be made on server shutdown?\n") public boolean shutdownBackup = true; @Comment("\nA path to backup folder\n") diff --git a/src/main/java/net/szum123321/textile_backup/TextileBackup.java b/src/main/java/net/szum123321/textile_backup/TextileBackup.java index d70999a..0e20340 100644 --- a/src/main/java/net/szum123321/textile_backup/TextileBackup.java +++ b/src/main/java/net/szum123321/textile_backup/TextileBackup.java @@ -23,25 +23,36 @@ import io.github.cottonmc.cotton.config.ConfigManager; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.minecraft.server.command.ServerCommandSource; import net.szum123321.textile_backup.commands.BlacklistCommand; import net.szum123321.textile_backup.commands.CleanupCommand; import net.szum123321.textile_backup.commands.StartBackupCommand; import net.szum123321.textile_backup.commands.WhitelistCommand; +import net.szum123321.textile_backup.core.BackupScheduler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + public class TextileBackup implements ModInitializer { public static final String MOD_ID = "textile_backup"; public static final Logger LOGGER = LogManager.getFormatterLogger("Textile Backup"); public static ConfigHandler config; + public static final BackupScheduler scheduler = new BackupScheduler(); + public static final ExecutorService executorSerivece = Executors.newSingleThreadExecutor(); + @Override public void onInitialize() { config = ConfigManager.loadConfig(ConfigHandler.class); registerCommands(); + + ServerTickEvents.END_SERVER_TICK.register(scheduler::tick); } private void registerCommands(){ diff --git a/src/main/java/net/szum123321/textile_backup/commands/StartBackupCommand.java b/src/main/java/net/szum123321/textile_backup/commands/StartBackupCommand.java index ac9c83c..571b46d 100644 --- a/src/main/java/net/szum123321/textile_backup/commands/StartBackupCommand.java +++ b/src/main/java/net/szum123321/textile_backup/commands/StartBackupCommand.java @@ -23,6 +23,7 @@ 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.TextileBackup; import net.szum123321.textile_backup.core.BackupHelper; public class StartBackupCommand { @@ -34,13 +35,27 @@ public class StartBackupCommand { } private static int executeWithComment(CommandContext source) { - BackupHelper.create(source.getSource().getMinecraftServer(), source.getSource(), true, StringArgumentType.getString(source, "comment").replace("#", "")); + TextileBackup.executorSerivece.submit( + BackupHelper.create( + source.getSource().getMinecraftServer(), + source.getSource(), + true, + StringArgumentType.getString(source, "comment").replace("#", "") + ) + ); return 1; } private static int execute(ServerCommandSource source){ - BackupHelper.create(source.getMinecraftServer(), source,true, null); + TextileBackup.executorSerivece.submit( + BackupHelper.create( + source.getMinecraftServer(), + source, + true, + null + ) + ); return 1; } diff --git a/src/main/java/net/szum123321/textile_backup/core/BackupHelper.java b/src/main/java/net/szum123321/textile_backup/core/BackupHelper.java index 6d4efe8..7e63e30 100644 --- a/src/main/java/net/szum123321/textile_backup/core/BackupHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/BackupHelper.java @@ -32,7 +32,7 @@ import java.util.Comparator; import java.util.concurrent.atomic.AtomicInteger; public class BackupHelper { - public static Thread create(MinecraftServer server, ServerCommandSource ctx, boolean save, String comment) { + public static Runnable create(MinecraftServer server, ServerCommandSource ctx, boolean save, String comment) { LocalDateTime now = LocalDateTime.now(); StringBuilder builder = new StringBuilder(); @@ -53,11 +53,7 @@ public class BackupHelper { if (save) server.save(true, true, false); - Thread thread = new Thread(new MakeBackupThread(server, ctx, comment)); - - thread.start(); - - return thread; + return new MakeBackupRunnable(server, ctx, comment); } public static void executeFileLimit(ServerCommandSource ctx, String worldName) { diff --git a/src/main/java/net/szum123321/textile_backup/core/BackupScheduler.java b/src/main/java/net/szum123321/textile_backup/core/BackupScheduler.java new file mode 100644 index 0000000..4319b6d --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/BackupScheduler.java @@ -0,0 +1,35 @@ +package net.szum123321.textile_backup.core; + +import net.minecraft.server.MinecraftServer; +import net.szum123321.textile_backup.TextileBackup; + +import java.time.Instant; + +public class BackupScheduler { + private boolean scheduled; + private long nextBackup; + + public BackupScheduler() { + scheduled = false; + nextBackup = -1; + } + + public void tick(MinecraftServer server) { + long now = Instant.now().getEpochSecond(); + + if(TextileBackup.config.doBackupsOnEmptyServer || server.getPlayerManager().getCurrentPlayerCount() > 0) { + if(scheduled) { + if(nextBackup >= now) { + TextileBackup.executorSerivece.submit(BackupHelper.create(server, null, true, null)); + + nextBackup = now + TextileBackup.config.backupInterval; + } + } else { + nextBackup = now + TextileBackup.config.backupInterval; + scheduled = true; + } + } else if(!TextileBackup.config.doBackupsOnEmptyServer && server.getPlayerManager().getCurrentPlayerCount() == 0) { + scheduled = false; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/szum123321/textile_backup/core/MakeBackupThread.java b/src/main/java/net/szum123321/textile_backup/core/MakeBackupRunnable.java similarity index 96% rename from src/main/java/net/szum123321/textile_backup/core/MakeBackupThread.java rename to src/main/java/net/szum123321/textile_backup/core/MakeBackupRunnable.java index 8e81e1f..51621d8 100644 --- a/src/main/java/net/szum123321/textile_backup/core/MakeBackupThread.java +++ b/src/main/java/net/szum123321/textile_backup/core/MakeBackupRunnable.java @@ -34,12 +34,12 @@ import java.io.File; import java.io.IOException; import java.time.LocalDateTime; -public class MakeBackupThread implements Runnable { +public class MakeBackupRunnable implements Runnable { private final MinecraftServer server; private final ServerCommandSource ctx; private final String comment; - public MakeBackupThread(MinecraftServer server, ServerCommandSource ctx, String comment){ + public MakeBackupRunnable(MinecraftServer server, ServerCommandSource ctx, String comment){ this.server = server; this.ctx = ctx; this.comment = comment; diff --git a/src/main/java/net/szum123321/textile_backup/mixin/MinecraftServerMixin.java b/src/main/java/net/szum123321/textile_backup/mixin/MinecraftServerMixin.java index 6c48fe5..e81a12f 100644 --- a/src/main/java/net/szum123321/textile_backup/mixin/MinecraftServerMixin.java +++ b/src/main/java/net/szum123321/textile_backup/mixin/MinecraftServerMixin.java @@ -32,6 +32,7 @@ import java.util.function.BooleanSupplier; @Mixin(MinecraftServer.class) public abstract class MinecraftServerMixin { +/* @Shadow private long timeReference; @Shadow public abstract PlayerManager getPlayerManager(); @@ -49,15 +50,11 @@ public abstract class MinecraftServerMixin { 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) { - try { - BackupHelper.create((MinecraftServer) (Object) this, null, false, "shutdown").join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + BackupHelper.create((MinecraftServer) (Object) this, null, false, "shutdown").run(); } } }