Skip to content

Resend player meta when LuckPerms permissions change - #36

Merged
ryanbarlow97 merged 4 commits into
mainfrom
fix/resync-meta-on-rank-change
Oct 11, 2026
Merged

ryanbarlow97 merged 4 commits into
mainfrom
fix/resync-meta-on-rank-change

Conversation

@ryanbarlow97

@ryanbarlow97 ryanbarlow97 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

A rank granted while a player is online never reached the website until they rejoined. On 11 October CaptainObviousXY linked Patreon at 16:33 UTC, got Gilded in game, and the site kept showing one wardrobe skin because TFMCWeb last sent his meta at his 16:23 join.

What changes

  • MetaResync subscribes to LuckPerms UserDataRecalculateEvent and GroupDataRecalculateEvent (when LuckPerms is installed). A user event rechecks that player 20 ticks later; a group event rechecks every online player. Repeats within that second share one check, and scheduling rejected during shutdown leaves nothing pending.
  • PlayerMetaSyncService.pushIfChanged skips the PUT when the resolved body equals the newest body already handed to the sender. LuckPerms 5.5.32 recalculates every online user and group on each storage sync (sync-minutes: 3 on Main and Dev), so without this every online player would be resent every three minutes. Join, reload and /web syncmeta still always send.
  • Sends for one player are attempted one at a time through a single drain task that always sends the newest queued body. A timed-out PUT can still be applied by the website after a newer one, so after a failed PUT unchanged bodies for that player are resent at each recalculation until one succeeds at least 10 minutes after the last failure. This repair is best effort and relies on the periodic LuckPerms sync.
  • LuckPermsRecalculateListener holds the only LuckPerms API references and is loaded by name, matching the rank writer and bridge.

LuckPerms 5.5.32 fires these events from setNode, unsetNode, temporary-node expiry and loadNodesFromStorage, so Patreon grants, staff-panel changes, /lp edits, rank-definition edits and changes synced from the other server are all covered.

Testing

  • mvn clean verify: 160 tests pass and JaCoCo's 100% line coverage check is met. New tests cover send ordering when the meta changes during an in-flight send, retry after a failed or throwing PUT, a fake-site late write after a timeout, group rechecks and shutdown rejection.
  • Not yet tested on a live server.

Docs: TF-Minecraft/Docs#141

🤖 Generated with Claude Code

A rank granted while a player was online (Patreon, staff panel or /lp)
never reached the website until they rejoined, because player meta was
only sent on join, reload and /web syncmeta. TFMCWeb now listens for
LuckPerms UserDataRecalculateEvent and resends that player's meta about
a second later. Those sends are skipped when nothing changed, since
LuckPerms recalculates every online player on each sync-minutes sync,
and a failed send is retried on the next recalculation.

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

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 43 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3fa1d4e0-22da-4aa2-870c-0ce6f3b63638

📥 Commits

Reviewing files that changed from the base of the PR and between c37cbd6 and 4b071a8.


📒 Files selected for processing (5)
  • src/main/java/net/tfminecraft/tfmcweb/entitlements/MetaResync.java
  • src/main/java/net/tfminecraft/tfmcweb/entitlements/PlayerMetaSyncService.java
  • src/main/java/net/tfminecraft/tfmcweb/luckperms/LuckPermsRecalculateListener.java
  • src/test/java/net/tfminecraft/tfmcweb/entitlements/EntitlementsTest.java
  • src/test/java/net/tfminecraft/tfmcweb/entitlements/MetaResyncTest.java

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 281d4c56-1393-4007-9edc-0ba58fdfa350




📥 Commits

Reviewing files that changed from the base of the PR and between 675a9f3 and c37cbd6.





📒 Files selected for processing (6)
  • src/main/java/net/tfminecraft/tfmcweb/TFMCWeb.java
  • src/main/java/net/tfminecraft/tfmcweb/entitlements/MetaResync.java
  • src/main/java/net/tfminecraft/tfmcweb/entitlements/PlayerMetaSyncService.java
  • src/main/java/net/tfminecraft/tfmcweb/luckperms/LuckPermsRecalculateListener.java
  • src/test/java/net/tfminecraft/tfmcweb/entitlements/EntitlementsTest.java
  • src/test/java/net/tfminecraft/tfmcweb/entitlements/MetaResyncTest.java




Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.






📝 Summary

Summary by CodeRabbit

  • New Features
    • Player metadata now syncs automatically after permission recalculations, with a short delay to ensure updates are ready.
    • Unchanged metadata is no longer sent again; failed syncs can be retried.
