diff --git a/AdminSQLManager.cs b/AdminSQLManager.cs index 364fcac..17f2906 100644 --- a/AdminSQLManager.cs +++ b/AdminSQLManager.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API.Modules.Entities; using Dapper; +using System.Collections.Concurrent; namespace CS2_SimpleAdmin { @@ -8,8 +9,8 @@ namespace CS2_SimpleAdmin private readonly Database _database; // Unused for now //public static readonly ConcurrentDictionary> _adminCache = new ConcurrentDictionary>(); - public static readonly HashSet _adminCacheSet = new HashSet(); - public static readonly Dictionary _adminCacheTimestamps = new Dictionary(); + public static readonly ConcurrentDictionary _adminCache = new ConcurrentDictionary(); + //public static readonly ConcurrentDictionary _adminCacheTimestamps = new ConcurrentDictionary(); public AdminSQLManager(Database database) { @@ -216,10 +217,10 @@ namespace CS2_SimpleAdmin if (!string.IsNullOrEmpty(steamIdStr) && SteamID.TryParse(steamIdStr, out var steamId) && steamId != null) { - if (!_adminCacheSet.Contains(steamId)) + if (!_adminCache.ContainsKey(steamId)) { - _adminCacheSet.Add(steamId); - _adminCacheTimestamps.Add(steamId, ends); + _adminCache.TryAdd(steamId, ends); + //_adminCacheTimestamps.Add(steamId, ends); } Helper.GivePlayerFlags(steamId, flags, (uint)immunity); diff --git a/BanManager.cs b/BanManager.cs index 67901b0..3a62b43 100644 --- a/BanManager.cs +++ b/BanManager.cs @@ -90,26 +90,35 @@ namespace CS2_SimpleAdmin public async Task IsPlayerBanned(PlayerInfo player) { - DateTime now = DateTime.Now; - - 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; - - await using var connection = _database.GetConnection(); - - if (!string.IsNullOrEmpty(player.IpAddress)) + if (player == null) { - banCount = await connection.ExecuteScalarAsync(sql, new { PlayerSteamID = player.SteamId, PlayerIP = player.IpAddress, CurrentTime = now }); + return false; } - else + + 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 { - banCount = await connection.ExecuteScalarAsync(sql, new { PlayerSteamID = player.SteamId, PlayerIP = DBNull.Value, CurrentTime = now }); + await using var connection = _database.GetConnection(); + + var parameters = new + { + PlayerSteamID = player.SteamId, + PlayerIP = !string.IsNullOrEmpty(player.IpAddress) ? player.IpAddress : (object)DBNull.Value, + CurrentTime = currentTimeUtc + }; + + banCount = await connection.ExecuteScalarAsync(sql, parameters); + } + catch (Exception) + { + return false; } return banCount > 0; } - public async Task GetPlayerBans(PlayerInfo player) { string sql = "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP)"; diff --git a/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin.cs index ab33ca1..a0dbdda 100644 --- a/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin.cs @@ -2,6 +2,7 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands.Targeting; @@ -26,26 +27,27 @@ namespace CS2_SimpleAdmin; public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { public static IStringLocalizer? _localizer; - public static ConcurrentBag gaggedPlayers = new ConcurrentBag(); //public static ConcurrentBag mutedPlayers = new ConcurrentBag(); public static Dictionary voteAnswers = new Dictionary(); - public static HashSet godPlayers = new HashSet(); - public static List silentPlayers = new List(); - public static HashSet bannedPlayers = new HashSet(); + public static HashSet votePlayers = new HashSet(); + public static ConcurrentBag godPlayers = new ConcurrentBag(); + public static ConcurrentBag gaggedPlayers = new ConcurrentBag(); + public static ConcurrentBag silentPlayers = new ConcurrentBag(); + public static ConcurrentBag bannedPlayers = new ConcurrentBag(); public static bool TagsDetected = false; public static bool voteInProgress = false; public static int? ServerId = null; internal string dbConnectionString = string.Empty; - internal Database? _database; + internal static Database? _database; public static MemoryFunctionVoid 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" + 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.2.9a"; + public override string ModuleVersion => "1.3.0a"; public CS2_SimpleAdminConfig Config { get; set; } = new(); @@ -73,17 +75,16 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { try { - - _database = new(dbConnectionString); - using (var connection = _database.GetConnection()) { using var transaction = await connection.BeginTransactionAsync(); @@ -176,11 +177,14 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(silentPlayers.Where(item => item != caller.Slot)); caller.PrintToChat($"You aren't hidden now!"); caller.ChangeTeam(CsTeam.Spectator); if (Config.DiscordWebhook.Length > 0 && _localizer != null) @@ -302,7 +303,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { @@ -310,14 +311,14 @@ 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.05f, () => { 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.25f, () => { Server.ExecuteCommand("sv_disable_teamselect_menu 0"); }); + AddTimer(1.1f, () => { Server.ExecuteCommand("sv_disable_teamselect_menu 0"); }); }); } } @@ -474,7 +475,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig= 2) { - player.PrintToCenter(_localizer!["sa_player_kick_message", reason, caller == null ? "Console" : caller.PlayerName]); + 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 @@ -482,11 +486,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig Helper.KickPlayer((ushort)player.UserId!), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); } - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) + if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains(caller.Slot)) { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_kick_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); - Server.PrintToChatAll(sb.ToString()); + foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_kick_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); + _player.PrintToChat(sb.ToString()); + } + } } if (Config.DiscordWebhook.Length > 0 && _localizer != null) @@ -548,42 +558,29 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig 0 && time <= 30) - { - AddTimer(time * 60, () => - { - if (player == null || !player.IsValid || player.AuthorizedSteamID == null) return; - - if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); - - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) - { - if (gaggedPlayers.TryTake(out string? removedItem) && removedItem != player.SteamID.ToString()) - { - gaggedPlayers.Add(removedItem); - } - } - - //MuteManager _muteManager = new(_database); - //_ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 0); - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - } + if (player != null && !gaggedPlayers.Contains(player.Slot)) + gaggedPlayers.Add(player.Slot); if (time == 0) { - player!.PrintToCenter(_localizer!["sa_player_gag_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); - - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) + using (new WithTemporaryCulture(player.GetLanguage())) { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_gag_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); - Server.PrintToChatAll(sb.ToString()); + player!.PrintToCenter(_localizer!["sa_player_gag_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); + } + + 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)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_gag_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_gag_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -593,13 +590,22 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_gag_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_gag_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -660,13 +666,22 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_gag_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_gag_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -676,13 +691,22 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_gag_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_gag_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -692,31 +716,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig 0 && time <= 30) - { - AddTimer(time * 60, () => - { - if (player == null || !player.IsValid || player.AuthorizedSteamID == null) return; - - if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); - - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) - { - if (gaggedPlayers.TryTake(out string? removedItem) && removedItem != player.SteamID.ToString()) - { - gaggedPlayers.Add(removedItem); - } - } - - //_ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 0); - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - } - - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) - gaggedPlayers.Add(player.SteamID.ToString()); + if (player != null && gaggedPlayers.Contains(player.Slot)) + gaggedPlayers.Add(player.Slot); } } _ = _muteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 0); @@ -749,16 +752,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(gaggedPlayers.Where(item => item != player.Slot)); } if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); + NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID}"); found = true; } @@ -772,12 +772,9 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(gaggedPlayers.Where(item => item != player.Slot)); } if (TagsDetected) @@ -809,19 +806,16 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) + if (player != null && gaggedPlayers.Contains(player.Slot)) { - if (gaggedPlayers.TryTake(out string? removedItem) && removedItem != player.SteamID.ToString()) - { - gaggedPlayers.Add(removedItem); - } + gaggedPlayers = new ConcurrentBag(gaggedPlayers.Where(item => item != player.Slot)); } if (player!.AuthorizedSteamID != null) _ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 0); // Unmute by type 0 (gag) if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); + NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID}"); }); command.ReplyToCommand($"Ungaged player with pattern {pattern}."); @@ -887,39 +881,24 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig 0 && time <= 30) - { - AddTimer(time * 60, () => - { - if (player == null || !player.IsValid || player.AuthorizedSteamID == null) return; - - //MuteManager _muteManager = new(_database); - //_ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 1); - - /* - if (mutedPlayers.Contains((int)player.Index)) - { - if (mutedPlayers.TryTake(out int removedItem) && removedItem != (int)player.Index) - { - mutedPlayers.Add(removedItem); - } - } - */ - - player.VoiceFlags = VoiceFlags.Normal; - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - } - if (time == 0) { - player!.PrintToCenter(_localizer!["sa_player_mute_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); - - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) + using (new WithTemporaryCulture(player.GetLanguage())) { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_mute_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); - Server.PrintToChatAll(sb.ToString()); + player!.PrintToCenter(_localizer!["sa_player_mute_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); + } + + 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)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_mute_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_mute_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -929,13 +908,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())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_mute_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_mute_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -997,13 +984,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())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_mute_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_mute_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -1013,13 +1008,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())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_mute_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_mute_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -1032,28 +1035,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig 0 && time <= 30) - { - AddTimer(time * 60, () => - { - if (player == null || !player.IsValid || player.AuthorizedSteamID == null) return; - - /* - if (mutedPlayers.Contains((int)player.Index)) - { - if (mutedPlayers.TryTake(out int removedItem) && removedItem != (int)player.Index) - { - mutedPlayers.Add(removedItem); - } - } - */ - - player.VoiceFlags = VoiceFlags.Normal; - - _ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 1); - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - } } } _ = _muteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 1); @@ -1227,15 +1208,29 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig Helper.KickPlayer((ushort)player!.UserId!), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + if (playerInfo.IpAddress != null && !bannedPlayers.Contains(playerInfo.IpAddress)) + bannedPlayers.Add(playerInfo.IpAddress); + if (!bannedPlayers.Contains(player!.SteamID.ToString())) + bannedPlayers.Add(player.SteamID.ToString()); + if (time == 0) { - player!.PrintToCenter(_localizer!["sa_player_ban_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); - - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) + using (new WithTemporaryCulture(player.GetLanguage())) { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_ban_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]); - Server.PrintToChatAll(sb.ToString()); + player!.PrintToCenter(_localizer!["sa_player_ban_message_perm", reason, caller == null ? "Console" : caller.PlayerName]); + } + + 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)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_ban_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_ban_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -1245,13 +1240,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())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_ban_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_ban_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -1316,13 +1319,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())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_ban_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_ban_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -1332,13 +1343,22 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_ban_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_ban_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -1408,13 +1428,22 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_ban_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_ban_message_perm", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason]; @@ -1424,13 +1453,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())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_ban_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_ban_message_time", caller == null ? "Console" : caller.PlayerName, player.PlayerName, reason, time]; @@ -1491,11 +1528,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_slay_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_slay_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -1544,11 +1588,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_give_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, weaponName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_give_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, weaponName]; @@ -1573,12 +1623,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_strip_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_strip_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -1607,12 +1663,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_hp_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_hp_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -1645,12 +1707,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_speed_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_speed_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -1674,19 +1742,29 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(godPlayers.Where(item => item != player.Slot)); + } + + + 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)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_god_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_god_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -1719,12 +1797,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_slap_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_slap_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -1777,7 +1861,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_team_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, _teamName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_team_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName, _teamName]; @@ -1826,60 +1916,80 @@ 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()); + } + } - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) - { - 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]); - Server.PrintToChatAll(sb.ToString()); if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_vote_message", caller == null ? "Console" : caller.PlayerName, question]; _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); } + voteInProgress = true; } - voteInProgress = true; - - foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV)) + if (voteInProgress) { - if (p == null) continue; - MenuManager.OpenChatMenu(p, voteMenu); - } - - AddTimer(40, () => - { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_vote_message_results", question]); - Server.PrintToChatAll(sb.ToString()); - if (Config.DiscordWebhook.Length > 0 && _localizer != null) + AddTimer(30, () => { - LocalizedString localizedMessage = _localizer["sa_admin_vote_message_results", question]; - _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); - } - - foreach (KeyValuePair kvp in voteAnswers) - { - sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_vote_message_results_answer", kvp.Key, kvp.Value]); - Server.PrintToChatAll(sb.ToString()); + foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_vote_message_results", question]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { - LocalizedString localizedMessage = _localizer["sa_admin_vote_message_results_answer", kvp.Key, kvp.Value]; + LocalizedString localizedMessage = _localizer["sa_admin_vote_message_results", question]; _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); } - } - voteAnswers.Clear(); - voteInProgress = false; - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + + foreach (KeyValuePair kvp in voteAnswers) + { + foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_vote_message_results_answer", kvp.Key, kvp.Value]); + _player.PrintToChat(sb.ToString()); + } + } + if (Config.DiscordWebhook.Length > 0 && _localizer != null) + { + LocalizedString localizedMessage = _localizer["sa_admin_vote_message_results_answer", kvp.Key, kvp.Value]; + _ = SendWebhookMessage(localizedMessage.ToString().Replace("", "").Replace("", "")); + } + } + voteAnswers.Clear(); + votePlayers.Clear(); + voteInProgress = false; + }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + } } [ConsoleCommand("css_changemap")] @@ -1916,11 +2026,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_changemap_message", caller == null ? "Console" : caller.PlayerName, map]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_changemap_message", caller == null ? "Console" : caller.PlayerName, map]; @@ -1956,11 +2072,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_changemap_message", caller == null ? "Console" : caller.PlayerName, map]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_changemap_message", caller == null ? "Console" : caller.PlayerName, map]; @@ -1984,15 +2106,18 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV && AdminManager.PlayerHasPermissions(p, "@css/chat"))) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(); + sb.Append(_localizer!["sa_adminchat_template_admin", caller == null ? "Console" : caller.PlayerName, utf8String]); + _player.PrintToChat(sb.ToString()); + } + } + if (Config.DiscordWebhook.Length > 0 && _localizer != null) _ = SendWebhookMessage($"ASAY: {caller!.PlayerName}: {utf8String}"); - - foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && AdminManager.PlayerHasPermissions(p, "@css/chat"))) - { - p.PrintToChat(sb.ToString()); - } } [ConsoleCommand("css_say", "Say to all players.")] @@ -2005,9 +2130,15 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(); + sb.Append(_localizer!["sa_adminsay_prefix", utf8String]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) _ = SendWebhookMessage($"ASAY: {caller!.PlayerName}: {utf8String}"); } @@ -2081,11 +2212,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_noclip_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_noclip_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -2116,11 +2253,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig 0) AddTimer(time, () => player.Pawn.Value!.Unfreeze(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) + if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_freeze_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); - Server.PrintToChatAll(sb.ToString()); + foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_freeze_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_freeze_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -2143,11 +2286,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_unfreeze_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } if (Config.DiscordWebhook.Length > 0 && _localizer != null) { LocalizedString localizedMessage = _localizer["sa_admin_unfreeze_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]; @@ -2176,11 +2325,17 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig(player.Handle, GameData.GetOffset("CCSPlayerController_Respawn"))(player); - if (caller == null || caller != null && caller.UserId != null && !silentPlayers.Contains((ushort)caller.UserId)) + if (caller == null || caller != null && !silentPlayers.Contains(caller.Slot)) { - StringBuilder sb = new(_localizer!["sa_prefix"]); - sb.Append(_localizer["sa_admin_respawn_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); - Server.PrintToChatAll(sb.ToString()); + foreach (CCSPlayerController _player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Connected == PlayerConnectedState.PlayerConnected && !p.IsBot && !p.IsHLTV)) + { + using (new WithTemporaryCulture(_player.GetLanguage())) + { + StringBuilder sb = new(_localizer!["sa_prefix"]); + sb.Append(_localizer["sa_admin_respawn_message", caller == null ? "Console" : caller.PlayerName, player.PlayerName]); + _player.PrintToChat(sb.ToString()); + } + } } if (Config.DiscordWebhook.Length > 0 && _localizer != null) @@ -2237,7 +2392,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig 1 || command.GetArg(1).StartsWith('@')) + if (command.GetArg(1).StartsWith('@')) return matches; - if (matches.Count() == 1 || !command.GetArg(1).StartsWith('@')) + if (matches.Count() == 1) return matches; command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(1)}\"."); diff --git a/Config.cs b/Config.cs index b1e59dc..21b3862 100644 --- a/Config.cs +++ b/Config.cs @@ -5,7 +5,7 @@ namespace CS2_SimpleAdmin { public class CS2_SimpleAdminConfig : BasePluginConfig { - public override int Version { get; set; } = 4; + public override int Version { get; set; } = 5; [JsonPropertyName("DatabaseHost")] public string DatabaseHost { get; set; } = ""; @@ -31,8 +31,10 @@ namespace CS2_SimpleAdmin [JsonPropertyName("BanType")] public int BanType { get; set; } = 1; + [JsonPropertyName("TeamSwitchType")] + public int TeamSwitchType { get; set; } = 1; + [JsonPropertyName("DiscordWebhook")] public string DiscordWebhook { get; set; } = ""; - } } \ No newline at end of file diff --git a/Database.cs b/Database.cs index 16413e1..b701af9 100644 --- a/Database.cs +++ b/Database.cs @@ -17,11 +17,3 @@ public class Database return connection; } } - -public static class DatabaseExtension -{ - public static string WithConnectionPooling(this string connectionString) - { - return $"{connectionString};Pooling=true;MinimumPoolSize=1;MaximumPoolSize=15"; - } -} \ No newline at end of file diff --git a/Events.cs b/Events.cs index 24839ca..13ac8ae 100644 --- a/Events.cs +++ b/Events.cs @@ -1,10 +1,12 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Admin; 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; @@ -17,12 +19,12 @@ public partial class CS2_SimpleAdmin { //RegisterListener(OnClientAuthorized); //RegisterListener(OnClientConnect); - RegisterListener(OnClientPutInServer); + //RegisterListener(OnClientPutInServer); + //RegisterListener(OnClientDisconnect); //RegisterEventHandler(OnPlayerFullConnect); - RegisterListener(OnClientDisconnect); RegisterListener(OnMapStart); - RegisterEventHandler(OnPlayerHurt); - RegisterEventHandler(OnRoundStart); + //RegisterEventHandler(OnPlayerHurt); + //RegisterEventHandler(OnRoundStart); AddCommandListener("say", OnCommandSay); AddCommandListener("say_team", OnCommandTeamSay); } @@ -31,7 +33,7 @@ public partial class CS2_SimpleAdmin { CCSPlayerController? player = @event.Userid; - if (player == null || player.IsBot || player.IsHLTV) return HookResult.Continue; + if (player is null || player.IsBot || player.IsHLTV) return HookResult.Continue; PlayerInfo playerInfo = new PlayerInfo { @@ -46,27 +48,28 @@ public partial class CS2_SimpleAdmin { Server.NextFrame(() => { - if (player == null) return; + if (player is null) return; }); }); return HookResult.Continue; } */ - private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) + [GameEventHandler] + private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { - godPlayers.Clear(); #if DEBUG - Logger.LogCritical("[OnRoundStart]"); + Logger.LogCritical("[OnRoundEnd]"); #endif + godPlayers.Clear(); return HookResult.Continue; } private HookResult OnCommandSay(CCSPlayerController? player, CommandInfo info) { - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; + if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) + if (player != null && gaggedPlayers.Contains(player.Slot)) { return HookResult.Handled; } @@ -76,9 +79,9 @@ public partial class CS2_SimpleAdmin private HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info) { - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; + if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || info.GetArg(1).Length == 0) return HookResult.Continue; - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) + if (player != null && gaggedPlayers.Contains(player.Slot)) { return HookResult.Handled; } @@ -111,265 +114,145 @@ public partial class CS2_SimpleAdmin return HookResult.Continue; } - private void OnClientPutInServer(int playerSlot) + [GameEventHandler] + public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo info) { - CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot); -#if DEBUG - Logger.LogCritical("[OnClientPutInServer] Before check"); -#endif + if (!@event.Userid.IsValid || !@event.Userid.PlayerPawn.IsValid) + return HookResult.Continue; - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.Connected == PlayerConnectedState.PlayerDisconnecting) - return; + CCSPlayerController? player = @event.Userid; #if DEBUG - Logger.LogCritical("[OnClientPutInServer] After Check"); + Logger.LogCritical("[OnPlayerConnect] Before check"); +#endif + if (_database == null || player is null || !player.IsValid || player.IsBot || player.IsHLTV) + return HookResult.Continue; + +#if DEBUG + Logger.LogCritical("[OnPlayerConnect] After Check"); #endif string? ipAddress = !string.IsNullOrEmpty(player.IpAddress) ? player.IpAddress.Split(":")[0] : null; if ( ipAddress != null && bannedPlayers.Contains(ipAddress) || - player.SteamID.ToString() != "" && bannedPlayers.Contains(player.SteamID.ToString()) + bannedPlayers.Contains(player.SteamID.ToString()) ) - Helper.KickPlayer((ushort)player.UserId!, "Banned"); + { + Server.NextFrame(() => + { + Helper.KickPlayer((ushort)player.UserId!, "Banned"); + }); + return HookResult.Continue; + } PlayerInfo playerInfo = new PlayerInfo { UserId = player.UserId, Index = (ushort)player.Index, - SteamId = player?.SteamID.ToString(), - Name = player?.PlayerName, + Slot = player.Slot, + SteamId = player.SteamID.ToString(), + Name = player.PlayerName, IpAddress = ipAddress }; - _ = Task.Run(async () => - { - if (_database == null) return; - - BanManager _banManager = new(_database, Config); - bool isBanned = await _banManager.IsPlayerBanned(playerInfo); - - MuteManager _muteManager = new(_database); - List activeMutes = await _muteManager.IsPlayerMuted(playerInfo.SteamId!); - - AdminSQLManager _adminManager = new(_database); - List<(List, int)> activeFlags = await _adminManager.GetAdminFlags(playerInfo.SteamId!); - - Server.NextFrame(() => - { - if (player == null || !player.IsValid) return; - if (isBanned) - { - if (playerInfo.IpAddress != null && !bannedPlayers.Contains(playerInfo.IpAddress)) - bannedPlayers.Add(playerInfo.IpAddress); - if (player.SteamID.ToString() != "" && !bannedPlayers.Contains(player.SteamID.ToString())) - bannedPlayers.Add(player.SteamID.ToString()); - - Helper.KickPlayer((ushort)player.UserId!, "Banned"); - return; - } - - //Helper.GivePlayerFlags(player, activeFlags); - - if (activeMutes.Count > 0) - { - foreach (var mute in activeMutes) - { - string muteType = mute.type; - TimeSpan duration = mute.ends - mute.created; - int durationInSeconds = (int)duration.TotalSeconds; - - if (muteType == "GAG") - { - // Chat mute - if (player.SteamID.ToString() != "" && !gaggedPlayers.Any(steamid => steamid.Equals(player.SteamID.ToString()))) - gaggedPlayers.Add(player.SteamID.ToString()); - - if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_mute {player!.SteamID.ToString()}"); - - if (durationInSeconds != 0 && duration.Minutes >= 0 && duration.Minutes <= 30) - { - AddTimer(durationInSeconds, () => - { - if (player == null || !player.IsValid || player.SteamID.ToString() == "") return; - - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) - { - if (gaggedPlayers.TryTake(out string? removedItem) && removedItem != player.SteamID.ToString()) - { - gaggedPlayers.Add(removedItem); - } - } - - if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); - - MuteManager _muteManager = new(_database); - _ = _muteManager.UnmutePlayer(player!.SteamID.ToString(), 0); - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - } - - /* - CCSPlayerController currentPlayer = player; - - if (mute.duration == 0 || durationInSeconds >= 1800) continue; - - await Task.Delay(TimeSpan.FromSeconds(durationInSeconds)); - - if (currentPlayer != null && currentPlayer.IsValid) - { - NativeAPI.IssueServerCommand($"css_tag_unmute {currentPlayer.Index.ToString()}"); - await UnmutePlayer(currentPlayer.AuthorizedSteamID.SteamId64.ToString(), 0); - } - */ - } - else if (muteType == "MUTE") - { - // Voice mute - player.VoiceFlags = VoiceFlags.Muted; - - if (durationInSeconds != 0 && duration.Minutes >= 0 && duration.Minutes <= 30) - { - AddTimer(durationInSeconds, () => - { - if (player == null || !player.IsValid || player.SteamID.ToString() == "") return; - - /* - if (mutedPlayers.Contains((ushort)player.UserId)) - { - if (mutedPlayers.TryTake(out int removedItem) && removedItem != (ushort)player.UserId) - { - mutedPlayers.Add(removedItem); - } - } - */ - - player.VoiceFlags = VoiceFlags.Normal; - - //MuteManager _muteManager = new(_database); - //_ = _muteManager.UnmutePlayer(player.AuthorizedSteamID.SteamId64.ToString(), 1); - }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - } - } - } - } - - /* - - if (_adminManager._adminCache != null && _adminManager._adminCache.Count > 0) - { - foreach (var flags in activeFlags) - { - if (flags == null) continue; - string flagsValue = flags.flags.ToString(); - - if (!string.IsNullOrEmpty(flagsValue)) - { - string[] _flags = flagsValue.Split(","); - - AddTimer(10, () => - { - if (player == null) return; - foreach (var _flag in _flags) - { - if (_flag.StartsWith("@")) - { - AdminManager.AddPlayerPermissions(player, _flag); - } - if (_flag.StartsWith("3")) - { - AdminManager.AddPlayerToGroup(player, _flag); - } - } - }); - } - } - } - */ - }); - }); - - /* - CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot); - - if (player == null || !player.IsValid || player.IpAddress == null || player.UserId == null || loadedPlayers.Contains((ushort)player.UserId) || player.IsBot || player.IsHLTV) - return; - - if (bannedPlayers.Contains(player.IpAddress) || player.AuthorizedSteamID != null && bannedPlayers.Contains(player.AuthorizedSteamID.SteamId64.ToString())) - Helper.KickPlayer((ushort)player.UserId!, "Banned"); - - 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 () => { - BanManager _banManager = new(dbConnectionString); - bool isBanned = await _banManager.IsPlayerBanned(playerInfo); - Server.NextFrame(() => + BanManager _banManager = new(_database, Config); + + MuteManager _muteManager = new(_database); + List activeMutes = await _muteManager.IsPlayerMuted(playerInfo.SteamId); + + if (await _banManager.IsPlayerBanned(playerInfo)) { - if (player == null || !player.IsValid) return; - if (isBanned) + if (playerInfo.IpAddress != null && !bannedPlayers.Contains(playerInfo.IpAddress)) + bannedPlayers.Add(playerInfo.IpAddress); + + if (!bannedPlayers.Contains(playerInfo.SteamId)) + bannedPlayers.Add(playerInfo.SteamId); + + Server.NextFrame(() => { - if (player.IpAddress != null && !bannedPlayers.Contains(player.IpAddress)) - bannedPlayers.Add(player.IpAddress); - if (player.AuthorizedSteamID != null && !bannedPlayers.Contains(player.AuthorizedSteamID.SteamId64.ToString())) - bannedPlayers.Add(player.AuthorizedSteamID.SteamId64.ToString()); - Helper.KickPlayer((ushort)player.UserId!, "Banned"); + if (playerInfo.UserId != null) + Helper.KickPlayer((ushort)playerInfo.UserId, "Banned"); + }); + + return; + } + + if (activeMutes.Count > 0) + { + foreach (var mute in activeMutes) + { + string muteType = mute.type; + + if (muteType == "GAG") + { + // Chat mute + if (playerInfo.Slot.HasValue && !gaggedPlayers.Contains(playerInfo.Slot.Value)) + gaggedPlayers.Add(playerInfo.Slot.Value); + + if (TagsDetected) + { + Server.NextFrame(() => + { + Server.ExecuteCommand($"css_tag_mute {playerInfo.SteamId}"); + }); + } + } + else if (muteType == "MUTE") + { + // Voice mute + Server.NextFrame(() => + { + player.VoiceFlags = VoiceFlags.Muted; + }); + } } - }); + } }); - */ + + return HookResult.Continue; } - private void OnClientDisconnect(int playerSlot) + [GameEventHandler] + public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info) { - CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot); + if (!@event.Userid.IsValid || @event.Userid.IsBot) + return HookResult.Continue; + + CCSPlayerController? player = @event.Userid; #if DEBUG Logger.LogCritical("[OnClientDisconnect] Before"); #endif - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV) return; + if (player is null || !player.IsValid || player.IsBot || player.IsHLTV) + return HookResult.Continue; + + if (player.Connected == PlayerConnectedState.PlayerConnecting) + return HookResult.Continue; #if DEBUG Logger.LogCritical("[OnClientDisconnect] After Check"); #endif - if (player != null && player.SteamID.ToString() != "" && gaggedPlayers.Contains(player.SteamID.ToString())) + if (gaggedPlayers.Contains(player.Slot)) { - if (gaggedPlayers.TryTake(out string? removedItem) && removedItem != player.SteamID.ToString()) - { - gaggedPlayers.Add(removedItem); - } + gaggedPlayers = new ConcurrentBag(gaggedPlayers.Where(item => item != player.Slot)); } - /* - if (mutedPlayers.Contains((ushort)player.UserId)) + if (silentPlayers.Contains(player.Slot)) { - if (mutedPlayers.TryTake(out int removedItem) && removedItem != (ushort)player.UserId) - { - mutedPlayers.Add(removedItem); - } - } - */ - - if (player!.UserId != null && silentPlayers.Contains((ushort)player.UserId)) - { - silentPlayers.Remove((ushort)player.UserId); + silentPlayers = new ConcurrentBag(silentPlayers.Where(item => item != player.Slot)); } - if (player.UserId != null && godPlayers.Contains((ushort)player.UserId)) + if (godPlayers.Contains(player.Slot)) { - godPlayers.Remove((ushort)player.UserId); + godPlayers = new ConcurrentBag(godPlayers.Where(item => item != player.Slot)); } - if (player.AuthorizedSteamID != null && AdminSQLManager._adminCacheSet.Contains(player.AuthorizedSteamID)) + if (player.AuthorizedSteamID != null && AdminSQLManager._adminCache.ContainsKey(player.AuthorizedSteamID)) { - if (AdminSQLManager._adminCacheTimestamps != null && AdminSQLManager._adminCacheTimestamps.TryGetValue(player.AuthorizedSteamID, out DateTime? expirationTime) && expirationTime.HasValue && expirationTime.Value <= DateTime.Now) + if (AdminSQLManager._adminCache.TryGetValue(player.AuthorizedSteamID, out DateTime? expirationTime) && + expirationTime <= DateTime.Now) { AdminManager.ClearPlayerPermissions(player.AuthorizedSteamID); AdminManager.RemovePlayerAdminData(player.AuthorizedSteamID); @@ -377,12 +260,16 @@ public partial class CS2_SimpleAdmin } if (TagsDetected) - NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID.ToString()}"); + NativeAPI.IssueServerCommand($"css_tag_unmute {player!.SteamID}"); + + return HookResult.Continue; } private void OnMapStart(string mapName) { gaggedPlayers.Clear(); + godPlayers.Clear(); + silentPlayers.Clear(); if (_database == null) return; @@ -434,17 +321,18 @@ public partial class CS2_SimpleAdmin }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); } + [GameEventHandler] private HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) { CCSPlayerController? player = @event.Userid; - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.Connected == PlayerConnectedState.PlayerDisconnecting) + if (player is null || !player.IsValid || !player.PlayerPawn.IsValid || player.PlayerPawn.Value == null || player.IsBot || player.IsHLTV || player.PlayerPawn.IsValid || player.Connected == PlayerConnectedState.PlayerDisconnecting) return HookResult.Continue; - if (player.UserId != null && godPlayers.Contains((ushort)player.UserId) && player.PawnIsAlive) + if (godPlayers.Contains(player.Slot) && player.PawnIsAlive) { player.Health = 100; - player.PlayerPawn.Value!.Health = 100; + player.PlayerPawn.Value.Health = 100; } return HookResult.Continue; diff --git a/Helper.cs b/Helper.cs index ee65393..e2be60c 100644 --- a/Helper.cs +++ b/Helper.cs @@ -116,7 +116,7 @@ namespace CS2_SimpleAdmin public static void KickPlayer(ushort userId, string? reason = null) { - NativeAPI.IssueServerCommand($"kickid {userId} {reason}"); + Server.ExecuteCommand($"kickid {userId} {reason}"); } public static void PrintToCenterAll(string message) @@ -148,8 +148,12 @@ namespace CS2_SimpleAdmin internal static void handleVotes(CCSPlayerController player, ChatMenuOption option) { - if (CS2_SimpleAdmin.voteInProgress) + if (CS2_SimpleAdmin.voteInProgress && !CS2_SimpleAdmin.votePlayers.Contains(player.Slot)) + { + CS2_SimpleAdmin.votePlayers.Add(player.Slot); CS2_SimpleAdmin.voteAnswers[option.Text]++; + option.Disabled = true; + } } } } \ No newline at end of file diff --git a/MuteManager.cs b/MuteManager.cs index ceff7fa..20b0ae2 100644 --- a/MuteManager.cs +++ b/MuteManager.cs @@ -75,14 +75,25 @@ namespace CS2_SimpleAdmin public async Task> IsPlayerMuted(string steamId) { + if (string.IsNullOrEmpty(steamId)) + { + return new List(); + } + await using var connection = _database.GetConnection(); - - DateTime now = DateTime.Now; - + DateTime currentTimeUtc = DateTime.UtcNow; string sql = "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)"; - var activeMutes = (await connection.QueryAsync(sql, new { PlayerSteamID = steamId, CurrentTime = now })).ToList(); - return activeMutes; + try + { + var parameters = new { PlayerSteamID = steamId, CurrentTime = currentTimeUtc }; + var activeMutes = (await connection.QueryAsync(sql, parameters)).ToList(); + return activeMutes; + } + catch (Exception) + { + return new List(); + } } public async Task GetPlayerMutes(string steamId) @@ -134,9 +145,9 @@ namespace CS2_SimpleAdmin public async Task CheckMute(PlayerInfo player) { - if (player.UserId == null) return; + if (player.UserId == null || player.SteamId == null) return; - string steamId = player.SteamId!; + string steamId = player.SteamId; List activeMutes = await IsPlayerMuted(steamId); if (activeMutes.Count > 0) @@ -149,11 +160,13 @@ namespace CS2_SimpleAdmin if (muteType == "GAG") { - if (!CS2_SimpleAdmin.gaggedPlayers.Any(steamid => steamid == player.SteamId!.ToString())) - CS2_SimpleAdmin.gaggedPlayers.Add(player.SteamId!.ToString()); + 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!.ToString()}"); + NativeAPI.IssueServerCommand($"css_tag_mute {player!.SteamId}"); /* CCSPlayerController currentPlayer = player; diff --git a/PlayerInfo.cs b/PlayerInfo.cs index 2173ce7..de7c85d 100644 --- a/PlayerInfo.cs +++ b/PlayerInfo.cs @@ -4,6 +4,7 @@ { public int? Index { get; set; } public int? UserId { 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/README.md b/README.md index cdc5ca1..17164f2 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,7 @@ Manage your Counter-Strike 2 server by simple commands :) - css_addadmin [time in minutes] - Add admin by steamid // @css/root - css_deladmin - Delete admin by steamid // @css/root - css_reladmin - Reload sql admins // @css/root -- css_silentmode - Enable or disable silentmode for admins // @css/kick -- css_hide - Hide admin on scoreboard // @css/kick +- css_hide - Hide admin on scoreboard and commands action // @css/kick - css_admin - Display all admin commands // @css/generic - css_who <#userid or name> - Display informations about player // @css/generic - css_players - Display player list // @css/generic @@ -59,7 +58,7 @@ Manage your Counter-Strike 2 server by simple commands :) ``` ### Requirments -- [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp/) **tested on v144** +- [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp/) **tested on v159** - MySQL **tested on MySQL (MariaDB) Server version: 10.11.4-MariaDB-1~deb12u1 Debian 12** diff --git a/lang/lv.json b/lang/lv.json index 5066eae..c05ee37 100644 --- a/lang/lv.json +++ b/lang/lv.json @@ -35,4 +35,4 @@ "sa_adminsay_prefix": "{RED}ADMINS: {lightred}{0}{default}", "sa_adminchat_template_admin": "{LIME}(ADMINS) {lightred}{0}{default}: {lightred}{1}{default}", "sa_adminchat_template_player": "{SILVER}(SPĒLĒTĀJS) {lightred}{0}{default}: {lightred}{1}{default}" -} +} \ No newline at end of file