Skip to content

fix: load CLV self user state correctly#36

Merged
CroaBeast merged 2 commits into
masterfrom
croabeast
Jul 10, 2026
Merged

fix: load CLV self user state correctly#36
CroaBeast merged 2 commits into
masterfrom
croabeast

Conversation

@CroaBeast

@CroaBeast CroaBeast commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • bump version to 1.2.9
  • load the latest user data when promoting players to online state
  • handle unavailable self-user data safely in the level command

Commits

  • chore: bump version to 1.2.9
  • fix: load CLV self user state correctly

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

@CroaBeast CroaBeast requested review from Kihsomray and Klema4 July 10, 2026 05:08

@review-me-code review-me-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where the self-user state was not being loaded correctly in CyberLevels. The promotion path in UserManagerImpl#finishUserLoad was reusing the stale in-memory existing user instead of the freshly loaded result.user, which could leave outdated data in the cache. The level command now also guards against a null self-user and a null player. Version is bumped to 1.2.9.

Changes:

  • build.gradle.kts: bump version from 1.2.8 to 1.2.9
  • UserManagerImpl#finishUserLoad: when promoting a cached user to online, use the freshly loaded result.user instead of the stale existing instance
  • CLVCommand#sendLevelInfo: early-return when player is null and emit a playerNotFound message when the self-user lookup returns null

Reviewed changes

  • Medium src/main/java/com/bitaspire/cyberlevels/command/CLVCommand.java - Self-user lookup may still race with async load
    sendLevelInfo now treats a null user as 'player not found', but userManager().getUser(player) for the executing player can legitimately return null while the self-user data is still being loaded asynchronously. Sending playerNotFound in that case is misleading and will spam players on first join / after reload. Consider either (a) triggering a load and returning a transient message, or (b) only treating null as 'not found' when the lookup is known synchronous, and otherwise returning a 'loading, try again' message.
  • Low src/main/java/com/bitaspire/cyberlevels/command/CLVCommand.java - Inconsistent null handling for player
    sendLevelInfo now silently returns true when player is null. Other helpers in this command typically log or surface a clearer error. If this method is only ever called with a non-null player (e.g. from a CommandSender cast), the guard is dead code; if it can be null, returning true swallows the failure. Either drop the guard or return false/log.
  • Low src/main/java/com/bitaspire/cyberlevels/UserManagerImpl.java - Promotion path still drops existing state on mismatch
    Switching from existing to result.user is correct for fixing stale data, but if result.user is a freshly constructed offline user that lacks transient fields the previous existing carried (e.g. session-only flags), those will be lost. Worth confirming toOnlineUser is fed a fully-populated user and that no in-memory deltas on existing need to be merged in.

Reviewed 3 changed files in this pull request and generated 1 inline comment.


Generated by pull_request.opened.

}

private boolean sendLevelInfo(Player player) {
if (player == null) return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning true on a null player silently swallows the failure. If this branch is unreachable, drop the guard; otherwise return false so the failure is visible.

Suggested change
if (player == null) return true;
if (player == null) return false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a good review to fix @CroaBeast?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially valid, but I would not change this to false. This command handles its own feedback and normally returns true; returning false would only delegate to Bukkit usage, which is not useful here. The real fix is to avoid calling sendLevelInfo with a null player, e.g. make the purge miss path send player-not-found for console instead.

@Klema4 Klema4 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll approve it soon, I just want to know this one pending comment

}

private boolean sendLevelInfo(Player player) {
if (player == null) return true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a good review to fix @CroaBeast?

@Klema4 Klema4 self-requested a review July 10, 2026 13:46

@Klema4 Klema4 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@CroaBeast CroaBeast merged commit 27ac3eb into master Jul 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants