Skip to content

Release 1.24.0#502

Merged
tastybento merged 37 commits intomasterfrom
develop
Apr 26, 2026
Merged

Release 1.24.0#502
tastybento merged 37 commits intomasterfrom
develop

Conversation

@tastybento
Copy link
Copy Markdown
Member

No description provided.

Copilot AI and others added 30 commits April 9, 2026 12:30
Add CraftEngineCustomBlock, CraftEngineListener, and register them
in AOneBlock.onLoad() following the same pattern as Nexo and
ItemsAdder integrations. Add craft-engine-bukkit dependency to pom.xml.

Agent-Logs-Url: https://github.com/BentoBoxWorld/AOneBlock/sessions/98ee3d0c-05a3-457b-8bce-42c0463fde3a

Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
Agent-Logs-Url: https://github.com/BentoBoxWorld/AOneBlock/sessions/98ee3d0c-05a3-457b-8bce-42c0463fde3a

Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
… Nexo custom blocks

Agent-Logs-Url: https://github.com/BentoBoxWorld/AOneBlock/sessions/e3aa31a3-2d63-45e5-acdb-c2662dfd773b

Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…-in-oneblock

docs: strengthen README documentation for MythicMobs, ItemsAdder, and Nexo custom blocks
The craft-engine-bukkit API references types from craft-engine-core
(Key, CustomBlock), so both modules are needed on the compile classpath.

Agent-Logs-Url: https://github.com/BentoBoxWorld/AOneBlock/sessions/02b4b996-4f28-499b-accc-6899a91de52a

Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…aftengine

Add CraftEngine custom block support
…ders

Return defaults for empty placeholders when player has no island
Sync 17 locale files with en-US.yml by adding 6 missing keys (actionbar
status/not-active, actionbar command description/toggle messages, and
my-island-phase-default placeholder). Russian only needed 1 key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ndencies

Add sections for dependency source lookup workflow, full project layout
of sibling repositories under ~/git/, and key dependency source locations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…anager

Extract helper methods to bring all four SonarCloud HIGH-severity
cognitive complexity violations (java:S3776) below the threshold of 15:

- BlockListener.onPlayerInteract (16→≤15): extract updateBrushSession
- OneBlocksManager.initBlock (18→≤15): extract checkNotDuplicate
- OneBlocksManager.addMobs (17→≤15): extract resolveEntityType + processMobEntry
- OneBlocksManager.addBlocks (16→≤15): extract processBlockMapEntry

No behaviour change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Stream.toList() in CheckPhase, OneBlockPhase, OneBlocksManager (S6204)
- Proper JUnit assertions in BlockListenerTest2 (S5785)
- Remove useless local variable assignments in BlockListenerTest2 (S1854)
- Add missing @OverRide to setUp/tearDown in test classes (S1161)
- Remove commented-out code in 5 test files (S125)
- Rename restricted identifier 'record' to 'mobRecord' in MythicMobCustomBlock (S6213)
- Add since/forRemoval to @deprecated in ChunkGeneratorWorld and Settings (S6355, S1123)
- Remove always-true e.getTo() != null in StartSafetyListener (S2589)
- Remove always-false user == null check in LocationStatsHandler (S2589)
- Replace deprecated PlayerQuitEvent(Player,String) constructor in tests (S5738)
- Replace deprecated EntityExplodeEvent null arg with ExplosionResult.DESTROY (S5738)
- Replace deprecated Biome.name() with getKey().getKey() (S5738)
- Use Map.computeIfAbsent in updateBrushSession (S3824)
- Convert anonymous Runnable to lambda in startContinuousBrush (S1604)
- Remove unused 'phase' parameter from handlePhaseChange (S1172)
- Add reason to @disabled on testInitBlock (S1607)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- S116: rename MOB_ASPECTS → mobAspects in WarningSounder (instance field, not constant)
- S1874: replace deprecated Registry.BIOME with RegistryAccess.registryAccess().getRegistry(RegistryKey.BIOME) in OneBlocksManager
- S1874: replace deprecated Util.translateColorCodes with raw text in HoloListener
- S1874: replace deprecated display.setText with display.text(Component) via LegacyComponentSerializer
- S1874: replace deprecated ChatColor.COLOR_CHAR with '\u00A7' in PhasesPanel; remove unused ChatColor import
- S2637: fix @nullable Player in BlockListener.breakBlock — early return instead of Objects.requireNonNull
- S2637: extract Location in BossBarListener.onJoin to avoid repeated @nullable call
- S2637: save user.getPlayer() to local variable in CheckPhase before calling showTitle
- S3577: suppress S3577 on BlockListenerTest2 and OneBlocksManagerTest3 (intentional numbered suffixes)
- S1874: suppress deprecation on FixedMetadataValue in CommonTestSetup
- S1128: remove unused imports (BlockState, BlockData, Entity, Event, eq)
- S6068: remove useless eq() wrappers in BlockListenerTest2
- S1612: revert ambiguous method reference in CommonTestSetup (toLegacyText is overloaded)
- S1130: suppress unnecessary throws warning on setUp()
- S1607: add reason to @disabled in OneBlocksManagerTest3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolves SonarCloud security hotspot — using a mutable tag reference
allows the action to change under us. Pinned to the SHA of v2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract location to local variable before the inWorld check so a single
non-null reference flows through both the guard and the getIslandAt call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Surefire <argLine> was hardcoded, silently overwriting the
argLine property that jacoco:prepare-agent sets. Changed to use
@{argLine} late-binding prefix so the JaCoCo Java agent is correctly
prepended to the JVM arguments at test execution time.

