Merge branch 'daffyyyy:main' into main

This commit is contained in:
crashzk 2025-12-03 21:01:16 -03:00 • committed by GitHub
commit 64d6999d28
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 62 additions and 61 deletions

View file

@ -22,7 +22,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)"); public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
public override string ModuleAuthor => "daffyy"; public override string ModuleAuthor => "daffyy";
public override string ModuleVersion => "1.7.8-beta-6"; public override string ModuleVersion => "1.7.8-beta-7";
public override void Load(bool hotReload) public override void Load(bool hotReload)
{ {
@ -46,7 +46,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
CachedPlayers.Clear(); CachedPlayers.Clear();
BotPlayers.Clear(); BotPlayers.Clear();
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsHLTV).ToArray()) foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsHLTV).ToArray())
{ {
if (!player.IsBot) if (!player.IsBot)
PlayerManager.LoadPlayerData(player, true); PlayerManager.LoadPlayerData(player, true);
@ -260,6 +260,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
CacheManager = null; CacheManager = null;
PlayersTimer?.Kill(); PlayersTimer?.Kill();
PlayersTimer = null; PlayersTimer = null;
UnregisterEvents(); UnregisterEvents();
if (hotReload) if (hotReload)

View file

@ -77,7 +77,7 @@ public partial class CS2_SimpleAdmin
new ServerManager().LoadServerData(); new ServerManager().LoadServerData();
} }
[GameEventHandler(HookMode.Pre)] [GameEventHandler]
public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info) public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
{ {
if (@event.Reason is 149 or 6) if (@event.Reason is 149 or 6)
@ -92,13 +92,14 @@ public partial class CS2_SimpleAdmin
if (player == null || !player.IsValid || player.IsHLTV) if (player == null || !player.IsValid || player.IsHLTV)
return HookResult.Continue; return HookResult.Continue;
BotPlayers.Remove(player);
CachedPlayers.Remove(player); CachedPlayers.Remove(player);
BotPlayers.Remove(player);
SilentPlayers.Remove(player.Slot); SilentPlayers.Remove(player.Slot);
if (player.IsBot) if (player.IsBot)
{
return HookResult.Continue; return HookResult.Continue;
}
#if DEBUG #if DEBUG
Logger.LogCritical("[OnClientDisconnect] After Check"); Logger.LogCritical("[OnClientDisconnect] After Check");
@ -176,6 +177,9 @@ public partial class CS2_SimpleAdmin
if (player == null || !player.IsValid || player.IsBot) if (player == null || !player.IsValid || player.IsBot)
return; return;
if (!CachedPlayers.Contains(player))
CachedPlayers.Add(player);
PlayerManager.LoadPlayerData(player); PlayerManager.LoadPlayerData(player);
} }
@ -458,28 +462,11 @@ public partial class CS2_SimpleAdmin
// OnGameServerSteamAPIActivated(); // OnGameServerSteamAPIActivated();
// }); // });
GodPlayers.Clear();
SilentPlayers.Clear(); SilentPlayers.Clear();
PlayerPenaltyManager.RemoveAllPenalties(); PlayerPenaltyManager.RemoveAllPenalties();
} }
[GameEventHandler]
public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info)
{
var player = @event.Userid;
if (player is null || @event.Attacker is null || player.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE || player.PlayerPawn.Value == null)
return HookResult.Continue;
if (!GodPlayers.Contains(player.Slot)) return HookResult.Continue;
player.PlayerPawn.Value.Health = player.PlayerPawn.Value.MaxHealth;
player.PlayerPawn.Value.ArmorValue = 100;
return HookResult.Continue;
}
[GameEventHandler] [GameEventHandler]
public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
{ {
@ -512,17 +499,13 @@ public partial class CS2_SimpleAdmin
public HookResult OnPlayerTeam(EventPlayerTeam @event, GameEventInfo info) public HookResult OnPlayerTeam(EventPlayerTeam @event, GameEventInfo info)
{ {
var player = @event.Userid; var player = @event.Userid;
if (player == null || !player.IsValid || player.IsBot) if (player == null || !player.IsValid || player.IsBot || !SilentPlayers.Contains(player.Slot))
return HookResult.Continue; return HookResult.Continue;
if (!SilentPlayers.Contains(player.Slot)) if (@event is not { Oldteam: <= 1, Team: >= 1 }) return HookResult.Continue;
return HookResult.Continue;
if (@event is { Oldteam: <= 1, Team: >= 1 }) SilentPlayers.Remove(player.Slot);
{ SimpleAdminApi?.OnAdminToggleSilentEvent(player.Slot, false);
SilentPlayers.Remove(player.Slot);
SimpleAdminApi?.OnAdminToggleSilentEvent(player.Slot, false);
}
return HookResult.Continue; return HookResult.Continue;
} }

View file

@ -64,7 +64,7 @@ internal static class Helper
public static List<CCSPlayerController> GetValidPlayers() public static List<CCSPlayerController> GetValidPlayers()
{ {
return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().Where(p => p.Connected == PlayerConnectedState.PlayerConnected).ToList(); return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().Where(p => p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected).ToList();
} }
public static List<CCSPlayerController> GetValidPlayersWithBots() public static List<CCSPlayerController> GetValidPlayersWithBots()

View file

@ -323,13 +323,19 @@ internal class CacheManager: IDisposable
} }
// Update cache with new/modified bans // Update cache with new/modified bans
var needsRebuild = false;
foreach (var ban in updatedBans) foreach (var ban in updatedBans)
{ {
if (_banCache.TryGetValue(ban.Id, out var oldBan) && oldBan.Status != ban.Status)
{
// Ban status changed (e.g., ACTIVE -> EXPIRED/UNBANNED), need to rebuild indexes
needsRebuild = true;
}
_banCache.AddOrUpdate(ban.Id, ban, (_, _) => ban); _banCache.AddOrUpdate(ban.Id, ban, (_, _) => ban);
} }
// Rebuild indexes if there were updates // Rebuild indexes if there were updates or status changes
if (updatedBans.Any()) if (updatedBans.Any() || needsRebuild)
{ {
RebuildIndexes(); RebuildIndexes();
} }
@ -480,13 +486,17 @@ internal class CacheManager: IDisposable
record = steamRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE); record = steamRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE);
if (record != null) if (record != null)
{ {
if ((string.IsNullOrEmpty(record.PlayerIp) && !string.IsNullOrEmpty(ipAddress)) || // Double-check the ban is still active in cache (handle race conditions)
(!record.PlayerSteamId.HasValue)) if (_banCache.TryGetValue(record.Id, out var cachedBan) && cachedBan.StatusEnum == BanStatus.ACTIVE)
{ {
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress)); if ((string.IsNullOrEmpty(record.PlayerIp) && !string.IsNullOrEmpty(ipAddress)) ||
} (!record.PlayerSteamId.HasValue))
{
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress));
}
return true; return true;
}
} }
} }
@ -500,6 +510,11 @@ internal class CacheManager: IDisposable
record = ipRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE); record = ipRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE);
if (record == null) return false; if (record == null) return false;
// Double-check the ban is still active in cache (handle race conditions)
if (!_banCache.TryGetValue(record.Id, out var cachedBanIp) || cachedBanIp.StatusEnum != BanStatus.ACTIVE)
return false;
if ((string.IsNullOrEmpty(record.PlayerIp) && !string.IsNullOrEmpty(ipAddress)) || if ((string.IsNullOrEmpty(record.PlayerIp) && !string.IsNullOrEmpty(ipAddress)) ||
(!record.PlayerSteamId.HasValue && steamId.HasValue)) (!record.PlayerSteamId.HasValue && steamId.HasValue))
{ {
@ -591,10 +606,14 @@ internal class CacheManager: IDisposable
var activeBan = steamBans.FirstOrDefault(b => b.StatusEnum == BanStatus.ACTIVE); var activeBan = steamBans.FirstOrDefault(b => b.StatusEnum == BanStatus.ACTIVE);
if (activeBan != null) if (activeBan != null)
{ {
if (string.IsNullOrEmpty(activeBan.PlayerName) || string.IsNullOrEmpty(activeBan.PlayerIp) && !string.IsNullOrEmpty(ipAddress)) // Double-check the ban is still active in cache (handle race conditions)
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress)); if (_banCache.TryGetValue(activeBan.Id, out var cachedBan) && cachedBan.StatusEnum == BanStatus.ACTIVE)
{
if (string.IsNullOrEmpty(activeBan.PlayerName) || string.IsNullOrEmpty(activeBan.PlayerIp) && !string.IsNullOrEmpty(ipAddress))
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress));
return true; return true;
}
} }
} }
@ -627,6 +646,10 @@ internal class CacheManager: IDisposable
if (activeBan == null) if (activeBan == null)
continue; continue;
// Double-check the ban is still active in cache (handle race conditions)
if (!_banCache.TryGetValue(activeBan.Id, out var cachedBan) || cachedBan.StatusEnum != BanStatus.ACTIVE)
continue;
if (string.IsNullOrEmpty(activeBan.PlayerName)) if (string.IsNullOrEmpty(activeBan.PlayerName))
activeBan.PlayerName = unknownName; activeBan.PlayerName = unknownName;

