From 6d5d3ee3c130b5910164e76d9d5805f2d51d8d9c Mon Sep 17 00:00:00 2001 From: XRain66 <2628883576@qq.com> Date: Tue, 30 Sep 2025 17:42:15 +0800 Subject: [PATCH 1/2] chore: upgrade to Minecraft 1.21.7 and update dependencies - Update minecraft version from 1.21.5 to 1.21.7 - Update parchment mappings to 1.21.7:2025.07.18 - Update fabric-loader to 0.16.13 - Update fabric-api to 0.129.0+1.21.7 - Update neoforge to 21.7.25-beta - Fix renderBlurredBackground method signature in RestoreScreen - Fix ClientRestoreDelegate level disconnect parameters - Add null check for minecraftClient.level before disconnect - Format code indentation --- build.gradle | 2 +- .../client/screen/RestoreScreen.java | 24 +++++++++---------- .../restore/ClientRestoreDelegate.java | 10 ++++---- fabric/build.gradle | 1 + gradle.properties | 8 +++---- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index a46a334..70eab30 100644 --- a/build.gradle +++ b/build.gradle @@ -53,7 +53,7 @@ subprojects { minecraft "net.minecraft:minecraft:$rootProject.minecraft_version" mappings loom.layered() { officialMojangMappings() - parchment("org.parchmentmc.data:parchment-1.21.5:2025.06.15@zip") + parchment("org.parchmentmc.data:parchment-1.21.7:2025.07.18@zip") } // incremental storage 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 3274090..5998631 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 @@ -33,18 +33,18 @@ public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) int centerY = this.height / 2; guiGraphics.drawCenteredString(font, Component.nullToEmpty(this.state), centerX, centerY - 20, 0xFFFFFF); drawProgressBar( - guiGraphics, - centerX - 70, - centerY - 5, - centerX + 70, - centerY + 5 + guiGraphics, + centerX - 70, + centerY - 5, + centerX + 70, + centerY + 5 ); guiGraphics.drawCenteredString( - font, - Component.nullToEmpty(Translate.tr("quickbackupmulti.screen.restore_screen.progress", this.getPercentString())), - centerX, - centerY + 10, - 0xFFFFFF + font, + Component.nullToEmpty(Translate.tr("quickbackupmulti.screen.restore_screen.progress", this.getPercentString())), + centerX, + centerY + 10, + 0xFFFFFF ); } @@ -90,7 +90,7 @@ private static int colorFromRatio(double ratio, boolean oneIsGreen) { @Override public void renderBackground(GuiGraphics guiGraphics, int i, int j, float f) { this.renderPanorama(guiGraphics, f); - this.renderBlurredBackground(); + this.renderBlurredBackground(guiGraphics); this.renderMenuBackground(guiGraphics); } -} +} \ No newline at end of file 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 b1c4217..6d5d5bd 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 @@ -26,8 +26,10 @@ public class ClientRestoreDelegate { public void run() { long startTime = System.currentTimeMillis(); minecraftClient.executeBlocking(() -> { - minecraftClient.level.disconnect(); - minecraftClient.disconnect(screen); + if (minecraftClient.level != null) { + minecraftClient.level.disconnect(Component.translatable("multiplayer.status.quitting")); + } + minecraftClient.disconnect(screen, false); }); restoreFuture = CompletableFuture.runAsync(() -> { @@ -65,7 +67,7 @@ public void run() { }); if (QuickbakcupmultiReforged.getModConfig().isClientAutoReJoinWorld()) { minecraftClient.execute(() -> minecraftClient.createWorldOpenFlows().openWorld(levelId, - () -> minecraftClient.setScreen(null))); + () -> minecraftClient.setScreen(null))); } else { minecraftClient.execute(() -> minecraftClient.setScreen(null)); } @@ -107,4 +109,4 @@ private void deleteWorld() { QuickbakcupmultiReforged.logger.error("Error during delete level", e); } } -} +} \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle index b71dae8..51e2e26 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -24,6 +24,7 @@ configurations { dependencies { modImplementation "net.fabricmc:fabric-loader:$rootProject.fabric_loader_version" + modImplementation "net.fabricmc:fabric-language-kotlin:1.13.0+kotlin.2.1.0" Set apiModules = [ "fabric-command-api-v2", diff --git a/gradle.properties b/gradle.properties index 0a710cc..4009653 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,11 +8,11 @@ mod_id = quickbakcupmulti_reforged archives_name = QuickBakcupMulti-Reforged enabled_platforms = fabric,neoforge # Minecraft properties -minecraft_version = 1.21.5 +minecraft_version = 1.21.7 minecraft_supported_versions = [1.21.5, ) # Dependencies -fabric_loader_version = 0.16.10 -fabric_api_version = 0.123.0+1.21.5 -neoforge_version = 21.5.65-beta +fabric_loader_version = 0.16.13 +fabric_api_version = 0.129.0+1.21.7 +neoforge_version = 21.7.25-beta incremental_storage_lib_version=1.2.0+build.25080123.45 From 080a259c36007f6abfb4f03f130eb10e261e2add Mon Sep 17 00:00:00 2001 From: XRain66 <2628883576@qq.com> Date: Sun, 5 Oct 2025 17:52:21 +0800 Subject: [PATCH 2/2] feat: add index-based restore selection --- .../command/RestoreCommand.java | 41 +++++++++++++++---- .../quickbakcupmulti/utils/BackupManager.java | 25 +++++++++++ .../utils/ListBackupsUtils.java | 25 +++++------ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/command/RestoreCommand.java b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/command/RestoreCommand.java index ca5e4d6..262838e 100644 --- a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/command/RestoreCommand.java +++ b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/command/RestoreCommand.java @@ -31,17 +31,25 @@ public class RestoreCommand { public static final LiteralArgumentBuilder restoreCmd = Commands.literal("restore") .requires(it -> PermissionManager.hasPermission(it, 4, PermissionType.ADMIN)) - .then(Commands.argument("name", StringArgumentType.string()) + .then(Commands.argument("target", StringArgumentType.string()) .suggests(((context, builder) -> { - for (StorageInfo info : BackupManager.getBackupsList()) { - if (info.getName().contains(builder.getRemaining())) { - builder.suggest(info.getName()); + List backups = BackupManager.getSortedBackups(); + String remaining = builder.getRemaining(); + int index = 1; + for (StorageInfo info : backups) { + String name = info.getName(); + if (name.contains(remaining)) { + builder.suggest(name); + } + String idx = String.valueOf(index++); + if (idx.startsWith(remaining)) { + builder.suggest(idx); } } return builder.buildFuture(); })) .executes(it -> - restoreBackup(it.getSource(), StringArgumentType.getString(it, "name")) + restoreBackup(it.getSource(), StringArgumentType.getString(it, "target")) ) ); @@ -63,8 +71,9 @@ public class RestoreCommand { @Getter private static final ConcurrentHashMap> restoreDataMap = new ConcurrentHashMap<>(); - private static int restoreBackup(CommandSourceStack commandSource, String name) { - if (!QuickbakcupmultiReforged.getDatabase().storageExists(name)) { + private static int restoreBackup(CommandSourceStack commandSource, String target) { + String name = resolveBackupName(target); + if (name == null || !QuickbakcupmultiReforged.getDatabase().storageExists(name)) { commandSource.sendSystemMessage(Component.nullToEmpty(tr("quickbackupmulti.restore.fail"))); return 0; } @@ -141,4 +150,22 @@ private static int cancelRestore(CommandSourceStack commandSource) { } return 1; } + + private static String resolveBackupName(String target) { + String trimmed = target.trim(); + if (trimmed.isEmpty()) { + return null; + } + if (trimmed.chars().allMatch(Character::isDigit)) { + try { + int index = Integer.parseInt(trimmed); + StorageInfo info = BackupManager.getBackupByIndex(index); + if (info != null) { + return info.getName(); + } + } catch (NumberFormatException ignored) { + } + } + return trimmed; + } } diff --git a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/BackupManager.java b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/BackupManager.java index 68d3f64..c79e72c 100644 --- a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/BackupManager.java +++ b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/BackupManager.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.UUID; @@ -54,6 +55,30 @@ public static List getBackupsList() { return backupList; } + public static List getSortedBackups() { + return getBackupsList().stream() + .sorted(Comparator.comparingLong(StorageInfo::getTimestamp)) + .toList(); + } + + public static StorageInfo getBackupByIndex(int index) { + List backups = getSortedBackups(); + if (index < 1 || index > backups.size()) { + return null; + } + return backups.get(index - 1); + } + + public static int getBackupIndex(String name) { + List backups = getSortedBackups(); + for (int i = 0; i < backups.size(); i++) { + if (backups.get(i).getName().equals(name)) { + return i + 1; + } + } + return -1; + } + public static void makeBackup(CommandSourceStack commandSource, String name, String desc) { if (QuickbakcupmultiReforged.getDatabase().storageExists(name)) { commandSource.sendSystemMessage(Component.nullToEmpty(tr("quickbackupmulti.make.fail_exists"))); diff --git a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/ListBackupsUtils.java b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/ListBackupsUtils.java index 987e7a8..b48b6e9 100644 --- a/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/ListBackupsUtils.java +++ b/common/src/main/java/io/github/skydynamic/quickbakcupmulti/utils/ListBackupsUtils.java @@ -1,7 +1,6 @@ package io.github.skydynamic.quickbakcupmulti.utils; import io.github.skydynamic.increment.storage.lib.database.StorageInfo; -import io.github.skydynamic.quickbakcupmulti.DatabaseCache; import io.github.skydynamic.quickbakcupmulti.QuickbakcupmultiReforged; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.ClickEvent; @@ -14,9 +13,7 @@ import java.io.File; import java.io.IOException; -import java.nio.file.Path; import java.text.SimpleDateFormat; -import java.util.Comparator; import java.util.List; import static io.github.skydynamic.quickbakcupmulti.translate.Translate.tr; @@ -67,14 +64,16 @@ private static MutableComponent getNextPageText(int page, int totalPage) { return getPageNavigationText("[->]", page, totalPage, 1); } - private static MutableComponent getSlotText(StorageInfo info, int page, int num) throws IOException { + private static MutableComponent getSlotText(StorageInfo info, int page, int num, int globalIndex) throws IOException { String name = info.getName(); MutableComponent backText = Component.literal("§2[▷] "); MutableComponent deleteText = Component.literal("§c[×] "); MutableComponent nameText = Component.literal("§6" + truncateString(name, 8) + "§r "); + MutableComponent indexText = Component.literal("#" + globalIndex + " ") + .withStyle(style -> style.withColor(ChatFormatting.GRAY)); MutableComponent resultText = Component.literal(""); - backText.withStyle(style -> style.withClickEvent(new ClickEvent.SuggestCommand("/qb restore \"%s\"".formatted(name)))) + backText.withStyle(style -> style.withClickEvent(new ClickEvent.SuggestCommand("/qb restore " + globalIndex))) .withStyle(style -> style.withHoverEvent( new HoverEvent.ShowText(Component.nullToEmpty(tr("quickbackupmulti.list_backup.slot.restore", name))))); @@ -89,6 +88,7 @@ private static MutableComponent getSlotText(StorageInfo info, int page, int num) String desc = info.getDesc(); if (desc.isEmpty()) desc = "Empty"; resultText.append("\n" + tr("quickbackupmulti.list_backup.slot.header", num + (5 * (page - 1))) + " ") + .append(indexText) .append(nameText) .append(backText) .append(deleteText) @@ -98,10 +98,7 @@ private static MutableComponent getSlotText(StorageInfo info, int page, int num) public static MutableComponent list(int page) { long totalBackupSizeB = 0; - List backupList = BackupManager.getBackupsList(); - List backupsInfoList = backupList.stream() - .sorted(Comparator.comparingLong(StorageInfo::getTimestamp)) - .toList(); + List backupsInfoList = BackupManager.getSortedBackups(); if (backupsInfoList.isEmpty() || getPageCount(backupsInfoList, page) == 0) { return Component.literal(tr("quickbackupmulti.list_empty")); } @@ -123,8 +120,8 @@ public static MutableComponent list(int page) { for (int j = 1; j <= getPageCount(backupsInfoList, page); j++) { try { StorageInfo info = backupsInfoList.get(((j - 1) + BACKUPS_PER_PAGE * (page - 1))); - String name = info.getName(); - resultText.append(getSlotText(info, page, j)); + int globalIndex = (page - 1) * BACKUPS_PER_PAGE + j; + resultText.append(getSlotText(info, page, j, globalIndex)); } catch (IOException e) { logger.error("Error while listing backups", e); return Component.literal("Error while listing backups").withStyle(ChatFormatting.RED); @@ -143,7 +140,11 @@ public static MutableComponent search(List searchResultList) { try { String name = searchResultList.get(i - 1); StorageInfo result = QuickbakcupmultiReforged.getDatabase().getStorageInfoWithName(name); - resultText.append(getSlotText(result, 1, i)); + int globalIndex = BackupManager.getBackupIndex(name); + if (globalIndex <= 0) { + globalIndex = i; + } + resultText.append(getSlotText(result, 1, i, globalIndex)); } catch (IOException e) { logger.error("Error while searching backups", e); return Component.literal("Error while searching backups").withStyle(ChatFormatting.RED);