Skip to content

Commit c2e8b4a

Browse files
committed
Refactor player cache and ban checks, update version
Improves player cache handling and ban status checks for race condition safety. Removes unused GodPlayers logic and related event handler. Refactors event handlers for disconnect and team changes, and fixes warn reason field naming. Updates version to 1.7.8-beta-7.
1 parent 9723a4f commit c2e8b4a

File tree

8 files changed

+62
-61
lines changed

8 files changed

+62
-61
lines changed

CS2-SimpleAdmin/CS2-SimpleAdmin.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
2222
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
2323
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
2424
public override string ModuleAuthor => "daffyy";
25-
public override string ModuleVersion => "1.7.8-beta-6";
25+
public override string ModuleVersion => "1.7.8-beta-7";
2626

2727
public override void Load(bool hotReload)
2828
{
@@ -46,7 +46,7 @@ public override void Load(bool hotReload)
4646
CachedPlayers.Clear();
4747
BotPlayers.Clear();
4848

49-
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsHLTV).ToArray())
49+
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsHLTV).ToArray())
5050
{
5151
if (!player.IsBot)
5252
PlayerManager.LoadPlayerData(player, true);
@@ -260,6 +260,7 @@ public override void Unload(bool hotReload)
260260
CacheManager = null;
261261
PlayersTimer?.Kill();
262262
PlayersTimer = null;
263+
263264
UnregisterEvents();
264265

265266
if (hotReload)

CS2-SimpleAdmin/Events.cs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private void OnGameServerSteamAPIActivated()
7777
new ServerManager().LoadServerData();
7878
}
7979

80-
[GameEventHandler(HookMode.Pre)]
80+
[GameEventHandler]
8181
public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
8282
{
8383
if (@event.Reason is 149 or 6)
@@ -91,14 +91,15 @@ public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo
9191

9292
if (player == null || !player.IsValid || player.IsHLTV)
9393
return HookResult.Continue;
94-
95-
BotPlayers.Remove(player);
96-
CachedPlayers.Remove(player);
9794

95+
CachedPlayers.Remove(player);
96+
BotPlayers.Remove(player);
9897
SilentPlayers.Remove(player.Slot);
9998

10099
if (player.IsBot)
100+
{
101101
return HookResult.Continue;
102+
}
102103

103104
#if DEBUG
104105
Logger.LogCritical("[OnClientDisconnect] After Check");
@@ -176,6 +177,9 @@ private void OnClientConnected(int playerslot)
176177
if (player == null || !player.IsValid || player.IsBot)
177178
return;
178179

180+
if (!CachedPlayers.Contains(player))
181+
CachedPlayers.Add(player);
182+
179183
PlayerManager.LoadPlayerData(player);
180184
}
181185

@@ -458,28 +462,11 @@ private void OnMapStart(string mapName)
458462
// OnGameServerSteamAPIActivated();
459463
// });
460464

461-
GodPlayers.Clear();
462465
SilentPlayers.Clear();
463466

464467
PlayerPenaltyManager.RemoveAllPenalties();
465468
}
466469

