Skip to content

Comments

Fix #242: enforce shulker entity limit on Paper via ShulkerDuplicateEvent#243

Merged
tastybento merged 5 commits intomasterfrom
242-fix-shulker-duplication-limit
Feb 20, 2026
Merged

Fix #242: enforce shulker entity limit on Paper via ShulkerDuplicateEvent#243
tastybento merged 5 commits intomasterfrom
242-fix-shulker-duplication-limit

Conversation

@tastybento
Copy link
Member

Summary

  • Closes Shulker duplication ignores shulker limits #242 — shulkers could exceed island entity limits by using duplication farms on Paper servers.
  • Adds PaperShulkerLimitListener which handles Paper's ShulkerDuplicateEvent to enforce shulker limits before duplication occurs.
  • Adds Paper API as an optional provided Maven dependency (compile-time only; not bundled in the jar).

Root cause

On Paper, CreatureSpawnEvent (with SpawnReason.DUPLICATION) fires for the new shulker after the original shulker has already teleported to a new position. If the original shulker teleports outside the island's protection bounding box, getNearbyEntities(island.getBoundingBox()) counts N−1 shulkers instead of N. This makes the limit check think there is room for one more, allowing duplication past the configured limit. Each farm cycle can leak one shulker outside the island, which then duplicates freely with no limit applied at all.

Paper's ShulkerDuplicateEvent fires before the original shulker teleports and before the duplicate is created, so the entity count within the island bounding box is accurate. Cancelling this event prevents both the teleport and the duplicate.

How it works

  • On Paper: PaperShulkerLimitListener is registered at startup (detected via Class.forName). It cancels ShulkerDuplicateEvent when the island is at its shulker entity limit.
  • On Spigot: The existing CreatureSpawnEvent / SpawnReason.DUPLICATION path is unchanged.
  • If Paper classes are absent, ClassNotFoundException is silently caught and no Paper listener is registered.

Test plan

  • Set SHULKER entity limit to a small value (e.g. 2) in entitylimits config.
  • Build a shulker duplication farm on a BSkyBlock/AcidIsland island on a Paper server.
  • Confirm shulkers cannot exceed the configured limit.
  • Confirm normal shulker spawning (spawner, natural) still works up to the limit.
  • Confirm behaviour on a vanilla Spigot server is unchanged.

🤖 Generated with Claude Code

tastybento and others added 3 commits February 19, 2026 22:47
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…vent

On Paper servers, CreatureSpawnEvent fires for the new shulker *after* the
original shulker has already teleported away. If the original shulker
teleports outside the island bounding box, getNearbyEntities counts N-1
shulkers instead of N, so the limit check incorrectly allows duplication
past the configured limit.

Paper's ShulkerDuplicateEvent fires *before* the original shulker teleports
and before the duplicate is created, so the island entity count is accurate.
Register PaperShulkerLimitListener when Paper is detected at runtime;
fall back to the existing CreatureSpawnEvent handling on Spigot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Change Paper API dependency from 1.21.8 to 1.20.4, which is the last
  version compiled for Java 17. Paper 1.20.6+ targets Java 21 (class
  version 65), which the compiler rejects under --release 17.
- Stage the remaining add_tags source files (IslandBlockCount,
  BlockLimitsListener, RecountCalculator, etc.) that Limits.java depends
  on; they were missing from the previous commit, causing NamespacedKey /
  Material type mismatches in CI.
- Fix @AfterEach (JUnit 5) -> @after (JUnit 4) in the three test files
  that have JUnit 4 imports; the annotation was unresolved in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tastybento tastybento force-pushed the 242-fix-shulker-duplication-limit branch from fc312d8 to 7dc5736 Compare February 20, 2026 17:50
tastybento and others added 2 commits February 20, 2026 10:05
Add isLogLimitsOnJoin() config option (from master commit bdf41ea) so
that the verbose per-permission log lines can be silenced. Wraps each
addon.log() call in checkPerms/runNullCheckAndSet with the guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Conflict in JoinListener.java resolved by keeping the add_tags/PR branch
version, which already incorporates the log-limits-on-join changes from
master commit bdf41ea.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
C Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@tastybento tastybento merged commit 490fce4 into master Feb 20, 2026
2 of 3 checks passed
@tastybento tastybento deleted the 242-fix-shulker-duplication-limit branch February 20, 2026 19:13
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