Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ca26e1b
Upgrade build and dependencies to Paper 26.3 and Java 25
Nov 12, 2026
113cd15
Replace legacy API access and restore lifecycle tests
Nov 12, 2026
7181dd0
Document Minecraft 26.1 and Java 25 requirements
Nov 12, 2026
516eab7
Merge PR #24: add tooltip display property
Nov 12, 2026
0dcd687
Resolve offline player heads with name-only profiles
Nov 12, 2026
bcf46a1
Fix tooltip component persistence during item builds
Nov 12, 2026
0296b03
Add item model, tooltip style, stack size and rarity properties
Nov 12, 2026
cf14d18
Use Adventure components for inventory titles
Nov 12, 2026
09bd95e
Modernize model, glint, flags and display counts for Paper 26.3
Nov 12, 2026
a8daab1
Document item component properties and display count limits
Nov 12, 2026
a2faec7
Merge offline heads and Component inventory titles
Nov 12, 2026
0fe0946
Fix item counts and component property composition
Nov 12, 2026
25d98cf
Remove legacy tooling and document upgrade behavior
Nov 12, 2026
d454575
Merge remote-tracking branch 'origin/master' into BrainRTP/Обновление
BrainRTP Nov 12, 2026
70314d1
Restore localized item name placeholder output
BrainRTP Nov 12, 2026
2943218
Preserve legacy attributes and distinct item modifiers
BrainRTP Nov 12, 2026
4079a03
Correct action parsing, item costs, XP and rule boundaries
BrainRTP Nov 12, 2026
7581961
Repair activators, entity extraction and variable placeholders
BrainRTP Nov 12, 2026
e83b9b9
Preserve menu deposits and isolate viewer lifecycle state
BrainRTP Nov 12, 2026
57260aa
Serialize variable persistence and repair addon infrastructure
BrainRTP Nov 12, 2026
0541c33
Use vanilla tooltip sprites in the bundled menu
BrainRTP Nov 12, 2026
6d24c7e
Keep attribute modifier identities stable across reloads
BrainRTP Nov 12, 2026
b6311fb
Close owned menus synchronously during unload
BrainRTP Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,33 @@ concurrency:

jobs:
build:
name: Build + test on JDK 21
name: Build + test on JDK 25
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7.0.1

- name: Set up JDK 21
uses: actions/setup-java@v4
- name: Set up JDK 25
uses: actions/setup-java@v6.2.0
with:
java-version: '21'
java-version: '25'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v6.4.1
with:
gradle-home-cache-cleanup: true
cache-cleanup: 'always'

- name: Build + tests (all modules) + shadowJar
run: ./gradlew --no-daemon build :plugin:shadowJar

- name: Publish test report
if: always()
uses: mikepenz/action-junit-report@v5
uses: mikepenz/action-junit-report@v6.7.1
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
fail_on_failure: true
annotate_only: true
require_tests: false

- name: Resolve plugin JAR path
Expand All @@ -62,15 +63,15 @@ jobs:
echo "javadoc=$(ls api/build/libs/AbstractMenus-api-*-javadoc.jar | head -n1)" >> "$GITHUB_OUTPUT"

- name: Upload plugin shadow JAR
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7.0.2
with:
name: AbstractMenus-jar
path: ${{ steps.plugin_jar.outputs.path }}
if-no-files-found: error
retention-days: 14

- name: Upload api artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7.0.2
with:
name: AbstractMenus-api
path: |
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/publish-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout (release tag)
uses: actions/checkout@v4
uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.release.tag_name || inputs.tag }}

- name: Set up JDK 21
uses: actions/setup-java@v4
- name: Set up JDK 25
uses: actions/setup-java@v6.2.0
with:
java-version: '21'
java-version: '25'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v6.4.1

- name: Publish :api
run: ./gradlew --no-daemon :api:publish
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout (release tag)
uses: actions/checkout@v4
uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.release.tag_name || inputs.tag }}
fetch-depth: 0

