Skip to content

Release 3.22.3 - #3064

Open
tastybento wants to merge 19 commits into
masterfrom
develop
Open

Release 3.22.3#3064
tastybento wants to merge 19 commits into
masterfrom
develop

Conversation

@tastybento

Copy link
Copy Markdown
Member

No description provided.

tastybento and others added 18 commits August 10, 2026 07:56
A PlayerProfile that has a UUID and a name but no textures property makes the
server resolve it against the Mojang session server every time the head is
shown. On a top ten panel that is ten lookups per open, which quickly returns
HTTP 429 and still renders a default skin.

HeadGetter created exactly that profile whenever its own texture fetch failed,
and handed it to requesters anyway: the "only if the texture is usable" check
tested for a null profile, which createProfile never returns. The failed lookup
also overwrote any good cached entry, so a single rate limited call cost a
working head for the whole cache period and kept the loop running.

- HeadCache gains hasTexture() and only calls setOwnerProfile when a skin is
  actually known, so a failed lookup yields a plain head instead of one the
  server keeps trying to resolve.
- HeadGetter only notifies requesters when the texture is usable, and no longer
  lets a failed fetch evict a cached head that has one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014HtnKzNE649pBrCdqMm7nw
Do not put texture-less profiles on player heads
…nation

Commit 07ae99f replaced deprecated ChatColor constants with Adventure's
NamedTextColor in string concatenations, but NamedTextColor.WHITE.toString()
is the word "white", not a color code — so the Management panel showed addon
names like "whiteChallenges". Use MiniMessage tags instead, which
Util.parseMiniMessageOrLegacy handles correctly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkVFZoe4hB2Req885z5ea7
The previous commit accidentally included in-progress work from the
fix/yaml-numeric-widening branch; restore those two files to their prior
state. That work will arrive via its own PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkVFZoe4hB2Req885z5ea7
Until now the only way to stop BentoBox submitting bStats data was the
global switch in plugins/bStats/config.yml, which disables metrics for
every plugin on the server. general.metrics: false (default true) skips
BStats registration for BentoBox alone. All metrics call sites already
go through the getMetrics() Optional, so nothing is recorded when it is
off. Changing the setting requires a restart because bStats offers no
unregister.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkVFZoe4hB2Req885z5ea7
Add general.metrics config toggle to opt out of bStats
Links the newly merged Privacy Policy, AI Policy, and Contributing
Guide (BentoBoxWorld/.github) from the contributing section, adds a
Policies section, and updates the translations bullet to the
native-speakers-only rule (GitLocalize is no longer used).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkVFZoe4hB2Req885z5ea7
DialogBuilder could only produce Paper's default two-wide list of
buttons, because it never passed a column count and never passed a
button width. Anything grid-shaped — a map, a picker, a calendar — had
to skip the API and build a Paper dialog by hand.

Adds DialogBuilder#columns(int) for the layout and a DialogButton
constructor taking a width, plus withWidth() so a button made by the
locale factory can still be sized. Width applies to confirmation buttons
too, which the client also sizes.

Both keep the current behaviour when untouched: a dialog left at
DEFAULT_COLUMNS is built without stating a column count and a button
left at DEFAULT_WIDTH without stating a width, so the client goes on
deciding and this API does not pin whatever default Paper uses today.
Values outside what the client accepts (columns < 1, width outside
1-1024) are rejected here with a clear message rather than deeper in
Paper.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017EZEwab2kL4i1FNnBYvSmp
Lay dialog buttons out in a grid: columns and button width
The Paper pin sat at the 26.1.2 dev bundle for one reason: MockBukkit
had no 26.2 artifact, so the API under test could not match the API
compiled against. MockBukkit 4.116.1 ships mockbukkit-v26.2, built
against 26.2.build.111-stable, so the reason is gone.

26.2 brings Adventure 5, which needed three test fixes:

  - ClickEvent is now generic and carries a typed payload, so
    click.value() becomes click.payload() as ClickEvent.Payload.Text.
  - Component is sealed, so Mockito can no longer mock it. Two tests
    passed a mocked Component as a join/quit message; they use a real
    empty component now.

Main code compiled unchanged. Whole suite green at 3462 tests.

Note for the release: those two are exactly what an addon will hit if it
recompiles. A survey of 59 local addon repos found none affected — 41
never touch Adventure, and of the 18 that do, none call anything
Adventure 5 removed — but third-party addons calling ClickEvent.value()
or mocking Component in their tests will need the same edits.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017EZEwab2kL4i1FNnBYvSmp
Compile against Paper 26.2 now that MockBukkit supports it
YAML types a number by how it is written: 20 loads as Integer and 20.0
as Double, regardless of the declared field type. A double field written
without a decimal point reached the setter as an Integer; inside a
collection, generic erasure hid the mismatch until the first read threw
ClassCastException far from the cause.

Replace the ad-hoc Integer-to-Long promotion in deserialize() with a
widen() helper covering Long, Double and Float targets. Widening only:
a decimal written against an int or long field is a config mistake, so
it is left alone to fail visibly rather than silently truncated
(the long branch is gated on integral sources).

The float switch arm in deserializeValue now accepts the boxed Float
that widen() produces via Number.floatValue() instead of casting to
Double, which would throw ClassCastException for every primitive float
field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkVFZoe4hB2Req885z5ea7
Now that the build compiles against 26.2 (#3067), EntityType.SULFUR_CUBE
is a real compile-time symbol, so the code that worked around its
absence can go.

The three SULFUR_CUBE fields go back to static final. They were left
non-final, with a Sonar suppression each, only so tests could
reflectively inject a stand-in — the JVM constant-folds static final
fields, which defeated that. The tests no longer need the trick: they
use EntityType.SULFUR_CUBE directly and the getStaticField /
setStaticField helpers and MAGMA_CUBE stand-ins are gone with it.

Also corrects .claude/rules/build-toolchain.md, which still described
the old 26.1.2 compile target, told readers to use the mockbukkit-v26.1.2
coordinate, and said this work was parked in a draft PR.

3462 tests, no failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017EZEwab2kL4i1FNnBYvSmp
…kkit

Drop the workarounds for 26.2 symbols missing at compile time
fix: widen YAML-loaded numbers to the declared numeric field type
Adds draft 2020-12 schemas for .blueprint files and blueprint bundle
JSON files, covering blocks, spawners (including trial spawners),
entities, display entities, item frames, and the Gson serialization
quirks (vector-keyed pair arrays, YAML-encoded ItemStacks). Usable for
editor validation and CI. The human-readable specification is on the
docs site (Blueprint File Format).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkVFZoe4hB2Req885z5ea7
@tastybento

Copy link
Copy Markdown
Member Author

Review: Release 3.22.3

Full diff (developmaster) reviewed from multiple angles — line-by-line, removed-behaviour audit, cross-file tracing — followed by a clean ./gradlew build with all tests passing. No correctness findings.

What this release bundles (since 3.22.2)

Release metadata

  • buildVersion bumped 3.22.23.22.3 in build.gradle.kts
  • New general.metrics key in config.yml carries an Added since 3.22.3 comment ✅
  • Toolchain comments in build.gradle.kts and .claude/rules/build-toolchain.md updated to match 26.2 ✅

Verdict: good to merge.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QDeESyBDbXV4ZLsMMRBZd4

@tastybento

Copy link
Copy Markdown
Member Author

Non-blocking nit: CLAUDE.md line 159 still reads (current: 3.22.2). It is only a doc string, but it will be stale as soon as this merges — worth bumping to 3.22.3 here or in the next develop commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDeESyBDbXV4ZLsMMRBZd4
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant