diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs index c16e37f..d974dbc 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs @@ -40,10 +40,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig + foreach (var player in Helper.GetValidPlayers()) { playerManager.LoadPlayerData(player); - }); + }; }); } _cBasePlayerControllerSetPawnFunc = new MemoryFunctionVoid(GameData.GetSignature("CBasePlayerController_SetPawn")); diff --git a/CS2-SimpleAdmin/Commands/RegisterCommands.cs b/CS2-SimpleAdmin/Commands/RegisterCommands.cs index fd2938c..625ad4e 100644 --- a/CS2-SimpleAdmin/Commands/RegisterCommands.cs +++ b/CS2-SimpleAdmin/Commands/RegisterCommands.cs @@ -34,6 +34,7 @@ public static class RegisterCommands new CommandMapping("css_addgroup", CS2_SimpleAdmin.Instance.OnAddGroup), new CommandMapping("css_delgroup", CS2_SimpleAdmin.Instance.OnDelGroupCommand), new CommandMapping("css_reloadadmins", CS2_SimpleAdmin.Instance.OnRelAdminCommand), + new CommandMapping("css_reloadbans", CS2_SimpleAdmin.Instance.OnRelBans), new CommandMapping("css_hide", CS2_SimpleAdmin.Instance.OnHideCommand), new CommandMapping("css_hidecomms", CS2_SimpleAdmin.Instance.OnHideCommsCommand), new CommandMapping("css_who", CS2_SimpleAdmin.Instance.OnWhoCommand), @@ -122,6 +123,7 @@ public static class RegisterCommands { "css_addgroup", new Command { Aliases = ["css_addgroup"] } }, { "css_delgroup", new Command { Aliases = ["css_delgroup"] } }, { "css_reloadadmins", new Command { Aliases = ["css_reloadadmins"] } }, + { "css_reloadbans", new Command { Aliases = ["css_reloadbans"] } }, { "css_hide", new Command { Aliases = ["css_hide", "css_stealth"] } }, { "css_hidecomms", new Command { Aliases = ["css_hidecomms"] } }, { "css_who", new Command { Aliases = ["css_who"] } }, diff --git a/CS2-SimpleAdmin/Commands/basecommands.cs b/CS2-SimpleAdmin/Commands/basecommands.cs index 4dc7517..26ac7d5 100644 --- a/CS2-SimpleAdmin/Commands/basecommands.cs +++ b/CS2-SimpleAdmin/Commands/basecommands.cs @@ -386,6 +386,16 @@ public partial class CS2_SimpleAdmin command.ReplyToCommand("Reloaded sql admins and groups"); } + + [CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + [RequiresPermissions("@css/root")] + public void OnRelBans(CCSPlayerController? caller, CommandInfo command) + { + if (Database == null) return; + + _ = Instance.CacheManager.ForceReInitializeCacheAsync(); + command.ReplyToCommand("Reloaded bans"); + } public void ReloadAdmins(CCSPlayerController? caller) { diff --git a/CS2-SimpleAdmin/Managers/CacheManager.cs b/CS2-SimpleAdmin/Managers/CacheManager.cs index 90d9254..194d02e 100644 --- a/CS2-SimpleAdmin/Managers/CacheManager.cs +++ b/CS2-SimpleAdmin/Managers/CacheManager.cs @@ -1,7 +1,6 @@ using System.Collections.Concurrent; using CS2_SimpleAdmin.Models; using Dapper; -using Microsoft.Extensions.Logging; using ZLinq; namespace CS2_SimpleAdmin.Managers; @@ -14,16 +13,15 @@ internal class CacheManager private DateTime _lastUpdateTime = DateTime.MinValue; private bool _isInitialized; - + public async Task InitializeCacheAsync() { if (CS2_SimpleAdmin.Database == null) return; - if (!CS2_SimpleAdmin.ServerLoaded) - return; + if (!CS2_SimpleAdmin.ServerLoaded) return; if (_isInitialized) return; _cachedIgnoredIps = [..CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps]; - + try { await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); @@ -44,21 +42,22 @@ internal class CacheManager status AS Status, updated_at AS UpdatedAt FROM sa_bans - """); - var ipHistory = await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>( - "SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC"); + """); + var ipHistory = + await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>( + "SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC"); + - foreach (var ban in bans) { _banCache.TryAdd(ban.Id, ban); } - + foreach (var group in ipHistory.GroupBy(x => x.steamid)) { var ips = new HashSet(group.Select(x => x.address)); var lastUsed = group.Max(x => x.used_at); - var playerName = group.FirstOrDefault(x => !string.IsNullOrEmpty(x.name)).name + var playerName = group.FirstOrDefault(x => !string.IsNullOrEmpty(x.name)).name ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; _playerIpsCache[group.Key] = (ips, lastUsed, playerName); @@ -72,6 +71,18 @@ internal class CacheManager Console.WriteLine(e.ToString()); } } + + public async Task ForceReInitializeCacheAsync() + { + _isInitialized = false; + + _banCache.Clear(); + _playerIpsCache.Clear(); + _cachedIgnoredIps.Clear(); + _lastUpdateTime = DateTime.MinValue; + + await InitializeCacheAsync(); + } public async Task RefreshCacheAsync() { @@ -84,10 +95,9 @@ internal class CacheManager var updatedBans = (await connection.QueryAsync( "SELECT * FROM `sa_bans` WHERE updated_at > @lastUpdate OR created > @lastUpdate ORDER BY updated_at DESC", new { lastUpdate = _lastUpdateTime } - )).ToList(); - - var ipHistory = await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>( - "SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC"); + )).ToList().AsValueEnumerable(); + var ipHistory = (await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>( + "SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC LIMIT 500")).ToList(); // foreach (var group in ipHistory.GroupBy(x => x.steamid)) // { @@ -95,13 +105,12 @@ internal class CacheManager // var lastUsed = group.Max(x => x.used_at); // _playerIpsCache[group.Key] = (ips, lastUsed); // } - - var groupedData = ipHistory + + var groupedData = ipHistory.AsValueEnumerable() .GroupBy(x => x.steamid) - .AsParallel() .ToList(); - Parallel.ForEach(groupedData, group => + groupedData.ForEach(group => { var ips = new HashSet( group.Select(x => x.address), @@ -132,7 +141,7 @@ internal class CacheManager }); }); - if (updatedBans.Count == 0) + if (updatedBans.Count() == 0) return; foreach (var ban in updatedBans) @@ -199,5 +208,4 @@ internal class CacheManager return _playerIpsCache.TryGetValue(steamId, out var ipList) && ipList.ips.Contains(ipAddress); } - } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Managers/PlayerManager.cs b/CS2-SimpleAdmin/Managers/PlayerManager.cs index 19d7288..d3d0c16 100644 --- a/CS2-SimpleAdmin/Managers/PlayerManager.cs +++ b/CS2-SimpleAdmin/Managers/PlayerManager.cs @@ -46,33 +46,32 @@ public class PlayerManager var steamId64 = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64; var steamId = steamId64.ToString(); - - var isBanned = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType switch - { - 0 => // SteamID only check - CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, null), - _ => CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp // SteamID and IP address check - ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(steamId64) // All associated IP addresses - : CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, ipAddress) // Only current IP address - }; - - if (isBanned) - { - // Kick the player if banned - Server.NextFrame(() => - { - if (!player.UserId.HasValue) return; - Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); - }); - - return; - } - + if (CS2_SimpleAdmin.Database == null) return; // Perform asynchronous database operations within a single method Task.Run(async () => { + var isBanned = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType switch + { + 0 => CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, null), + _ => CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp + ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(steamId64) + : CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, ipAddress) + }; + + if (isBanned) + { + // Kick the player if banned + await Server.NextFrameAsync(() => + { + if (!player.UserId.HasValue) return; + Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); + }); + + return; + } + if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null) { try