Inventory sync, item tracking & locks

Three modules that build on each other:

ModuleContentsrequires
inventory-syncInventories of all players in the database; /invsee for online and offline players and players on other servers; optionally a shared inventory for several servers; overflow storage for full inventories–
item-trackingInvisible item IDs, complete history, chest registry, stock, statistics, assignment, /deleteiteminventory-sync
locksItem and chest locks, automatic locks by quantityitem-tracking
Note

License: inventory-sync, item-tracking and locks need an EternalSystem license. Free in the base by default are core, punishments, reports and lobby; which modules are free can change – the dashboard shows locked modules grayed out.

Enabling

  • Enable the modules on every game server, e.g. via the survival or economy preset (see Modules & Presets).
  • Also enable inventory-sync on the proxy: /invsee runs there, resolves offline targets and players on other servers, and opens the GUI on the viewer's server.
  • All servers and the REST API need the same MySQL database.
  • Everything is in the inventory-sync section of config.yml (same file on Spigot and proxy).

Inventory sync

inventory-sync:
  enabled: true
  mode: separate          # separate = each server has its own inventory, global = one for the whole network
  groups: {}              # only with separate: servers with a shared inventory
  #  survival: [survival-1, survival-2]
  parts:
    inventory: true
    armor: true
    offhand: true
    enderchest: true
    experience: true
    health: true
    hunger: true
    effects: true
    gamemode: false
  autosave-seconds: 60       # snapshot interval for online players; quitting always saves immediately
  join-load-timeout-ms: 3000 # how long the new server waits for the old server's quit save
OptionDefaultMeaning
modeseparateseparate: every server stores its own inventory (for viewing only). global: one inventory for the whole network, loaded on join and saved on quit/server switch.
groups{}In separate mode: servers in a group share one inventory.
parts.*everything except gamemodeWhat is saved and (with global/groups) carried over.

Scope is the key of a saved inventory: the server name (separate), the group name or global. The dashboard and /invsee <Spieler> <Scope> show all scopes a player has ever had.

Server switch with global/groups: the old server writes the snapshot on quit and releases the sync session. Until then, the new server freezes the player (no inventory access, no picking up), then loads and applies the state. After a crash, every server releases its stuck sessions on startup.

In-game commands

CommandPermissionModuleDescription
/invsee <Spieler>eternal.base.invseeinventory-syncOne view for all cases (inventory, hotbar, armor, offhand, ender chest button), always editable. Target on the same server: live in both directions. Target on another server: you are connected there. Target offline: saved state; changes are applied on the next join
/invsee <Spieler> <Scope>eternal.sync.viewinventory-syncSaved state of a specific scope; editable with eternal.base.invsee or eternal.sync.edit, otherwise read only
Left-click in the read-only GUIeternal.sync.historyitem-trackingItem history in chat
Right-click in the read-only GUIeternal.sync.lock.itemlocksLock/unlock the item
/trackitem [history|<id>] (/itemtrack, /itemhistory)eternal.sync.historyitem-trackingID of the item in your hand (click copies) and who owned it before; history = full history, <id> = by ID
/trackchest (/chesttrack, /trackcontainer)eternal.sync.historyitem-trackingThe chest/frame/block you are looking at: chest ID, owner, all users
/deleteitem [Grund] (/delitem)eternal.sync.delete.itemitem-trackingWithout a reason ([Grund]): destroy GUI. With a reason: destroy the item in your hand immediately
/itemlock <lock|unlock|info> [Grund]eternal.sync.lock.itemlocksLock the item in your hand
/chestlock <hard|soft|off|info> [Grund] (/containerlock)eternal.sync.lock.containerlocksLock the container you are looking at
/expandedinv [Spieler] (/ei)eternal.expandedinv.useinventory-syncOpen the overflow storage, taking out only (see overflow storage)

Protection bypass for mods (module inventory-sync, no command): mods interact completely normally. If something forbids a right-click – a chest lock, PlotSquared, WorldGuard, GriefPrevention – Eternal lifts the ban only for the categories the player has a permission for. Vanilla then does the rest (the door opens, the chest opens live with animation). Whatever the mod is allowed to do anyway stays unchanged.

PermissionAllowed despite protectionDefault
eternal.inspect.container.viewOpen chests, barrels, shulkers, furnaces, hoppers …Staff
eternal.inspect.container.takeTake from chests opened this way (without it: click, shift-click, hotbar swap, double-click are blocked)Admin
eternal.inspect.container.putPut into chests opened this way (without it: dragging and shift-click from your own inventory are also blocked)Admin
eternal.inspect.doorDoors, trapdoors, fence gatesStaff
eternal.inspect.switchLevers, buttonsAdmin
eternal.inspect.useOther usable blocks (anvil, bed, note block, lectern …)Admin

eternal.inspect.* grants everything. A locked dragon egg is never released (a click would teleport it). If a locked gravity block (dragon egg, anvil, sand …) falls because its support is missing, it falls normally – the lock moves with it to where it lands. If it would break into an item in the process (torch trick), it jumps back to its place.

