Skip to content

Commit 16a5220

Browse files
authored
Merge pull request #13 from BentoBoxWorld/develop
Release 2.0.0
2 parents b98644e + 915cfe5 commit 16a5220

40 files changed

Lines changed: 2864 additions & 1052 deletions

.github/workflows/build.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@ jobs:
1111
name: Build
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1515
with:
1616
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
17-
- name: Set up JDK 17
18-
uses: actions/setup-java@v3
17+
- name: Set up JDK 21
18+
uses: actions/setup-java@v4
1919
with:
20-
distribution: 'adopt'
21-
java-version: '17'
20+
distribution: 'temurin'
21+
java-version: '21'
2222
- name: Cache SonarCloud packages
23-
uses: actions/cache@v3
23+
uses: actions/cache@v4
2424
with:
2525
path: ~/.sonar/cache
2626
key: ${{ runner.os }}-sonar
2727
restore-keys: ${{ runner.os }}-sonar
2828
- name: Cache Maven packages
29-
uses: actions/cache@v3
29+
uses: actions/cache@v4
3030
with:
3131
path: ~/.m2
3232
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
@@ -35,4 +35,4 @@ jobs:
3535
env:
3636
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
3737
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
38-
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
38+
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar

CLAUDE.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project
6+
7+
TopBlock is a BentoBox addon that produces a Top Ten ranking for the AOneBlock game mode based on how many magic blocks each island has mined. It is **not** standalone — it depends on the BentoBox plugin and the AOneBlock addon being present at runtime, and refuses to enable otherwise.
8+
9+
## Build & Test
10+
11+
Maven project, Java 21, Paper 1.21.11 API, BentoBox 3.14.0, AOneBlock 1.18.0.
12+
13+
- Build (default goal is `clean package`): `mvn package` — produces a shaded jar in `target/` named `TopBlock-<revision><build.number>.jar`. The shade plugin bundles only `lv.id.bonne:panelutils`; everything else is `provided`.
14+
- Run tests: `mvn test`
15+
- Run a single test class: `mvn test -Dtest=TopBlockManagerTest`
16+
- Run a single test method: `mvn test -Dtest=TopBlockManagerTest#testFormatLevelShorthandKilo`
17+
- The Surefire config sets a long list of `--add-opens` JVM flags — required for Mockito + MockBukkit reflection on Java 21; do not remove them when tweaking the build.
18+
19+
Version handling is driven by Maven properties: `build.version` is the human version (currently 1.1.0), `revision` resolves to `${build.version}-SNAPSHOT` locally and to `${build.version}` under the `master` profile (activated by `GIT_BRANCH=origin/master` on Jenkins). `build.number` is `-LOCAL` locally, `-b<num>` on CI, empty on master. Don't hand-edit `<version>` — bump `build.version`.
20+
21+
## Runtime entry points (Pladdon pattern)
22+
23+
There are **two** main classes and the distinction matters:
24+
25+
- `TopBlockPladdon` (referenced by `plugin.yml`) is the Bukkit-facing `Pladdon`. Spigot loads this; its only job is `getAddon() → new TopBlock()`.
26+
- `TopBlock` (referenced by `addon.yml`) is the BentoBox `Addon`. All real lifecycle (`onLoad`, `onEnable`, `onDisable`) lives here.
27+
28+
`onEnable` looks up the AOneBlock addon via `getPlugin().getAddonsManager().getAddonByName("aoneblock")`; if missing or not a `GameModeAddon`, the addon disables itself. The `/<gamemode> topblock` command is registered against AOneBlock's player command, not as a top-level command.
29+
30+
## Data flow
31+
32+
`TopBlockManager` is a `Listener` that reacts to `BentoBoxReadyEvent` (handler is `public void onBentoBoxReady` — Bukkit silently skips private @EventHandler methods, which is what broke the addon historically) to start a repeating Bukkit task. The task period is `settings.getRefreshTime() * 20L * 60` ticks (minutes → ticks). Each tick of the task:
33+
34+
1. Calls `AOneBlock.getBlockListener().getAllIslands()` — this reads every island, so the refresh interval is intentionally coarse (default 5 min, min 1 min).
35+
2. Builds a fresh `List<TopTenData>` (record of island + blockNumber + lifetime + phaseName) — sorted at read time via `Comparator` on `lifetime` then `blockNumber`.
36+
3. Updates `PlaceholderManager`'s cached snapshot.
37+
38+
Placeholders are registered once via a `runTaskLater` 10-tick delay after the first ready event (so PAPI / BentoBox's `PlaceholdersManager` is up). Names follow `island_<field>_top_<1..10>` and are scoped to the AOneBlock `GameModeAddon`. The `TopBlock.TEN` constant is the source of truth for the list size.
39+
40+
## Panel
41+
42+
`TopLevelPanel` uses BentoBox's `TemplatedPanelBuilder`. The template file is shipped in `src/main/resources/panels/top_panel.yml` and copied to the data folder on load via `saveResource("panels/top_panel.yml", false)` — players' edits to the on-disk file persist across restarts. Localization keys live under `topblock.gui.buttons.island.*` in `src/main/resources/locales/en-US.yml`. The icon material can be overridden per-player via the `<permissionPrefix>topblock.icon.<MATERIAL>` permission.
43+
44+
The panel has no click actions (TopBlock doesn't bundle Warp/Visit hooks like Level does). The YAML still declares `warp`/`visit` actions with tooltips, but no click handler is registered — clicking does nothing.
45+
46+
## Resource filtering
47+
48+
`pom.xml` filters `src/main/resources` (so `${version}` etc. in `addon.yml` / `plugin.yml` get substituted) **except** `src/main/resources/locales`, which is copied verbatim to `./locales` to avoid Maven mangling YAML colons / placeholder syntax in translations.
49+
50+
## Tests
51+
52+
JUnit 5 + Mockito + MockBukkit. Test classes extend `CommonTestSetup` which:
53+
- Mocks `Bukkit` statically and provides a real `MockBukkit.mock()` server (needed for Tag/Material initialisation).
54+
- Injects the BentoBox singleton via `WhiteBox.setInternalState(BentoBox.class, "instance", plugin)`.
55+
- Sets up the standard graph of mocks: `IslandWorldManager`, `IslandsManager`, `PlayersManager`, `LocalesManager`, `PlaceholdersManager`, `Notifier`, `HooksManager`, `BlueprintsManager`.
56+
- Calls `User.setPlugin(plugin)` and pre-creates a `User` instance for `mockPlayer` (uuid `tastybento`).
57+
58+
`TestWorldSettings` returns `"TopBlock"` for friendly name and `"topblock."` for permission prefix. The addon test (`TopBlockTest`) builds an in-memory `addon.jar` containing `config.yml` + `panels/top_panel.yml` because `Addon.saveResource` reads from a real JarFile.
59+
60+
JaCoCo excludes `**/*Names*` to avoid synthetic-field issues on JavaBeans — keep that exclusion if adding similar classes.

README.md

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,77 @@
33

44
## About
55

6-
Add-on for BentoBox to calculate island levels for AOneBlock specifically. Ranks are determined by how many magic blocks have been mined - the count.
6+
TopBlock is a [BentoBox](https://github.com/BentoBoxWorld/BentoBox) addon that produces a Top Ten ranking for the [AOneBlock](https://github.com/BentoBoxWorld/AOneBlock) game mode based on how many magic blocks each island has mined.
7+
8+
## Requirements
9+
10+
- Paper 1.21.x (Spigot is no longer supported)
11+
- Java 21
12+
- BentoBox 3.14.0 or later
13+
- AOneBlock 1.18.0 or later
714

815
## How to use
916

10-
1. Place the level addon jar in the addons folder of the BentoBox plugin. Make sure you have AOneBlock installed too!
11-
2. Restart the server
12-
3. The addon will create a data folder and inside the folder will be a config.yml
13-
4. Edit the config.yml how you want.
14-
5. Restart the server if you make a change
17+
1. Drop the TopBlock jar into your server's `plugins/BentoBox/addons/` folder. AOneBlock must already be installed there too.
18+
2. Restart the server. TopBlock will create `addons/TopBlock/config.yml` and `addons/TopBlock/panels/top_panel.yml`.
19+
3. Edit `config.yml` if you want to tune anything (see below) and restart the server again to apply.
20+
21+
## Configuration
22+
23+
`addons/TopBlock/config.yml`:
24+
25+
| Option | Default | Description |
26+
|----------------|---------|-------------------------------------------------------------------------------------------------------------------|
27+
| `refresh-time` | `5` | How often the Top Ten is recalculated, in minutes. Minimum 1. Each refresh reads every island, so don't set it too low. |
28+
| `shorthand` | `false` | If `true`, format large counts using units — `10,500` becomes `10.5k`, `1,527,314` becomes `1.5M`, etc. |
29+
30+
The panel layout lives in `addons/TopBlock/panels/top_panel.yml`. Edits are preserved across restarts.
1531

1632
## Commands
1733

18-
`/ob topblock` - this shows the Top Ten
34+
`/ob topblock` (alias: `/oneblock topblock`) — opens the Top Ten panel.
35+
36+
To get into the top ten, a player just needs to mine at least one magic block on their AOneBlock island. The list refreshes every `refresh-time` minutes; a player who just started mining may need to wait that long before appearing.
1937

2038
## Permissions
21-
Permissions are given automatically to players as listed below. If your permissions plugin strips permissions then you may have to allocate these manually. Note that if a player doesn't have the `intopten` permission, they will not be listed in the top ten.
2239

23-
```
24-
permissions:
40+
Permissions are given automatically to players. If your permissions plugin strips defaults, allocate them manually:
41+
42+
```yaml
43+
permissions:
2544
'aoneblock.island.topblock':
26-
description: Player can use TopBlock command
45+
description: Player can use the TopBlock command
46+
default: true
47+
'aoneblock.intopten':
48+
description: Player's island will be listed in the top ten. Remove from admins or testers to hide them.
2749
default: true
2850
```
2951
52+
If an island owner is **online** and lacks `aoneblock.intopten`, their island is excluded from the top ten panel and from placeholders. **Offline** owners are always included — to hide an admin or tester, remove the perm from the player who can actually log in. Removing the perm from an entire group (e.g. ops) excludes everyone in that group while online.
53+
54+
The icon shown for each rank can be overridden per player by granting `aoneblock.topblock.icon.<MATERIAL>` (for example `aoneblock.topblock.icon.diamond_block`). Without an override, the rank icon is the player's head.
55+
3056
## Placeholders
3157

3258
```
33-
%aoneblock_island_player_name_top_RANK% where RANK is 1 to 10 - Island owner's name
34-
%aoneblock_island_member_names_top_RANK% where RANK is 1 to 10 - Name of island team members
35-
%aoneblock_island_phase_name_top_RANK% where RANK is 1 to 10 - Name of the phase they have reached
36-
%aoneblock_island_phase_number_top_RANK% where RANK is 1 to 10 - Phase number, e.g. Plains is 1, Underground is 2, etc.
37-
%aoneblock_island_count_top_RANK% where RANK is 1 to 10 - Block Count of magic blocks mined this round
38-
%aoneblock_island_lifetime_top_RANK% where RANK is 1 to 10 - Lifetime count of magic blocks mined
59+
%aoneblock_island_player_name_top_RANK% - Island owner's name
60+
%aoneblock_island_member_names_top_RANK% - Comma-separated team members (highest rank first)
61+
%aoneblock_island_phase_name_top_RANK% - Name of the phase the island has reached
62+
%aoneblock_island_phase_number_top_RANK% - Phase number, e.g. Plains is 1, Underground is 2
63+
%aoneblock_island_count_top_RANK% - Block count of magic blocks mined this round
64+
%aoneblock_island_lifetime_top_RANK% - Lifetime count of magic blocks mined
3965
```
66+
67+
`RANK` is `1` to `10`. If fewer than `RANK` islands qualify for the top ten, the placeholder returns an empty string.
68+
69+
## Building from source
70+
71+
```bash
72+
mvn clean package
73+
```
74+
75+
Produces `target/TopBlock-<version>.jar`.
76+
77+
## License
78+
79+
[EPL-2.0](LICENSE)

0 commit comments

Comments
 (0)