From da2e5bd1dc82c56202fd6e65c9133d2e1fb04549 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 29 May 2026 17:25:57 -0700 Subject: [PATCH 01/11] Pin MockBukkit to Maven Central 4.110.0 instead of jitpack snapshot The floating jitpack snapshot v1.21-SNAPSHOT resolves to an ephemeral git-described build whose jar/POM get evicted, breaking CI even on unchanged commits. Switch to the equivalent stable Maven Central coordinates (org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.110.0). Co-Authored-By: Claude Opus 4.8 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a034c5e..4ae7d4a 100644 --- a/pom.xml +++ b/pom.xml @@ -140,9 +140,9 @@ - com.github.MockBukkit - MockBukkit - v1.21-SNAPSHOT + org.mockbukkit.mockbukkit + mockbukkit-v1.21 + 4.110.0 test From ad43941b9fb760d03334183e897acc5df143c1aa Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 27 Jun 2026 17:29:30 -0700 Subject: [PATCH 02/11] Add files via upload --- .github/workflows/publish.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..ac8df96 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,19 @@ +# ControlPanel — .github/workflows/publish.yml +# CurseForge-first rollout. Hangar left blank; add its slug later to enable Hangar. + +name: Publish release + +on: + release: + types: [published] + +jobs: + publish: + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@main + with: + hangar_slug: "" + curseforge_id: "1514827" + game_versions: "26.1.2,26.1.1,26.1,1.21.11,1.21.10,1.21.9,1.21.8,1.21.7,1.21.6" + secrets: + HANGAR_API_KEY: ${{ secrets.HANGAR_API_KEY }} + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} From 9b4121119282b04e2698c2c7f66c15adbd395b30 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 28 Jun 2026 09:02:14 -0700 Subject: [PATCH 03/11] ci: add CurseForge publish workflow (publishes the release asset) Publish the jar attached to each GitHub release to CurseForge via the shared BentoBoxWorld/.github reusable workflow, downloading the release asset instead of rebuilding from source. Mirrors the BentoBox core setup. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/publish.yml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ac8df96..0f3e488 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,19 +1,30 @@ # ControlPanel — .github/workflows/publish.yml -# CurseForge-first rollout. Hangar left blank; add its slug later to enable Hangar. +# Publishes the jar attached to a GitHub release to CurseForge (and Hangar once a +# slug is set) via the shared BentoBoxWorld/.github reusable workflow. It downloads +# the release asset rather than rebuilding from source, so a dependency-repo outage +# can't block publishing. Includes workflow_dispatch to (re)publish a given version. -name: Publish release +name: Publish release to CurseForge on: release: types: [published] + workflow_dispatch: + inputs: + version: + description: "Version to publish (e.g. 1.2.3)" + required: true + type: string jobs: publish: - uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@main + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@master with: - hangar_slug: "" + use_release_asset: "true" # publish the jar attached to the release; do not rebuild + hangar_slug: "" # set the Hangar project slug to enable Hangar publishing curseforge_id: "1514827" - game_versions: "26.1.2,26.1.1,26.1,1.21.11,1.21.10,1.21.9,1.21.8,1.21.7,1.21.6" + game_versions: "26.2,26.1.2,26.1.1,26.1,1.21.11,1.21.10,1.21.9,1.21.8,1.21.7,1.21.6,1.21.5" + version: ${{ inputs.version }} # empty on release events -> falls back to the release tag secrets: HANGAR_API_KEY: ${{ secrets.HANGAR_API_KEY }} CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} From be4b87a307e9f803af5c0d07585bbc916247da44 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 28 Jun 2026 11:17:04 -0700 Subject: [PATCH 04/11] ci: pin reusable workflow to SHA and enable Hangar publish Pin bentoboxworld/.github publish-platforms.yml to commit e0c5d98f5e6ef9ea7c9a28afad05f4c07bcde898 (Sonar githubactions:S7637) and set the Hangar slug so releases publish to Hangar alongside CurseForge. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/publish.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0f3e488..d32c3c8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,8 +1,8 @@ # ControlPanel — .github/workflows/publish.yml -# Publishes the jar attached to a GitHub release to CurseForge (and Hangar once a -# slug is set) via the shared BentoBoxWorld/.github reusable workflow. It downloads -# the release asset rather than rebuilding from source, so a dependency-repo outage -# can't block publishing. Includes workflow_dispatch to (re)publish a given version. +# Publishes the jar attached to a GitHub release to CurseForge via the +# shared BentoBoxWorld/.github reusable workflow. Downloads the release asset instead of +# rebuilding from source. The reusable workflow is pinned to a commit SHA (Sonar +# githubactions:S7637). workflow_dispatch lets you (re)publish a given version. name: Publish release to CurseForge @@ -18,10 +18,10 @@ on: jobs: publish: - uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@master + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@e0c5d98f5e6ef9ea7c9a28afad05f4c07bcde898 # master with: use_release_asset: "true" # publish the jar attached to the release; do not rebuild - hangar_slug: "" # set the Hangar project slug to enable Hangar publishing + hangar_slug: "" # blank = skip Hangar curseforge_id: "1514827" game_versions: "26.2,26.1.2,26.1.1,26.1,1.21.11,1.21.10,1.21.9,1.21.8,1.21.7,1.21.6,1.21.5" version: ${{ inputs.version }} # empty on release events -> falls back to the release tag From 729f9e7cd27d09199aaf82156bf214d266af1d95 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 28 Jun 2026 11:51:22 -0700 Subject: [PATCH 05/11] ci: bump pinned reusable workflow to 71bf927bce32586216baa6995f21852d944b98b9 Picks up the split into independent CurseForge and Hangar jobs so neither platform can block the other. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d32c3c8..2a7c0e7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ on: jobs: publish: - uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@e0c5d98f5e6ef9ea7c9a28afad05f4c07bcde898 # master + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@71bf927bce32586216baa6995f21852d944b98b9 # master with: use_release_asset: "true" # publish the jar attached to the release; do not rebuild hangar_slug: "" # blank = skip Hangar From 0052c3db540d6ed5bc5cec819a2fcad97d969f96 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 30 Jun 2026 23:15:22 -0700 Subject: [PATCH 06/11] ci: bump pinned reusable workflow to fe4b1f0 --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2a7c0e7..ab15cbb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ on: jobs: publish: - uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@71bf927bce32586216baa6995f21852d944b98b9 # master + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@fe4b1f03c19f4fd4212020a06a07a7097923adec # master with: use_release_asset: "true" # publish the jar attached to the release; do not rebuild hangar_slug: "" # blank = skip Hangar @@ -27,4 +27,4 @@ jobs: version: ${{ inputs.version }} # empty on release events -> falls back to the release tag secrets: HANGAR_API_KEY: ${{ secrets.HANGAR_API_KEY }} - CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} \ No newline at end of file From 6efd980ecdcbf5864e51c1e657fb71cb3345b807 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 3 Jul 2026 11:53:54 -0700 Subject: [PATCH 07/11] ci: bump pinned publish-platforms.yml to ca2dcd1 --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ab15cbb..64be91a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ on: jobs: publish: - uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@fe4b1f03c19f4fd4212020a06a07a7097923adec # master + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@ca2dcd167e8db4e0f671a976080744dda43801a6 # master with: use_release_asset: "true" # publish the jar attached to the release; do not rebuild hangar_slug: "" # blank = skip Hangar From a3be0bdf51359edefd8a5570deca375b64acd3b7 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 12 Jul 2026 08:50:05 -0700 Subject: [PATCH 08/11] Reload re-imports control panels from the template file Control panels were pinned to the database after the first seed, so editing controlPanelTemplate.yml and running 'bbox reload' had no effect: onReload only re-read the database. The only way to apply template edits was the confirmation-gated admin import command. onReload now wipes and re-imports each active game mode from the template so plain reloads pick up edits. The template file name is configurable via a new 'template-file' entry in config.yml (default controlPanelTemplate.yml), honored by reload, importControlPanels, and the admin import command. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_0118vFoM1ejLPLUGdz4sLunb --- .../controlpanel/ControlPanelAddon.java | 12 +++ .../commands/admin/AdminCommand.java | 5 +- .../controlpanel/config/Settings.java | 30 ++++++ .../managers/ControlPanelManager.java | 25 ++++- src/main/resources/config.yml | 6 ++ .../controlpanel/config/SettingsTest.java | 11 +++ .../managers/ControlPanelManagerTest.java | 91 +++++++++++++++++++ 7 files changed, 176 insertions(+), 4 deletions(-) diff --git a/src/main/java/world/bentobox/controlpanel/ControlPanelAddon.java b/src/main/java/world/bentobox/controlpanel/ControlPanelAddon.java index 183b882..ad5d79b 100644 --- a/src/main/java/world/bentobox/controlpanel/ControlPanelAddon.java +++ b/src/main/java/world/bentobox/controlpanel/ControlPanelAddon.java @@ -138,7 +138,19 @@ public void onReload() } else { + // Reload the database into cache first so wipe/re-import operate on a + // consistent view of what is currently stored. this.manager.reload(); + + // Re-import each active game mode's panels from controlPanelTemplate.yml so + // that admin edits to the template take effect on reload. Without this the + // panels stay pinned to whatever was first seeded into the database. + this.getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> { + if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName())) + { + this.manager.reimportControlPanels(gameModeAddon); + } + }); } } diff --git a/src/main/java/world/bentobox/controlpanel/commands/admin/AdminCommand.java b/src/main/java/world/bentobox/controlpanel/commands/admin/AdminCommand.java index f3d5fa0..9f26223 100644 --- a/src/main/java/world/bentobox/controlpanel/commands/admin/AdminCommand.java +++ b/src/main/java/world/bentobox/controlpanel/commands/admin/AdminCommand.java @@ -127,9 +127,10 @@ public void setup() @Override public boolean execute(User user, String label, List args) { - ControlPanelManager manager = this.getAddon().getAddonManager(); + ControlPanelAddon addon = this.getAddon(); + ControlPanelManager manager = addon.getAddonManager(); - String fileName = args.size() == 1 ? args.get(0) : "controlPanelTemplate.yml"; + String fileName = args.size() == 1 ? args.get(0) : addon.getSettings().getTemplateFile(); if (manager.hasAnyControlPanel(this.getWorld())) { diff --git a/src/main/java/world/bentobox/controlpanel/config/Settings.java b/src/main/java/world/bentobox/controlpanel/config/Settings.java index 7be79aa..9c03862 100644 --- a/src/main/java/world/bentobox/controlpanel/config/Settings.java +++ b/src/main/java/world/bentobox/controlpanel/config/Settings.java @@ -52,6 +52,28 @@ public void setDisabledGameModes(Set disabledGameModes) } + /** + * This method returns the templateFile value. + * + * @return the value of templateFile. + */ + public String getTemplateFile() + { + return templateFile; + } + + + /** + * This method sets the templateFile value. + * + * @param templateFile the templateFile new value. + */ + public void setTemplateFile(String templateFile) + { + this.templateFile = templateFile; + } + + // --------------------------------------------------------------------- // Section: Variables // --------------------------------------------------------------------- @@ -64,4 +86,12 @@ public void setDisabledGameModes(Set disabledGameModes) @ConfigComment(" - BSkyBlock") @ConfigEntry(path = "disabled-gamemodes") private Set disabledGameModes = new HashSet<>(); + + @ConfigComment("") + @ConfigComment("The template file that control panels are imported from.") + @ConfigComment("This file is read when panels are first seeded and re-read on every reload,") + @ConfigComment("so editing it and running 'bbox reload' will apply your changes.") + @ConfigComment("It must exist in the addon folder (addons/ControlPanel).") + @ConfigEntry(path = "template-file") + private String templateFile = "controlPanelTemplate.yml"; } diff --git a/src/main/java/world/bentobox/controlpanel/managers/ControlPanelManager.java b/src/main/java/world/bentobox/controlpanel/managers/ControlPanelManager.java index e7cc2f0..ed87ed6 100644 --- a/src/main/java/world/bentobox/controlpanel/managers/ControlPanelManager.java +++ b/src/main/java/world/bentobox/controlpanel/managers/ControlPanelManager.java @@ -55,7 +55,8 @@ public ControlPanelManager(ControlPanelAddon addon) { this.addon = addon; - // save template file into directory. + // Save the default template file into the directory. The configured template file + // may point elsewhere, but the packaged default is always named controlPanelTemplate.yml. if (!new File(this.addon.getDataFolder(), "controlPanelTemplate.yml").exists()) { this.addon.saveResource("controlPanelTemplate.yml", false); @@ -128,6 +129,26 @@ public void reload() } + /** + * This method re-imports the control panels for the given game mode from the + * template file configured via {@code template-file} in config.yml (defaults to + * {@code controlPanelTemplate.yml}), replacing whatever is currently stored in the + * database and cache. + *