While an offline inventory is being edited, the GUI holds a lock. If the player joins, the GUI closes; the player gets a notice about the change. If the lock cannot be taken (player is online, someone else is editing), the GUI stays read-only.

Rank protection

As with punishments, the viewer needs a higher level than the target (level = maximum of eternal.tier.N and rank priority). This applies in-game and in the dashboard, for inventories and item histories (there, the current owner counts). eternal.sync.bypass or eternal.bypass remove the protection.

Warning

Without rank priorities and without eternal.tier.*, everyone has level 0 – then nobody can see other players' inventories. Staff then need eternal.sync.bypass.

Overflow storage (expanded inventory)

The overflow storage („Zwischenlager“, part of inventory-sync) catches what no longer fits into a full inventory. Every player turns it on themselves: /settings → Zwischenlager (expandedinv.collect, default off; the entry appears with eternal.expandedinv.use, see Player settings).

  • Collecting: when it is on and the inventory is full, items you walk over go into the overflow storage. Auto-pickup drops that no longer fit into the inventory go there too.
  • Network-wide: the storage lives in the database and is the same on all servers – at most 270 stacks (6 pages of 45).
  • Taking out only: /expandedinv or /ei opens it. A click puts the stack into your inventory if it fits completely. Putting items in is never possible.
  • Storage full: the player gets a message, the items stay on the ground.
  • Rules still apply: every collection fires the normal pickup event – item locks, lobby protection, the no_pickup perk (see Perks) and item tracking work just as with a normal pickup.
  • Dupe-safe across servers: changes use optimistic versioning; if two servers conflict, the change is retried.

Other players' overflow storage

UsagePermissionDefault level
/ei – your own storageeternal.expandedinv.useAll
/ei <Spieler> – player online on this servereternal.expandedinv.othersTeam
/ei <Spieler> – offline or on another serveradditionally eternal.expandedinv.others.offlineTeam
Take items out of someone else's storageeternal.expandedinv.others.takeAdmin

Every removal from someone else's storage is logged in the console. The same rank protection as for /invsee applies; eternal.sync.bypass removes it.

In the dashboard, a player's inventory page shows a Zwischenlager ("Overflow storage") card with all stacks and their lock state; a click on an item opens its history (permission eternal.web.inventory.view, API GET /players/{name}/expanded-inv).

Item tracking

Every item gets an invisible ID (eternal_item_id in the PersistentDataContainer; on 1.8–1.13 in a hidden lore line, see Versions). Logged are who had it when, which chest it is in (with coordinates and who put it there), and server switches.

inventory-sync:
  item-tracking:
    enabled: true
    stack-mode: id                 # id = every stack has a stack ID, log = only history per material
    stack-log-materials: []        # always in log mode, e.g. [COBBLESTONE, DIRT, NETHERRACK]
    log-stack-hopper-moves: false  # log hopper merges of stack-ID items (many rows)
    container-flush-ticks: 10      # write live chest contents every X ticks, 0 = only on close
    container-exclude-types: []    # e.g. [HOPPER] for huge farms
    tracked-blocks: [SPAWNER, DRAGON_EGG, BEACON, ...]  # keep their ID when placed
    track-frames: true             # log items in frames
    log-hopper-moves: true
    scan-interval-seconds: 3       # scan for new items without an event (/give, other plugins)
    lock-refresh-seconds: 5        # reload locks from the DB

Stack IDs: a split stack keeps the ID only on the larger part; the other part immediately gets a new one (event SPLIT, in creative mode CLONED). When items come together (click, shift-click, double-click, pickup, hopper, furnace, crafting), they take over the ID of the target stack (MERGE); if an entire stack is absorbed into another, its ID is closed (STACKED).

Events (selection): REGISTER, PICKUP, DROP, DEATH_DROP, DESPAWN, CONTAINER_PUT/CONTAINER_TAKE, HOPPER_MOVE, CONTAINER_BROKEN, SERVER_SWITCH, LOCK/UNLOCK, MERGE, SPLIT, STACKED, DESTROYED (with cause: lava, fire, explosion, cactus, void, lightning, durability, consumed), DELETED (destroyed by staff), FRAME_PUT/FRAME_TAKE, PLACED/BROKEN, TRADE (see Party, friends & clans).