Also added sonar.coverage.jacoco.xmlReportPaths to make the report
path explicit for SonarCloud.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CraftEngineCustomBlock now delegates to CraftEngineHook static methods
instead of importing CraftEngine classes directly. Removes the
craft-engine-core compile dependency (craft-engine-bukkit is still
needed for CraftEngineListener). Bumps bentobox.version to 3.15.0-SNAPSHOT.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refactor: use BentoBox CraftEngineHook instead of direct API calls
Add explicit null guards Sonar's symbolic execution can track:
- BlockListener: capture player.getLocation() into local with null check
- BossBarListener: include playerLoc null check in early-return guard
- CheckPhase: replace Objects.requireNonNullElse with explicit ternary

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Agent-Logs-Url: https://github.com/BentoBoxWorld/AOneBlock/sessions/d83aa5f8-7590-4063-9445-a19282652b52

Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…scooping-default

Disable OBSIDIAN_SCOOPING by default
@tastybento tastybento requested a review from Copilot April 26, 2026 19:43
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Release 1.24.0 updates AOneBlock for newer BentoBox/Paper APIs while adding CraftEngine custom-block support and improving phase/chest behavior and messaging.

Changes:

  • Add CraftEngine integration (custom block implementation + reload listener) and update dependencies/build settings for 1.24.0.
  • Add CHEST_WITH_<ITEM> fixed-block shorthand, plus configurable chest particle effects by rarity.
  • Update placeholders/locales/tests and refactor a few code paths for newer API signatures.

Reviewed changes

