Class PermissionChestService
enhancedechest.additional_amount.<count>.slot.<size> (e.g.
enhancedechest.additional_amount.2.slot.54 → two 54-slot chests). All matching permissions
stack (summed per size), so a player gets the total of every matching permission.
The grants live as ChestKind.PERM chests: to the player they behave exactly like a NORMAL
chest (open/rename/icon/set-main), but admin commands never touch them and they are managed entirely
by reconcile(java.util.UUID, java.util.Map<java.lang.Integer, java.lang.Integer>, int, int, java.util.List<com.enhancedechest.model.ChestSummary>) — the diff between the player's permission-derived target and the PERM chests
they currently own. ChestOpener runs the reconcile on open, reusing the chest list it already
fetched so the common case (target already matches) issues zero extra queries.
The player's base chest is inviolable: reconcile bootstraps a NORMAL chest #1 before granting any PERM chest, and never deletes a NORMAL chest, so a player can never be left with no chests.
All deletions/shrinks go through ChestSpillService, so any items that no longer fit spill
into a temp chest (recoverable from /eclist) rather than being lost. The move back is
automatic too: a chest granted here pulls one fitting temp chest's items back in
(ChestSpillService.reclaimTempInto(java.util.UUID, int)), so a re-granted rank restores what its revoke parked.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordBoth permission-derived targets, resolved together: the PERM-chest target assize → countand the base-chest size override (the largest validdefault_sizepermission held, or0for none). -
Constructor Summary
ConstructorsConstructorDescriptionPermissionChestService(StorageGateway storageGateway, ChestSpillService spillService, int defaultSize) -
Method Summary
Modifier and TypeMethodDescriptionreconcile(UUID owner, Map<Integer, Integer> desired, int defaultTarget, int appliedDefault, List<ChestSummary> chests) Reconciles both the player's PERM chests (against their permission-deriveddesiredtarget) and the base NORMAL chest's size (against thedefault_sizepermission), then completes with the up-to-date chest list.resolveTargets(org.bukkit.entity.Player player) Resolves both permission-derived targets in a single pass over the player's effective permissions.voidsetConfig(int defaultSize) Re-applies the runtime-tunable values after a/ee reload.
-
Constructor Details
-
PermissionChestService
public PermissionChestService(StorageGateway storageGateway, ChestSpillService spillService, int defaultSize)
-
-
Method Details
-
setConfig
public void setConfig(int defaultSize) Re-applies the runtime-tunable values after a/ee reload. Dupe-safe (only future work). -
resolveTargets
Resolves both permission-derived targets in a single pass over the player's effective permissions. This runs on the region/main thread per open, and with LuckPerms the effective set is often hundreds of nodes with eachgetEffectivePermissions()call building a fresh snapshot — so it is scanned exactly once, and a cheapString.startsWith(java.lang.String, int)prefilter skips the regex Matcher allocation for the ~all nodes that are neither grant nor size-override nodes. Must be called on the player's entity thread (getEffectivePermissions). -
reconcile
public CompletableFuture<List<ChestSummary>> reconcile(UUID owner, Map<Integer, Integer> desired, int defaultTarget, int appliedDefault, List<ChestSummary> chests) Reconciles both the player's PERM chests (against their permission-deriveddesiredtarget) and the base NORMAL chest's size (against thedefault_sizepermission), then completes with the up-to-date chest list. When nothing needs to change, returns the passed-in list with no DB writes (fast path).PERM chests. The diff keeps as many items in place as possible: existing PERM chests already at a desired size are kept untouched; surplus PERM chests are resized in place to fill a still-missing size (preserving their items, name and icon — only a shrink spills the overflow); any remaining missing sizes create fresh empty chests; and any true surplus is removed with its items spilled to temp.
Base chest size. Driven by
defaultTarget(fromresolveTargets(org.bukkit.entity.Player)) and the persistedappliedDefaultbaseline:defaultTarget > 0— the player holds adefault_sizepermission: the base chest is resized to it (grow, or shrink spilling the overflow to a temp chest);defaultTarget == 0withappliedDefault > 0— the permission was just revoked: the base chest shrinks back to the config default (spilling any overflow);defaultTarget == 0withappliedDefault == 0— never permission-managed: the base chest is left alone (its size is the admin/config domain).
defaultTarget); this method only moves items.- Parameters:
defaultTarget- the base-chest size override (0 = nodefault_sizepermission held)appliedDefault- the persistedapplied_default_sizebaseline (last permission-set size)chests- the player's current chests (already fetched by the caller)
-