Repository navigation
Deliveries
What cannot be handed over now - a full inventory, an offline recipient, money for a wallet that cannot take it -
becomes a pending delivery instead of being lost. The core keeps them (package
br.com.finalcraft.evernifecore.logic.delivery), in each player's deliveries section: it is the one piece of
engine state the core keeps for plugins.
Most plugins never call it: the stock give-item effect already does it.
# a quest reward, read with Effects.parseList(caller, node, zone)
effects:
- { type: give-item, item: minecraft:diamond, amount: 100 } # what does not fit waits as a delivery
- { type: give-item, item: minecraft:elytra, expires: 7d } # waits at most a week
- { type: money, amount: 500, to: pending } # straight to the deliveries: claimed later
- { type: give-item, item: hytale:Rock_Stone, to: finalcolonies:warehouse }Raw effect nodes owed to one player, parsed again when claimed:
| Member | Meaning |
|---|---|
getId() / getRecipient()
|
the delivery and the player it is for |
getOrigin() |
a DeliveryOrigin: getPlugin() (lower-cased), getEmitter() (the caller's origin), getReason()
|
getCreatedAt() / getExpiresAt() / isExpiredAt(now)
|
when it was kept; when it stops waiting (null: until claimed or purged) |
getPolicy() |
KEEP_SELF_CONTAINED (default) hands out the core's effects and keeps a missing plugin's ones raw; REQUIRES_ORIGIN waits whole until every plugin it names is loaded |
getEffects() / isSelfContained()
|
the nodes; whether every one is a core type |
A node is never lost - not one whose plugin is not loaded, nor one whose effect failed on the claim and stays in the delivery:
the first stays raw, and a claim tells the player what it is waiting for; the second (audited EFFECT_FAILED: a currency
that is not registered or cannot pay, no inventory) is logged with its failure and tried again on the next claim. A node
is one effect: a list whose one child failed comes back whole.
Deliveries.get(), any thread; every verb completes a future, and a claim applies its effects on the player's thread.
| Call | What it does |
|---|---|
enqueue(recipient, origin, policy, ttl, effects) |
keeps effects for a player, online or not |
keepFor(ctx, policy, ttl, node) |
what an effect does with what it could not hand over: inside a claim it stays in the claimed delivery, anywhere else it becomes a new one from the context's caller |
enqueueSelfContained(ctx, recipient, effects) |
keeps only the core's nodes and audits each other one as DELIVERY_DISCARDED - the path of a delayed effect whose player left |
listOf(recipient) |
every pending delivery, oldest first |
claim(player, id) / claimAll(player)
|
hands out what fits now; what still does not fit, and what failed, stays pending in the same delivery; answers a ClaimResult (getDelivered, getKept, getExpired) |
listFrom(plugin) |
every player's deliveries from one plugin |
purge(plugin, by) |
removes every pending delivery from one plugin, logs how many on the core's log |
sweepExpired() |
drops the expired ones of every loaded player |
Deliveries.start() (the core calls it at enable) claims on every login, sweeps the expired ones once a minute and on
login, and registers the logic's DeferredEffectSink: a delayed or repeated effect whose player left becomes a delivery
through enqueueSelfContained (a share of a reward is still dropped). Deliveries.closeAll() stops the claim and the
sweep and puts the dropping sink back; the pending deliveries stay in the players' data. Each step posts a
DeliveryEvent (ENQUEUED, DELIVERED, EXPIRED, PURGED, DISCARDED; getDelivery(), getBy()) and an
AuditLog of the delivering plugin records it.
The effect modifier to: <destination> sends what an effect gives somewhere else than the player's inventory or
wallet. It is accepted by effects whose Effect.acceptsDestination() is true - give-item and money - and refused,
naming them, on any other. Destinations live in DeliveryDestinations (a TypeRegistry "destination"):
| Destination | What it does |
|---|---|
evernifecore:inventory |
the player's inventory: an InventoryDestination each platform registers (Bukkit, Hytale); also counts and takes items for the item cost |
evernifecore:pending |
always pending - "claim it later" |
| a plugin's own | DeliveryDestinations.register(owner, destination) |
A to: that no registered destination answers keeps the whole node, to: included, as a pending delivery, handed
out once the plugin is back.
A destination implements DeliveryDestination: getId(), deliverItem(ctx, item) (returns what did not fit, or
null), and optionally deliverAmount(ctx, currency, amount) (the default pays the context owner's wallet). Any thread;
a destination that needs the player's thread hops there itself.
A plugin mounts the player side on its own command:
@FinalCMD.Node(subcmd = "deliveries", permission = "myplugin.deliveries")
private final DeliveriesCommandNode deliveries = new DeliveriesCommandNode();/<cmd> deliveries list shows the player's deliveries with origin, reason and age; claim <id>|all hands out what
fits now (an id may be shortened to its first characters).
The admin side is the core's: /ecore deliveries list <plugin> (how many each player has from that plugin) and
/ecore deliveries purge <plugin>, permission evernifecore.command.deliveries.
Platforms.withInventory(slots) registers a TestInventory as evernifecore:inventory for the life of the world
(add, fill, count, take, getContents, clear per player); without it an item effect fails naming that
builder. LogicWorld.deliveries() brings up an in-memory PlayerData layer with the deliveries section;
LogicWorld.quit(player) / rejoin(player) take a player away and back, so a delayed effect can fire while they are
gone. ECoreTestWorld.close() restores the dropping sink. On a live
server the deliveries suite of In-Server Conformance proves both paths.
EverNifeCore · Home · made by Petrus Pradella
Getting Started
Commands & Text
Player Data & Storage
- PlayerData & PDSections
- Accounts
- Storage Backends
- Inline Backends for Plugins
- Block Data (SVWorldDataManager)
- Legacy Data Migration
- Cooldowns
Config & Minecraft Systems
- Configuration
- Logging & Debug Modules
- Events
- Regions
- Groups
- Notifications
- NPCs
- Logic
- Quests
- Provenance
- Scheduler & Threading
- Items & NBT
- Screens
- Dialogues
- Menus
- Integrations
- Economy
- Boosters
- Deliveries
- Audit Log
- Dynamic Values
- Player Ignore
- Version Compatibility
Architecture & Reference