Copilot reviewed 53 out of 53 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/test/java/world/bentobox/aoneblock/oneblocks/customblock/CraftEngineCustomBlockTest.java Adds unit coverage for CraftEngine custom-block map parsing.
src/test/java/world/bentobox/aoneblock/oneblocks/OneBlocksManagerTest3.java Adds tests for CHEST_WITH_* fixedBlocks parsing and updates some test setup.
src/test/java/world/bentobox/aoneblock/listeners/MakeSpaceTest.java Aligns test class visibility with JUnit 5 style.
src/test/java/world/bentobox/aoneblock/listeners/JoinLeaveListenerTest.java Updates for newer PlayerQuitEvent constructor signature.
src/test/java/world/bentobox/aoneblock/listeners/BlockListenerTest2.java Updates mocks/assertions and adds defaults for new chest particle settings.
src/test/java/world/bentobox/aoneblock/listeners/BlockListenerTest.java Adds missing @Override annotation.
src/test/java/world/bentobox/aoneblock/commands/island/IslandSetCountCommandTest.java Cleans up commented-out test code.
src/test/java/world/bentobox/aoneblock/commands/island/IslandRespawnBlockCommandTest.java Adds @Override annotations and cleans up commented-out code.
src/test/java/world/bentobox/aoneblock/commands/admin/AdminSanityCheckTest.java Removes unused Mockito import.
src/test/java/world/bentobox/aoneblock/PlaceholdersManagerTest.java Updates expectations for new placeholder defaults.
src/test/java/world/bentobox/aoneblock/CommonTestSetup.java Updates explode event construction for newer API.
src/test/java/world/bentobox/aoneblock/AOneBlockTest.java Adds regression test for loadData() when manager not initialized.
src/main/resources/phases/0_plains.yml Updates default phase fixedBlocks example to CHEST_WITH_WATER_BUCKET.
src/main/resources/locales/zh-TW.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/zh-CN.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/vi.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/uk.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/tr.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/ru.yml Adds new default phase placeholder translation.
src/main/resources/locales/pt.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/pl.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/ja.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/it.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/id.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/hu.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/hr.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/fr.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/es.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/en-US.yml Adds new default phase placeholder translation.
src/main/resources/locales/de.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/locales/cs.yml Adds actionbar strings and new default phase placeholder translation.
src/main/resources/config.yml Adds chest particle configuration and adjusts default flag values.
src/main/java/world/bentobox/aoneblock/requests/LocationStatsHandler.java Simplifies user handling for location stats request.
src/main/java/world/bentobox/aoneblock/panels/PhasesPanel.java Removes ChatColor dependency in line-wrapping helper.
src/main/java/world/bentobox/aoneblock/oneblocks/customblock/MythicMobCustomBlock.java Variable rename/refactor for clarity.
src/main/java/world/bentobox/aoneblock/oneblocks/customblock/CraftEngineCustomBlock.java Adds CraftEngine custom-block implementation.
src/main/java/world/bentobox/aoneblock/oneblocks/OneBlocksManager.java Adds CHEST_WITH_* parsing/serialization and updates biome registry access.
src/main/java/world/bentobox/aoneblock/oneblocks/OneBlockPhase.java Uses toList() for chest collection creation.
src/main/java/world/bentobox/aoneblock/listeners/WarningSounder.java Renames mob-aspects map field for style consistency.
src/main/java/world/bentobox/aoneblock/listeners/StartSafetyListener.java Adjusts movement safety logic (but introduces a null-safety issue).
src/main/java/world/bentobox/aoneblock/listeners/HoloListener.java Switches hologram text to Adventure legacy deserialization.
src/main/java/world/bentobox/aoneblock/listeners/CraftEngineListener.java Adds listener to reload addon data on CraftEngine reload.
src/main/java/world/bentobox/aoneblock/listeners/CheckPhase.java Null-safety and stream collection updates.
src/main/java/world/bentobox/aoneblock/listeners/BossBarListener.java Uses cached player location and adds null-safety.
src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java Refactors brushing session logic; adds chest particle effects with settings.
src/main/java/world/bentobox/aoneblock/generators/ChunkGeneratorWorld.java Updates deprecation metadata for legacy generator method.
src/main/java/world/bentobox/aoneblock/Settings.java Adds config entries and resolution helpers for chest particle settings.
src/main/java/world/bentobox/aoneblock/AOneBlockPlaceholders.java Adds translation-backed default for missing phase placeholder.
src/main/java/world/bentobox/aoneblock/AOneBlock.java Registers CraftEngine support and guards loadData() when manager uninitialized.
pom.xml Bumps version to 1.24.0, updates BentoBox dep, adds CraftEngine dep/repo, tweaks surefire argLine.
README.md Expands documentation for MythicMobs and custom blocks.
CLAUDE.md Adds guidance for dependency source lookup and workspace layout.
.github/workflows/modrinth-publish.yml Pins Modrinth publish action to a commit SHA.
Comments suppressed due to low confidence (1)

src/main/java/world/bentobox/aoneblock/listeners/StartSafetyListener.java:66

  • PlayerMoveEvent#getTo() can be null (some move events only report a from-location). The current condition and new Location(... e.getTo()...) dereference e.getTo() without a null check, which can throw NPE and break the safety listener for players.
    public void onPlayerMove(PlayerMoveEvent e) {
        if (addon.inWorld(e.getPlayer().getWorld()) && newIslands.containsKey(e.getPlayer().getUniqueId())
                && !e.getPlayer().isSneaking()
                && (e.getFrom().getX() != e.getTo().getX() || e.getFrom().getZ() != e.getTo().getZ())) {
            // Do not allow x or z movement
            e.setTo(new Location(e.getFrom().getWorld(), e.getFrom().getX(), e.getTo().getY(), e.getFrom().getZ(),
                    e.getTo().getYaw(), e.getTo().getPitch()));

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +888 to +889
Color color = addon.getSettings().resolveChestColor(rarity);
Object particleData = Particle.DUST.equals(particle) ? new Particle.DustOptions(color, 1) : null;
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spawnParticle(particle, ..., particleData) will throw if particle requires non-null/typed data (e.g., BLOCK/ITEM/BLOCK_CRACK), but particleData is only provided for Particle.DUST and otherwise set to null. Since the particle type is user-configurable, this can cause runtime exceptions when special chests spawn. Consider restricting config to particles with getDataType()==Void (plus DUST with DustOptions), or derive the correct data object per particle type and skip/log invalid selections.

Suggested change
Color color = addon.getSettings().resolveChestColor(rarity);
Object particleData = Particle.DUST.equals(particle) ? new Particle.DustOptions(color, 1) : null;
Object particleData = null;
if (Particle.DUST.equals(particle)) {
Color color = addon.getSettings().resolveChestColor(rarity);
particleData = new Particle.DustOptions(color, 1);
} else if (!Void.class.equals(particle.getDataType())) {
// Unsupported configured particle type for this effect; avoid invalid spawnParticle data
return;
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Added a guard in fillChest that returns early (with a warning log) for any particle whose getDataType() is not Void.class and is not DUST. This avoids the crash without needing to restrict the config — the warning will tell the admin exactly what to change.

Comment on lines +2348 to +2357
@Nullable
private Particle parseParticle(@Nullable String name, Particle defaultParticle) {
if (name == null || name.equalsIgnoreCase("NONE")) {
return null;
}
try {
return Particle.valueOf(name.toUpperCase(java.util.Locale.ENGLISH));
} catch (IllegalArgumentException e) {
return defaultParticle;
}
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseParticle() currently allows any Particle enum value (and silently falls back on parse errors), but BlockListener#fillChest only supports particles that either take no extra data or are DUST with DustOptions. To avoid misconfiguration causing runtime exceptions, consider validating the configured particle names here (e.g., reject/disable particles whose Particle#getDataType() is not Void unless you also supply the required data type), and optionally log a warning when falling back.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The runtime guard added to fillChest covers this: if a misconfigured particle reaches that method it now logs a warning and returns safely. Adding a second layer of validation in parseParticle would be redundant — the warning message already tells the admin exactly which particle name is invalid and what to use instead.

Comment on lines 593 to 612
@@ -609,7 +608,7 @@ private static String insertNewlines(String input, int interval) {
result.append(input, index, breakPoint).append('\n');
if (lastAmpIndex >= 0) {
// Append color code
result.append(ChatColor.COLOR_CHAR);
result.append('\u00A7');
result.append(activeColor);
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the raw section-sign literal ('\u00A7') for legacy color codes makes this harder to read/maintain and duplicates a well-known constant. Consider using ChatColor.COLOR_CHAR (qualified if you want to avoid the import) or a named local constant instead of the magic Unicode value.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional — one of this PR's goals was to remove the ChatColor import from this helper. Re-adding ChatColor.COLOR_CHAR would undo that. The raw literal '\u00A7' is used exactly twice in a private method and is perfectly clear. No change.

@tastybento tastybento merged commit 96a1665 into master Apr 26, 2026
9 checks passed
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.

3 participants