fix: NPE importing GriefPrevention data with Bedrock (Geyser/Floodgate) players - #503
fix: NPE importing GriefPrevention data with Bedrock (Geyser/Floodgate) players#503noaskers wants to merge 1 commit into
Conversation
OfflinePlayer#hasPlayedBefore only indicates that playerdata exists for a UUID; it does not guarantee the server has a cached username for it. Names come from usercache.json, which is size-capped and expires entries, so getName may return null for players who have played before. That null reached User.of, tripping its non-null check and failing the whole claim import with a NullPointerException. Fall back to the shortened UUID whenever no name is available, not just when the player has never played.
|
Closing this — on further investigation the null names on my server are Geyser/Floodgate Bedrock players rather than usercache expiry, so the explanation in this PR is not accurate. I'd rather not have a fix upstream with the wrong rationale attached. May reopen with a corrected diagnosis. |
|
Appreciate your detailed diagnostics nonetheless. |
|
Its mostly up to you what you do with it, but as shown above I got that long error due to Bedrock players. I check the code out and in the current way it does not allow bedrock players to be converted due to there UUID not existing at all. The screenshot I provied in the comment above is with my local build with this PR in it making it so it does not fully break the converter. |
And I did not mean to close it I just wanted to edit it, but claude was cracking up some GITHUB shit. idk what he's on I ask him to push but he just don't understand and does everything for me. |

Problem
Importing from GriefPrevention on a server with Bedrock players fails partway through, aborting the whole claim import:
Cause
GriefPreventionUserresolves usernames with:This assumes
getName()is non-null wheneverhasPlayedBefore()is true, but those come from different sources — playerdata on disk versus a resolvable account name.Geyser/Floodgate players break that assumption. Their UUIDs are synthesised by Floodgate rather than issued by Mojang, so Bukkit has no name to return for them, while they do have playerdata from having joined. The result is
hasPlayedBefore() == truealongsidegetName() == null, so the existing UUID fallback is skipped and thenullreachesUser.of, tripping its Lombok@NonNullcheck.Because this happens inside the
importClaimsfuture, one Bedrock player is enough to fail the import for the entire server. The failure surfaces duringCLAIMSrather thanUSERSbecauseimportUsers()only constructs the objects —importClaims()is the first caller oftoUser()/toSavedUser().Fix
Treat a missing name the same as a never-seen player, so the existing UUID fallback covers both cases.
Tested on a local build against a GriefPrevention database containing Bedrock players; the import runs to completion instead of aborting.
Note
This gets Bedrock players through the importer rather than naming them well: they fall back to the shortened UUID, and since Floodgate UUIDs begin with a long run of zeroes, they will share the same
00000000placeholder until each player next logs in.Resolving those through the Floodgate API would be the more complete fix, but it adds a dependency and needs testing against a real Floodgate setup, so I've kept this change to stopping the import from breaking. Happy to look at the fuller version if you'd prefer it.