View file

@ -81,12 +81,6 @@ internal class PlayerManager
var playerInfo = new PlayerInfo(userId, slot, new SteamID(steamId), playerName, ipAddress); var playerInfo = new PlayerInfo(userId, slot, new SteamID(steamId), playerName, ipAddress);
CS2_SimpleAdmin.PlayersInfo[steamId] = playerInfo; CS2_SimpleAdmin.PlayersInfo[steamId] = playerInfo;
await Server.NextWorldUpdateAsync(() =>
{
if (!CS2_SimpleAdmin.CachedPlayers.Contains(player))
CS2_SimpleAdmin.CachedPlayers.Add(player);
});
if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null && if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null &&
CS2_SimpleAdmin.PlayersInfo[steamId] != null) CS2_SimpleAdmin.PlayersInfo[steamId] != null)
{ {
@ -253,6 +247,7 @@ internal class PlayerManager
_loadPlayerSemaphore.Release(); _loadPlayerSemaphore.Release();
} }
}); });
if (CS2_SimpleAdmin.RenamedPlayers.TryGetValue(player.SteamID, out var name)) if (CS2_SimpleAdmin.RenamedPlayers.TryGetValue(player.SteamID, out var name))
{ {
player.Rename(name); player.Rename(name);

View file

@ -33,7 +33,7 @@ internal class WarnManager(IDatabaseProvider? databaseProvider)
playerName = player.Name, playerName = player.Name,
adminSteamid = issuer?.SteamId.SteamId64 ?? 0, adminSteamid = issuer?.SteamId.SteamId64 ?? 0,
adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
muteReason = reason, warnReason = reason,
duration = time, duration = time,
ends = futureTime, ends = futureTime,
created = now, created = now,
@ -42,7 +42,7 @@ internal class WarnManager(IDatabaseProvider? databaseProvider)
return warnId; return warnId;
} }
catch catch(Exception e)
{ {
return null; return null;
} }
@ -73,7 +73,7 @@ internal class WarnManager(IDatabaseProvider? databaseProvider)
playerSteamid = playerSteamId, playerSteamid = playerSteamId,
adminSteamid = issuer?.SteamId.SteamId64 ?? 0, adminSteamid = issuer?.SteamId.SteamId64 ?? 0,
adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
muteReason = reason, warnReason = reason,
duration = time, duration = time,
ends = futureTime, ends = futureTime,
created = now, created = now,

View file

@ -1 +1 @@
1.7.8-beta-6 1.7.8-beta-7

View file

@ -40,7 +40,6 @@ public partial class CS2_SimpleAdmin
internal static readonly HashSet<ulong> AdminDisabledJoinComms = []; internal static readonly HashSet<ulong> AdminDisabledJoinComms = [];
// Player Management // Player Management
private static readonly HashSet<int> GodPlayers = [];
internal static readonly HashSet<int> SilentPlayers = []; internal static readonly HashSet<int> SilentPlayers = [];
internal static readonly Dictionary<ulong, string> RenamedPlayers = []; internal static readonly Dictionary<ulong, string> RenamedPlayers = [];
internal static readonly ConcurrentDictionary<ulong, PlayerInfo> PlayersInfo = []; internal static readonly ConcurrentDictionary<ulong, PlayerInfo> PlayersInfo = [];