Repository navigation
Conversation
hasBypass moved to Cache#asMap().computeIfAbsent in #2325. Guava implements that through compute, which records a write on every hit, so expireAfterWrite restarted each time. hasBypass runs on every block crossing, so an active player kept a stale result until they stayed idle for two seconds or changed worlds. A revoked bypass permission kept working in protected regions, and a newly granted one was ignored. Use getIfPresent and put, which only set the write time on a miss. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I can do some more investigations into this later, but are you sure about this? I specifically tested what you've changed here while making that change as I had a hunch it was impacting the cache, and found it behaved identically in my testing (had no impact on cache evictions/expiry) |
Hey! I'm not 100% sure that caching is the root cause. This was Claude's hypothesis based on its analysis of the code, rather than something I've verified through testing. After updating WorldGuard to 7.0.21, players were able to break blocks in other protected regions even after their duels had ended. |
|
Thanks for the PR, I've gone and swapped the two usages of that function in the session manager with an alternative. I was already sus about it, so I don't really see any harm in swapping it over if it'll possibly resolve an issue. Sorry for not merging this PR, I just felt that as there were multiple places doing it that it felt easier to just resolve those myself. |
Players on our server could break blocks in protected regions right after a duel. The duel plugin gives them a temporary region bypass and removes it when the duel ends, but WorldGuard kept treating them as bypassing for as long as they kept moving. This started with 7.0.21.
It comes from the cache change in #2325.
hasBypassnow goes throughasMap().computeIfAbsent, and Guava counts each of those calls as a write, which restarts the two second expiry. SincehasBypassruns whenever a player steps onto a new block, the old answer never expires while they're moving around. It also works in reverse: someone who was just given the bypass can keep getting denied.This PR uses
getIfPresentandputinstead, so the two seconds only start when the answer is first cached.I added a test that fails without the fix, and
./gradlew buildpasses. A similar check against the real jars showed 7.0.21 still saying yes 8 seconds after the permission was removed, while this branch said no after 2. I haven't tried it in-game yet. Until a fix ships,disable-permission-cache: trueworks around it.