diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs index 2811b12..9f5d4e9 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs @@ -1,19 +1,17 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Core.Capabilities; -using CounterStrikeSharp.API.Core.Commands; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands.Targeting; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CS2_SimpleAdmin.Managers; using CS2_SimpleAdminApi; -using Discord.Webhook; using Microsoft.Extensions.Logging; using MySqlConnector; namespace CS2_SimpleAdmin; -[MinimumApiVersion(260)] +[MinimumApiVersion(271)] public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { internal static CS2_SimpleAdmin Instance { get; private set; } = new(); @@ -21,10 +19,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)"); public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleAuthor => "daffyy & Dliix66"; - public override string ModuleVersion => "1.6.1b"; - - public CS2_SimpleAdminConfig Config { get; set; } = new(); - + public override string ModuleVersion => "1.6.2a"; + public override void Load(bool hotReload) { Instance = this; @@ -98,6 +94,11 @@ public void OnConfigParsed(CS2_SimpleAdminConfig config) } Task.Run(() => Database.DatabaseMigration()); + + PermissionManager = new PermissionManager(Database); + BanManager = new BanManager(Database); + MuteManager = new MuteManager(Database); + WarnManager = new WarnManager(Database); Config = config; Helper.UpdateConfig(config); @@ -110,7 +111,7 @@ public void OnConfigParsed(CS2_SimpleAdminConfig config) _localizer = Localizer; if (!string.IsNullOrEmpty(Config.Discord.DiscordLogWebhook)) - DiscordWebhookClientLog = new DiscordWebhookClient(Config.Discord.DiscordLogWebhook); + DiscordWebhookClientLog = new DiscordManager(Config.Discord.DiscordLogWebhook); PluginInfo.ShowAd(ModuleVersion); if (Config.EnableUpdateCheck) diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj b/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj index 7d834d8..519af28 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj @@ -12,7 +12,6 @@ - diff --git a/CS2-SimpleAdmin/Commands/basebans.cs b/CS2-SimpleAdmin/Commands/basebans.cs index d076966..bc45d0c 100644 --- a/CS2-SimpleAdmin/Commands/basebans.cs +++ b/CS2-SimpleAdmin/Commands/basebans.cs @@ -1,11 +1,11 @@ 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.Entities; using CounterStrikeSharp.API.ValveConstants.Protobuf; using CS2_SimpleAdmin.Managers; +using CS2_SimpleAdmin.Menus; using CS2_SimpleAdminApi; namespace CS2_SimpleAdmin; @@ -30,21 +30,22 @@ public void OnBanCommand(CCSPlayerController? caller, CommandInfo command) { return; } - - Database.Database database = new(DbConnectionString); - BanManager banManager = new(database, Config); - - int.TryParse(command.GetArg(2), out var time); - + if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) reason = command.GetArg(3); playersToTarget.ForEach(player => { - if (caller!.CanTarget(player)) + if (!caller.CanTarget(player)) return; + + if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid) { - Ban(caller, player, time, reason, callerName, banManager, command); + DurationMenu.OpenMenu(caller, $"{_localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player, + ManagePlayersMenu.BanMenu); + return; } + + Ban(caller, player, time, reason, callerName, BanManager, command); }); } @@ -70,7 +71,7 @@ internal void Ban(CCSPlayerController? caller, CCSPlayerController player, int t // Asynchronously handle banning logic Task.Run(async () => { - await (banManager ??= new BanManager(Database, Config)).BanPlayer(playerInfo, adminInfo, reason, time); + await BanManager.BanPlayer(playerInfo, adminInfo, reason, time); }); // Update banned players list @@ -168,8 +169,7 @@ public void OnAddBanCommand(CCSPlayerController? caller, CommandInfo command) // Asynchronous ban operation if player is not online or not found Task.Run(async () => { - var banManager = new BanManager(Database, Config); - await banManager.AddBanBySteamid(steamid, adminInfo, reason, time); + await BanManager.AddBanBySteamid(steamid, adminInfo, reason, time); }); command.ReplyToCommand($"Player with steamid {steamid} is not online. Ban has been added offline."); @@ -224,8 +224,7 @@ public void OnBanIpCommand(CCSPlayerController? caller, CommandInfo command) // Asynchronous ban operation if player is not online or not found Task.Run(async () => { - var banManager = new BanManager(Database, Config); - await banManager.AddBanByIp(ipAddress, adminInfo, reason, time); + await BanManager.AddBanByIp(ipAddress, adminInfo, reason, time); }); command.ReplyToCommand($"Player with ip {ipAddress} is not online. Ban has been added offline."); @@ -269,8 +268,7 @@ public void OnUnbanCommand(CCSPlayerController? caller, CommandInfo command) var pattern = command.GetArg(1); var reason = command.GetArg(2); - BanManager banManager = new(Database, Config); - Task.Run(async () => await banManager.UnbanPlayer(pattern, callerSteamId, reason)); + Task.Run(async () => await BanManager.UnbanPlayer(pattern, callerSteamId, reason)); Helper.LogCommand(caller, command); @@ -406,8 +404,7 @@ public void OnUnwarnCommand(CCSPlayerController? caller, CommandInfo command) var pattern = command.GetArg(1); - WarnManager warnManager = new(Database); - Task.Run(async () => await warnManager.UnwarnPlayer(pattern)); + Task.Run(async () => await WarnManager.UnwarnPlayer(pattern)); Helper.LogCommand(caller, command); command.ReplyToCommand($"Unwarned player with pattern {pattern}."); diff --git a/CS2-SimpleAdmin/Commands/basecommands.cs b/CS2-SimpleAdmin/Commands/basecommands.cs index 9c2a181..f337d3a 100644 --- a/CS2-SimpleAdmin/Commands/basecommands.cs +++ b/CS2-SimpleAdmin/Commands/basecommands.cs @@ -29,16 +29,12 @@ public void OnPenaltiesCommand(CCSPlayerController? caller, CommandInfo command) Task.Run(async () => { - // Initialize managers - MuteManager muteManager = new(Database); - WarnManager warnManager = new(Database); - try { - var warns = await warnManager.GetPlayerWarns(PlayersInfo[userId], false); + var warns = await WarnManager.GetPlayerWarns(PlayersInfo[userId], false); // Check if the player is muted - var activeMutes = await muteManager.IsPlayerMuted(PlayersInfo[userId].SteamId.SteamId64.ToString()); + var activeMutes = await MuteManager.IsPlayerMuted(PlayersInfo[userId].SteamId.SteamId64.ToString()); Dictionary> mutesList = new() { @@ -221,8 +217,7 @@ public void OnDelAdminCommand(CCSPlayerController? caller, CommandInfo command) public void RemoveAdmin(CCSPlayerController? caller, string steamid, bool globalDelete = false, CommandInfo? command = null) { if (Database == null) return; - PermissionManager adminManager = new(Database); - _ = adminManager.DeleteAdminBySteamId(steamid, globalDelete); + _ = PermissionManager.DeleteAdminBySteamId(steamid, globalDelete); AddTimer(2, () => { @@ -313,8 +308,7 @@ public void OnDelGroupCommand(CCSPlayerController? caller, CommandInfo command) private void RemoveGroup(CCSPlayerController? caller, string name, CommandInfo? command = null) { if (Database == null) return; - PermissionManager adminManager = new(Database); - _ = adminManager.DeleteGroup(name); + _ = PermissionManager.DeleteGroup(name); AddTimer(2, () => { @@ -551,9 +545,6 @@ public void OnWarnsCommand(CCSPlayerController? caller, CommandInfo command) if (playersToTarget.Count > 1) return; - Database.Database database = new(DbConnectionString); - WarnManager warnManager = new(database); - playersToTarget.ForEach(player => { if (!player.UserId.HasValue) return; @@ -565,7 +556,7 @@ public void OnWarnsCommand(CCSPlayerController? caller, CommandInfo command) Task.Run(async () => { - var warnsList = await warnManager.GetPlayerWarns(PlayersInfo[userId], false); + var warnsList = await WarnManager.GetPlayerWarns(PlayersInfo[userId], false); var sortedWarns = warnsList .OrderBy(warn => (string)warn.status == "ACTIVE" ? 0 : 1) .ThenByDescending(warn => (int)warn.id) @@ -576,7 +567,7 @@ public void OnWarnsCommand(CCSPlayerController? caller, CommandInfo command) warnsMenu?.AddMenuOption($"[{((string)w.status == "ACTIVE" ? $"{ChatColors.LightRed}X" : $"{ChatColors.Lime}✔️")}{ChatColors.Default}] {(string)w.reason}", (controller, option) => { - _ = warnManager.UnwarnPlayer(PlayersInfo[userId], (int)w.id); + _ = WarnManager.UnwarnPlayer(PlayersInfo[userId], (int)w.id); player.PrintToChat(_localizer["sa_admin_warns_unwarn", player.PlayerName, (string)w.reason]); }); }); diff --git a/CS2-SimpleAdmin/Commands/basecomms.cs b/CS2-SimpleAdmin/Commands/basecomms.cs index 1c32117..d0d2647 100644 --- a/CS2-SimpleAdmin/Commands/basecomms.cs +++ b/CS2-SimpleAdmin/Commands/basecomms.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; using CS2_SimpleAdmin.Managers; +using CS2_SimpleAdmin.Menus; using CS2_SimpleAdminApi; namespace CS2_SimpleAdmin; @@ -27,20 +28,21 @@ public void OnGagCommand(CCSPlayerController? caller, CommandInfo command) { return; } - - int.TryParse(command.GetArg(2), out var time); - + if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) reason = command.GetArg(3); - MuteManager muteManager = new(Database); - playersToTarget.ForEach(player => { - if (caller!.CanTarget(player)) + if (!caller!.CanTarget(player)) return; + if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid) { - Gag(caller, player, time, reason, callerName, muteManager, command); + DurationMenu.OpenMenu(caller, $"{_localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player, + ManagePlayersMenu.GagMenu); + return; } + + Gag(caller, player, time, reason, callerName, MuteManager, command); }); } @@ -124,7 +126,6 @@ public void OnAddGagCommand(CCSPlayerController? caller, CommandInfo command) ? command.GetArg(3) : (_localizer?["sa_unknown"] ?? "Unknown"); - MuteManager muteManager = new(Database); int.TryParse(command.GetArg(2), out var time); // Get player and admin info @@ -140,14 +141,14 @@ public void OnAddGagCommand(CCSPlayerController? caller, CommandInfo command) if (!caller.CanTarget(player)) return; // Perform the gag for an online player - Gag(caller, player, time, reason, callerName, muteManager, silent: true); + Gag(caller, player, time, reason, callerName, MuteManager, silent: true); } else { // Asynchronous gag operation for offline players Task.Run(async () => { - await muteManager.AddMuteBySteamid(steamid, adminInfo, reason, time); + await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time); }); command.ReplyToCommand($"Player with steamid {steamid} is not online. Gag has been added offline."); @@ -244,19 +245,20 @@ public void OnMuteCommand(CCSPlayerController? caller, CommandInfo command) return; } - int.TryParse(command.GetArg(2), out var time); - if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) reason = command.GetArg(3); - MuteManager muteManager = new(Database); - playersToTarget.ForEach(player => { - if (caller!.CanTarget(player)) + if (!caller!.CanTarget(player)) return; + if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid) { - Mute(caller, player, time, reason, callerName, muteManager, command); + DurationMenu.OpenMenu(caller, $"{_localizer?["sa_mute"] ?? "Mute"}: {player.PlayerName}", player, + ManagePlayersMenu.MuteMenu); + return; } + + Mute(caller, player, time, reason, callerName, MuteManager, command); }); } @@ -343,7 +345,6 @@ public void OnAddMuteCommand(CCSPlayerController? caller, CommandInfo command) ? command.GetArg(3) : (_localizer?["sa_unknown"] ?? "Unknown"); - MuteManager muteManager = new(Database); int.TryParse(command.GetArg(2), out var time); // Get player and admin info @@ -359,14 +360,14 @@ public void OnAddMuteCommand(CCSPlayerController? caller, CommandInfo command) if (!caller.CanTarget(player)) return; // Perform the mute for an online player - Mute(caller, player, time, reason, callerName, muteManager, silent: true); + Mute(caller, player, time, reason, callerName, MuteManager, silent: true); } else { // Asynchronous mute operation for offline players Task.Run(async () => { - await muteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 1); + await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 1); }); command.ReplyToCommand($"Player with steamid {steamid} is not online. Mute has been added offline."); @@ -464,20 +465,21 @@ public void OnSilenceCommand(CCSPlayerController? caller, CommandInfo command) { return; } - - int.TryParse(command.GetArg(2), out var time); - + if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) reason = command.GetArg(3); - MuteManager muteManager = new(Database); - playersToTarget.ForEach(player => { - if (caller!.CanTarget(player)) + if (!caller!.CanTarget(player)) return; + if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid) { - Silence(caller, player, time, reason, callerName, muteManager, command); + DurationMenu.OpenMenu(caller, $"{_localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player, + ManagePlayersMenu.SilenceMenu); + return; } + + Silence(caller, player, time, reason, callerName, MuteManager, command); }); } @@ -562,7 +564,6 @@ public void OnAddSilenceCommand(CCSPlayerController? caller, CommandInfo command : (_localizer?["sa_unknown"] ?? "Unknown"); int.TryParse(command.GetArg(2), out var time); - MuteManager muteManager = new(Database); // Get player and admin info var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; @@ -577,14 +578,14 @@ public void OnAddSilenceCommand(CCSPlayerController? caller, CommandInfo command if (!caller.CanTarget(player)) return; // Perform the silence for an online player - Silence(caller, player, time, reason, callerName, muteManager, silent: true); + Silence(caller, player, time, reason, callerName, MuteManager, silent: true); } else { // Asynchronous silence operation for offline players Task.Run(async () => { - await muteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 2); + await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 2); }); command.ReplyToCommand($"Player with steamid {steamid} is not online. Silence has been added offline."); diff --git a/CS2-SimpleAdmin/Config.cs b/CS2-SimpleAdmin/Config.cs index c9d895c..7a043ad 100644 --- a/CS2-SimpleAdmin/Config.cs +++ b/CS2-SimpleAdmin/Config.cs @@ -27,7 +27,7 @@ public class DiscordPenaltySetting public required string Name { get; set; } [JsonPropertyName("value")] - public string Value { get; set; } = ""; + public string? Value { get; set; } = ""; } public class Discord @@ -210,6 +210,9 @@ public class OtherSettings [JsonPropertyName("DisconnectedPlayersHistoryCount")] public int DisconnectedPlayersHistoryCount { get; set; } = 10; + + [JsonPropertyName("NotifyPenaltiesToAdminOnConnect")] + public bool NotifyPenaltiesToAdminOnConnect { get; set; } = true; } public class CS2_SimpleAdminConfig : BasePluginConfig diff --git a/CS2-SimpleAdmin/Database/Migrations/010_CreateWarnsTable.sql b/CS2-SimpleAdmin/Database/Migrations/010_CreateWarnsTable.sql index de1afa5..af4d509 100644 --- a/CS2-SimpleAdmin/Database/Migrations/010_CreateWarnsTable.sql +++ b/CS2-SimpleAdmin/Database/Migrations/010_CreateWarnsTable.sql @@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS `sa_warns` ( `admin_name` varchar(128) NOT NULL, `reason` varchar(255) NOT NULL, `duration` int(11) NOT NULL, - `ends` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ends` timestamp NOT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `server_id` int(11) DEFAULT NULL, `status` enum('ACTIVE','EXPIRED','') NOT NULL DEFAULT 'ACTIVE', diff --git a/CS2-SimpleAdmin/Events.cs b/CS2-SimpleAdmin/Events.cs index db48ca5..38d630f 100644 --- a/CS2-SimpleAdmin/Events.cs +++ b/CS2-SimpleAdmin/Events.cs @@ -21,10 +21,27 @@ private void RegisterEvents() RegisterListener(OnMapStart); RegisterListener(OnGameServerSteamAPIActivated); AddCommandListener(null, OnCommandSayNew); + AddCommandListener("callvote", OnCommandCallVote); // AddCommandListener("say", OnCommandSay); // AddCommandListener("say_team", OnCommandTeamSay); } + private HookResult OnCommandCallVote(CCSPlayerController? caller, CommandInfo commandinfo) + { + var voteType = commandinfo.GetArg(1).ToLower(); + if (voteType != "kick") + return HookResult.Continue; + + var target = int.TryParse(commandinfo.GetArg(2), out var userId) + ? Utilities.GetPlayerFromUserid(userId) + : null; + + if (target == null || !target.IsValid || target.Connected != PlayerConnectedState.PlayerConnected) + return HookResult.Continue; + + return !CounterStrikeSharp.API.Modules.Admin.AdminManager.CanPlayerTarget(caller, target) ? HookResult.Stop : HookResult.Continue; + } + private void OnGameServerSteamAPIActivated() { new ServerManager().LoadServerData(); @@ -79,8 +96,8 @@ public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo out var expirationTime) || !(expirationTime <= Time.ActualDateTime())) return HookResult.Continue; - AdminManager.ClearPlayerPermissions(authorizedSteamId); - AdminManager.RemovePlayerAdminData(authorizedSteamId); + CounterStrikeSharp.API.Modules.Admin.AdminManager.ClearPlayerPermissions(authorizedSteamId); + CounterStrikeSharp.API.Modules.Admin.AdminManager.RemovePlayerAdminData(authorizedSteamId); return HookResult.Continue; } @@ -160,10 +177,10 @@ private HookResult OnCommandSayNew(CCSPlayerController? player, CommandInfo info StringBuilder sb = new(); - if (AdminManager.PlayerHasPermissions(player, "@css/chat")) + if (CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(player, "@css/chat")) { sb.Append(_localizer!["sa_adminchat_template_admin", player.PlayerName, info.GetArg(1).Remove(0, 1)]); - foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p is { IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(p, "@css/chat"))) + foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p is { IsBot: false, IsHLTV: false } && CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(p, "@css/chat"))) { p.PrintToChat(sb.ToString()); } @@ -172,7 +189,7 @@ private HookResult OnCommandSayNew(CCSPlayerController? player, CommandInfo info { sb.Append(_localizer!["sa_adminchat_template_player", player.PlayerName, info.GetArg(1).Remove(0, 1)]); player.PrintToChat(sb.ToString()); - foreach (var p in Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(p, "@css/chat"))) + foreach (var p in Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false } && CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(p, "@css/chat"))) { p.PrintToChat(sb.ToString()); } @@ -218,10 +235,10 @@ public HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info StringBuilder sb = new(); - if (AdminManager.PlayerHasPermissions(player, "@css/chat")) + if (CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(player, "@css/chat")) { sb.Append(_localizer!["sa_adminchat_template_admin", player.PlayerName, info.GetArg(1).Remove(0, 1)]); - foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p is { IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(p, "@css/chat"))) + foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p is { IsBot: false, IsHLTV: false } && CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(p, "@css/chat"))) { p.PrintToChat(sb.ToString()); } @@ -230,7 +247,7 @@ public HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info { sb.Append(_localizer!["sa_adminchat_template_player", player.PlayerName, info.GetArg(1).Remove(0, 1)]); player.PrintToChat(sb.ToString()); - foreach (var p in Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(p, "@css/chat"))) + foreach (var p in Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false } && CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(p, "@css/chat"))) { p.PrintToChat(sb.ToString()); } diff --git a/CS2-SimpleAdmin/Helper.cs b/CS2-SimpleAdmin/Helper.cs index aef9635..ce6f797 100644 --- a/CS2-SimpleAdmin/Helper.cs +++ b/CS2-SimpleAdmin/Helper.cs @@ -1,4 +1,5 @@ -using CounterStrikeSharp.API; +using System.Globalization; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; @@ -9,18 +10,15 @@ using CounterStrikeSharp.API.Modules.Menu; using CounterStrikeSharp.API.ValveConstants.Protobuf; using CS2_SimpleAdminApi; -using Discord; -using Discord.Webhook; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; -using System.Drawing; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; -using Color = Discord.Color; +using CS2_SimpleAdmin.Managers; namespace CS2_SimpleAdmin; @@ -188,7 +186,7 @@ internal static void LogCommand(CCSPlayerController? caller, CommandInfo command "sa_discord_log_command", playerName, command.GetCommandString]}".Replace("HOSTNAME", hostname).Replace("**", "")); - SendDiscordLogMessage(caller, command, CS2_SimpleAdmin.DiscordWebhookClientLog, CS2_SimpleAdmin._localizer); + SendDiscordLogMessage(caller, command, CS2_SimpleAdmin._localizer); } internal static void LogCommand(CCSPlayerController? caller, string command) @@ -204,7 +202,7 @@ internal static void LogCommand(CCSPlayerController? caller, string command) CS2_SimpleAdmin.Instance.Logger.LogInformation($"{CS2_SimpleAdmin._localizer["sa_discord_log_command", playerName, command]}".Replace("HOSTNAME", hostname).Replace("**", "")); - SendDiscordLogMessage(caller, command, CS2_SimpleAdmin.DiscordWebhookClientLog, CS2_SimpleAdmin._localizer); + SendDiscordLogMessage(caller, command, CS2_SimpleAdmin._localizer); } /*public static IEnumerable GenerateEmbedsDiscord(string title, string description, string thumbnailUrl, Color color, string[] fieldNames, string[] fieldValues, bool[] inlineFlags) @@ -239,22 +237,22 @@ internal static void LogCommand(CCSPlayerController? caller, string command) return new List { embed.Build() }; }*/ - private static void SendDiscordLogMessage(CCSPlayerController? caller, CommandInfo command, DiscordWebhookClient? discordWebhookClientLog, IStringLocalizer? localizer) + private static void SendDiscordLogMessage(CCSPlayerController? caller, CommandInfo command, IStringLocalizer? localizer) { - if (discordWebhookClientLog == null || localizer == null) return; + if (CS2_SimpleAdmin.DiscordWebhookClientLog == null || localizer == null) return; var communityUrl = caller != null ? "<" + new SteamID(caller.SteamID).ToCommunityUrl() + ">" : ""; var callerName = caller != null ? caller.PlayerName : CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console"; - discordWebhookClientLog.SendMessageAsync(Helper.GenerateMessageDiscord(localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", command.GetCommandString])); + _ = CS2_SimpleAdmin.DiscordWebhookClientLog.SendMessageAsync(Helper.GenerateMessageDiscord(localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", command.GetCommandString])); } - private static void SendDiscordLogMessage(CCSPlayerController? caller, string command, DiscordWebhookClient? discordWebhookClientLog, IStringLocalizer? localizer) + private static void SendDiscordLogMessage(CCSPlayerController? caller, string command, IStringLocalizer? localizer) { - if (discordWebhookClientLog == null || localizer == null) return; + if (CS2_SimpleAdmin.DiscordWebhookClientLog == null || localizer == null) return; var communityUrl = caller != null ? "<" + new SteamID(caller.SteamID).ToCommunityUrl() + ">" : ""; var callerName = caller != null ? caller.PlayerName : CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console"; - discordWebhookClientLog.SendMessageAsync(GenerateMessageDiscord(localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", command])); + _ = CS2_SimpleAdmin.DiscordWebhookClientLog.SendMessageAsync(GenerateMessageDiscord(localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", command])); } public static void ShowAdminActivity(string messageKey, string? callerName = null, params object[] messageArgs) @@ -343,7 +341,7 @@ private static string ConvertMinutesToTime(int minutes) public static void SendDiscordPenaltyMessage(CCSPlayerController? caller, CCSPlayerController? target, string reason, int duration, PenaltyType penalty, IStringLocalizer? localizer) { if (localizer == null) return; - + var penaltySetting = penalty switch { PenaltyType.Ban => CS2_SimpleAdmin.Instance.Config.Discord.DiscordPenaltyBanSettings, @@ -357,11 +355,13 @@ public static void SendDiscordPenaltyMessage(CCSPlayerController? caller, CCSPla var webhookUrl = penaltySetting.FirstOrDefault(s => s.Name.Equals("Webhook"))?.Value; if (string.IsNullOrEmpty(webhookUrl)) return; + + const string defaultCommunityUrl = ""; + var callerCommunityUrl = caller != null ? $"<{new SteamID(caller.SteamID).ToCommunityUrl()}>" : defaultCommunityUrl; + var targetCommunityUrl = target != null ? $"<{new SteamID(target.SteamID).ToCommunityUrl()}>" : defaultCommunityUrl; - var callerCommunityUrl = caller != null ? "<" + new SteamID(caller.SteamID).ToCommunityUrl() + ">" : ""; - var targetCommunityUrl = target != null ? "<" + new SteamID(target.SteamID).ToCommunityUrl() + ">" : ""; - var callerName = caller != null ? caller.PlayerName : CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console"; - var targetName = target != null ? target.PlayerName : localizer["sa_unknown"]; + var callerName = caller?.PlayerName ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console"; + var targetName = target?.PlayerName ?? localizer["sa_unknown"]; var targetSteamId = target != null ? new SteamID(target.SteamID).SteamId64.ToString() : localizer["sa_unknown"]; var futureTime = Time.ActualDateTime().AddMinutes(duration); @@ -385,16 +385,14 @@ public static void SendDiscordPenaltyMessage(CCSPlayerController? caller, CCSPla $"[{targetName}]({targetCommunityUrl})", $"||{targetSteamId}||", time, reason, $"[{callerName}]({callerCommunityUrl})" ]; + bool[] inlineFlags = [true, true, true, false, false]; - var hostname = ConVar.Find("hostname")?.StringValue ?? localizer["sa_unknown"]; - var colorHex = penaltySetting.FirstOrDefault(s => s.Name.Equals("Color"))?.Value ?? "#FFFFFF"; - var color = ColorTranslator.FromHtml(colorHex); - var embed = new EmbedBuilder + var embed = new Embed { - Color = new Color(color.R, color.G, color.B), + Color = DiscordManager.ColorFromHex(colorHex), Title = penalty switch { PenaltyType.Ban => localizer["sa_discord_penalty_ban"], @@ -404,14 +402,15 @@ public static void SendDiscordPenaltyMessage(CCSPlayerController? caller, CCSPla PenaltyType.Warn => localizer["sa_discord_penalty_warn"], _ => throw new ArgumentOutOfRangeException(nameof(penalty), penalty, null) }, + Description = $"{hostname}", ThumbnailUrl = penaltySetting.FirstOrDefault(s => s.Name.Equals("ThumbnailUrl"))?.Value, ImageUrl = penaltySetting.FirstOrDefault(s => s.Name.Equals("ImageUrl"))?.Value, - Footer = new EmbedFooterBuilder + Footer = new Footer { - Text = penaltySetting.FirstOrDefault(s => s.Name.Equals("Footer"))?.Value, + Text = penaltySetting.FirstOrDefault(s => s.Name.Equals("Footer"))?.Value }, - Description = $"{hostname}", - Timestamp = DateTimeOffset.Now, + + Timestamp = Time.ActualDateTime().ToUniversalTime().ToString("o"), }; for (var i = 0; i < fieldNames.Length; i++) @@ -421,7 +420,15 @@ public static void SendDiscordPenaltyMessage(CCSPlayerController? caller, CCSPla Task.Run(async () => { - await new DiscordWebhookClient(webhookUrl).SendMessageAsync(embeds: [embed.Build()]); + try + { + await new DiscordManager(webhookUrl).SendEmbedAsync(embed); + } + catch (Exception ex) + { + // Log or handle the exception + Console.WriteLine(ex); + } }); } @@ -470,7 +477,6 @@ uint16_t port } } - public static void UpdateConfig(T config) where T : BasePluginConfig, new() { // get newest config version @@ -505,7 +511,7 @@ public static void TryLogCommandOnDiscord(CCSPlayerController? caller, string co var communityUrl = caller != null ? "<" + new SteamID(caller.SteamID).ToCommunityUrl() + ">" : ""; - CS2_SimpleAdmin.DiscordWebhookClientLog.SendMessageAsync(GenerateMessageDiscord( + _ = CS2_SimpleAdmin.DiscordWebhookClientLog.SendMessageAsync(GenerateMessageDiscord( CS2_SimpleAdmin._localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", commandString])); } @@ -513,20 +519,21 @@ public static void TryLogCommandOnDiscord(CCSPlayerController? caller, string co public static class PluginInfo { - internal static async Task CheckVersion(string version, ILogger logger) + internal static async Task CheckVersion(string localVersion, ILogger logger) { - using HttpClient client = new(); + const string versionUrl = "https://raw.githubusercontent.com/daffyyyy/CS2-SimpleAdmin/main/CS2-SimpleAdmin/VERSION"; + var client = CS2_SimpleAdmin.HttpClient; try { - var response = await client.GetAsync("https://raw.githubusercontent.com/daffyyyy/CS2-SimpleAdmin/main/CS2-SimpleAdmin/VERSION"); + var response = await client.GetAsync(versionUrl); if (response.IsSuccessStatusCode) { var remoteVersion = await response.Content.ReadAsStringAsync(); remoteVersion = remoteVersion.Trim(); - var comparisonResult = string.CompareOrdinal(version, remoteVersion); + var comparisonResult = string.CompareOrdinal(localVersion, remoteVersion); switch (comparisonResult) { @@ -543,7 +550,7 @@ internal static async Task CheckVersion(string version, ILogger logger) } else { - logger.LogWarning("Failed to check version"); + logger.LogWarning($"Failed to check version. Status Code: {response.StatusCode}"); } } catch (HttpRequestException ex) @@ -555,7 +562,7 @@ internal static async Task CheckVersion(string version, ILogger logger) logger.LogError(ex, "An error occurred while checking version."); } } - + internal static void ShowAd(string moduleVersion) { Console.WriteLine(" "); diff --git a/CS2-SimpleAdmin/Managers/BanManager.cs b/CS2-SimpleAdmin/Managers/BanManager.cs index f9059f8..a9854bd 100644 --- a/CS2-SimpleAdmin/Managers/BanManager.cs +++ b/CS2-SimpleAdmin/Managers/BanManager.cs @@ -8,10 +8,12 @@ namespace CS2_SimpleAdmin.Managers; -internal class BanManager(Database.Database database, CS2_SimpleAdminConfig config) +internal class BanManager(Database.Database? database) { public async Task BanPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0) { + if (database == null) return; + DateTime now = Time.ActualDateTime(); DateTime futureTime = now.AddMinutes(time); @@ -26,7 +28,7 @@ public async Task BanPlayer(PlayerInfo player, PlayerInfo? issuer, string reason { playerSteamid = player.SteamId.SteamId64.ToString(), playerName = player.Name, - playerIp = config.OtherSettings.BanType == 1 ? player.IpAddress : null, + playerIp = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 1 ? player.IpAddress : null, adminSteamid = issuer?.SteamId.SteamId64.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", banReason = reason, @@ -41,6 +43,8 @@ public async Task BanPlayer(PlayerInfo player, PlayerInfo? issuer, string reason public async Task AddBanBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0) { + if (database == null) return; + if (string.IsNullOrEmpty(playerSteamId)) return; DateTime now = Time.ActualDateTime(); @@ -70,6 +74,8 @@ public async Task AddBanBySteamid(string playerSteamId, PlayerInfo? issuer, stri public async Task AddBanByIp(string playerIp, PlayerInfo? issuer, string reason, int time = 0) { + if (database == null) return; + if (string.IsNullOrEmpty(playerIp)) return; DateTime now = Time.ActualDateTime(); @@ -99,6 +105,8 @@ public async Task AddBanByIp(string playerIp, PlayerInfo? issuer, string reason, public async Task IsPlayerBanned(PlayerInfo player) { + if (database == null) return false; + if (player.IpAddress == null) { return false; @@ -115,62 +123,58 @@ public async Task IsPlayerBanned(PlayerInfo player) try { - var sql = config.MultiServerMode ? """ - UPDATE sa_bans - SET player_ip = CASE WHEN player_ip IS NULL THEN @PlayerIP ELSE player_ip END, - player_name = CASE WHEN player_name IS NULL THEN @PlayerName ELSE player_name END - WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) - AND status = 'ACTIVE' - AND (duration = 0 OR ends > @CurrentTime); - - SELECT COUNT(*) FROM sa_bans - WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) - AND status = 'ACTIVE' - AND (duration = 0 OR ends > @CurrentTime); - """ : @" - UPDATE sa_bans - SET player_ip = CASE WHEN player_ip IS NULL THEN @PlayerIP ELSE player_ip END, - player_name = CASE WHEN player_name IS NULL THEN @PlayerName ELSE player_name END - WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) - AND status = 'ACTIVE' - AND (duration = 0 OR ends > @CurrentTime) AND server_id = @serverid; - - SELECT COUNT(*) FROM sa_bans - WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) - AND status = 'ACTIVE' - AND (duration = 0 OR ends > @CurrentTime) AND server_id = @serverid;"; + var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? """ + SELECT COALESCE(( + SELECT COUNT(*) + FROM sa_bans + WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) + AND status = 'ACTIVE' + AND (duration = 0 OR ends > @CurrentTime) + ), 0) AS BanCount + + COALESCE(( + SELECT COUNT(*) + FROM sa_bans + JOIN sa_players_ips ON sa_bans.player_steamid = sa_players_ips.steamid + WHERE sa_bans.status = 'ACTIVE' + AND sa_players_ips.address = @PlayerIP + AND (SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) + AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)) = 0 + ), 0) AS TotalBanCount; + """ : """ + SELECT COALESCE(( + SELECT COUNT(*) + FROM sa_bans + WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) + AND status = 'ACTIVE' + AND (duration = 0 OR ends > @CurrentTime) + AND server_id = @ServerId + ), 0) AS BanCount + + COALESCE(( + SELECT COUNT(*) + FROM sa_bans + JOIN sa_players_ips ON sa_bans.player_steamid = sa_players_ips.steamid + WHERE sa_bans.status = 'ACTIVE' + AND sa_players_ips.address = @PlayerIP + AND (SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) + AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime) AND server_id = @ServerId) = 0 + ), 0) AS TotalBanCount; + """; await using var connection = await database.GetConnectionAsync(); var parameters = new { PlayerSteamID = player.SteamId.SteamId64.ToString(), - PlayerIP = config.OtherSettings.BanType == 0 || string.IsNullOrEmpty(player.IpAddress) ? null : player.IpAddress, + PlayerIP = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0 || + string.IsNullOrEmpty(player.IpAddress) + ? null + : player.IpAddress, PlayerName = !string.IsNullOrEmpty(player.Name) ? player.Name : string.Empty, CurrentTime = currentTime, - serverid = CS2_SimpleAdmin.ServerId + CS2_SimpleAdmin.ServerId }; banCount = await connection.ExecuteScalarAsync(sql, parameters); - - if (config.OtherSettings.BanType == 1 && banCount == 0) - { - sql = """ - SELECT - COUNT(*) - FROM - sa_bans - JOIN sa_players_ips ON sa_bans.player_steamid = sa_players_ips.steamid - WHERE - sa_bans.status = 'ACTIVE' - AND sa_players_ips.address = @PlayerIP; - """; - - banCount = await connection.ExecuteScalarAsync(sql, new - { - PlayerIP = player.IpAddress - }); - } } catch (Exception) { @@ -182,11 +186,13 @@ SELECT COUNT(*) FROM sa_bans public async Task GetPlayerBans(PlayerInfo player) { + if (database == null) return 0; + try { - var sql = ""; + string sql; - sql = config.MultiServerMode + sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP)" : "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND server_id = @serverid"; @@ -194,7 +200,7 @@ public async Task GetPlayerBans(PlayerInfo player) await using var connection = await database.GetConnectionAsync(); - if (config.OtherSettings.BanType > 0 && !string.IsNullOrEmpty(player.IpAddress)) + if (CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType > 0 && !string.IsNullOrEmpty(player.IpAddress)) { banCount = await connection.ExecuteScalarAsync(sql, new @@ -224,6 +230,8 @@ public async Task GetPlayerBans(PlayerInfo player) public async Task UnbanPlayer(string playerPattern, string adminSteamId, string reason) { + if (database == null) return; + if (playerPattern is not { Length: > 1 }) { return; @@ -232,7 +240,7 @@ public async Task UnbanPlayer(string playerPattern, string adminSteamId, string { await using var connection = await database.GetConnectionAsync(); - var sqlRetrieveBans = config.MultiServerMode + var sqlRetrieveBans = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? "SELECT id FROM sa_bans WHERE (player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern) AND status = 'ACTIVE'" : "SELECT id FROM sa_bans WHERE (player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern) AND status = 'ACTIVE' AND server_id = @serverid"; @@ -273,10 +281,12 @@ public async Task UnbanPlayer(string playerPattern, string adminSteamId, string public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players) { + if (database == null) return; + try { await using var connection = await database.GetConnectionAsync(); - bool checkIpBans = config.OtherSettings.BanType > 0; + bool checkIpBans = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType > 0; var filteredPlayers = players.Where(p => p.UserId.HasValue).ToList(); @@ -290,7 +300,7 @@ public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int var sql = new StringBuilder(); sql.Append("SELECT `player_steamid`, `player_ip` FROM `sa_bans` WHERE `status` = 'ACTIVE' "); - if (config.MultiServerMode) + if (CS2_SimpleAdmin.Instance.Config.MultiServerMode) { sql.Append("AND (player_steamid IN @SteamIDs "); if (checkIpBans && ipAddresses.Count != 0) @@ -341,6 +351,7 @@ await Server.NextFrameAsync(() => public async Task ExpireOldBans() { + if (database == null) return; var currentTime = Time.ActualDateTime(); try @@ -354,58 +365,58 @@ public async Task ExpireOldBans() await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.UtcNow }); */ - var sql = ""; - - sql = config.MultiServerMode ? """ - - UPDATE sa_bans - SET - status = 'EXPIRED' - WHERE - status = 'ACTIVE' - AND - `duration` > 0 - AND - ends <= @currentTime - """ : """ - - UPDATE sa_bans - SET - status = 'EXPIRED' - WHERE - status = 'ACTIVE' - AND - `duration` > 0 - AND - ends <= @currentTime - AND server_id = @serverid - """; + string sql; + + sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? """ + + UPDATE sa_bans + SET + status = 'EXPIRED' + WHERE + status = 'ACTIVE' + AND + `duration` > 0 + AND + ends <= @currentTime + """ : """ + + UPDATE sa_bans + SET + status = 'EXPIRED' + WHERE + status = 'ACTIVE' + AND + `duration` > 0 + AND + ends <= @currentTime + AND server_id = @serverid + """; await connection.ExecuteAsync(sql, new { currentTime, serverid = CS2_SimpleAdmin.ServerId }); - if (config.OtherSettings.ExpireOldIpBans > 0) + if (CS2_SimpleAdmin.Instance.Config.OtherSettings.ExpireOldIpBans > 0) { - var ipBansTime = currentTime.AddDays(-config.OtherSettings.ExpireOldIpBans); - sql = config.MultiServerMode ? """ - - UPDATE sa_bans - SET - player_ip = NULL - WHERE - status = 'ACTIVE' - AND - ends <= @ipBansTime - """ : """ - - UPDATE sa_bans - SET - player_ip = NULL - WHERE - status = 'ACTIVE' - AND - ends <= @ipBansTime - AND server_id = @serverid - """; + var ipBansTime = currentTime.AddDays(-CS2_SimpleAdmin.Instance.Config.OtherSettings.ExpireOldIpBans); + sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? """ + + UPDATE sa_bans + SET + player_ip = NULL + WHERE + status = 'ACTIVE' + AND + ends <= @ipBansTime + """ : """ + + UPDATE sa_bans + SET + player_ip = NULL + WHERE + status = 'ACTIVE' + AND + ends <= @ipBansTime + AND server_id = @serverid + """; await connection.ExecuteAsync(sql, new { ipBansTime, CS2_SimpleAdmin.ServerId }); } diff --git a/CS2-SimpleAdmin/Managers/DiscordManager.cs b/CS2-SimpleAdmin/Managers/DiscordManager.cs new file mode 100644 index 0000000..60ce5d8 --- /dev/null +++ b/CS2-SimpleAdmin/Managers/DiscordManager.cs @@ -0,0 +1,124 @@ +using System.Text; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; + +namespace CS2_SimpleAdmin.Managers; + +public class DiscordManager(string webhookUrl) +{ + public async Task SendMessageAsync(string message) + { + var client = CS2_SimpleAdmin.HttpClient; + + var payload = new + { + content = message + }; + + var json = JsonConvert.SerializeObject(payload); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + try + { + var response = await client.PostAsync(webhookUrl, content); + + if (!response.IsSuccessStatusCode) + { + CS2_SimpleAdmin._logger?.LogError( + $"Failed to send discord message. Status Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"); + } + } + catch (HttpRequestException e) + { + CS2_SimpleAdmin._logger?.LogError($"Error sending discord message: {e.Message}"); + } + } + + public async Task SendEmbedAsync(Embed embed) + { + var httpClient = CS2_SimpleAdmin.HttpClient; + + var payload = new + { + embeds = new[] + { + new + { + color = embed.Color, + title = !string.IsNullOrEmpty(embed.Title) ? embed.Title : null, + description = !string.IsNullOrEmpty(embed.Description) ? embed.Description : null, + thumbnail = !string.IsNullOrEmpty(embed.ThumbnailUrl) ? new { url = embed.ThumbnailUrl } : null, + image = !string.IsNullOrEmpty(embed.ImageUrl) ? new { url = embed.ImageUrl } : null, + footer = !string.IsNullOrEmpty(embed.Footer?.Text) ? new { text = embed.Footer.Text, icon_url = embed.Footer.IconUrl } : null, + timestamp = embed.Timestamp, + fields = embed.Fields.Count > 0 ? embed.Fields.Select(field => new + { + name = field.Name, + value = field.Value, + inline = field.Inline + }).ToArray() : null + } + } + }; + + var jsonPayload = JsonConvert.SerializeObject(payload); + var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"); + + var response = await httpClient.PostAsync(webhookUrl, content); + + if (!response.IsSuccessStatusCode) + { + var errorMessage = await response.Content.ReadAsStringAsync(); + CS2_SimpleAdmin._logger?.LogError($"Failed to send embed: {response.StatusCode} - {errorMessage}"); + } + } + + public static int ColorFromHex(string hex) + { + if (hex.StartsWith($"#")) + { + hex = hex[1..]; + } + + return int.Parse(hex, System.Globalization.NumberStyles.HexNumber); + } +} + +public class Embed +{ + public int Color { get; init; } + public string? Title { get; init; } + public string? Description { get; init; } + public string? ImageUrl { get; init; } + public string? ThumbnailUrl { get; init; } + public Footer? Footer { get; init; } + public string? Timestamp { get; init; } + + public List Fields { get; } = []; + + public void AddField(string name, string value, bool inline) + { + var field = new EmbedField + { + Name = name, + Value = value, + Inline = inline + }; + + Fields.Add(field); + } +} + +public class Footer +{ + public string? Text { get; init; } + public string? IconUrl { get; set; } +} + +public class EmbedField +{ + public string? Name { get; init; } + public string? Value { get; init; } + public bool Inline { get; init; } +} + diff --git a/CS2-SimpleAdmin/Managers/MuteManager.cs b/CS2-SimpleAdmin/Managers/MuteManager.cs index d112cb4..ef907eb 100644 --- a/CS2-SimpleAdmin/Managers/MuteManager.cs +++ b/CS2-SimpleAdmin/Managers/MuteManager.cs @@ -4,10 +4,12 @@ namespace CS2_SimpleAdmin.Managers; -internal class MuteManager(Database.Database database) +internal class MuteManager(Database.Database? database) { public async Task MutePlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0, int type = 0) { + if (database == null) return; + var now = Time.ActualDateTime(); var futureTime = now.AddMinutes(time); @@ -47,6 +49,8 @@ public async Task MutePlayer(PlayerInfo player, PlayerInfo? issuer, string reaso public async Task AddMuteBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0, int type = 0) { + if (database == null) return; + if (string.IsNullOrEmpty(playerSteamId)) return; @@ -84,6 +88,8 @@ public async Task AddMuteBySteamid(string playerSteamId, PlayerInfo? issuer, str public async Task> IsPlayerMuted(string steamId) { + if (database == null) return []; + if (string.IsNullOrEmpty(steamId)) { return []; @@ -124,34 +130,50 @@ public async Task> IsPlayerMuted(string steamId) } } - public async Task GetPlayerMutes(PlayerInfo playerInfo, int type = 0) + public async Task<(int TotalMutes, int TotalGags, int TotalSilences)> GetPlayerMutes(PlayerInfo playerInfo) { + if (database == null) return (0,0,0); + try { - var muteType = type switch - { - 1 => "MUTE", - 2 => "SILENCE", - _ => "GAG" - }; - await using var connection = await database.GetConnectionAsync(); var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode - ? "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND type = @MuteType" - : "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND server_id = @serverid AND type = @MuteType"; + ? """ + SELECT + COUNT(CASE WHEN type = 'MUTE' THEN 1 END) AS TotalMutes, + COUNT(CASE WHEN type = 'GAG' THEN 1 END) AS TotalGags, + COUNT(CASE WHEN type = 'SILENCE' THEN 1 END) AS TotalSilences + FROM sa_mutes + WHERE player_steamid = @PlayerSteamID; + """ + : """ + SELECT + COUNT(CASE WHEN type = 'MUTE' THEN 1 END) AS TotalMutes, + COUNT(CASE WHEN type = 'GAG' THEN 1 END) AS TotalGags, + COUNT(CASE WHEN type = 'SILENCE' THEN 1 END) AS TotalSilences + FROM sa_mutes + WHERE player_steamid = @PlayerSteamID AND server_id = @ServerId; + """; + + var result = await connection.QuerySingleAsync<(int TotalMutes, int TotalGags, int TotalSilences)>(sql, new + { + PlayerSteamID = playerInfo.SteamId.SteamId64.ToString(), + CS2_SimpleAdmin.ServerId + }); - var muteCount = await connection.ExecuteScalarAsync(sql, new { PlayerSteamID = playerInfo.SteamId.SteamId64.ToString(), serverid = CS2_SimpleAdmin.ServerId, MuteType = muteType }); - return muteCount; + return result; } catch (Exception) { - return 0; + return (0, 0, 0); } } - + public async Task CheckOnlineModeMutes(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players) { + if (database == null) return; + try { int batchSize = 10; @@ -196,6 +218,8 @@ public async Task CheckOnlineModeMutes(List<(string? IpAddress, ulong SteamID, i public async Task UnmutePlayer(string playerPattern, string adminSteamId, string reason, int type = 0) { + if (database == null) return; + if (playerPattern.Length <= 1) { return; @@ -266,6 +290,8 @@ public async Task UnmutePlayer(string playerPattern, string adminSteamId, string public async Task ExpireOldMutes() { + if (database == null) return; + try { await using var connection = await database.GetConnectionAsync(); diff --git a/CS2-SimpleAdmin/Managers/PermissionManager.cs b/CS2-SimpleAdmin/Managers/PermissionManager.cs index c094191..4ac21b0 100644 --- a/CS2-SimpleAdmin/Managers/PermissionManager.cs +++ b/CS2-SimpleAdmin/Managers/PermissionManager.cs @@ -8,7 +8,7 @@ namespace CS2_SimpleAdmin.Managers; -public class PermissionManager(Database.Database database) +public class PermissionManager(Database.Database? database) { // Unused for now //public static readonly ConcurrentDictionary> _adminCache = new ConcurrentDictionary>(); @@ -59,6 +59,8 @@ public class PermissionManager(Database.Database database) private async Task, int, DateTime?)>> GetAllPlayersFlags() { + if (database == null) return []; + var now = Time.ActualDateTime(); try @@ -176,6 +178,8 @@ FROM sa_admins a private async Task, int)>> GetAllGroupsData() { + if (database == null) return []; + await using MySqlConnection connection = await database.GetConnectionAsync(); try { @@ -366,6 +370,8 @@ public async Task CreateAdminsJsonFile() public async Task DeleteAdminBySteamId(string playerSteamId, bool globalDelete = false) { + if (database == null) return; + if (string.IsNullOrEmpty(playerSteamId)) return; //_adminCache.TryRemove(playerSteamId, out _); @@ -388,6 +394,8 @@ public async Task DeleteAdminBySteamId(string playerSteamId, bool globalDelete = public async Task AddAdminBySteamId(string playerSteamId, string playerName, List flagsList, int immunity = 0, int time = 0, bool globalAdmin = false) { + if (database == null) return; + if (string.IsNullOrEmpty(playerSteamId) || flagsList.Count == 0) return; var now = Time.ActualDateTime(); @@ -458,6 +466,8 @@ await Server.NextFrameAsync(() => public async Task AddGroup(string groupName, List flagsList, int immunity = 0, bool globalGroup = false) { + if (database == null) return; + if (string.IsNullOrEmpty(groupName) || flagsList.Count == 0) return; await using var connection = await database.GetConnectionAsync(); @@ -504,6 +514,8 @@ await Server.NextFrameAsync(() => public async Task DeleteGroup(string groupName) { + if (database == null) return; + if (string.IsNullOrEmpty(groupName)) return; await using var connection = await database.GetConnectionAsync(); @@ -520,6 +532,8 @@ public async Task DeleteGroup(string groupName) public async Task DeleteOldAdmins() { + if (database == null) return; + try { await using var connection = await database.GetConnectionAsync(); diff --git a/CS2-SimpleAdmin/Managers/PlayerManager.cs b/CS2-SimpleAdmin/Managers/PlayerManager.cs index 59b3df5..cb19d2d 100644 --- a/CS2-SimpleAdmin/Managers/PlayerManager.cs +++ b/CS2-SimpleAdmin/Managers/PlayerManager.cs @@ -27,12 +27,12 @@ public void LoadPlayerData(CCSPlayerController player) var userId = player.UserId.Value; // Check if the player's IP or SteamID is in the bannedPlayers list - if (_config.OtherSettings.BanType > 0 && CS2_SimpleAdmin.BannedPlayers.Contains(ipAddress) || CS2_SimpleAdmin.BannedPlayers.Contains(player.SteamID.ToString())) + if (_config.OtherSettings.BanType > 0 && CS2_SimpleAdmin.BannedPlayers.Contains(ipAddress) || + CS2_SimpleAdmin.BannedPlayers.Contains(player.SteamID.ToString())) { // Kick the player if banned if (player.UserId.HasValue) Helper.KickPlayer(player.UserId.Value, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); - return; } @@ -41,32 +41,52 @@ public void LoadPlayerData(CCSPlayerController player) // Perform asynchronous database operations within a single method Task.Run(async () => { - // Initialize managers - BanManager banManager = new(CS2_SimpleAdmin.Database, _config); - MuteManager muteManager = new(CS2_SimpleAdmin.Database); - WarnManager warnManager = new(CS2_SimpleAdmin.Database); - try { await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); - - const string query = """ - INSERT INTO `sa_players_ips` (steamid, address) - VALUES (@SteamID, @IPAddress) ON DUPLICATE KEY UPDATE `used_at` = CURRENT_TIMESTAMP - """; - - await connection.ExecuteAsync(query, new + const string selectQuery = "SELECT COUNT(*) FROM `sa_players_ips` WHERE steamid = @SteamID AND address = @IPAddress;"; + var recordExists = await connection.ExecuteScalarAsync(selectQuery, new { - SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId, - IPAddress = ipAddress, + SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, + IPAddress = ipAddress }); + + if (recordExists > 0) + { + const string updateQuery = """ + UPDATE `sa_players_ips` + SET used_at = CURRENT_TIMESTAMP + WHERE steamid = @SteamID AND address = @IPAddress; + """; + await connection.ExecuteAsync(updateQuery, new + { + SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, + IPAddress = ipAddress + }); + } + else + { + const string insertQuery = """ + INSERT INTO `sa_players_ips` (steamid, address, used_at) + VALUES (@SteamID, @IPAddress, CURRENT_TIMESTAMP); + """; + await connection.ExecuteAsync(insertQuery, new + { + SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, + IPAddress = ipAddress + }); + } + } + catch (Exception ex) + { + CS2_SimpleAdmin._logger?.LogError( + $"Unable to save ip address for {CS2_SimpleAdmin.PlayersInfo[userId].Name} ({ipAddress}) {ex.Message}"); } - catch { } try { // Check if the player is banned - bool isBanned = await banManager.IsPlayerBanned(CS2_SimpleAdmin.PlayersInfo[userId]); + bool isBanned = await CS2_SimpleAdmin.Instance.BanManager.IsPlayerBanned(CS2_SimpleAdmin.PlayersInfo[userId]); if (isBanned) { @@ -98,50 +118,19 @@ await Server.NextFrameAsync(() => return; } - var warns = await warnManager.GetPlayerWarns(CS2_SimpleAdmin.PlayersInfo[userId], false); + var warns = await CS2_SimpleAdmin.Instance.WarnManager.GetPlayerWarns(CS2_SimpleAdmin.PlayersInfo[userId], false); + var (totalMutes, totalGags, totalSilences) = + await CS2_SimpleAdmin.Instance.MuteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId]); CS2_SimpleAdmin.PlayersInfo[userId].TotalBans = - await banManager.GetPlayerBans(CS2_SimpleAdmin.PlayersInfo[userId]); - CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes = - await muteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId], 1); - CS2_SimpleAdmin.PlayersInfo[userId].TotalGags = - await muteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId], 0); - CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences = - await muteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId], 2); + await CS2_SimpleAdmin.Instance.BanManager.GetPlayerBans(CS2_SimpleAdmin.PlayersInfo[userId]); + CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes = totalMutes; + CS2_SimpleAdmin.PlayersInfo[userId].TotalGags = totalGags; + CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences = totalSilences; CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns = warns.Count; - // Check if the player is muted - var activeMutes = await muteManager.IsPlayerMuted(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString()); - - /* - Dictionary> mutesList = new() - { - { PenaltyType.Gag, [] }, - { PenaltyType.Mute, [] }, - { PenaltyType.Silence, [] } - }; - - List warnsList = []; - - bool found = false; - foreach (var warn in warns.TakeWhile(warn => (string)warn.status == "ACTIVE")) - { - DateTime ends = warn.ends; - if (CS2_SimpleAdmin._localizer == null) continue; - - Console.WriteLine(ends.ToLocalTime().ToString(CultureInfo.CurrentCulture)); - - warnsList.Add(CS2_SimpleAdmin._localizer["sa_player_penalty_info_active_warn", ends.ToLocalTime().ToString(CultureInfo.CurrentCulture), (string)warn.reason]); - found = true; - } - - if (!found) - { - if (CS2_SimpleAdmin._localizer != null) - warnsList.Add(CS2_SimpleAdmin._localizer["sa_player_penalty_info_no_active_warn"]); - } - */ + var activeMutes = await CS2_SimpleAdmin.Instance.MuteManager.IsPlayerMuted(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString()); if (activeMutes.Count > 0) { @@ -180,24 +169,27 @@ await Server.NextFrameAsync(() => } } - await Server.NextFrameAsync(() => + if (CS2_SimpleAdmin.Instance.Config.OtherSettings.NotifyPenaltiesToAdminOnConnect) { - foreach (var admin in Helper.GetValidPlayers() - .Where(p => (AdminManager.PlayerHasPermissions(p, "@css/kick") || - AdminManager.PlayerHasPermissions(p, "@css/ban")) && - p.Connected == PlayerConnectedState.PlayerConnected && !CS2_SimpleAdmin.AdminDisabledJoinComms.Contains(p.SteamID))) + await Server.NextFrameAsync(() => { - if (CS2_SimpleAdmin._localizer != null && admin != player) - admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_penalty_info", - player.PlayerName, - CS2_SimpleAdmin.PlayersInfo[userId].TotalBans, - CS2_SimpleAdmin.PlayersInfo[userId].TotalGags, - CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes, - CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences, - CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns - ); - } - }); + foreach (var admin in Helper.GetValidPlayers() + .Where(p => (AdminManager.PlayerHasPermissions(p, "@css/kick") || + AdminManager.PlayerHasPermissions(p, "@css/ban")) && + p.Connected == PlayerConnectedState.PlayerConnected && !CS2_SimpleAdmin.AdminDisabledJoinComms.Contains(p.SteamID))) + { + if (CS2_SimpleAdmin._localizer != null && admin != player) + admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_penalty_info", + player.PlayerName, + CS2_SimpleAdmin.PlayersInfo[userId].TotalBans, + CS2_SimpleAdmin.PlayersInfo[userId].TotalGags, + CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes, + CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences, + CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns + ); + } + }); + } } catch (Exception ex) { @@ -229,15 +221,10 @@ public void CheckPlayersTimer() Task.Run(async () => { - PermissionManager adminManager = new(CS2_SimpleAdmin.Database); - BanManager banManager = new(CS2_SimpleAdmin.Database, _config); - MuteManager muteManager = new(CS2_SimpleAdmin.Database); - WarnManager warnManager = new(CS2_SimpleAdmin.Database); - - await muteManager.ExpireOldMutes(); - await banManager.ExpireOldBans(); - await warnManager.ExpireOldWarns(); - await adminManager.DeleteOldAdmins(); + await CS2_SimpleAdmin.Instance.MuteManager.ExpireOldMutes(); + await CS2_SimpleAdmin.Instance.BanManager.ExpireOldBans(); + await CS2_SimpleAdmin.Instance.WarnManager.ExpireOldWarns(); + await CS2_SimpleAdmin.Instance.PermissionManager.DeleteOldAdmins(); CS2_SimpleAdmin.BannedPlayers.Clear(); @@ -245,11 +232,11 @@ public void CheckPlayersTimer() { try { - await banManager.CheckOnlinePlayers(onlinePlayers); + await CS2_SimpleAdmin.Instance.BanManager.CheckOnlinePlayers(onlinePlayers); if (_config.OtherSettings.TimeMode == 0) { - await muteManager.CheckOnlineModeMutes(onlinePlayers); + await CS2_SimpleAdmin.Instance.MuteManager.CheckOnlineModeMutes(onlinePlayers); } } catch (Exception) diff --git a/CS2-SimpleAdmin/Managers/ServerManager.cs b/CS2-SimpleAdmin/Managers/ServerManager.cs index 4b570c7..3e59976 100644 --- a/CS2-SimpleAdmin/Managers/ServerManager.cs +++ b/CS2-SimpleAdmin/Managers/ServerManager.cs @@ -79,7 +79,7 @@ await connection.ExecuteAsync( if (CS2_SimpleAdmin.Instance.Config.EnableMetrics) { var queryString = $"?address={address}&hostname={hostname}"; - using HttpClient client = new(); + var client = CS2_SimpleAdmin.HttpClient; try { diff --git a/CS2-SimpleAdmin/Managers/WarnManager.cs b/CS2-SimpleAdmin/Managers/WarnManager.cs index fc7f281..82b9e2d 100644 --- a/CS2-SimpleAdmin/Managers/WarnManager.cs +++ b/CS2-SimpleAdmin/Managers/WarnManager.cs @@ -4,10 +4,12 @@ namespace CS2_SimpleAdmin.Managers; -internal class WarnManager(Database.Database database) +internal class WarnManager(Database.Database? database) { public async Task WarnPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0) { + if (database == null) return; + var now = Time.ActualDateTime(); var futureTime = now.AddMinutes(time); @@ -36,9 +38,9 @@ public async Task WarnPlayer(PlayerInfo player, PlayerInfo? issuer, string reaso public async Task AddWarnBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0) { + if (database == null) return; if (string.IsNullOrEmpty(playerSteamId)) return; - var now = Time.ActualDateTime(); var futureTime = now.AddMinutes(time); @@ -65,6 +67,8 @@ public async Task AddWarnBySteamid(string playerSteamId, PlayerInfo? issuer, str public async Task> GetPlayerWarns(PlayerInfo player, bool active = true) { + if (database == null) return []; + try { await using var connection = await database.GetConnectionAsync(); @@ -97,6 +101,8 @@ public async Task> GetPlayerWarns(PlayerInfo player, bool active = public async Task GetPlayerWarnsCount(string steamId, bool active = true) { + if (database == null) return 0; + try { await using var connection = await database.GetConnectionAsync(); @@ -120,6 +126,8 @@ public async Task GetPlayerWarnsCount(string steamId, bool active = true) public async Task UnwarnPlayer(PlayerInfo player, int warnId) { + if (database == null) return; + try { await using var connection = await database.GetConnectionAsync(); @@ -138,6 +146,8 @@ public async Task UnwarnPlayer(PlayerInfo player, int warnId) public async Task UnwarnPlayer(string playerPattern) { + if (database == null) return; + try { await using var connection = await database.GetConnectionAsync(); @@ -156,6 +166,8 @@ public async Task UnwarnPlayer(string playerPattern) public async Task ExpireOldWarns() { + if (database == null) return; + try { await using var connection = await database.GetConnectionAsync(); diff --git a/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs b/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs index 7cb19a2..594ebce 100644 --- a/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs +++ b/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs @@ -151,7 +151,7 @@ private static void Kick(CCSPlayerController admin, CCSPlayerController player, CS2_SimpleAdmin.Instance.Kick(admin, player, reason); } - private static void BanMenu(CCSPlayerController admin, CCSPlayerController player, int duration) + internal static void BanMenu(CCSPlayerController admin, CCSPlayerController player, int duration) { ReasonMenu.OpenMenu(admin, PenaltyType.Ban, $"{CS2_SimpleAdmin._localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player, (_, _, reason) => @@ -211,7 +211,7 @@ private static void Warn(CCSPlayerController admin, CCSPlayerController player, CS2_SimpleAdmin.Instance.Warn(admin, player, duration, reason); } - private static void GagMenu(CCSPlayerController admin, CCSPlayerController player, int duration) + internal static void GagMenu(CCSPlayerController admin, CCSPlayerController player, int duration) { ReasonMenu.OpenMenu(admin, PenaltyType.Gag, $"{CS2_SimpleAdmin._localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player, (_, _, reason) => @@ -241,7 +241,7 @@ private static void Gag(CCSPlayerController admin, CCSPlayerController player, i CS2_SimpleAdmin.Instance.Gag(admin, player, duration, reason); } - private static void MuteMenu(CCSPlayerController admin, CCSPlayerController player, int duration) + internal static void MuteMenu(CCSPlayerController admin, CCSPlayerController player, int duration) { ReasonMenu.OpenMenu(admin, PenaltyType.Mute, $"{CS2_SimpleAdmin._localizer?["sa_mute"] ?? "mute"}: {player.PlayerName}", player, (_, _, reason) => @@ -272,7 +272,7 @@ private static void Mute(CCSPlayerController admin, CCSPlayerController player, CS2_SimpleAdmin.Instance.Mute(admin, player, duration, reason); } - private static void SilenceMenu(CCSPlayerController admin, CCSPlayerController player, int duration) + internal static void SilenceMenu(CCSPlayerController admin, CCSPlayerController player, int duration) { ReasonMenu.OpenMenu(admin, PenaltyType.Silence, $"{CS2_SimpleAdmin._localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player, (_, _, reason) => diff --git a/CS2-SimpleAdmin/Menus/ReasonMenu.cs b/CS2-SimpleAdmin/Menus/ReasonMenu.cs index 883cad6..026edf1 100644 --- a/CS2-SimpleAdmin/Menus/ReasonMenu.cs +++ b/CS2-SimpleAdmin/Menus/ReasonMenu.cs @@ -16,6 +16,8 @@ public static void OpenMenu(CCSPlayerController admin, PenaltyType penaltyType, PenaltyType.Kick => CS2_SimpleAdmin.Instance.Config.MenuConfigs.KickReasons, PenaltyType.Mute => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons, PenaltyType.Warn => CS2_SimpleAdmin.Instance.Config.MenuConfigs.WarnReasons, + PenaltyType.Gag => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons, + PenaltyType.Silence => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons, _ => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons }; diff --git a/CS2-SimpleAdmin/VERSION b/CS2-SimpleAdmin/VERSION index e91cefb..a142da5 100644 --- a/CS2-SimpleAdmin/VERSION +++ b/CS2-SimpleAdmin/VERSION @@ -1 +1 @@ -1.6.1b \ No newline at end of file +1.6.2a \ No newline at end of file diff --git a/CS2-SimpleAdmin/Variables.cs b/CS2-SimpleAdmin/Variables.cs index 76da91b..db1d6d9 100644 --- a/CS2-SimpleAdmin/Variables.cs +++ b/CS2-SimpleAdmin/Variables.cs @@ -3,18 +3,24 @@ using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CS2_SimpleAdmin.Models; using CS2_SimpleAdminApi; -using Discord.Webhook; using MenuManager; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using System.Collections.Concurrent; +using CS2_SimpleAdmin.Managers; namespace CS2_SimpleAdmin; public partial class CS2_SimpleAdmin { + // Config + public CS2_SimpleAdminConfig Config { get; set; } = new(); + + // HttpClient + internal static readonly HttpClient HttpClient = new(); + // Paths - internal static string ConfigDirectory = Path.Combine(Application.RootDirectory, "configs/plugins/CS2-SimpleAdmin"); + internal static readonly string ConfigDirectory = Path.Combine(Application.RootDirectory, "configs/plugins/CS2-SimpleAdmin"); // Localization public static IStringLocalizer? _localizer; @@ -39,7 +45,7 @@ public partial class CS2_SimpleAdmin private static readonly List DisconnectedPlayers = []; // Discord Integration - internal static DiscordWebhookClient? DiscordWebhookClientLog; + internal static DiscordManager? DiscordWebhookClientLog; // Database Settings internal string DbConnectionString = string.Empty; @@ -57,4 +63,10 @@ public partial class CS2_SimpleAdmin // Shared API private Api.CS2_SimpleAdminApi? SimpleAdminApi { get; set; } + + // Managers + internal PermissionManager PermissionManager = new(Database); + internal BanManager BanManager = new(Database); + internal MuteManager MuteManager = new(Database); + internal WarnManager WarnManager = new(Database); } \ No newline at end of file