+ * This is what makes edits to the template file take effect on {@code bbox reload}: + * without it, {@link #reload()} only re-reads the database and template changes are + * silently ignored. + * + * @param gameModeAddon Game mode whose panels must be re-imported from the template. + */ + public void reimportControlPanels(@NotNull GameModeAddon gameModeAddon) + { + // Clear existing data so removed/renamed panels do not linger, then re-read the template. + this.wipeData(gameModeAddon, null); + this.importControlPanels(null, gameModeAddon); + } + + // --------------------------------------------------------------------- // Section: Save methods // --------------------------------------------------------------------- @@ -226,7 +247,7 @@ public void importControlPanels(@Nullable User user, @NotNull World world, @NotN */ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addon) { - this.importControlPanels(user, addon, "controlPanelTemplate"); + this.importControlPanels(user, addon, this.addon.getSettings().getTemplateFile()); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 84d005c..2d3e59d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -5,3 +5,9 @@ # disabled-gamemodes: # - BSkyBlock disabled-gamemodes: [] +# +# The template file that control panels are imported from. +# This file is read when panels are first seeded and re-read on every reload, +# so editing it and running 'bbox reload' will apply your changes. +# It must exist in the addon folder (addons/ControlPanel). +template-file: controlPanelTemplate.yml diff --git a/src/test/java/world/bentobox/controlpanel/config/SettingsTest.java b/src/test/java/world/bentobox/controlpanel/config/SettingsTest.java index fca8b04..0e37f60 100644 --- a/src/test/java/world/bentobox/controlpanel/config/SettingsTest.java +++ b/src/test/java/world/bentobox/controlpanel/config/SettingsTest.java @@ -35,4 +35,15 @@ void testSetDisabledGameModes() { assertTrue(settings.getDisabledGameModes().contains("BSkyBlock")); assertTrue(settings.getDisabledGameModes().contains("AcidIsland")); } + + @Test + void testDefaultTemplateFile() { + assertEquals("controlPanelTemplate.yml", settings.getTemplateFile()); + } + + @Test + void testSetTemplateFile() { + settings.setTemplateFile("myPanels.yml"); + assertEquals("myPanels.yml", settings.getTemplateFile()); + } } diff --git a/src/test/java/world/bentobox/controlpanel/managers/ControlPanelManagerTest.java b/src/test/java/world/bentobox/controlpanel/managers/ControlPanelManagerTest.java index aaf0186..02e3dc3 100644 --- a/src/test/java/world/bentobox/controlpanel/managers/ControlPanelManagerTest.java +++ b/src/test/java/world/bentobox/controlpanel/managers/ControlPanelManagerTest.java @@ -57,6 +57,7 @@ public void setUp() throws Exception { when(addon.getPlugin()).thenReturn(plugin); when(addon.getLogger()).thenReturn(Logger.getAnonymousLogger()); + when(addon.getSettings()).thenReturn(new world.bentobox.controlpanel.config.Settings()); File dataFolder = new File("addons/ControlPanel"); dataFolder.mkdirs(); @@ -260,6 +261,96 @@ void testReload() { manager.reload(); } + @Test + void testReimportControlPanelsReadsTemplateFile() throws Exception { + // Make import's trailing getAddonManager().save() call resolve to this manager. + when(addon.getAddonManager()).thenReturn(manager); + + // Write a template file that reimport should read from disk. + writeTemplate(""" + panel-list: + default: + defaultPanel: true + panelName: 'From Template' + permission: 'default' + buttons: + 0: + name: 'Island' + material: GRASS_BLOCK + description: 'Go to your island' + command: '[label] go' + """); + + GameModeAddon gameModeAddon = mock(GameModeAddon.class); + manager.reimportControlPanels(gameModeAddon); + + // Template panel is now in the cache. + assertTrue(manager.hasAnyControlPanel(world)); + ControlPanelObject panel = manager.getUserControlPanel(User.getInstance(mockPlayer), world, "bskyblock."); + assertNotNull(panel); + assertEquals("From Template", panel.getPanelName()); + } + + @Test + void testReimportControlPanelsRemovesDeletedPanels() throws Exception { + when(addon.getAddonManager()).thenReturn(manager); + + // Seed the cache with an existing panel, as if previously stored in the database. + when(handler.loadObjects()).thenReturn(Collections.singletonList(createDefaultPanel())); + manager.reload(); + assertTrue(manager.hasAnyControlPanel(world)); + + // A template with no panel-list entries should wipe the stored panel on reimport. + writeTemplate("panel-list: {}\n"); + + GameModeAddon gameModeAddon = mock(GameModeAddon.class); + manager.reimportControlPanels(gameModeAddon); + + assertFalse(manager.hasAnyControlPanel(world)); + } + + @Test + void testReimportControlPanelsUsesConfiguredTemplateFile() throws Exception { + // Point the config at a custom template file name. + world.bentobox.controlpanel.config.Settings settings = + new world.bentobox.controlpanel.config.Settings(); + settings.setTemplateFile("customPanels.yml"); + when(addon.getSettings()).thenReturn(settings); + when(addon.getAddonManager()).thenReturn(manager); + + // The default template exists but is empty; only the custom file has a panel. + writeTemplate("panel-list: {}\n"); + writeNamedTemplate("customPanels.yml", """ + panel-list: + default: + defaultPanel: true + panelName: 'From Custom File' + permission: 'default' + buttons: + 0: + name: 'Island' + material: GRASS_BLOCK + description: 'Go to your island' + command: '[label] go' + """); + + GameModeAddon gameModeAddon = mock(GameModeAddon.class); + manager.reimportControlPanels(gameModeAddon); + + ControlPanelObject panel = manager.getUserControlPanel(User.getInstance(mockPlayer), world, "bskyblock."); + assertNotNull(panel); + assertEquals("From Custom File", panel.getPanelName()); + } + + private void writeTemplate(String content) throws Exception { + writeNamedTemplate("controlPanelTemplate.yml", content); + } + + private void writeNamedTemplate(String name, String content) throws Exception { + File templateFile = new File(new File("addons/ControlPanel"), name); + java.nio.file.Files.writeString(templateFile.toPath(), content); + } + private ControlPanelObject createDefaultPanel() { ControlPanelObject cpo = new ControlPanelObject(); cpo.setUniqueId("BSkyBlock_default"); From 8f4777e94498ad7281d2cc9e4e9805f056d7b85d Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 29 Jul 2026 09:07:48 -0700 Subject: [PATCH 09/11] ci: bump publish-platforms pin to the multipart-JSON fix The pinned SHA predates BentoBoxWorld/.github#13, which moved the CurseForge metadata and Hangar versionUpload JSON out of inline curl -F values and into files. curl treats a ';' in an inline -F value as the start of a type= attribute, so a release body containing a semicolon truncates the JSON and both platforms reject the upload. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01SAQ3YQkcfRoCZEwa6SPJcp --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 64be91a..680b3a2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ on: jobs: publish: - uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@ca2dcd167e8db4e0f671a976080744dda43801a6 # master + uses: bentoboxworld/.github/.github/workflows/publish-platforms.yml@1f91a0edf72e8c86d671b3b8fdd3121ac6fb88e1 # master with: use_release_asset: "true" # publish the jar attached to the release; do not rebuild hangar_slug: "" # blank = skip Hangar From f2cffa251529f0c5ead371c36f2a120a804161ea Mon Sep 17 00:00:00 2001 From: qwe664 <93234700+qwe664@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:59:50 +0800 Subject: [PATCH 10/11] Update Chinese translations in zh-TW.yml --- src/main/resources/locales/zh-TW.yml | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/resources/locales/zh-TW.yml b/src/main/resources/locales/zh-TW.yml index 9549694..f312fd3 100644 --- a/src/main/resources/locales/zh-TW.yml +++ b/src/main/resources/locales/zh-TW.yml @@ -1,23 +1,21 @@ ---- controlpanel: messages: - import-count: 導入 [number] 控制面板 - control-panels-wiped: "&2 所有為 [gamemode] 模式的控制面板已移除" + import-count: 已匯入 [number] 個控制面板。 + control-panels-wiped: '&2已移除 [gamemode] 的所有控制面板。' errors: - no-load: "&4 無法讀取 [file] 原因: [message]" - no-file: "&4 遺失 [file] 檔案" - no-valid-panels: "&4 未發現任何可用的控制面板" - no-valid-panels-op: "&4 未發現任何可用的控制面板. 你應該試著去導入他 請使用 /[admin] cp import" - not-a-gamemode-world: "&4 未發現任何有效的模式" + no-load: '&4無法載入檔案 [file]:[message]' + no-file: '&4找不到檔案 [file]。' + not-a-gamemode-world: '&4找不到有效的遊戲模式。' + no-valid-panels: '&4找不到任何有效的控制面板。' + no-valid-panels-op: '&4找不到任何有效的控制面板。請嘗試使用 /[admin] cp import 匯入。' commands: admin: help: - description: '顯示管理員幫助指令 - -' + description: 顯示管理員說明指令。 import: - parameters: "[file-name] - 要導入的檔案的名子. 檔案為空 所以我們將創建 一般面板." - description: 導入控制面板從 [file] - confirmation: 請確認您要從 [gamemode] 中刪除現有控制面板,並從 [file] 中導入控制面板 + parameters: '[file-name] - 要匯入的檔案名稱。留空則匯入預設範本。' + description: 從 [file] 匯入控制面板。 + confirmation: 請確認是否要移除 [gamemode] 目前的控制面板,並從 [file] 匯入新的控制面板。 help: - description: 開啟控制面板 + parameters: '' + description: 開啟控制面板。 From ef9c192629f2a1bfa0ffa83e66d4fcfbd0044d36 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 31 Aug 2026 07:44:56 -0700 Subject: [PATCH 11/11] Lower minimum BentoBox version to 2.7.1 and bump to 1.16.1 The 3.10.0 api-version floor was set as a build baseline during the Java 21 / Paper modernisation, not because the addon uses any 3.x API. The source compiles cleanly against BentoBox 2.7.1, so declare that as the minimum instead. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_013xDgjUJJZc9c91WoAEg1vh --- pom.xml | 2 +- src/main/resources/addon.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4ae7d4a..58efb10 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ ${build.version}-SNAPSHOT - 1.16.0 + 1.16.1 -LOCAL BentoBoxWorld_ControlPanel diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index de01fef..76dc9d8 100644 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -12,7 +12,7 @@ repository: 'BentoBoxWorld/ControlPanel' # Must use Material.values() with uppercase. icon: 'COMMAND_BLOCK' # Minimum BentoBox API version -api-version: 3.10.0 +api-version: 2.7.1 # List of addon authors. authors: