diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index a25f03d..2a159d6 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -1,4 +1,5 @@ -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands.Targeting; @@ -12,7 +13,7 @@ namespace CS2_SimpleAdmin; -[MinimumApiVersion(191)] +[MinimumApiVersion(198)] public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { public static CS2_SimpleAdmin Instance { get; private set; } = new(); @@ -38,7 +39,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig "CS2-SimpleAdmin"; public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleAuthor => "daffyy & Dliix66"; - public override string ModuleVersion => "1.3.6c"; + public override string ModuleVersion => "1.3.6d"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -71,7 +72,10 @@ public void OnConfigParsed(CS2_SimpleAdminConfig config) UserID = config.DatabaseUser, Password = config.DatabasePassword, Port = (uint)config.DatabasePort, - Pooling = true + Pooling = true, + MinimumPoolSize = 0, + MaximumPoolSize = (uint)(Server.MaxPlayers > 21 ? 640 : 210), + ConnectionIdleTimeout = 30 }; dbConnectionString = builder.ConnectionString; diff --git a/CS2-SimpleAdmin.csproj b/CS2-SimpleAdmin.csproj index dc0a740..57b9de1 100644 --- a/CS2-SimpleAdmin.csproj +++ b/CS2-SimpleAdmin.csproj @@ -10,10 +10,10 @@ - + - - + + diff --git a/Commands/basecommands.cs b/Commands/basecommands.cs index ff564a6..22331a0 100644 --- a/Commands/basecommands.cs +++ b/Commands/basecommands.cs @@ -33,7 +33,12 @@ public void OnSaUpgradeCommand(CCSPlayerController? caller, CommandInfo command) commandSql.CommandText = commandText; await commandSql.ExecuteNonQueryAsync(); - command.ReplyToCommand("Successfully updated the database"); + commandText = "ALTER TABLE `sa_servers` MODIFY COLUMN `hostname` varchar(128);"; + using var commandSql1 = connection.CreateCommand(); + commandSql1.CommandText = commandText; + await commandSql1.ExecuteNonQueryAsync(); + + command.ReplyToCommand($"Successfully updated the database - {ModuleVersion}"); } catch (Exception ex) { diff --git a/Commands/playercommands.cs b/Commands/playercommands.cs index 089e84d..a148d6f 100644 --- a/Commands/playercommands.cs +++ b/Commands/playercommands.cs @@ -662,7 +662,6 @@ public void OnRenameCommand(CCSPlayerController? caller, CommandInfo command) if (caller!.CanTarget(player)) { - player.Rename(newName); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { @@ -676,6 +675,8 @@ public void OnRenameCommand(CCSPlayerController? caller, CommandInfo command) } } } + + player.Rename(newName); } }); } @@ -815,6 +816,7 @@ public void OnBringCommand(CCSPlayerController? caller, CommandInfo command) _discordWebhookClientLog.SendMessageAsync(Helper.GenerateMessageDiscord(_localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", command.GetCommandString])); } + Helper.LogCommand(caller, command); playersToTarget.ForEach(player => diff --git a/Database/database_setup.sql b/Database/database_setup.sql index 44622a4..de7e1b4 100644 --- a/Database/database_setup.sql +++ b/Database/database_setup.sql @@ -44,7 +44,7 @@ CREATE TABLE IF NOT EXISTS `sa_admins` ( CREATE TABLE IF NOT EXISTS `sa_servers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `address` varchar(64) NOT NULL, - `hostname` varchar(64) NOT NULL, + `hostname` varchar(128) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `address` (`address`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; \ No newline at end of file diff --git a/Events.cs b/Events.cs index e22b946..2ede139 100644 --- a/Events.cs +++ b/Events.cs @@ -32,70 +32,84 @@ public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo CCSPlayerController? player = @event.Userid; #if DEBUG - Logger.LogCritical("[OnClientDisconnect] Before"); + Logger.LogCritical("[OnClientDisconnect] Before"); #endif - if (player is null || !player.IsValid || string.IsNullOrEmpty(player.IpAddress) || player.IsBot || player.IsHLTV) return HookResult.Continue; - if (!loadedPlayers.Contains(player.Slot)) return HookResult.Continue; + if (player == null || !player.IsValid || string.IsNullOrEmpty(player.IpAddress) || player.IsBot || player.IsHLTV) + { + return HookResult.Continue; + } + + if (!loadedPlayers.Contains(player.Slot)) + { + return HookResult.Continue; + } #if DEBUG - Logger.LogCritical("[OnClientDisconnect] After Check"); + Logger.LogCritical("[OnClientDisconnect] After Check"); #endif + try + { + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + playerPenaltyManager.RemoveAllPenalties(player.Slot); - PlayerPenaltyManager playerPenaltyManager = new(); - playerPenaltyManager.RemoveAllPenalties(player.Slot); - - if (TagsDetected) - Server.ExecuteCommand($"css_tag_unmute {player.SteamID}"); - - if (silentPlayers.Contains(player.Slot)) - RemoveFromConcurrentBag(silentPlayers, player.Slot); - if (godPlayers.Contains(player.Slot)) - RemoveFromConcurrentBag(godPlayers, player.Slot); - - loadedPlayers.Remove(player.Slot); + if (TagsDetected) + { + Server.ExecuteCommand($"css_tag_unmute {player.SteamID}"); + } - SteamID? authorizedSteamID = player.AuthorizedSteamID; + if (silentPlayers.Contains(player.Slot)) + { + RemoveFromConcurrentBag(silentPlayers, player.Slot); + } - if (authorizedSteamID == null) return HookResult.Continue; + if (godPlayers.Contains(player.Slot)) + { + RemoveFromConcurrentBag(godPlayers, player.Slot); + } - Task.Run(() => - { - if (AdminSQLManager._adminCache.TryGetValue(authorizedSteamID, out DateTime? expirationTime) + SteamID? authorizedSteamID = player.AuthorizedSteamID; + if (authorizedSteamID != null && AdminSQLManager._adminCache.TryGetValue(authorizedSteamID, out DateTime? expirationTime) && expirationTime <= DateTime.Now) { AdminManager.ClearPlayerPermissions(authorizedSteamID); AdminManager.RemovePlayerAdminData(authorizedSteamID); } - }); - return HookResult.Continue; + loadedPlayers.Remove(player.Slot); + + return HookResult.Continue; + } + catch (Exception ex) + { + Logger.LogError($"An error occurred in OnClientDisconnect: {ex.Message}"); + return HookResult.Continue; + } } + + [GameEventHandler] public HookResult OnPlayerFullConnect(EventPlayerConnectFull @event, GameEventInfo info) { CCSPlayerController? player = @event.Userid; -#if DEBUG - Logger.LogCritical($"[OnPlayerConnect] Before check {player.PlayerName} : {player.IpAddress}"); -#endif - if (player is null - || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1") - || player.IsBot || player.IsHLTV || !player.UserId.HasValue) return HookResult.Continue; -#if DEBUG - Logger.LogCritical("[OnPlayerConnect] After Check"); -#endif + if (player == null || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1") + || player.IsBot || player.IsHLTV || !player.UserId.HasValue) + return HookResult.Continue; + string ipAddress = player.IpAddress.Split(":")[0]; + // Check if the player's IP or SteamID is in the bannedPlayers list if (bannedPlayers.Contains(ipAddress) || bannedPlayers.Contains(player.SteamID.ToString())) { - if (!player.UserId.HasValue) return HookResult.Continue; - Helper.KickPlayer(player.UserId.Value, "Banned"); + // Kick the player if banned + if (player.UserId.HasValue) + Helper.KickPlayer(player.UserId.Value, "Banned"); + return HookResult.Continue; } - if (_database == null || !player.UserId.HasValue || player.UserId == null) - return HookResult.Continue; + if (_database == null) return HookResult.Continue; PlayerInfo playerInfo = new PlayerInfo { @@ -107,12 +121,13 @@ public HookResult OnPlayerFullConnect(EventPlayerConnectFull @event, GameEventIn IpAddress = ipAddress }; - BanManager _banManager = new(_database, Config); - MuteManager _muteManager = new(_database); - PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); - Task.Run(async () => { + // Initialize BanManager, MuteManager, and PlayerPenaltyManager within the async delegate + BanManager _banManager = new(_database, Config); + MuteManager _muteManager = new(_database); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + if (await _banManager.IsPlayerBanned(playerInfo)) { if (playerInfo.IpAddress != null && !bannedPlayers.Contains(playerInfo.IpAddress)) @@ -178,6 +193,7 @@ public HookResult OnPlayerFullConnect(EventPlayerConnectFull @event, GameEventIn } }); + // Add player to loadedPlayers if (!loadedPlayers.Contains(player.Slot)) loadedPlayers.Add(player.Slot); @@ -197,7 +213,9 @@ public HookResult OnRoundEnd(EventRoundStart @event, GameEventInfo info) public HookResult OnCommandSay(CCSPlayerController? player, CommandInfo info) { - if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; + if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0 || info.GetArg(1).StartsWith("/") + || info.GetArg(1).StartsWith("!") && info.GetArg(1).Length >= 12) + return HookResult.Continue; PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); @@ -209,7 +227,9 @@ public HookResult OnCommandSay(CCSPlayerController? player, CommandInfo info) public HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info) { - if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; + if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0 || info.GetArg(1).StartsWith("/") + || info.GetArg(1).StartsWith("!") && info.GetArg(1).Length >= 12) + return HookResult.Continue; PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); @@ -262,63 +282,68 @@ private void OnMapStart(string mapName) if (_database == null) return; - AddTimer(61.0f, async () => + AddTimer(61.0f, () => { + #if DEBUG Logger.LogCritical("[OnMapStart] Expired check"); #endif - AdminSQLManager _adminManager = new(_database); - BanManager _banManager = new(_database, Config); - MuteManager _muteManager = new(_database); - await _banManager.ExpireOldBans(); - await _muteManager.ExpireOldMutes(); - await _adminManager.DeleteOldAdmins(); - bannedPlayers.Clear(); - - Server.NextFrame(() => + Task.Run(async () => { - try + AdminSQLManager _adminManager = new AdminSQLManager(_database); + BanManager _banManager = new BanManager(_database, Config); + MuteManager _muteManager = new MuteManager(_database); + await _banManager.ExpireOldBans(); + await _muteManager.ExpireOldMutes(); + await _adminManager.DeleteOldAdmins(); + + bannedPlayers.Clear(); + + Server.NextFrame(() => { - foreach (CCSPlayerController player in Helper.GetValidPlayers()) + try { - if (playerPenaltyManager.IsSlotInPenalties(player.Slot)) + foreach (CCSPlayerController player in Helper.GetValidPlayers()) { - if (!playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) && !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence)) - player.VoiceFlags = VoiceFlags.Normal; - - if (!playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) && !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence)) + if (playerPenaltyManager.IsSlotInPenalties(player.Slot)) { - if (TagsDetected) - Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); - } - - if ( - !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence) && - !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) && - !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) - ) - { - player.VoiceFlags = VoiceFlags.Normal; - - if (TagsDetected) - Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); + if (!playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) && !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence)) + player.VoiceFlags = VoiceFlags.Normal; + + if (!playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) && !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence)) + { + if (TagsDetected) + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); + } + + if ( + !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence) && + !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) && + !playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) + ) + { + player.VoiceFlags = VoiceFlags.Normal; + + if (TagsDetected) + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); + } } } + + playerPenaltyManager.RemoveExpiredPenalties(); } - } - catch (Exception) { } + catch (Exception) { } + }); }); - - playerPenaltyManager.RemoveExpiredPenalties(); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - AddTimer(2.0f, async () => + AddTimer(2.5f, () => { string? address = $"{ConVar.Find("ip")!.StringValue}:{ConVar.Find("hostport")!.GetPrimitiveValue()}"; string? hostname = ConVar.Find("hostname")!.StringValue; - await Task.Run(async () => + Task.Run(async () => { AdminSQLManager _adminManager = new(_database); try @@ -354,6 +379,7 @@ await connection.ExecuteAsync( await _adminManager.GiveAllFlags(); }); + }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); AddTimer(3.0f, () => diff --git a/Extensions/PlayerExtensions.cs b/Extensions/PlayerExtensions.cs index eb67428..0c2f6c5 100644 --- a/Extensions/PlayerExtensions.cs +++ b/Extensions/PlayerExtensions.cs @@ -121,7 +121,7 @@ public static void Rename(this CCSPlayerController controller, string newName = if (CS2_SimpleAdmin.Instance == null) return; - newName = CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; + newName = newName ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; SchemaString playerName = new SchemaString(controller, "m_iszPlayerName"); playerName.Set(newName + " "); diff --git a/Helper.cs b/Helper.cs index 51e7548..7a38528 100644 --- a/Helper.cs +++ b/Helper.cs @@ -45,13 +45,13 @@ public static List GetPlayerFromIp(string ipAddress) public static List GetValidPlayers() { - return Utilities.GetPlayers().FindAll(p => p != null && p.IsValid && p.SteamID.ToString().Length == 17 && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV); + return Utilities.GetPlayers().FindAll(p => p != null && p.IsValid && p.SteamID.ToString().Length == 17 && !string.IsNullOrEmpty(p.IpAddress) && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV); } public static List GetValidPlayersWithBots() { return Utilities.GetPlayers().FindAll(p => - p != null && p.IsValid && p.SteamID.ToString().Length == 17 && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV || + p != null && p.IsValid && p.SteamID.ToString().Length == 17 && !string.IsNullOrEmpty(p.IpAddress) && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV || p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && p.IsBot && !p.IsHLTV ); } diff --git a/Managers/PlayerPenaltyManager.cs b/Managers/PlayerPenaltyManager.cs index f50cba9..64333f7 100644 --- a/Managers/PlayerPenaltyManager.cs +++ b/Managers/PlayerPenaltyManager.cs @@ -17,17 +17,22 @@ public class PlayerPenaltyManager // Add a penalty for a player public void AddPenalty(int slot, PenaltyType penaltyType, DateTime endDateTime, int durationSeconds) { - if (!penalties.ContainsKey(slot)) - { - penalties[slot] = new Dictionary>(); - } - - if (!penalties[slot].ContainsKey(penaltyType)) - { - penalties[slot][penaltyType] = new List<(DateTime, int)>(); - } - - penalties[slot][penaltyType].Add((endDateTime, durationSeconds)); + penalties.AddOrUpdate(slot, + (_) => + { + var dict = new Dictionary>(); + dict[penaltyType] = new List<(DateTime, int)>() { (endDateTime, durationSeconds) }; + return dict; + }, + (_, existingDict) => + { + if (!existingDict.ContainsKey(penaltyType)) + { + existingDict[penaltyType] = new List<(DateTime, int)>(); + } + existingDict[penaltyType].Add((endDateTime, durationSeconds)); + return existingDict; + }); } public bool IsPenalized(int slot, PenaltyType penaltyType)