
Advanced TreeCapitator
Advanced TreeCapitator enables fast tree felling on Paper 1.21. Sneak with an axe to chop entire trees, with configurable durability loss, world restrictions, and a reload command.
765
2
Список изменений
[1.5.1] — 2025-06-03
Fixed — Bug Fixes
| # | Bug | Details |
|---|---|---|
| 1 | BFS adds out-of-range blocks to the break-set before checking distance caps | In TreeFinder.findLogs(), logsToBreak.add(current) ran unconditionally at the start of the loop body — before the dist > MAX_DISTANCE and hdist > maxHorizontalDistance checks. A block at the outer edge of the BFS scan (e.g. hdist == maxHorizontalDistance + 1) was enqueued as a neighbour of an in-range block, then added to the break-set when dequeued, even though the check immediately after prevented its own neighbours from being explored. Result: logs slightly beyond max-horizontal-distance were still felled, making the config option unreliable at the boundary. Fixed by moving both distance checks before the logsToBreak.add() call. |
| 2 | cooldownMs loaded with (int) cast before clamping — silent integer overflow | cooldownMs = clamp((int) cfg.getLong("cooldown-ms", 200L), 0, 60_000) cast the raw YAML long to int before clamping. Any value larger than Integer.MAX_VALUE (2 147 483 647) in the config file overflowed to a negative number, which clamp() then floored to 0, silently disabling the per-player cooldown entirely. Fixed by clamping on the long value first: (int) Math.min(Math.max(...), 60_000L). Field type also changed from long to int for consistency; getCooldownMs() now returns int. |
| 3 | Hardcoded MAX_DISTANCE = 30 truncated tall Jungle trees | The 3-D Manhattan BFS safety cap was hardcoded as private static final int MAX_DISTANCE = 30 in TreeFinder. Jungle trees can reach 30+ blocks tall; a player chopping from a non-base position (reducing the vertical budget) or a tree with any horizontal spread would have its top logs excluded from the fell silently. Exposed as max-distance in config.yml with a default of 50. Configurable range: 10 – 200. |
| 4 | getBreakingTrees() exposed the internal mutable anti-recursion set | The public getter getBreakingTrees() returned the raw ConcurrentHashMap.newKeySet() directly. External code (another plugin or a misbehaving task) could call .add(uuid) to permanently lock a player out of tree felling, or .clear() to disable the anti-recursion guard entirely mid-fell. Fixed by removing the public getter and replacing it with the package-private helpers markFelling(UUID) and unmarkFelling(UUID), used only by TreeCapitatorTask. |
| 5 | isOverworldLog() did not cover stripped-log variants — require-leaves bypass | The method used a hard-coded switch that only listed nine non-stripped log variants (e.g. OAK_LOG). If a server operator added a stripped variant (e.g. STRIPPED_OAK_LOG) to log-types in config.yml, isOverworldLog() returned false (default case), and the require-leaves check was silently skipped. A player-built wall of stripped logs could be felled with a single swing even with require-leaves: true. Fixed by replacing the switch with a Material name-suffix check: any material ending in _LOG or _WOOD returns true. Nether stems (CRIMSON_STEM, WARPED_STEM), hyphae, and BAMBOO_BLOCK end in _STEM, _HYPHAE, or _BLOCK and continue to return false correctly. |
| 6 | Leaf durability hits silently discarded by integer truncation | leafBreaks / safeRatio used integer division, dropping the remainder entirely. With the default leaf-durability-ratio: 10, breaking fewer than 10 leaves contributed exactly 0 durability hits — so a small tree with leaves produced no leaf-based durability cost at all. Fixed by resolving the remainder probabilistically: remainder / safeRatio gives the probability of one additional hit, resolved with a ThreadLocalRandom roll, consistent with the existing fractional-hit logic in calcDamage(). |
| 7 | TreeCapitatorEvent API lacked @NotNull annotations | All three public getters (getPlayer(), getLogs(), getLeaves()) and the constructor parameters had no nullability contract. Third-party plugins integrating the API had no IDE or static-analysis guidance about null safety. Added @NotNull (from org.jetbrains:annotations:24.1.0) to all public constructor parameters and return types. org.jetbrains:annotations added to pom.xml as a provided dependency. |
Метаданные
Канал релиза
Release
Номер версии
1.5.1
Загрузчики
BukkitPaperPurpurSpigot
Версии игры
1.20–1.20.6
Загрузок
13
Дата публикации
1 нед. назад
