diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e33ae98..7599a7a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,16 +77,22 @@ jobs: mkdir -p ${{ env.OUTPUT_PATH }}/shared cp -r ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }} ${{ env.OUTPUT_PATH }}/plugins/ cp -r ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }} ${{ env.OUTPUT_PATH }}/shared/ + mkdir -p ${{ env.OUTPUT_PATH }}/shared/KitsuneMenu + cp ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/KitsuneMenu.dll ${{ env.OUTPUT_PATH }}/shared/KitsuneMenu/ - name: Zip combined uses: thedoctor0/zip-release@0.7.6 with: type: 'zip' filename: '${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}-${{ env.BUILD_NUMBER }}.zip' path: ${{ env.OUTPUT_PATH }} + - name: Zip statusblocker + run: | + cd CS2-SimpleAdmin/3rd_party/statusblocker + zip -r ../../../statusblocker.zip * - name: Publish combined release uses: ncipollo/release-action@v1.14.0 with: - artifacts: "${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}-${{ env.BUILD_NUMBER }}.zip" + artifacts: "${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}-${{ env.BUILD_NUMBER }}.zip,statusblocker.zip" name: "CS2-SimpleAdmin - Build ${{ env.BUILD_NUMBER }}" tag: "fork-build-${{ env.BUILD_NUMBER }}-${{ github.run_id }}" body: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 57a42c2..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: Build - -on: - push: - branches: [ "main" ] - paths-ignore: - - '**/README.md' - pull_request: - branches: [ "main" ] - paths-ignore: - - '**/README.md' - -env: - BUILD_NUMBER: ${{ github.run_number }} - PROJECT_PATH_CS2_SIMPLEADMIN: "CS2-SimpleAdmin/CS2-SimpleAdmin.csproj" - PROJECT_PATH_CS2_SIMPLEADMINAPI: "CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj" - PROJECT_NAME_CS2_SIMPLEADMIN: "CS2-SimpleAdmin" - PROJECT_NAME_CS2_SIMPLEADMINAPI: "CS2-SimpleAdminApi" - OUTPUT_PATH: "./counterstrikesharp" - TMP_PATH: "./tmp" - -jobs: - build: - permissions: write-all - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - name: Restore CS2-SimpleAdmin - run: dotnet restore ${{ env.PROJECT_PATH_CS2_SIMPLEADMIN }} - - name: Build CS2-SimpleAdmin - run: dotnet build ${{ env.PROJECT_PATH_CS2_SIMPLEADMIN }} -c Release -o ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }} - - name: Restore CS2-SimpleAdminApi - run: dotnet restore ${{ env.PROJECT_PATH_CS2_SIMPLEADMINAPI }} - - name: Build CS2-SimpleAdminApi - run: dotnet build ${{ env.PROJECT_PATH_CS2_SIMPLEADMINAPI }} -c Release -o ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }} - - publish: - if: github.event_name == 'push' - permissions: write-all - runs-on: ubuntu-latest - needs: build - steps: - - uses: actions/checkout@v4 - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - name: Restore CS2-SimpleAdmin - run: dotnet restore ${{ env.PROJECT_PATH_CS2_SIMPLEADMIN }} - - name: Build CS2-SimpleAdmin - run: dotnet build ${{ env.PROJECT_PATH_CS2_SIMPLEADMIN }} -c Release -o ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }} - - name: Restore CS2-SimpleAdminApi - run: dotnet restore ${{ env.PROJECT_PATH_CS2_SIMPLEADMINAPI }} - - name: Build CS2-SimpleAdminApi - run: dotnet build ${{ env.PROJECT_PATH_CS2_SIMPLEADMINAPI }} -c Release -o ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }} - - name: Clean files - run: | - rm -f \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/CounterStrikeSharp.API.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/McMaster.NETCore.Plugins.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/Microsoft.DotNet.PlatformAbstractions.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/Microsoft.Extensions.DependencyModel.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/CS2-SimpleAdminApi.* \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}/Microsoft.* \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }}/CounterStrikeSharp.API.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }}/McMaster.NETCore.Plugins.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }}/Microsoft.DotNet.PlatformAbstractions.dll \ - ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }}/Microsoft.Extensions.DependencyModel.dll - - name: Combine projects - run: | - mkdir -p ${{ env.OUTPUT_PATH }}/plugins - mkdir -p ${{ env.OUTPUT_PATH }}/shared - cp -r ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }} ${{ env.OUTPUT_PATH }}/plugins/ - cp -r ${{ env.TMP_PATH }}/${{ env.PROJECT_NAME_CS2_SIMPLEADMINAPI }} ${{ env.OUTPUT_PATH }}/shared/ - - name: Zip combined - uses: thedoctor0/zip-release@0.7.6 - with: - type: 'zip' - filename: '${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}-${{ env.BUILD_NUMBER }}.zip' - path: ${{ env.OUTPUT_PATH }} - - name: Publish combined release - uses: ncipollo/release-action@v1.14.0 - with: - artifacts: "${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}-${{ env.BUILD_NUMBER }}.zip" - name: "CS2-SimpleAdmin - Build ${{ env.BUILD_NUMBER }}" - tag: "build-${{ env.BUILD_NUMBER }}" - body: | - Place files in addons/counterstrikesharp - After first launch, configure the plugins in the respective configs: - - CS2-SimpleAdmin: addons/counterstrikesharp/configs/plugins/CS2-SimpleAdmin/CS2-SimpleAdmin.json diff --git a/CS2-SimpleAdmin.example.json b/CS2-SimpleAdmin.example.json index ca2decc..126a661 100644 --- a/CS2-SimpleAdmin.example.json +++ b/CS2-SimpleAdmin.example.json @@ -22,7 +22,8 @@ "UserMessageGagChatType": false, "CheckMultiAccountsByIp": true, "AdditionalCommandsToLog": [], - "HideStealthPlayersFromSpecList": false + "HideStealthPlayersFromSpecList": false, + "HideAdminsOnJoinPermission": ["@css/unban"] }, "EnableMetrics": true, "EnableUpdateCheck": true, diff --git a/CS2-SimpleAdmin/3rd_party/KitsuneMenu.dll b/CS2-SimpleAdmin/3rd_party/KitsuneMenu.dll new file mode 100644 index 0000000..c9eb665 Binary files /dev/null and b/CS2-SimpleAdmin/3rd_party/KitsuneMenu.dll differ diff --git a/CS2-SimpleAdmin/3rd_party/MenuManagerApi.dll b/CS2-SimpleAdmin/3rd_party/MenuManagerApi.dll deleted file mode 100644 index 3a47c6a..0000000 Binary files a/CS2-SimpleAdmin/3rd_party/MenuManagerApi.dll and /dev/null differ diff --git a/CS2-SimpleAdmin/3rd_party/statusblocker/StatusBlocker-v1.0.3-linux.tar.gz b/CS2-SimpleAdmin/3rd_party/statusblocker/StatusBlocker-v1.0.3-linux.tar.gz new file mode 100644 index 0000000..61f7be3 Binary files /dev/null and b/CS2-SimpleAdmin/3rd_party/statusblocker/StatusBlocker-v1.0.3-linux.tar.gz differ diff --git a/CS2-SimpleAdmin/3rd_party/statusblocker/StatusBlocker-v1.0.3-windows.tar.gz b/CS2-SimpleAdmin/3rd_party/statusblocker/StatusBlocker-v1.0.3-windows.tar.gz new file mode 100644 index 0000000..050a3a9 Binary files /dev/null and b/CS2-SimpleAdmin/3rd_party/statusblocker/StatusBlocker-v1.0.3-windows.tar.gz differ diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs index 1fc5b20..009db6d 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs @@ -3,35 +3,42 @@ using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Core.Capabilities; 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 Microsoft.Extensions.Logging; using MySqlConnector; +using Menu; + namespace CS2_SimpleAdmin; -[MinimumApiVersion(300)] +// TODO: +// Speed fix +// Gravity fix + +[MinimumApiVersion(340)] public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { internal static CS2_SimpleAdmin Instance { get; private set; } = new(); public override string ModuleName => "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.7.7-alpha"; - + public override string ModuleAuthor => "daffyy, Dliix66, ShiNxz & Cruze"; + public override string ModuleVersion => "1.7.8-alpha"; + public override void Load(bool hotReload) { Instance = this; + Menu = new KitsuneMenu(this); + RegisterEvents(); if (hotReload) { ServerLoaded = false; _serverLoading = false; - + CacheManager = new CacheManager(); OnGameServerSteamAPIActivated(); OnMapStart(string.Empty); @@ -39,38 +46,24 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig { if (Database == null) return; - + var playerManager = new PlayerManager(); - foreach (var player in Helper.GetValidPlayers()) + foreach (var player in Helper.GetValidPlayers()) { playerManager.LoadPlayerData(player); - }; + } + ; }); } - _cBasePlayerControllerSetPawnFunc = new MemoryFunctionVoid(GameData.GetSignature("CBasePlayerController_SetPawn")); SimpleAdminApi = new Api.CS2_SimpleAdminApi(); Capabilities.RegisterPluginCapability(ICS2_SimpleAdminApi.PluginCapability, () => SimpleAdminApi); - + new PlayerManager().CheckPlayersTimer(); ChatManager = new ChatManager(); - } - public override void OnAllPluginsLoaded(bool hotReload) - { - AddTimer(5.0f, () => ReloadAdmins(null)); - - try - { - MenuApi = MenuCapability.Get(); - } - catch (Exception ex) - { - Logger.LogError("Unable to load required plugins ... \n{exception}", ex.Message); - } - RegisterCommands.InitializeCommands(); } @@ -78,12 +71,12 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig Database.DatabaseMigration()); - + Config = config; Helper.UpdateConfig(config); @@ -127,7 +120,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig await PluginInfo.CheckVersion(ModuleVersion, _logger)); - + PermissionManager = new PermissionManager(Database); BanManager = new BanManager(Database); MuteManager = new MuteManager(Database); diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj b/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj index 89e6e97..f6092bc 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.csproj @@ -10,7 +10,7 @@ - + @@ -43,8 +43,8 @@ - - 3rd_party\MenuManagerApi.dll + + 3rd_party\KitsuneMenu.dll diff --git a/CS2-SimpleAdmin/Commands/basebans.cs b/CS2-SimpleAdmin/Commands/basebans.cs index 33dc456..35c855a 100644 --- a/CS2-SimpleAdmin/Commands/basebans.cs +++ b/CS2-SimpleAdmin/Commands/basebans.cs @@ -365,6 +365,7 @@ public partial class CS2_SimpleAdmin // Get player and admin information var playerInfo = PlayersInfo[player.UserId.Value]; + var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; // Asynchronously handle warning logic @@ -388,7 +389,7 @@ public partial class CS2_SimpleAdmin if (!string.IsNullOrEmpty(punishCommand)) { - await Server.NextFrameAsync(() => + await Server.NextWorldUpdateAsync(() => { Server.ExecuteCommand(punishCommand.Replace("USERID", playerInfo.UserId.ToString()).Replace("STEAMID64", playerInfo.SteamId?.ToString())); }); @@ -468,7 +469,7 @@ public partial class CS2_SimpleAdmin if (!string.IsNullOrEmpty(punishCommand)) { - await Server.NextFrameAsync(() => + await Server.NextWorldUpdateAsync(() => { Server.ExecuteCommand(punishCommand.Replace("STEAMID64", steamid.SteamId64.ToString())); }); diff --git a/CS2-SimpleAdmin/Commands/basechat.cs b/CS2-SimpleAdmin/Commands/basechat.cs index 58b6c3c..7af393c 100644 --- a/CS2-SimpleAdmin/Commands/basechat.cs +++ b/CS2-SimpleAdmin/Commands/basechat.cs @@ -115,6 +115,6 @@ public partial class CS2_SimpleAdmin VirtualFunctions.ClientPrintAll( HudDestination.Alert, utf8String.ReplaceColorTags(), - 0, 0, 0, 0); + 0, 0, 0, 0, 0); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Commands/basecommands.cs b/CS2-SimpleAdmin/Commands/basecommands.cs index 54a68ba..e6e4d8d 100644 --- a/CS2-SimpleAdmin/Commands/basecommands.cs +++ b/CS2-SimpleAdmin/Commands/basecommands.cs @@ -16,7 +16,9 @@ using Newtonsoft.Json; using System.Globalization; using System.Reflection; using CounterStrikeSharp.API.ValveConstants.Protobuf; -using MenuManager; + +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin; @@ -27,16 +29,16 @@ public partial class CS2_SimpleAdmin { if (caller == null || caller.IsValid == false || !caller.UserId.HasValue || Database == null) return; - + var userId = caller.UserId.Value; - + if (!string.IsNullOrEmpty(command.GetArg(1)) && AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/kick")) { var targets = GetTarget(command); - + if (targets == null) return; - + var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList(); playersToTarget.ForEach(player => { @@ -157,7 +159,7 @@ public partial class CS2_SimpleAdmin player.VoiceFlags = VoiceFlags.Muted; } } - + if (command.GetArg(2).ToLower().Equals("unmuteAll")) { foreach (var player in Helper.GetValidPlayers().Where(p => p != caller)) @@ -169,10 +171,10 @@ public partial class CS2_SimpleAdmin return; } - + caller.VoiceFlags = caller.VoiceFlags == VoiceFlags.All ? VoiceFlags.Normal : VoiceFlags.All; } - + [RequiresPermissions("@css/generic")] [CommandHelper(whoCanExecute: CommandUsage.CLIENT_ONLY)] public void OnAdminCommand(CCSPlayerController? caller, CommandInfo command) @@ -233,7 +235,7 @@ public partial class CS2_SimpleAdmin public static void AddAdmin(CCSPlayerController? caller, string steamid, string name, string flags, int immunity, int time = 0, bool globalAdmin = false, CommandInfo? command = null) { if (Database == null) return; - + var flagsList = flags.Split(',').Select(flag => flag.Trim()).ToList(); _ = Instance.PermissionManager.AddAdminBySteamId(steamid, name, flagsList, immunity, time, globalAdmin); @@ -386,7 +388,7 @@ public partial class CS2_SimpleAdmin command.ReplyToCommand("Reloaded sql admins and groups"); } - + [CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] [RequiresPermissions("@css/root")] public void OnRelBans(CCSPlayerController? caller, CommandInfo command) @@ -400,8 +402,8 @@ public partial class CS2_SimpleAdmin public void ReloadAdmins(CCSPlayerController? caller) { if (Database == null) return; - - if(!Config.IsCSSPanel) + + if (!Config.IsCSSPanel) { Task.Run(async () => { @@ -441,18 +443,20 @@ public partial class CS2_SimpleAdmin SilentPlayers.Remove(caller.Slot); caller.PrintToChat($"You aren't hidden now!"); caller.ChangeTeam(CsTeam.Spectator); + Server.ExecuteCommand($"mm_removeexcludeslot {caller.Slot}"); } else { Server.ExecuteCommand("sv_disable_teamselect_menu 1"); + Server.ExecuteCommand($"mm_excludeslot {caller.Slot}"); if (caller.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE) caller.PlayerPawn.Value?.CommitSuicide(true, false); - AddTimer(1.0f, () => { Server.NextFrame(() => caller.ChangeTeam(CsTeam.Spectator)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - AddTimer(1.4f, () => { Server.NextFrame(() => caller.ChangeTeam(CsTeam.None)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + AddTimer(1.0f, () => { Server.NextWorldUpdateAsync(() => caller.ChangeTeam(CsTeam.Spectator)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + AddTimer(1.4f, () => { Server.NextWorldUpdateAsync(() => caller.ChangeTeam(CsTeam.None)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); caller.PrintToChat($"You are hidden now!"); - AddTimer(2.0f, () => { Server.NextFrame(() => Server.ExecuteCommand("sv_disable_teamselect_menu 0")); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + AddTimer(2.0f, () => { Server.NextWorldUpdateAsync(() => Server.ExecuteCommand("sv_disable_teamselect_menu 0")); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); } } @@ -539,119 +543,100 @@ public partial class CS2_SimpleAdmin { if (_localizer == null || caller == null) return; - var disconnectedMenu = Helper.CreateMenu(_localizer["sa_menu_disconnected_title"]); + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - DisconnectedPlayers.ForEach(player => + foreach (var player in DisconnectedPlayers) { - disconnectedMenu?.AddMenuOption(player.Name, (_, _) => + var menuName = player.Name; + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(menuName)])); + + optionMap[i++] = () => { - var disconnectedMenuAction = Helper.CreateMenu(_localizer["sa_menu_disconnected_action_title"]); - disconnectedMenuAction?.AddMenuOption(_localizer["sa_ban"], (_, _) => + // Build submenu for actions (ban, mute, gag, silence) + List subItems = new(); + var subOptionMap = new Dictionary(); + int j = 0; + + void AddSubMenuOption(string title, string command, string permMsgKey, string timeMsgKey, string adminPermMsgKey, string adminTimeMsgKey) { - DurationMenu.OpenMenu(caller, _localizer["sa_ban"], player, (_, _, duration) => - ReasonMenu.OpenMenu(caller, PenaltyType.Ban, _localizer["sa_reason"], player, (_, _, reason) => - { - caller.ExecuteClientCommandFromServer($"css_addban {player.SteamId.SteamId64} {duration} \"{reason}\""); - - // Determine message keys and arguments based on ban time - var (_, activityMessageKey, _, adminActivityArgs) = duration == 0 - ? ("sa_player_ban_message_perm", "sa_admin_ban_message_perm", - [reason, "CALLER"], - ["CALLER", player.Name, reason]) - : ("sa_player_ban_message_time", "sa_admin_ban_message_time", - new object[] { reason, duration, "CALLER" }, - new object[] { "CALLER", player.Name, reason, duration }); - - // Display admin activity message if necessary - if (!SilentPlayers.Contains(caller.Slot)) + subItems.Add(new MenuItem(MenuItemType.Button, [new MenuValue(title)])); + subOptionMap[j++] = () => + { + DurationMenu.OpenMenu(caller, title, player, (_, _, duration) => + ReasonMenu.OpenMenu(caller, PenaltyType.Ban, _localizer?["sa_reason"] ?? "reason", player, (_, _, reason) => { - Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, false ,adminActivityArgs); - } - - MenuApi?.CloseMenu(caller); - })); - }); - disconnectedMenuAction?.AddMenuOption(_localizer["sa_mute"], (_, _) => + caller.ExecuteClientCommandFromServer($"{command} {player.SteamId.SteamId64} {duration} \"{reason}\""); + + // Message handling + var (_, activityMessageKey, _, adminActivityArgs) = duration == 0 + ? (permMsgKey, adminPermMsgKey, + new object[] { reason, "CALLER" }, + new object[] { "CALLER", player.Name, reason }) + : (timeMsgKey, adminTimeMsgKey, + new object[] { reason, duration, "CALLER" }, + new object[] { "CALLER", player.Name, reason, duration }); + + if (!SilentPlayers.Contains(caller.Slot)) + { + Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, false, adminActivityArgs); + } + })); + }; + } + + // Add each option + AddSubMenuOption(_localizer["sa_ban"], "css_addban", + "sa_player_ban_message_perm", "sa_player_ban_message_time", + "sa_admin_ban_message_perm", "sa_admin_ban_message_time"); + + AddSubMenuOption(_localizer["sa_mute"], "css_addmute", + "sa_player_mute_message_perm", "sa_player_mute_message_time", + "sa_admin_mute_message_perm", "sa_admin_mute_message_time"); + + AddSubMenuOption(_localizer["sa_gag"], "css_addgag", + "sa_player_gag_message_perm", "sa_player_gag_message_time", + "sa_admin_gag_message_perm", "sa_admin_gag_message_time"); + + AddSubMenuOption(_localizer["sa_silence"], "css_addsilence", + "sa_player_silence_message_perm", "sa_player_silence_message_time", + "sa_admin_silence_message_perm", "sa_admin_silence_message_time"); + + // Show submenu + Menu?.ShowScrollableMenu(caller, + _localizer["sa_menu_disconnected_action_title"], + subItems, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && subOptionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + false, freezePlayer: false, disableDeveloper: true); + }; + } + + // Main disconnected menu + if (i > 0) + { + Menu?.ShowScrollableMenu(caller, + _localizer["sa_menu_disconnected_title"], + items, + (buttons, menu, selected) => { - DurationMenu.OpenMenu(caller, _localizer["sa_mute"], player, (_, _, duration) => - ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) => - { - caller.ExecuteClientCommandFromServer($"css_addmute {player.SteamId.SteamId64} {duration} \"{reason}\""); - - // Determine message keys and arguments based on mute time (permanent or timed) - var (_, activityMessageKey, _, adminActivityArgs) = duration == 0 - ? ("sa_player_mute_message_perm", "sa_admin_mute_message_perm", - [reason, "CALLER"], - ["CALLER", player.Name, reason]) - : ("sa_player_mute_message_time", "sa_admin_mute_message_time", - new object[] { reason, duration, "CALLER" }, - new object[] { "CALLER", player.Name, reason, duration }); + if (selected == null) return; - // Display admin activity message to other players - if (!SilentPlayers.Contains(caller.Slot)) - { - Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, false, adminActivityArgs); - } - - MenuApi?.CloseMenu(caller); - })); - }); - disconnectedMenuAction?.AddMenuOption(_localizer["sa_gag"], (_, _) => - { - DurationMenu.OpenMenu(caller, _localizer["sa_gag"], player, (_, _, duration) => - ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) => - { - caller.ExecuteClientCommandFromServer($"css_addgag {player.SteamId.SteamId64} {duration} \"{reason}\""); - - // Determine message keys and arguments based on gag time (permanent or timed) - var (_, activityMessageKey, _, adminActivityArgs) = duration == 0 - ? ("sa_player_gag_message_perm", "sa_admin_gag_message_perm", - [reason, "CALLER"], - ["CALLER", player.Name, reason]) - : ("sa_player_gag_message_time", "sa_admin_gag_message_time", - new object[] { reason, duration, "CALLER" }, - new object[] { "CALLER", player.Name, reason, duration}); - - // Display admin activity message to other players - if (!SilentPlayers.Contains(caller.Slot)) - { - Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, false, adminActivityArgs); - } - - MenuApi?.CloseMenu(caller); - })); - }); - disconnectedMenuAction?.AddMenuOption(_localizer["sa_silence"], (_, _) => - { - DurationMenu.OpenMenu(caller, _localizer["sa_silence"], player, (_, _, duration) => - ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) => - { - caller.ExecuteClientCommandFromServer($"css_addsilence {player.SteamId.SteamId64} {duration} \"{reason}\""); - - // Determine message keys and arguments based on silence time (permanent or timed) - var (_, activityMessageKey, _, adminActivityArgs) = duration == 0 - ? ("sa_player_silence_message_perm", "sa_admin_silence_message_perm", - [reason, "CALLER"], - ["CALLER", player.Name, reason]) - : ("sa_player_silence_message_time", "sa_admin_silence_message_time", - new object[] { reason, duration, "CALLER" }, - new object[] { "CALLER", player.Name, reason, duration }); - - // Display admin activity message to other players - if (!SilentPlayers.Contains(caller.Slot)) - { - Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, false, adminActivityArgs); - } - - MenuApi?.CloseMenu(caller); - })); - }); - - disconnectedMenuAction?.Open(caller); - }); - }); - - disconnectedMenu?.Open(caller); + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + false, freezePlayer: false, disableDeveloper: true); + } } [CommandHelper(minArgs: 1, usage: "<#userid or name>", whoCanExecute: CommandUsage.CLIENT_ONLY)] @@ -676,8 +661,6 @@ public partial class CS2_SimpleAdmin var userId = player.UserId.Value; - IMenu? warnsMenu = Helper.CreateMenu(_localizer["sa_admin_warns_menu_title", player.PlayerName]); - Task.Run(async () => { var warnsList = await WarnManager.GetPlayerWarns(PlayersInfo[userId], false); @@ -686,21 +669,52 @@ public partial class CS2_SimpleAdmin .ThenByDescending(warn => (int)warn.id) .ToList(); - sortedWarns.ForEach(w => + List items = new(); + var optionMap = new Dictionary(); + int i = 0; + + foreach (var w in sortedWarns) { - 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); - player.PrintToChat(_localizer["sa_admin_warns_unwarn", player.PlayerName, (string)w.reason]); - }); - }); + string statusSymbol = (string)w.status == "ACTIVE" + ? $"{ChatColors.LightRed}X{ChatColors.Default}" + : $"{ChatColors.Lime}✔️{ChatColors.Default}"; + + string label = $"[{statusSymbol}] {(string)w.reason}"; + + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(label)])); + + optionMap[i++] = () => + { + _ = WarnManager.UnwarnPlayer(PlayersInfo[userId], (int)w.id); + player.PrintToChat(_localizer["sa_admin_warns_unwarn", player.PlayerName, (string)w.reason]); + }; + } + + if (i == 0) + { + player.PrintToChat(_localizer["sa_admin_warns_no_warns", player.PlayerName]); + return; + } await Server.NextFrameAsync(() => { - warnsMenu?.Open(caller); + Menu?.ShowScrollableMenu( + caller, + _localizer["sa_admin_warns_menu_title", player.PlayerName], + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + false, freezePlayer: false, disableDeveloper: true); }); }); + }); } @@ -727,7 +741,8 @@ public partial class CS2_SimpleAdmin { caller.PrintToConsole( $"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")"); - }; + } + ; caller.PrintToConsole("--------- END PLAYER LIST ---------"); } else @@ -736,7 +751,8 @@ public partial class CS2_SimpleAdmin foreach (var player in playersToTarget) { Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); - }; + } + ; Server.PrintToConsole("--------- END PLAYER LIST ---------"); } } @@ -745,7 +761,7 @@ public partial class CS2_SimpleAdmin var playersJson = JsonConvert.SerializeObject(playersToTarget.Select(player => { var matchStats = player.ActionTrackingServices?.MatchStats; - + return new { player.UserId, @@ -788,8 +804,8 @@ public partial class CS2_SimpleAdmin return; } - var reason = command.ArgCount >= 2 - ? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg)).Trim() + var reason = command.ArgCount >= 2 + ? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg)).Trim() : _localizer?["sa_unknown"] ?? "Unknown"; reason = string.IsNullOrWhiteSpace(reason) ? _localizer?["sa_unknown"] ?? "Unknown" : reason; @@ -804,7 +820,7 @@ public partial class CS2_SimpleAdmin Kick(caller, player, reason, callerName, command); } }); - + Helper.LogCommand(caller, command); } @@ -813,14 +829,14 @@ public partial class CS2_SimpleAdmin if (!player.IsValid) return; if (!caller.CanTarget(player)) return; if (!player.UserId.HasValue) return; - + // Set default caller name if not provided callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console"; reason ??= _localizer?["sa_unknown"] ?? "Unknown"; - + var playerInfo = PlayersInfo[player.UserId.Value]; var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; - + // Determine message keys and arguments for the kick notification var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = ("sa_player_kick_message", "sa_admin_kick_message", @@ -845,7 +861,7 @@ public partial class CS2_SimpleAdmin // Log the command and send Discord notification if (command == null) Helper.LogCommand(caller, $"css_kick {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {reason}"); - + SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Kick, reason, -1, null); } @@ -879,7 +895,7 @@ public partial class CS2_SimpleAdmin { if (!Server.IsMapValid(map)) { - if(wsMaps.ContainsKey(map)) + if (wsMaps.ContainsKey(map)) { map = wsMaps.Where(m => m.Key == map).FirstOrDefault().Key; } @@ -1005,9 +1021,9 @@ public partial class CS2_SimpleAdmin [CommandHelper(whoCanExecute: CommandUsage.CLIENT_ONLY)] public void OnPluginManagerCommand(CCSPlayerController? caller, CommandInfo commandInfo) { - if (MenuApi == null || caller == null) + if (caller == null) return; - + var pluginManager = Helper.GetPluginManager(); if (pluginManager == null) { @@ -1022,8 +1038,10 @@ public partial class CS2_SimpleAdmin return; } - var pluginsMenu = Helper.CreateMenu(Localizer["sa_menu_pluginsmanager_title"]); - + List items = new(); + var optionMap = new Dictionary(); + int i = 0; + foreach (var plugin in plugins) { var pluginType = plugin.GetType(); @@ -1037,19 +1055,21 @@ public partial class CS2_SimpleAdmin // Access nested properties within "Plugin" (like ModuleName, ModuleVersion, etc.) var nestedPlugin = pluginType.GetProperty("Plugin")?.GetValue(plugin); if (nestedPlugin == null) continue; - - var status = state?.ToUpper() != "UNLOADED" ? "ON" : "OFF"; - var allowedMenuTypes = new[] { "chat", "console" }; - if (!allowedMenuTypes.Contains(Config.MenuConfigs.MenuType) && MenuApi.GetMenuType(caller) >= MenuType.CenterMenu) - status = state?.ToUpper() != "UNLOADED" ? "ON" : "OFF"; + var status = state?.ToUpper() != "UNLOADED" ? "ON" : "OFF"; + + status = state?.ToUpper() != "UNLOADED" + ? "ON" + : "OFF"; + var nestedType = nestedPlugin.GetType(); var moduleName = nestedType.GetProperty("ModuleName")?.GetValue(nestedPlugin)?.ToString() ?? "Unknown"; var moduleVersion = nestedType.GetProperty("ModuleVersion")?.GetValue(nestedPlugin)?.ToString(); - // var moduleAuthor = nestedType.GetProperty("ModuleAuthor")?.GetValue(nestedPlugin)?.ToString(); - // var moduleDescription = nestedType.GetProperty("ModuleDescription")?.GetValue(nestedPlugin)?.ToString(); - pluginsMenu?.AddMenuOption($"({status}) [{moduleName} {moduleVersion}]", (_, _) => + string label = $"({status}) [{moduleName} {moduleVersion}]"; + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(label)])); + + optionMap[i++] = () => { if (state?.ToUpper() != "UNLOADED") { @@ -1062,13 +1082,30 @@ public partial class CS2_SimpleAdmin Server.ExecuteCommand($"css_plugins load {path}"); } + // refresh menu after a short delay AddTimer(0.1f, () => OnPluginManagerCommand(caller, commandInfo)); - }); - - // Console.WriteLine($"[#{pluginId}:{state?.ToUpper()}]: \"{moduleName ?? "Unknown"}\" ({moduleVersion ?? "Unknown"}) by {moduleAuthor}"); + }; } - - pluginsMenu?.Open(caller); + + // Only show if there are plugins + if (i > 0) + { + Menu?.ShowScrollableMenu( + caller, + Localizer["sa_menu_pluginsmanager_title"], + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + true, freezePlayer: false, disableDeveloper: true); + } + } public static void RestartGame(CCSPlayerController? admin) diff --git a/CS2-SimpleAdmin/Commands/basevotes.cs b/CS2-SimpleAdmin/Commands/basevotes.cs index 68908d7..657acbf 100644 --- a/CS2-SimpleAdmin/Commands/basevotes.cs +++ b/CS2-SimpleAdmin/Commands/basevotes.cs @@ -3,6 +3,8 @@ using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Menu; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin; @@ -33,28 +35,55 @@ public partial class CS2_SimpleAdmin { using (new WithTemporaryCulture(player.GetLanguage())) { - IMenu? voteMenu = Helper.CreateMenu(_localizer["sa_admin_vote_menu_title", question]); - if (voteMenu == null) - return; - //ChatMenu voteMenu = new(_localizer!["sa_admin_vote_menu_title", question]); + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - for (var i = 2; i <= answersCount - 1; i++) + for (var argIndex = 2; argIndex <= answersCount - 1; argIndex++) { - voteMenu.AddMenuOption(command.GetArg(i), Helper.HandleVotes); + string answer = command.GetArg(argIndex); + + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(answer)])); + + optionMap[i++] = () => + { + if (!VoteInProgress) + return; + + VoteAnswers[answer]++; + }; } - voteMenu.PostSelectAction = PostSelectAction.Close; + // If no answers, stop + if (i == 0) return; - Helper.PrintToCenterAll(_localizer["sa_admin_vote_message", caller == null ? _localizer["sa_console"] : caller.PlayerName, question]); + // Broadcast vote message + Helper.PrintToCenterAll( + _localizer["sa_admin_vote_message", + caller == null ? _localizer["sa_console"] : caller.PlayerName, + question]); - player.SendLocalizedMessage(_localizer, + player.SendLocalizedMessage( + _localizer, "sa_admin_vote_message", caller == null ? _localizer["sa_console"] : caller.PlayerName, question); - voteMenu.Open(player); + // Show the vote menu + Menu?.ShowScrollableMenu( + player, + _localizer["sa_admin_vote_menu_title", question], + items, + (buttons, menu, selected) => + { + if (selected == null) return; - //MenuManager.OpenChatMenu(player, voteMenu); + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + false, freezePlayer: false, disableDeveloper: true); } } @@ -67,6 +96,7 @@ public partial class CS2_SimpleAdmin { foreach (var player in Helper.GetValidPlayers()) { + Menu?.ClearMenus(player); if (_localizer != null) player.SendLocalizedMessage(_localizer, "sa_admin_vote_message_results", diff --git a/CS2-SimpleAdmin/Commands/panelcommands.cs b/CS2-SimpleAdmin/Commands/panelcommands.cs index fb8dce1..700d13a 100644 --- a/CS2-SimpleAdmin/Commands/panelcommands.cs +++ b/CS2-SimpleAdmin/Commands/panelcommands.cs @@ -15,6 +15,7 @@ using System.Text; using System.Text.Json; namespace CS2_SimpleAdmin; + public partial class CS2_SimpleAdmin { [ConsoleCommand("css_panel_say", "Say to all players from the panel.")] @@ -118,4 +119,37 @@ public partial class CS2_SimpleAdmin Logger.LogError(ex, "Unexpected error while query command"); } } + + [ConsoleCommand("css_fexec")] + [CommandHelper(minArgs: 2, usage: "<#userid or name or steamid> ", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + [RequiresPermissions("@css/root")] + public void OnFexecCommand(CCSPlayerController? caller, CommandInfo command) + { + var target = command.GetArg(1); + var exec = command.GetArg(2); + + List playersToTarget = Helper.GetValidPlayers(); + + // Find the player by name, userid or steamid + if (target.StartsWith("#")) + { + playersToTarget = playersToTarget.Where(player => player.UserId.ToString() == target.Replace("#", "")).ToList(); + } + else if (Helper.IsValidSteamId64(target)) + { + playersToTarget = playersToTarget.Where(player => player.SteamID.ToString() == target).ToList(); + } + else + { + playersToTarget = playersToTarget.Where(player => player.PlayerName.ToLower().Contains(target.ToLower())).ToList(); + } + + playersToTarget.ForEach(player => + { + if (caller.CanTarget(player)) + { + player.ExecuteClientCommandFromServer(exec); + } + }); + } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Commands/playercommands.cs b/CS2-SimpleAdmin/Commands/playercommands.cs index dc24e95..3388667 100644 --- a/CS2-SimpleAdmin/Commands/playercommands.cs +++ b/CS2-SimpleAdmin/Commands/playercommands.cs @@ -697,7 +697,7 @@ public partial class CS2_SimpleAdmin Respawn(caller, player, callerName, command); } }); - + Helper.LogCommand(caller, command); } @@ -710,12 +710,11 @@ public partial class CS2_SimpleAdmin callerName ??= caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; // Ensure the player's pawn is valid before attempting to respawn - if (_cBasePlayerControllerSetPawnFunc == null || player.PlayerPawn.Value == null || !player.PlayerPawn.IsValid) return; + if (player.PlayerPawn.Value == null || !player.PlayerPawn.IsValid) return; // Perform the respawn operation var playerPawn = player.PlayerPawn.Value; - _cBasePlayerControllerSetPawnFunc.Invoke(player, playerPawn, true, false); - VirtualFunction.CreateVoid(player.Handle, GameData.GetOffset("CCSPlayerController_Respawn"))(player); + player.Respawn(); if (player.UserId.HasValue && PlayersInfo.TryGetValue(player.UserId.Value, out var value) && value.DiePosition != null) playerPawn.Teleport(value.DiePosition?.Position, value.DiePosition?.Angle); diff --git a/CS2-SimpleAdmin/Config.cs b/CS2-SimpleAdmin/Config.cs index 64577bb..b4703c7 100644 --- a/CS2-SimpleAdmin/Config.cs +++ b/CS2-SimpleAdmin/Config.cs @@ -258,7 +258,10 @@ public class OtherSettings public List AdditionalCommandsToLog { get; set; } = new(); [JsonPropertyName("HideStealthPlayersFromSpecList")] - public bool HideStealthPlayersFromSpecList { get; set; } = false; + public bool HideStealthPlayersFromSpecList { get; set; } = true; + + [JsonPropertyName("HideAdminsOnJoinPermission")] + public List HideAdminsOnJoinPermission { get; set; } = ["@css/unban"]; [JsonPropertyName("IgnoredIps")] public List IgnoredIps { get; set; } = new(); @@ -289,9 +292,6 @@ public class CS2_SimpleAdminConfig : BasePluginConfig [JsonPropertyName("OtherSettings")] public OtherSettings OtherSettings { get; set; } = new(); - [JsonPropertyName("EnableMetrics")] - public bool EnableMetrics { get; set; } = true; - [JsonPropertyName("EnableUpdateCheck")] public bool EnableUpdateCheck { get; set; } = true; diff --git a/CS2-SimpleAdmin/Events.cs b/CS2-SimpleAdmin/Events.cs index 0901771..88b27dd 100644 --- a/CS2-SimpleAdmin/Events.cs +++ b/CS2-SimpleAdmin/Events.cs @@ -73,14 +73,16 @@ public partial class CS2_SimpleAdmin { if (player is null || player.IsValid is not true) continue; - //itereate cached players - for (int i = 0; i < CachedPlayers.Count(); i++) { + //iterate cached players + for (int i = 0; i < CachedPlayers.Count(); i++) + { //leave self's observerPawn so it can spectate and check if feature is enabled //we are clearing the whole spectator list as it doesn't work relaibly per person basis if (CachedPlayers[i] is null || CachedPlayers[i].IsValid is not true) continue; //check if it 'us' in the current context and do the magic only if it's not - if (CachedPlayers[i].Slot != player.Slot) { + if (CachedPlayers[i].Slot != player.Slot) + { //get the target's pawn var targetPawn = CachedPlayers[i].PlayerPawn.Value; @@ -121,6 +123,9 @@ public partial class CS2_SimpleAdmin #if DEBUG Logger.LogCritical("[OnClientDisconnect] After Check"); #endif + + Server.ExecuteCommand($"mm_removeexcludeslot {player.Slot}"); + try { if (DisconnectedPlayers.Count >= Config.OtherSettings.DisconnectedPlayersHistoryCount) @@ -150,20 +155,20 @@ public partial class CS2_SimpleAdmin if (player.UserId.HasValue) PlayersInfo.TryRemove(player.UserId.Value, out _); - - if (!PermissionManager.AdminCache.TryGetValue(steamId, out var data) + + if (!PermissionManager.AdminCache.TryGetValue(steamId, out var data) || !(data.ExpirationTime <= Time.ActualDateTime())) { return HookResult.Continue; } - + AdminManager.RemovePlayerPermissions(steamId, PermissionManager.AdminCache[steamId].Flags.ToArray()); AdminManager.RemovePlayerFromGroup(steamId, true, PermissionManager.AdminCache[steamId].Flags.ToArray()); var adminData = AdminManager.GetPlayerAdminData(steamId); - + if (adminData == null || data.Flags.ToList().Count != 0 && adminData.Groups.ToList().Count != 0) return HookResult.Continue; - + AdminManager.ClearPlayerPermissions(steamId); AdminManager.RemovePlayerAdminData(steamId); @@ -187,7 +192,7 @@ public partial class CS2_SimpleAdmin if (Instance.CacheManager != null && !Instance.CacheManager.IsPlayerBanned(null, ipaddress.Split(":")[0])) return; - Server.NextFrame((() => + Server.NextWorldUpdate((() => { var player = Utilities.GetPlayerFromSlot(playerslot); if (player == null || !player.IsValid || player.IsBot) @@ -195,7 +200,7 @@ public partial class CS2_SimpleAdmin Helper.KickPlayer(player, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); })); - + // Server.NextFrame(() => // { // var player = Utilities.GetPlayerFromSlot(playerslot); @@ -218,15 +223,25 @@ public partial class CS2_SimpleAdmin if (player == null || !player.IsValid || player.IsBot) return HookResult.Continue; - + CachedPlayers.Add(player); -// if (player.UserId.HasValue && PlayersInfo.TryGetValue(player.UserId.Value, out PlayerInfo? value) && -// value.WaitingForKick) -// return HookResult.Continue; - new PlayerManager().LoadPlayerData(player); + if (Config.OtherSettings.HideAdminsOnJoinPermission.Count() == 0 || !Config.OtherSettings.HideAdminsOnJoinPermission.Any((string permission) => AdminManager.PlayerHasPermissions(player, permission))) + { + return HookResult.Continue; + } + + AddTimer(0.5f, () => + { + player.ChangeTeam(CsTeam.Spectator); + }); + AddTimer(0.65f, () => + { + player.ExecuteClientCommandFromServer("css_hide"); + }); + return HookResult.Continue; } @@ -557,7 +572,11 @@ public partial class CS2_SimpleAdmin info.DontBroadcast = true; if (@event.Team > 1) + { SilentPlayers.Remove(player.Slot); + Server.ExecuteCommand($"mm_removeexcludeslot {player.Slot}"); + player.PrintToChat($"You aren't hidden now!"); + } return HookResult.Continue; } diff --git a/CS2-SimpleAdmin/Helper.cs b/CS2-SimpleAdmin/Helper.cs index fa58772..a8fda36 100644 --- a/CS2-SimpleAdmin/Helper.cs +++ b/CS2-SimpleAdmin/Helper.cs @@ -21,7 +21,6 @@ using System.Text.RegularExpressions; using CounterStrikeSharp.API.Core.Plugin.Host; using CounterStrikeSharp.API.Modules.Entities.Constants; using CS2_SimpleAdmin.Managers; -using MenuManager; using ZLinq; namespace CS2_SimpleAdmin; @@ -103,11 +102,11 @@ internal static class Helper } - // public static bool IsValidSteamId64(string input) - // { - // const string pattern = @"^\d{17}$"; - // return Regex.IsMatch(input, pattern); - // } + public static bool IsValidSteamId64(string input) + { + const string pattern = @"^\d{17}$"; + return Regex.IsMatch(input, pattern); + } public static bool ValidateSteamId(string input, out SteamID? steamId) { @@ -117,7 +116,7 @@ internal static class Helper { return false; } - + if (!SteamID.TryParse(input, out var parsedSteamId)) return false; steamId = parsedSteamId; @@ -321,15 +320,6 @@ internal static class Helper }); } - internal static void HandleVotes(CCSPlayerController player, ChatMenuOption option) - { - if (!CS2_SimpleAdmin.VoteInProgress) - return; - - option.Disabled = true; - CS2_SimpleAdmin.VoteAnswers[option.Text]++; - } - internal static void LogCommand(CCSPlayerController? caller, CommandInfo command) { if (CS2_SimpleAdmin._localizer == null) @@ -785,33 +775,6 @@ internal static class Helper commandString])); } - public static IMenu? CreateMenu(string title, Action? backAction = null) - { - var menuType = CS2_SimpleAdmin.Instance.Config.MenuConfigs.MenuType.ToLower(); - - var menu = menuType switch - { - _ when menuType.Equals("selectable", StringComparison.CurrentCultureIgnoreCase) => - CS2_SimpleAdmin.MenuApi?.GetMenu(title), - - _ when menuType.Equals("dynamic", StringComparison.CurrentCultureIgnoreCase) => - CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.ButtonMenu), - - _ when menuType.Equals("center", StringComparison.CurrentCultureIgnoreCase) => - CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.CenterMenu), - - _ when menuType.Equals("chat", StringComparison.CurrentCultureIgnoreCase) => - CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.ChatMenu), - - _ when menuType.Equals("console", StringComparison.CurrentCultureIgnoreCase) => - CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.ConsoleMenu), - - _ => CS2_SimpleAdmin.MenuApi?.GetMenu(title) - }; - - return menu; - } - internal static IPluginManager? GetPluginManager() { // Access the singleton instance of Application @@ -830,7 +793,7 @@ public static class PluginInfo { internal static async Task CheckVersion(string localVersion, ILogger logger) { - const string versionUrl = "https://raw.githubusercontent.com/daffyyyy/CS2-SimpleAdmin/main/CS2-SimpleAdmin/VERSION"; + const string versionUrl = "https://raw.githubusercontent.com/cruze03/CS2-SimpleAdmin/main/CS2-SimpleAdmin/VERSION"; var client = CS2_SimpleAdmin.HttpClient; try @@ -847,7 +810,7 @@ public static class PluginInfo switch (comparisonResult) { case < 0: - logger.LogWarning("Plugin is outdated! Check https://github.com/daffyyyy/CS2-SimpleAdmin"); + logger.LogWarning("Plugin is outdated! Check https://github.com/cruze03/CS2-SimpleAdmin"); break; case > 0: logger.LogInformation("Probably dev version detected"); @@ -883,7 +846,7 @@ public static class PluginInfo Console.WriteLine(" _____| || | | ||_|| || | | || |___ | _ || || ||_|| || | | | | |"); Console.WriteLine("|_______||___| |_| |_||___| |_______||_______||__| |__||______| |_| |_||___| |_| |__|"); Console.WriteLine(" >> Version: " + moduleVersion); - Console.WriteLine(" >> GitHub: https://github.com/daffyyyy/CS2-SimpleAdmin"); + Console.WriteLine(" >> GitHub: https://github.com/cruze03/CS2-SimpleAdmin"); Console.WriteLine(" "); } } diff --git a/CS2-SimpleAdmin/Managers/PlayerManager.cs b/CS2-SimpleAdmin/Managers/PlayerManager.cs index b80cb1e..dee5b58 100644 --- a/CS2-SimpleAdmin/Managers/PlayerManager.cs +++ b/CS2-SimpleAdmin/Managers/PlayerManager.cs @@ -19,7 +19,7 @@ public class PlayerManager { if (player.IsBot || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1")) return; - + if (!player.UserId.HasValue) { Helper.KickPlayer(player, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION); @@ -29,7 +29,6 @@ public class PlayerManager var ipAddress = player.IpAddress?.Split(":")[0]; CS2_SimpleAdmin.PlayersInfo[player.UserId.Value] = new PlayerInfo(player.UserId.Value, player.Slot, new SteamID(player.SteamID), player.PlayerName, ipAddress); - // if (!player.UserId.HasValue) // { diff --git a/CS2-SimpleAdmin/Managers/ServerManager.cs b/CS2-SimpleAdmin/Managers/ServerManager.cs index 756f0ed..18f1947 100644 --- a/CS2-SimpleAdmin/Managers/ServerManager.cs +++ b/CS2-SimpleAdmin/Managers/ServerManager.cs @@ -111,21 +111,6 @@ public class ServerManager { CS2_SimpleAdmin._logger?.LogCritical("Unable to create or get server_id: " + ex.Message); } - - if (CS2_SimpleAdmin.Instance.Config.EnableMetrics) - { - var queryString = $"?address={address}&hostname={hostname}"; - var client = CS2_SimpleAdmin.HttpClient; - - try - { - await client.GetAsync($"https://api.daffyy.dev/index.php{queryString}"); - } - catch (HttpRequestException ex) - { - CS2_SimpleAdmin._logger?.LogWarning($"Unable to make metrics call: {ex.Message}"); - } - } }); }); } diff --git a/CS2-SimpleAdmin/Menus/AdminMenu.cs b/CS2-SimpleAdmin/Menus/AdminMenu.cs index 454128d..00261d9 100644 --- a/CS2-SimpleAdmin/Menus/AdminMenu.cs +++ b/CS2-SimpleAdmin/Menus/AdminMenu.cs @@ -1,32 +1,13 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; -using CounterStrikeSharp.API.Modules.Menu; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; public static class AdminMenu { - public static IMenu? CreateMenu(string title, Action? backAction = null) - { - return Helper.CreateMenu(title, backAction); - // return CS2_SimpleAdmin.Instance.Config.UseChatMenu ? new ChatMenu(title) : new CenterHtmlMenu(title, CS2_SimpleAdmin.Instance); - } - - public static void OpenMenu(CCSPlayerController player, IMenu menu) - { - menu.Open(player); - // switch (menu) - // { - // case CenterHtmlMenu centerHtmlMenu: - // MenuManager.OpenCenterHtmlMenu(CS2_SimpleAdmin.Instance, player, centerHtmlMenu); - // break; - // case ChatMenu chatMenu: - // MenuManager.OpenChatMenu(player, chatMenu); - // break; - // } - } - public static void OpenMenu(CCSPlayerController admin) { if (admin.IsValid == false) @@ -42,7 +23,6 @@ public static class AdminMenu return; } - var menu = CreateMenu(localizer?["sa_title"] ?? "SimpleAdmin"); List options = [ new ChatMenuOptionData(localizer?["sa_menu_players_manage"] ?? "Players Manage", () => ManagePlayersMenu.OpenMenu(admin)), @@ -59,12 +39,30 @@ public static class AdminMenu if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/root")) options.Add(new ChatMenuOptionData(localizer?["sa_menu_admins_manage"] ?? "Admins Manage", () => ManageAdminsMenu.OpenMenu(admin))); + List items = []; + var optionMap = new Dictionary(); + int i = 0; + foreach (var menuOptionData in options) { var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); + if (!menuOptionData.Disabled) + { + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(menuName)])); + optionMap[i++] = menuOptionData; + } } - if (menu != null) OpenMenu(admin, menu); + if(i == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu(admin, localizer?["sa_title"] ?? "SimpleAdmin", items, (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var menuOptionData)) + { + menuOptionData.Action.Invoke(); + } + }, false, freezePlayer: false, disableDeveloper: true); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Menus/CustomCommandsMenu.cs b/CS2-SimpleAdmin/Menus/CustomCommandsMenu.cs index 47eb577..0a9635e 100644 --- a/CS2-SimpleAdmin/Menus/CustomCommandsMenu.cs +++ b/CS2-SimpleAdmin/Menus/CustomCommandsMenu.cs @@ -2,6 +2,8 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; @@ -9,43 +11,50 @@ public static class CustomCommandsMenu { public static void OpenMenu(CCSPlayerController admin) { - if (admin.IsValid == false) - return; + if (!admin.IsValid) return; var localizer = CS2_SimpleAdmin._localizer; - if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic") == false) + if (!AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic")) { - admin.PrintToChat(localizer?["sa_prefix"] ?? - "[SimpleAdmin] " + - (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command") - ); + admin.PrintToChat(localizer?["sa_prefix"] ?? "[SimpleAdmin] " + + (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command")); return; } - var menu = AdminMenu.CreateMenu(localizer?["sa_menu_custom_commands"] ?? "Custom Commands"); - List options = []; + var customCommands = CS2_SimpleAdmin.Instance.Config.CustomServerCommands + .Where(c => !string.IsNullOrEmpty(c.DisplayName) && !string.IsNullOrEmpty(c.Command)) + .Where(c => AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), c.Flag)) + .ToList(); - var customCommands = CS2_SimpleAdmin.Instance.Config.CustomServerCommands; - options.AddRange(from customCommand in customCommands - where !string.IsNullOrEmpty(customCommand.DisplayName) && !string.IsNullOrEmpty(customCommand.Command) - let hasRights = AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), customCommand.Flag) - where hasRights - select new ChatMenuOptionData(customCommand.DisplayName, () => - { - Helper.TryLogCommandOnDiscord(admin, customCommand.Command); + if (customCommands.Count == 0) return; - if (customCommand.ExecuteOnClient) - admin.ExecuteClientCommandFromServer(customCommand.Command); - else - Server.ExecuteCommand(customCommand.Command); - })); - - foreach (var menuOptionData in options) + var items = new List(); + for (int i = 0; i < customCommands.Count; i++) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action(); }, menuOptionData.Disabled); + var cmd = customCommands[i]; + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(cmd.DisplayName)])); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + localizer?["sa_menu_custom_commands"] ?? "Custom Commands", + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && menu.Option >= 0 && menu.Option < customCommands.Count) + { + var cmd = customCommands[menu.Option]; + Helper.TryLogCommandOnDiscord(admin, cmd.Command); + + if (cmd.ExecuteOnClient) + admin.ExecuteClientCommandFromServer(cmd.Command); + else + Server.ExecuteCommand(cmd.Command); + } + }, + true, + freezePlayer: false, + disableDeveloper: true); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Menus/DurationMenu.cs b/CS2-SimpleAdmin/Menus/DurationMenu.cs index a0cc724..bb955b5 100644 --- a/CS2-SimpleAdmin/Menus/DurationMenu.cs +++ b/CS2-SimpleAdmin/Menus/DurationMenu.cs @@ -1,5 +1,7 @@ using CounterStrikeSharp.API.Core; using CS2_SimpleAdmin.Models; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; @@ -7,26 +9,69 @@ public static class DurationMenu { public static void OpenMenu(CCSPlayerController admin, string menuName, CCSPlayerController player, Action onSelectAction) { - var menu = AdminMenu.CreateMenu(menuName); + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var durationItem in CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations) { - menu?.AddMenuOption(durationItem.Name, (_, _) => { onSelectAction(admin, player, durationItem.Duration); }); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(durationItem.Name)])); + + optionMap[i++] = () => + { + onSelectAction(admin, player, durationItem.Duration); + }; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuName, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + true, freezePlayer: false, disableDeveloper: true); } public static void OpenMenu(CCSPlayerController admin, string menuName, DisconnectedPlayer player, Action onSelectAction) { - var menu = AdminMenu.CreateMenu(menuName); + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var durationItem in CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations) { - menu?.AddMenuOption(durationItem.Name, (_, _) => { onSelectAction(admin, player, durationItem.Duration); }); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(durationItem.Name)])); + + optionMap[i++] = () => + { + onSelectAction(admin, player, durationItem.Duration); + }; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); - } + if (i == 0) return; + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuName, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + true, freezePlayer: false, disableDeveloper: true); + } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Menus/FunActionsMenu.cs b/CS2-SimpleAdmin/Menus/FunActionsMenu.cs index 394f27b..ba696e3 100644 --- a/CS2-SimpleAdmin/Menus/FunActionsMenu.cs +++ b/CS2-SimpleAdmin/Menus/FunActionsMenu.cs @@ -2,6 +2,8 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Entities.Constants; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; @@ -33,76 +35,76 @@ public static class FunActionsMenu public static void OpenMenu(CCSPlayerController admin) { - if (admin.IsValid == false) + if (!admin.IsValid) return; var localizer = CS2_SimpleAdmin._localizer; - if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic") == false) + + if (!AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic")) { admin.PrintToChat(localizer?["sa_prefix"] ?? - "[SimpleAdmin] " + - (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command") - ); + "[SimpleAdmin] " + + (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command")); return; } - var menu = AdminMenu.CreateMenu(localizer?["sa_menu_fun_commands"] ?? "Fun Commands"); - List options = []; + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - //var hasCheats = AdminManager.PlayerHasPermissions(admin, "@css/cheats"); - //var hasSlay = AdminManager.PlayerHasPermissions(admin, "@css/slay"); - - // options added in order - - if (AdminManager.CommandIsOverriden("css_god") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_god")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/cheats")) - options.Add(new ChatMenuOptionData(localizer?["sa_godmode"] ?? "God Mode", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_godmode"] ?? "God Mode", GodMode))); - if (AdminManager.CommandIsOverriden("css_noclip") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_noclip")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/cheats")) - options.Add(new ChatMenuOptionData(localizer?["sa_noclip"] ?? "No Clip", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_noclip"] ?? "No Clip", NoClip))); - if (AdminManager.CommandIsOverriden("css_respawn") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_respawn")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/cheats")) - options.Add(new ChatMenuOptionData(localizer?["sa_respawn"] ?? "Respawn", () => PlayersMenu.OpenDeadMenu(admin, localizer?["sa_respawn"] ?? "Respawn", Respawn))); - if (AdminManager.CommandIsOverriden("css_give") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_give")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/cheats")) - options.Add(new ChatMenuOptionData(localizer?["sa_give_weapon"] ?? "Give Weapon", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_give_weapon"] ?? "Give Weapon", GiveWeaponMenu))); - - if (AdminManager.CommandIsOverriden("css_strip") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_strip")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay")) - options.Add(new ChatMenuOptionData(localizer?["sa_strip_weapons"] ?? "Strip Weapons", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_strip_weapons"] ?? "Strip Weapons", StripWeapons))); - if (AdminManager.CommandIsOverriden("css_freeze") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_freeze")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay")) - options.Add(new ChatMenuOptionData(localizer?["sa_freeze"] ?? "Freeze", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_freeze"] ?? "Freeze", Freeze))); - if (AdminManager.CommandIsOverriden("css_hp") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_hp")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay")) - options.Add(new ChatMenuOptionData(localizer?["sa_set_hp"] ?? "Set Hp", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_set_hp"] ?? "Set Hp", SetHpMenu))); - if (AdminManager.CommandIsOverriden("css_speed") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_speed")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay")) - options.Add(new ChatMenuOptionData(localizer?["sa_set_speed"] ?? "Set Speed", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_set_speed"] ?? "Set Speed", SetSpeedMenu))); - if (AdminManager.CommandIsOverriden("css_gravity") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gravity")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay")) - options.Add(new ChatMenuOptionData(localizer?["sa_set_gravity"] ?? "Set Gravity", () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_set_gravity"] ?? "Set Gravity", SetGravityMenu))); - if (AdminManager.CommandIsOverriden("css_money") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_money")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay")) - options.Add(new ChatMenuOptionData(localizer?["sa_set_money"] ?? "Set Money", () => PlayersMenu.OpenMenu(admin, localizer?["sa_set_money"] ?? "Set Money", SetMoneyMenu))); - - foreach (var menuOptionData in options) + void TryAddOption(string command, string defaultPermission, string localizerKey, Action action) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action(); }, menuOptionData.Disabled); + string[] permission = AdminManager.CommandIsOverriden(command) + ? AdminManager.GetPermissionOverrides(command) + : [defaultPermission]; + + if (!AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), permission)) + return; + + string menuName = localizer?[localizerKey] ?? localizerKey; + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(menuName)])); + optionMap[i++] = action; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + // Add options + TryAddOption("css_god", "@css/cheats", "sa_godmode", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_godmode"] ?? "God Mode", GodMode)); + TryAddOption("css_noclip", "@css/cheats", "sa_noclip", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_noclip"] ?? "No Clip", NoClip)); + TryAddOption("css_respawn", "@css/cheats", "sa_respawn", + () => PlayersMenu.OpenDeadMenu(admin, localizer?["sa_respawn"] ?? "Respawn", Respawn)); + TryAddOption("css_give", "@css/cheats", "sa_give_weapon", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_give_weapon"] ?? "Give Weapon", GiveWeaponMenu)); + TryAddOption("css_strip", "@css/slay", "sa_strip_weapons", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_strip_weapons"] ?? "Strip Weapons", StripWeapons)); + TryAddOption("css_freeze", "@css/slay", "sa_freeze", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_freeze"] ?? "Freeze", Freeze)); + TryAddOption("css_hp", "@css/slay", "sa_set_hp", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_set_hp"] ?? "Set Hp", SetHpMenu)); + TryAddOption("css_speed", "@css/slay", "sa_set_speed", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_set_speed"] ?? "Set Speed", SetSpeedMenu)); + TryAddOption("css_gravity", "@css/slay", "sa_set_gravity", + () => PlayersMenu.OpenAliveMenu(admin, localizer?["sa_set_gravity"] ?? "Set Gravity", SetGravityMenu)); + TryAddOption("css_money", "@css/slay", "sa_set_money", + () => PlayersMenu.OpenMenu(admin, localizer?["sa_set_money"] ?? "Set Money", SetMoneyMenu)); + + if (i == 0) return; // nothing to show + + // Show menu using new ShowScrollableMenu method + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + localizer?["sa_menu_fun_commands"] ?? "Fun Commands", + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + true, freezePlayer: false, disableDeveloper: true); } private static void GodMode(CCSPlayerController admin, CCSPlayerController player) @@ -122,14 +124,39 @@ public static class FunActionsMenu private static void GiveWeaponMenu(CCSPlayerController admin, CCSPlayerController player) { - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_give_weapon"] ?? "Give Weapon"}: {player.PlayerName}"); + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_give_weapon"] ?? "Give Weapon"}: {player.PlayerName}"; + + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var weapon in GetWeaponsCache) { - menu?.AddMenuOption(weapon.Value.ToString(), (_, _) => { GiveWeapon(admin, player, weapon.Value); }); + string weaponName = weapon.Value.ToString(); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(weaponName)])); + + optionMap[i++] = () => + { + GiveWeapon(admin, player, weapon.Value); + }; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; // nothing to show + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + true, freezePlayer: false, disableDeveloper: true); } private static void GiveWeapon(CCSPlayerController admin, CCSPlayerController player, CsItem weaponValue) @@ -167,14 +194,38 @@ public static class FunActionsMenu new Tuple("999", 999) }; - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_set_hp"] ?? "Set Hp"}: {player.PlayerName}"); + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_set_hp"] ?? "Set Hp"}: {player.PlayerName}"; + + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var (optionName, value) in hpArray) { - menu?.AddMenuOption(optionName, (_, _) => { SetHp(admin, player, value); }); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(optionName)])); + + optionMap[i++] = () => + { + SetHp(admin, player, value); + }; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; // nothing to show + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + { + action.Invoke(); + } + }, + true, freezePlayer: false, disableDeveloper: true); } private static void SetHp(CCSPlayerController admin, CCSPlayerController player, int hp) @@ -196,14 +247,31 @@ public static class FunActionsMenu new Tuple("4", 4) }; - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_set_speed"] ?? "Set Speed"}: {player.PlayerName}"); + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_set_speed"] ?? "Set Speed"}: {player.PlayerName}"; + + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var (optionName, value) in speedArray) { - menu?.AddMenuOption(optionName, (_, _) => { SetSpeed(admin, player, value); }); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(optionName)])); + optionMap[i++] = () => SetSpeed(admin, player, value); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void SetSpeed(CCSPlayerController admin, CCSPlayerController player, float speed) @@ -223,14 +291,31 @@ public static class FunActionsMenu new Tuple("2", 2) }; - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_set_gravity"] ?? "Set Gravity"}: {player.PlayerName}"); + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_set_gravity"] ?? "Set Gravity"}: {player.PlayerName}"; + + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var (optionName, value) in gravityArray) { - menu?.AddMenuOption(optionName, (_, _) => { SetGravity(admin, player, value); }); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(optionName)])); + optionMap[i++] = () => SetGravity(admin, player, value); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void SetGravity(CCSPlayerController admin, CCSPlayerController player, float gravity) @@ -250,14 +335,31 @@ public static class FunActionsMenu new Tuple("$16000", 16000) }; - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_set_money"] ?? "Set Money"}: {player.PlayerName}"); + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_set_money"] ?? "Set Money"}: {player.PlayerName}"; + + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var (optionName, value) in moneyArray) { - menu?.AddMenuOption(optionName, (_, _) => { SetMoney(admin, player, value); }); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(optionName)])); + optionMap[i++] = () => SetMoney(admin, player, value); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; // nothing to show + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void SetMoney(CCSPlayerController admin, CCSPlayerController player, int money) diff --git a/CS2-SimpleAdmin/Menus/ManageAdminsMenu.cs b/CS2-SimpleAdmin/Menus/ManageAdminsMenu.cs index 1b68955..60989f6 100644 --- a/CS2-SimpleAdmin/Menus/ManageAdminsMenu.cs +++ b/CS2-SimpleAdmin/Menus/ManageAdminsMenu.cs @@ -1,6 +1,8 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; @@ -8,52 +10,88 @@ public static class ManageAdminsMenu { public static void OpenMenu(CCSPlayerController admin) { - if (admin.IsValid == false) + if (!admin.IsValid) return; var localizer = CS2_SimpleAdmin._localizer; - if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/root") == false) + + if (!AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/root")) { admin.PrintToChat(localizer?["sa_prefix"] ?? - "[SimpleAdmin] " + - (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command") - ); + "[SimpleAdmin] " + + (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command")); return; } - var menu = AdminMenu.CreateMenu(localizer?["sa_menu_admins_manage"] ?? "Admins Manage"); - List options = - [ - new ChatMenuOptionData(localizer?["sa_admin_add"] ?? "Add Admin", - () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_admin_add"] ?? "Add Admin", AddAdminMenu)), - new ChatMenuOptionData(localizer?["sa_admin_remove"] ?? "Remove Admin", - () => PlayersMenu.OpenAdminPlayersMenu(admin, localizer?["sa_admin_remove"] ?? "Remove Admin", RemoveAdmin, - player => player != admin && admin.CanTarget(player))), - new ChatMenuOptionData(localizer?["sa_admin_reload"] ?? "Reload Admins", () => ReloadAdmins(admin)) - ]; + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - foreach (var menuOptionData in options) + void AddOption(string name, Action action, bool disabled = false) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); + if (disabled) return; // skip disabled options + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(name)])); + optionMap[i++] = action; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + AddOption(localizer?["sa_admin_add"] ?? "Add Admin", + () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_admin_add"] ?? "Add Admin", AddAdminMenu)); + + AddOption(localizer?["sa_admin_remove"] ?? "Remove Admin", + () => PlayersMenu.OpenAdminPlayersMenu(admin, localizer?["sa_admin_remove"] ?? "Remove Admin", + RemoveAdmin, player => player != admin && admin.CanTarget(player))); + + AddOption(localizer?["sa_admin_reload"] ?? "Reload Admins", () => ReloadAdmins(admin)); + + if (i == 0) return; // nothing to show + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + localizer?["sa_menu_admins_manage"] ?? "Admins Manage", + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void AddAdminMenu(CCSPlayerController admin, CCSPlayerController player) { - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_admin_add"] ?? "Add Admin"}: {player.PlayerName}"); + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_admin_add"] ?? "Add Admin"}: {player.PlayerName}"; + + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var adminFlag in CS2_SimpleAdmin.Instance.Config.MenuConfigs.AdminFlags) { - var disabled = AdminManager.PlayerHasPermissions(player, adminFlag.Flag); - menu?.AddMenuOption(adminFlag.Name, (_, _) => { AddAdmin(admin, player, adminFlag.Flag); }, disabled); + bool disabled = AdminManager.PlayerHasPermissions(player, adminFlag.Flag); + if (disabled) continue; // skip disabled flags + + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(adminFlag.Name)])); + int index = i++; + optionMap[index] = () => AddAdmin(admin, player, adminFlag.Flag); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } + private static void AddAdmin(CCSPlayerController admin, CCSPlayerController player, string flag) { // TODO: Change default immunity? diff --git a/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs b/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs index 8b64944..9facd2e 100644 --- a/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs +++ b/CS2-SimpleAdmin/Menus/ManagePlayersMenu.cs @@ -3,6 +3,8 @@ using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Utils; using CS2_SimpleAdminApi; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; @@ -10,101 +12,162 @@ public static class ManagePlayersMenu { public static void OpenMenu(CCSPlayerController admin) { - if (admin.IsValid == false) - return; + if (!admin.IsValid) return; var localizer = CS2_SimpleAdmin._localizer; - if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic") == false) + if (!AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic")) { - admin.PrintToChat(localizer?["sa_prefix"] ?? - "[SimpleAdmin] " + - (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command") - ); + admin.PrintToChat(localizer?["sa_prefix"] ?? "[SimpleAdmin] " + + (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command")); return; } - var menu = AdminMenu.CreateMenu(localizer?["sa_menu_players_manage"] ?? "Manage Players"); - List options = []; + var menuTitle = localizer?["sa_menu_players_manage"] ?? "Manage Players"; + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - // permissions - var hasSlay = AdminManager.CommandIsOverriden("css_slay") ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_slay")) : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay"); - var hasKick = AdminManager.CommandIsOverriden("css_kick") ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_kick")) : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick"); - var hasBan = AdminManager.CommandIsOverriden("css_ban") ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_ban")) : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/ban"); - var hasChat = AdminManager.CommandIsOverriden("css_gag") ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gag")) : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat"); + void AddOption(string name, Action action, bool disabled = false) + { + if (disabled) return; // skip disabled options + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(name)])); + optionMap[i++] = action; + } - // TODO: Localize options - // options added in order + // Permissions + var hasSlay = AdminManager.CommandIsOverriden("css_slay") + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_slay")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/slay"); + var hasKick = AdminManager.CommandIsOverriden("css_kick") + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_kick")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick"); + + var hasBan = AdminManager.CommandIsOverriden("css_ban") + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_ban")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/ban"); + + var hasChat = AdminManager.CommandIsOverriden("css_gag") + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gag")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat"); + + // Add menu options if (hasSlay) { - options.Add(new ChatMenuOptionData(localizer?["sa_slap"] ?? "Slap", () => PlayersMenu.OpenMenu(admin, localizer?["sa_slap"] ?? "Slap", SlapMenu))); - options.Add(new ChatMenuOptionData(localizer?["sa_slay"] ?? "Slay", () => PlayersMenu.OpenMenu(admin, localizer?["sa_slay"] ?? "Slay", Slay))); + AddOption(localizer?["sa_slap"] ?? "Slap", () => PlayersMenu.OpenMenu(admin, localizer?["sa_slap"] ?? "Slap", SlapMenu)); + AddOption(localizer?["sa_slay"] ?? "Slay", () => PlayersMenu.OpenMenu(admin, localizer?["sa_slay"] ?? "Slay", Slay)); } if (hasKick) { - options.Add(new ChatMenuOptionData(localizer?["sa_kick"] ?? "Kick", () => PlayersMenu.OpenMenu(admin, localizer?["sa_kick"] ?? "Kick", KickMenu))); + AddOption(localizer?["sa_kick"] ?? "Kick", () => PlayersMenu.OpenMenu(admin, localizer?["sa_kick"] ?? "Kick", KickMenu)); } if (AdminManager.CommandIsOverriden("css_warn") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_warn")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick")) - options.Add(new ChatMenuOptionData(localizer?["sa_warn"] ?? "Warn", () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_warn"] ?? "Warn", (admin, player) => DurationMenu.OpenMenu(admin, $"{localizer?["sa_warn"] ?? "Warn"}: {player.PlayerName}", player, WarnMenu)))); + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_warn")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick")) + { + AddOption(localizer?["sa_warn"] ?? "Warn", + () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_warn"] ?? "Warn", + (adminController, player) => DurationMenu.OpenMenu(adminController, $"{localizer?["sa_warn"] ?? "Warn"}: {player.PlayerName}", player, WarnMenu))); + } if (hasBan) - options.Add(new ChatMenuOptionData(localizer?["sa_ban"] ?? "Ban", () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_ban"] ?? "Ban", (admin, player) => DurationMenu.OpenMenu(admin, $"{localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player, BanMenu)))); + { + AddOption(localizer?["sa_ban"] ?? "Ban", + () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_ban"] ?? "Ban", + (adminController, player) => DurationMenu.OpenMenu(adminController, $"{localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player, BanMenu))); + } if (hasChat) { if (AdminManager.CommandIsOverriden("css_gag") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gag")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) - options.Add(new ChatMenuOptionData(localizer?["sa_gag"] ?? "Gag", () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_gag"] ?? "Gag", (admin, player) => DurationMenu.OpenMenu(admin, $"{localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player, GagMenu)))); + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gag")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) + { + AddOption(localizer?["sa_gag"] ?? "Gag", + () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_gag"] ?? "Gag", + (adminController, player) => DurationMenu.OpenMenu(adminController, $"{localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player, GagMenu))); + } + if (AdminManager.CommandIsOverriden("css_mute") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_mute")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) - options.Add(new ChatMenuOptionData(localizer?["sa_mute"] ?? "Mute", () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_mute"] ?? "Mute", (admin, player) => DurationMenu.OpenMenu(admin, $"{localizer?["sa_mute"] ?? "Mute"}: {player.PlayerName}", player, MuteMenu)))); + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_mute")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) + { + AddOption(localizer?["sa_mute"] ?? "Mute", + () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_mute"] ?? "Mute", + (adminController, player) => DurationMenu.OpenMenu(adminController, $"{localizer?["sa_mute"] ?? "Mute"}: {player.PlayerName}", player, MuteMenu))); + } + if (AdminManager.CommandIsOverriden("css_silence") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_silence")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) - options.Add(new ChatMenuOptionData(localizer?["sa_silence"] ?? "Silence", () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_silence"] ?? "Silence", (admin, player) => DurationMenu.OpenMenu(admin, $"{localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player, SilenceMenu)))); + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_silence")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) + { + AddOption(localizer?["sa_silence"] ?? "Silence", + () => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_silence"] ?? "Silence", + (adminController, player) => DurationMenu.OpenMenu(adminController, $"{localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player, SilenceMenu))); + } } if (AdminManager.CommandIsOverriden("css_team") - ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_team")) - : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick")) - options.Add(new ChatMenuOptionData(localizer?["sa_team_force"] ?? "Force Team", () => PlayersMenu.OpenMenu(admin, localizer?["sa_team_force"] ?? "Force Team", ForceTeamMenu))); - - foreach (var menuOptionData in options) + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_team")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick")) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); + AddOption(localizer?["sa_team_force"] ?? "Force Team", () => PlayersMenu.OpenMenu(admin, localizer?["sa_team_force"] ?? "Force Team", ForceTeamMenu)); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (i == 0) return; // nothing to show + + // Show scrollable menu + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void SlapMenu(CCSPlayerController admin, CCSPlayerController player) { - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_slap"] ?? "Slap"}: {player.PlayerName}"); - List options = - [ - // options added in order - new ChatMenuOptionData("0 hp", () => ApplySlapAndKeepMenu(admin, player, 0)), - new ChatMenuOptionData("1 hp", () => ApplySlapAndKeepMenu(admin, player, 1)), - new ChatMenuOptionData("5 hp", () => ApplySlapAndKeepMenu(admin, player, 5)), - new ChatMenuOptionData("10 hp", () => ApplySlapAndKeepMenu(admin, player, 10)), - new ChatMenuOptionData("50 hp", () => ApplySlapAndKeepMenu(admin, player, 50)), - new ChatMenuOptionData("100 hp", () => ApplySlapAndKeepMenu(admin, player, 100)), - ]; + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_slap"] ?? "Slap"}: {player.PlayerName}"; - foreach (var menuOptionData in options) + List items = new(); + var optionMap = new Dictionary(); + int i = 0; + + void AddOption(string name, Action action, bool disabled = false) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); + if (disabled) return; // skip disabled options + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(name)])); + optionMap[i++] = action; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + // Add slap options + AddOption("0 hp", () => ApplySlapAndKeepMenu(admin, player, 0)); + AddOption("1 hp", () => ApplySlapAndKeepMenu(admin, player, 1)); + AddOption("5 hp", () => ApplySlapAndKeepMenu(admin, player, 5)); + AddOption("10 hp", () => ApplySlapAndKeepMenu(admin, player, 10)); + AddOption("50 hp", () => ApplySlapAndKeepMenu(admin, player, 50)); + AddOption("100 hp", () => ApplySlapAndKeepMenu(admin, player, 100)); + + if (i == 0) return; // nothing to show + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void ApplySlapAndKeepMenu(CCSPlayerController admin, CCSPlayerController player, int damage) @@ -154,29 +217,25 @@ public static class ManagePlayersMenu 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) => + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}"; + + // Open the reason menu as a scrollable menu + ReasonMenu.OpenMenu( + admin, + PenaltyType.Ban, + menuTitle, + player, + (_, _, reason) => { if (player is { IsValid: true }) Ban(admin, player, duration, reason); - - CS2_SimpleAdmin.MenuApi?.CloseMenu(admin); - }); - // var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_ban"] ?? "Ban"}: {player?.PlayerName}"); - // - // foreach (var option in CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons) - // { - // menu?.AddMenuOption(option, (_, _) => - // { - // if (player is { IsValid: true }) - // Ban(admin, player, duration, option); - // }); - // } - // - // if (menu != null) AdminMenu.OpenMenu(admin, menu); + // Close menu after selection + CS2_SimpleAdmin.Menu.ClearMenus(admin); + }); } + private static void Ban(CCSPlayerController admin, CCSPlayerController player, int duration, string reason) { if (player is not { IsValid: true }) return; @@ -190,7 +249,9 @@ public static class ManagePlayersMenu $"{CS2_SimpleAdmin._localizer?["sa_warn"] ?? "Warn"}: {player.PlayerName}", player, (_, _, reason) => { if (player is { IsValid: true }) + { Warn(admin, player, duration, reason); + } }); // var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_warn"] ?? "Warn"}: {player?.PlayerName}"); @@ -308,25 +369,47 @@ public static class ManagePlayersMenu private static void ForceTeamMenu(CCSPlayerController admin, CCSPlayerController player) { - // TODO: Localize - var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_team_force"] ?? "Force Team"} {player.PlayerName}"); - List options = - [ - new ChatMenuOptionData(CS2_SimpleAdmin._localizer?["sa_team_ct"] ?? "CT", () => ForceTeam(admin, player, "ct", CsTeam.CounterTerrorist)), - new ChatMenuOptionData(CS2_SimpleAdmin._localizer?["sa_team_t"] ?? "T", () => ForceTeam(admin, player, "t", CsTeam.Terrorist)), - new ChatMenuOptionData(CS2_SimpleAdmin._localizer?["sa_team_swap"] ?? "Swap", () => ForceTeam(admin, player, "swap", CsTeam.Spectator)), - new ChatMenuOptionData(CS2_SimpleAdmin._localizer?["sa_team_spec"] ?? "Spec", () => ForceTeam(admin, player, "spec", CsTeam.Spectator)), - ]; + var menuTitle = $"{CS2_SimpleAdmin._localizer?["sa_team_force"] ?? "Force Team"} {player.PlayerName}"; - foreach (var menuOptionData in options) + List items = new(); + var optionMap = new Dictionary(); + int i = 0; + + void AddOption(string name, Action action, bool disabled = false) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); + if (disabled) return; // skip disabled options + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(name)])); + optionMap[i++] = action; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + AddOption(CS2_SimpleAdmin._localizer?["sa_team_ct"] ?? "CT", + () => ForceTeam(admin, player, "ct", CsTeam.CounterTerrorist)); + + AddOption(CS2_SimpleAdmin._localizer?["sa_team_t"] ?? "T", + () => ForceTeam(admin, player, "t", CsTeam.Terrorist)); + + AddOption(CS2_SimpleAdmin._localizer?["sa_team_swap"] ?? "Swap", + () => ForceTeam(admin, player, "swap", CsTeam.Spectator)); + + AddOption(CS2_SimpleAdmin._localizer?["sa_team_spec"] ?? "Spec", + () => ForceTeam(admin, player, "spec", CsTeam.Spectator)); + + if (i == 0) return; // nothing to show + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } + private static void ForceTeam(CCSPlayerController admin, CCSPlayerController player, string teamName, CsTeam teamNum) { if (player is not { IsValid: true }) return; diff --git a/CS2-SimpleAdmin/Menus/ManageServerMenu.cs b/CS2-SimpleAdmin/Menus/ManageServerMenu.cs index dd60a67..ccfac38 100644 --- a/CS2-SimpleAdmin/Menus/ManageServerMenu.cs +++ b/CS2-SimpleAdmin/Menus/ManageServerMenu.cs @@ -1,6 +1,8 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Entities; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; @@ -8,70 +10,97 @@ public static class ManageServerMenu { public static void OpenMenu(CCSPlayerController admin) { - if (admin.IsValid == false) - return; + if (!admin.IsValid) return; var localizer = CS2_SimpleAdmin._localizer; - if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic") == false) + if (!AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic")) { - admin.PrintToChat(localizer?["sa_prefix"] ?? - "[SimpleAdmin] " + - (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command") - ); + admin.PrintToChat(localizer?["sa_prefix"] ?? "[SimpleAdmin] " + + (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command")); return; } - var menu = AdminMenu.CreateMenu(localizer?["sa_menu_server_manage"] ?? "Server Manage"); - List options = []; + string menuTitle = localizer?["sa_menu_server_manage"] ?? "Server Manage"; + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - - // permissions - var hasMap = AdminManager.CommandIsOverriden("css_map") ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_map")) : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/changemap"); - var hasPlugins = AdminManager.CommandIsOverriden("css_pluginsmanager") ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_pluginsmanager")) : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/root"); - - //bool hasMap = AdminManager.PlayerHasPermissions(admin, "@css/changemap"); - - // options added in order - - if (hasPlugins) + void AddOption(string name, Action action, bool disabled = false) { - options.Add(new ChatMenuOptionData(localizer?["sa_menu_pluginsmanager_title"] ?? "Manage Plugins", () => admin.ExecuteClientCommandFromServer("css_pluginsmanager"))); + if (disabled) return; // skip disabled options + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(name)])); + optionMap[i++] = action; } + // Permissions + var hasMap = AdminManager.CommandIsOverriden("css_map") + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_map")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/changemap"); + + var hasPlugins = AdminManager.CommandIsOverriden("css_pluginsmanager") + ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_pluginsmanager")) + : AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/root"); + + // Menu options + if (hasPlugins) + AddOption(localizer?["sa_menu_pluginsmanager_title"] ?? "Manage Plugins", () => admin.ExecuteClientCommandFromServer("css_pluginsmanager")); + if (hasMap) - { - options.Add(new ChatMenuOptionData(localizer?["sa_changemap"] ?? "Change Map", () => ChangeMapMenu(admin))); - } + AddOption(localizer?["sa_changemap"] ?? "Change Map", () => ChangeMapMenu(admin)); - options.Add(new ChatMenuOptionData(localizer?["sa_restart_game"] ?? "Restart Game", () => CS2_SimpleAdmin.RestartGame(admin))); + AddOption(localizer?["sa_restart_game"] ?? "Restart Game", () => CS2_SimpleAdmin.RestartGame(admin)); - foreach (var menuOptionData in options) - { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); - } + if (items.Count == 0) return; // nothing to show - if (menu != null) AdminMenu.OpenMenu(admin, menu); + // Show scrollable menu + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void ChangeMapMenu(CCSPlayerController admin) { - var menu = AdminMenu.CreateMenu(CS2_SimpleAdmin._localizer?["sa_changemap"] ?? "Change Map"); - List options = []; + string menuTitle = CS2_SimpleAdmin._localizer?["sa_changemap"] ?? "Change Map"; + List items = new(); + var optionMap = new Dictionary(); + int i = 0; - var maps = CS2_SimpleAdmin.Instance.Config.DefaultMaps; - options.AddRange(maps.Select(map => new ChatMenuOptionData(map, () => ExecuteChangeMap(admin, map, false)))); - - var wsMaps = CS2_SimpleAdmin.Instance.Config.WorkshopMaps; - options.AddRange(wsMaps.Select(map => new ChatMenuOptionData($"{map.Key} (WS)", () => ExecuteChangeMap(admin, map.Value?.ToString() ?? map.Key, true)))); - - foreach (var menuOptionData in options) + void AddOption(string name, Action action, bool disabled = false) { - var menuName = menuOptionData.Name; - menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled); + if (disabled) return; + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(name)])); + optionMap[i++] = action; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + var maps = CS2_SimpleAdmin.Instance.Config.DefaultMaps; + foreach (var map in maps) + AddOption(map, () => ExecuteChangeMap(admin, map, false)); + + var wsMaps = CS2_SimpleAdmin.Instance.Config.WorkshopMaps; + foreach (var map in wsMaps) + AddOption($"{map.Key} (WS)", () => ExecuteChangeMap(admin, map.Value?.ToString() ?? map.Key, true)); + + if (items.Count == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuTitle, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var action)) + action.Invoke(); + }, + true, freezePlayer: false, disableDeveloper: true); } private static void ExecuteChangeMap(CCSPlayerController admin, string mapName, bool workshop) diff --git a/CS2-SimpleAdmin/Menus/PlayersMenu.cs b/CS2-SimpleAdmin/Menus/PlayersMenu.cs index 19b76c2..56885a8 100644 --- a/CS2-SimpleAdmin/Menus/PlayersMenu.cs +++ b/CS2-SimpleAdmin/Menus/PlayersMenu.cs @@ -1,5 +1,7 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; +using Menu; +using Menu.Enums; using System.Web; namespace CS2_SimpleAdmin.Menus; @@ -26,30 +28,47 @@ public static class PlayersMenu OpenMenu(admin, menuName, onSelectAction, p => p.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE); } - public static void OpenMenu(CCSPlayerController admin, string menuName, Action onSelectAction, Func? enableFilter = null) + public static void OpenMenu( + CCSPlayerController admin, + string menuName, + Action onSelectAction, + Func? enableFilter = null) { - var menu = AdminMenu.CreateMenu(menuName); - var players = Helper.GetValidPlayersWithBots(); + List items = new(); + var optionMap = new Dictionary(); + int i = 0; foreach (var player in players) { - var playerName = player != null && player.PlayerName.Length > 26 ? player.PlayerName[..26] : player?.PlayerName; + if (player == null) continue; + var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var optionName = HttpUtility.HtmlEncode(playerName); - if (player != null && enableFilter != null && enableFilter(player) == false) - continue; - var enabled = admin.CanTarget(player); + if (enableFilter != null && !enableFilter(player)) continue; - if (optionName != null) - menu?.AddMenuOption(optionName, (_, _) => - { - if (player != null) onSelectAction.Invoke(admin, player); - }, - enabled == false); + bool enabled = admin.CanTarget(player); + if (!enabled) continue; // skip disabled options + + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(optionName)])); + optionMap[i++] = player; } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (items.Count == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuName, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && optionMap.TryGetValue(menu.Option, out var player)) + onSelectAction(admin, player); + }, + true, + freezePlayer: false, + disableDeveloper: true); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Menus/ReasonMenu.cs b/CS2-SimpleAdmin/Menus/ReasonMenu.cs index 5a1d6a2..1e81bef 100644 --- a/CS2-SimpleAdmin/Menus/ReasonMenu.cs +++ b/CS2-SimpleAdmin/Menus/ReasonMenu.cs @@ -1,15 +1,20 @@ using CounterStrikeSharp.API.Core; using CS2_SimpleAdmin.Models; using CS2_SimpleAdminApi; +using Menu; +using Menu.Enums; namespace CS2_SimpleAdmin.Menus; public static class ReasonMenu { - public static void OpenMenu(CCSPlayerController admin, PenaltyType penaltyType, string menuName, CCSPlayerController player, Action onSelectAction) + public static void OpenMenu( + CCSPlayerController admin, + PenaltyType penaltyType, + string menuName, + CCSPlayerController player, + Action onSelectAction) { - var menu = AdminMenu.CreateMenu(menuName); - var reasons = penaltyType switch { PenaltyType.Ban => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons, @@ -21,18 +26,38 @@ public static class ReasonMenu _ => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons }; - foreach (var reason in reasons) + var items = new List(); + for (int i = 0; i < reasons.Count; i++) { - menu?.AddMenuOption(reason, (_, _) => onSelectAction(admin, player, reason)); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(reasons[i])])); } - if (menu != null) AdminMenu.OpenMenu(admin, menu); + if (items.Count == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuName, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && menu.Option >= 0 && menu.Option < reasons.Count) + { + onSelectAction(admin, player, reasons[menu.Option]); + } + }, + true, + freezePlayer: false, + disableDeveloper: true); } - public static void OpenMenu(CCSPlayerController admin, PenaltyType penaltyType, string menuName, DisconnectedPlayer player, Action onSelectAction) + public static void OpenMenu( + CCSPlayerController admin, + PenaltyType penaltyType, + string menuName, + DisconnectedPlayer player, + Action onSelectAction) { - var menu = AdminMenu.CreateMenu(menuName); - var reasons = penaltyType switch { PenaltyType.Ban => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons, @@ -42,11 +67,28 @@ public static class ReasonMenu _ => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons }; - foreach (var reason in reasons) + var items = new List(); + for (int i = 0; i < reasons.Count; i++) { - menu?.AddMenuOption(reason, (_, _) => onSelectAction(admin, player, reason)); + items.Add(new MenuItem(MenuItemType.Button, [new MenuValue(reasons[i])])); } - - if (menu != null) AdminMenu.OpenMenu(admin, menu); + + if (items.Count == 0) return; + + CS2_SimpleAdmin.Menu?.ShowScrollableMenu( + admin, + menuName, + items, + (buttons, menu, selected) => + { + if (selected == null) return; + if (buttons == MenuButtons.Select && menu.Option >= 0 && menu.Option < reasons.Count) + { + onSelectAction(admin, player, reasons[menu.Option]); + } + }, + true, + freezePlayer: false, + disableDeveloper: true); } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/VERSION b/CS2-SimpleAdmin/VERSION index 58630bc..3136544 100644 --- a/CS2-SimpleAdmin/VERSION +++ b/CS2-SimpleAdmin/VERSION @@ -1 +1 @@ -1.7.7-alpha \ No newline at end of file +1.7.8-alpha \ No newline at end of file diff --git a/CS2-SimpleAdmin/Variables.cs b/CS2-SimpleAdmin/Variables.cs index 78db477..40f99b2 100644 --- a/CS2-SimpleAdmin/Variables.cs +++ b/CS2-SimpleAdmin/Variables.cs @@ -1,24 +1,23 @@ using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Capabilities; -using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CS2_SimpleAdmin.Models; using CS2_SimpleAdminApi; -using MenuManager; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using System.Collections.Concurrent; using CS2_SimpleAdmin.Managers; +using Menu; + 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 readonly string ConfigDirectory = Path.Combine(Application.RootDirectory, "configs/plugins/CS2-SimpleAdmin"); @@ -53,16 +52,12 @@ public partial class CS2_SimpleAdmin // Logger internal static ILogger? _logger; - // Memory Function (Game-related) - private static MemoryFunctionVoid? _cBasePlayerControllerSetPawnFunc; - // Menu API and Capabilities - internal static IMenuApi? MenuApi; - private static readonly PluginCapability MenuCapability = new("menu:nfcore"); + public static KitsuneMenu Menu { get; private set; } = null!; // Shared API internal static Api.CS2_SimpleAdminApi? SimpleAdminApi { get; set; } - + // Managers internal PermissionManager PermissionManager = new(Database); internal BanManager BanManager = new(Database); @@ -72,5 +67,5 @@ public partial class CS2_SimpleAdmin internal ChatManager ChatManager = new(); static string firstMessage = ""; - static string secondMessage = ""; + static string secondMessage = ""; } \ No newline at end of file diff --git a/CS2-SimpleAdmin/lang/en.json b/CS2-SimpleAdmin/lang/en.json index b3d87cf..a4f52f7 100644 --- a/CS2-SimpleAdmin/lang/en.json +++ b/CS2-SimpleAdmin/lang/en.json @@ -31,7 +31,7 @@ "sa_team_spec": "Spec", "sa_slap": "Slap", - "sa_slay": "slay", + "sa_slay": "Slay", "sa_kick": "Kick", "sa_ban": "Ban", "sa_gag": "Gag", diff --git a/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj b/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj index d675c66..d1d66f0 100644 --- a/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj +++ b/CS2-SimpleAdminApi/CS2-SimpleAdminApi.csproj @@ -9,7 +9,7 @@ - + diff --git a/CS2-SimpleAdminApi/ICS2-SimpleAdminApi.cs b/CS2-SimpleAdminApi/ICS2-SimpleAdminApi.cs index 32c0669..b86a489 100644 --- a/CS2-SimpleAdminApi/ICS2-SimpleAdminApi.cs +++ b/CS2-SimpleAdminApi/ICS2-SimpleAdminApi.cs @@ -10,7 +10,7 @@ public interface ICS2_SimpleAdminApi public static readonly PluginCapability PluginCapability = new("simpleadmin:api"); public PlayerInfo GetPlayerInfo(CCSPlayerController player); - + public string GetConnectionString(); public string GetServerAddress(); public int? GetServerId(); @@ -20,7 +20,7 @@ public interface ICS2_SimpleAdminApi public event Action? OnPlayerPenaltied; public event Action? OnPlayerPenaltiedAdded; public event Action? OnAdminShowActivity; - + public void IssuePenalty(CCSPlayerController player, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1); public void IssuePenalty(SteamID steamid, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1); public void LogCommand(CCSPlayerController? caller, string command); diff --git a/Modules/CS2-SimpleAdmin_RedisInform/RedisSubscriber.cs b/Modules/CS2-SimpleAdmin_RedisInform/RedisSubscriber.cs index f0f9575..cfbe7b1 100644 --- a/Modules/CS2-SimpleAdmin_RedisInform/RedisSubscriber.cs +++ b/Modules/CS2-SimpleAdmin_RedisInform/RedisSubscriber.cs @@ -51,7 +51,7 @@ public class RedisSubscriber(string serverIdentifier) if (deserializedMessage == null) return; - Server.NextFrame(() => CS2_SimpleAdmin_RedisInform.SharedApi?.ShowAdminActivity(deserializedMessage.MessageKey.ToString(), deserializedMessage.CallerName.ToString(), true, GetMessageArgsAsStringArray(deserializedMessage.MessageArgs))); + Server.NextWorldUpdate(() => CS2_SimpleAdmin_RedisInform.SharedApi?.ShowAdminActivity(deserializedMessage.MessageKey.ToString(), deserializedMessage.CallerName.ToString(), true, GetMessageArgsAsStringArray(deserializedMessage.MessageArgs))); }); } catch (Exception ex) diff --git a/README.md b/README.md index e2af2f3..8af244a 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,7 @@ ## ⚙️ Requirements **Ensure all the following dependencies are installed before proceeding** - [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp) -- [PlayerSettings](https://github.com/NickFox007/PlayerSettingsCS2) - Required by MenuManagerCS2 -- [AnyBaseLibCS2](https://github.com/NickFox007/AnyBaseLibCS2) - Required by PlayerSettings -- [MenuManagerCS2](https://github.com/NickFox007/MenuManagerCS2) +- KitsuneMenu (attached binary with release) - MySQL database ## 🚀 Getting Started