- name: Set up JDK 21
uses: actions/setup-java@v4
- name: Set up JDK 25
uses: actions/setup-java@v6.2.0
with:
java-version: '21'
java-version: '25'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v6.4.1

- name: Verify tag matches project version
run: |
Expand All @@ -46,7 +46,7 @@ jobs:
exit 1
fi

- name: Build shadow plugin + api artifacts (skip tests — already run on the tagged commit by build.yml)
- name: Build shadow plugin + api artifacts (skip tests - already run on the tagged commit by build.yml)
run: ./gradlew --no-daemon :plugin:shadowJar :api:build

- name: Resolve artifact paths
Expand All @@ -63,7 +63,7 @@ jobs:
echo "api_doc=$API_DOC" >> "$GITHUB_OUTPUT"

- name: Attach JARs to release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3.0.4
with:
tag_name: ${{ github.event.release.tag_name || inputs.tag }}
files: |
Expand Down
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

AbstractMenus is a GUI plugin for SpigotMC/PaperMC Minecraft servers (1.20.6+) that allows creating custom inventory-based menus. Written in Java 21, it uses Gradle with PaperMC Paperweight userdev and Shadow plugin.
AbstractMenus is a GUI plugin for PaperMC/Folia Minecraft servers (26.1+) that allows creating custom inventory-based menus. Written in Java 25, it uses Gradle 9.9.1 with the Paper 26.3 API and Shadow plugin.

## Build Commands

```bash
./gradlew build # Compile and run tests
./gradlew shadowJar # Create fat JAR with bundled dependencies (output: build/libs/AbstractMenus-<version>.jar)
./gradlew test # Run JUnit 5 tests only
./gradlew shadowJar # Create fat JAR with bundled dependencies (output: build/dist/AbstractMenus-<version>.jar)
./gradlew test # Run JUnit 6 tests only
```

Tests are in `src/test/java/` using JUnit 5 (Jupiter). There are currently 4 test classes. Run a single test with:
Tests are in `plugin/src/test/java/` using JUnit 6 (Jupiter), Mockito, and MockBukkit 26.3. Run a single test with:
```bash
./gradlew test --tests "ru.abstractmenus.TestValueComparator"
```
Expand Down Expand Up @@ -65,11 +65,11 @@ Menu (API interface)
Menus and config use HOCON format (not YAML). The internal HOCON library is at `ru.abstractmenus.hocon`.

### Key Dependencies
- **API module**: `com.github.AbstractMenus:api` (separate repo, pulled via JitPack)
- **API module**: Local `:api` subproject (`ru.abstractmenus:api`)
- **Lombok**: Used throughout for `@Getter`/`@Setter`/`@AllArgsConstructor`
- **Kyori Adventure + MiniMessage**: Rich text component API
- **FoliaLib**: Thread-safe task scheduling (Folia compatibility)
- **Paperweight userdev**: NMS access with Mojang mappings
- **Paper API**: Compile-only Paper 26.3 API dependency

### Adding a New Action/Rule/Property/Activator
1. Create class in the appropriate `data/` subpackage
Expand Down
130 changes: 85 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

<a href="https://github.com/AbstractMenus/minecraft-plugin/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-red.svg" alt="license"/></a>
<a href="https://github.com/AbstractMenus/minecraft-plugin/releases"><img src="https://img.shields.io/badge/version-2.0.0--alpha.2-blue" alt="version"/></a>
<img src="https://img.shields.io/badge/minecraft-1.20.6+-brightgreen" alt="minecraft"/>
<img src="https://img.shields.io/badge/paper-1.21.11-brightgreen" alt="paper"/>
<img src="https://img.shields.io/badge/java-21-orange" alt="java"/>
<img src="https://img.shields.io/badge/minecraft-26.1+-brightgreen" alt="minecraft"/>
<img src="https://img.shields.io/badge/paper-26.3-brightgreen" alt="paper"/>
<img src="https://img.shields.io/badge/java-25-orange" alt="java"/>
<img src="https://img.shields.io/badge/folia-supported-8a2be2" alt="folia"/>

