Skip to content

fix(session): expire cached bypass for active players - #2330

Closed
strobil wants to merge 1 commit into
EngineHub:version/7.0.xfrom
strobil:fix/bypass-cache-expiry
Closed

strobil wants to merge 1 commit into
EngineHub:version/7.0.xfrom
strobil:fix/bypass-cache-expiry

Conversation

@strobil

@strobil strobil commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

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. hasBypass now goes through asMap().computeIfAbsent, and Guava counts each of those calls as a write, which restarts the two second expiry. Since hasBypass runs 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 getIfPresent and put instead, so the two seconds only start when the answer is first cached.

I added a test that fails without the fix, and ./gradlew build passes. 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: true works around it.

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>
@strobil strobil changed the title Fix bypass cache never expiring for active players fix(session): expire cached bypass for active players Nov 5, 2026
@me4502

me4502 commented Nov 5, 2026

Copy link
Copy Markdown
Member

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)

@strobil

strobil commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor Author

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.

@me4502

me4502 commented Nov 5, 2026

Copy link
Copy Markdown
Member

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.

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