diff --git a/.gitignore b/.gitignore index 870e2ac..79b4f27 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,6 @@ obj/ .git .vscode/ .idea/ +Modules/CS2-SimpleAdmin_PlayTimeModule CS2-SimpleAdmin.sln.DotSettings.user Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdmin_ExampleModule.sln.DotSettings.user diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs index 6cb7bf7..c16e37f 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs @@ -19,7 +19,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)"); public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleAuthor => "daffyy & Dliix66"; - public override string ModuleVersion => "1.7.6a"; + public override string ModuleVersion => "1.7.7-alpha"; public override void Load(bool hotReload) { @@ -40,7 +40,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig + Parallel.ForEach(Helper.GetValidPlayers(), player => { playerManager.LoadPlayerData(player); }); diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj b/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj index 78d0918..e3ddb47 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj @@ -10,10 +10,11 @@ - + + diff --git a/CS2-SimpleAdmin/Commands/basebans.cs b/CS2-SimpleAdmin/Commands/basebans.cs index ac6b064..f71e757 100644 --- a/CS2-SimpleAdmin/Commands/basebans.cs +++ b/CS2-SimpleAdmin/Commands/basebans.cs @@ -73,12 +73,6 @@ public partial class CS2_SimpleAdmin SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Ban, reason, time, penaltyId); }); - // Update banned players list - if (playerInfo.IpAddress != null && !BannedPlayers.Contains(playerInfo.IpAddress)) - BannedPlayers.Add(playerInfo.IpAddress); - if (!BannedPlayers.Contains(player.SteamID.ToString())) - BannedPlayers.Add(player.SteamID.ToString()); - // Determine message keys and arguments based on ban time var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = time == 0 ? ("sa_player_ban_message_perm", "sa_admin_ban_message_perm", @@ -129,8 +123,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); if (player != null && player.IsValid) { @@ -184,8 +177,7 @@ public partial class CS2_SimpleAdmin ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromSteamid64(steamid); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid); if (player != null && player.IsValid) { @@ -247,8 +239,7 @@ public partial class CS2_SimpleAdmin ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromIp(ipAddress); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromIp(ipAddress); if (player != null && player.IsValid) { @@ -442,8 +433,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); if (player != null && player.IsValid) { diff --git a/CS2-SimpleAdmin/Commands/basechat.cs b/CS2-SimpleAdmin/Commands/basechat.cs index f193705..58b6c3c 100644 --- a/CS2-SimpleAdmin/Commands/basechat.cs +++ b/CS2-SimpleAdmin/Commands/basechat.cs @@ -100,7 +100,6 @@ public partial class CS2_SimpleAdmin var utf8String = Encoding.UTF8.GetString(utf8BytesString); Helper.LogCommand(caller, command); - Helper.PrintToCenterAll(utf8String.ReplaceColorTags()); } diff --git a/CS2-SimpleAdmin/Commands/basecommands.cs b/CS2-SimpleAdmin/Commands/basecommands.cs index 98a9e52..88b935b 100644 --- a/CS2-SimpleAdmin/Commands/basecommands.cs +++ b/CS2-SimpleAdmin/Commands/basecommands.cs @@ -650,7 +650,6 @@ public partial class CS2_SimpleAdmin Helper.LogCommand(caller, command); var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsBot: false }).ToList(); - if (playersToTarget.Count > 1) return; @@ -708,20 +707,20 @@ public partial class CS2_SimpleAdmin if (caller != null) { caller.PrintToConsole("--------- PLAYER LIST ---------"); - playersToTarget.ForEach(player => + foreach (var player in playersToTarget) { caller.PrintToConsole( $"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")"); - }); + }; caller.PrintToConsole("--------- END PLAYER LIST ---------"); } else { Server.PrintToConsole("--------- PLAYER LIST ---------"); - playersToTarget.ForEach(player => + foreach (var player in playersToTarget) { Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); - }); + }; Server.PrintToConsole("--------- END PLAYER LIST ---------"); } } @@ -789,6 +788,8 @@ public partial class CS2_SimpleAdmin Kick(caller, player, reason, callerName, command); } }); + + Helper.LogCommand(caller, command); } public void Kick(CCSPlayerController? caller, CCSPlayerController player, string? reason = "Unknown", string? callerName = null, CommandInfo? command = null) @@ -828,8 +829,6 @@ public partial class CS2_SimpleAdmin // Log the command and send Discord notification if (command == null) Helper.LogCommand(caller, $"css_kick {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {reason}"); - else - Helper.LogCommand(caller, command); SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Kick, reason, -1, null); } diff --git a/CS2-SimpleAdmin/Commands/basecomms.cs b/CS2-SimpleAdmin/Commands/basecomms.cs index 29b1e26..c30b832 100644 --- a/CS2-SimpleAdmin/Commands/basecomms.cs +++ b/CS2-SimpleAdmin/Commands/basecomms.cs @@ -114,8 +114,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); if (player != null && player.IsValid) { @@ -173,8 +172,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; // Attempt to match player based on SteamID - var matches = Helper.GetPlayerFromSteamid64(steamid); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid); if (player != null && player.IsValid) { @@ -230,8 +228,7 @@ public partial class CS2_SimpleAdmin // Check if pattern is a valid SteamID64 if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null) { - var matches = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString()); if (player != null && player.IsValid) { @@ -406,8 +403,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; // Attempt to match player based on SteamID - var matches = Helper.GetPlayerFromSteamid64(steamid); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid); if (player != null && player.IsValid) { @@ -447,8 +443,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); if (player != null && player.IsValid) { @@ -498,8 +493,7 @@ public partial class CS2_SimpleAdmin // Check if pattern is a valid SteamID64 if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null) { - var matches = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString()); if (player != null && player.IsValid) { @@ -674,8 +668,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; // Attempt to match player based on SteamID - var matches = Helper.GetPlayerFromSteamid64(steamid); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid); if (player != null && player.IsValid) { @@ -715,8 +708,7 @@ public partial class CS2_SimpleAdmin var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; - var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString()); if (player != null && player.IsValid) { @@ -766,8 +758,7 @@ public partial class CS2_SimpleAdmin // Check if pattern is a valid SteamID64 if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null) { - var matches = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString()); - var player = matches.Count == 1 ? matches.FirstOrDefault() : null; + var player = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString()); if (player != null && player.IsValid) { diff --git a/CS2-SimpleAdmin/Commands/funcommands.cs b/CS2-SimpleAdmin/Commands/funcommands.cs index c336c81..efa1f9d 100644 --- a/CS2-SimpleAdmin/Commands/funcommands.cs +++ b/CS2-SimpleAdmin/Commands/funcommands.cs @@ -27,6 +27,8 @@ public partial class CS2_SimpleAdmin NoClip(caller, player, callerName); } }); + + Helper.LogCommand(caller, command); } internal static void NoClip(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null) @@ -53,13 +55,7 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) - { Helper.LogCommand(caller, $"css_noclip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}"); - } - else - { - Helper.LogCommand(caller, command); - } } [RequiresPermissions("@css/cheats")] @@ -82,6 +78,8 @@ public partial class CS2_SimpleAdmin God(caller, player, command); } }); + + Helper.LogCommand(caller, command); } internal static void God(CCSPlayerController? caller, CCSPlayerController player, CommandInfo? command = null) @@ -100,8 +98,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_god {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}"); - else - Helper.LogCommand(caller, command); // Determine message key and arguments for the god mode notification var (activityMessageKey, adminActivityArgs) = @@ -133,6 +129,8 @@ public partial class CS2_SimpleAdmin Freeze(caller, player, time, callerName, command); } }); + + Helper.LogCommand(caller, command); } [CommandHelper(1, "<#userid or name> [size]")] @@ -206,8 +204,6 @@ public partial class CS2_SimpleAdmin // Log the command and send Discord notification if (command == null) Helper.LogCommand(caller, $"css_freeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {time}"); - else - Helper.LogCommand(caller, command); } [CommandHelper(1, "<#userid or name>")] @@ -224,6 +220,8 @@ public partial class CS2_SimpleAdmin { Unfreeze(caller, player, callerName, command); }); + + Helper.LogCommand(caller, command); } internal static void Unfreeze(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null) @@ -251,7 +249,5 @@ public partial class CS2_SimpleAdmin // Log the command and send Discord notification if (command == null) Helper.LogCommand(caller, $"css_unfreeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}"); - else - Helper.LogCommand(caller, command); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Commands/playercommands.cs b/CS2-SimpleAdmin/Commands/playercommands.cs index 08102fa..3be0b36 100644 --- a/CS2-SimpleAdmin/Commands/playercommands.cs +++ b/CS2-SimpleAdmin/Commands/playercommands.cs @@ -28,6 +28,8 @@ public partial class CS2_SimpleAdmin { Slay(caller, player, callerName, command); }); + + Helper.LogCommand(caller, command); } internal static void Slay(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null) @@ -55,8 +57,6 @@ public partial class CS2_SimpleAdmin // Log the command and send Discord notification if (command == null) Helper.LogCommand(caller, $"css_slay {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}"); - else - Helper.LogCommand(caller, command); } [RequiresPermissions("@css/cheats")] @@ -94,6 +94,8 @@ public partial class CS2_SimpleAdmin GiveWeapon(caller, player, weaponName, callerName, command); }); + + Helper.LogCommand(caller, command); } private static void GiveWeapon(CCSPlayerController? caller, CCSPlayerController player, string weaponName, string? callerName = null, CommandInfo? command = null) @@ -122,8 +124,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_giveweapon {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {weaponName}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the weapon give notification var (activityMessageKey, adminActivityArgs) = @@ -150,8 +150,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_giveweapon {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {weapon.ToString()}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the weapon give notification var (activityMessageKey, adminActivityArgs) = @@ -182,6 +180,8 @@ public partial class CS2_SimpleAdmin StripWeapons(caller, player, callerName, command); } }); + + Helper.LogCommand(caller, command); } internal static void StripWeapons(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null) @@ -201,8 +201,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_strip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the weapon strip notification var (activityMessageKey, adminActivityArgs) = @@ -234,6 +232,8 @@ public partial class CS2_SimpleAdmin SetHp(caller, player, health, command); } }); + + Helper.LogCommand(caller, command); } internal static void SetHp(CCSPlayerController? caller, CCSPlayerController player, int health, CommandInfo? command = null) @@ -250,8 +250,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_hp {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {health}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the HP set notification var (activityMessageKey, adminActivityArgs) = @@ -286,6 +284,8 @@ public partial class CS2_SimpleAdmin SetSpeed(caller, player, speed, command); } }); + + Helper.LogCommand(caller, command); } internal static void SetSpeed(CCSPlayerController? caller, CCSPlayerController player, float speed, CommandInfo? command = null) @@ -306,8 +306,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_speed {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {speed}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the speed set notification var (activityMessageKey, adminActivityArgs) = @@ -342,6 +340,8 @@ public partial class CS2_SimpleAdmin SetGravity(caller, player, gravity, command); } }); + + Helper.LogCommand(caller, command); } internal static void SetGravity(CCSPlayerController? caller, CCSPlayerController player, float gravity, CommandInfo? command = null) @@ -362,8 +362,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_gravity {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {gravity}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the gravity set notification var (activityMessageKey, adminActivityArgs) = @@ -399,6 +397,8 @@ public partial class CS2_SimpleAdmin SetMoney(caller, player, money, command); } }); + + Helper.LogCommand(caller, command); } internal static void SetMoney(CCSPlayerController? caller, CCSPlayerController player, int money, CommandInfo? command = null) @@ -414,8 +414,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_money {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {money}"); - else - Helper.LogCommand(caller, command); // Determine message keys and arguments for the money set notification var (activityMessageKey, adminActivityArgs) = @@ -455,6 +453,8 @@ public partial class CS2_SimpleAdmin Slap(caller, player, damage, command); } }); + + Helper.LogCommand(caller, command); } internal static void Slap(CCSPlayerController? caller, CCSPlayerController player, int damage, CommandInfo? command = null) @@ -470,9 +470,7 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_slap {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {damage}"); - else - Helper.LogCommand(caller, command); - + // Determine message key and arguments for the slap notification var (activityMessageKey, adminActivityArgs) = ("sa_admin_slap_message", @@ -532,6 +530,8 @@ public partial class CS2_SimpleAdmin { ChangeTeam(caller, player, _teamName, teamNum, kill, command); }); + + Helper.LogCommand(caller, command); } internal static void ChangeTeam(CCSPlayerController? caller, CCSPlayerController player, string teamName, CsTeam teamNum, bool kill, CommandInfo? command = null) @@ -570,8 +570,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_team {player.PlayerName} {teamName}"); - else - Helper.LogCommand(caller, command); // Determine message key and arguments for the team change notification var activityMessageKey = "sa_admin_team_message"; @@ -698,6 +696,8 @@ public partial class CS2_SimpleAdmin Respawn(caller, player, callerName, command); } }); + + Helper.LogCommand(caller, command); } internal static void Respawn(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null) @@ -722,8 +722,6 @@ public partial class CS2_SimpleAdmin // Log the command if (command == null) Helper.LogCommand(caller, $"css_respawn {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}"); - else - Helper.LogCommand(caller, command); // Determine message key and arguments for the respawn notification var activityMessageKey = "sa_admin_respawn_message"; diff --git a/CS2-SimpleAdmin/Events.cs b/CS2-SimpleAdmin/Events.cs index e8ef371..f4ade1c 100644 --- a/CS2-SimpleAdmin/Events.cs +++ b/CS2-SimpleAdmin/Events.cs @@ -137,8 +137,8 @@ public partial class CS2_SimpleAdmin #if DEBUG Logger.LogCritical("[OnClientConnect]"); #endif - if (!CS2_SimpleAdmin.BannedPlayers.Contains(ipaddress.Split(":")[0])) - return; + if (Config.OtherSettings.BanType == 1 && !Instance.CacheManager.IsPlayerBanned(null, ipaddress.Split(":")[0])) + return; Server.NextFrame((() => { @@ -225,13 +225,26 @@ public partial class CS2_SimpleAdmin if (!PlayerPenaltyManager.IsPenalized(author.Slot, PenaltyType.Gag, out DateTime? endDateTime) && !PlayerPenaltyManager.IsPenalized(author.Slot, PenaltyType.Silence, out endDateTime)) return HookResult.Continue; + + var message = um.ReadString("param2"); + + if (_localizer == null || endDateTime is null) return HookResult.Continue; + + if (CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger).Any(trigger => message.StartsWith(trigger))) + { + foreach (var recipient in um.Recipients) + { + if (recipient == author) + continue; + + um.Recipients.Remove(recipient); + } + + return HookResult.Continue; + } - if (_localizer != null && endDateTime is not null) - author.SendLocalizedMessage(_localizer, "sa_player_penalty_chat_active", endDateTime.Value.ToString("g", author.GetLanguage())); + author.SendLocalizedMessage(_localizer, "sa_player_penalty_chat_active", endDateTime.Value.ToString("g", author.GetLanguage())); return HookResult.Stop; - - // um.Recipients.Clear(); - } private HookResult ComamndListenerHandler(CCSPlayerController? player, CommandInfo info) @@ -382,7 +395,7 @@ public partial class CS2_SimpleAdmin if (Config.OtherSettings.ReloadAdminsEveryMapChange && ServerLoaded && ServerId != null) AddTimer(5.0f, () => ReloadAdmins(null)); - AddTimer(1.0f, () => new ServerManager().CheckHibernationStatus()); + AddTimer(1.0f, () => ServerManager.CheckHibernationStatus()); // AddTimer(34, () => // { diff --git a/CS2-SimpleAdmin/Helper.cs b/CS2-SimpleAdmin/Helper.cs index 29df5a9..e62ba7d 100644 --- a/CS2-SimpleAdmin/Helper.cs +++ b/CS2-SimpleAdmin/Helper.cs @@ -22,6 +22,7 @@ using CounterStrikeSharp.API.Core.Plugin.Host; using CounterStrikeSharp.API.Modules.Entities.Constants; using CS2_SimpleAdmin.Managers; using MenuManager; +using ZLinq; namespace CS2_SimpleAdmin; @@ -51,33 +52,29 @@ internal static class Helper return Utilities.GetPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase)); } - public static List GetPlayerFromSteamid64(string steamid) + public static CCSPlayerController? GetPlayerFromSteamid64(string steamid) { - return GetValidPlayers().FindAll(x => - x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase) - ); + return GetValidPlayers().FirstOrDefault(x => x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase)); } - public static List GetPlayerFromIp(string ipAddress) + public static CCSPlayerController? GetPlayerFromIp(string ipAddress) { - return GetValidPlayers().FindAll(x => - x.IpAddress != null && - x.IpAddress.Split(":")[0].Equals(ipAddress) - ); + return GetValidPlayers().FirstOrDefault(x => x.IpAddress != null && x.IpAddress.Split(":")[0].Equals(ipAddress)); } - public static List GetValidPlayers() + public static IReadOnlyList GetValidPlayers() { - return Utilities.GetPlayers().FindAll(p => p is - { IsValid: true, IsBot: false, Connected: PlayerConnectedState.PlayerConnected }); + return Utilities.GetPlayers().AsValueEnumerable() + .Where(p => p is { IsValid: true, IsBot: false, Connected: PlayerConnectedState.PlayerConnected }) + .ToList(); + } + + public static IReadOnlyList GetValidPlayersWithBots() + { + return Utilities.GetPlayers().AsValueEnumerable() + .Where(p => p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.PlayerConnected }).ToList(); } - public static IEnumerable GetValidPlayersWithBots() - { - return Utilities.GetPlayers().FindAll(p => - p is { IsValid: true, IsBot: false, IsHLTV: false } or { IsValid: true, IsBot: true, IsHLTV: false } - ); - } // public static bool IsValidSteamId64(string input) // { @@ -800,6 +797,7 @@ internal static class Helper return pluginManager; } + } public static class PluginInfo diff --git a/CS2-SimpleAdmin/Managers/BanManager.cs b/CS2-SimpleAdmin/Managers/BanManager.cs index 4012059..368f8a8 100644 --- a/CS2-SimpleAdmin/Managers/BanManager.cs +++ b/CS2-SimpleAdmin/Managers/BanManager.cs @@ -394,7 +394,7 @@ internal class BanManager(Database.Database? database) { SteamIDs = steamIds, IpAddresses = checkIpBans ? ipAddresses : [], - ServerId = CS2_SimpleAdmin.ServerId + CS2_SimpleAdmin.ServerId }); var valueTuples = bannedPlayers.ToList(); diff --git a/CS2-SimpleAdmin/Managers/CacheManager.cs b/CS2-SimpleAdmin/Managers/CacheManager.cs new file mode 100644 index 0000000..c8298d8 --- /dev/null +++ b/CS2-SimpleAdmin/Managers/CacheManager.cs @@ -0,0 +1,168 @@ +using System.Collections.Concurrent; +using CS2_SimpleAdmin.Models; +using Dapper; +using Microsoft.Extensions.Logging; + +namespace CS2_SimpleAdmin.Managers; + +internal class CacheManager +{ + private readonly ConcurrentDictionary _banCache = new(); + private readonly ConcurrentDictionary ips, DateTime used_at)> _playerIpsCache = new(); + + private DateTime _lastUpdateTime = DateTime.MinValue; + private bool _isInitialized; + + public async Task InitializeCacheAsync() + { + if (CS2_SimpleAdmin.Database == null) return; + if (!CS2_SimpleAdmin.ServerLoaded) + return; + if (_isInitialized) return; + + try + { + await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); + var bans = await connection.QueryAsync( + """ + SELECT + id AS Id, + player_name AS PlayerName, + player_steamid AS PlayerSteamId, + player_ip AS PlayerIp, + admin_steamid AS AdminSteamId, + admin_name AS AdminName, + reason AS Reason, + duration AS Duration, + ends AS Ends, + created AS Created, + server_id AS ServerId, + status AS Status, + updated_at AS UpdatedAt + FROM sa_bans + """); + var ipHistory = await connection.QueryAsync<(ulong steamid, string address, DateTime used_at)>( + "SELECT steamid, address, used_at FROM sa_players_ips"); + + + 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); + _playerIpsCache[group.Key] = (ips, lastUsed); + } + + _lastUpdateTime = DateTime.Now; + _isInitialized = true; + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + public async Task RefreshCacheAsync() + { + if (CS2_SimpleAdmin.Database == null) return; + if (!_isInitialized) return; + + try + { + await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); + 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 address, DateTime used_at)>( + "SELECT steamid, address, used_at FROM sa_players_ips"); + + // 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); + // _playerIpsCache[group.Key] = (ips, lastUsed); + // } + + var groupedData = ipHistory.GroupBy(x => x.steamid).ToList(); + Parallel.ForEach(groupedData, group => + { + var ips = new HashSet(group.Select(x => x.address)); + var lastUsed = group.Max(x => x.used_at); + + _playerIpsCache.AddOrUpdate( + group.Key, + _ => (ips, lastUsed), + (_, existing) => + { + existing.ips.UnionWith(ips); + return (existing.ips, + lastUsed > existing.used_at ? lastUsed : existing.used_at); + }); + }); + + if (updatedBans.Count == 0) + return; + + foreach (var ban in updatedBans) + { + _banCache.AddOrUpdate(ban.Id, ban, (_, _) => ban); + } + + _lastUpdateTime = DateTime.Now; + } + catch (Exception e) + { + // ignored + } + } + + public List GetAllBans() => _banCache.Values.ToList(); + public List GetActiveBans() => _banCache.Values.Where(b => b.Status == "ACTIVE").ToList(); + public List GetPlayerBansBySteamId(string steamId) => _banCache.Values.Where(b => b.PlayerSteamId == steamId).ToList(); + + + private bool IsIpBanned(string ipAddress) + { + return _banCache.Values.Any(b => + b.Status == "ACTIVE" && + !string.IsNullOrEmpty(b.PlayerIp) && + b.PlayerIp.Equals(ipAddress, StringComparison.OrdinalIgnoreCase)); + } + + public bool IsPlayerBanned(string? steamId, string? ipAddress) => + _banCache.Values.Any(b => + b.Status == "ACTIVE" && ( + (steamId != null && + b.PlayerSteamId != null && + b.PlayerSteamId.Equals(steamId, StringComparison.OrdinalIgnoreCase)) || + (ipAddress != null && + b.PlayerIp != null && + b.PlayerIp.Equals(ipAddress, StringComparison.OrdinalIgnoreCase)) + )); + + public bool IsPlayerOrAnyIpBanned(ulong steamId) + { + var steamIdStr = steamId.ToString(); + if (_banCache.Values.Any(b => + b.Status == "ACTIVE" && + b.PlayerSteamId?.Equals(steamIdStr, StringComparison.OrdinalIgnoreCase) == true)) + { + return true; + } + + return _playerIpsCache.TryGetValue(steamId, out var ipList) && ipList.ips.Any(IsIpBanned); + } + + public bool HasIpForPlayer(ulong steamId, string ipAddress) + { + return _playerIpsCache.TryGetValue(steamId, out var ipList) + && ipList.ips.Contains(ipAddress); + } + +} \ No newline at end of file diff --git a/CS2-SimpleAdmin/Managers/MuteManager.cs b/CS2-SimpleAdmin/Managers/MuteManager.cs index be3e9bf..55df4b6 100644 --- a/CS2-SimpleAdmin/Managers/MuteManager.cs +++ b/CS2-SimpleAdmin/Managers/MuteManager.cs @@ -187,13 +187,13 @@ internal class MuteManager(Database.Database? database) } } - public async Task CheckOnlineModeMutes(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players) + public async Task CheckOnlineModeMutes(List<(ulong SteamID, int? UserId, int Slot)> players) { if (database == null) return; try { - var batchSize = 10; + const int batchSize = 20; await using var connection = await database.GetConnectionAsync(); var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode @@ -205,7 +205,7 @@ internal class MuteManager(Database.Database? database) var batch = players.Skip(i).Take(batchSize); var parametersList = new List(); - foreach (var (_, steamId, _, _) in batch) + foreach (var (steamId, _, _) in batch) { parametersList.Add(new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId }); } @@ -218,7 +218,7 @@ internal class MuteManager(Database.Database? database) : "SELECT * FROM `sa_mutes` WHERE player_steamid = @PlayerSteamID AND passed >= duration AND duration > 0 AND status = 'ACTIVE' AND server_id = @serverid"; - foreach (var (_, steamId, _, slot) in players) + foreach (var (steamId, _, slot) in players) { var muteRecords = await connection.QueryAsync(sql, new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId }); diff --git a/CS2-SimpleAdmin/Managers/PlayerManager.cs b/CS2-SimpleAdmin/Managers/PlayerManager.cs index 487e9dd..8923df3 100644 --- a/CS2-SimpleAdmin/Managers/PlayerManager.cs +++ b/CS2-SimpleAdmin/Managers/PlayerManager.cs @@ -7,6 +7,7 @@ using CounterStrikeSharp.API.ValveConstants.Protobuf; using CS2_SimpleAdminApi; using Dapper; using Microsoft.Extensions.Logging; +using ZLinq; namespace CS2_SimpleAdmin.Managers; @@ -29,6 +30,7 @@ public class PlayerManager CS2_SimpleAdmin.PlayersInfo[player.UserId.Value] = new PlayerInfo(player.UserId.Value, player.Slot, new SteamID(player.SteamID), player.PlayerName, ipAddress); + // if (!player.UserId.HasValue) // { @@ -37,13 +39,32 @@ public class PlayerManager // } var userId = player.UserId.Value; + if (!CS2_SimpleAdmin.PlayersInfo.ContainsKey(userId)) + { + Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION); + } + + var steamId64 = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64; + var steamId = steamId64.ToString(); - // Check if the player's IP or SteamID is in the bannedPlayers list - if (_config.OtherSettings.BanType > 0 && CS2_SimpleAdmin.BannedPlayers.Contains(ipAddress) || - CS2_SimpleAdmin.BannedPlayers.Contains(player.SteamID.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 - Helper.KickPlayer(player.UserId.Value, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); + Server.NextFrame(() => + { + if (!player.UserId.HasValue) return; + Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); + }); + return; } @@ -52,20 +73,15 @@ public class PlayerManager // Perform asynchronous database operations within a single method Task.Run(async () => { - if (_config.OtherSettings.CheckMultiAccountsByIp) + if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null) { try { - await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); - const string selectQuery = "SELECT COUNT(*) FROM `sa_players_ips` WHERE steamid = @SteamID AND address = @IPAddress;"; - var recordExists = await connection.ExecuteScalarAsync(selectQuery, new - { - SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, - IPAddress = ipAddress - }); - - if (recordExists > 0) + if (CS2_SimpleAdmin.Instance.CacheManager.HasIpForPlayer( + CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, ipAddress)) { + await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); + const string updateQuery = """ UPDATE `sa_players_ips` SET used_at = CURRENT_TIMESTAMP @@ -79,15 +95,41 @@ public class PlayerManager } else { - const string insertQuery = """ - INSERT INTO `sa_players_ips` (steamid, address, used_at) - VALUES (@SteamID, @IPAddress, CURRENT_TIMESTAMP); - """; - await connection.ExecuteAsync(insertQuery, new + await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); + + const string selectQuery = + "SELECT COUNT(*) FROM `sa_players_ips` WHERE steamid = @SteamID AND address = @IPAddress;"; + var recordExists = await connection.ExecuteScalarAsync(selectQuery, new { SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, IPAddress = ipAddress }); + + if (recordExists > 0) + { + const string updateQuery = """ + UPDATE `sa_players_ips` + SET used_at = CURRENT_TIMESTAMP + WHERE steamid = @SteamID AND address = @IPAddress; + """; + await connection.ExecuteAsync(updateQuery, new + { + SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, + IPAddress = ipAddress + }); + } + else + { + const string insertQuery = """ + INSERT INTO `sa_players_ips` (steamid, address, used_at) + VALUES (@SteamID, @IPAddress, CURRENT_TIMESTAMP); + """; + await connection.ExecuteAsync(insertQuery, new + { + SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, + IPAddress = ipAddress + }); + } } } catch (Exception ex) @@ -99,47 +141,21 @@ public class PlayerManager try { - if (!CS2_SimpleAdmin.PlayersInfo.ContainsKey(userId)) - { - await Server.NextFrameAsync(() => Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION)); - } + // var isBanned = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0 + // ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned( + // CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString(), null) + // : CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp + // ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(CS2_SimpleAdmin + // .PlayersInfo[userId].SteamId.SteamId64) + // : CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString(), ipAddress); - // Check if the player is banned - var isBanned = await CS2_SimpleAdmin.Instance.BanManager.IsPlayerBanned(CS2_SimpleAdmin.PlayersInfo[userId]); - - if (isBanned) - { - // Add player's IP and SteamID to bannedPlayers list if not already present - if (_config.OtherSettings.BanType > 0 && ipAddress != null && - !CS2_SimpleAdmin.BannedPlayers.Contains(ipAddress)) - { - CS2_SimpleAdmin.BannedPlayers.Add(ipAddress); - } - - if (!CS2_SimpleAdmin.BannedPlayers.Contains(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString())) - { - CS2_SimpleAdmin.BannedPlayers.Add(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString()); - } - - // Kick the player if banned - await Server.NextFrameAsync(() => - { - var victim = Utilities.GetPlayerFromUserid(userId); - if (victim == null || !victim.UserId.HasValue) return; - Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); - }); - - return; - } - if (fullConnect || !fullConnect) // Temp skip { var warns = await CS2_SimpleAdmin.Instance.WarnManager.GetPlayerWarns(CS2_SimpleAdmin.PlayersInfo[userId], false); var (totalMutes, totalGags, totalSilences) = await CS2_SimpleAdmin.Instance.MuteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId]); - CS2_SimpleAdmin.PlayersInfo[userId].TotalBans = - await CS2_SimpleAdmin.Instance.BanManager.GetPlayerBans(CS2_SimpleAdmin.PlayersInfo[userId]); + CS2_SimpleAdmin.PlayersInfo[userId].TotalBans = CS2_SimpleAdmin.Instance.CacheManager.GetPlayerBansBySteamId(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString()).Count; CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes = totalMutes; CS2_SimpleAdmin.PlayersInfo[userId].TotalGags = totalGags; CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences = totalSilences; @@ -225,13 +241,10 @@ public class PlayerManager CS2_SimpleAdmin.Instance.AddTimer(0.1f, () => { if (CS2_SimpleAdmin.GravityPlayers.Count <= 0) return; - - foreach (var value in CS2_SimpleAdmin.GravityPlayers) - { - if (value.Key is not - { IsValid: true, Connected: PlayerConnectedState.PlayerConnected } && value.Key.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE) - continue; + foreach (var value in CS2_SimpleAdmin.GravityPlayers.Where(value => value.Key is + { IsValid: true, Connected: PlayerConnectedState.PlayerConnected } || value.Key.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE)) + { value.Key.SetGravity(value.Value); } }, TimerFlags.REPEAT); @@ -244,19 +257,29 @@ public class PlayerManager if (CS2_SimpleAdmin.Database == null) return; - var players = Helper.GetValidPlayers(); - var onlinePlayers = new List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)>(); - // var onlinePlayers = players - // .Where(player => player.IpAddress != null) - // .Select(player => (player.IpAddress, player.SteamID, player.UserId, player.Slot)) - // .ToList(); + var players = Helper.GetValidPlayers().ToList(); + + var bannedPlayers = players.AsValueEnumerable() + .Where(player => + { + return CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType switch + { + 0 => CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(player.SteamID.ToString(), null), + _ => CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp + ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(player.SteamID) + : CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(player.SteamID.ToString(), player.IpAddress) + }; + }) + .ToList(); - foreach (var player in players) + foreach (var player in bannedPlayers) { - if (player.IpAddress != null) - onlinePlayers.Add((player.IpAddress, player.SteamID, player.UserId, player.Slot)); + Helper.KickPlayer(player, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); + players.Remove(player); } + var onlinePlayers = players.AsValueEnumerable().Select(player => (player.SteamID, player.UserId, player.Slot)).ToList(); + try { var expireTasks = new[] @@ -264,6 +287,7 @@ public class PlayerManager CS2_SimpleAdmin.Instance.BanManager.ExpireOldBans(), CS2_SimpleAdmin.Instance.MuteManager.ExpireOldMutes(), CS2_SimpleAdmin.Instance.WarnManager.ExpireOldWarns(), + CS2_SimpleAdmin.Instance.CacheManager.RefreshCacheAsync(), CS2_SimpleAdmin.Instance.PermissionManager.DeleteOldAdmins() }; @@ -273,77 +297,71 @@ public class PlayerManager foreach (var ex in t.Exception.InnerExceptions) { - CS2_SimpleAdmin._logger?.LogError($"Error expiring penalties: {ex.Message}"); + CS2_SimpleAdmin._logger?.LogError($"Error processing players timer tasks: {ex.Message}"); } }); + } catch (Exception ex) { CS2_SimpleAdmin._logger?.LogError("Unexpected error: {exception}", ex.Message); } - CS2_SimpleAdmin.BannedPlayers.Clear(); + if (players.Count == 0 || onlinePlayers.Count == 0) return; - if (onlinePlayers.Count > 0) + try { - try + Task.Run(async () => { - Task.Run(async () => - { - await CS2_SimpleAdmin.Instance.BanManager.CheckOnlinePlayers(onlinePlayers); + // await CS2_SimpleAdmin.Instance.BanManager.CheckOnlinePlayers(onlinePlayers); - if (_config.OtherSettings.TimeMode == 0) - { - await CS2_SimpleAdmin.Instance.MuteManager.CheckOnlineModeMutes(onlinePlayers); - } - }).ContinueWith(t => + if (_config.OtherSettings.TimeMode == 0) { - if (t is not { IsFaulted: true, Exception: not null }) return; - - foreach (var ex in t.Exception.InnerExceptions) - { - CS2_SimpleAdmin._logger?.LogError($"Error checking online players: {ex.Message}"); - } - }); - } - catch (Exception ex) - { - CS2_SimpleAdmin._logger?.LogError($"Unexpected error: {ex.Message}"); - } - } - - if (onlinePlayers.Count <= 0) return; - - { - try - { - var penalizedSlots = players - .Where(player => PlayerPenaltyManager.IsSlotInPenalties(player.Slot)) - .Select(player => new - { - Player = player, - IsMuted = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute, out _), - IsSilenced = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence, out _), - IsGagged = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag, out _) - }); - - foreach (var entry in penalizedSlots) - { - // If the player is not muted or silenced, set voice flags to normal - if (!entry.IsMuted && !entry.IsSilenced) - { - entry.Player.VoiceFlags = VoiceFlags.Normal; - } + await CS2_SimpleAdmin.Instance.MuteManager.CheckOnlineModeMutes(onlinePlayers); } - - PlayerPenaltyManager.RemoveExpiredPenalties(); - } - catch (Exception ex) + }).ContinueWith(t => { - CS2_SimpleAdmin._logger?.LogError($"Unable to remove old penalties: {ex.Message}"); - } + if (t is not { IsFaulted: true, Exception: not null }) return; + + foreach (var ex in t.Exception.InnerExceptions) + { + CS2_SimpleAdmin._logger?.LogError($"Error checking online players: {ex.Message}"); + } + }); + } + catch (Exception ex) + { + CS2_SimpleAdmin._logger?.LogError($"Unexpected error: {ex.Message}"); } - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT); + try + { + var penalizedSlots = players + .Where(player => PlayerPenaltyManager.IsSlotInPenalties(player.Slot)) + .Select(player => new + { + Player = player, + IsMuted = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute, out _), + IsSilenced = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence, out _), + IsGagged = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag, out _) + }); + + foreach (var entry in penalizedSlots) + { + // If the player is not muted or silenced, set voice flags to normal + if (!entry.IsMuted && !entry.IsSilenced) + { + entry.Player.VoiceFlags = VoiceFlags.Normal; + } + } + + PlayerPenaltyManager.RemoveExpiredPenalties(); + } + catch (Exception ex) + { + CS2_SimpleAdmin._logger?.LogError($"Unable to remove old penalties: {ex.Message}"); + } + + }, TimerFlags.REPEAT); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Managers/ServerManager.cs b/CS2-SimpleAdmin/Managers/ServerManager.cs index bb14cc1..c1988ce 100644 --- a/CS2-SimpleAdmin/Managers/ServerManager.cs +++ b/CS2-SimpleAdmin/Managers/ServerManager.cs @@ -9,9 +9,9 @@ public class ServerManager { private int _getIpTryCount; - public void CheckHibernationStatus() + public static void CheckHibernationStatus() { - ConVar? convar = ConVar.Find("sv_hibernate_when_empty"); + var convar = ConVar.Find("sv_hibernate_when_empty"); if (convar == null || !convar.GetPrimitiveValue()) return; @@ -51,8 +51,6 @@ public class ServerManager var rconPassword = ConVar.Find("rcon_password")!.StringValue; CS2_SimpleAdmin.IpAddress = address; - CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress); - Task.Run(async () => { try @@ -81,6 +79,8 @@ public class ServerManager } CS2_SimpleAdmin.ServerId = serverId; + + CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress); if (CS2_SimpleAdmin.ServerId != null) { @@ -88,6 +88,8 @@ public class ServerManager } CS2_SimpleAdmin.ServerLoaded = true; + + await CS2_SimpleAdmin.Instance.CacheManager.InitializeCacheAsync(); } catch (Exception ex) { diff --git a/CS2-SimpleAdmin/Models/BanRecord.cs b/CS2-SimpleAdmin/Models/BanRecord.cs new file mode 100644 index 0000000..818745b --- /dev/null +++ b/CS2-SimpleAdmin/Models/BanRecord.cs @@ -0,0 +1,45 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace CS2_SimpleAdmin.Models; + +public record BanRecord +{ + [Column("id")] + public int Id { get; set; } + + [Column("player_name")] + public string PlayerName { get; set; } + + [Column("player_steamid")] + public string? PlayerSteamId { get; set; } + + [Column("player_ip")] + public string? PlayerIp { get; set; } + + [Column("admin_steamid")] + public string AdminSteamId { get; set; } + + [Column("admin_name")] + public string AdminName { get; set; } + + [Column("reason")] + public string Reason { get; set; } + + [Column("duration")] + public int Duration { get; set; } + + [Column("ends")] + public DateTime? Ends { get; set; } + + [Column("created")] + public DateTime Created { get; set; } + + [Column("server_id")] + public int? ServerId { get; set; } + + [Column("status")] + public string Status { get; set; } + + [Column("updated_at")] + public DateTime UpdatedAt { get; set; } +} diff --git a/CS2-SimpleAdmin/VERSION b/CS2-SimpleAdmin/VERSION index 4e7dcbe..58630bc 100644 --- a/CS2-SimpleAdmin/VERSION +++ b/CS2-SimpleAdmin/VERSION @@ -1 +1 @@ -1.7.6a \ No newline at end of file +1.7.7-alpha \ No newline at end of file diff --git a/CS2-SimpleAdmin/Variables.cs b/CS2-SimpleAdmin/Variables.cs index 8436e54..c12cbc0 100644 --- a/CS2-SimpleAdmin/Variables.cs +++ b/CS2-SimpleAdmin/Variables.cs @@ -32,14 +32,13 @@ public partial class CS2_SimpleAdmin // Command and Server Settings public static readonly bool UnlockedCommands = CoreConfig.UnlockConCommands; internal static string IpAddress = string.Empty; - public static bool ServerLoaded; - public static int? ServerId = null; + internal static bool ServerLoaded; + internal static int? ServerId = null; internal static readonly HashSet AdminDisabledJoinComms = []; // Player Management private static readonly HashSet GodPlayers = []; internal static readonly HashSet SilentPlayers = []; - internal static readonly ConcurrentBag BannedPlayers = []; internal static readonly Dictionary RenamedPlayers = []; internal static readonly ConcurrentDictionary PlayersInfo = []; private static readonly List DisconnectedPlayers = []; @@ -69,4 +68,5 @@ public partial class CS2_SimpleAdmin internal BanManager BanManager = new(Database); internal MuteManager MuteManager = new(Database); internal WarnManager WarnManager = new(Database); + internal readonly CacheManager CacheManager = new(); } \ No newline at end of file diff --git a/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj b/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj index 228359e..97feaf5 100644 --- a/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj +++ b/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj @@ -8,7 +8,7 @@ - +