Skip to content

Commit

Permalink
Changed the BackupManager system to be more expandable and sustainable
Browse files Browse the repository at this point in the history
  • Loading branch information
MehradN committed Apr 22, 2023
1 parent a6aad55 commit e264293
Show file tree
Hide file tree
Showing 15 changed files with 281 additions and 262 deletions.
60 changes: 23 additions & 37 deletions src/main/java/ir/mehradn/rollback/event/AutomatedBackup.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ir.mehradn.rollback.Rollback;
import ir.mehradn.rollback.config.RollbackConfig;
import ir.mehradn.rollback.util.backup.BackupManager;
import ir.mehradn.rollback.util.backup.RollbackWorld;
import ir.mehradn.rollback.util.mixin.MinecraftServerExpanded;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand All @@ -11,14 +12,12 @@
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import org.apache.commons.lang3.tuple.Triple;

@Environment(EnvType.CLIENT)
public final class AutomatedBackup {
private static BackupManager backupManager;
private static RollbackWorld rollbackWorld;
private static int latestUpdate;
private static int daysPassed;
private static int sinceDay;
private static int sinceBackup;

public static void register() {
ServerLifecycleEvents.SERVER_STARTED.register(AutomatedBackup::onServerStarted);
Expand All @@ -28,14 +27,10 @@ public static void register() {

public static void onServerStarted(MinecraftServer server) {
Rollback.LOGGER.info("Reading the timer information...");
BackupManager backupManager = ((MinecraftServerExpanded)server).getBackupManager();
String worldName = ((MinecraftServerExpanded)server).getLevelAccess().getLevelId();
Triple<Integer, Integer, Integer> info = backupManager.getTimerInformation(worldName);

backupManager = ((MinecraftServerExpanded)server).getBackupManager();
rollbackWorld = backupManager.getWorld(worldName);
latestUpdate = server.getTickCount();
daysPassed = info.getLeft();
sinceDay = info.getMiddle();
sinceBackup = info.getRight();
}

public static void onEndTick(MinecraftServer server) {
Expand All @@ -45,40 +40,31 @@ public static void onEndTick(MinecraftServer server) {

if (shouldUpdate(serverTick, worldTick)) {
Rollback.LOGGER.info("Updating the timer information...");
BackupManager backupManager = ((MinecraftServerExpanded)server).getBackupManager();
String worldName = ((MinecraftServerExpanded)server).getLevelAccess().getLevelId();

int timePassed = serverTick - latestUpdate;
latestUpdate = serverTick;
sinceDay += timePassed;
sinceBackup += timePassed;
if (isMorning(worldTick) && sinceDay >= 11900) {
daysPassed++;
sinceDay = 0;
rollbackWorld.ticksSinceLastMorning += timePassed;
rollbackWorld.ticksSinceLastBackup += timePassed;
if (isMorning(worldTick) && rollbackWorld.ticksSinceLastMorning >= 11900) {
rollbackWorld.daysSinceLastBackup++;
rollbackWorld.ticksSinceLastMorning = 0;
}

if (shouldCreateBackup(worldTick, backupManager, worldName)) {
if (shouldCreateBackup(worldTick)) {
Rollback.LOGGER.info("Creating an automated backup...");
backupManager.createRollbackBackup(server, true);
daysPassed = 0;
sinceDay = 0;
sinceBackup = 0;
} else {
backupManager.setTimerInformation(worldName, daysPassed, sinceBackup);
backupManager.createRollbackBackup(server);
rollbackWorld.resetTimers();
}

backupManager.saveMetadata();
}
}

public static void onServerStopping(MinecraftServer server) {
int serverTick = server.getTickCount();
BackupManager backupManager = ((MinecraftServerExpanded)server).getBackupManager();
String worldName = ((MinecraftServerExpanded)server).getLevelAccess().getLevelId();

int timePassed = serverTick - latestUpdate;
sinceDay += timePassed;
sinceBackup += timePassed;

backupManager.setTimerInformation(worldName, daysPassed, sinceDay, sinceBackup);
rollbackWorld.ticksSinceLastMorning += timePassed;
rollbackWorld.ticksSinceLastBackup += timePassed;
backupManager.saveMetadata();
}

private static boolean isMorning(int worldTick) {
Expand All @@ -88,14 +74,14 @@ private static boolean isMorning(int worldTick) {
}

private static boolean shouldUpdate(int serverTick, int worldTick) {
return (isMorning(worldTick) || (serverTick - latestUpdate + sinceBackup) % 24000 == 0);
return (isMorning(worldTick) || (serverTick - latestUpdate + rollbackWorld.ticksSinceLastBackup) % 24000 == 0);
}

private static boolean shouldCreateBackup(int worldTick, BackupManager backupManager, String worldName) {
if (backupManager.getAutomated(worldName)) {
private static boolean shouldCreateBackup(int worldTick) {
if (rollbackWorld.automatedBackups) {
switch (RollbackConfig.timerMode()) {
case DAYLIGHT_CYCLE -> { return (isMorning(worldTick) && daysPassed >= RollbackConfig.daysPerBackup()); }
case IN_GAME_TIME -> { return (sinceBackup >= RollbackConfig.ticksPerBackup()); }
case DAYLIGHT_CYCLE -> { return (isMorning(worldTick) && rollbackWorld.daysSinceLastBackup >= RollbackConfig.daysPerBackup()); }
case IN_GAME_TIME -> { return (rollbackWorld.ticksSinceLastBackup >= RollbackConfig.ticksPerBackup()); }
}
}
return false;
Expand Down
17 changes: 8 additions & 9 deletions src/main/java/ir/mehradn/rollback/event/RollbackCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ir.mehradn.rollback.config.RollbackConfig;
import ir.mehradn.rollback.util.backup.BackupManager;
import ir.mehradn.rollback.util.backup.RollbackBackup;
import ir.mehradn.rollback.util.backup.RollbackWorld;
import ir.mehradn.rollback.util.mixin.MinecraftServerExpanded;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand All @@ -20,8 +21,6 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.storage.LevelStorageSource;

import java.util.List;

@Environment(EnvType.CLIENT)
public final class RollbackCommand {
public static void register() {
Expand Down Expand Up @@ -56,7 +55,7 @@ public static int createBackup(CommandContext<CommandSourceStack> context) {
MinecraftServer server = context.getSource().getServer();
BackupManager backupManager = ((MinecraftServerExpanded)server).getBackupManager();

boolean f = backupManager.createRollbackBackup(server, false);
boolean f = backupManager.createRollbackBackup(server);
if (!f) {
context.getSource().sendFailure(Component.translatable("rollback.createBackup.failed"));
return 0;
Expand Down Expand Up @@ -98,18 +97,18 @@ public static int listBackups(CommandContext<CommandSourceStack> context) {
return 0;

MinecraftServer server = context.getSource().getServer();
BackupManager backupManager = ((MinecraftServerExpanded)server).getBackupManager();
String worldName = ((MinecraftServerExpanded)server).getLevelAccess().getLevelId();
List<RollbackBackup> backups = backupManager.getRollbacksFor(worldName);
BackupManager backupManager = ((MinecraftServerExpanded)server).getBackupManager();
RollbackWorld world = backupManager.getWorld(worldName);

if (backups.isEmpty()) {
if (world.backups.isEmpty()) {
context.getSource().sendSystemMessage(Component.translatable("rollback.command.list.noBackups"));
return 1;
}

context.getSource().sendSystemMessage(Component.translatable("rollback.command.list.title"));
for (int i = 1; i <= backups.size(); i++) {
RollbackBackup backup = backups.get(backups.size() - i);
for (int i = 1; i <= world.backups.size(); i++) {
RollbackBackup backup = world.backups.get(world.backups.size() - i);
MutableComponent part1, part2, part3;
part1 = Component.literal(String.format(" #%-2d ", i));
part2 = Component.translatable("rollback.created", backup.getDateAsString()).append(Component.literal(" "));
Expand All @@ -123,7 +122,7 @@ private static boolean isNotServerHost(CommandContext<CommandSourceStack> contex
LocalPlayer player1 = Minecraft.getInstance().player;
ServerPlayer player2 = context.getSource().getPlayer();
if (player1 == null || player2 == null) {
context.getSource().sendFailure(Component.literal("This command can only be used by a player"));
context.getSource().sendFailure(Component.translatable("rollback.command.playerOnly"));
return true;
}

Expand Down
15 changes: 10 additions & 5 deletions src/main/java/ir/mehradn/rollback/gui/RollbackScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import eu.midnightdust.lib.config.MidnightConfig;
import ir.mehradn.rollback.Rollback;
import ir.mehradn.rollback.util.backup.BackupManager;
import ir.mehradn.rollback.util.backup.RollbackWorld;
import ir.mehradn.rollback.util.mixin.WorldSelectionListCallbackAction;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand All @@ -25,6 +26,7 @@ public class RollbackScreen extends Screen {
private final Consumer<WorldSelectionListCallbackAction> callback;
private final LevelSummary levelSummary;
private final BackupManager backupManager;
private final RollbackWorld rollbackWorld;
private RollbackSelectionList rollbackList;
private Button rollbackButton;
private Button deleteButton;
Expand All @@ -33,7 +35,8 @@ public RollbackScreen(LevelSummary summary, Consumer<WorldSelectionListCallbackA
super(Component.translatable("rollback.screen.title"));
this.callback = callback;
this.levelSummary = summary;
this.backupManager = new BackupManager();
this.backupManager = BackupManager.loadMetadata();
this.rollbackWorld = this.backupManager.getWorld(this.levelSummary.getLevelId());
}

public void doAction(WorldSelectionListCallbackAction action) {
Expand Down Expand Up @@ -61,7 +64,7 @@ protected void init() {
assert this.minecraft != null;

this.rollbackList = new RollbackSelectionList(
this, this.backupManager, this.levelSummary, this.minecraft,
this, this.backupManager, this.rollbackWorld, this.levelSummary, this.minecraft,
this.width, this.height, 22, this.height - 84, 36
);
addWidget(this.rollbackList);
Expand All @@ -80,11 +83,13 @@ protected void init() {
}
).bounds(this.width / 2 + 4, this.height - 76, 150, 20).build());

boolean automatedEnabled = this.backupManager.getAutomated(this.levelSummary.getLevelId());
addRenderableWidget(CycleButton.onOffBuilder(automatedEnabled).create(
addRenderableWidget(CycleButton.onOffBuilder(this.rollbackWorld.automatedBackups).create(
this.width / 2 - 154, this.height - 52, 150, 20,
Component.translatable("rollback.screen.automatedOption"),
(button, enabled) -> this.backupManager.setAutomated(this.levelSummary.getLevelId(), enabled)
(button, enabled) -> {
this.rollbackWorld.automatedBackups = enabled;
this.backupManager.saveMetadata();
}
));
addRenderableWidget(Button.builder(
Component.translatable("selectWorld.edit.backupFolder"),
Expand Down
16 changes: 10 additions & 6 deletions src/main/java/ir/mehradn/rollback/gui/RollbackSelectionList.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ir.mehradn.rollback.Rollback;
import ir.mehradn.rollback.util.backup.BackupManager;
import ir.mehradn.rollback.util.backup.RollbackBackup;
import ir.mehradn.rollback.util.backup.RollbackWorld;
import ir.mehradn.rollback.util.mixin.WorldSelectionListCallbackAction;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand Down Expand Up @@ -33,15 +34,17 @@
public final class RollbackSelectionList extends ObjectSelectionList<RollbackSelectionList.Entry> {
private final RollbackScreen screen;
private final BackupManager backupManager;
private final RollbackWorld rollbackWorld;
private final LevelSummary summary;
private final CurrentSaveEntry currentSaveEntry;
private boolean shouldReloadEntries;

public RollbackSelectionList(RollbackScreen screen, BackupManager backupManager, LevelSummary levelSummary, Minecraft minecraftClient,
public RollbackSelectionList(RollbackScreen screen, BackupManager backupManager, RollbackWorld rollbackWorld, LevelSummary levelSummary, Minecraft minecraftClient,
int width, int height, int top, int bottom, int itemHeight) {
super(minecraftClient, width, height, top, bottom, itemHeight);
this.screen = screen;
this.backupManager = backupManager;
this.rollbackWorld = rollbackWorld;
this.summary = levelSummary;
this.currentSaveEntry = new CurrentSaveEntry();
this.shouldReloadEntries = true;
Expand Down Expand Up @@ -77,9 +80,8 @@ private void reloadEntries() {
clearEntries();
addEntry(this.currentSaveEntry);

List<RollbackBackup> backups = this.backupManager.getRollbacksFor(this.summary.getLevelId());
for (int i = 1; i <= backups.size(); i++)
addEntry(new RollbackEntry(i, backups.get(backups.size() - i)));
for (int i = 1; i <= this.rollbackWorld.backups.size(); i++)
addEntry(new RollbackEntry(i, this.rollbackWorld.backups.get(this.rollbackWorld.backups.size() - i)));

this.screen.triggerImmediateNarration(true);
this.shouldReloadEntries = false;
Expand Down Expand Up @@ -198,11 +200,13 @@ private DynamicTexture getIconTexture() {
@Environment(EnvType.CLIENT)
public final class RollbackEntry extends Entry {
private final int backupNumber;
private final String worldName;
private final RollbackBackup backup;

public RollbackEntry(int backupNumber, RollbackBackup rollbackBackup) {
super();
this.backupNumber = backupNumber;
this.worldName = RollbackSelectionList.this.summary.getLevelId();
this.backup = rollbackBackup;
this.iconLocation = new ResourceLocation("rollback", "backup/" + this.backupNumber + "/icon.png");
this.icon = getIconTexture();
Expand Down Expand Up @@ -231,7 +235,7 @@ public void playBackup() {
(confirmed) -> {
if (confirmed) {
Rollback.LOGGER.info("Rolling back to backup #{}...", this.backupNumber);
boolean f = RollbackSelectionList.this.backupManager.rollbackTo(this.backup);
boolean f = RollbackSelectionList.this.backupManager.rollbackTo(this.worldName, this.backup);
if (f)
RollbackSelectionList.this.screen.doAction(WorldSelectionListCallbackAction.JOIN_WORLD);
else
Expand All @@ -251,7 +255,7 @@ public void deleteBackup() {
(confirmed) -> {
if (confirmed) {
Rollback.LOGGER.info("Deleting the backup #{}...", this.backupNumber);
RollbackSelectionList.this.backupManager.deleteBackup(this.backup.worldName, -this.backupNumber);
RollbackSelectionList.this.backupManager.deleteBackup(this.worldName, -this.backupNumber);
RollbackSelectionList.this.shouldReloadEntries = true;
}
this.minecraft.setScreen(RollbackSelectionList.this.screen);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ public void setAutomatedBackups(boolean enabled) {
private Optional<LevelStorageSource.LevelStorageAccess> saveOption(Optional<LevelStorageSource.LevelStorageAccess> optional) {
if (optional.isPresent()) {
String worldName = optional.get().getLevelId();
BackupManager backupManager = new BackupManager();
backupManager.setAutomated(worldName, getAutomatedBackups());
BackupManager backupManager = BackupManager.loadMetadata();
backupManager.getWorld(worldName).automatedBackups = getAutomatedBackups();
backupManager.saveMetadata();
}
return optional;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ public BackupManager getBackupManager() {

@Inject(method = "<init>", at = @At("RETURN"))
private void addBackupManager(CallbackInfo ci) {
this.backupManager = new BackupManager();
this.backupManager = BackupManager.loadMetadata();
}
}
11 changes: 7 additions & 4 deletions src/main/java/ir/mehradn/rollback/mixin/WorldListEntryMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ir.mehradn.rollback.config.RollbackConfig;
import ir.mehradn.rollback.gui.RollbackScreen;
import ir.mehradn.rollback.util.backup.BackupManager;
import ir.mehradn.rollback.util.backup.RollbackWorld;
import ir.mehradn.rollback.util.mixin.EditWorldScreenExpanded;
import ir.mehradn.rollback.util.mixin.WorldListEntryExpanded;
import ir.mehradn.rollback.util.mixin.WorldSelectionListCallbackAction;
Expand Down Expand Up @@ -72,7 +73,7 @@ public EditWorldScreen improveEditWorldScreen(EditWorldScreen screen) {

@Inject(method = "deleteWorld", at = @At("RETURN"))
private void deleteBackups(CallbackInfo ci) {
BackupManager backupManager = new BackupManager();
BackupManager backupManager = BackupManager.loadMetadata();
backupManager.deleteAllBackupsFor(this.summary.getLevelId());
}

Expand All @@ -82,13 +83,15 @@ private void promptFeature(CallbackInfo ci) {
return;

this.queueLoadScreen();
BackupManager backupManager = new BackupManager();
String worldName = this.summary.getLevelId();
BackupManager backupManager = BackupManager.loadMetadata();
RollbackWorld rollbackWorld = backupManager.getWorld(worldName);

if (!backupManager.getPrompted(worldName)) {
if (!rollbackWorld.prompted) {
this.minecraft.setScreen(new ConfirmScreen(
(confirmed) -> {
backupManager.setPromptAnswer(worldName, confirmed);
rollbackWorld.setPromptAnswer(confirmed);
backupManager.saveMetadata();
this.loadWorld();
},
Component.translatable("rollback.screen.enableAutomatedQuestion"),
Expand Down
Loading

0 comments on commit e264293

Please sign in to comment.