From c1455ea41190e33ff8b5597b54adddb1700493ad Mon Sep 17 00:00:00 2001 From: Mehrad Nayyeri Date: Sun, 5 Mar 2023 14:44:14 +0330 Subject: [PATCH] Added a prompt to enable the automated backups. --- .../mixin/CreateWorldScreenMixin.java | 40 +++++++++++++++++++ .../rollback/mixin/WorldEntryMixin.java | 25 ++++++++++++ .../rollback/util/backup/BackupManager.java | 19 +++++++++ .../resources/assets/rollback/lang/en_us.json | 3 ++ 4 files changed, 87 insertions(+) diff --git a/src/main/java/ir/mehradn/rollback/mixin/CreateWorldScreenMixin.java b/src/main/java/ir/mehradn/rollback/mixin/CreateWorldScreenMixin.java index 6399413..c6e92f0 100644 --- a/src/main/java/ir/mehradn/rollback/mixin/CreateWorldScreenMixin.java +++ b/src/main/java/ir/mehradn/rollback/mixin/CreateWorldScreenMixin.java @@ -1,15 +1,20 @@ package ir.mehradn.rollback.mixin; +import com.mojang.serialization.Lifecycle; import ir.mehradn.rollback.config.RollbackConfig; import ir.mehradn.rollback.util.backup.BackupManager; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.ConfirmScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.world.CreateWorldScreen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.CyclingButtonWidget; +import net.minecraft.registry.CombinedDynamicRegistries; +import net.minecraft.registry.ServerDynamicRegistryType; import net.minecraft.text.Text; +import net.minecraft.world.level.LevelProperties; import net.minecraft.world.level.storage.LevelStorage; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -27,8 +32,12 @@ public abstract class CreateWorldScreenMixin extends Screen { @Shadow private ButtonWidget gameRulesButton; + @Shadow protected abstract void startServer(LevelProperties.SpecialProperty specialProperty, CombinedDynamicRegistries combinedDynamicRegistries, Lifecycle lifecycle); + private CyclingButtonWidget automatedButton; private int[] buttonPos; + private boolean promptEnabled = true; + private boolean enablePrompted = false; protected CreateWorldScreenMixin(Text title) { super(title); @@ -67,6 +76,33 @@ private void toggleButtons(boolean moreOptionsOpen, CallbackInfo ci) { this.automatedButton.visible = f; } + @Inject(method = "startServer", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/world/CreateWorldScreen;showMessage(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/text/Text;)V")) + private void promptFeature(LevelProperties.SpecialProperty specialProperty, + CombinedDynamicRegistries combinedDynamicRegistries, + Lifecycle lifecycle, + CallbackInfo ci) { + if (!this.promptEnabled) { + this.promptEnabled = true; + return; + } + if (!this.automatedButton.getValue()) { + this.client.setScreen(new ConfirmScreen( + (confirmed) -> { + this.automatedButton.setValue(confirmed); + this.promptEnabled = false; + this.enablePrompted = true; + this.startServer(specialProperty, combinedDynamicRegistries, lifecycle); + }, + Text.translatable("rollback.screen.enableAutomatedQuestion"), + Text.empty(), + Text.translatable("rollback.screen.yes"), + Text.translatable("rollback.screen.no") + )); + ci.cancel(); + } + this.enablePrompted = false; + } + @Inject(method = "createSession", at = @At("RETURN")) private void saveOption(CallbackInfoReturnable> ci) { if (ci.getReturnValue().isEmpty()) @@ -74,5 +110,9 @@ private void saveOption(CallbackInfoReturnable> c String worldName = ci.getReturnValue().get().getDirectoryName(); BackupManager backupManager = new BackupManager(); backupManager.setAutomated(worldName, this.automatedButton.getValue()); + if (this.enablePrompted) { + backupManager.setPrompted(worldName); + this.enablePrompted = false; + } } } diff --git a/src/main/java/ir/mehradn/rollback/mixin/WorldEntryMixin.java b/src/main/java/ir/mehradn/rollback/mixin/WorldEntryMixin.java index 9a9e643..5bfefeb 100644 --- a/src/main/java/ir/mehradn/rollback/mixin/WorldEntryMixin.java +++ b/src/main/java/ir/mehradn/rollback/mixin/WorldEntryMixin.java @@ -7,8 +7,10 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.ConfirmScreen; import net.minecraft.client.gui.screen.world.SelectWorldScreen; import net.minecraft.client.gui.screen.world.WorldListWidget; +import net.minecraft.text.Text; import net.minecraft.world.level.storage.LevelSummary; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -31,6 +33,8 @@ public abstract class WorldEntryMixin extends WorldListWidget.Entry implements A @Shadow protected abstract void openReadingWorldScreen(); + @Shadow + protected abstract void start(); public void rollback() { Rollback.LOGGER.debug("Opening rollback screen..."); @@ -47,4 +51,25 @@ private void deleteBackups(CallbackInfo ci) { BackupManager backupManager = new BackupManager(); backupManager.deleteAllBackupsFor(this.level.getName()); } + + @Inject(method = "start", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/world/WorldListWidget$WorldEntry;openReadingWorldScreen()V")) + private void promptFeature(CallbackInfo ci) { + this.openReadingWorldScreen(); + BackupManager backupManager = new BackupManager(); + String worldName = this.level.getName(); + + if (!backupManager.getPrompted(worldName)) { + this.client.setScreen(new ConfirmScreen( + (confirmed) -> { + backupManager.setPromptAnswer(worldName, confirmed); + this.start(); + }, + Text.translatable("rollback.screen.enableAutomatedQuestion"), + Text.empty(), + Text.translatable("rollback.screen.yes"), + Text.translatable("rollback.screen.no") + )); + ci.cancel(); + } + } } diff --git a/src/main/java/ir/mehradn/rollback/util/backup/BackupManager.java b/src/main/java/ir/mehradn/rollback/util/backup/BackupManager.java index 10438ab..748b7a9 100644 --- a/src/main/java/ir/mehradn/rollback/util/backup/BackupManager.java +++ b/src/main/java/ir/mehradn/rollback/util/backup/BackupManager.java @@ -84,6 +84,8 @@ private JsonObject getWorldObject(String worldName) { if (!worldObject.has("automated")) worldObject.addProperty("automated", false); + if (!worldObject.has("prompted")) + worldObject.addProperty("prompted", false); if (!worldObject.has("backups")) worldObject.add("backups", new JsonArray()); @@ -100,6 +102,23 @@ public boolean getAutomated(String worldName) { return worldObject.get("automated").getAsBoolean(); } + public boolean getPrompted(String worldName) { + JsonObject worldObject = getWorldObject(worldName); + return (worldObject.get("automated").getAsBoolean() || worldObject.get("prompted").getAsBoolean()); + } + + public void setPrompted(String worldName) { + getWorldObject(worldName).addProperty("prompted", true); + saveMetadata(); + } + + public void setPromptAnswer(String worldName, boolean automated) { + JsonObject worldObject = getWorldObject(worldName); + worldObject.addProperty("automated", automated); + worldObject.addProperty("prompted", true); + saveMetadata(); + } + private void showError(String title, String info, Throwable exception) { Rollback.LOGGER.error(info, exception); MinecraftClient.getInstance().getToastManager().add(new SystemToast( diff --git a/src/main/resources/assets/rollback/lang/en_us.json b/src/main/resources/assets/rollback/lang/en_us.json index 47292d5..060b676 100644 --- a/src/main/resources/assets/rollback/lang/en_us.json +++ b/src/main/resources/assets/rollback/lang/en_us.json @@ -15,12 +15,15 @@ "rollback.screen.delete": "Delete", "rollback.screen.options": "Options...", "rollback.screen.cancel": "Cancel", + "rollback.screen.yes": "Yes", + "rollback.screen.no": "No", "rollback.screen.automatedOption": "Automated Backups", "rollback.screen.currentSave": "Current Save", "rollback.screen.lastPlayed": "Last Played: %s", "rollback.screen.deleteQuestion": "Are you sure you want to delete this backup?", "rollback.screen.rollbackQuestion": "Are you sure you want to rollback to this backup?", "rollback.screen.rollbackWarning": "Any not backed up progress will be lost!", + "rollback.screen.enableAutomatedQuestion": "Do you want to enable automated backups for this world?", "rollback.narrator.selectRollback": "Selected backup %d, created: %s, day: %d", "rollback.narrator.selectCurrentSave": "Current save, last played: %s", "rollback.command.list.title": "Backups:",