467-
[GameEventHandler]
468-
public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info)
469-
{
470-
var player = @event.Userid;
471-
472-
if (player is null || @event.Attacker is null || player.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE || player.PlayerPawn.Value == null)
473-
return HookResult.Continue;
474-
475-
if (!GodPlayers.Contains(player.Slot)) return HookResult.Continue;
476-
477-
player.PlayerPawn.Value.Health = player.PlayerPawn.Value.MaxHealth;
478-
player.PlayerPawn.Value.ArmorValue = 100;
479-
480-
return HookResult.Continue;
481-
}
482-
483470
[GameEventHandler]
484471
public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
485472
{
@@ -512,17 +499,13 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
512499
public HookResult OnPlayerTeam(EventPlayerTeam @event, GameEventInfo info)
513500
{
514501
var player = @event.Userid;
515-
if (player == null || !player.IsValid || player.IsBot)
516-
return HookResult.Continue;
517-
518-
if (!SilentPlayers.Contains(player.Slot))
502+
if (player == null || !player.IsValid || player.IsBot || !SilentPlayers.Contains(player.Slot))
519503
return HookResult.Continue;
520504

521-
if (@event is { Oldteam: <= 1, Team: >= 1 })
522-
{
523-
SilentPlayers.Remove(player.Slot);
524-
SimpleAdminApi?.OnAdminToggleSilentEvent(player.Slot, false);
525-
}
505+
if (@event is not { Oldteam: <= 1, Team: >= 1 }) return HookResult.Continue;
506+
507+
SilentPlayers.Remove(player.Slot);
508+
SimpleAdminApi?.OnAdminToggleSilentEvent(player.Slot, false);
526509

527510
return HookResult.Continue;
528511
}

CS2-SimpleAdmin/Helper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public static List<CCSPlayerController> GetPlayerFromIp(string ipAddress)
6464

6565
public static List<CCSPlayerController> GetValidPlayers()
6666
{
67-
return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().Where(p => p.Connected == PlayerConnectedState.PlayerConnected).ToList();
67+
return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().Where(p => p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected).ToList();
6868
}
6969

7070
public static List<CCSPlayerController> GetValidPlayersWithBots()

CS2-SimpleAdmin/Managers/CacheManager.cs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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));

CS2-SimpleAdmin/Managers/PlayerManager.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,7 @@ await Server.NextWorldUpdateAsync(() =>
8080
{
8181
var playerInfo = new PlayerInfo(userId, slot, new SteamID(steamId), playerName, ipAddress);
8282
CS2_SimpleAdmin.PlayersInfo[steamId] = playerInfo;
83-
84-
await Server.NextWorldUpdateAsync(() =>
85-
{
86-
if (!CS2_SimpleAdmin.CachedPlayers.Contains(player))
87-
CS2_SimpleAdmin.CachedPlayers.Add(player);
88-
});
89-
83+
9084
if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null &&
9185
CS2_SimpleAdmin.PlayersInfo[steamId] != null)
9286
{
@@ -253,6 +247,7 @@ await Server.NextWorldUpdateAsync(() =>
253247
_loadPlayerSemaphore.Release();
254248
}
255249
});
250+
256251
if (CS2_SimpleAdmin.RenamedPlayers.TryGetValue(player.SteamID, out var name))
257252
{
258253
player.Rename(name);

CS2-SimpleAdmin/Managers/WarnManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal class WarnManager(IDatabaseProvider? databaseProvider)
3333
playerName = player.Name,
3434
adminSteamid = issuer?.SteamId.SteamId64 ?? 0,
3535
adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
36-
muteReason = reason,
36+
warnReason = reason,
3737
duration = time,
3838
ends = futureTime,
3939
created = now,
@@ -42,7 +42,7 @@ internal class WarnManager(IDatabaseProvider? databaseProvider)
4242

4343
return warnId;
4444
}
45-
catch
45+
catch(Exception e)
4646
{
4747
return null;
4848
}
@@ -73,7 +73,7 @@ internal class WarnManager(IDatabaseProvider? databaseProvider)
7373
playerSteamid = playerSteamId,
7474
adminSteamid = issuer?.SteamId.SteamId64 ?? 0,
7575
adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
76-
muteReason = reason,
76+
warnReason = reason,
7777
duration = time,
7878
ends = futureTime,
7979
created = now,

CS2-SimpleAdmin/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.7.8-beta-6
1+
1.7.8-beta-7

CS2-SimpleAdmin/Variables.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ public partial class CS2_SimpleAdmin
4040
internal static readonly HashSet<ulong> AdminDisabledJoinComms = [];
4141

4242
// Player Management
43-
private static readonly HashSet<int> GodPlayers = [];
4443
internal static readonly HashSet<int> SilentPlayers = [];
4544
internal static readonly Dictionary<ulong, string> RenamedPlayers = [];
4645
internal static readonly ConcurrentDictionary<ulong, PlayerInfo> PlayersInfo = [];

0 commit comments

Comments
 (0)