From 400f3b7c4ff3dba5cc1dfdbe41100d4f4d08e4bd Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Mon, 12 Oct 2026 18:39:21 +0000 Subject: [PATCH 1/2] docs: explain recoverable node payments and character death lookup --- projects/Dowsing/README.md | 6 +++--- projects/Dowsing/overview.md | 17 +++++++++++++++-- projects/TLibs/character-identity.md | 8 +++++++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/projects/Dowsing/README.md b/projects/Dowsing/README.md index eb44c64..487afac 100644 --- a/projects/Dowsing/README.md +++ b/projects/Dowsing/README.md @@ -10,14 +10,14 @@ TFMC runs Minecraft **1.21.10**. See the [shared platform and build baseline](.. Dowsing builds with Java **21** against `io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT`. Install the pinned TLibs -`2.0.0`, SimpleFactions `3.0.1`, DenarEconomy `0.2.4`, and Magic `0.2.0` release +`2.4.0`, SimpleFactions `4.0.0`, DenarEconomy `0.3.0`, and Magic `0.2.0` release artifacts with the shared dependency installer. The build also prepares checksum-verified ItemsAdder, MMOItems, MythicLib, and json-simple inputs from the private ServerAssets repository. -DenarEconomy supplies API types exposed by SimpleFactions bank signatures. +DenarEconomy stores guild treasury payments and their operation IDs. -At runtime, `plugin.yml` requires TLibs, SimpleFactions, MMOItems, MythicLib, +At runtime, `plugin.yml` requires TLibs, DenarEconomy, SimpleFactions, MMOItems, MythicLib, and ItemsAdder. Magic is optional; configured Magic artifact paths are only resolved when that plugin is present. diff --git a/projects/Dowsing/overview.md b/projects/Dowsing/overview.md index 7e8b6c7..40b97a8 100644 --- a/projects/Dowsing/overview.md +++ b/projects/Dowsing/overview.md @@ -73,8 +73,21 @@ node. - Purchased guild capacity is stored in `plugins/Dowsing/guild_capacity.json`. -On a normal plugin disable, Dowsing rewrites the node JSON files and saves guild -capacity. Back up the complete `plugins/Dowsing/` directory before changing +Dowsing waits for `SimpleFactionsApi.ready()` before loading nodes, starting their +timers or saving owners. A temporary unavailable faction lookup never clears an +owner. Guild access uses the player's active character, and leader names use the +character directory. + +Upgrades, downgrades and capacity purchases write `node-payment.json` before +posting to the guild's immutable treasury account. The journal contains the +operation ID, guild incarnation, node and exact target level/capacity. Recovery +reuses that posting, saves the target state, then marks the journal complete. +Unknown owners, conflicting state or failed writes pause node changes and preserve +the journal for staff; inspect it alongside DenarEconomy's operation before making +any repair. Never delete an unresolved journal just to re-enable purchases. + +On a normal plugin disable after successful startup and payment recovery, Dowsing +saves the node JSON files before pruning removed nodes and saves guild capacity. Back up the complete `plugins/Dowsing/` directory before changing identifiers or migrating configuration, and stop the server cleanly before copying live state. diff --git a/projects/TLibs/character-identity.md b/projects/TLibs/character-identity.md index 635fded..7339aeb 100644 --- a/projects/TLibs/character-identity.md +++ b/projects/TLibs/character-identity.md @@ -41,6 +41,7 @@ caller. | `currentSession(Player)` | The session being played now, or empty. | | `isCurrent(CharacterSession)` | Whether that session is still being played. It turns false when the session ends and never turns true again. | | `info(UUID characterId)` | Any character, online or offline, or empty if unknown. | +| `deathId(UUID characterId)` | Most recent saved death ID, including after revival; empty when unknown. | | `characters(UUID ownerId)` | Every character on the account, as an immutable copy. Empty means the records could not be read; an empty list means the account has none. | | `lastPlayed(UUID ownerId)` | The character the account played most recently, dead or alive. | | `displayName(Player)` | The name other players see now, including masks and aliases. | @@ -73,7 +74,12 @@ still clean up against it. fires only after the death has been saved, and does not fire if the save fails. `killerId` and `killerCharacter` may be null; a killer character always belongs to `killerId`. Delivery is not durable: a crash between the save and the event loses -it. Consumers must be idempotent by `deathId`. +it. Consumers must be idempotent by `deathId`. Since TLibs 2.4.1, they can reconcile +`DEAD` characters through `Characters.deathId(characterId)` after restart. The +interface has an empty default for older providers. RPCharacters preserves each +saved ID across revival and assigns a new one for the next death. Older deceased +records without a saved ID use a deterministic legacy key based on their character +UUID; a later saved death supersedes that key. None of these events can be cancelled. From 840d74a63dfd651e83e6058e500536023731a3ff Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Mon, 12 Oct 2026 18:54:58 +0000 Subject: [PATCH 2/2] docs: explain character theft and consumer API pins --- projects/ActivityTF/README.md | 4 +++ projects/Cooking/README.md | 2 +- projects/TFMCCore/README.md | 4 +++ projects/Thievery/docs/SYSTEM.md | 44 +++++++++++++++++++++------ projects/Thievery/docs/TEST_MATRIX.md | 7 +++-- projects/Thievery/docs/testing.md | 9 +++++- 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/projects/ActivityTF/README.md b/projects/ActivityTF/README.md index 8b3cd0d..782bdfc 100644 --- a/projects/ActivityTF/README.md +++ b/projects/ActivityTF/README.md @@ -17,6 +17,10 @@ Optional runtime integrations are declared as `softdepend` in `src/main/resource - [Reward pools and operator checks](REWARD-POOLS.md) - [Activity descriptions, placeholders and config updates](ACTIVITY-LORE.md) +The POM pins TLibs **2.4.1** and SimpleFactions **4.0.0**. Battle participation +remains an account UUID integration; the character migration preserves that +event contract. + ## Builds and releases See the [shared pipeline guide](../../PIPELINES.md) for development artifacts, release tags, and dependency access. diff --git a/projects/Cooking/README.md b/projects/Cooking/README.md index 3118cf9..7c5b318 100644 --- a/projects/Cooking/README.md +++ b/projects/Cooking/README.md @@ -16,7 +16,7 @@ Use JDK 21, install the matching TLibs Maven artifact (`me.plugins:tlibs`, versi ## Runtime and configuration -The plugin registers food item paths with TLibs and integrates furniture stations, TLibs inventory scanning, crops and husbandry. The manifest requires TLibs and InteractibleFurniture, and the POM pins TLibs 2.3.0 and RPCharacters 2.16.0; RPCharacters, MMOCore, CustomCrops, SimpleFactions and CustomFishing enable additional integrations. `/cooking` requires `cooking.admin` (op by default). Nutrition follows the shared ready character session and needs RPCharacters 2.16.0 or newer. The guides below define nutrition, crop and husbandry behaviour and their configuration boundaries. +The plugin registers food item paths with TLibs and integrates furniture stations, TLibs inventory scanning, crops and husbandry. The manifest requires TLibs and InteractibleFurniture, and the POM pins TLibs 2.4.1, SimpleFactions 4.0.0 and RPCharacters 2.16.0; RPCharacters, MMOCore, CustomCrops, SimpleFactions and CustomFishing enable additional integrations. `/cooking` requires `cooking.admin` (op by default). Nutrition follows the shared ready character session and needs RPCharacters 2.16.0 or newer. The guides below define nutrition, crop and husbandry behaviour and their configuration boundaries. ## Guides diff --git a/projects/TFMCCore/README.md b/projects/TFMCCore/README.md index ab09a83..ba7f758 100644 --- a/projects/TFMCCore/README.md +++ b/projects/TFMCCore/README.md @@ -13,6 +13,10 @@ TFMC runs Minecraft **1.21.10**. See the [shared platform and build baseline](.. - [Statistics configuration and commands](src/main/java/net/tfminecraft/tfmccore/stats/STATS.md) - [Player commands](src/main/java/net/tfminecraft/tfmccore/tfmc/TFMC.md) +The POM pins TLibs **2.4.1** and SimpleFactions **4.0.0**. Battle participation +remains an account UUID integration; the character migration preserves that +event contract. + ## Builds and releases See the [shared pipeline guide](../../PIPELINES.md) for development artifacts, release tags, and dependency access. diff --git a/projects/Thievery/docs/SYSTEM.md b/projects/Thievery/docs/SYSTEM.md index d70393f..ccb0f4f 100644 --- a/projects/Thievery/docs/SYSTEM.md +++ b/projects/Thievery/docs/SYSTEM.md @@ -27,16 +27,40 @@ current and that the robber still has a robbery trait; otherwise the request expires. Switching away and back to the same character starts a new session, so it also expires the request. When either player's session ends by switching, death, quitting or shutdown, the robber stops targeting and pending requests -expire, with a message to the other player. An accepted robbery is not tied to -sessions and ends through the robbery's own quit handling. - -The build pins TLibs **2.3.0** and RPCharacters **2.16.0**. With an older TLibs -that lacks the character API, Thievery still starts and logs a warning. Lock, -door and container protection keeps working; every action with a nonempty trait -list is denied, and pending robbery requests are checked only on acceptance. -RPCharacters remains a required dependency for clues, graves and evil-RP -rewards. Account-owned locks, risk, cooldowns and saved data keep their format -and ownership. +expire, with a message to the other player. An accepted robbery ends through its +own quit handling. Pouch transfers still require both captured sessions to be +current; switching characters never redirects the transfer to another pouch. + +The build pins TLibs **2.4.0**, RPCharacters **2.16.0**, SimpleFactions **4.0.0** +and DenarEconomy **0.3.0**. RPCharacters remains required for clues, graves and +evil-RP rewards. Protected guild access and theft cooldown checks deny access +while factions or reviewed heirs are unavailable. + +## Character money and guild access + +Pouch clicks transfer whole cents between the captured victim and robber using +one ledger posting. Before posting, Thievery forces a record under +`plugins/Thievery/pouch-payments/.properties` and its directories to disk. +The record contains the operation ID, both character IDs, cents and budget cost. +Only `APPLIED` consumes budget. A retry reuses the pending operation and its +original amount; a repeated event never transfers or consumes budget twice. +An unavailable ledger or an unsavable record changes neither pouch nor budget. + +Robbery sessions end on restart, and these records remain as an audit trail. +A ledger result is authoritative: look up its `thievery:robbery:` operation +before investigating a disputed payment. Startup does not issue another payment +or resume a closed robbery. Pouch transfers move no physical coin items. + +Guild lookups use the active character. Guild cooldowns map character members +back to their account UUIDs and retain existing account-wide history. Offline +lock owner guild checks and `LockAccess` ownership checks use the account's +reviewed legacy heir; a different active character does not inherit those access +rights. Online guild checks require the relevant member character to be active. + +Lock files, owner controls, risk and cooldown storage remain account-based until +stage 6. This includes owner toggles, shared-key and automation paths; this stage +does not claim full character isolation for physical locks. Existing guild target +keys retain their cooldown history. ## Responsibilities diff --git a/projects/Thievery/docs/TEST_MATRIX.md b/projects/Thievery/docs/TEST_MATRIX.md index 7ffcd41..89a0ef8 100644 --- a/projects/Thievery/docs/TEST_MATRIX.md +++ b/projects/Thievery/docs/TEST_MATRIX.md @@ -6,7 +6,8 @@ Run these checks on Minecraft **1.21.10** with the intended plugin dependencies ## Regression -With TLibs **2.3.0** and RPCharacters **2.16.0**, check a restricted command, +With TLibs **2.4.0**, RPCharacters **2.16.0** or newer, SimpleFactions **4.0.0** +and DenarEconomy **0.3.0**, check a restricted command, container lockpick and display lockpick while the character is loading, after loading a character with the required trait, and after switching to one without it. Only the matching ready character should pass the trait restriction. Switch @@ -156,7 +157,9 @@ ItemsAdder must not grant inspection access. | M3 | `/robbery start` + accept: GUI slot 8 (top-right) shows pouch when victim balance > 0 and thief has `money` | | M4 | Slot 8 left-click takes up to `pouch-click-amount` (10); shift-left up to `pouch-shift-amount` (100) | | M5 | Pouch take capped by victim balance, remaining budget (`floor(remaining / amount_per_money)`), and config amounts | -| M6 | Pouch debits victim DenarEconomy pouch, credits robber pouch (not coin items); GUI title budget updates | +| M6 | Pouch debits the captured victim character, credits the captured robber character; only an applied transfer updates the budget | +| M7 | Repeat one payout attempt after ledger failure: reuse its operation ID and amount, charge budget once; a closed ledger or unwritable payment folder takes nothing | +| M8 | Switch either character after acceptance: no transfer from the new character; faction waiting grants no protected access | | M7 | Without `money` in loadout: slot 8 is filler; coins in shuffled grid stay hidden | | M8 | Victim with 7 denars: single click takes 7 | | M9 | Grave steal **without** `money`: coins in grave are skipped; message "nothing you can steal" if only coins | diff --git a/projects/Thievery/docs/testing.md b/projects/Thievery/docs/testing.md index c7c2e12..576c6c3 100644 --- a/projects/Thievery/docs/testing.md +++ b/projects/Thievery/docs/testing.md @@ -5,7 +5,7 @@ with Java 21 and the pinned dependencies prepared according to the [shared build guide](../../../PIPELINES.md#build-dependencies): ```sh -mvn -B --no-transfer-progress clean verify +tfmc-mvn -o -B --no-transfer-progress clean verify python3 .github/scripts/check-test-reports.py ``` @@ -25,6 +25,13 @@ listeners register while trait checks deny. Robbery tests cover requests made as one character and accepted after switching away and back, and pending requests expiring when either session ends. +Pouch payment tests use real temporary SQLite files for balanced transfers, +ledger reopen, a committed payment with a lost reply, insufficient funds and +stale sessions. Handler tests repeat the same click, retry unavailable payments, +and verify that unsavable intents consume no budget. Identity tests check +reviewed-heir ownership, another character on the same account, faction waiting, +and member-to-account cooldown mapping. + Hands-up inspection tests exercise consent, independent item copies and live refresh, full-view click and drag cancellation, creative inventory events, robbery/pickpocket event ordering, range and visibility checks, cancelled opens,