📝 Summary
📝 Summary
📝 Summary

Walkthrough

The plugin now listens for LuckPerms recalculations and schedules metadata checks for affected online players. Metadata updates skip unchanged payloads, while forced updates remain available. The plugin starts and stops the resynchronisation service with its lifecycle.

Changes

LuckPerms metadata resynchronisation

Layer / File(s) Summary
LuckPerms event subscription
src/main/java/net/tfminecraft/tfmcweb/entitlements/MetaResync.java, src/main/java/net/tfminecraft/tfmcweb/luckperms/LuckPermsRecalculateListener.java, src/test/java/net/tfminecraft/tfmcweb/entitlements/MetaResyncTest.java
MetaResync subscribes to recalculation events when LuckPerms is enabled. The listener forwards recalculated user UUIDs. Tests cover plugin availability, subscription behaviour and event forwarding.
Delayed, change-only metadata sync
src/main/java/net/tfminecraft/tfmcweb/entitlements/MetaResync.java, src/main/java/net/tfminecraft/tfmcweb/entitlements/PlayerMetaSyncService.java, src/test/java/net/tfminecraft/tfmcweb/entitlements/EntitlementsTest.java, src/test/java/net/tfminecraft/tfmcweb/entitlements/MetaResyncTest.java
MetaResync deduplicates UUIDs and checks player status after 20 ticks. PlayerMetaSyncService skips unchanged payloads for change-only pushes; failed requests can be retried. Tests cover scheduling, payload changes and retry behaviour.
Plugin lifecycle integration
src/main/java/net/tfminecraft/tfmcweb/TFMCWeb.java, src/main/java/net/tfminecraft/tfmcweb/entitlements/MetaResync.java, src/test/java/net/tfminecraft/tfmcweb/entitlements/MetaResyncTest.java
TFMCWeb starts the service on enable and stops it on disable. Stopping clears pending UUIDs and closes the subscription.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant LuckPerms
  participant LuckPermsRecalculateListener
  participant MetaResync
  participant BukkitScheduler
  participant PlayerMetaSyncService
  LuckPerms->>LuckPermsRecalculateListener: send recalculation event
  LuckPermsRecalculateListener->>MetaResync: forward user UUID
  MetaResync->>BukkitScheduler: schedule check after 20 ticks
  BukkitScheduler->>MetaResync: run check for UUID
  MetaResync->>PlayerMetaSyncService: pushIfChanged for online player
Loading







Merge Risk: ⚪ Minimal · up to c37cb

This change resends player metadata to the website after LuckPerms recalculates permissions, skipping unchanged payloads. No concrete merge-blocking risk was found. Live-server behavior is untested by the author, which is normal pre-merge uncertainty.

  • 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:L 100-499 effective changed lines (tests excluded in mixed PRs). label Oct 11, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 11, 2026
Review fixes:
- Sends for one player now run through a single drain task that always
  sends the newest queued body, so an older body can no longer land
  after a newer one. Change detection compares against the newest body
  handed to the sender, not the last acknowledged one, so a change made
  while a send is in flight is still sent.
- GroupDataRecalculateEvent checks every online player, so edits to
  what a rank grants also reach the website.
- Scheduling rejected during shutdown no longer leaves a player stuck
  as pending, and an unexpected exception from the PUT cannot leave a
  player stuck as sending.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ryanbarlow97 and others added 2 commits October 11, 2026 17:31
A PUT that times out on our side can still be processed by the website
after a newer PUT, leaving the site on older meta while change detection
skips the current body. After any failed send, unchanged bodies for that
player are now resent at each recalculation until 10 minutes have passed
since the last failure, so the periodic LuckPerms sync repairs a late
write. Producers are documented as main-thread only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The repair window used to end ten minutes after the last failure even if
the last successful resend came earlier, so a late write landing between
that resend and the deadline went unrepaired. The failure marker is now
cleared only by a send that succeeds at least ten minutes after the last
failure. Comments no longer claim the website applies sends in order, and
a fake-site test covers a timed-out write landing after a newer one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanbarlow97 ryanbarlow97 reopened this Oct 11, 2026
@ryanbarlow97 ryanbarlow97 reopened this Oct 11, 2026
@ryanbarlow97
ryanbarlow97 merged commit 4a0468a into main Oct 11, 2026
5 of 8 checks passed
@ryanbarlow97
ryanbarlow97 deleted the fix/resync-meta-on-rank-change branch October 11, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 effective changed lines (tests excluded in mixed PRs).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant