From 4e3db850aac39a5f59ff75b6ffdae764f43ac3c8 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Thu, 31 Jul 2025 20:11:32 +0800 Subject: [PATCH 1/2] add restore progress bar --- .../client/screen/RestoreScreen.java | 93 +++++++++++++++++-- .../restore/ClientRestoreDelegate.java | 7 +- .../assets/quickbackupmulti/lang/en_us.json | 3 +- .../assets/quickbackupmulti/lang/zh_cn.json | 3 +- ...va => QuickbackupmultiReforgedFabric.java} | 3 +- .../fabric/events/FabricEvents.java | 4 +- fabric/src/main/resources/fabric.mod.json | 2 +- ... => QuickbackupmultiReforgedNeoForge.java} | 5 +- .../neoforge/events/NeoForgeEvents.java | 4 +- .../mixin/MixinNeoforgeServerMain.java | 4 +- 10 files changed, 104 insertions(+), 24 deletions(-) rename fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/{QuickbakcupmultiReforgedFabric.java => QuickbackupmultiReforgedFabric.java} (91%) rename neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/{QuickbakcupmultiReforgedNeoForge.java => QuickbackupmultiReforgedNeoForge.java} (88%) diff --git a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java index 833e7ca..343bded 100644 --- a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java +++ b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java @@ -1,18 +1,33 @@ package io.github.skydynamic.quickbakcupmulti.client.screen; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.BufferUploader; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; import io.github.skydynamic.quickbakcupmulti.translate.Translate; import lombok.Setter; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.TextColor; +import org.joml.Matrix4f; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; public class RestoreScreen extends Screen { private final Button cancelButton; @Setter - private String state = Translate.tr("quickbackupmulti.screen.restore_screen.title"); + private String state = Translate.tr("quickbackupmulti.screen.restore_screen.waiting_for_server"); @Setter - private String progress = "0%"; + private float progress = 0; public RestoreScreen(Button.OnPress onCancelButtonPress) { super(Component.nullToEmpty(Translate.tr("quickbackupmulti.screen.restore_screen.title"))); @@ -29,12 +44,21 @@ protected void init() { @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) { super.render(guiGraphics, mouseX, mouseY, delta); - guiGraphics.drawCenteredString(font, Component.nullToEmpty(this.state), this.width / 2, this.height / 2, 0xFFFFFF); + float centerX = this.width / 2f; + float centerY = this.height / 2f; + guiGraphics.drawCenteredString(font, Component.nullToEmpty(this.state), (int) centerX, (int) centerY - 20, 0xFFFFFF); + drawProgressBar( + guiGraphics.pose(), + centerX - 70, + centerY - 5, + centerX + 70, + centerY + 5 + ); guiGraphics.drawCenteredString( font, - Component.nullToEmpty(Translate.tr("quickbackupmulti.screen.restore_screen.progress") + this.progress), - this.width / 2, - this.height / 2 + 20, + Component.nullToEmpty(Translate.tr("quickbackupmulti.screen.restore_screen.progress", this.getPercentString())), + (int) centerX, + (int) (centerY + 10), 0xFFFFFF ); } @@ -49,6 +73,63 @@ protected boolean shouldNarrateNavigation() { return false; } + private String getPercentString() { + return String.format("%.2f", this.progress * 100); + } + + private void drawProgressBar(PoseStack poseStack, float x0, float y0, float x1, float y1) { + Matrix4f pose = poseStack.last().pose(); + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder builder = tesselator.begin( + VertexFormat.Mode.QUADS, + DefaultVertexFormat.POSITION_COLOR + ); + + float barX0 = x0 + 2; + float barY0 = y0 + 2; + float barX1 = x0 + (x1 - x0) * progress; + float barY1 = y1 - 2; + + int progressBarColor = colorFromRatio(progress, true); + + builder.addVertex(pose, x0, y0, 0.1f) + .setColor(0xffffffff); + builder.addVertex(pose, x0, y1, 0.1f) + .setColor(0xffffffff); + builder.addVertex(pose, x1, y1, 0.1f) + .setColor(0xffffffff); + builder.addVertex(pose, x1, y0, 0.1f) + .setColor(0xffffffff); + + builder.addVertex(pose, barX0, barY0, 0.1f) + .setColor(progressBarColor); + builder.addVertex(pose, barX0, barY1, 0.1f) + .setColor(progressBarColor); + builder.addVertex(pose, barX1, barY1, 0.1f) + .setColor(progressBarColor); + builder.addVertex(pose, barX1, barY0, 0.1f) + .setColor(progressBarColor); + + MeshData data = builder.build(); + if (data == null) return; + RenderSystem.disableDepthTest(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + BufferUploader.drawWithShader(data); + } + + private static int colorFromRatio(double ratio, boolean oneIsGreen) { + double p = ratio; + + if (!oneIsGreen) { + p = 1 - p; + } + + int r = (int) (255d * (Math.max(0, Math.min(2 - 2 * p, 1)))); + int g = (int) (255d * (Math.max(0, Math.min(2 * p, 1)))); + + return 0xFF000000 + (r << 16) + (g << 8); + } + @Override public void renderBackground(GuiGraphics guiGraphics, int i, int j, float f) { this.renderPanorama(guiGraphics, f); diff --git a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/restore/ClientRestoreDelegate.java b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/restore/ClientRestoreDelegate.java index f7a46ba..a98a653 100644 --- a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/restore/ClientRestoreDelegate.java +++ b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/restore/ClientRestoreDelegate.java @@ -32,12 +32,12 @@ public void run() { restoreFuture = CompletableFuture.runAsync(() -> { screen.setState(Translate.tr("quickbackupmulti.restoring_backup.state.make_temp_backup")); + screen.setProgress(0.05f); BackupManager.makeTempBackup(); - screen.setProgress("5%"); screen.setState(Translate.tr("quickbackupmulti.restoring_backup.state.delete_origin_save")); + screen.setProgress(0.1f); deleteWorld(); - screen.setProgress("10%"); if (isCancelled.get()) { handleCancellation(); @@ -46,8 +46,7 @@ public void run() { BackupManager.RestoreExtraRunnable extraRunnable = (totalProgress, currentProgress) -> { screen.setState(Translate.tr("quickbackupmulti.restoring_backup.state.restoring_backup")); - int progress = (int) ((currentProgress / (double) totalProgress) * 0.9 * 100); - screen.setProgress(progress + "%"); + screen.setProgress((float) currentProgress / totalProgress * 0.9f); }; BackupManager.restoreBackup(QuickbakcupmultiReforged.getModContainer().getCurrentSelectionBackup(), extraRunnable); diff --git a/common/src/main/resources/assets/quickbackupmulti/lang/en_us.json b/common/src/main/resources/assets/quickbackupmulti/lang/en_us.json index d5eb9bf..61fea3a 100644 --- a/common/src/main/resources/assets/quickbackupmulti/lang/en_us.json +++ b/common/src/main/resources/assets/quickbackupmulti/lang/en_us.json @@ -50,6 +50,7 @@ "quickbackupmulti.restoring_backup.state.restore_temp_backup": "Restoring save from before backup execution...", "quickbackupmulti.restoring_backup.state.cancel": "Cancelling restore backup...", "quickbackupmulti.screen.restore_screen.title": "Restore Visualization Screen", - "quickbackupmulti.screen.restore_screen.progress": "Progress: ", + "quickbackupmulti.screen.restore_screen.waiting_for_server": "Waiting for server", + "quickbackupmulti.screen.restore_screen.progress": "Progress: %s", "quickbackupmulti.screen.restore_screen.cancel_button": "Cancel" } diff --git a/common/src/main/resources/assets/quickbackupmulti/lang/zh_cn.json b/common/src/main/resources/assets/quickbackupmulti/lang/zh_cn.json index a9d9091..8b3e4bf 100644 --- a/common/src/main/resources/assets/quickbackupmulti/lang/zh_cn.json +++ b/common/src/main/resources/assets/quickbackupmulti/lang/zh_cn.json @@ -50,6 +50,7 @@ "quickbackupmulti.restoring_backup.state.restore_temp_backup": "正在还原执行备份前的存档...", "quickbackupmulti.restoring_backup.state.cancel": "正在取消还原备份...", "quickbackupmulti.screen.restore_screen.title": "回档可视化页面", - "quickbackupmulti.screen.restore_screen.progress": "进度: ", + "quickbackupmulti.screen.restore_screen.waiting_for_server": "等待服务器关闭", + "quickbackupmulti.screen.restore_screen.progress": "进度: %s", "quickbackupmulti.screen.restore_screen.cancel_button": "取消" } diff --git a/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/QuickbakcupmultiReforgedFabric.java b/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/QuickbackupmultiReforgedFabric.java similarity index 91% rename from fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/QuickbakcupmultiReforgedFabric.java rename to fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/QuickbackupmultiReforgedFabric.java index dae65ef..f5d0946 100644 --- a/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/QuickbakcupmultiReforgedFabric.java +++ b/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/QuickbackupmultiReforgedFabric.java @@ -6,12 +6,11 @@ import io.github.skydynamic.quickbakcupmulti.ModContainer; import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged; import lombok.Getter; -import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; -public final class QuickbakcupmultiReforgedFabric implements ModInitializer { +public final class QuickbackupmultiReforgedFabric implements ModInitializer { @Getter private static final ModContainer modContainer = new ModContainer(); diff --git a/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/events/FabricEvents.java b/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/events/FabricEvents.java index 5eb7d98..5fd0f55 100644 --- a/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/events/FabricEvents.java +++ b/fabric/src/main/java/io/github/skydynamic/quickbakcupmulti/fabric/events/FabricEvents.java @@ -1,6 +1,6 @@ package io.github.skydynamic.quickbakcupmulti.fabric.events; -import io.github.skydynamic.quickbakcupmulti.fabric.QuickbakcupmultiReforgedFabric; +import io.github.skydynamic.quickbakcupmulti.fabric.QuickbackupmultiReforgedFabric; import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged; import io.github.skydynamic.quickbakcupmulti.ServerManager; import io.github.skydynamic.quickbakcupmulti.event.OnServerStoppedHandler; @@ -13,7 +13,7 @@ public static void register() { ServerLifecycleEvents.SERVER_STARTED.register(FabricEvents::onServerStarted); CommandRegistrationCallback.EVENT.register( (commandDispatcher, registryAccess, environment) -> { - QuickbakcupmultiReforgedFabric.getModContainer().setDispatcher(commandDispatcher); + QuickbackupmultiReforgedFabric.getModContainer().setDispatcher(commandDispatcher); QuickbakcupmultiReforged.registerCommand(); } ); diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 7ae171c..75bdd9c 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -16,7 +16,7 @@ "environment": "*", "entrypoints": { "main": [ - "io.github.skydynamic.quickbakcupmulti.fabric.QuickbakcupmultiReforgedFabric" + "io.github.skydynamic.quickbakcupmulti.fabric.QuickbackupmultiReforgedFabric" ], "client": [ "io.github.skydynamic.quickbakcupmulti.fabric.client.QuickbakcupmultiReforgedFabricClient" diff --git a/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/QuickbakcupmultiReforgedNeoForge.java b/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/QuickbackupmultiReforgedNeoForge.java similarity index 88% rename from neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/QuickbakcupmultiReforgedNeoForge.java rename to neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/QuickbackupmultiReforgedNeoForge.java index 9e30503..87b306d 100644 --- a/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/QuickbakcupmultiReforgedNeoForge.java +++ b/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/QuickbackupmultiReforgedNeoForge.java @@ -6,19 +6,18 @@ import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged; import lombok.Getter; import lombok.Setter; -import net.neoforged.api.distmarker.Dist; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.fml.loading.FMLPaths; @Mod(value = QuickbakcupmultiReforged.MOD_ID) -public final class QuickbakcupmultiReforgedNeoForge { +public final class QuickbackupmultiReforgedNeoForge { @Getter private static final ModContainer modContainer = new ModContainer(); @Setter @Getter private static String[] boostArgs = null; - public QuickbakcupmultiReforgedNeoForge() { + public QuickbackupmultiReforgedNeoForge() { modContainer.setConfigPath(FMLPaths.CONFIGDIR.get()); modContainer.setEnvType(FMLLoader.getDist().isClient() ? ModEnvType.CLIENT : ModEnvType.SERVER); diff --git a/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/events/NeoForgeEvents.java b/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/events/NeoForgeEvents.java index b78fc7d..6ae00ab 100644 --- a/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/events/NeoForgeEvents.java +++ b/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/events/NeoForgeEvents.java @@ -1,7 +1,7 @@ package io.github.skydynamic.quickbakcupmulti.neoforge.events; import io.github.skydynamic.quickbakcupmulti.config.ModConfig; -import io.github.skydynamic.quickbakcupmulti.neoforge.QuickbakcupmultiReforgedNeoForge; +import io.github.skydynamic.quickbakcupmulti.neoforge.QuickbackupmultiReforgedNeoForge; import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged; import io.github.skydynamic.quickbakcupmulti.event.OnServerStoppedHandler; import io.github.skydynamic.quickbakcupmulti.neoforge.ServerManagerNeoforge; @@ -18,7 +18,7 @@ public class NeoForgeEvents { @SubscribeEvent public static void onRegisterCommands(RegisterCommandsEvent event) { - QuickbakcupmultiReforgedNeoForge.getModContainer().setDispatcher(event.getDispatcher()); + QuickbackupmultiReforgedNeoForge.getModContainer().setDispatcher(event.getDispatcher()); QuickbakcupmultiReforged.registerCommand(); } diff --git a/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/mixin/MixinNeoforgeServerMain.java b/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/mixin/MixinNeoforgeServerMain.java index 83aa9b1..23f65cb 100644 --- a/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/mixin/MixinNeoforgeServerMain.java +++ b/neoforge/src/main/java/io/github/skydynamic/quickbakcupmulti/neoforge/mixin/MixinNeoforgeServerMain.java @@ -1,6 +1,6 @@ package io.github.skydynamic.quickbakcupmulti.neoforge.mixin; -import io.github.skydynamic.quickbakcupmulti.neoforge.QuickbakcupmultiReforgedNeoForge; +import io.github.skydynamic.quickbakcupmulti.neoforge.QuickbackupmultiReforgedNeoForge; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -13,6 +13,6 @@ public class MixinNeoforgeServerMain { at = @At("HEAD") ) private static void injectServerMain(String[] strings, CallbackInfo ci) { - QuickbakcupmultiReforgedNeoForge.setBoostArgs(strings); + QuickbackupmultiReforgedNeoForge.setBoostArgs(strings); } } From 7453c2368f6470c11ef1f88c1173b7344170475f Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Thu, 31 Jul 2025 20:12:24 +0800 Subject: [PATCH 2/2] remove unused import --- .../quickbakcupmulti/client/screen/RestoreScreen.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java index 343bded..7ec9567 100644 --- a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java +++ b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/client/screen/RestoreScreen.java @@ -15,13 +15,8 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.Style; -import net.minecraft.network.chat.TextColor; import org.joml.Matrix4f; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.LockSupport; - public class RestoreScreen extends Screen { private final Button cancelButton; @Setter