Files

49 lines
5.1 KiB
Markdown

## GameModeInventories-OG
Allow players to have separate inventories for each game mode (Creative, Survival and Adventure).
This is a [TrueOG Network](https://trueog.net) maintained soft fork of [eccentricdevotion/GameModeInventories](https://github.com/eccentricdevotion/GameModeInventories).
### Changes from Upstream
- Build system migrated from Maven to Gradle (Kotlin DSL), Gradle 8.14.3, Shadow 8.3.9, Spotless with TrueOG Network's eclipse-based Java Formatting.
- `config.yml` is read-only at runtime — the plugin no longer mutates or rewrites it. A default `config.yml` is copied into the plugin folder on first run if missing.
- Compatible with [NoClip-OG](https://git.trueog.net/trueog/NoClip-OG) (1.3.0+). When `restrict_spectator` is enabled, players holding the `noclip.use` permission are exempt from the restriction so NoClip's creative/spectator toggle works without being cancelled or spamming chat.
- Creative is staff only: it needs `gamemodeinventories.toggle` *and* a region in `creative_regions`, or `gamemodeinventories.anywhere` to ignore both. Spectator needs `gamemodeinventories.spectator` or `noclip.use`. Adventure is refused in `restrict_adventure_worlds`.
- Gamemode rules live in one place, `api/GameModePolicy`, which every enforcement point in the plugin asks. It is published for other plugins so they enforce the same rule instead of reimplementing it: fetch it from the Bukkit services manager, or reflectively via `GameModeInventories#getGameModePolicy()`. `mayUse(player, gameMode, location)` answers for any gamemode; survival is always allowed, adventure never is.
- Creative is enforced on movement and teleports, judged at the destination, and unsanctioned creative is forced back to survival with one-time fall protection. Gamemode switches pre-validated through the policy (`internalGameModeChange`) are trusted rather than policed a second time.
- Login is deferred to [Spawn-OG](https://git.trueog.net/trueog/Spawn-OG) when it is installed. It normalizes gamemode inside a safety transaction that also relocates the player, so forcing survival underneath it would race that transaction. Spawn-OG also uses the policy and `internalGameModeChange` to hand creative or spectator back after a rescue or `/spawnback` return. Without Spawn-OG, GameModeInventories-OG still forces survival on join for creative players outside a creative region.
- Only the **creative** inventory is stored here, one per bundle (a bundle is a MyWorlds inventory group, so world/world_nether/world_the_end share one). The **survival** inventory is owned by MyWorlds in Purpur's RocksDB, so no inventory is ever stored in two places and the two stores cannot diverge. On the creative boundary GMI saves the outgoing creative inventory at `LOW` and loads the incoming one at `HIGH`, so MyWorlds (which saves/restores survival at the same priorities) always captures the outgoing inventory before the incoming one is loaded. Creative follows the bundle on a world change too (saved for the world left, loaded for the world entered via `PlayerProfileAppliedEvent`), and is persisted on quit, shutdown and login. `(uuid, gamemode, bundle)` is unique, and a failed creative swap or legacy bundle assignment refuses (kick or no enable) rather than hand out a wrong inventory. Spectator and adventure are transient (not persisted). Death inventories are parked in a `deaths` table, keyed by bundle and game mode, and are added back (never overwriting what the player holds) when they are next in that bundle and mode; if parking fails the normal drops are kept. Without MyWorlds the bundle is the world name and players are switched to survival before a cross-world teleport.
- Dropped LogBlock integration. Block-removal logging now runs exclusively through CoreProtect / CoreProtect-OG.
- Targets Purpur API 1.19.4 (Java 17, GraalVM toolchain).
### Commands
| Command | Description | Permission |
| --- | --- | --- |
| `/gmi [option]` (alias `/gmic`) | Toggle creative mode, or change config options | `gamemodeinventories.toggle` / `gamemodeinventories.anywhere` to toggle; `gamemodeinventories.admin` for config |
### Permissions
- `gamemodeinventories.use` - Separate per-gamemode inventories (default: true)
- `gamemodeinventories.toggle` - Toggle creative via `/gmic` inside a `creative_regions` region (default: op)
- `gamemodeinventories.anywhere` - Hold and toggle creative anywhere, exempt from forced survival (default: op)
- `gamemodeinventories.spectator` - Hold spectator mode (default: op)
- `gamemodeinventories.death` - Keep separate death handling (default: op)
- `gamemodeinventories.bypass` - Bypass restrictions enabled under `bypass` in the config (default: op)
- `gamemodeinventories.admin` - Change config options via `/gmi` (default: op)
### Compilation and Build
This project uses Gradle. To build the plugin:
```bash
./gradlew build
```
This produces the plugin jar in the `build/libs` directory. It is normally built as a submodule of Spawn-OG, which compiles against its API.
### License
GPL v3 or later. Inventory serialization derives from work by eccentric_nz, drtshock, and Kristian S. Stangeland (aadnk); the bundled `JSON` package is JSON.org code under its own license.