Skip to content

Stage 6a: character vehicle owners - #162

Merged
ryanbarlow97 merged 8 commits into
mainfrom
stage6/vehicle-owners
Oct 13, 2026
Merged

ryanbarlow97 merged 8 commits into
mainfrom
stage6/vehicle-owners

Conversation

@ryanbarlow97

@ryanbarlow97 ryanbarlow97 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Stage 6a part B for SimpleFactions: vehicles are owned by characters through VehicleFramework 2.13's ownership API. Stacked on #161 (part A, lockGuild); both ship together as SimpleFactions 4.1.0.

Vehicle stage. Factions no longer wait for VehicleFramework. startVehicles() runs once, after started = true or when VehicleFramework enables (a once-guard covers VehicleFramework enabling inside SimpleFactions' own enable window): payer migration, the one-time owner migration, the leader reconcile, the upkeep reconcile, the vehicle listeners, and last the VehicleOwnershipAuthority. Steps 1–2 failing keep today's failFinancialState; steps 3–4 failing stop before listeners and authority. The construction freeze and registration fee still hook in early. Without VehicleFramework 2.13 in characters mode only the payer migration and listeners run, non-staff claims are refused, and upkeep is charged from registry rows.

Owner migration (vehicles/owner-migration.json). The plan records originals and decided values and is synced before fixed-name backups (vehicles-6a-premigration.db via VACUUM INTO + quick_check, vehicles_registry-6a-premigration.json); a !backedUp plan resumes at the backup. Apply is conditional (planned new → done, original → setOwnership(MIGRATE), anything else → quarantine, gone → counted, SAVE_FAILED/REFUSED_MODE → abort), then stored and live copies are verified separately. Seeding: personal rows need a round-tripping name whose account plays the row's character; faction rows get the paying faction's leader character or char_none; rows-less vehicles get the round-tripped account's heir; everything else is quarantined and listed through VehicleQuarantineSource.

Ownership changes. At HIGH, non-staff changes to faction vehicles are refused (both toggles included) and claims need a character, ready payments and a free per-account slot; at HIGHEST the transfer fee is confirmed and charged under VehicleFramework's operation ID. The payer row is written once from VehicleOwnershipChangedEvent; failed claims are refunded; staff takeovers record the target character with no fee and an audit line. SimpleFactions' handlers on VehicleOwnerClaimedEvent are gone (the VehicleRemoveEvent one stays). Every SimpleFactions owner write (construction, spawn sync, berth/pool, installation transfer incl. stored vehicles, release, handover, restamps) goes through setOwnership, registry first and rolled back on failure. Construction stamps the registration-fee payer and holds the vehicle at char_none for staff if VFBuilders' constructor character (or the old station's heir) differs.

Vehicles on the staff list (migration quarantine, construction mismatches, constructions whose stamp could not be written) are held: players cannot change them and leader stamps leave them alone until staff assign an owner. Builds start only once the vehicle stage has finished in characters mode.

Leader stamps. Faction.setLeader/succeedDeadLeader fire FactionLeaderChangedEvent; the restamp handler waits for the stage; FactionManager.deleteFaction restamps leftover rows to char_none; a LOWEST VehiclePreInteractEvent backstop and the edit check refuse stale stamps and restamp on the next tick.

Upkeep reconcile at boot and daily, per-account slot limits with the account cached on rows (backfilled from characters and both migration plans), and consent requests capturing both characters.

Name round trip. A legacy owner name counts when it is still the account's latest name: Bukkit's name for the account, or, once the user cache has forgotten it, the name DenarEconomy remembered last in its durable player-names.json.

Rollback. VehicleOwnerRollback (run with the server stopped) restores only the owner column and payload owner/whitelisted/whitelist of rows still holding the migration's values, moves the plan aside, and writes a refund list of claim/build/handover fees paid since the plan was made. It needs Gson 2.10+ and sqlite-jdbc and refuses an older Gson up front.

Docs: TF-Minecraft/Docs#211

