From 3793385ce439887d2d94eb78065889a3c4e18f47 Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Sun, 4 Feb 2024 21:04:22 +0100 Subject: [PATCH] 1.3.0b - Minor changes - Fixed `css_players` - Probably fixed problems with taking actions with bots --- AdminSQLManager.cs | 105 +++++++++++-------- BanManager.cs | 27 +++-- CS2-SimpleAdmin.cs | 226 +++++++++++++++++++---------------------- CS2-SimpleAdmin.csproj | 4 + Database.cs | 40 +++++--- Events.cs | 96 ++++++++--------- MuteManager.cs | 31 ++++-- database_setup.sql | 50 +++++++++ 8 files changed, 330 insertions(+), 249 deletions(-) create mode 100644 database_setup.sql diff --git a/AdminSQLManager.cs b/AdminSQLManager.cs index 17f2906..dbfe571 100644 --- a/AdminSQLManager.cs +++ b/AdminSQLManager.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API.Modules.Entities; using Dapper; +using Microsoft.Extensions.Logging; using System.Collections.Concurrent; namespace CS2_SimpleAdmin @@ -50,7 +51,7 @@ namespace CS2_SimpleAdmin { DateTime now = DateTime.Now; - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); string sql = "SELECT flags, immunity, ends FROM sa_admins WHERE player_steamid = @PlayerSteamID AND (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR server_id = @serverid)"; List? activeFlags = (await connection.QueryAsync(sql, new { PlayerSteamID = steamId, CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId }))?.ToList(); @@ -148,59 +149,66 @@ namespace CS2_SimpleAdmin { DateTime now = DateTime.Now; - await using var connection = _database.GetConnection(); - - string sql = "SELECT player_steamid, flags, immunity, ends FROM sa_admins WHERE (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR server_id = @serverid)"; - List? activeFlags = (await connection.QueryAsync(sql, new { CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId }))?.ToList(); - - if (activeFlags == null) + try { - return new List<(string, List, int, DateTime?)>(); - } + using var connection = await _database.GetConnection(); - List<(string, List, int, DateTime?)> filteredFlagsWithImmunity = new List<(string, List, int, DateTime?)>(); + string sql = "SELECT player_steamid, flags, immunity, ends FROM sa_admins WHERE (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR server_id = @serverid)"; + List? activeFlags = (await connection.QueryAsync(sql, new { CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId }))?.ToList(); - foreach (dynamic flags in activeFlags) - { - if (flags is not IDictionary flagsDict) + if (activeFlags == null) { - continue; + return new List<(string, List, int, DateTime?)>(); } - if (!flagsDict.TryGetValue("player_steamid", out var steamIdObj) || - !flagsDict.TryGetValue("flags", out var flagsValueObj) || - !flagsDict.TryGetValue("immunity", out var immunityValueObj) || - !flagsDict.TryGetValue("ends", out var endsObj)) - { - //Console.WriteLine("One or more required keys are missing."); - continue; - } + List<(string, List, int, DateTime?)> filteredFlagsWithImmunity = new List<(string, List, int, DateTime?)>(); - DateTime? ends = null; - - if (endsObj != null) // Check if "ends" is not null + foreach (dynamic flags in activeFlags) { - if (!DateTime.TryParse(endsObj.ToString(), out var parsedEnds)) + if (flags is not IDictionary flagsDict) { - //Console.WriteLine("Failed to parse 'ends' value."); continue; } - ends = parsedEnds; + if (!flagsDict.TryGetValue("player_steamid", out var steamIdObj) || + !flagsDict.TryGetValue("flags", out var flagsValueObj) || + !flagsDict.TryGetValue("immunity", out var immunityValueObj) || + !flagsDict.TryGetValue("ends", out var endsObj)) + { + //Console.WriteLine("One or more required keys are missing."); + continue; + } + + DateTime? ends = null; + + if (endsObj != null) // Check if "ends" is not null + { + if (!DateTime.TryParse(endsObj.ToString(), out var parsedEnds)) + { + //Console.WriteLine("Failed to parse 'ends' value."); + continue; + } + + ends = parsedEnds; + } + + if (!(steamIdObj is string steamId) || + !(flagsValueObj is string flagsValue) || + !int.TryParse(immunityValueObj.ToString(), out var immunityValue)) + { + //Console.WriteLine("Failed to parse one or more values."); + continue; + } + + filteredFlagsWithImmunity.Add((steamId, flagsValue.Split(',').ToList(), immunityValue, ends)); } - if (!(steamIdObj is string steamId) || - !(flagsValueObj is string flagsValue) || - !int.TryParse(immunityValueObj.ToString(), out var immunityValue)) - { - //Console.WriteLine("Failed to parse one or more values."); - continue; - } - - filteredFlagsWithImmunity.Add((steamId, flagsValue.Split(',').ToList(), immunityValue, ends)); + return filteredFlagsWithImmunity; + } + catch (Exception) + { + return new List<(string, List, int, DateTime?)>(); } - - return filteredFlagsWithImmunity; } public async Task GiveAllFlags() @@ -236,7 +244,7 @@ namespace CS2_SimpleAdmin //_adminCache.TryRemove(playerSteamId, out _); - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); string sql = ""; @@ -265,7 +273,7 @@ namespace CS2_SimpleAdmin else futureTime = null; - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); var sql = "INSERT INTO `sa_admins` (`player_steamid`, `player_name`, `flags`, `immunity`, `ends`, `created`, `server_id`) " + "VALUES (@playerSteamid, @playerName, @flags, @immunity, @ends, @created, @serverid)"; @@ -286,10 +294,19 @@ namespace CS2_SimpleAdmin public async Task DeleteOldAdmins() { - await using var connection = _database.GetConnection(); + try + { + using var connection = await _database.GetConnection(); + + string sql = "DELETE FROM sa_admins WHERE ends IS NOT NULL AND ends <= @CurrentTime"; + await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); + } + catch (Exception) + { + if (CS2_SimpleAdmin._logger != null) + CS2_SimpleAdmin._logger.LogCritical("Unable to remove expired admins"); + } - string sql = "DELETE FROM sa_admins WHERE ends IS NOT NULL AND ends <= @CurrentTime"; - await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); } } } \ No newline at end of file diff --git a/BanManager.cs b/BanManager.cs index 3a62b43..195c6fd 100644 --- a/BanManager.cs +++ b/BanManager.cs @@ -1,4 +1,5 @@ using Dapper; +using Microsoft.Extensions.Logging; namespace CS2_SimpleAdmin { @@ -18,7 +19,7 @@ namespace CS2_SimpleAdmin DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); var sql = "INSERT INTO `sa_bans` (`player_steamid`, `player_name`, `player_ip`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " + "VALUES (@playerSteamid, @playerName, @playerIp, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid)"; @@ -45,7 +46,7 @@ namespace CS2_SimpleAdmin DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); var sql = "INSERT INTO `sa_bans` (`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " + "VALUES (@playerSteamid, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid)"; @@ -70,7 +71,7 @@ namespace CS2_SimpleAdmin DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); var sql = "INSERT INTO `sa_bans` (`player_ip`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " + "VALUES (@playerIp, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid)"; @@ -101,7 +102,7 @@ namespace CS2_SimpleAdmin try { - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); var parameters = new { @@ -124,7 +125,7 @@ namespace CS2_SimpleAdmin string sql = "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP)"; int banCount; - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); if (!string.IsNullOrEmpty(player.IpAddress)) { @@ -145,7 +146,7 @@ namespace CS2_SimpleAdmin return; } - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); string sqlUnban = "UPDATE sa_bans SET status = 'UNBANNED' WHERE player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern AND status = 'ACTIVE'"; await connection.ExecuteAsync(sqlUnban, new { pattern = playerPattern }); @@ -153,10 +154,18 @@ namespace CS2_SimpleAdmin public async Task ExpireOldBans() { - await using var connection = _database.GetConnection(); + try + { + using var connection = await _database.GetConnection(); - string sql = "UPDATE sa_bans SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime"; - await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); + string sql = "UPDATE sa_bans SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime"; + await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); + } + catch (Exception) + { + if (CS2_SimpleAdmin._logger != null) + CS2_SimpleAdmin._logger.LogCritical("Unable to remove expired bans"); + } } } } \ No newline at end of file diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index a0dbdda..efde0b1 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -41,13 +41,15 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig CBasePlayerController_SetPawnFunc = new( RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x49\\x89\\xFC\\x53\\x48\\x89\\xF3\\x48\\x81\\xEC\\xC8\\x00\\x00\\x00" : "\\x44\\x88\\x4C\\x24\\x2A\\x55\\x57" ); public override string ModuleName => "CS2-SimpleAdmin"; public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleAuthor => "daffyy"; - public override string ModuleVersion => "1.3.0a"; + public override string ModuleVersion => "1.3.0b"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -59,6 +61,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { caller.ChangeTeam(CsTeam.Spectator); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - AddTimer(1.05f, () => { caller.ChangeTeam(CsTeam.None); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + AddTimer(1.1f, () => { caller.ChangeTeam(CsTeam.None); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); caller.PrintToChat($"You are hidden now!"); if (Config.DiscordWebhook.Length > 0 && _localizer != null) _ = SendWebhookMessage($"{caller.PlayerName} is hidden now."); }); Server.NextFrame(() => { - AddTimer(1.1f, () => { Server.ExecuteCommand("sv_disable_teamselect_menu 0"); }); + AddTimer(1.2f, () => { Server.ExecuteCommand("sv_disable_teamselect_menu 0"); }); }); } } @@ -420,16 +369,14 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.Connected == PlayerConnectedState.PlayerConnected && !player.IsHLTV).ToList(); + List playersToTarget = Utilities.GetPlayers().Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.Connected == PlayerConnectedState.PlayerConnected && !player.IsHLTV).ToList(); if (caller != null) { caller!.PrintToConsole($"--------- PLAYER LIST ---------"); playersToTarget.ForEach(player => { - caller!.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.AuthorizedSteamID?.SteamId64}\")"); + caller!.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); }); caller!.PrintToConsole($"--------- END PLAYER LIST ---------"); } @@ -438,7 +385,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { - Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.AuthorizedSteamID?.SteamId64}\")"); + Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); }); Server.PrintToConsole($"--------- END PLAYER LIST ---------"); } @@ -475,10 +422,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig= 2) { - using (new WithTemporaryCulture(player.GetLanguage())) - { - player.PrintToCenter(_localizer!["sa_player_kick_message", reason, caller == null ? "Console" : caller.PlayerName]); - } + if (!player.IsBot && !player.IsHLTV) + using (new WithTemporaryCulture(player.GetLanguage())) + { + player.PrintToCenter(_localizer!["sa_player_kick_message", reason, caller == null ? "Console" : caller.PlayerName]); + } AddTimer(Config.KickTime, () => Helper.KickPlayer((ushort)player.UserId!, reason), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); } else @@ -565,9 +513,12 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) @@ -984,10 +942,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) @@ -1008,10 +967,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) @@ -1215,10 +1175,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) @@ -1319,10 +1281,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) @@ -1343,10 +1306,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) @@ -2425,4 +2391,16 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig bag, int value) + { + if (bag.Count > 0) + { + if (bag.Contains(value)) + { + bag = new ConcurrentBag(bag.Where(item => item != value)); + } + } + } + } diff --git a/CS2-SimpleAdmin.csproj b/CS2-SimpleAdmin.csproj index 127d09a..fd311f8 100644 --- a/CS2-SimpleAdmin.csproj +++ b/CS2-SimpleAdmin.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/Database.cs b/Database.cs index b701af9..8b94079 100644 --- a/Database.cs +++ b/Database.cs @@ -1,19 +1,31 @@ -using MySqlConnector; +using Microsoft.Extensions.Logging; +using MySqlConnector; -namespace CS2_SimpleAdmin; -public class Database +namespace CS2_SimpleAdmin { - private readonly string _dbConnectionString; - - public Database(string dbConnectionString) + public class Database { - _dbConnectionString = dbConnectionString; - } + private readonly string _dbConnectionString; - public MySqlConnection GetConnection() - { - var connection = new MySqlConnection(_dbConnectionString); - connection.Open(); - return connection; + public Database(string dbConnectionString) + { + _dbConnectionString = dbConnectionString; + } + + public async Task GetConnection() + { + try + { + var connection = new MySqlConnection(_dbConnectionString); + await connection.OpenAsync(); + return connection; + } + catch (Exception) + { + if (CS2_SimpleAdmin._logger != null) + CS2_SimpleAdmin._logger.LogCritical("Unable to connect to database"); + throw; + } + } } -} +} \ No newline at end of file diff --git a/Events.cs b/Events.cs index 13ac8ae..f9766b5 100644 --- a/Events.cs +++ b/Events.cs @@ -6,7 +6,6 @@ using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Cvars; using Dapper; using Microsoft.Extensions.Logging; -using System.Collections.Concurrent; using System.Data; using System.Text; using static CounterStrikeSharp.API.Core.Listeners; @@ -117,14 +116,11 @@ public partial class CS2_SimpleAdmin [GameEventHandler] public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo info) { - if (!@event.Userid.IsValid || !@event.Userid.PlayerPawn.IsValid) - return HookResult.Continue; - CCSPlayerController? player = @event.Userid; #if DEBUG Logger.LogCritical("[OnPlayerConnect] Before check"); #endif - if (_database == null || player is null || !player.IsValid || player.IsBot || player.IsHLTV) + if (_database == null || player is null || !player.IsValid || player.UserId == null || player.SteamID.ToString().Length != 17 || !@event.Userid.PlayerPawn.IsValid || player.IsBot || player.IsHLTV) return HookResult.Continue; #if DEBUG @@ -167,7 +163,7 @@ public partial class CS2_SimpleAdmin if (playerInfo.IpAddress != null && !bannedPlayers.Contains(playerInfo.IpAddress)) bannedPlayers.Add(playerInfo.IpAddress); - if (!bannedPlayers.Contains(playerInfo.SteamId)) + if (playerInfo.SteamId != null && !bannedPlayers.Contains(playerInfo.SteamId)) bannedPlayers.Add(playerInfo.SteamId); Server.NextFrame(() => @@ -187,7 +183,6 @@ public partial class CS2_SimpleAdmin if (muteType == "GAG") { - // Chat mute if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) gaggedPlayers.Add(playerInfo.Slot.Value); @@ -201,7 +196,6 @@ public partial class CS2_SimpleAdmin } else if (muteType == "MUTE") { - // Voice mute Server.NextFrame(() => { player.VoiceFlags = VoiceFlags.Muted; @@ -217,50 +211,35 @@ public partial class CS2_SimpleAdmin [GameEventHandler] public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info) { - if (!@event.Userid.IsValid || @event.Userid.IsBot) + if (@event.Userid is null || !@event.Userid.IsValid || @event.Userid.IsBot) return HookResult.Continue; CCSPlayerController? player = @event.Userid; + #if DEBUG Logger.LogCritical("[OnClientDisconnect] Before"); #endif - if (player is null || !player.IsValid || player.IsBot || player.IsHLTV) + if (player == null || player.IsBot || player.IsHLTV || player.Connected == PlayerConnectedState.PlayerConnecting) return HookResult.Continue; - if (player.Connected == PlayerConnectedState.PlayerConnecting) - return HookResult.Continue; #if DEBUG Logger.LogCritical("[OnClientDisconnect] After Check"); #endif - if (gaggedPlayers.Contains(player.Slot)) - { - gaggedPlayers = new ConcurrentBag(gaggedPlayers.Where(item => item != player.Slot)); - } + RemoveFromConcurrentBag(gaggedPlayers, player.Slot); + RemoveFromConcurrentBag(silentPlayers, player.Slot); + RemoveFromConcurrentBag(godPlayers, player.Slot); - if (silentPlayers.Contains(player.Slot)) + if (player.AuthorizedSteamID != null && AdminSQLManager._adminCache.TryGetValue(player.AuthorizedSteamID, out DateTime? expirationTime) + && expirationTime <= DateTime.Now) { - silentPlayers = new ConcurrentBag(silentPlayers.Where(item => item != player.Slot)); - } - - if (godPlayers.Contains(player.Slot)) - { - godPlayers = new ConcurrentBag(godPlayers.Where(item => item != player.Slot)); - } - - if (player.AuthorizedSteamID != null && AdminSQLManager._adminCache.ContainsKey(player.AuthorizedSteamID)) - { - if (AdminSQLManager._adminCache.TryGetValue(player.AuthorizedSteamID, out DateTime? expirationTime) && - expirationTime <= DateTime.Now) - { - AdminManager.ClearPlayerPermissions(player.AuthorizedSteamID); - AdminManager.RemovePlayerAdminData(player.AuthorizedSteamID); - } + AdminManager.ClearPlayerPermissions(player.AuthorizedSteamID); + AdminManager.RemovePlayerAdminData(player.AuthorizedSteamID); } if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID}"); + NativeAPI.IssueServerCommand($"css_tag_unmute {player.SteamID}"); return HookResult.Continue; } @@ -273,11 +252,11 @@ public partial class CS2_SimpleAdmin if (_database == null) return; - AdminSQLManager _adminManager = new(_database); AddTimer(60.0f, bannedPlayers.Clear, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - AddTimer(120.0f, async () => + AddTimer(130.0f, async () => { + AdminSQLManager _adminManager = new(_database); BanManager _banManager = new(_database, Config); MuteManager _muteManager = new(_database); await _banManager.ExpireOldBans(); @@ -302,21 +281,41 @@ public partial class CS2_SimpleAdmin await Task.Run(async () => { - using (var connection = _database.GetConnection()) + AdminSQLManager _adminManager = new(_database); + try { - await connection.ExecuteAsync( - "INSERT INTO `sa_servers` (address, hostname) VALUES (@address, @hostname) " + - "ON DUPLICATE KEY UPDATE hostname = @hostname", - new { address = $"{address}", hostname }); + using (var connection = await _database.GetConnection()) + { + bool addressExists = await connection.ExecuteScalarAsync( + "SELECT COUNT(*) FROM sa_servers WHERE address = @address", + new { address }); - int? serverId = await connection.ExecuteScalarAsync( - "SELECT `id` FROM `sa_servers` WHERE `address` = @address", - new { address = $"{address}" }); + if (!addressExists) + { + await connection.ExecuteAsync( + "INSERT INTO sa_servers (address, hostname) VALUES (@address, @hostname)", + new { address, hostname }); + } + else + { + await connection.ExecuteAsync( + "UPDATE `sa_servers` SET hostname = @hostname WHERE address = @address", + new { address, hostname }); + } - ServerId = serverId; + int? serverId = await connection.ExecuteScalarAsync( + "SELECT `id` FROM `sa_servers` WHERE `address` = @address", + new { address }); - await _adminManager.GiveAllFlags(); + ServerId = serverId; + } } + catch (Exception) + { + if (_logger != null) + _logger.LogCritical("Unable to create or get server_id"); + } + await _adminManager.GiveAllFlags(); }); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); } @@ -326,7 +325,9 @@ public partial class CS2_SimpleAdmin { CCSPlayerController? player = @event.Userid; - if (player is null || !player.IsValid || !player.PlayerPawn.IsValid || player.PlayerPawn.Value == null || player.IsBot || player.IsHLTV || player.PlayerPawn.IsValid || player.Connected == PlayerConnectedState.PlayerDisconnecting) + if (player is null || @event.Attacker == null || !player.IsValid || !player.PlayerPawn.IsValid || player.PlayerPawn.Value == null + || player.IsBot || player.IsHLTV || player.PlayerPawn.IsValid || player.Connected == PlayerConnectedState.PlayerDisconnecting + || @event.Attacker.Connected == PlayerConnectedState.PlayerDisconnecting) return HookResult.Continue; if (godPlayers.Contains(player.Slot) && player.PawnIsAlive) @@ -337,4 +338,5 @@ public partial class CS2_SimpleAdmin return HookResult.Continue; } + } \ No newline at end of file diff --git a/MuteManager.cs b/MuteManager.cs index 20b0ae2..c561ec1 100644 --- a/MuteManager.cs +++ b/MuteManager.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API.Core; using Dapper; +using Microsoft.Extensions.Logging; namespace CS2_SimpleAdmin { @@ -16,7 +17,7 @@ namespace CS2_SimpleAdmin { if (player == null || player.SteamId == null) return; - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); @@ -47,7 +48,7 @@ namespace CS2_SimpleAdmin { if (string.IsNullOrEmpty(playerSteamId)) return; - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); @@ -80,12 +81,12 @@ namespace CS2_SimpleAdmin return new List(); } - await using var connection = _database.GetConnection(); - DateTime currentTimeUtc = DateTime.UtcNow; - string sql = "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)"; - try { + using var connection = await _database.GetConnection(); + DateTime currentTimeUtc = DateTime.UtcNow; + string sql = "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)"; + var parameters = new { PlayerSteamID = steamId, CurrentTime = currentTimeUtc }; var activeMutes = (await connection.QueryAsync(sql, parameters)).ToList(); return activeMutes; @@ -98,7 +99,7 @@ namespace CS2_SimpleAdmin public async Task GetPlayerMutes(string steamId) { - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); int muteCount; string sql = "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID"; @@ -115,7 +116,7 @@ namespace CS2_SimpleAdmin return; } - await using var connection = _database.GetConnection(); + using var connection = await _database.GetConnection(); if (type == 2) { @@ -137,10 +138,18 @@ namespace CS2_SimpleAdmin public async Task ExpireOldMutes() { - await using var connection = _database.GetConnection(); + try + { + using var connection = await _database.GetConnection(); - string sql = "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime"; - await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); + string sql = "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime"; + await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); + } + catch (Exception) + { + if (CS2_SimpleAdmin._logger != null) + CS2_SimpleAdmin._logger.LogCritical("Unable to remove expired mutes"); + } } public async Task CheckMute(PlayerInfo player) diff --git a/database_setup.sql b/database_setup.sql new file mode 100644 index 0000000..1f18e62 --- /dev/null +++ b/database_setup.sql @@ -0,0 +1,50 @@ +CREATE TABLE IF NOT EXISTS `sa_bans` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `player_steamid` VARCHAR(64), + `player_name` VARCHAR(128), + `player_ip` VARCHAR(128), + `admin_steamid` VARCHAR(64) NOT NULL, + `admin_name` VARCHAR(128) NOT NULL, + `reason` VARCHAR(255) NOT NULL, + `duration` INT NOT NULL, + `ends` TIMESTAMP NOT NULL, + `created` TIMESTAMP NOT NULL, + `server_id` INT NULL, + `status` ENUM('ACTIVE', 'UNBANNED', 'EXPIRED', '') NOT NULL DEFAULT 'ACTIVE' + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE IF NOT EXISTS `sa_mutes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `player_steamid` varchar(64) NOT NULL, + `player_name` varchar(128) NULL, + `admin_steamid` varchar(64) NOT NULL, + `admin_name` varchar(128) NOT NULL, + `reason` varchar(255) NOT NULL, + `duration` int(11) NOT NULL, + `ends` timestamp NOT NULL, + `created` timestamp NOT NULL, + `type` enum('GAG','MUTE','') NOT NULL DEFAULT 'GAG', + `server_id` INT NULL, + `status` enum('ACTIVE','UNMUTED','EXPIRED','') NOT NULL DEFAULT 'ACTIVE', + PRIMARY KEY (`id`) + ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE IF NOT EXISTS `sa_admins` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `player_steamid` varchar(64) NOT NULL, + `player_name` varchar(128) NOT NULL, + `flags` TEXT NOT NULL, + `immunity` varchar(64) NOT NULL DEFAULT '0', + `server_id` INT NULL, + `ends` timestamp NULL, + `created` timestamp NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE IF NOT EXISTS `sa_servers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `address` varchar(64) NOT NULL, + `hostname` varchar(64) 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