fix: UltiEssentials residue defects (#21, #24, #33, #39, #40, #41, #42, #45, #47, #48, #49, #51, #54, #56, #59, #60, #61, #62) - #64
Conversation
#41) The two existing ensureUnique tests seeded the board's own entries to force a collision; they now configure two equal lines, the collision the dedup exists for, since a line is made unique against this update's lines. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nd is kept per player (#40) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…eboard's teams onto it (#40) Maintainer decision 2026-09-27: whoever gives a player a private scoreboard carries the main board's teams onto it. The board is built once and updated in place, so the copy survives and the sidebar is no longer rebuilt every second. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ays so (#40) The test player's scoreboard now follows setScoreboard. The update-loop isolation test asserted that the second player's board was assigned again on every update; it now asserts that the refresh rendered the player's line, since a board already on screen is no longer assigned again. Red on master by compilation (the slot query does not exist yet); behaviour-level reds are mutation proofs on each yield guard. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…board (#40) The offline-player isolation test re-enabled the same player object while it still held the board of its earlier session; a returning player views the main scoreboard, which is what the yield guard reads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…aken (#40) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ys so (#40) Mutual yield as the maintainer decided on 2026-09-27: the board is shown only while the player views the main scoreboard or this module's own board, is removed only while it is on screen, and comes back on the next update once the slot is free. /scoreboard on and toggle reply truthfully when another scoreboard keeps the slot, and one start-up line reports UltiSideBar's sidebar. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ed auto-enable (#45) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The command test verified the service's plain disable; turning it off now goes through the call that also remembers the choice for the session. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…es it off (#45) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…h PlaceholderAPI installed (#59) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ugh the title (#59) The test made the rebuild fail through player.getWorld(), which the old fallback called for every line whatever it contained; built-in placeholders are now filled only where they occur, so the reloaded title names the world. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Scoreboard lines and name prefixes fill this module's own placeholders in one pass over the text as written, then hand the result to PlaceholderAPI when it is installed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e is shut down (#51) ScoreboardService and NamePrefixService set a flag in shutdown() that reload() clears again, so a delayed enable or prefix update that fires after an unload does nothing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ervice (#51) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… unloads (#51) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…es (#54) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Expired on read and swept on every new request, as the maintainer decided on 2026-09-27; the cooldown itself behaves as before and a reconnect still does not reset it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… or ban completion, and can always un-vanish (#56) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… completion, and let them always un-vanish (#56) All three paths as the maintainer decided on 2026-09-27. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ous chunk load (#24) The safety-check tests left the player offline, which the main-thread check now respects, and the MockBukkit thread test runs on a world that answers the asynchronous chunk request MockBukkit itself leaves unimplemented. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…hem on the main thread (#24) Attempts are chained, up to ten as before; the configured cooldown is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ation (#33) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The listener tests that recorded a raw COMMAND or PLUGIN teleport now assert that such a teleport, which this module did not start, is not recorded; the event-bus test now drives /back's own teleport through the bus. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rts (#39) An OwnTeleports mark is set for one player around each of this module's command teleports and removed in a finally block; the listener records only a teleport carrying it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…reaches (#47) Tests of the two uncalled unban methods are removed; those that exercised the shared verified-deactivation logic through the by-UUID method now go through the by-name method, which /unban uses. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 354894f1e7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!Objects.equals(source.displayName(), copy.displayName())) { | ||
| copy.displayName(source.displayName()); |
There was a problem hiding this comment.
Preserve compatibility with legacy scoreboard APIs
On the advertised Minecraft 1.8–1.21 range, releases whose scoreboard API predates the Adventure component accessors do not provide Team.displayName(), prefix(), or suffix(), so the first default-enabled sidebar refresh reaches this method and fails at runtime with NoSuchMethodError. The previous implementation used the legacy string prefix/suffix API; use compatible accessors or isolate these calls behind a version adapter so the new team mirror does not disable the sidebar on older supported servers.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Not a failure on a server this module can run on, but the advertised platform was wrong, and that is fixed in ee65c1a. The UltiTools framework this module is loaded by declares Bukkit api-version: 1.19 and uses Paper's Adventure API throughout (its own Component messages), so neither Spigot nor a pre-1.19 server can load the framework at all, let alone reach this method. On Paper 1.19+ Team#displayName()/prefix()/suffix() are present (Paper has had them since 1.16.5). The README badge claimed "Minecraft 1.8–1.21" linked to spigotmc.org; it now says Paper 1.19–1.21 and states that Spigot and older servers are not supported. The Adventure accessors are kept on purpose: the legacy string accessors round-trip through a legacy serializer and can lose hex colours in a copied prefix.
…rk does The badge advertised Spigot and 1.8; the framework declares api-version 1.19 and uses Paper's Adventure API throughout, so neither ever ran this module. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee65c1ae7c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return; | ||
| } | ||
|
|
||
| declinedPlayers.remove(player.getUniqueId()); |
There was a problem hiding this comment.
Preserve declined choices during automatic reload enablement
When a player has used /scoreboard off and an administrator disables then re-enables the scoreboard feature during the same session, reload() sees wasRunning == false, follows scoreboard.auto-enable, and calls this method, which clears the player's decline marker and shows the sidebar again. This violates the new session-long opt-out behavior; automatic reload restoration should skip declined players or only the explicit /scoreboard on path should remove this marker.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 673c033 (test) and f882df7 (fix). The decline was honoured by the delayed join enable only; the reload path was the other automatic caller of the same enable and was missed. enableScoreboard now skips a declined player, so no automatic enable can override the choice, and only the player's own /scoreboard on or toggle (acceptScoreboard) clears it. The test turns the feature off and on by two reloads after /scoreboard off; a control without the off still shows the sidebar.
…yer's /scoreboard off (#45) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…scoreboard off (#45) The decline was honoured by the delayed join enable only; a reload that turns the feature on enabled by auto-enable and cleared it. enableScoreboard now skips a declined player, and only /scoreboard on and toggle (acceptScoreboard) clear the decline. Two command tests now verify the renamed call. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review
|
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Issue closure
Closes #21 — the main-class test runs in the build, from a module jar the test builds itself
(主类测试在构建中运行,使用测试自行构建的模块 jar)
Closes #24 — /wild loads candidate chunks asynchronously and does all world work and the teleport on the main thread
(/wild 异步加载区块,世界读取和传送都在主线程执行)
Closes #33 — /wild reports the landing block position
(/wild 报告实际落脚的方块坐标)
Closes #39 — /back records only this module's own teleports
(/back 只记录本模块自己的传送)
Closes #40 — one board per player, reused; main-board teams copied onto it so name prefixes stay visible; the sidebar yields to another plugin's scoreboard
(每位玩家复用一个计分板;复制主计分板队伍使名称前缀可见;让出被其他插件占用的侧边栏位置)
Closes #41 — lines are truncated before they are made unique
(先截断再去重)
Closes #42 — the checklist and inventory name the real key, features.scheduled-commands.commands
(清单与清单文档写明真实键名 features.scheduled-commands.commands)
Closes #45 — /scoreboard off right after joining stays off
(刚加入时执行 /scoreboard off 后保持关闭)
Closes #47 — the never-reachable BanService#unbanIp/#unbanPlayer(UUID) and the /unbanip javadoc line are removed; the command is requested in #63
(删除不可达的 unbanIp/unbanPlayer(UUID) 和 /unbanip 文档;功能请求见 #63)
Closes #48 — the pardon alias is removed
(删除 pardon 别名)
Closes #49 — test-scope H2 and commons-dbutils run a real relational insert, update and delete
(测试范围引入 H2 与 commons-dbutils,执行真实的关系型增改删)
Closes #51 — after an unload the delayed join callbacks do nothing and every pending /tpa expiry is cancelled
(卸载后延迟回调不再执行,所有待处理的 /tpa 过期任务被取消)
Closes #54 — the /tpa cooldown map drops expired entries
(/tpa 冷却表清除过期条目)
Closes #56 — vanished players are hidden from /tpa, /tpahere and ban completions, and can un-vanish whatever features.hide.enabled says
(隐身玩家不会出现在 /tpa、/tpahere 和封禁补全中;无论开关如何都能取消隐身)
Closes #59 — built-in placeholders are filled in one pass before PlaceholderAPI
(内置占位符一次性填充后再交给 PlaceholderAPI)
Closes #60 — the w alias of /warp is removed
(删除 /warp 的 w 别名)
Closes #61 — /ban, /banlist and /scoreboard are documented as deliberate takeovers of the vanilla commands (vanilla stays reachable as minecraft:)
(文档写明 /ban、/banlist、/scoreboard 有意接管原版命令(原版可用 minecraft: 前缀))
Closes #62 — the ul, l and sb aliases are removed
(删除 ul、l、sb 别名)
Decisions applied
pardon,w) are removed; the primary names/ban,/banlistand/scoreboardare kept and documented as takeovers.ul,landsb.Checklist rows amended
UAT-CHECKLIST.md:ultiessentials.wild.teleport,ultiessentials.back.teleport,ultiessentials.back.teleport.neg-no-location,ultiessentials.back.track,ultiessentials.back.track.neg-foreign-teleport,ultiessentials.tpa.send.neg-vanished-target,ultiessentials.hide.toggle.neg-disabled-unvanish,ultiessentials.scoreboard.toggle,ultiessentials.scoreboard.enable,ultiessentials.scoreboard.disable,ultiessentials.scoreboard.auto-enable-on-join,ultiessentials.ban.ban.neg-completion-vanished,ultiessentials.ban.unban.neg-also-server-banned,ultiessentials.nameprefix.on-join,ultiessentials.scheduledcommands.run,ultiessentials.lifecycle.reload-scoreboard-off,ultiessentials.compat.ultisidebar-yieldFEATURES.md:ultiessentials.wild.teleport,ultiessentials.back.teleport,ultiessentials.back.track,ultiessentials.warp.teleport,ultiessentials.tpa.send,ultiessentials.tpa.send-here,ultiessentials.hide.toggle,ultiessentials.scoreboard.toggle,ultiessentials.scoreboard.enable,ultiessentials.scoreboard.disable,ultiessentials.scoreboard.auto-enable-on-join,ultiessentials.ban.ban,ultiessentials.ban.unban,ultiessentials.banlist.list,ultiessentials.lock.lock,ultiessentials.lock.unlock,ultiessentials.nameprefix.on-join,ultiessentials.lifecycle.unload-tasks,ultiessentials.config.essentials.features.hide.enabled,ultiessentials.config.essentials.features.scoreboard.enabled,ultiessentials.config.essentials.features.scoreboard.title,ultiessentials.config.essentials.features.scoreboard.lines,ultiessentials.config.essentials.features.nameprefix.prefix-format,ultiessentials.compat.ultisidebar-yieldRow IDs are taken from the diff against the base branch; a row whose ID appears is added, removed or changed.
Red-when-reverted evidence
Each fix was reverted on its own at the head and its tests re-run: red with the fix reverted, green with it (log file names, kept with the phase evidence). A
-review-pair proves a fix made after this pull request's own review, a-codex-rNpair a fix made after the automated review's round N, and a-sweep-pair a same-class fix found by a sweep.UltiEssentials-21-GREEN.log/UltiEssentials-21-RED.logUltiEssentials-24-GREEN.log/UltiEssentials-24-RED.log/UltiEssentials-24-codex-r1-GREEN.log/UltiEssentials-24-codex-r1-RED.logUltiEssentials-33-GREEN.log/UltiEssentials-33-RED.logUltiEssentials-39-GREEN.log/UltiEssentials-39-RED.logUltiEssentials-40-GREEN.log/UltiEssentials-40-RED.log/UltiEssentials-40-codex-r2-GREEN.log/UltiEssentials-40-codex-r2-RED.log/UltiEssentials-40-codex-r4-GREEN.log/UltiEssentials-40-codex-r4-RED.log/UltiEssentials-40-codex-r5-GREEN.log/UltiEssentials-40-codex-r5-RED.log/UltiEssentials-40-codex-r6-GREEN.log/UltiEssentials-40-codex-r6-RED.log/UltiEssentials-40-mirror-GREEN.log/UltiEssentials-40-mirror-RED.log/UltiEssentials-40-sweep-team-entries-GREEN.log/UltiEssentials-40-sweep-team-entries-RED.log/UltiEssentials-40-yield-GREEN.log/UltiEssentials-40-yield-RED.log; plus 13 mutation pairsUltiEssentials-40-MUTATION-<name>-RED.log/-GREEN.log, each one neutralising a single call or check and going redUltiEssentials-41-GREEN.log/UltiEssentials-41-RED.logUltiEssentials-42-GREEN.log/UltiEssentials-42-RED.logUltiEssentials-45-GREEN.log/UltiEssentials-45-RED.log/UltiEssentials-45-codex-r9-GREEN.log/UltiEssentials-45-codex-r9-RED.log; plus 3 mutation pairsUltiEssentials-45-MUTATION-<name>-RED.log/-GREEN.log, each one neutralising a single call or check and going redUltiEssentials-47-GREEN.log/UltiEssentials-47-RED.logUltiEssentials-48-GREEN.log/UltiEssentials-48-RED.logUltiEssentials-49-GREEN.log/UltiEssentials-49-RED.logUltiEssentials-51-GREEN.log/UltiEssentials-51-RED.log/UltiEssentials-51-flags-GREEN.log/UltiEssentials-51-flags-RED.log/UltiEssentials-51-tpa-GREEN.log/UltiEssentials-51-tpa-RED.log; plus 4 mutation pairsUltiEssentials-51-MUTATION-<name>-RED.log/-GREEN.log, each one neutralising a single call or check and going redUltiEssentials-54-GREEN.log/UltiEssentials-54-RED.logUltiEssentials-56-GREEN.log/UltiEssentials-56-RED.log/UltiEssentials-56-codex-r3-GREEN.log/UltiEssentials-56-codex-r3-RED.logUltiEssentials-59-GREEN.log/UltiEssentials-59-RED.logUltiEssentials-60-GREEN.log/UltiEssentials-60-RED.logUltiEssentials-61-GREEN.log/UltiEssentials-61-RED.logUltiEssentials-62-GREEN.log/UltiEssentials-62-RED.logBehaviour changes
From
CHANGELOG.md## [Unreleased], as added by this pull request:Known limitation
This module's
plugin.ymlapi-versionand any README compatibility line still advertise the pre-6.3.0 API level, and the framework's 6.3.0 lifecycle hooks (onReload(),onUnregister()) run only under a 6.3.0 framework. Theapi-version: 630pin lands together with the UltiTools 6.3.0 release package, by an earlier maintainer decision, before any module release. No module version is bumped and nothing is released from this pull request. Tracking instance: UltiKits/UltiRecipe#19.Gates
This repository is not onboarded to Codacy — gate 2 for module repositories is the Codex review only, per the phase's carried-forward decision.
/wildsearch pending at unload; sidebar rows formatted by a copied team; the reused sidebar board's objective, slot and lines not restored, and board-wide writes reaching another plugin's content; a vanished player hidden from themselves (P3); a reload that turned the feature on overriding/scoreboard off. Settled by the maintainer's decisions: ownership of the private board (#65), a foreign board counting as occupied (UltiKits/UltiSideBar#29). Platform finding answered by stating Paper 1.19+ in the README. Final headf882df7: "Codex Review: Didn't find any major issues. Can't wait for the next one!"maven-cisuccessonf882df7— https://github.com/UltiKits/UltiEssentials/actions/runs/36331091983🤖 Generated with Claude Code