diff --git a/projects/CompanionPets/README.md b/projects/CompanionPets/README.md index 7251b1e..5c6c704 100644 --- a/projects/CompanionPets/README.md +++ b/projects/CompanionPets/README.md @@ -18,9 +18,10 @@ for runtime, build, and validation conventions. - [Pet types and ModelEngine](docs/models.md) — bodies, eggs, animation clips, and model authoring - [Staff commands](docs/staff.md) — commands, permissions, and audit +- [Character ownership, migration and estates](docs/ownership.md) - [Saved data and recovery](docs/saved-data.md) — persistence files, backups, and recovery after a failed save -- [Testing](docs/testing.md) — automated coverage and the dev-only Paper helper +- [Testing](docs/testing.md) — automated coverage and isolated Paper fixtures - [Default configuration](https://github.com/TF-Minecraft/CompanionPets/blob/main/src/main/resources/config.yml) - [Plugin commands and permissions](https://github.com/TF-Minecraft/CompanionPets/blob/main/src/main/resources/plugin.yml) @@ -29,17 +30,19 @@ for runtime, build, and validation conventions. Build the source repository with Java **21** and Maven: ```sh -mvn clean verify +python3 ../tlibs/tools/install-plugins.py --pom pom.xml --mode pinned +tfmc-mvn -o -B clean verify python3 .github/scripts/plugin-artifact.py --jar target/companionpets-main-SNAPSHOT.jar --version main-SNAPSHOT ``` The build uses `io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT` with -`provided` scope. No private jars or shared TFMC plugin artifacts are required. +`provided` scope. TLibs 2.6.0 is a provided shared plugin dependency; no private jars are required. The plugin entry point is `net.tfminecraft.companionpets.PetsPlugin`. -The descriptor soft-depends on MythicMobs, ModelEngine, ItemsAdder, MMOItems, and -MythicLib so that they load first when installed; none of them is required. The -plugin calls their APIs by reflection: MythicMobs and ModelEngine supply bodies +The descriptor requires TLibs and soft-depends on RPCharacters, MythicMobs, ModelEngine, ItemsAdder, MMOItems, and +MythicLib so that they load first when installed. Property actions need a ready +character provider. The optional presentation/item integrations use reflection: +MythicMobs and ModelEngine supply bodies and models (`integration/`), and MMOItems and ItemsAdder supply interaction items and eggs (`item/ItemBridge.java`). MythicLib is only a load-order dependency. CompanionPets has no runtime dependency on Archaeo, Cooking, or MCPets. @@ -51,11 +54,11 @@ verification; the `coverage` profile is only a compatibility alias. ## Testing on a Paper server -The source repository includes a dev-only -[integration helper](docs/testing.md#paper-integration-helper) -that runs once against a real Paper server with the configured providers and -reports `COMPANIONPETS_INTEGRATION PASS` or `FAIL` in the log. It does not -establish correct rendering in a Minecraft client. +The source repository includes an +[isolated ownership fixture](docs/testing.md#isolated-paper-character-ownership-fixture) +that runs against a fresh loopback Paper server and reports `OWNERSHIP_PROOF PASS` +or `FAIL`. It proves native follow/session isolation; client rendering needs a +separate in-game check. ## Builds and releases diff --git a/projects/CompanionPets/docs/ownership.md b/projects/CompanionPets/docs/ownership.md new file mode 100644 index 0000000..daf4a32 --- /dev/null +++ b/projects/CompanionPets/docs/ownership.md @@ -0,0 +1,51 @@ +# CompanionPets character ownership + +[CompanionPets](../README.md) · [Saved data](saved-data.md) + +Pets and Pet Houses belong to a character. The account UUID remains routing metadata for Minecraft's tame owner and account capacity limits. Switching characters ends hatch/rename/release prompts, training, greetings and fetch work; an inactive character's pet does not follow, teleport to or deliver a fetched toy to the new character. Native swimming, self-defense and safety goals remain available. When `native-combat` is enabled, the two native owner-assist goals require the recorded current owner character; another character on the same account cannot trigger that pet's assistance. + +The configured total-pet and outside-pet limits are account-wide. Character rosters show only that character's pets. Hatching, management and new Pet House ownership require a ready character session. Missing identity services refuse property actions. + +Carer recognition uses character IDs; changing character does not borrow another character's trust. Pet friendships use pet IDs. Inheritance retains physiology, bond, tricks, favourite toy, pet friendships and the original character identities of human memories. + +## Dependencies and compatibility + +The build pins TLibs **2.6.0**. RPCharacters supplies ready character sessions and reviewed legacy heirs. New API classes are capability-probed: an older or absent identity API leaves property actions unavailable; an absent estate API leaves ownership with the existing character. Upgrade provider and consumer JARs through a server restart. Plugin reload tools are not supported. + +## Legacy ownership migration + +After the reviewed legacy-heir directory is ready, each account-owned pet and Pet House receives that account's single reviewed heir. A dead reviewed heir remains the recipient; its estate decides any subsequent inheritance. No active-character or last-played fallback is used. + +`ownership-migrations/plan-NNNN.original.yml` is an immutable, verified source copy. `plan-NNNN.yml` contains the original/planned hashes, exact planned bytes and completion marker. These precede the forced file replacement and synchronization of its directory ancestry. Restart retries the stored recipient; conflicting source edits are held for review. Later migration passes may resolve previously missing heirs. + +Unknown owners remain inaccessible, retain their saved records and still count toward account limits. Unresolved human-carer pages remain under `legacy-carers` and are inert without freezing an otherwise assigned pet. Root, nested pet, relationship and Pet House metadata survive ordinary saves and restart, including unknown null-valued fields. Unsupported, quoted, null or fractional ownership schema versions, duplicate YAML keys and duplicate Pet House coordinates are refused without rewriting the source. No legacy files are automatically deleted. + +## Estates + +The `companionpets` estate participant describes pets and Pet Houses for wills. It uses the estate's property recipient. WAITING and FROZEN property stays with the testator. Moving ownership preserves pet/entity IDs and saved gameplay state; inherited overflow is retained. + +`estates/-.yml` records the exact decision, source/recipient account and character, pet/house IDs and completed receipts. Settlement requires the matching death, revision and decision immediately before publication. The participant reconciles at startup and hourly. It waits for this startup's reviewed migration and healthy persistence before creating estate intents; delayed heir readiness cannot seal an empty transfer. An unresolved legacy owner slot on the testator account blocks settlement until staff review resolves its heir; resolved pets retain their normal character authority. Completed IDs remain receipts; repeated settlement does not duplicate pets. A completed receipt that conflicts with remaining testator holdings is BLOCKED for a reviewed new revision, including old empty receipts after late heir resolution. Previously completed IDs that reappear under the testator are held for source/receipt reconciliation and are never transferred again automatically. A stale partial, malformed or conflicting intent is BLOCKED for staff review. Preserve its journal and current save before resolving it. + +## Stopped-server rollback + +Stop the server cleanly and preserve the complete CompanionPets directory, including deletion/estate journals and the latest progress. Install Python with PyYAML for the source repository tool: + +```sh +python3 tools/ownership-rollback.py /path/to/plugins/CompanionPets plan-0001 +python3 tools/ownership-rollback.py /path/to/plugins/CompanionPets plan-0001 --apply +``` + +The first command previews. Applying is accepted only while the current file exactly matches the migration's planned hash and the immutable archive verifies. `pets.pre-rollback.yml` preserves the current file. Any gameplay, estate or later migration changes produce a conflict; reconcile them manually rather than overwriting them. Never remove `pet-deletions.log` to resurrect deleted pets. + +An older JAR alone is not a rollback: it cannot enforce character ownership and +discards unknown fields during saves. Once `pets.yml` has changed, the migration +tool refuses rollback. Stay on the character-aware JAR and fix forward, or review +the care, grants, item state and estates that would be lost before restoring a +complete pre-upgrade snapshot and its corresponding JAR while stopped. There is +no automatic conversion of later character data into the old format. + +## Verification boundaries + +Unit tests exercise character isolation, captured callbacks, reviewed-heir mapping, unknown-field preservation, durable failure/replay and exact estate-intent guards. The loopback-only Paper ownership fixture exercises the actual native FOLLOW_OWNER selector across same-account character switches, water and training transitions; see [testing](testing.md). + +Ownership/queue commits and player inventory are separate transactions. Existing egg consumption and physical toy/world effects do not establish arbitrary-crash exactly-once delivery. Preserve the recovery marker, saved carried-toy state and world evidence after interruption; ambiguous effects need staff reconciliation. diff --git a/projects/CompanionPets/docs/saved-data.md b/projects/CompanionPets/docs/saved-data.md index 139948a..3a64b3f 100644 --- a/projects/CompanionPets/docs/saved-data.md +++ b/projects/CompanionPets/docs/saved-data.md @@ -16,9 +16,11 @@ plugin stops. Each save writes a temporary file and replaces the main file; | `pets.yml.bak` | The previous valid save. Never activated automatically. | | `pet-deletions.log` | Durable journal of terminal deletions. | | `pets-recovery-required` | Marker present while the plugin runs; removed after a successful final save. | +| `ownership-migrations/` | Immutable source copies, planned ownership bytes and completion receipts. | +| `estates/` | Exact death/revision ownership intents and cumulative transfer receipts. | | `staff-audit.yml.log` | Private log of [staff interventions](staff.md#audit). | -Back up all these files together before manually editing saved data. +Back up all these files together before manually editing saved data. Character ownership, migration and stopped-server rollback are described in the [ownership guide](ownership.md). External edits during a writer session are detected and held instead of overwritten. ## Damaged or missing saves diff --git a/projects/CompanionPets/docs/staff.md b/projects/CompanionPets/docs/staff.md index 16dc95a..144b2bd 100644 --- a/projects/CompanionPets/docs/staff.md +++ b/projects/CompanionPets/docs/staff.md @@ -10,9 +10,10 @@ root aliases. Running `/companionpets` shows help and examples. | `reload` | Reload config and refresh models. Provider problems are logged automatically. | | `moment ` | Trigger a moment while looking at your pet; normal care and animation conditions apply. | | `testpet [name...]` | Spawn a normal pet with every compatible trick learned. No special marker, pause state or cleanup category. | -| `list [pet name...]` | Open that player's pets or a selected pet's read-only profile. Console gets readable names. | -| `find [pet name...]` | Show Pet House, current or last-known location, and missing or duplicate bodies for that player's pets, without loading chunks. | -| `create type= name= [option=value ...]` | Create a new saved replacement in the owner's Pet House. | +| `list unassigned` | Show pets and Pet Houses held for ownership review without assigning them. | +| `list [pet name...]` | Open that character's pets or a selected pet's read-only profile. Console gets readable names. | +| `find [pet name...]` | Show Pet House, current or last-known location, and missing or duplicate bodies for that character's pets, without loading chunks. | +| `create type= name= [option=value ...]` | Create a new saved replacement in the owner's Pet House. | | `egg [online-player] [1..64]` | Give configured eggs; omit the recipient in game to receive them yourself. | ```text @@ -25,18 +26,20 @@ root aliases. Running `/companionpets` shows help and examples. /companionpets moment belly ``` -## Browsing players and pets +## Browsing characters and pets -Tab completion suggests player names first, then only that player's pet names. -Names can contain spaces. Duplicate pet names are never resolved arbitrarily: +Tab completion suggests owning characters' display names, then that character's +pet names. Creation also offers online account names. The character argument is +one token: use its character UUID when its name contains spaces or is ambiguous. +Pet names can contain spaces. Duplicate pet names are never resolved arbitrarily: select the pet from `list` to view its identity internally. There is no player -inventory: select the owner using command completion. +inventory. The selected pet's staff inventory shares the normal pet profile: species, name, sex, age, needs, bond, personality, favourite toy and learned tricks. It is read-only, including its trick inventory; renaming, calling, Pet House and -release actions are omitted. No UUIDs or audit snapshots are required or shown -in command help, completion or pet cards. Menu layout and navigation are +release actions are omitted. Character UUIDs can identify owners in commands; +pet cards do not expose audit snapshots. Menu layout and navigation are described in the [gameplay guide](gameplay.md#menus). ## Creating pets @@ -55,8 +58,7 @@ addition to configured default tricks. `tricks=all` teaches every compatible enabled trick; `tricks=none` adds no extra tricks. Defaults: needs 100, bond 0, male, new age, generated personality. -An explicitly supplied owner UUID is still accepted for reconstruction of an -unknown or offline player; ordinary browsing and completion use player names. +Specify a known character UUID or a unique single-token living character name. Dead character UUIDs are available for inspection; creation requires a living character. An online account name selects its current ready character. Unknown and ambiguous characters are refused; an arbitrary account UUID cannot create property. Creation validates options before writing and checks Pet House capacity. The owner takes the created pet out through their Pet House menu. diff --git a/projects/CompanionPets/docs/testing.md b/projects/CompanionPets/docs/testing.md index ebe9eea..b72248a 100644 --- a/projects/CompanionPets/docs/testing.md +++ b/projects/CompanionPets/docs/testing.md @@ -19,7 +19,34 @@ compatibility alias; ordinary verification already enforces the same gate. These tests do not establish live Paper behaviour or correct client rendering. -## Paper integration helper +## Isolated Paper character ownership fixture + +Build the verified plugin into the local Maven repository, then build the +[loopback ownership probe](https://github.com/TF-Minecraft/CompanionPets/tree/main/integration-tests/ownership): + +```sh +tfmc-mvn -o -B clean install +tfmc-mvn -o -B -f integration-tests/ownership/pom.xml clean package +``` + +Run only in a fresh disposable Paper 1.21.10 server with TLibs 2.6.0, loopback +address `127.0.0.1`, port `25583` and offline mode. Connect `S6PetProbe` using an +offline protocol client. The probe registers a synthetic character provider; +never install it on Main or Dev. It checks actual native follower movement for A, +same-account A→B isolation, active training cleanup, real native owner-assist goals under `native-combat: true`, swimming/self-defense safety, held/unknown +owners and reattachment. It writes +`plugins/CompanionPetsOwnershipProbe/result.json`, logs +`OWNERSHIP_PROOF PASS` only after every check, and stops its disposable server. +Its README documents setup and the actual older-TLibs classloader check. + +## Legacy provider integration helper + +The broader helper below predates character ownership. CI retains its compilation +gate, but its random account/proxy-player and raw native follower fixtures need a +character-aware update before it can validate current ownership. Use the isolated +ownership probe above for character isolation evidence. + + The [helper source](https://github.com/TF-Minecraft/CompanionPets/tree/main/integration-tests) runs once, starting 240 server ticks after enabling, then disables itself when