Gate: tfmc-mvn -o -B clean verify — 7,913 tests, 0 failures, 100% line coverage. CI will 404 on the unreleased VehicleFramework 2.13.0 / VFBuilders 2.2.0 until they are released.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 101 files, which is 1 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7b9f6512-eb04-4d12-9290-27d5d7ca2f41
📥 Commits

Reviewing files that changed from the base of the PR and between 98dab33 and b4fb94a.

📒 Files selected for processing (101)
  • pom.xml
  • src/main/java/net/tfminecraft/simplefactions/SimpleFactions.java
  • src/main/java/net/tfminecraft/simplefactions/events/FactionLeaderChangedEvent.java
  • src/main/java/net/tfminecraft/simplefactions/identity/death/LockGuildIndex.java
  • src/main/java/net/tfminecraft/simplefactions/installation/InstallationTransferService.java
  • src/main/java/net/tfminecraft/simplefactions/managers/FactionManager.java
  • src/main/java/net/tfminecraft/simplefactions/managers/inventory/InstallationView.java
  • src/main/java/net/tfminecraft/simplefactions/objects/Faction.java
  • src/main/java/net/tfminecraft/simplefactions/objects/request/VehicleGiveConsentRequest.java
  • src/main/java/net/tfminecraft/simplefactions/objects/request/VehicleHandoverRequest.java
  • src/main/java/net/tfminecraft/simplefactions/objects/request/VehicleTransferConsentRequest.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/VehicleIntegrationListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/battle/BattleVehicleEligibilityService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/FactionVehicleGiveService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/FactionVehicleReleaseListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/FactionVehicleReleaseMessages.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/FactionVehicleReleaseService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/InstallationVehicleOwnerSync.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/InstallationVehicleService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/InstallationVehicleUnberthService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleConstructionMessages.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleSlotGuard.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleTransferConsentService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleTransferListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/fees/VehicleFeeMessages.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/fees/VehiclePayments.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/fees/VehicleReclaimFeeListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/fees/VehicleRegistrationFeeListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/handover/VehicleHandoverListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/handover/VehicleHandoverService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleSettlement.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleUpkeepProjection.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/ConstructionStamp.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/LeaderStamps.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/OwnerFields.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/OwnerMeta.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/OwnerTags.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleClaimsOff.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerApi.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerMigration.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerRollback.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerWrites.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnershipGate.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnershipServices.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleQuarantine.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleUpkeepReconcile.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/owners/VfOwnerApi.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/pool/FactionVehiclePoolService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/PlayerVehicleRecord.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/RegistryAccounts.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleOwnershipQueries.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/VehiclePayerMigration.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleRegistryClaimListener.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleRegistryClaimService.java
  • src/main/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleRegistryPersistence.java
  • src/main/java/net/tfminecraft/simplefactions/war/freeze/VfBuildersConstructionFreeze.java
  • src/test/java/net/tfminecraft/simplefactions/PluginLifecycleCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/identity/death/LockGuildIndexTest.java
  • src/test/java/net/tfminecraft/simplefactions/installation/InstallationProtectionCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/installation/handler/InstallationLifecycleCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/managers/RequestLifecycleCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/managers/RequestManagerDeclineTest.java
  • src/test/java/net/tfminecraft/simplefactions/managers/inventory/InstallationMenusCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/objects/request/VehicleTransferConsentRequestTest.java
  • src/test/java/net/tfminecraft/simplefactions/testsupport/VehicleOwnersReset.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/FactionVehicleGiveServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/FactionVehicleReleaseServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/InstallationVehicleOwnerSyncTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/InstallationVehicleServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/InstallationVehicleUnberthServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleInteractionsCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleSlotGuardTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleTransactionBoundaryCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/berth/VehicleTransferConsentServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/fees/VehiclePaymentsTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/handover/VehicleHandoverServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleRuntimeLifecycleCoverageTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleSettlementTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleUpkeepProjectionTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleUpkeepServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/ConstructionStampTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/FakeOwnerApi.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/LeaderStampsTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/OwnerTagsTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleClaimsOffTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerMigrationTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerRollbackTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnerWritesTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnershipGateTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleOwnershipServicesTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleQuarantineTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/owners/VehicleUpkeepReconcileTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/pool/FactionVehiclePoolServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/registry/FakeOwnedInventory.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/registry/RegistryAccountsTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleOwnerKeysTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleOwnershipQueriesTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/registry/VehiclePayerMigrationTest.java
  • src/test/java/net/tfminecraft/simplefactions/vehicles/registry/VehicleRegistryClaimServiceTest.java
  • src/test/java/net/tfminecraft/simplefactions/war/freeze/VfBuildersConstructionFreezeTest.java
  • src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the size:XXL 1,000+ effective changed lines (tests excluded in mixed PRs). label Oct 13, 2026
