diff --git a/Commands/basebans.cs b/Commands/basebans.cs index 5b236fb..c6dba6c 100644 --- a/Commands/basebans.cs +++ b/Commands/basebans.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; diff --git a/Commands/basecommands.cs b/Commands/basecommands.cs index 89adf98..18a5c2c 100644 --- a/Commands/basecommands.cs +++ b/Commands/basecommands.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; diff --git a/Commands/basecomms.cs b/Commands/basecomms.cs index 173b1db..d66a69b 100644 --- a/Commands/basecomms.cs +++ b/Commands/basecomms.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; diff --git a/Commands/funcommands.cs b/Commands/funcommands.cs index 26ec5e6..f2b7f53 100644 --- a/Commands/funcommands.cs +++ b/Commands/funcommands.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; diff --git a/Commands/playercommands.cs b/Commands/playercommands.cs index 0a30fce..190f3e5 100644 --- a/Commands/playercommands.cs +++ b/Commands/playercommands.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; diff --git a/Config.cs b/Config.cs index 20fa8db..595e8cf 100644 --- a/Config.cs +++ b/Config.cs @@ -22,6 +22,9 @@ namespace CS2_SimpleAdmin [JsonPropertyName("Command")] public string Command { get; set; } = ""; + + [JsonPropertyName("ExecuteOnClient")] + public bool ExecuteOnClient { get; set; } = false; } public class CS2_SimpleAdminConfig : BasePluginConfig diff --git a/Helper.cs b/Helper.cs index 522ca5b..b6200b3 100644 --- a/Helper.cs +++ b/Helper.cs @@ -307,6 +307,19 @@ namespace CS2_SimpleAdmin var updatedJsonContent = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping }); File.WriteAllText(CfgPath, updatedJsonContent); } + + public static void TryLogCommandOnDiscord(CCSPlayerController? caller, string commandString) + { + if (CS2_SimpleAdmin._discordWebhookClientLog == null || CS2_SimpleAdmin._localizer == null) + return; + + if (caller != null && caller.IsValid == false) + caller = null; + + string callerName = caller == null ? "Console" : caller.PlayerName; + string communityUrl = caller != null ? "<" + new SteamID(caller.SteamID).ToCommunityUrl().ToString() + ">" : ""; + CS2_SimpleAdmin._discordWebhookClientLog.SendMessageAsync(GenerateMessageDiscord(CS2_SimpleAdmin._localizer["sa_discord_log_command", $"[{callerName}]({communityUrl})", commandString])); + } } public class SchemaString : NativeObject where SchemaClass : NativeObject diff --git a/Menus/AdminMenu.cs b/Menus/AdminMenu.cs index a43495f..c3754cb 100644 --- a/Menus/AdminMenu.cs +++ b/Menus/AdminMenu.cs @@ -44,6 +44,12 @@ namespace CS2_SimpleAdmin.Menus new ChatMenuOptionData("Manage Server", () => ManageServerMenu.OpenMenu(admin)), new ChatMenuOptionData("Fun actions", () => FunActionsMenu.OpenMenu(admin)), }; + + List customCommands = CS2_SimpleAdmin.Instance.Config.CustomServerCommands; + if (customCommands.Count > 0) + { + options.Add(new ChatMenuOptionData("Custom Commands", () => CustomCommandsMenu.OpenMenu(admin))); + } if (AdminManager.PlayerHasPermissions(admin, "@css/root")) options.Add(new ChatMenuOptionData("Manage Admins", () => ManageAdminsMenu.OpenMenu(admin))); diff --git a/Menus/CustomCommandsMenu.cs b/Menus/CustomCommandsMenu.cs new file mode 100644 index 0000000..dd1d9d1 --- /dev/null +++ b/Menus/CustomCommandsMenu.cs @@ -0,0 +1,55 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Admin; +using CounterStrikeSharp.API.Modules.Menu; + +namespace CS2_SimpleAdmin.Menus +{ + public static class CustomCommandsMenu + { + public static void OpenMenu(CCSPlayerController admin) + { + if (admin == null || admin.IsValid == false) + return; + + if (AdminManager.PlayerHasPermissions(admin, "@css/generic") == false) + { + // TODO: Localize + admin.PrintToChat("[Simple Admin] You do not have permissions to use this command."); + return; + } + + BaseMenu menu = AdminMenu.CreateMenu("Custom Commands"); + List options = new(); + + List customCommands = CS2_SimpleAdmin.Instance.Config.CustomServerCommands; + foreach (CustomServerCommandData customCommand in customCommands) + { + if (string.IsNullOrEmpty(customCommand.DisplayName) || string.IsNullOrEmpty(customCommand.Command)) + continue; + + bool hasRights = AdminManager.PlayerHasPermissions(admin, customCommand.Flag); + if (!hasRights) + continue; + + options.Add(new ChatMenuOptionData(customCommand.DisplayName, () => + { + Helper.TryLogCommandOnDiscord(admin, customCommand.Command); + + if (customCommand.ExecuteOnClient) + admin.ExecuteClientCommand(customCommand.Command); + else + Server.ExecuteCommand(customCommand.Command); + })); + } + + foreach (ChatMenuOptionData menuOptionData in options) + { + string menuName = menuOptionData.name; + menu.AddMenuOption(menuName, (_, _) => { menuOptionData.action?.Invoke(); }, menuOptionData.disabled); + } + + AdminMenu.OpenMenu(admin, menu); + } + } +} diff --git a/Menus/FunActionsMenu.cs b/Menus/FunActionsMenu.cs index 3e4b60b..59b8909 100644 --- a/Menus/FunActionsMenu.cs +++ b/Menus/FunActionsMenu.cs @@ -21,7 +21,8 @@ namespace CS2_SimpleAdmin.Menus _weaponsCache = new(); foreach (CsItem item in weaponsArray) { - if (item == CsItem.Tablet) continue; + if (item == CsItem.Tablet) + continue; _weaponsCache[(int)item] = item; } @@ -57,7 +58,7 @@ namespace CS2_SimpleAdmin.Menus { options.Add(new ChatMenuOptionData("God Mode", () => PlayersMenu.OpenAliveMenu(admin, "God Mode", GodMode))); options.Add(new ChatMenuOptionData("No Clip", () => PlayersMenu.OpenAliveMenu(admin, "No Clip", NoClip))); - options.Add(new ChatMenuOptionData("Respawn", () => PlayersMenu.OpenAliveMenu(admin, "Respawn", Respawn))); + options.Add(new ChatMenuOptionData("Respawn", () => PlayersMenu.OpenDeadMenu(admin, "Respawn", Respawn))); options.Add(new ChatMenuOptionData("Give Weapon", () => PlayersMenu.OpenAliveMenu(admin, "Give Weapon", GiveWeaponMenu))); } @@ -67,6 +68,8 @@ namespace CS2_SimpleAdmin.Menus options.Add(new ChatMenuOptionData("Freeze", () => PlayersMenu.OpenAliveMenu(admin, "Freeze", Freeze))); options.Add(new ChatMenuOptionData("HP", () => PlayersMenu.OpenAliveMenu(admin, "HP", SetHpMenu))); options.Add(new ChatMenuOptionData("Speed", () => PlayersMenu.OpenAliveMenu(admin, "Speed", SetSpeedMenu))); + options.Add(new ChatMenuOptionData("Gravity", () => PlayersMenu.OpenAliveMenu(admin, "Gravity", SetGravityMenu))); + options.Add(new ChatMenuOptionData("Set Money", () => PlayersMenu.OpenMenu(admin, "Set Money", SetMoneyMenu))); } foreach (ChatMenuOptionData menuOptionData in options) @@ -117,7 +120,8 @@ namespace CS2_SimpleAdmin.Menus private static void Freeze(CCSPlayerController admin, CCSPlayerController player) { - if (!(player.PlayerPawn?.Value?.IsValid ?? false)) return; + if (!(player.PlayerPawn?.Value?.IsValid ?? false)) + return; if (player.PlayerPawn.Value.MoveType != MoveType_t.MOVETYPE_OBSOLETE) CS2_SimpleAdmin.Instance.Freeze(admin, player, -1); @@ -184,5 +188,61 @@ namespace CS2_SimpleAdmin.Menus { CS2_SimpleAdmin.Instance.SetSpeed(admin, player, speed); } + + private static void SetGravityMenu(CCSPlayerController admin, CCSPlayerController player) + { + Tuple[] _gravityArray = new[] + { + new Tuple("0.1", .1f), + new Tuple("0.25", .25f), + new Tuple("0.5", .5f), + new Tuple("0.75", .75f), + new Tuple("1", 1), + new Tuple("2", 2) + }; + + BaseMenu menu = AdminMenu.CreateMenu($"Set Gravity: {player.PlayerName}"); + + foreach (Tuple gravityTuple in _gravityArray) + { + string optionName = gravityTuple.Item1; + menu.AddMenuOption(optionName, (_, _) => { SetGravity(admin, player, gravityTuple.Item2); }); + } + + AdminMenu.OpenMenu(admin, menu); + } + + private static void SetGravity(CCSPlayerController admin, CCSPlayerController player, float gravity) + { + CS2_SimpleAdmin.Instance.SetGravity(admin, player, gravity); + } + + private static void SetMoneyMenu(CCSPlayerController admin, CCSPlayerController player) + { + Tuple[] _moneyArray = new[] + { + new Tuple("$0", 0), + new Tuple("$1000", 1000), + new Tuple("$2500", 2500), + new Tuple("$5000", 5000), + new Tuple("$10000", 10000), + new Tuple("$16000", 16000) + }; + + BaseMenu menu = AdminMenu.CreateMenu($"Set Money: {player.PlayerName}"); + + foreach (Tuple moneyTuple in _moneyArray) + { + string optionName = moneyTuple.Item1; + menu.AddMenuOption(optionName, (_, _) => { SetMoney(admin, player, moneyTuple.Item2); }); + } + + AdminMenu.OpenMenu(admin, menu); + } + + private static void SetMoney(CCSPlayerController admin, CCSPlayerController player, int money) + { + CS2_SimpleAdmin.Instance.SetMoney(admin, player, money); + } } -} \ No newline at end of file +} diff --git a/Menus/ManageAdminsMenu.cs b/Menus/ManageAdminsMenu.cs index 7f7b6fa..ac4127f 100644 --- a/Menus/ManageAdminsMenu.cs +++ b/Menus/ManageAdminsMenu.cs @@ -24,9 +24,9 @@ namespace CS2_SimpleAdmin.Menus // TODO: Localize options // options added in order - options.Add(new ChatMenuOptionData("Add Admin", () => PlayersMenu.OpenAliveMenu(admin, "Add Admin", AddAdminMenu))); - options.Add(new ChatMenuOptionData("Remove Admin", () => PlayersMenu.OpenAliveMenu(admin, "Remove Admin", RemoveAdmin, player => player != admin && admin.CanTarget(player)))); - options.Add(new ChatMenuOptionData("Reload Admins", ReloadAdmins)); + options.Add(new ChatMenuOptionData("Add Admin", () => PlayersMenu.OpenRealPlayersMenu(admin, "Add Admin", AddAdminMenu))); + options.Add(new ChatMenuOptionData("Remove Admin", () => PlayersMenu.OpenAdminPlayersMenu(admin, "Remove Admin", RemoveAdmin, player => player != admin && admin.CanTarget(player)))); + options.Add(new ChatMenuOptionData("Reload Admins", () => ReloadAdmins(admin))); foreach (ChatMenuOptionData menuOptionData in options) { diff --git a/Menus/ManagePlayersMenu.cs b/Menus/ManagePlayersMenu.cs index 33a44fc..399080f 100644 --- a/Menus/ManagePlayersMenu.cs +++ b/Menus/ManagePlayersMenu.cs @@ -44,14 +44,14 @@ namespace CS2_SimpleAdmin.Menus if (hasBan) { - options.Add(new ChatMenuOptionData("Ban", () => PlayersMenu.OpenMenu(admin, "Ban", (admin, player) => DurationMenu.OpenMenu(admin, $"Ban: {player.PlayerName}", player, BanMenu)))); + options.Add(new ChatMenuOptionData("Ban", () => PlayersMenu.OpenRealPlayersMenu(admin, "Ban", (admin, player) => DurationMenu.OpenMenu(admin, $"Ban: {player.PlayerName}", player, BanMenu)))); } if (hasChat) { - options.Add(new ChatMenuOptionData("Gag", () => PlayersMenu.OpenMenu(admin, "Gag", (admin, player) => DurationMenu.OpenMenu(admin, $"Gag: {player.PlayerName}", player, GagMenu)))); - options.Add(new ChatMenuOptionData("Mute", () => PlayersMenu.OpenMenu(admin, "Mute", (admin, player) => DurationMenu.OpenMenu(admin, $"Mute: {player.PlayerName}", player, MuteMenu)))); - options.Add(new ChatMenuOptionData("Silence", () => PlayersMenu.OpenMenu(admin, "Silence", (admin, player) => DurationMenu.OpenMenu(admin, $"Silence: {player.PlayerName}", player, SilenceMenu)))); + options.Add(new ChatMenuOptionData("Gag", () => PlayersMenu.OpenRealPlayersMenu(admin, "Gag", (admin, player) => DurationMenu.OpenMenu(admin, $"Gag: {player.PlayerName}", player, GagMenu)))); + options.Add(new ChatMenuOptionData("Mute", () => PlayersMenu.OpenRealPlayersMenu(admin, "Mute", (admin, player) => DurationMenu.OpenMenu(admin, $"Mute: {player.PlayerName}", player, MuteMenu)))); + options.Add(new ChatMenuOptionData("Silence", () => PlayersMenu.OpenRealPlayersMenu(admin, "Silence", (admin, player) => DurationMenu.OpenMenu(admin, $"Silence: {player.PlayerName}", player, SilenceMenu)))); } if (hasKick) diff --git a/Menus/ManageServerMenu.cs b/Menus/ManageServerMenu.cs index 8b19ebb..ea75e80 100644 --- a/Menus/ManageServerMenu.cs +++ b/Menus/ManageServerMenu.cs @@ -1,4 +1,3 @@ -using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Menu; @@ -35,19 +34,6 @@ namespace CS2_SimpleAdmin.Menus options.Add(new ChatMenuOptionData("Restart Game", () => CS2_SimpleAdmin.RestartGame(admin))); - List customCommands = CS2_SimpleAdmin.Instance.Config.CustomServerCommands; - foreach (CustomServerCommandData customCommand in customCommands) - { - if (string.IsNullOrEmpty(customCommand.DisplayName) || string.IsNullOrEmpty(customCommand.Command)) - continue; - - bool hasRights = AdminManager.PlayerHasPermissions(admin, customCommand.Flag); - if (!hasRights) - continue; - - options.Add(new ChatMenuOptionData(customCommand.DisplayName, () => Server.ExecuteCommand(customCommand.Command))); - } - foreach (ChatMenuOptionData menuOptionData in options) { string menuName = menuOptionData.name; diff --git a/Menus/PlayersMenu.cs b/Menus/PlayersMenu.cs index 3e3d631..7d0525f 100644 --- a/Menus/PlayersMenu.cs +++ b/Menus/PlayersMenu.cs @@ -1,15 +1,32 @@ +using System.Web; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Menu; namespace CS2_SimpleAdmin.Menus { public static class PlayersMenu { + public static void OpenRealPlayersMenu(CCSPlayerController admin, string menuName, Action onSelectAction, Func? enableFilter = null) + { + OpenMenu(admin, menuName, onSelectAction, p => p.IsBot == false); + } + + public static void OpenAdminPlayersMenu(CCSPlayerController admin, string menuName, Action onSelectAction, Func? enableFilter = null) + { + OpenMenu(admin, menuName, onSelectAction, p => AdminManager.GetPlayerAdminData(p)?.Flags?.Count > 0); + } + public static void OpenAliveMenu(CCSPlayerController admin, string menuName, Action onSelectAction, Func? enableFilter = null) { OpenMenu(admin, menuName, onSelectAction, p => p.PawnIsAlive); } + public static void OpenDeadMenu(CCSPlayerController admin, string menuName, Action onSelectAction, Func? enableFilter = null) + { + OpenMenu(admin, menuName, onSelectAction, p => p.PawnIsAlive == false); + } + public static void OpenMenu(CCSPlayerController admin, string menuName, Action onSelectAction, Func? enableFilter = null) { BaseMenu menu = AdminMenu.CreateMenu(menuName); @@ -17,14 +34,15 @@ namespace CS2_SimpleAdmin.Menus IEnumerable players = Helper.GetValidPlayersWithBots(); foreach (CCSPlayerController player in players) { - string optionName = player.PlayerName; + string optionName = HttpUtility.HtmlEncode(player.PlayerName); + if (enableFilter != null && enableFilter(player) == false) + continue; + bool enabled = admin.CanTarget(player); - if (enableFilter != null) - enabled &= enableFilter(player); menu.AddMenuOption(optionName, (_, _) => { onSelectAction?.Invoke(admin, player); }, enabled == false); } AdminMenu.OpenMenu(admin, menu); } } -} \ No newline at end of file +} diff --git a/lang/en.json b/lang/en.json index 88cf250..a2d39ce 100644 --- a/lang/en.json +++ b/lang/en.json @@ -44,8 +44,8 @@ "sa_admin_slap_message": "Admin {lightred}{0}{default} slapped {lightred}{1}{default}!", "sa_admin_changemap_message": "Admin {lightred}{0}{default} changed map to {lightred}{1}{default}!", "sa_admin_noclip_message": "Admin {lightred}{0}{default} toggled noclip for {lightred}{1}{default}!", - "sa_admin_freeze_message": "Admin {lightred}{0}{default} freezed {lightred}{1}{default}!", - "sa_admin_unfreeze_message": "Admin {lightred}{0}{default} umfreezed {lightred}{1}{default}!", + "sa_admin_freeze_message": "Admin {lightred}{0}{default} froze {lightred}{1}{default}!", + "sa_admin_unfreeze_message": "Admin {lightred}{0}{default} unfroze {lightred}{1}{default}!", "sa_admin_rename_message": "Admin {lightred}{0}{default} changed {lightred}{1}{default} nickname to {lightred}{2}{default}!", "sa_admin_respawn_message": "Admin {lightred}{0}{default} respawned {lightred}{1}{default}!", "sa_admin_tp_message": "Admin {lightred}{0}{default} teleported to {lightred}{1}{default}!",