Added BackupContext. This object gets passed instead of passing ServerCommandSource, MinecraftServer, etc... separately.

2.x-1.16
szymon 2020-08-02 20:05:07 +02:00
parent 51ecf54fb6
commit fec162ae24
6 changed files with 220 additions and 53 deletions

View File

@ -24,6 +24,7 @@ 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.TextileBackup; import net.szum123321.textile_backup.TextileBackup;
import net.szum123321.textile_backup.core.BackupContext;
import net.szum123321.textile_backup.core.BackupHelper; import net.szum123321.textile_backup.core.BackupHelper;
public class StartBackupCommand { public class StartBackupCommand {
@ -34,13 +35,17 @@ public class StartBackupCommand {
).executes(ctx -> execute(ctx.getSource())); ).executes(ctx -> execute(ctx.getSource()));
} }
private static int executeWithComment(CommandContext<ServerCommandSource> source) { private static int executeWithComment(CommandContext<ServerCommandSource> ctx) {
if(!TextileBackup.executorService.isShutdown())
TextileBackup.executorService.submit( TextileBackup.executorService.submit(
BackupHelper.create( BackupHelper.create(
source.getSource().getMinecraftServer(), new BackupContext.Builder()
source.getSource(), .setCommandSource(ctx.getSource())
true, .setServer(ctx.getSource().getMinecraftServer())
StringArgumentType.getString(source, "comment").replace("#", "") .setComment(StringArgumentType.getString(ctx, "comment"))
.guessInitiator()
.setSave()
.build()
) )
); );
@ -48,12 +53,15 @@ public class StartBackupCommand {
} }
private static int execute(ServerCommandSource source){ private static int execute(ServerCommandSource source){
if(!TextileBackup.executorService.isShutdown())
TextileBackup.executorService.submit( TextileBackup.executorService.submit(
BackupHelper.create( BackupHelper.create(
source.getMinecraftServer(), new BackupContext.Builder()
source, .setCommandSource(source)
true, .setServer(source.getMinecraftServer())
null .guessInitiator()
.setSave()
.build()
) )
); );

View File

@ -0,0 +1,132 @@
package net.szum123321.textile_backup.core;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import org.jetbrains.annotations.NotNull;
public class BackupContext {
private final MinecraftServer server;
private final ServerCommandSource commandSource;
private final BackupInitiator initiator;
private final boolean save;
private final String comment;
protected BackupContext(@NotNull MinecraftServer server, ServerCommandSource commandSource, @NotNull BackupInitiator initiator, boolean save, String comment) {
this.server = server;
this.commandSource = commandSource;
this.initiator = initiator;
this.save = save;
this.comment = comment;
}
public MinecraftServer getServer() {
return server;
}
public ServerCommandSource getCommandSource() {
return commandSource;
}
public BackupInitiator getInitiator() {
return initiator;
}
public boolean startedByPlayer() {
return initiator == BackupInitiator.Player;
}
public boolean shouldSave() {
return save;
}
public String getComment() {
return comment;
}
public static class Builder {
private MinecraftServer server;
private ServerCommandSource commandSource;
private BackupInitiator initiator;
private boolean save;
private String comment;
private boolean guessInitiator;
public Builder() {
this.server = null;
this.commandSource = null;
this.initiator = null;
this.save = false;
this.comment = null;
guessInitiator = false;
}
public Builder setCommandSource(ServerCommandSource commandSource) {
this.commandSource = commandSource;
return this;
}
public Builder setServer(MinecraftServer server) {
this.server = server;
return this;
}
public Builder setInitiator(BackupInitiator initiator) {
this.initiator = initiator;
return this;
}
public Builder setComment(String comment) {
this.comment = comment;
return this;
}
public Builder guessInitiator() {
this.guessInitiator = true;
return this;
}
public Builder setSave() {
this.save = true;
return this;
}
public BackupContext build() {
if(guessInitiator) {
initiator = commandSource.getEntity() == null ? BackupInitiator.ServerConsole : BackupInitiator.Player;
} else if(initiator == null) {
initiator = BackupInitiator.Null;
}
if(server == null)
setServer(commandSource.getMinecraftServer());
return new BackupContext(server, commandSource, initiator, save, comment);
}
}
public enum BackupInitiator {
Player ("Player", "by: "),
ServerConsole ("Server Console", "from: "),
Timer ("Timer", "by: "),
Shutdown ("Server Shutdown", "by: "),
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;
}
}
}

View File

@ -19,7 +19,6 @@
package net.szum123321.textile_backup.core; package net.szum123321.textile_backup.core;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.szum123321.textile_backup.TextileBackup; import net.szum123321.textile_backup.TextileBackup;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
@ -32,28 +31,30 @@ import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
public class BackupHelper { public class BackupHelper {
public static Runnable create(MinecraftServer server, ServerCommandSource ctx, boolean save, String comment) { public static Runnable create(BackupContext ctx) {
LocalDateTime now = LocalDateTime.now();
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("Backup started by: ");
if (ctx != null) builder.append("Backup started ");
builder.append(ctx.getName());
else builder.append(ctx.getInitiator().getPrefix());
builder.append("SERVER");
if(ctx.startedByPlayer()) {
builder.append(ctx.getCommandSource().getDisplayName().getString());
} else {
builder.append(ctx.getInitiator().getName());
}
builder.append(" on: "); builder.append(" on: ");
builder.append(Utilities.getDateTimeFormatter().format(now)); builder.append(Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
Utilities.info(builder.toString(), null); Utilities.info(builder.toString(), null);
Utilities.info("Saving server...", ctx); if (ctx.shouldSave()) {
Utilities.info("Saving server...", ctx.getCommandSource());
ctx.getServer().save(true, true, false);
}
if (save) return new MakeBackupRunnable(ctx);
server.save(true, true, false);
return new MakeBackupRunnable(server, ctx, comment);
} }
public static void executeFileLimit(ServerCommandSource ctx, String worldName) { public static void executeFileLimit(ServerCommandSource ctx, String worldName) {
@ -92,6 +93,7 @@ public class BackupHelper {
} else { } else {
Utilities.sendError("Something went wrong while deleting: " + f.getName(), ctx); Utilities.sendError("Something went wrong while deleting: " + f.getName(), ctx);
} }
i--; i--;
} }
} }

View File

@ -20,7 +20,15 @@ public class BackupScheduler {
if(TextileBackup.config.doBackupsOnEmptyServer || server.getPlayerManager().getCurrentPlayerCount() > 0) { if(TextileBackup.config.doBackupsOnEmptyServer || server.getPlayerManager().getCurrentPlayerCount() > 0) {
if(scheduled) { if(scheduled) {
if(nextBackup <= now) { if(nextBackup <= now) {
TextileBackup.executorService.submit(BackupHelper.create(server, null, true, null)); TextileBackup.executorService.submit(
BackupHelper.create(
new BackupContext.Builder()
.setServer(server)
.setInitiator(BackupContext.BackupInitiator.Timer)
.setSave()
.build()
)
);
nextBackup = now + TextileBackup.config.backupInterval; nextBackup = now + TextileBackup.config.backupInterval;
} }
@ -30,7 +38,15 @@ public class BackupScheduler {
} }
} else if(!TextileBackup.config.doBackupsOnEmptyServer && server.getPlayerManager().getCurrentPlayerCount() == 0) { } else if(!TextileBackup.config.doBackupsOnEmptyServer && server.getPlayerManager().getCurrentPlayerCount() == 0) {
if(scheduled && nextBackup <= now) { if(scheduled && nextBackup <= now) {
TextileBackup.executorService.submit(BackupHelper.create(server, null, true, null)); TextileBackup.executorService.submit(
BackupHelper.create(
new BackupContext.Builder()
.setServer(server)
.setInitiator(BackupContext.BackupInitiator.Timer)
.setSave()
.build()
)
);
scheduled = false; scheduled = false;
} }

View File

@ -36,18 +36,18 @@ import java.time.LocalDateTime;
public class MakeBackupRunnable implements Runnable { public class MakeBackupRunnable implements Runnable {
private final MinecraftServer server; private final MinecraftServer server;
private final ServerCommandSource ctx; private final ServerCommandSource commandSource;
private final String comment; private final String comment;
public MakeBackupRunnable(MinecraftServer server, ServerCommandSource ctx, String comment){ public MakeBackupRunnable(BackupContext context){
this.server = server; this.server = context.getServer();
this.ctx = ctx; this.commandSource = context.getCommandSource();
this.comment = comment; this.comment = context.getComment();
} }
@Override @Override
public void run() { public void run() {
Utilities.info("Starting backup", ctx); Utilities.info("Starting backup", commandSource);
File world = ((MinecraftServerSessionAccessor)server) File world = ((MinecraftServerSessionAccessor)server)
.getSession() .getSession()
@ -70,7 +70,7 @@ public class MakeBackupRunnable implements Runnable {
} catch (IOException e) { } catch (IOException e) {
TextileBackup.LOGGER.error("An exception occurred when trying to create new backup file!", e); TextileBackup.LOGGER.error("An exception occurred when trying to create new backup file!", e);
Utilities.sendError("An exception occurred when trying to create new backup file!", ctx); Utilities.sendError("An exception occurred when trying to create new backup file!", commandSource);
return; return;
} }
@ -83,36 +83,36 @@ public class MakeBackupRunnable implements Runnable {
coreCount = Math.min(TextileBackup.config.compressionCoreCountLimit, Runtime.getRuntime().availableProcessors()); coreCount = Math.min(TextileBackup.config.compressionCoreCountLimit, Runtime.getRuntime().availableProcessors());
} }
TextileBackup.LOGGER.trace("Running compression on {} threads", coreCount); TextileBackup.LOGGER.trace("Running compression on {} threads. Available cores = {}", coreCount, Runtime.getRuntime().availableProcessors());
switch (TextileBackup.config.format) { switch (TextileBackup.config.format) {
case ZIP: case ZIP:
ParallelZipCompressor.createArchive(world, outFile, ctx, coreCount); ParallelZipCompressor.createArchive(world, outFile, commandSource, coreCount);
break; break;
case BZIP2: case BZIP2:
ParallelBZip2Compressor.createArchive(world, outFile, ctx, coreCount); ParallelBZip2Compressor.createArchive(world, outFile, commandSource, coreCount);
break; break;
case GZIP: case GZIP:
ParallelGzipCompressor.createArchive(world, outFile, ctx, coreCount); ParallelGzipCompressor.createArchive(world, outFile, commandSource, coreCount);
break; break;
case LZMA: case LZMA:
LZMACompressor.createArchive(world, outFile, ctx); // Always single-threaded ): LZMACompressor.createArchive(world, outFile, commandSource); // Always single-threaded ):
break; break;
default: default:
TextileBackup.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", TextileBackup.config.format); TextileBackup.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", TextileBackup.config.format);
Utilities.sendError("Error! No correct compression format specified! Using default compressor!", commandSource);
Utilities.sendError("Error! No correct compression format specified! using default compressor!", ctx); ParallelZipCompressor.createArchive(world, outFile, commandSource, coreCount);
ParallelZipCompressor.createArchive(world, outFile, ctx, coreCount);
break; break;
} }
BackupHelper.executeFileLimit(ctx, Utilities.getLevelName(server)); BackupHelper.executeFileLimit(commandSource, Utilities.getLevelName(server));
Utilities.info("Done!", ctx); Utilities.info("Done!", commandSource);
} }
private String getFileName(){ private String getFileName(){

View File

@ -20,6 +20,7 @@ package net.szum123321.textile_backup.mixin;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.szum123321.textile_backup.TextileBackup; import net.szum123321.textile_backup.TextileBackup;
import net.szum123321.textile_backup.core.BackupContext;
import net.szum123321.textile_backup.core.BackupHelper; import net.szum123321.textile_backup.core.BackupHelper;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -31,6 +32,14 @@ public abstract class MinecraftServerMixin {
@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 onFinalWorldSave(CallbackInfo ci) { public void onFinalWorldSave(CallbackInfo ci) {
if (TextileBackup.config.shutdownBackup) if (TextileBackup.config.shutdownBackup)
TextileBackup.executorService.submit(BackupHelper.create((MinecraftServer) (Object) this, null, false, "shutdown")); TextileBackup.executorService.submit(
BackupHelper.create(
new BackupContext.Builder()
.setServer((MinecraftServer)(Object) this)
.setInitiator(BackupContext.BackupInitiator.Shutdown)
.setComment("shutdown")
.build()
)
);
} }
} }