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 01/10] 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 From aa95815fbda1636a3d62a9f448489fb0151b7559 Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Tue, 6 Feb 2024 00:57:28 +0100 Subject: [PATCH 02/10] Added info about crashes with bots --- AdminSQLManager.cs | 10 +++--- BanManager.cs | 22 ++++++++----- CS2-SimpleAdmin.cs | 15 ++++----- Database.cs | 2 +- Events.cs | 79 ++++++++++++++++++++++++++++++---------------- MuteManager.cs | 17 ++++++---- 6 files changed, 89 insertions(+), 56 deletions(-) diff --git a/AdminSQLManager.cs b/AdminSQLManager.cs index dbfe571..608f9e5 100644 --- a/AdminSQLManager.cs +++ b/AdminSQLManager.cs @@ -51,7 +51,7 @@ namespace CS2_SimpleAdmin { DateTime now = DateTime.Now; - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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(); @@ -151,7 +151,7 @@ namespace CS2_SimpleAdmin try { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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(); @@ -244,7 +244,7 @@ namespace CS2_SimpleAdmin //_adminCache.TryRemove(playerSteamId, out _); - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); string sql = ""; @@ -273,7 +273,7 @@ namespace CS2_SimpleAdmin else futureTime = null; - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); var sql = "INSERT INTO `sa_admins` (`player_steamid`, `player_name`, `flags`, `immunity`, `ends`, `created`, `server_id`) " + "VALUES (@playerSteamid, @playerName, @flags, @immunity, @ends, @created, @serverid)"; @@ -296,7 +296,7 @@ namespace CS2_SimpleAdmin { try { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); string sql = "DELETE FROM sa_admins WHERE ends IS NOT NULL AND ends <= @CurrentTime"; await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.Now }); diff --git a/BanManager.cs b/BanManager.cs index 195c6fd..0a317ad 100644 --- a/BanManager.cs +++ b/BanManager.cs @@ -19,7 +19,7 @@ namespace CS2_SimpleAdmin DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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)"; @@ -46,7 +46,7 @@ namespace CS2_SimpleAdmin DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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)"; @@ -71,7 +71,7 @@ namespace CS2_SimpleAdmin DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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)"; @@ -91,18 +91,23 @@ namespace CS2_SimpleAdmin public async Task IsPlayerBanned(PlayerInfo player) { - if (player == null) + if (player.SteamId == null && player.IpAddress == null) { return false; } +#if DEBUG + if (CS2_SimpleAdmin._logger != null) + CS2_SimpleAdmin._logger.LogCritical($"IsPlayerBanned for {player.Name}"); +#endif + DateTime currentTimeUtc = DateTime.UtcNow; string sql = "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)"; int banCount = 0; try { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); var parameters = new { @@ -120,12 +125,13 @@ namespace CS2_SimpleAdmin return banCount > 0; } + public async Task GetPlayerBans(PlayerInfo player) { string sql = "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP)"; int banCount; - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); if (!string.IsNullOrEmpty(player.IpAddress)) { @@ -146,7 +152,7 @@ namespace CS2_SimpleAdmin return; } - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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 }); @@ -156,7 +162,7 @@ namespace CS2_SimpleAdmin { try { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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 }); diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index efde0b1..d5b94f2 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -89,7 +89,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(silentPlayers.Where(item => item != caller.Slot)); + RemoveFromConcurrentBag(silentPlayers, caller.Slot); caller.PrintToChat($"You aren't hidden now!"); caller.ChangeTeam(CsTeam.Spectator); - if (Config.DiscordWebhook.Length > 0 && _localizer != null) + if (Config.DiscordWebhook.Length > 0) _ = SendWebhookMessage($"{caller.PlayerName} isn't hidden now."); } else @@ -260,14 +260,11 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { caller.ChangeTeam(CsTeam.Spectator); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - AddTimer(1.1f, () => { caller.ChangeTeam(CsTeam.None); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + AddTimer(1.15f, () => { 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) + if (Config.DiscordWebhook.Length > 0) _ = SendWebhookMessage($"{caller.PlayerName} is hidden now."); - }); - Server.NextFrame(() => - { - AddTimer(1.2f, () => { Server.ExecuteCommand("sv_disable_teamselect_menu 0"); }); + AddTimer(1.22f, () => { Server.ExecuteCommand("sv_disable_teamselect_menu 0"); }); }); } } diff --git a/Database.cs b/Database.cs index 8b94079..87a3c59 100644 --- a/Database.cs +++ b/Database.cs @@ -12,7 +12,7 @@ namespace CS2_SimpleAdmin _dbConnectionString = dbConnectionString; } - public async Task GetConnection() + public async Task GetConnectionAsync() { try { diff --git a/Events.cs b/Events.cs index f9766b5..2978697 100644 --- a/Events.cs +++ b/Events.cs @@ -8,7 +8,6 @@ using Dapper; using Microsoft.Extensions.Logging; using System.Data; using System.Text; -using static CounterStrikeSharp.API.Core.Listeners; namespace CS2_SimpleAdmin; @@ -18,10 +17,10 @@ public partial class CS2_SimpleAdmin { //RegisterListener(OnClientAuthorized); //RegisterListener(OnClientConnect); - //RegisterListener(OnClientPutInServer); + RegisterListener(OnClientPutInServer); //RegisterListener(OnClientDisconnect); //RegisterEventHandler(OnPlayerFullConnect); - RegisterListener(OnMapStart); + RegisterListener(OnMapStart); //RegisterEventHandler(OnPlayerHurt); //RegisterEventHandler(OnRoundStart); AddCommandListener("say", OnCommandSay); @@ -113,20 +112,17 @@ public partial class CS2_SimpleAdmin return HookResult.Continue; } - [GameEventHandler] - public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo info) + public void OnClientPutInServer(int playerSlot) { - CCSPlayerController? player = @event.Userid; + CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot); #if DEBUG Logger.LogCritical("[OnPlayerConnect] Before check"); -#endif - 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; +#endif + if (player is null || !player.IsValid || player.IsBot || player.IsHLTV) return; #if DEBUG Logger.LogCritical("[OnPlayerConnect] After Check"); #endif - string? ipAddress = !string.IsNullOrEmpty(player.IpAddress) ? player.IpAddress.Split(":")[0] : null; if ( @@ -134,13 +130,13 @@ public partial class CS2_SimpleAdmin bannedPlayers.Contains(player.SteamID.ToString()) ) { - Server.NextFrame(() => - { - Helper.KickPlayer((ushort)player.UserId!, "Banned"); - }); - return HookResult.Continue; + Helper.KickPlayer((ushort)player.UserId!, "Banned"); + return; } + if (_database == null) + return; + PlayerInfo playerInfo = new PlayerInfo { UserId = player.UserId, @@ -151,13 +147,11 @@ public partial class CS2_SimpleAdmin IpAddress = ipAddress }; + BanManager _banManager = new(_database, Config); + MuteManager _muteManager = new(_database); + Task.Run(async () => { - BanManager _banManager = new(_database, Config); - - MuteManager _muteManager = new(_database); - List activeMutes = await _muteManager.IsPlayerMuted(playerInfo.SteamId); - if (await _banManager.IsPlayerBanned(playerInfo)) { if (playerInfo.IpAddress != null && !bannedPlayers.Contains(playerInfo.IpAddress)) @@ -175,6 +169,8 @@ public partial class CS2_SimpleAdmin return; } + List activeMutes = await _muteManager.IsPlayerMuted(playerInfo.SteamId); + if (activeMutes.Count > 0) { foreach (var mute in activeMutes) @@ -198,20 +194,39 @@ public partial class CS2_SimpleAdmin { Server.NextFrame(() => { - player.VoiceFlags = VoiceFlags.Muted; + if (player.IsValid) + player.VoiceFlags = VoiceFlags.Muted; }); } + else + { + if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) + gaggedPlayers.Add(playerInfo.Slot.Value); + + Server.NextFrame(() => + { + if (player.IsValid) + { + if (TagsDetected) + { + Server.ExecuteCommand($"css_tag_mute {playerInfo.SteamId}"); + } + player.VoiceFlags = VoiceFlags.Muted; + } + }); + + } } } }); - return HookResult.Continue; + return; } [GameEventHandler] public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info) { - if (@event.Userid is null || !@event.Userid.IsValid || @event.Userid.IsBot) + if (@event.Userid is null || !@event.Userid.IsValid) return HookResult.Continue; CCSPlayerController? player = @event.Userid; @@ -220,8 +235,7 @@ public partial class CS2_SimpleAdmin Logger.LogCritical("[OnClientDisconnect] Before"); #endif - if (player == null || player.IsBot || player.IsHLTV || player.Connected == PlayerConnectedState.PlayerConnecting) - return HookResult.Continue; + if (player.IsBot || player.IsHLTV) return HookResult.Continue; #if DEBUG Logger.LogCritical("[OnClientDisconnect] After Check"); @@ -250,8 +264,9 @@ public partial class CS2_SimpleAdmin godPlayers.Clear(); silentPlayers.Clear(); - if (_database == null) return; + _database = new(dbConnectionString); + if (_database == null) return; AddTimer(60.0f, bannedPlayers.Clear, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); AddTimer(130.0f, async () => @@ -284,7 +299,7 @@ public partial class CS2_SimpleAdmin AdminSQLManager _adminManager = new(_database); try { - using (var connection = await _database.GetConnection()) + await using (var connection = await _database.GetConnectionAsync()) { bool addressExists = await connection.ExecuteScalarAsync( "SELECT COUNT(*) FROM sa_servers WHERE address = @address", @@ -318,6 +333,16 @@ public partial class CS2_SimpleAdmin await _adminManager.GiveAllFlags(); }); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + + ConVar? botQuota = ConVar.Find("bot_quota"); + + if (botQuota != null && botQuota.GetPrimitiveValue() > 0) + { + Logger.LogInformation("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); + Logger.LogWarning("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); + Logger.LogCritical("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); + } + } [GameEventHandler] diff --git a/MuteManager.cs b/MuteManager.cs index c561ec1..e7075cf 100644 --- a/MuteManager.cs +++ b/MuteManager.cs @@ -17,7 +17,7 @@ namespace CS2_SimpleAdmin { if (player == null || player.SteamId == null) return; - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); @@ -48,7 +48,7 @@ namespace CS2_SimpleAdmin { if (string.IsNullOrEmpty(playerSteamId)) return; - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); DateTime now = DateTime.Now; DateTime futureTime = now.AddMinutes(time); @@ -81,9 +81,14 @@ namespace CS2_SimpleAdmin return new List(); } +#if DEBUG + if (CS2_SimpleAdmin._logger != null) + CS2_SimpleAdmin._logger.LogCritical($"IsPlayerMuted for {steamId}"); +#endif + try { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); DateTime currentTimeUtc = DateTime.UtcNow; string sql = "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)"; @@ -99,7 +104,7 @@ namespace CS2_SimpleAdmin public async Task GetPlayerMutes(string steamId) { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); int muteCount; string sql = "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID"; @@ -116,7 +121,7 @@ namespace CS2_SimpleAdmin return; } - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); if (type == 2) { @@ -140,7 +145,7 @@ namespace CS2_SimpleAdmin { try { - using var connection = await _database.GetConnection(); + await using var connection = await _database.GetConnectionAsync(); 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 }); From fbed647699ede9455bcb5a3f8268d2246ca8137f Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Thu, 8 Feb 2024 11:11:53 +0100 Subject: [PATCH 03/10] 1.3.0c - CounterStrikeSharp v163 --- CS2-SimpleAdmin.cs | 11 +++++------ CS2-SimpleAdmin.csproj | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index d5b94f2..c6baa13 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -18,12 +18,11 @@ using Microsoft.Extensions.Logging; using MySqlConnector; using Newtonsoft.Json; using System.Collections.Concurrent; -using System.Runtime.InteropServices; using System.Text; namespace CS2_SimpleAdmin; -[MinimumApiVersion(159)] +[MinimumApiVersion(163)] public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { public static IStringLocalizer? _localizer; @@ -43,13 +42,11 @@ 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 static MemoryFunctionVoid? CBasePlayerController_SetPawnFunc = null; 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.0b"; + public override string ModuleVersion => "1.3.0c"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -62,6 +59,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig - + From e401fe7c8bd9c17bad5c96fd3bc05692d42f0e0b Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Fri, 9 Feb 2024 21:54:55 +0100 Subject: [PATCH 04/10] 1.3.0d - Fixed noclip - Fixed freeze - Fixed vote --- CS2-SimpleAdmin.cs | 13 +++++++------ Helper.cs | 6 ++---- PlayerUtils.cs | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index c6baa13..e4260b5 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -31,6 +31,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig votePlayers = new HashSet(); public static ConcurrentBag godPlayers = new ConcurrentBag(); public static ConcurrentBag gaggedPlayers = new ConcurrentBag(); + public static ConcurrentBag commsPlayers = new ConcurrentBag(); public static ConcurrentBag silentPlayers = new ConcurrentBag(); public static ConcurrentBag bannedPlayers = new ConcurrentBag(); public static bool TagsDetected = false; @@ -46,7 +47,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"; - public override string ModuleVersion => "1.3.0c"; + public override string ModuleVersion => "1.3.0d"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -1885,22 +1886,21 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) { + using (new WithTemporaryCulture(_player.GetLanguage())) { - MenuManager.OpenChatMenu(_player, voteMenu); - for (int i = 2; i <= answersCount - 1; i++) - { - voteMenu.AddMenuOption(command.GetArg(i), Helper.handleVotes); - } Helper.PrintToCenterAll(_localizer!["sa_admin_vote_message", caller == null ? "Console" : caller.PlayerName, question]); StringBuilder sb = new(_localizer!["sa_prefix"]); sb.Append(_localizer["sa_admin_vote_message", caller == null ? "Console" : caller.PlayerName, question]); _player.PrintToChat(sb.ToString()); } + + MenuManager.OpenChatMenu(_player, voteMenu); } if (Config.DiscordWebhook.Length > 0 && _localizer != null) @@ -1908,6 +1908,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig GetPlayerFromSteamid64(string steamid) { return Utilities.GetPlayers().FindAll(x => - x.AuthorizedSteamID != null && - x.AuthorizedSteamID.SteamId64.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase) + x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase) ); } @@ -60,7 +59,6 @@ namespace CS2_SimpleAdmin //Console.WriteLine($"Setting immunity for SteamID {steamid} to {immunity}"); - if (flags != null) { //Console.WriteLine($"Applying flags to SteamID {steamid}:"); @@ -150,9 +148,9 @@ namespace CS2_SimpleAdmin { if (CS2_SimpleAdmin.voteInProgress && !CS2_SimpleAdmin.votePlayers.Contains(player.Slot)) { + option.Disabled = true; CS2_SimpleAdmin.votePlayers.Add(player.Slot); CS2_SimpleAdmin.voteAnswers[option.Text]++; - option.Disabled = true; } } } diff --git a/PlayerUtils.cs b/PlayerUtils.cs index 539512e..d802ff0 100644 --- a/PlayerUtils.cs +++ b/PlayerUtils.cs @@ -1,5 +1,7 @@ -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; +using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; using System.Text; @@ -80,19 +82,31 @@ public static class PlayerUtils public static void Freeze(this CBasePlayerPawn pawn) { pawn.MoveType = MoveType_t.MOVETYPE_OBSOLETE; + Schema.SetSchemaValue(pawn.Handle, "CBaseEntity", "m_nActualMoveType", 1); // obsolete + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_MoveType"); } public static void Unfreeze(this CBasePlayerPawn pawn) { pawn.MoveType = MoveType_t.MOVETYPE_WALK; + Schema.SetSchemaValue(pawn.Handle, "CBaseEntity", "m_nActualMoveType", 2); // walk + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_MoveType"); } public static void ToggleNoclip(this CBasePlayerPawn pawn) { if (pawn.MoveType == MoveType_t.MOVETYPE_NOCLIP) + { pawn.MoveType = MoveType_t.MOVETYPE_WALK; + Schema.SetSchemaValue(pawn.Handle, "CBaseEntity", "m_nActualMoveType", 2); // walk + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_MoveType"); + } else + { pawn.MoveType = MoveType_t.MOVETYPE_NOCLIP; + Schema.SetSchemaValue(pawn.Handle, "CBaseEntity", "m_nActualMoveType", 8); // noclip + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_MoveType"); + } } private static void PerformSlap(CBasePlayerPawn pawn, int damage = 0) From 01ceb104c551a9c172446f96e7f563c6fd3eb5d6 Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Sat, 10 Feb 2024 15:31:09 +0100 Subject: [PATCH 05/10] Update Events.cs --- Events.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Events.cs b/Events.cs index 2978697..defe150 100644 --- a/Events.cs +++ b/Events.cs @@ -334,15 +334,18 @@ public partial class CS2_SimpleAdmin }); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - ConVar? botQuota = ConVar.Find("bot_quota"); - if (botQuota != null && botQuota.GetPrimitiveValue() > 0) + AddTimer(2.0f, () => { - Logger.LogInformation("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); - Logger.LogWarning("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); - Logger.LogCritical("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); - } + ConVar? botQuota = ConVar.Find("bot_quota"); + if (botQuota != null && botQuota.GetPrimitiveValue() > 0) + { + Logger.LogInformation("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); + Logger.LogWarning("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); + Logger.LogCritical("Due to bugs with bots (game bug), consider disabling bots by setting `bot_quota 0` in the gamemode config if your server crashes after a map change."); + } + }); } [GameEventHandler] From 79bbe0f4c577e1557aec55402bfd0350401d8a3b Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Sun, 11 Feb 2024 03:24:27 +0100 Subject: [PATCH 06/10] 1.3.0e - Added `css_rename` - Added `css_silence` - Added `css_addsilence` - Added `css_unsilence` - PlayerPenaltyManager class - Fix for invalid players New commands localized only for `pl` and `en`, if u can please make pr for other languages --- CS2-SimpleAdmin.cs | 655 +++++++++++++++++++++++++++++++--------- CS2-SimpleAdmin.csproj | 1 + Events.cs | 114 ++++--- Helper.cs | 32 ++ MuteManager.cs | 11 +- PlayerPenaltyManager.cs | 139 +++++++++ PlayerUtils.cs | 25 ++ lang/en.json | 5 + lang/pl.json | 5 + 9 files changed, 793 insertions(+), 194 deletions(-) create mode 100644 PlayerPenaltyManager.cs diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index e4260b5..5ceb7c1 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -25,13 +25,14 @@ namespace CS2_SimpleAdmin; [MinimumApiVersion(163)] public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { + public static BasePlugin? _plugin = null; public static IStringLocalizer? _localizer; //public static ConcurrentBag mutedPlayers = new ConcurrentBag(); public static Dictionary voteAnswers = new Dictionary(); public static HashSet votePlayers = new HashSet(); public static ConcurrentBag godPlayers = new ConcurrentBag(); - public static ConcurrentBag gaggedPlayers = new ConcurrentBag(); - public static ConcurrentBag commsPlayers = new ConcurrentBag(); + //public static ConcurrentBag gaggedPlayers = new ConcurrentBag(); + //public static ConcurrentBag commsPlayers = new ConcurrentBag(); public static ConcurrentBag silentPlayers = new ConcurrentBag(); public static ConcurrentBag bannedPlayers = new ConcurrentBag(); public static bool TagsDetected = false; @@ -54,6 +55,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && !player.IsBot && !player.IsHLTV).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); Database database = new Database(dbConnectionString); BanManager _banManager = new(database, Config); @@ -292,7 +293,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = Utilities.GetPlayers().Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.Connected == PlayerConnectedState.PlayerConnected && !player.IsHLTV).ToList(); + List playersToTarget = Helper.GetValidPlayers(); if (caller != null) { @@ -397,7 +398,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) { @@ -409,8 +410,14 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (caller!.CanTarget(player)) { + if (!player.IsBot && player.SteamID.ToString().Length == 17) + return; + if (player.PawnIsAlive) { player.Pawn.Value!.Freeze(); @@ -433,7 +440,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -465,7 +472,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) { @@ -478,6 +485,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { @@ -485,14 +493,14 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -548,7 +555,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -590,6 +597,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -651,7 +659,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -669,10 +677,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig matches = Helper.GetPlayerFromSteamid64(pattern); @@ -705,13 +714,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(gaggedPlayers.Where(item => item != player.Slot)); - } + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Gag); if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID}"); + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); found = true; } @@ -725,15 +731,12 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(gaggedPlayers.Where(item => item != player.Slot)); - } + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Gag); if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID.ToString()}"); - pattern = player!.AuthorizedSteamID!.SteamId64.ToString(); + pattern = player!.SteamID.ToString(); found = true; } @@ -748,7 +751,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) { @@ -759,16 +762,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { - if (player != null && gaggedPlayers.Contains(player.Slot)) - { - gaggedPlayers = new ConcurrentBag(gaggedPlayers.Where(item => item != player.Slot)); - } + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Gag); - if (player!.AuthorizedSteamID != null) - _ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 0); // Unmute by type 0 (gag) + if (player!.SteamID.ToString().Length == 17) + _ = _muteManager.UnmutePlayer(player.SteamID.ToString(), 0); // Unmute by type 0 (gag) if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID}"); + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); }); command.ReplyToCommand($"Ungaged player with pattern {pattern}."); @@ -790,7 +790,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) { @@ -803,6 +803,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { @@ -810,23 +811,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig @@ -834,6 +830,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -869,7 +867,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -912,6 +910,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -971,7 +972,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -987,11 +988,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) { @@ -1082,19 +1061,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { - /* - if (mutedPlayers.Contains((int)player.Index)) - { - if (mutedPlayers.TryTake(out int removedItem) && removedItem != (int)player.Index) - { - mutedPlayers.Add(removedItem); - } - } - */ - - if (player.AuthorizedSteamID != null) - _ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 1); // Unmute by type 1 (mute) + if (player.SteamID.ToString().Length == 17) + _ = _muteManager.UnmutePlayer(player.SteamID.ToString(), 1); // Unmute by type 1 (mute) + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Mute); player.VoiceFlags = VoiceFlags.Normal; }); @@ -1105,6 +1075,321 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig [time in minutes/0 perm] [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + public void OnSilenceCommand(CCSPlayerController? caller, CommandInfo command) + { + if (_database == null) return; + + int time = 0; + string reason = "Unknown"; + + TargetResult? targets = GetTarget(command); + if (targets == null) return; + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); + + if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) + { + return; + } + + int.TryParse(command.GetArg(2), out time); + + if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) + reason = command.GetArg(3); + + MuteManager _muteManager = new(_database); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + + playersToTarget.ForEach(player => + { + if (caller!.CanTarget(player)) + { + PlayerInfo playerInfo = new PlayerInfo + { + SteamId = player?.SteamID.ToString(), + Name = player?.PlayerName, + IpAddress = player?.IpAddress?.Split(":")[0] + }; + + PlayerInfo adminInfo = new PlayerInfo + { + SteamId = caller?.SteamID.ToString(), + Name = caller?.PlayerName, + IpAddress = caller?.IpAddress?.Split(":")[0] + }; + + Task.Run(async () => + { + await _muteManager.MutePlayer(playerInfo, adminInfo, reason, time, 2); + }); + + if (TagsDetected) + Server.ExecuteCommand($"css_tag_mute {player!.SteamID}"); + + playerPenaltyManager.AddPenalty(player!.Slot, PenaltyType.Silence, DateTime.Now.AddMinutes(time), time); + + if (time == 0) + { + if (!player!.IsBot && !player.IsHLTV) + { + using (new WithTemporaryCulture(player.GetLanguage())) + { + player.PrintToCenter(_localizer!["sa_player_silence_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); + } + } + + if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) + { + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_silence_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); + _player.PrintToChat(sb.ToString()); + } + } + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + { + LocalizedString localizedMessage = _localizer["sa_admin_silence_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; + _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); + } + } + } + else + { + if (!player!.IsBot && !player.IsHLTV) + { + using (new WithTemporaryCulture(player.GetLanguage())) + { + player!.PrintToCenter(_localizer!["sa_player_silence_message_time", reason, time, caller == null ? "Console" : caller.PlayerName]); + } + } + + if (caller == null || caller != null && caller != null && !silentPlayers.Contains(caller.Slot)) + { + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_silence_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]); + _player.PrintToChat(sb.ToString()); + } + } + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + { + LocalizedString localizedMessage = _localizer["sa_admin_silence_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; + _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); + } + } + } + } + }); + } + + [ConsoleCommand("css_addsilence")] + [RequiresPermissions("@css/chat")] + [CommandHelper(minArgs: 1, usage: "<#userid or name> [time in minutes/0 perm] [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + public void OnAddSilenceCommand(CCSPlayerController? caller, CommandInfo command) + { + if (_database == null) return; + + if (command.ArgCount < 2) + return; + if (string.IsNullOrEmpty(command.GetArg(1))) return; + + string steamid = command.GetArg(1); + + if (!Helper.IsValidSteamID64(steamid)) + { + command.ReplyToCommand($"Invalid SteamID64."); + return; + } + + int time = 0; + string reason = "Unknown"; + + MuteManager _muteManager = new(_database); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + + int.TryParse(command.GetArg(2), out time); + + if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) + reason = command.GetArg(3); + + PlayerInfo adminInfo = new PlayerInfo + { + SteamId = caller?.SteamID.ToString(), + Name = caller?.PlayerName, + IpAddress = caller?.IpAddress?.Split(":")[0] + }; + + List matches = Helper.GetPlayerFromSteamid64(steamid); + if (matches.Count == 1) + { + CCSPlayerController? player = matches.FirstOrDefault(); + if (player != null && player.IsValid) + { + if (!caller!.CanTarget(player)) + { + command.ReplyToCommand($"{player.PlayerName} is more powerful than you!"); + return; + } + + if (TagsDetected) + Server.ExecuteCommand($"css_tag_mute {player!.SteamID}"); + + playerPenaltyManager.AddPenalty(player!.Slot, PenaltyType.Silence, DateTime.Now.AddMinutes(time), time); + + if (time == 0) + { + if (!player.IsBot && !player.IsHLTV) + using (new WithTemporaryCulture(player.GetLanguage())) + { + player!.PrintToCenter(_localizer!["sa_player_silence_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); + } + if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) + { + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_silence_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); + _player.PrintToChat(sb.ToString()); + } + } + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + { + LocalizedString localizedMessage = _localizer["sa_admin_silence_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; + _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); + } + } + } + else + { + if (!player.IsBot && !player.IsHLTV) + using (new WithTemporaryCulture(player.GetLanguage())) + { + player!.PrintToCenter(_localizer!["sa_player_silence_message_time", reason, time, caller == null ? "Console" : caller.PlayerName]); + } + if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) + { + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_silence_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]); + _player.PrintToChat(sb.ToString()); + } + } + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + { + LocalizedString localizedMessage = _localizer["sa_admin_silence_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; + _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); + } + } + } + } + } + _ = _muteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 2); + command.ReplyToCommand($"Silenced player with steamid {steamid}."); + } + + [ConsoleCommand("css_unsilence")] + [RequiresPermissions("@css/chat")] + [CommandHelper(minArgs: 1, usage: "", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + public void OnUnsilenceCommand(CCSPlayerController? caller, CommandInfo command) + { + if (_database == null) return; + + if (command.GetArg(1).Length <= 1) + { + command.ReplyToCommand($"Too short pattern to search."); + return; + } + + string pattern = command.GetArg(1); + bool found = false; + MuteManager _muteManager = new(_database); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + + if (Helper.IsValidSteamID64(pattern)) + { + List matches = Helper.GetPlayerFromSteamid64(pattern); + if (matches.Count == 1) + { + CCSPlayerController? player = matches.FirstOrDefault(); + if (player != null && player.IsValid) + { + if (TagsDetected) + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); + + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Silence); + player.VoiceFlags = VoiceFlags.Normal; + found = true; + } + } + } + else + { + List matches = Helper.GetPlayerFromName(pattern); + if (matches.Count == 1) + { + CCSPlayerController? player = matches.FirstOrDefault(); + if (player != null && player.IsValid) + { + if (TagsDetected) + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); + + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Silence); + player.VoiceFlags = VoiceFlags.Normal; + pattern = player.SteamID.ToString(); + found = true; + } + } + } + + if (found) + { + _ = _muteManager.UnmutePlayer(pattern, 2); // Unmute by type 2 (silence) + command.ReplyToCommand($"Unsilenced player with pattern {pattern}."); + return; + } + + TargetResult? targets = GetTarget(command); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); + + if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) + { + return; + } + + if (playersToTarget.Count > 1) + { + playersToTarget.ForEach(player => + { + if (player.SteamID.ToString().Length == 17) + _ = _muteManager.UnmutePlayer(player.SteamID.ToString(), 2); // Unmute by type 2 (silence) + + if (TagsDetected) + Server.ExecuteCommand($"css_tag_unmute {player!.SteamID}"); + + playerPenaltyManager.RemovePenaltiesByType(player!.Slot, PenaltyType.Silence); + player.VoiceFlags = VoiceFlags.Normal; + }); + + command.ReplyToCommand($"Unsilenced player with pattern {pattern}."); + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + _ = SendWebhookMessage($"Unsilenced player with pattern {pattern}."); + return; + } + } + [ConsoleCommand("css_ban")] [RequiresPermissions("@css/ban")] [CommandHelper(minArgs: 1, usage: "<#userid or name> [time in minutes/0 perm] [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] @@ -1118,7 +1403,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) { @@ -1146,14 +1431,14 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1205,7 +1490,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1256,7 +1541,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1311,7 +1596,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1363,7 +1648,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1422,7 +1707,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1485,15 +1770,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + player.CommitSuicide(false, true); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1519,7 +1807,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); + string weaponName = command.GetArg(2); @@ -1549,11 +1839,14 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + player.GiveNamedItem(weaponName); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1578,18 +1871,21 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { if (caller!.CanTarget(player)) { - player.RemoveWeapons(); + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + player.RemoveWeapons(); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1618,18 +1914,20 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { if (caller!.CanTarget(player)) { - player.SetHp(health); + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + player.SetHp(health); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1658,10 +1956,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (caller!.CanTarget(player)) { /* @@ -1673,7 +1974,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1699,10 +2000,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (caller!.CanTarget(player)) { if (player != null) @@ -1719,7 +2023,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1748,7 +2052,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); if (command.ArgCount >= 2) { @@ -1757,13 +2061,16 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (caller!.CanTarget(player)) { player!.Pawn.Value!.Slap(damage); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1793,7 +2100,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && !player.IsHLTV).ToList(); switch (teamName) { @@ -1822,6 +2129,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (!teamName.Equals("swap")) { if (player.PawnIsAlive && teamNum != CsTeam.Spectator && !command.GetArg(3).ToLower().Equals("-k") && Config.TeamSwitchType == 1) @@ -1848,7 +2158,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1889,7 +2199,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) @@ -1916,7 +2226,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1933,7 +2243,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig kvp in voteAnswers) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -1991,7 +2301,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2037,7 +2347,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2069,7 +2379,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV && AdminManager.PlayerHasPermissions(p, "@css/chat"))) + foreach (CCSPlayerController _player in Helper.GetValidPlayers().Where(p => AdminManager.PlayerHasPermissions(p, "@css/chat"))) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2093,7 +2403,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2113,7 +2423,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && !player.IsHLTV).ToList(); int range = command.GetArg(0).Length + command.GetArg(1).Length + 2; string message = command.GetCommandString[range..]; @@ -2167,7 +2477,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.SteamID.ToString().Length == 17 && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { @@ -2177,7 +2487,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2205,10 +2515,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (caller!.CanTarget(player)) { player!.Pawn.Value!.Freeze(); @@ -2218,7 +2531,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2243,15 +2556,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid && player.PawnIsAlive).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && player.PawnIsAlive && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + player!.Pawn.Value!.Unfreeze(); if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { @@ -2269,16 +2585,63 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig ")] + [RequiresPermissions("@css/kick")] + public void OnRenameCommand(CCSPlayerController? caller, CommandInfo command) + { + string? newName = command.GetArg(2); + + if (string.IsNullOrEmpty(newName)) + return; + + TargetResult? targets = GetTarget(command); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && !player.IsHLTV).ToList(); + + playersToTarget.ForEach(player => + { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + + if (caller!.CanTarget(player)) + { + player.Rename(newName); + + if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) + { + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_rename_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, newName]); + _player.PrintToChat(sb.ToString()); + } + } + } + + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + { + LocalizedString localizedMessage = _localizer["sa_admin_rename_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, newName]; + _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); + } + } + }); + } + [ConsoleCommand("css_respawn", "Respawn a dead player.")] [CommandHelper(1, "<#userid or name>")] [RequiresPermissions("@css/cheats")] public void OnRespawnCommand(CCSPlayerController? caller, CommandInfo command) { TargetResult? targets = GetTarget(command); - List playersToTarget = targets!.Players.Where(player => caller!.CanTarget(player) && player != null && player.IsValid).ToList(); + List playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && !player.IsHLTV).ToList(); playersToTarget.ForEach(player => { + if (!player.IsBot && player.SteamID.ToString().Length != 17) + return; + if (caller!.CanTarget(player)) { if (CBasePlayerController_SetPawnFunc == null || player.PlayerPawn.Value == null || !player.PlayerPawn.IsValid) return; @@ -2290,7 +2653,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + foreach (CCSPlayerController _player in Helper.GetValidPlayers()) { using (new WithTemporaryCulture(_player.GetLanguage())) { diff --git a/CS2-SimpleAdmin.csproj b/CS2-SimpleAdmin.csproj index 2d05889..dcf84d6 100644 --- a/CS2-SimpleAdmin.csproj +++ b/CS2-SimpleAdmin.csproj @@ -6,6 +6,7 @@ enable enable true + true diff --git a/Events.cs b/Events.cs index defe150..8627851 100644 --- a/Events.cs +++ b/Events.cs @@ -21,37 +21,24 @@ public partial class CS2_SimpleAdmin //RegisterListener(OnClientDisconnect); //RegisterEventHandler(OnPlayerFullConnect); RegisterListener(OnMapStart); + RegisterListener(OnClientVoice); //RegisterEventHandler(OnPlayerHurt); //RegisterEventHandler(OnRoundStart); AddCommandListener("say", OnCommandSay); AddCommandListener("say_team", OnCommandTeamSay); } - /*private HookResult OnPlayerFullConnect(EventPlayerConnectFull @event, GameEventInfo info) + private void OnClientVoice(int playerSlot) { - CCSPlayerController? player = @event.Userid; + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + if (!playerPenaltyManager.IsSlotInPenalties(playerSlot)) return; - if (player is null || player.IsBot || player.IsHLTV) return HookResult.Continue; + CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot); + if (player is null || !player.IsValid) return; - PlayerInfo playerInfo = new PlayerInfo - { - UserId = player.UserId, - Index = (ushort)player.UserId, - SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), - Name = player?.PlayerName, - IpAddress = player?.IpAddress?.Split(":")[0] - }; - - Task.Run(async () => - { - Server.NextFrame(() => - { - if (player is null) return; - }); - }); - return HookResult.Continue; + if (playerPenaltyManager.IsPenalized(playerSlot, PenaltyType.Mute) || playerPenaltyManager.IsPenalized(playerSlot, PenaltyType.Silence)) + player.VoiceFlags = VoiceFlags.Muted; } - */ [GameEventHandler] private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) @@ -67,10 +54,10 @@ public partial class CS2_SimpleAdmin { if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; - if (player != null && gaggedPlayers.Contains(player.Slot)) - { + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + + if (playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) || playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence)) return HookResult.Handled; - } return HookResult.Continue; } @@ -79,10 +66,10 @@ public partial class CS2_SimpleAdmin { if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; - if (player != null && gaggedPlayers.Contains(player.Slot)) - { + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + + if (playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) || playerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence)) return HookResult.Handled; - } if (info.GetArg(1).StartsWith("@")) { @@ -173,14 +160,18 @@ public partial class CS2_SimpleAdmin if (activeMutes.Count > 0) { + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); foreach (var mute in activeMutes) { string muteType = mute.type; if (muteType == "GAG") { + /* if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) gaggedPlayers.Add(playerInfo.Slot.Value); + */ + playerPenaltyManager.AddPenalty(1, PenaltyType.Gag, DateTime.Parse(mute.ends), mute.duration); if (TagsDetected) { @@ -192,16 +183,16 @@ public partial class CS2_SimpleAdmin } else if (muteType == "MUTE") { - Server.NextFrame(() => - { - if (player.IsValid) - player.VoiceFlags = VoiceFlags.Muted; - }); + playerPenaltyManager.AddPenalty(1, PenaltyType.Mute, DateTime.Parse(mute.ends), mute.duration); + } else { - if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) + /* + * if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) gaggedPlayers.Add(playerInfo.Slot.Value); + */ + playerPenaltyManager.AddPenalty(1, PenaltyType.Silence, DateTime.Parse(mute.ends), mute.duration); Server.NextFrame(() => { @@ -211,10 +202,8 @@ public partial class CS2_SimpleAdmin { Server.ExecuteCommand($"css_tag_mute {playerInfo.SteamId}"); } - player.VoiceFlags = VoiceFlags.Muted; } }); - } } } @@ -241,7 +230,9 @@ public partial class CS2_SimpleAdmin Logger.LogCritical("[OnClientDisconnect] After Check"); #endif - RemoveFromConcurrentBag(gaggedPlayers, player.Slot); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + playerPenaltyManager.RemoveAllPenalties(player.Slot); + //RemoveFromConcurrentBag(gaggedPlayers, player.Slot); RemoveFromConcurrentBag(silentPlayers, player.Slot); RemoveFromConcurrentBag(godPlayers, player.Slot); @@ -253,33 +244,70 @@ public partial class CS2_SimpleAdmin } if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player.SteamID}"); + Server.ExecuteCommand($"css_tag_unmute {player.SteamID}"); return HookResult.Continue; } private void OnMapStart(string mapName) { - gaggedPlayers.Clear(); + Random random = new Random(); + //gaggedPlayers.Clear(); godPlayers.Clear(); silentPlayers.Clear(); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); + playerPenaltyManager.RemoveAllPenalties(); + _database = new(dbConnectionString); if (_database == null) return; - AddTimer(60.0f, bannedPlayers.Clear, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - AddTimer(130.0f, async () => + AddTimer(random.Next(60, 80), async () => { +#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(); -#if DEBUG - Logger.LogCritical("[OnMapStart] Expired check"); -#endif + + bannedPlayers.Clear(); + + Server.NextFrame(() => + { + foreach (CCSPlayerController player in Helper.GetValidPlayers()) + { + if (playerPenaltyManager.IsSlotInPenalties(player.Slot)) + { + 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(); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); diff --git a/Helper.cs b/Helper.cs index 4df7b3f..84db15f 100644 --- a/Helper.cs +++ b/Helper.cs @@ -2,9 +2,12 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; +using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Menu; using CounterStrikeSharp.API.Modules.Utils; using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; using System.Text.RegularExpressions; namespace CS2_SimpleAdmin @@ -33,6 +36,12 @@ namespace CS2_SimpleAdmin ); } + 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); + } + + public static bool IsValidSteamID64(string input) { string pattern = @"^\d{17}$"; @@ -154,4 +163,27 @@ namespace CS2_SimpleAdmin } } } + + public class SchemaString : NativeObject where SchemaClass : NativeObject + { + public SchemaString(SchemaClass instance, string member) : base(Schema.GetSchemaValue(instance.Handle, typeof(SchemaClass).Name!, member)) + { } + + public unsafe void Set(string str) + { + byte[] bytes = this.GetStringBytes(str); + + for (int i = 0; i < bytes.Length; i++) + { + Unsafe.Write((void*)(this.Handle.ToInt64() + i), bytes[i]); + } + + Unsafe.Write((void*)(this.Handle.ToInt64() + bytes.Length), 0); + } + + private byte[] GetStringBytes(string str) + { + return Encoding.ASCII.GetBytes(str); + } + } } \ No newline at end of file diff --git a/MuteManager.cs b/MuteManager.cs index e7075cf..088be35 100644 --- a/MuteManager.cs +++ b/MuteManager.cs @@ -25,6 +25,8 @@ namespace CS2_SimpleAdmin string muteType = "GAG"; if (type == 1) muteType = "MUTE"; + else if (type == 2) + muteType = "SILENCE"; var sql = "INSERT INTO `sa_mutes` (`player_steamid`, `player_name`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `type`, `server_id`) " + "VALUES (@playerSteamid, @playerName, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @type, @serverid)"; @@ -56,6 +58,8 @@ namespace CS2_SimpleAdmin string muteType = "GAG"; if (type == 1) muteType = "MUTE"; + else if (type == 2) + muteType = "SILENCE"; var sql = "INSERT INTO `sa_mutes` (`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `type`, `server_id`) " + "VALUES (@playerSteamid, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @type, @serverid)"; @@ -136,6 +140,8 @@ namespace CS2_SimpleAdmin { muteType = "MUTE"; } + else if (type == 2) + muteType = "SILENCE"; string sqlUnban = "UPDATE sa_mutes SET status = 'UNMUTED' WHERE (player_steamid = @pattern OR player_name = @pattern) AND type = @muteType AND status = 'ACTIVE'"; await connection.ExecuteAsync(sqlUnban, new { pattern = playerPattern, muteType }); @@ -174,11 +180,6 @@ namespace CS2_SimpleAdmin if (muteType == "GAG") { - if (player.Slot.HasValue && !CS2_SimpleAdmin.gaggedPlayers.Contains(player.Slot.Value)) - { - CS2_SimpleAdmin.gaggedPlayers.Add(player.Slot.Value); - } - if (CS2_SimpleAdmin.TagsDetected) NativeAPI.IssueServerCommand($"css_tag_mute {player!.SteamId}"); diff --git a/PlayerPenaltyManager.cs b/PlayerPenaltyManager.cs new file mode 100644 index 0000000..d8cae04 --- /dev/null +++ b/PlayerPenaltyManager.cs @@ -0,0 +1,139 @@ +using System.Collections.Concurrent; + +namespace CS2_SimpleAdmin +{ + public enum PenaltyType + { + Mute, + Gag, + Silence + } + + public class PlayerPenaltyManager + { + private static ConcurrentDictionary>> penalties = + new ConcurrentDictionary>>(); + + // 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)); + } + + public bool IsPenalized(int slot, PenaltyType penaltyType) + { + //Console.WriteLine($"Checking penalties for player with slot {slot} and penalty type {penaltyType}"); + + if (penalties.TryGetValue(slot, out var penaltyDict) && penaltyDict.TryGetValue(penaltyType, out var penaltiesList)) + { + //Console.WriteLine($"Found penalties for player with slot {slot} and penalty type {penaltyType}"); + + DateTime now = DateTime.Now; + + // Check if any active penalties exist + foreach (var penalty in penaltiesList.ToList()) + { + // Check if the penalty is still active + if (penalty.Duration > 0 && now >= penalty.EndDateTime.AddSeconds(penalty.Duration)) + { + //Console.WriteLine($"Removing expired penalty for player with slot {slot} and penalty type {penaltyType}"); + penaltiesList.Remove(penalty); // Remove expired penalty + if (penaltiesList.Count == 0) + { + //Console.WriteLine($"No more penalties of type {penaltyType} for player with slot {slot}. Removing penalty type."); + penaltyDict.Remove(penaltyType); // Remove penalty type if no more penalties exist + } + } + else if (penalty.Duration == 0 || now < penalty.EndDateTime) + { + //Console.WriteLine($"Player with slot {slot} is penalized for type {penaltyType}"); + // Return true if there's an active penalty + return true; + } + } + + // Return false if no active penalties are found + //Console.WriteLine($"Player with slot {slot} is not penalized for type {penaltyType}"); + return false; + } + + // Return false if no penalties of the specified type were found for the player + //Console.WriteLine($"No penalties found for player with slot {slot} and penalty type {penaltyType}"); + return false; + } + + // Get the end datetime and duration of penalties for a player and penalty type + public List<(DateTime EndDateTime, int Duration)> GetPlayerPenalties(int slot, PenaltyType penaltyType) + { + if (penalties.TryGetValue(slot, out Dictionary>? penaltyDict) && + penaltyDict.TryGetValue(penaltyType, out List<(DateTime EndDateTime, int Duration)>? penaltiesList) && penaltiesList != null) + { + return penaltiesList; + } + return new List<(DateTime EndDateTime, int Duration)>(); + } + + public bool IsSlotInPenalties(int slot) + { + return penalties.ContainsKey(slot); + } + + // Remove all penalties for a player slot + public void RemoveAllPenalties(int slot) + { + if (penalties.ContainsKey(slot)) + { + penalties.TryRemove(slot, out _); + } + } + + // Remove all penalties + public void RemoveAllPenalties() + { + penalties.Clear(); + } + + // Remove all penalties of a selected type from a specific player + public void RemovePenaltiesByType(int slot, PenaltyType penaltyType) + { + if (penalties.TryGetValue(slot, out Dictionary>? penaltyDict) && + penaltyDict.ContainsKey(penaltyType)) + { + penaltyDict.Remove(penaltyType); + } + } + + // Remove all expired penalties for all players and penalty types + public void RemoveExpiredPenalties() + { + DateTime now = DateTime.Now; + foreach (var kvp in penalties.ToList()) // Use ToList to avoid modification while iterating + { + var playerSlot = kvp.Key; + var penaltyDict = kvp.Value; + + // Remove expired penalties for the player + foreach (var penaltiesList in penaltyDict.Values) + { + penaltiesList.RemoveAll(p => p.Duration > 0 && now >= p.EndDateTime.AddSeconds(p.Duration)); + } + + // Remove player slot if no penalties left + if (penaltyDict.Count == 0) + { + penalties.TryRemove(playerSlot, out _); + } + } + } + } +} \ No newline at end of file diff --git a/PlayerUtils.cs b/PlayerUtils.cs index d802ff0..874afed 100644 --- a/PlayerUtils.cs +++ b/PlayerUtils.cs @@ -109,6 +109,31 @@ public static class PlayerUtils } } + public static void Rename(this CCSPlayerController controller, string newName = "Unknown") + { + if (CS2_SimpleAdmin._plugin == null) + return; + + SchemaString playerName = new SchemaString(controller, "m_iszPlayerName"); + playerName.Set(newName + " "); + + CS2_SimpleAdmin._plugin.AddTimer(0.25f, () => + { + Utilities.SetStateChanged(controller, "CCSPlayerController", "m_szClan"); + Utilities.SetStateChanged(controller, "CBasePlayerController", "m_iszPlayerName"); + }); + + CS2_SimpleAdmin._plugin.AddTimer(0.3f, () => + { + playerName.Set(newName); + }); + + CS2_SimpleAdmin._plugin.AddTimer(0.4f, () => + { + Utilities.SetStateChanged(controller, "CBasePlayerController", "m_iszPlayerName"); + }); + } + private static void PerformSlap(CBasePlayerPawn pawn, int damage = 0) { if (pawn.LifeState != (int)LifeState_t.LIFE_ALIVE) diff --git a/lang/en.json b/lang/en.json index f49baed..099961d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -8,6 +8,8 @@ "sa_player_gag_message_perm": "You have been gagged permanently for {lightred}{0}{default} by {lightred}{1}{default}!", "sa_player_mute_message_time": "You have been muted for {lightred}{0}{default} for {lightred}{1}{default} minutes by {lightred}{2}{default}!", "sa_player_mute_message_perm": "You have been muted permanently for {lightred}{0}{default} by {lightred}{1}{default}!", + "sa_player_silence_message_time": "You have been silenced for {lightred}{0}{default} for {lightred}{1}{default} minutes by {lightred}{2}{default}!", + "sa_player_silence_message_perm": "You have been silenced permanently for {lightred}{0}{default} by {lightred}{1}{default}!", "sa_admin_ban_message_time": "Admin {lightred}{0}{default} banned {lightred}{1}{default} for {lightred}{2}{default} for {lightred}{3}{default} minutes!", "sa_admin_ban_message_perm": "Admin {lightred}{0}{default} banned {lightred}{1}{default} permanently for {lightred}{2}{default}!", "sa_admin_kick_message": "Admin {lightred}{0}{default} kicked {lightred}{1}{default} for {lightred}{2}{default}!", @@ -15,6 +17,8 @@ "sa_admin_gag_message_perm": "Admin {lightred}{0}{default} gagged {lightred}{1}{default} permanently for {lightred}{2}{default}!", "sa_admin_mute_message_time": "Admin {lightred}{0}{default} muted {lightred}{1}{default} for {lightred}{2}{default} for {lightred}{3}{default} minutes!", "sa_admin_mute_message_perm": "Admin {lightred}{0}{default} muted {lightred}{1}{default} permanently for {lightred}{2}{default}!", + "sa_admin_silence_message_time": "Admin {lightred}{0}{default} silenced {lightred}{1}{default} for {lightred}{2}{default} for {lightred}{3}{default} minutes!", + "sa_admin_silence_message_perm": "Admin {lightred}{0}{default} silenced {lightred}{1}{default} permanently for {lightred}{2}{default}!", "sa_admin_give_message": "Admin {lightred}{0}{default} gave {lightred}{1}{default} a {lightred}{2}{default}!", "sa_admin_strip_message": "Admin {lightred}{0}{default} took all of player {lightred}{1}{default} weapons!", "sa_admin_hp_message": "Admin {lightred}{0}{default} changed {lightred}{1}{default} hp amount{default}!", @@ -26,6 +30,7 @@ "sa_admin_noclip_message": "Admin {lightred}{0}{default} toggled noclip for {lightred}{1}{default}!", "sa_admin_freeze_message": "Admin {lightred}{0}{default} freezed {lightred}{1}{default}!", "sa_admin_unfreeze_message": "Admin {lightred}{0}{default} umfreezed {lightred}{1}{default}!", + "sa_admin_rename_message": "Admin {lightred}{0}{default} changed {lightred}{1}{default} nickname to {lightred}{2}{default}!", "sa_admin_respawn_message": "Admin {lightred}{0}{default} respawned {lightred}{1}{default}!", "sa_admin_team_message": "Admin {lightred}{0}{default} transfered {lightred}{1}{default} to {lightred}{2}{default}!", "sa_admin_vote_menu_title": "{lime}VOTING FOR {gold}{0}", diff --git a/lang/pl.json b/lang/pl.json index 048017c..f2823f1 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -8,6 +8,8 @@ "sa_player_gag_message_perm": "Zostałeś zakneblowany na zawsze za {lightred}{0}{default} przez {lightred}{1}{default}!", "sa_player_mute_message_time": "Zostałeś uciszony za {lightred}{0}{default} na {lightred}{1}{default} minute przez {lightred}{2}{default}!", "sa_player_mute_message_perm": "Zostałeś uciszony na zawsze za {lightred}{0}{default} przez {lightred}{1}{default}!", + "sa_player_silence_message_time": "Zostałeś wyciszony za {lightred}{0}{default} na {lightred}{1}{default} minut przez {lightred}{2}{default}!", + "sa_player_silence_message_perm": "Zostałeś wyciszony na zawsze za {lightred}{0}{default} przez {lightred}{1}{default}!", "sa_admin_ban_message_time": "Admin {lightred}{0}{default} zbanował {lightred}{1}{default} za {lightred}{2}{default} na {lightred}{3}{default} minut!", "sa_admin_ban_message_perm": "Admin {lightred}{0}{default} zbanował {lightred}{1}{default} na zawsze za {lightred}{2}{default}!", "sa_admin_kick_message": "Admin {lightred}{0}{default} wyrzucił {lightred}{1}{default} za {lightred}{2}{default}!", @@ -15,6 +17,8 @@ "sa_admin_gag_message_perm": "Admin {lightred}{0}{default} zakneblował {lightred}{1}{default} na zawsze za {lightred}{2}{default}!", "sa_admin_mute_message_time": "Admin {lightred}{0}{default} uciszył {lightred}{1}{default} za {lightred}{2}{default} na {lightred}{3}{default} minut!", "sa_admin_mute_message_perm": "Admin {lightred}{0}{default} uciszył {lightred}{1}{default} na zawsze za {lightred}{2}{default}!", + "sa_admin_silence_message_time": "Admin {lightred}{0}{default} wyciszył {lightred}{1}{default} za {lightred}{2}{default} na {lightred}{3}{default} minut!", + "sa_admin_silence_message_perm": "Admin {lightred}{0}{default} wyciszył {lightred}{1}{default} na zawsze za {lightred}{2}{default}!", "sa_admin_give_message": "Admin {lightred}{0}{default} dał {lightred}{1}{default} przedmiot {lightred}{2}{default}!", "sa_admin_strip_message": "Admin {lightred}{0}{default} zabrał wszystkie bronie {lightred}{1}{default}!", "sa_admin_hp_message": "Admin {lightred}{0}{default} zmienił ilość hp dla {lightred}{1}{default}!", @@ -26,6 +30,7 @@ "sa_admin_noclip_message": "Admin {lightred}{0}{default} ustawił latanie dla {lightred}{1}{default}!", "sa_admin_freeze_message": "Admin {lightred}{0}{default} zamroził {lightred}{1}{default}!", "sa_admin_unfreeze_message": "Admin {lightred}{0}{default} odmroził {lightred}{1}{default}!", + "sa_admin_rename_message": "Admin {lightred}{0}{default} zmienił nick gracza {lightred}{1}{default} na {lightred}{2}{default}!", "sa_admin_respawn_message": "Admin {lightred}{0}{default} odrodził {lightred}{1}{default}!", "sa_admin_team_message": "Admin {lightred}{0}{default} przerzucił {lightred}{1}{default} do {lightred}{2}{default}!", "sa_admin_vote_menu_title": "{lime}GŁOSOWANIE NA {gold}{0}", From 0b2a520a0737e764bed1f7e9aebbe988fa31f79c Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Sun, 11 Feb 2024 03:39:42 +0100 Subject: [PATCH 07/10] 1.3.0e - Added `css_sa_upgrade` command --- CS2-SimpleAdmin.cs | 30 +++++++++++++++++++++++++++++- README.md | 6 +++++- database_setup.sql | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index 5ceb7c1..0f16da1 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -48,7 +48,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"; - public override string ModuleVersion => "1.3.0d"; + public override string ModuleVersion => "1.3.0e"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -121,6 +121,34 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig + { + try + { + using (var connection = await _database.GetConnectionAsync()) + { + var commandText = "ALTER TABLE `sa_mutes` CHANGE `type` `type` ENUM('GAG','MUTE', 'SILENCE', '') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'GAG';"; + + using (var command = connection.CreateCommand()) + { + command.CommandText = commandText; + await command.ExecuteNonQueryAsync(); + } + } + } + catch (Exception ex) + { + Logger.LogError($"{ex.Message}"); + } + }); + } + [ConsoleCommand("css_admin")] [RequiresPermissions("@css/generic")] public void OnAdminCommand(CCSPlayerController? caller, CommandInfo command) diff --git a/README.md b/README.md index 17164f2..b63471e 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,9 @@ Manage your Counter-Strike 2 server by simple commands :) - css_mute <#userid or name> [time in minutes/0 perm] [reason] - Mute player // @css/chat - css_addmute [time in minutes/0 perm] [reason] - Mute player via steamid64 // @css/chat - css_unmute - Unmute player // @css/chat +- css_silence <#userid or name> [time in minutes/0 perm] [reason] - Silence player // @css/chat +- css_addsilence [time in minutes/0 perm] [reason] - Silence player via steamid64 // @css/chat +- css_unsilence - Unsilence player // @css/chat - css_give <#userid or name> - Give weapon to player // @css/cheats - css_strip <#userid or name> - Takes all of the player weapons // @css/slay - css_hp <#userid or name> [health] - Set player health // @css/slay @@ -49,6 +52,7 @@ Manage your Counter-Strike 2 server by simple commands :) - css_noclip <#userid or name> - Toggle noclip for player // @css/cheats - css_freeze <#userid or name> [duration] - Freeze player // @css/slay - css_unfreeze <#userid or name> - Unfreeze player // @css/slay +- css_rename <#userid or name> - Rename player // @css/kick - css_respawn <#userid or name> - Respawn player // @css/cheats - css_cvar - Change cvar value // @css/cvar - css_rcon - Run command as server // @css/rcon @@ -58,7 +62,7 @@ Manage your Counter-Strike 2 server by simple commands :) ``` ### Requirments -- [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp/) **tested on v159** +- [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp/) **tested on v163** - MySQL **tested on MySQL (MariaDB) Server version: 10.11.4-MariaDB-1~deb12u1 Debian 12** diff --git a/database_setup.sql b/database_setup.sql index 1f18e62..b3dcdb0 100644 --- a/database_setup.sql +++ b/database_setup.sql @@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS `sa_mutes` ( `duration` int(11) NOT NULL, `ends` timestamp NOT NULL, `created` timestamp NOT NULL, - `type` enum('GAG','MUTE','') NOT NULL DEFAULT 'GAG', + `type` enum('GAG','MUTE','SILENCE','') NOT NULL DEFAULT 'GAG', `server_id` INT NULL, `status` enum('ACTIVE','UNMUTED','EXPIRED','') NOT NULL DEFAULT 'ACTIVE', PRIMARY KEY (`id`) From aadcaa0e64c68d990be098db0e65ed92643293a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?crist=C3=B3bal?= <36176343+criskkky@users.noreply.github.com> Date: Sun, 11 Feb 2024 00:04:08 -0300 Subject: [PATCH 08/10] 1.3.0e Updated: Spanish Language Support --- lang/es.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lang/es.json b/lang/es.json index 32bc1c8..44d7652 100644 --- a/lang/es.json +++ b/lang/es.json @@ -8,6 +8,11 @@ "sa_player_gag_message_perm": "Has sido silenciado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}.", "sa_player_mute_message_time": "Has sido silenciado por {lightred}{0}{default} durante {lightred}{1}{default} minutos por {lightred}{2}{default}.", "sa_player_mute_message_perm": "Has sido silenciado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}.", + "sa_player_silence_message_time": "Has sido silenciado por {lightred}{0}{default} durante {lightred}{1}{default} minutos por {lightred}{2}{default}.", + "sa_player_silence_message_perm": "Has sido silenciado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}.", + "sa_admin_silence_message_time": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} por {lightred}{2}{default} durante {lightred}{3}{default} minutos.", + "sa_admin_silence_message_perm": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", + "sa_admin_rename_message": "El administrador {lightred}{0}{default} ha cambiado el nombre de {lightred}{1}{default} a {lightred}{2}{default}." "sa_admin_ban_message_time": "El administrador {lightred}{0}{default} ha baneado a {lightred}{1}{default} por {lightred}{2}{default} durante {lightred}{3}{default} minutos.", "sa_admin_ban_message_perm": "El administrador {lightred}{0}{default} ha baneado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", "sa_admin_kick_message": "El administrador {lightred}{0}{default} ha expulsado a {lightred}{1}{default} por {lightred}{2}{default}.", @@ -35,4 +40,4 @@ "sa_adminsay_prefix": "{RED}ADMIN: {lightred}{0}{default}", "sa_adminchat_template_admin": "{LIME}(ADMIN) {lightred}{0}{default}: {lightred}{1}{default}", "sa_adminchat_template_player": "{SILVER}(JUGADOR) {lightred}{0}{default}: {lightred}{1}{default}" -} \ No newline at end of file +} From 76914be5555c2cdcac1ce0dd49386a8073827958 Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Sun, 11 Feb 2024 04:15:04 +0100 Subject: [PATCH 09/10] Update es.json --- lang/es.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lang/es.json b/lang/es.json index 44d7652..9c8d680 100644 --- a/lang/es.json +++ b/lang/es.json @@ -10,9 +10,6 @@ "sa_player_mute_message_perm": "Has sido silenciado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}.", "sa_player_silence_message_time": "Has sido silenciado por {lightred}{0}{default} durante {lightred}{1}{default} minutos por {lightred}{2}{default}.", "sa_player_silence_message_perm": "Has sido silenciado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}.", - "sa_admin_silence_message_time": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} por {lightred}{2}{default} durante {lightred}{3}{default} minutos.", - "sa_admin_silence_message_perm": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", - "sa_admin_rename_message": "El administrador {lightred}{0}{default} ha cambiado el nombre de {lightred}{1}{default} a {lightred}{2}{default}." "sa_admin_ban_message_time": "El administrador {lightred}{0}{default} ha baneado a {lightred}{1}{default} por {lightred}{2}{default} durante {lightred}{3}{default} minutos.", "sa_admin_ban_message_perm": "El administrador {lightred}{0}{default} ha baneado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", "sa_admin_kick_message": "El administrador {lightred}{0}{default} ha expulsado a {lightred}{1}{default} por {lightred}{2}{default}.", @@ -20,6 +17,8 @@ "sa_admin_gag_message_perm": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", "sa_admin_mute_message_time": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} por {lightred}{2}{default} durante {lightred}{3}{default} minutos.", "sa_admin_mute_message_perm": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", + "sa_admin_silence_message_time": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} por {lightred}{2}{default} durante {lightred}{3}{default} minutos.", + "sa_admin_silence_message_perm": "El administrador {lightred}{0}{default} ha silenciado a {lightred}{1}{default} permanentemente por {lightred}{2}{default}.", "sa_admin_give_message": "El administrador {lightred}{0}{default} le ha dado a {lightred}{1}{default} un {lightred}{2}{default}.", "sa_admin_strip_message": "El administrador {lightred}{0}{default} le ha quitado todas las armas al jugador {lightred}{1}{default}.", "sa_admin_hp_message": "El administrador {lightred}{0}{default} ha cambiado la cantidad de salud de {lightred}{1}{default}{default}.", @@ -31,6 +30,7 @@ "sa_admin_noclip_message": "El administrador {lightred}{0}{default} ha activado noclip para {lightred}{1}{default}.", "sa_admin_freeze_message": "El administrador {lightred}{0}{default} ha congelado a {lightred}{1}{default}.", "sa_admin_unfreeze_message": "El administrador {lightred}{0}{default} ha descongelado a {lightred}{1}{default}.", + "sa_admin_rename_message": "El administrador {lightred}{0}{default} ha cambiado el nombre de {lightred}{1}{default} a {lightred}{2}{default}." "sa_admin_respawn_message": "El administrador {lightred}{0}{default} ha respawnado a {lightred}{1}{default}.", "sa_admin_team_message": "El administrador {lightred}{0}{default} ha transferido a {lightred}{1}{default} a {lightred}{2}{default}.", "sa_admin_vote_menu_title": "{lime}VOTACIÓN PARA {gold}{0}", From 6a182fff9d562d4faceb779557cffdb0f303d7a0 Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Sun, 11 Feb 2024 16:27:54 +0100 Subject: [PATCH 10/10] 1.3.0f - Fixed `css_kick` - Fixed gag/mute/silence on connect - Additional check in immunity --- CS2-SimpleAdmin.cs | 15 ++++------- CS2-SimpleAdmin.csproj | 2 +- Events.cs | 61 +++++++++++++----------------------------- Helper.cs | 4 +-- PlayerInfo.cs | 2 +- PlayerUtils.cs | 5 +++- 6 files changed, 31 insertions(+), 58 deletions(-) diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index 0f16da1..85777c1 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -27,12 +27,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig mutedPlayers = new ConcurrentBag(); public static Dictionary voteAnswers = new Dictionary(); public static HashSet votePlayers = new HashSet(); public static ConcurrentBag godPlayers = new ConcurrentBag(); - //public static ConcurrentBag gaggedPlayers = new ConcurrentBag(); - //public static ConcurrentBag commsPlayers = new ConcurrentBag(); public static ConcurrentBag silentPlayers = new ConcurrentBag(); public static ConcurrentBag bannedPlayers = new ConcurrentBag(); public static bool TagsDetected = false; @@ -48,7 +45,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"; - public override string ModuleVersion => "1.3.0e"; + public override string ModuleVersion => "1.3.0f"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -425,7 +422,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig playersToTarget = targets!.Players.Where(player => player != null && player.IsValid && !player.IsHLTV).ToList(); if (playersToTarget.Count > 1 && Config.DisableDangerousCommands || playersToTarget.Count == 0) @@ -443,13 +443,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig= 2) @@ -1454,7 +1450,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig - + diff --git a/Events.cs b/Events.cs index 8627851..af0d300 100644 --- a/Events.cs +++ b/Events.cs @@ -15,31 +15,12 @@ public partial class CS2_SimpleAdmin { private void registerEvents() { - //RegisterListener(OnClientAuthorized); - //RegisterListener(OnClientConnect); RegisterListener(OnClientPutInServer); - //RegisterListener(OnClientDisconnect); - //RegisterEventHandler(OnPlayerFullConnect); RegisterListener(OnMapStart); - RegisterListener(OnClientVoice); - //RegisterEventHandler(OnPlayerHurt); - //RegisterEventHandler(OnRoundStart); AddCommandListener("say", OnCommandSay); AddCommandListener("say_team", OnCommandTeamSay); } - private void OnClientVoice(int playerSlot) - { - PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); - if (!playerPenaltyManager.IsSlotInPenalties(playerSlot)) return; - - CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot); - if (player is null || !player.IsValid) return; - - if (playerPenaltyManager.IsPenalized(playerSlot, PenaltyType.Mute) || playerPenaltyManager.IsPenalized(playerSlot, PenaltyType.Silence)) - player.VoiceFlags = VoiceFlags.Muted; - } - [GameEventHandler] private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { @@ -136,6 +117,7 @@ public partial class CS2_SimpleAdmin BanManager _banManager = new(_database, Config); MuteManager _muteManager = new(_database); + PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); Task.Run(async () => { @@ -160,48 +142,41 @@ public partial class CS2_SimpleAdmin if (activeMutes.Count > 0) { - PlayerPenaltyManager playerPenaltyManager = new PlayerPenaltyManager(); - foreach (var mute in activeMutes) + foreach (dynamic mute in activeMutes) { string muteType = mute.type; + DateTime ends = mute.ends; + int duration = mute.duration; if (muteType == "GAG") { - /* - if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) - gaggedPlayers.Add(playerInfo.Slot.Value); - */ - playerPenaltyManager.AddPenalty(1, PenaltyType.Gag, DateTime.Parse(mute.ends), mute.duration); - - if (TagsDetected) + playerPenaltyManager.AddPenalty(playerInfo.Slot, PenaltyType.Gag, ends, duration); + Server.NextFrame(() => { - Server.NextFrame(() => + if (TagsDetected) { Server.ExecuteCommand($"css_tag_mute {playerInfo.SteamId}"); - }); - } + } + }); } else if (muteType == "MUTE") { - playerPenaltyManager.AddPenalty(1, PenaltyType.Mute, DateTime.Parse(mute.ends), mute.duration); + playerPenaltyManager.AddPenalty(playerInfo.Slot, PenaltyType.Mute, ends, duration); + Server.NextFrame(() => + { + player.VoiceFlags = VoiceFlags.Muted; + }); } else { - /* - * if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) - gaggedPlayers.Add(playerInfo.Slot.Value); - */ - playerPenaltyManager.AddPenalty(1, PenaltyType.Silence, DateTime.Parse(mute.ends), mute.duration); - + playerPenaltyManager.AddPenalty(playerInfo.Slot, PenaltyType.Silence, ends, duration); Server.NextFrame(() => { - if (player.IsValid) + player.VoiceFlags = VoiceFlags.Muted; + if (TagsDetected) { - if (TagsDetected) - { - Server.ExecuteCommand($"css_tag_mute {playerInfo.SteamId}"); - } + Server.ExecuteCommand($"css_tag_mute {playerInfo.SteamId}"); } }); } diff --git a/Helper.cs b/Helper.cs index 84db15f..c545fea 100644 --- a/Helper.cs +++ b/Helper.cs @@ -23,14 +23,14 @@ namespace CS2_SimpleAdmin public static List GetPlayerFromSteamid64(string steamid) { - return Utilities.GetPlayers().FindAll(x => + return GetValidPlayers().FindAll(x => x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase) ); } public static List GetPlayerFromIp(string ipAddress) { - return Utilities.GetPlayers().FindAll(x => + return GetValidPlayers().FindAll(x => x.IpAddress != null && x.IpAddress.Split(":")[0].Equals(ipAddress) ); diff --git a/PlayerInfo.cs b/PlayerInfo.cs index de7c85d..4d472c0 100644 --- a/PlayerInfo.cs +++ b/PlayerInfo.cs @@ -4,7 +4,7 @@ { public int? Index { get; set; } public int? UserId { get; set; } - public int? Slot { get; set; } + public int Slot { get; set; } public string? SteamId { get; set; } public string? Name { get; set; } public string? IpAddress { get; set; } diff --git a/PlayerUtils.cs b/PlayerUtils.cs index 874afed..6acdddf 100644 --- a/PlayerUtils.cs +++ b/PlayerUtils.cs @@ -1,6 +1,7 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; +using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; using System.Text; @@ -24,7 +25,9 @@ public static class PlayerUtils public static bool CanTarget(this CCSPlayerController controller, CCSPlayerController target) { if (target.IsBot) return true; - return AdminManager.CanPlayerTarget(controller, target); + if (controller is null) return true; + + return AdminManager.CanPlayerTarget(controller, target) || AdminManager.CanPlayerTarget(new SteamID(controller.SteamID), new SteamID(target.SteamID)); } public static void SetSpeed(this CCSPlayerController controller, float speed)