Chest registry: every chest, every frame and every placed special block gets a chest ID (#12). Contents are recorded live – player clicks, hoppers, droppers, furnaces, brewing stands, placing, breaking, explosions – and saved in one transaction every container-flush-ticks. Entity inventories (minecart with chest, donkey, llama) are not captured.

Known gaps: results from the stonecutter, anvil, grindstone, loom and villager trading land as a separate stack and only take over the ID on the next scan.

Destroying (/deleteitem)

/deleteitem opens a GUI: put items in, close it, then the chat asks for the reason for 10 seconds (no answer = no reason). Every stack is logged as DELETED with player, time and reason; untracked items get an ID first. Taking items out is only possible with eternal.sync.delete.item.take – without this permission, putting items in is final.

Locks

KindEffect
Item lockThe item cannot be moved, dropped, placed or consumed – in the inventory as well as in the chest. Hoppers do not pull it.
Chest HARDThe chest cannot be opened, broken or blown up; hoppers in/out are blocked.
Chest SOFTThe chest opens, but nothing can be taken out. Putting items in is still allowed; breaking is blocked.
Frame / placed blockOne lock; breaking, explosions, pistons (and for the dragon egg, the teleport) are blocked.

Double chests: a lock on one half protects both. Parts split off a locked stack inherit the lock. eternal.sync.lock.bypass ignores all locks. Locks from the dashboard or from other servers take effect after at most lock-refresh-seconds.

Automatic locks (dashboard, permission eternal.web.thresholds.manage): rules "lock from quantity X" per stack, chest, inventory or player, for one material or *, optionally only for one player, for chests optionally the chest itself (soft). The API checks every 15 s. Owners with eternal.sync.lock.bypass are skipped.

Dashboard

PagePermissionContents
Spieler ("Players") → Inventar ansehen ("View inventory")eternal.web.inventory.viewInventory per scope in the game layout (armor, 3×9, hotbar, ender chest, effects, level/health/hunger); click on an item → history and lock
↳ Zwischenlager ("Overflow storage") cardeternal.web.inventory.viewAll stacks in the overflow storage with lock state; click → history
↳ Remove items / „Zu mir“ ("To me")eternal.web.inventory.editOnline immediately, offline on the next join
Item-Tracking → Statistik ("Statistics")eternal.web.trackingWhat exists most, who has the most, new items and trading in 24 h, automatic locks
Item-Tracking → Itemseternal.web.inventory.viewSearch by ID, material, name, owner, server, location (chest/player/ground), locked only; full history
Item-Tracking → Kisten ("Chests")eternal.web.inventory.viewFilters (contains item, server, with contents, locked, broken; All/Chests/Placed), detail view with contents, tracked items, history; „Live“ refresh every 3 s
Item-Tracking → Kisten-Sperren ("Chest locks")eternal.web.inventory.viewAll locks, new lock by coordinates
Item-Tracking → Spieler ("Players")eternal.web.trackingEverything a player owns (inventories + chests)
Item-Tracking → Auto-Sperren ("Automatic locks")eternal.web.thresholds.manageCreate/change rules
Set/lift lockseternal.web.locks.manageButtons on the pages above
Teleport button on chestseternal.web.tracking.teleportOnline: you are taken there in-game. Offline: /tppos x y z welt copied to the clipboard
Item tracking → Zurücksetzen ("Reset")eternal.web.adminWipe tracking data network-wide (choose: items & history, stock, locks, auto-lock rules); confirm by typing "ZURÜCKSETZEN"
Warning

Reset is final – take a backup first (Cloud › Backups or mysqldump). Within seconds the servers clear their caches and register everything players carry again. Items keep their id mark and reappear in the registry on their next contact. Deleting directly in the database is not needed (and leaves the servers' caches stale).

Every item with an ID has an owner (the last player who held it). If it is in a shared chest, it stays assigned to them.

Permissions

PermissionDefault levelPurpose
eternal.base.invseeTeam/invsee live and editable
eternal.sync.viewTeam/invsee <Spieler> <Scope>
eternal.sync.editAdminEdit saved inventories
eternal.sync.bypassAdminBypass rank protection for inventories and history
eternal.sync.historyTeam/trackitem, /trackchest, chest ID in the chest title
eternal.sync.lock.itemAdmin/itemlock
eternal.sync.lock.containerAdmin/chestlock
eternal.sync.lock.bypassAdminIgnore locks
eternal.sync.delete.itemAdmin/deleteitem
eternal.sync.delete.item.takeAdminTake items back out of the destroy GUI
eternal.expandedinv.useAllYour own overflow storage and the „Zwischenlager“ setting
eternal.expandedinv.othersTeam/ei <Spieler> on this server
eternal.expandedinv.others.offlineTeam/ei <Spieler> offline / on other servers
eternal.expandedinv.others.takeAdminTake from other players' overflow storage (logged)

In-game, the plugin.yml defaults also apply (e.g. eternal.sync.delete.item: op) as long as Eternal Perms does not define anything. See Permissions reference.

Common pitfalls

  • /invsee does not find offline players: inventory-sync is missing on the proxy.
  • Inventory "jumps back" with global: the old server saves too slowly – increase join-load-timeout-ms, check database latency.
  • Huge tables because of farms: put bulk goods in stack-log-materials, leave log-stack-hopper-moves: false, and if needed container-exclude-types: [HOPPER].
  • Item icons are missing in the dashboard: the icons come from assets.mcasset.cloud. In eternal-web/src/app/core/api.config.ts you can point textureUrl to your own host or empty it (then only the material text is shown).
  • Edited offline inventories do not arrive: the player must join a server of the matching scope.