Common states
Reconciling UNKNOWN
- Use
/km inspect <operation-id>to inspect the player, amounts/items, source node, session, and execution stage. Check item summaries and this operation’s administrative before/after records, and retain relevant external evidence. - Determine whether execution never occurred, occurred successfully, or remains uncertain.
UNKNOWNis neither failure nor permission to debit again. - Use an administrative command to record the confirmed outcome and a reason. Leave uncertain cases unresolved instead of editing wallet values to hide differences.
- Verify reservations, claims, and audit records before reporting the result to the player.
PREPARED is still preparing or executing. It can be inspected and refreshed, but cannot be reconciled early. An execution permit, a returned call, and the final ledger state are shown separately; a return receipt alone does not prove a sufficiently certain external outcome. A timed-out economy call is not submitted again. Its late return only adds evidence and preserves UNKNOWN, without automatically crediting funds, refunding, or redelivering.
If execution has not confirmed completion and its source node is active, EXECUTION_IN_FLIGHT blocks reconciliation, including a failure decision that would release assets. An offline source with no completion receipt requires a separate declaration: the source has been stopped and external economy requests have been verified no longer pending. Explicitly selecting the declaration and confirming the result records it and the reason in the audit. An expired lease, the player’s current balance, or elapsed time cannot replace that verification.
Use /km admin <player-UUID-or-online-name> to cross-check the same player’s wallets, all asset states, orders, and history. Offline players require a complete UUID; names resolve only players online on this server. This is a read-only audit entry with no proxy claims, balance editing, or general currency issuance. Evidence pages show interpretable fields and identify missing older details instead of treating raw serialized data as a conclusion.
Backup and migration
Stop market writes on every old node before migration and account for pending operations. Back up the complete database andplugins/KiteMarket/ configuration. Preserve network identity, currencies, wallets, orders, escrowed items, and operation records together.
GUI preferences use separate InnoDB tables km_ui_preferences and km_ui_theme_selections, both keyed by network and player UUID, with the mode or theme ID and database update time. No preference row means AUTO; no theme row uses the selected backend’s server default. Startup creates both through the migration entry without changing the financial schema version or snapshot format 2. Fixed backup and restore lists must include both tables. Older theme IDs remain readable; a missing theme causes fallback without rewriting the saved preference.
Validate the restored environment in isolation, then add nodes gradually. Match the Minecraft version, market protocol, item profile, and currency definitions; keep node IDs unique. Ensure old nodes cannot keep writing before opening the new network.
The current database schema is version 1; startup validates it and requires InnoDB. Before upgrading, inventory unfinished orders, claim assets, and PREPARED/UNKNOWN operations, then back up and test in an isolated database. There is no defined automatic downgrade between schema versions. Do not bypass version checks with an older JAR or partial restore.
Replacing a plugin JAR requires a normal full-network stop, complete backup and matching builds. An interface-only update does not require a protocol upgrade or clearing existing assets. The warm layout is the default; older custom slots select the compatible layout, and invalid candidates leave active settings intact. Automatic selection tries IA, then vanilla, with no default IA theme; saved preferences and settings are not rewritten. Third-party themes need no additional KiteMC theme license. See compatibility for the tested scope.
If the database contains extension tables such as km_dlc_proofs, include them in full km_* backup/restoration. Back up installed theme resources, proofs or encrypted caches together with the matching build; do not automatically delete them or mix older loaders. Key caches are private operational data, not public downloads.
Third-party themes load from plugins/KiteMarket/themes/; retain their declarations and resources during migration. /km ui explains the actual interface and fallback. After pack content changes, register a new actual sent UUID and matching SHA-1 and run /km reload. Assigning a different digest to a registered UUID is rejected. An unavailable theme affects presentation without canceling orders or releasing market reservations. See ItemsAdder integration and the UI SDK.
Do not restore only order tables, roll back a single node’s configuration independently, or connect cloned test servers to production data. Currency-scale or provider changes need a dedicated reconciliation migration. Cross-Minecraft-version conversion is outside v1.
Upgrading an existing market to protocol 4
Protocol 4 builds store a sale order’s minimum purchase quantity. Sales still use per-item unit prices and partial purchases; auctions use whole-lot totals. The build determines the protocol. Do not mix nodes or switch it through a reload. Database schema version is1, item snapshots use format 2, and licensing uses HTTP v2; these versions are checked separately. A new market does not need the migration field. See compatibility for actual tests; upgrade rules do not certify every combination.
Existing protocol 1, 2 and 3 markets all use the following strict steps. Open orders and escrowed trades must be cleared first:
- Inspect wallets, claims, open orders, and
PREPARED/UNKNOWNoperations with the old build. Reconcile uncertain effects before issuing items or refunds. - Enter
EXIT_ONLYthrough the verified license exit process. Wait until unfinished orders, auctions, frozen funds, and escrow are cleared. Available wallet balances and claimable items may remain. - Stop every node normally. Back up all
km_*data, each node’splugins/KiteMarket/, and the old JAR, verify restoration, and wait for every node lease to expire. - Explicitly set the actual source
network.upgrade-from-protocol: '3'on the first node; use'1'or'2'when appropriate. Replace all nodes with protocol 4 builds. Keep the Minecraft version, currencies,network.name, andnetwork.item-profileidentical. The source protocol must be accurate; the field cannot also change the currency or item environment. - Start one node first. The upgrade requires an exact old identity match,
EXIT_ONLY, no live node lease, open order, frozen funds,PREPARED/UNKNOWNoperation, or item inESCROW/DELIVERING. Identity changes, invalidation of every old node epoch and session, and thePROTOCOL_UPGRADEaudit commit in one database transaction. An old process with an expired lease cannot heartbeat again or acquire a session. The network UUID, license binding, available wallets, claim snapshots and history are preserved. - Verify the UUID, balances, claims, and license, remove the temporary upgrade field, then start the remaining new nodes. Restored authorization can reopen the market; cleared orders do not revive.
Original snapshots and attribute comparison
New item snapshots use format2. data retains the original bytes produced by the server, and rawDigest checks their integrity independently. The comparison fingerprint ignores quantity. Existing format 1 snapshots are not automatically rewritten and retain their original digest checks and asset exit path.
Comparison ignores only typed-NBT compound field order and the order of vanilla enchantment entries with unique string id values in the legacy root tag.Enchantments / tag.StoredEnchantments. Names, Lore, other lists (including PDC lists), data types, numeric values, strings, and array contents still participate. Corrupted, ambiguous, or over-budget data is rejected without falling back to looser matching.
Comparison does not rewrite escrowed items; claiming still restores the original snapshot. Raw-byte integrity and attribute equivalence are separate checks. Players cannot provide custom NBT expressions. Verification records list exact artifacts and scenarios.
Narrower admission and existing assets
New trades currently admit tested baseUNSPECIFIC and enchanted-book ENCHANTED types and verified property keys. Potions, books, skulls, maps, special armor, and other unverified types are explicitly rejected. Exact samples cannot bypass admission. Verified data such as PDC that advanced conditions cannot interpret still requires an exact sample.
Admission limits new samples, listings, supplies, and escrow deposits. Existing items retain restoration, cancellation returns, license exits, and claims, with snapshot-format, digest, and source-version checks. A narrower allowlist must not destroy or permanently lock old assets. Type admission does not certify an entire game version, network, or economy combination; see certification for the actual scope.
Minimum validation
Use isolated test players and small test balances to exercise all three trading modes, simultaneous actions on two nodes, transfers, full-inventory claims, and restart recovery. Remove test assets afterward and retain useful acceptance records. See certification for platform coverage. That checklist applies when enabling a new environment or changing related features. Interface updates also need checks for navigation, drafts, amount input, resource-pack rejection/failure and third-party-theme fallback. Use isolated characters and orders without resetting existing players’ assets.Read-only developer API
com.kitemc.market.api.KiteMarketApi is registered through Bukkit ServicesManager after database initialization succeeds. Its independent Java 11/MIT SDK exposes immutable allowlisted summaries of network identity, currency precision, orders, wallets, claim assets and history. It provides no public rule-matching, currency creation, remote transfers or general trading writes. See market API quick start.
Queries return CompletableFuture; do not call join() or get() on the game thread or a Folia entity thread. Raw audit JSON, item bytes, execution tokens, licenses and recovery evidence are excluded; returned lists and nested objects are immutable. Schedule player, inventory, and menu work on the correct player context.
MarketCommittedEvent only reports committed purchases, supplies and auction wins. It is asynchronous and non-cancellable, carrying TradeSummary rather than raw JSON. Deduplicate using network ID and event ID, and schedule player work on its Entity Scheduler. Notifications can be delayed; historical entries from before startup are not replayed. This is not exactly-once or reliable catch-up delivery; query authoritative state.