@@ -323,13 +323,19 @@ status AS Status
323323 }
324324
325325 // Update cache with new/modified bans
326+ var needsRebuild = false ;
326327 foreach ( var ban in updatedBans )
327328 {
329+ if ( _banCache . TryGetValue ( ban . Id , out var oldBan ) && oldBan . Status != ban . Status )
330+ {
331+ // Ban status changed (e.g., ACTIVE -> EXPIRED/UNBANNED), need to rebuild indexes
332+ needsRebuild = true ;
333+ }
328334 _banCache . AddOrUpdate ( ban . Id , ban , ( _ , _ ) => ban ) ;
329335 }
330336
331- // Rebuild indexes if there were updates
332- if ( updatedBans . Any ( ) )
337+ // Rebuild indexes if there were updates or status changes
338+ if ( updatedBans . Any ( ) || needsRebuild )
333339 {
334340 RebuildIndexes ( ) ;
335341 }
@@ -480,13 +486,17 @@ public bool IsPlayerBanned(string playerName, ulong? steamId, string? ipAddress)
480486 record = steamRecords . FirstOrDefault ( r => r . StatusEnum == BanStatus . ACTIVE ) ;
481487 if ( record != null )
482488 {
483- if ( ( string . IsNullOrEmpty ( record . PlayerIp ) && ! string . IsNullOrEmpty ( ipAddress ) ) ||
484- ( ! record . PlayerSteamId . HasValue ) )
489+ // Double-check the ban is still active in cache (handle race conditions)
490+ if ( _banCache . TryGetValue ( record . Id , out var cachedBan ) && cachedBan . StatusEnum == BanStatus . ACTIVE )
485491 {
486- _ = Task . Run ( ( ) => UpdatePlayerData ( playerName , steamId , ipAddress ) ) ;
487- }
492+ if ( ( string . IsNullOrEmpty ( record . PlayerIp ) && ! string . IsNullOrEmpty ( ipAddress ) ) ||
493+ ( ! record . PlayerSteamId . HasValue ) )
494+ {
495+ _ = Task . Run ( ( ) => UpdatePlayerData ( playerName , steamId , ipAddress ) ) ;
496+ }
488497
489- return true ;
498+ return true ;
499+ }
490500 }
491501 }
492502
@@ -497,15 +507,20 @@ record = steamRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE);
497507 ! IpHelper . TryConvertIpToUint ( ipAddress , out var ipUInt ) ||
498508 _cachedIgnoredIps . Contains ( ipUInt ) ||
499509 ! _ipIndex . TryGetValue ( ipUInt , out var ipRecords ) ) return false ;
500-
510+
501511 record = ipRecords . FirstOrDefault ( r => r . StatusEnum == BanStatus . ACTIVE ) ;
502512 if ( record == null ) return false ;
513+
514+ // Double-check the ban is still active in cache (handle race conditions)
515+ if ( ! _banCache . TryGetValue ( record . Id , out var cachedBanIp ) || cachedBanIp . StatusEnum != BanStatus . ACTIVE )
516+ return false ;
517+
503518 if ( ( string . IsNullOrEmpty ( record . PlayerIp ) && ! string . IsNullOrEmpty ( ipAddress ) ) ||
504519 ( ! record . PlayerSteamId . HasValue && steamId . HasValue ) )
505520 {
506521 _ = Task . Run ( ( ) => UpdatePlayerData ( playerName , steamId , ipAddress ) ) ;
507522 }
508-
523+
509524 return true ;
510525 }
511526
@@ -591,10 +606,14 @@ public bool IsPlayerOrAnyIpBanned(string playerName, ulong steamId, string? ipAd
591606 var activeBan = steamBans . FirstOrDefault ( b => b . StatusEnum == BanStatus . ACTIVE ) ;
592607 if ( activeBan != null )
593608 {
594- if ( string . IsNullOrEmpty ( activeBan . PlayerName ) || string . IsNullOrEmpty ( activeBan . PlayerIp ) && ! string . IsNullOrEmpty ( ipAddress ) )
595- _ = Task . Run ( ( ) => UpdatePlayerData ( playerName , steamId , ipAddress ) ) ;
596-
597- return true ;
609+ // Double-check the ban is still active in cache (handle race conditions)
610+ if ( _banCache . TryGetValue ( activeBan . Id , out var cachedBan ) && cachedBan . StatusEnum == BanStatus . ACTIVE )
611+ {
612+ if ( string . IsNullOrEmpty ( activeBan . PlayerName ) || string . IsNullOrEmpty ( activeBan . PlayerIp ) && ! string . IsNullOrEmpty ( ipAddress ) )
613+ _ = Task . Run ( ( ) => UpdatePlayerData ( playerName , steamId , ipAddress ) ) ;
614+
615+ return true ;
616+ }
598617 }
599618 }
600619
@@ -620,16 +639,20 @@ public bool IsPlayerOrAnyIpBanned(string playerName, ulong steamId, string? ipAd
620639 if ( ipRecord . UsedAt < cutoff || _cachedIgnoredIps . Contains ( ipRecord . Ip ) )
621640 continue ;
622641
623- if ( ! _ipIndex . TryGetValue ( ipRecord . Ip , out var banRecords ) )
642+ if ( ! _ipIndex . TryGetValue ( ipRecord . Ip , out var banRecords ) )
624643 continue ;
625644
626645 var activeBan = banRecords . FirstOrDefault ( r => r . StatusEnum == BanStatus . ACTIVE ) ;
627- if ( activeBan == null )
646+ if ( activeBan == null )
647+ continue ;
648+
649+ // Double-check the ban is still active in cache (handle race conditions)
650+ if ( ! _banCache . TryGetValue ( activeBan . Id , out var cachedBan ) || cachedBan . StatusEnum != BanStatus . ACTIVE )
628651 continue ;
629652
630653 if ( string . IsNullOrEmpty ( activeBan . PlayerName ) )
631654 activeBan . PlayerName = unknownName ;
632-
655+
633656 activeBan . PlayerSteamId ??= steamId ;
634657
635658 _ = Task . Run ( ( ) => UpdatePlayerData ( playerName , steamId , ipAddress ) ) ;
0 commit comments