Base automatically changed from stage6/lock-guild to main October 13, 2026 10:03
ryanbarlow97 and others added 5 commits October 13, 2026 10:03
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vehicle work moves into a stage that runs once factions have started and
VehicleFramework is enabled: payer migration, the one-time owner migration
(plan, fixed-name backups, conditional apply, separate stored/live verify),
the leader and upkeep reconciles, the vehicle listeners and last the
VehicleOwnershipAuthority. Every SimpleFactions owner write goes through
VehicleFramework's setOwnership with the registry first and rolled back on
failure. SimpleFactions vetoes non-staff changes to faction vehicles,
charges claim fees under VehicleFramework's operation ID and records the
payer row once from the post-write event. Leader changes and faction
deletion restamp faction vehicles, with a click backstop. Slot limits count
personal rows per cached account. Consent requests capture both characters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Builds wait for the finished vehicle stage, a construction whose owner
cannot be written is held so nobody claims it, and vehicles held for
staff are never restamped or changed by players. Rollback also restores
pending entries of an interrupted plan and counts fees from when the plan
was made. Handover fees carry the offer time in their replayable intent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A legacy owner name now also round-trips through the name DenarEconomy
remembered last for the account when the server's user cache has
forgotten it, so expiring cache entries no longer quarantine personal
vehicles; a name the account has since replaced still fails. The rollback
tool names a too-old Gson (needs 2.10) or a missing sqlite-jdbc before it
starts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanbarlow97
ryanbarlow97 force-pushed the stage6/vehicle-owners branch from c0f2e63 to 2a3bf53 Compare October 13, 2026 10:03
@ryanbarlow97
ryanbarlow97 marked this pull request as ready for review October 13, 2026 10:03
@ryanbarlow97

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

ryanbarlow97 and others added 3 commits October 13, 2026 10:55
A pre-6a journal whose rights snapshot has a missing or non-array guild
list, a non-object guild, missing members or a blank or invalid
incarnation now gives that character no lock-guild entry instead of
failing the index rebuild.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Verification listed a DONE vehicle with neither a stored nor a live copy
by indexing an empty list; it now joins the torn-vehicle failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The refund is capped at the guild bank's balance. A short refund is now
logged with the shortfall and the player told what came back and what
did not, as the registration-fee cancel does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanbarlow97

Copy link
Copy Markdown
Contributor Author

Muse (independent reviewer) reviewed parts A (#161) and B (this PR) against the stage 6a design: verdict OK. Its three minor findings were valid and are fixed on this branch with tests:

  • fe04bfd: the lock-guild backfill gives a malformed pre-6a death journal no entry instead of throwing during indexing. This touches part A code.
  • 4e689fc: a migrated vehicle with neither a stored nor a live copy fails verification as torn, not with an IndexOutOfBoundsException.
  • b4fb94a: a partial claim-fee refund is logged and the player is told the shortfall.

Full gate at b4fb94a: 7,916 tests, 0 failures, 100% line coverage. Merging with admin rights: Muse's review replaces the CodeRabbit wait, because CodeRabbit's free quota was exhausted.

@ryanbarlow97
ryanbarlow97 merged commit 4717834 into main Oct 13, 2026
3 checks passed
@ryanbarlow97
ryanbarlow97 deleted the stage6/vehicle-owners branch October 13, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ effective changed lines (tests excluded in mixed PRs).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant