Compare commits

...

17 Commits

Author SHA1 Message Date
Dawid Bepierszcz
91615ffc67 Update VERSION 2026-01-27 13:50:27 +01:00
Dawid Bepierszcz
eb9b438315 Update CS2-SimpleAdmin.cs 2026-01-27 13:47:41 +01:00
Dawid Bepierszcz
3d23b8981b Update VERSION 2026-01-27 12:21:07 +01:00
Dawid Bepierszcz
39cbfdab1e Update CS2-SimpleAdmin.cs 2026-01-27 12:20:56 +01:00
Dawid Bepierszcz
4599f08fd7 Update basecommands.cs 2026-01-27 12:20:29 +01:00
Dawid Bepierszcz
4c43f14c82 Update VERSION 2026-01-27 09:52:44 +01:00
Dawid Bepierszcz
f16f8cf1a5 Update CS2-SimpleAdmin.cs 2026-01-27 09:52:31 +01:00
Dawid Bepierszcz
193685826c Update ServerManager.cs 2026-01-27 09:51:12 +01:00
Dawid Bepierszcz
fe73fa9917 Refactor admin and server loading timing logic
Adjusted timers for admin and server data loading to improve reliability and reduce delays. Admin data is now loaded more promptly on map changes and during command execution. ServerManager now initializes the cache after setting the server ID, and redundant admin reloads have been removed. Version bumped to 1.7.8-beta-10.
2026-01-26 01:19:25 +01:00
Dawid Bepierszcz
bdada2df1e Update VERSION 2026-01-25 14:41:33 +01:00
Dawid Bepierszcz
310a43fcd9 Update CS2-SimpleAdmin.cs 2026-01-25 14:39:01 +01:00
Dawid Bepierszcz
58243e813a Update StatusBlocker plugin binaries
Replaced StatusBlocker-v1.1.4 binaries for both Linux and Windows in the METAMOD PLUGIN directory. This may include bug fixes or improvements in the updated plugin versions.
2026-01-25 14:36:47 +01:00
Dawid Bepierszcz
d53446e0fe Bump version to 1.7.8-beta-8-recompiled
Updated the ModuleVersion string to reflect a recompiled build. No other changes were made.
2026-01-25 14:10:57 +01:00
Dawid Bepierszcz
2404c1bc03 Update dependencies and StatusBlocker plugin version
Upgraded several NuGet packages in CS2-SimpleAdmin and CS2-SimpleAdminApi projects, including CounterStrikeSharp.API, MySqlConnector, System.Linq.Async, and ZLinq. Replaced StatusBlocker v1.1.3 plugin files with v1.1.4 for both Linux and Windows in the StealthModule.
2026-01-25 14:09:12 +01:00
Dawid Bepierszcz
665962565e Update ban logic and StatusBlocker plugin version
Refactored IP ban checking logic in CacheManager for improved accuracy and maintainability. Replaced StatusBlocker plugin binaries with v1.1.3 for both Linux and Windows.

EOL, no more new features
2025-12-13 16:54:33 +01:00
Dawid Bepierszcz
c2e8b4a898 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.
2025-12-02 17:37:14 +01:00
Dawid Bepierszcz
9723a4faee :(
:(
2025-11-13 01:40:50 +01:00
17 changed files with 116 additions and 118 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-10b";
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);
@@ -83,9 +83,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
Unload(false); Unload(false);
} }
AddTimer(6.0f, () => ReloadAdmins(null));
RegisterEvents(); RegisterEvents();
AddTimer(0.5f, RegisterCommands.InitializeCommands); AddTimer(0.5f, RegisterCommands.InitializeCommands);
AddTimer(3.0f, () => ReloadAdmins(null));
if (!CoreConfig.UnlockConCommands) if (!CoreConfig.UnlockConCommands)
{ {
@@ -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

@@ -19,16 +19,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.346"> <PackageReference Include="CounterStrikeSharp.API" Version="1.0.361">
<PrivateAssets>none</PrivateAssets> <PrivateAssets>none</PrivateAssets>
<ExcludeAssets>runtime</ExcludeAssets> <ExcludeAssets>runtime</ExcludeAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Dapper" Version="2.1.66" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="MySqlConnector" Version="2.5.0-beta.1" /> <PackageReference Include="MySqlConnector" Version="2.5.0" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" /> <PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
<PackageReference Include="System.Linq.Async" Version="7.0.0-preview.1.g24680b5469" /> <PackageReference Include="System.Linq.Async" Version="7.0.0" />
<PackageReference Include="ZLinq" Version="1.5.3" /> <PackageReference Include="ZLinq" Version="1.5.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -507,7 +507,7 @@ public partial class CS2_SimpleAdmin
var adminsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/admins.json"); var adminsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/admins.json");
var groupsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/groups.json"); var groupsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/groups.json");
await Server.NextWorldUpdateAsync(() => await Server.NextWorldUpdateAsync(() =>
{ {
AddTimer(1, () => AddTimer(1, () =>
{ {
@@ -521,7 +521,7 @@ public partial class CS2_SimpleAdmin
_logger?.LogInformation("Loaded admins!"); _logger?.LogInformation("Loaded admins!");
}); });
}); });
}); });
//_ = _adminManager.GiveAllGroupsFlags(); //_ = _adminManager.GiveAllGroupsFlags();
//_ = _adminManager.GiveAllFlags(); //_ = _adminManager.GiveAllFlags();

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)
@@ -91,14 +91,15 @@ 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);
} }
@@ -444,13 +448,13 @@ public partial class CS2_SimpleAdmin
private void OnMapStart(string mapName) private void OnMapStart(string mapName)
{ {
if (!ServerLoaded || ServerId == null)
AddTimer(2.0f, OnGameServerSteamAPIActivated);
if (Config.OtherSettings.ReloadAdminsEveryMapChange && ServerLoaded && ServerId != null) if (Config.OtherSettings.ReloadAdminsEveryMapChange && ServerLoaded && ServerId != null)
AddTimer(5.0f, () => ReloadAdmins(null)); ReloadAdmins(null);
AddTimer(1.0f, ServerManager.CheckHibernationStatus); AddTimer(1.0f, ServerManager.CheckHibernationStatus);
if (!ServerLoaded || ServerId == null)
AddTimer(1.5f, OnGameServerSteamAPIActivated);
// AddTimer(34, () => // AddTimer(34, () =>
// { // {
@@ -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;
SilentPlayers.Remove(player.Slot);
if (@event is { Oldteam: <= 1, Team: >= 1 }) 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;
}
} }
} }
@@ -497,15 +507,20 @@ internal class CacheManager: IDisposable
!IpHelper.TryConvertIpToUint(ipAddress, out var ipUInt) || !IpHelper.TryConvertIpToUint(ipAddress, out var ipUInt) ||
_cachedIgnoredIps.Contains(ipUInt) || _cachedIgnoredIps.Contains(ipUInt) ||
!_ipIndex.TryGetValue(ipUInt, out var ipRecords)) return false; !_ipIndex.TryGetValue(ipUInt, out var ipRecords)) return false;
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))
{ {
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress)); _ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress));
} }
return true; return true;
} }
@@ -591,53 +606,54 @@ 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)
{
return true; if (string.IsNullOrEmpty(activeBan.PlayerName) || string.IsNullOrEmpty(activeBan.PlayerIp) && !string.IsNullOrEmpty(ipAddress))
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress));
return true;
}
} }
} }
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0 || string.IsNullOrEmpty(ipAddress)) if (CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0 || string.IsNullOrEmpty(ipAddress))
return false; return false;
if (!_playerIpsCache.TryGetValue(steamId, out var ipData)) if (!IpHelper.TryConvertIpToUint(ipAddress, out var ipUInt))
return false; return false;
var cutoff = Time.ActualDateTime().AddDays(-CS2_SimpleAdmin.Instance.Config.OtherSettings.ExpireOldIpBans); if (_cachedIgnoredIps.Contains(ipUInt))
return false;
if (!_ipIndex.TryGetValue(ipUInt, out var ipBanRecords))
return false;
var ipBan = ipBanRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE);
if (ipBan == null)
return false;
if (!_banCache.TryGetValue(ipBan.Id, out var cachedIpBan) || cachedIpBan.StatusEnum != BanStatus.ACTIVE)
return false;
var expireOldIpBans = CS2_SimpleAdmin.Instance.Config.OtherSettings.ExpireOldIpBans;
if (expireOldIpBans > 0)
{
var cutoff = Time.ActualDateTime().AddDays(-expireOldIpBans);
if (ipBan.Created < cutoff)
return false;
}
var unknownName = CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; var unknownName = CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown";
if (ipAddress != null && IpHelper.TryConvertIpToUint(ipAddress, out var ipAsUint)) if (string.IsNullOrEmpty(ipBan.PlayerName))
{ ipBan.PlayerName = playerName;
if (!_cachedIgnoredIps.Contains(ipAsUint))
{
ipData.Add(new IpRecord(ipAsUint, Time.ActualDateTime().AddSeconds(-2), unknownName));
}
}
foreach (var ipRecord in ipData) ipBan.PlayerSteamId ??= steamId;
{
if (ipRecord.UsedAt < cutoff || _cachedIgnoredIps.Contains(ipRecord.Ip))
continue;
if (!_ipIndex.TryGetValue(ipRecord.Ip, out var banRecords)) _ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress));
continue;
var activeBan = banRecords.FirstOrDefault(r => r.StatusEnum == BanStatus.ACTIVE); return true;
if (activeBan == null)
continue;
if (string.IsNullOrEmpty(activeBan.PlayerName))
activeBan.PlayerName = unknownName;
activeBan.PlayerSteamId ??= steamId;
_ = Task.Run(() => UpdatePlayerData(playerName, steamId, ipAddress));
return true;
}
return false;
} }
/// <summary> /// <summary>