AbstractMenus is a GUI plugin for Paper / Folia Minecraft servers that lets
Expand All @@ -13,9 +13,7 @@ HOCON configuration. Menus, rules, actions, activators, and item properties
are all first-class, extensible via an open type registry, and render through
a cached, MiniMessage-aware pipeline.

The plugin supports **Minecraft 1.20.6 onwards**. Older versions were dropped
to keep the codebase free of backwards-compatibility wrappers and to track the
current Paper API surface.
The plugin supports **Minecraft 26.1 onwards** and requires **Java 25**. The build targets the Paper 26.3 API.

## 🔭 Table of contents
- [Features](#-features)
Expand Down Expand Up @@ -51,6 +49,8 @@ current Paper API surface.
BungeeCord channel.
- **Folia-compatible scheduling** — all Bukkit scheduler calls go through a
`BukkitTasks` wrapper backed by FoliaLib.

**Known limitations:** The `playerScope` rule cannot safely read another player's state across Folia regions.
- **External integrations (soft-deps)** — Vault, LuckPerms, WorldGuard,
SkinsRestorer, MMOItems, HeadDatabase, ItemsAdder, Oraxen, Citizens,
NBT-API.
Expand All @@ -62,57 +62,104 @@ current Paper API surface.

## 🧰 Item properties

Item properties are configured per menu item. The `tooltipDisplay` property
wraps the Paper `tooltip_display` data component (Minecraft 1.21.5+).
Item properties are configured per menu item on Minecraft 26.x. Namespaced keys containing `:` must be quoted in HOCON; keys without a namespace use `minecraft`.

Hide an item's tooltip entirely:
`tooltipDisplay` can hide an entire tooltip or selected data components, alongside normal name and lore properties:

```hocon
material: DIAMOND_SWORD
name: "Bundle"
tooltipDisplay {
hideTooltip: true
hideTooltip: false
hiddenComponents: [BUNDLE_CONTENTS, "minecraft:enchantments"]
}
lore: ["Contents stay hidden"]
```

Hide the tooltip of specific components, e.g. only the Bundle contents:
Set `hideTooltip: true` to hide the whole tooltip. Component names accept uppercase, lowercase and namespaced keys. Unknown components fail at menu load. Hidden components are merged with existing flags, so `tooltipDisplay` and `flags` can appear in either order.

`itemModel` selects a resource-pack item model; `tooltipStyle` selects tooltip sprites and requires a resource pack that defines the style:

```hocon
material: BUNDLE
tooltipDisplay {
hiddenComponents: [
BUNDLE_CONTENTS
]
}
itemModel: "example:menu/cake"
tooltipStyle: "example:menu/gold"
```

Several components at once:
`maxStackSize` accepts integers from 1 through 99, with invalid constants rejected at menu load. It also accepts integer placeholders; results outside that range log a warning and leave the existing stack limit unchanged. Stack sizes above one cannot be combined with the `max_damage` component, so use them on items without durability:

```hocon
tooltipDisplay {
hiddenComponents: [
BUNDLE_CONTENTS,
ATTRIBUTE_MODIFIERS,
ENCHANTMENTS
]
material: CAKE
maxStackSize: 99
count: 64
```

`rarity` accepts `COMMON`, `UNCOMMON`, `RARE` or `EPIC`, including enum placeholders:

```hocon
rarity: RARE
```

`model` keeps the integer format used by existing menus, mapping it to one float in the custom model data component:

```hocon
model: 123
```

It also accepts an object containing any of the four custom model data lists. Floats, flags, strings and colors support placeholders; colors accept hex, RGB strings or dye names:

```hocon
model {
floats: [1.0, 2.5]
flags: [true, false]
strings: ["cake"]
colors: ["#ff8000"]
}
```

`hiddenComponents` accepts component keys case-insensitively and in
namespaced form (`BUNDLE_CONTENTS`, `bundle_contents`,
`"minecraft:bundle_contents"`). Unknown component names fail loudly at menu load.
Namespaced keys contain `:`, which HOCON only allows inside quotes, so write
them as `"minecraft:bundle_contents"`. Namespaced keys without an explicit
namespace are assumed to be `minecraft:`.
`glow: true` forces the enchantment glint without adding an enchantment; `false` leaves the item's glint unchanged:

```hocon
glow: true
```

`flags` hides the matching tooltip components and preserves attribute modifiers, including those configured with `attributeModifier`:

```hocon
material: DIAMOND_SWORD
flags: HIDE_ATTRIBUTES
```

`count` is passed through unchanged, including amounts above the item's maximum stack size:

```hocon
material: DIAMOND_SWORD
count: 64
```

`data` remains accepted as a byte-valued alias for item damage through `Damageable`. It no longer reads or writes legacy material data; use `damage` for new menus.

## Upgrading

This version supports Minecraft 26.1+ and Java 25 only.

`glow` no longer adds an Unbreaking enchantment, and `flags` no longer writes default attribute modifiers. Items handed to players by older versions, such as menu opener items and quest tokens, that carry those old enchantments or modifiers no longer match updated item definitions in `clickItem` activators, `heldItem` and `inventoryItem` rules, or `itemRemove`. Reissue those affected items after updating.

The built-in placeholder values have changed:

- `block_data` returns the full block state string, such as `minecraft:oak_log[axis=y]`, instead of a legacy numeric data byte.
- `item_data` returns the item's damage value, or `0` for items without damage.
- `block_biome` returns the registry key path in uppercase, such as `PLAINS`.

`count` is passed through unchanged.

## 🔗 Links
- [SpigotMC](https://www.spigotmc.org/resources/abstract-menus-an-advanced-gui-plugin.75107/)
- [Discord](https://discord.gg/kt4P9Cgw)
- [Documentation](https://abstractmenus.github.io/docs/index.html)

## 🧰 Requirements
- **JDK 21+** (target and source)
- **Gradle 9.x** (wrapper included)
- **Paper** or Folia, **1.20.6 – 1.21.11+** (built against 1.21.11 dev bundle)
- **JDK 25+** (target and source)
- **Gradle 9.9.1** (wrapper included)
- **Paper** or Folia, **26.1+** (built against the Paper 26.3 API)

## 🔨 Build
Clone and build a distributable shaded JAR:
Expand All @@ -131,7 +178,7 @@ Other useful tasks:

```bash
./gradlew build # compile + tests
./gradlew test # JUnit 5 + Mockito tests
./gradlew test # JUnit 6 + Mockito tests
./gradlew test --tests "ru.abstractmenus.util.TestStringUtil"
./gradlew jmh -Pbench=PlaceholderReplace # JMH micro-benchmarks
```
Expand Down Expand Up @@ -199,23 +246,16 @@ build, and concurrent map access.
```

## 🧪 Tests
~190 unit and integration tests under `src/test/java/`, covering pure-logic
utilities, the HOCON type deserializers, the copy-on-write item contract, the
MiniMessage legacy color path, and Mockito-based regression pinning for
Bukkit API fixes.
Unit and integration tests under `plugin/src/test/java/`, covering pure-logic utilities, the HOCON type deserializers, the copy-on-write item contract, the MiniMessage legacy color path, and Mockito-based regression pinning for Bukkit API fixes.

```bash
./gradlew test
```

MockBukkit-backed integration tests are scaffolded but currently `@Disabled`
due to an upstream MockBukkit ↔ Paper 1.21.11 registry-bootstrap collision.
MockBukkit 26.3 integration tests verify that the plugin enables, initializes its menu manager, and disables cleanly.

## 👪 Contributions and feedback
If you have suggestions for improvement or want to report a bug, feel free
to create an issue or a pull request in the project repository. The
codebase follows standard Java style, uses Lombok for boilerplate, and
targets Java 21 (pattern matching, records, switch expressions welcome).
If you have suggestions for improvement or want to report a bug, feel free to create an issue or a pull request in the project repository. The codebase follows standard Java style, uses Lombok for boilerplate, and targets Java 25 (pattern matching, records, switch expressions welcome).

## 🙌 Contributors

Expand Down
Loading
Loading