View File

@@ -80,13 +80,7 @@ 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);
@@ -283,6 +278,15 @@ internal class PlayerManager
#endif #endif
if (CS2_SimpleAdmin.DatabaseProvider == null) if (CS2_SimpleAdmin.DatabaseProvider == null)
return; return;
// Optimization: Get players once and avoid allocating anonymous types
var validPlayers = Helper.GetValidPlayers();
// Use ValueTuple instead of anonymous type - better performance and less allocations
var tempPlayers = new List<(string PlayerName, ulong SteamID, string? IpAddress, int? UserId, int Slot)>(validPlayers.Count);
foreach (var p in validPlayers)
{
tempPlayers.Add((p.PlayerName, p.SteamID, p.IpAddress, p.UserId, p.Slot));
}
var pluginInstance = CS2_SimpleAdmin.Instance; var pluginInstance = CS2_SimpleAdmin.Instance;
var config = _config.OtherSettings; // Cache config access var config = _config.OtherSettings; // Cache config access
@@ -291,8 +295,7 @@ internal class PlayerManager
{ {
try try
{ {
// Always run cache and permission refresh, regardless of player count // Run all expire tasks in parallel
// This ensures bans/mutes status changes are detected even when server is empty
var expireTasks = new[] var expireTasks = new[]
{ {
pluginInstance.BanManager.ExpireOldBans(), pluginInstance.BanManager.ExpireOldBans(),
@@ -320,11 +323,6 @@ internal class PlayerManager
if (pluginInstance.CacheManager == null) if (pluginInstance.CacheManager == null)
return; return;
// Only check players if there are any online
var validPlayers = Helper.GetValidPlayers();
if (validPlayers.Count == 0)
return;
// Optimization: Cache ban type and multi-account check to avoid repeated config access // Optimization: Cache ban type and multi-account check to avoid repeated config access
var banType = config.BanType; var banType = config.BanType;
var checkMultiAccounts = config.CheckMultiAccountsByIp; var checkMultiAccounts = config.CheckMultiAccountsByIp;
@@ -332,7 +330,7 @@ internal class PlayerManager
var bannedPlayers = new List<(string PlayerName, ulong SteamID, string? IpAddress, int? UserId, int Slot)>(); var bannedPlayers = new List<(string PlayerName, ulong SteamID, string? IpAddress, int? UserId, int Slot)>();
// Manual loop instead of LINQ - better performance // Manual loop instead of LINQ - better performance
foreach (var player in validPlayers) foreach (var player in tempPlayers)
{ {
var playerName = player.PlayerName; var playerName = player.PlayerName;
var steamId = player.SteamID; var steamId = player.SteamID;
@@ -348,7 +346,7 @@ internal class PlayerManager
if (isBanned) if (isBanned)
{ {
bannedPlayers.Add((playerName, steamId, ip, player.UserId, player.Slot)); bannedPlayers.Add(player);
} }
} }
@@ -369,8 +367,8 @@ internal class PlayerManager
if (config.TimeMode == 0) if (config.TimeMode == 0)
{ {
// Optimization: Manual projection instead of LINQ // Optimization: Manual projection instead of LINQ
var onlinePlayers = new List<(ulong, int?, int)>(validPlayers.Count); var onlinePlayers = new List<(ulong, int?, int)>(tempPlayers.Count);
foreach (var player in validPlayers) foreach (var player in tempPlayers)
{ {
onlinePlayers.Add((player.SteamID, player.UserId, player.Slot)); onlinePlayers.Add((player.SteamID, player.UserId, player.Slot));
} }

View File

@@ -31,7 +31,7 @@ public class ServerManager
/// </summary> /// </summary>
public void LoadServerData() public void LoadServerData()
{ {
CS2_SimpleAdmin.Instance.AddTimer(2.0f, () => CS2_SimpleAdmin.Instance.AddTimer(1.0f, () =>
{ {
if (CS2_SimpleAdmin.ServerLoaded || CS2_SimpleAdmin.DatabaseProvider == null) return; if (CS2_SimpleAdmin.ServerLoaded || CS2_SimpleAdmin.DatabaseProvider == null) return;
@@ -103,14 +103,12 @@ public class ServerManager
CS2_SimpleAdmin.ServerId = serverId; CS2_SimpleAdmin.ServerId = serverId;
CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress); CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress);
if (CS2_SimpleAdmin.ServerId != null) CS2_SimpleAdmin.ServerLoaded = true;
{
await Server.NextWorldUpdateAsync(() => CS2_SimpleAdmin.Instance.ReloadAdmins(null));
}
CS2_SimpleAdmin.ServerLoaded = true;
if (CS2_SimpleAdmin.Instance.CacheManager != null) if (CS2_SimpleAdmin.Instance.CacheManager != null)
{
await CS2_SimpleAdmin.Instance.CacheManager.InitializeCacheAsync(); await CS2_SimpleAdmin.Instance.CacheManager.InitializeCacheAsync();
}
} }
catch (Exception ex) catch (Exception ex)
{ {

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

@@ -24,7 +24,10 @@ public record BanRecord
[Column("player_ip")] [Column("player_ip")]
public string? PlayerIp { get; set; } public string? PlayerIp { get; set; }
[Column("created")]
public DateTime Created { get; init; }
[Column("status")] [Column("status")]
public required string Status { get; init; } public required string Status { get; init; }

View File

@@ -1 +1 @@
1.7.8-beta-6 1.7.8-beta-10b1

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 = [];

View File

@@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.346" /> <PackageReference Include="CounterStrikeSharp.API" Version="1.0.361" />
</ItemGroup> </ItemGroup>
</Project> </Project>