mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-11-07 12:07:05 +01:00
Migrate menus and votes to Panorama UI Kit
Replace MenuManagerCS2 with Panorama UI Kit for the admin menus and css_vote. Layout names (menu, vote, banner, toast) are configurable under MenuConfig and preloaded on startup; MenuType is removed and ConfigVersion bumped to 26. - Drop MenuManagerApi.dll and the old chat menu classes - Reference PanoramaUiKit.Shared.dll, bump CounterStrikeSharp to 1.0.376 - Add .editorconfig and CODING_CONVENTIONS.md, apply them codebase-wide - Remove the CS2-SimpleAdmin-docs site - Rewrite README for the fork
This commit is contained in:
parent
03a454b1b5
commit
460d8b2b85
112 changed files with 5559 additions and 36371 deletions
|
|
@ -1,75 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Menu;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class AdminMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin)
|
||||
{
|
||||
MenuManager.Instance.OpenMainMenu(admin);
|
||||
}
|
||||
|
||||
public static IMenu? CreateMenu(string title, Action<CCSPlayerController>? 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)
|
||||
// return;
|
||||
//
|
||||
// var localizer = CS2_SimpleAdmin._localizer;
|
||||
// if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/generic") == false)
|
||||
// {
|
||||
// admin.PrintToChat(localizer?["sa_prefix"] ??
|
||||
// "[SimpleAdmin] " +
|
||||
// (localizer?["sa_no_permission"] ?? "You do not have permissions to use this command")
|
||||
// );
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var menu = CreateMenu(localizer?["sa_title"] ?? "SimpleAdmin");
|
||||
// List<ChatMenuOptionData> options =
|
||||
// [
|
||||
// new(localizer?["sa_menu_players_manage"] ?? "Players Manage", () => ManagePlayersMenu.OpenMenu(admin)),
|
||||
// new(localizer?["sa_menu_server_manage"] ?? "Server Manage", () => ManageServerMenu.OpenMenu(admin)),
|
||||
// new(localizer?["sa_menu_fun_commands"] ?? "Fun Commands", () => FunActionsMenu.OpenMenu(admin)),
|
||||
// ];
|
||||
//
|
||||
// var customCommands = CS2_SimpleAdmin.Instance.Config.CustomServerCommands;
|
||||
// if (customCommands.Count > 0)
|
||||
// {
|
||||
// options.Add(new ChatMenuOptionData(localizer?["sa_menu_custom_commands"] ?? "Custom Commands", () => CustomCommandsMenu.OpenMenu(admin)));
|
||||
// }
|
||||
//
|
||||
// if (AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/root"))
|
||||
// options.Add(new ChatMenuOptionData(localizer?["sa_menu_admins_manage"] ?? "Admins Manage", () => ManageAdminsMenu.OpenMenu(admin)));
|
||||
//
|
||||
// foreach (var menuOptionData in options)
|
||||
// {
|
||||
// var menuName = menuOptionData.Name;
|
||||
// menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled);
|
||||
// }
|
||||
//
|
||||
// if (menu != null) OpenMenu(admin, menu);
|
||||
// }
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +0,0 @@
|
|||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public class ChatMenuOptionData(string name, Action action, bool disabled = false)
|
||||
{
|
||||
public readonly string Name = name;
|
||||
public readonly Action Action = action;
|
||||
public readonly bool Disabled = disabled;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class CustomCommandsMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin)
|
||||
{
|
||||
if (!admin.IsValid)
|
||||
return;
|
||||
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
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")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var menu = AdminMenu.CreateMenu(localizer?["sa_menu_custom_commands"] ?? "Custom Commands");
|
||||
List<ChatMenuOptionData> options = [];
|
||||
|
||||
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 (customCommand.ExecuteOnClient)
|
||||
admin.ExecuteClientCommandFromServer(customCommand.Command);
|
||||
else
|
||||
Server.ExecuteCommand(customCommand.Command);
|
||||
}));
|
||||
|
||||
foreach (var menuOptionData in options)
|
||||
{
|
||||
var menuName = menuOptionData.Name;
|
||||
menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action(); }, menuOptionData.Disabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CS2_SimpleAdmin.Models;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class DurationMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin, string menuName, CCSPlayerController player, Action<CCSPlayerController, CCSPlayerController, int> onSelectAction)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu(menuName);
|
||||
if (menu == null)
|
||||
return;
|
||||
|
||||
var durations = CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations;
|
||||
|
||||
// Capture admin and player to avoid closure issues
|
||||
var capturedAdmin = admin;
|
||||
var capturedPlayer = player;
|
||||
var capturedAction = onSelectAction;
|
||||
|
||||
foreach (var durationItem in durations)
|
||||
{
|
||||
var duration = durationItem.Duration; // Capture in local variable
|
||||
var name = durationItem.Name;
|
||||
|
||||
menu.AddMenuOption(name, (controller, option) =>
|
||||
{
|
||||
capturedAction(capturedAdmin, capturedPlayer, duration);
|
||||
});
|
||||
}
|
||||
|
||||
AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
public static void OpenMenu(CCSPlayerController admin, string menuName, DisconnectedPlayer player, Action<CCSPlayerController, DisconnectedPlayer, int> onSelectAction)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu(menuName);
|
||||
foreach (var durationItem in CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations)
|
||||
{
|
||||
menu?.AddMenuOption(durationItem.Name, (_, _) => { onSelectAction(admin, player, durationItem.Duration); });
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -264,4 +264,4 @@
|
|||
// {
|
||||
// CS2_SimpleAdmin.SetMoney(admin, player, money);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class ManageAdminsMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin)
|
||||
{
|
||||
if (!admin.IsValid)
|
||||
return;
|
||||
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
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")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var menu = AdminMenu.CreateMenu(localizer?["sa_menu_admins_manage"] ?? "Admins Manage");
|
||||
List<ChatMenuOptionData> options =
|
||||
[
|
||||
new(localizer?["sa_admin_add"] ?? "Add Admin",
|
||||
() => PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_admin_add"] ?? "Add Admin", AddAdminMenu)),
|
||||
new(localizer?["sa_admin_remove"] ?? "Remove Admin",
|
||||
() => PlayersMenu.OpenAdminPlayersMenu(admin, localizer?["sa_admin_remove"] ?? "Remove Admin", RemoveAdmin,
|
||||
player => player != admin && admin.CanTarget(player))),
|
||||
new(localizer?["sa_admin_reload"] ?? "Reload Admins", () => ReloadAdmins(admin))
|
||||
];
|
||||
|
||||
foreach (var menuOptionData in options)
|
||||
{
|
||||
var menuName = menuOptionData.Name;
|
||||
menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void AddAdminMenu(CCSPlayerController admin, CCSPlayerController player)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_admin_add"] ?? "Add Admin"}: {player.PlayerName}");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void AddAdmin(CCSPlayerController admin, CCSPlayerController player, string flag)
|
||||
{
|
||||
// TODO: Change default immunity?
|
||||
CS2_SimpleAdmin.AddAdmin(admin, player.SteamID.ToString(), player.PlayerName, flag, 10);
|
||||
}
|
||||
|
||||
private static void RemoveAdmin(CCSPlayerController admin, CCSPlayerController player)
|
||||
{
|
||||
CS2_SimpleAdmin.Instance.RemoveAdmin(admin, player.SteamID.ToString());
|
||||
}
|
||||
|
||||
private static void ReloadAdmins(CCSPlayerController admin)
|
||||
{
|
||||
CS2_SimpleAdmin.Instance.ReloadAdmins(admin);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using CS2_SimpleAdminApi;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class ManagePlayersMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin)
|
||||
{
|
||||
if (!admin.IsValid)
|
||||
return;
|
||||
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
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")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var menu = AdminMenu.CreateMenu(localizer?["sa_menu_players_manage"] ?? "Manage Players");
|
||||
List<ChatMenuOptionData> options = [];
|
||||
|
||||
// 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");
|
||||
|
||||
// TODO: Localize options
|
||||
// options added in order
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
if (hasKick)
|
||||
{
|
||||
options.Add(new ChatMenuOptionData(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", (a, p) => DurationMenu.OpenMenu(a, $"{localizer?["sa_warn"] ?? "Warn"}: {p.PlayerName}", p, WarnMenu))));
|
||||
|
||||
if (hasBan)
|
||||
options.Add(new ChatMenuOptionData(localizer?["sa_ban"] ?? "Ban", () =>
|
||||
PlayersMenu.OpenRealPlayersMenu(admin, localizer?["sa_ban"] ?? "Ban", (a, p) =>
|
||||
DurationMenu.OpenMenu(a, $"{localizer?["sa_ban"] ?? "Ban"}: {p.PlayerName}", p, 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", (a, p) => DurationMenu.OpenMenu(a, $"{localizer?["sa_gag"] ?? "Gag"}: {p.PlayerName}", p, 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", (a, p) => DurationMenu.OpenMenu(a, $"{localizer?["sa_mute"] ?? "Mute"}: {p.PlayerName}", p, 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", (a, p) => DurationMenu.OpenMenu(a, $"{localizer?["sa_silence"] ?? "Silence"}: {p.PlayerName}", p, 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)
|
||||
{
|
||||
var menuName = menuOptionData.Name;
|
||||
menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void SlapMenu(CCSPlayerController admin, CCSPlayerController player)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_slap"] ?? "Slap"}: {player.PlayerName}");
|
||||
List<ChatMenuOptionData> options =
|
||||
[
|
||||
// options added in order
|
||||
new("0 hp", () => ApplySlapAndKeepMenu(admin, player, 0)),
|
||||
new("1 hp", () => ApplySlapAndKeepMenu(admin, player, 1)),
|
||||
new("5 hp", () => ApplySlapAndKeepMenu(admin, player, 5)),
|
||||
new("10 hp", () => ApplySlapAndKeepMenu(admin, player, 10)),
|
||||
new("50 hp", () => ApplySlapAndKeepMenu(admin, player, 50)),
|
||||
new("100 hp", () => ApplySlapAndKeepMenu(admin, player, 100)),
|
||||
];
|
||||
|
||||
foreach (var menuOptionData in options)
|
||||
{
|
||||
var menuName = menuOptionData.Name;
|
||||
menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void ApplySlapAndKeepMenu(CCSPlayerController admin, CCSPlayerController player, int damage)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Slap(admin, player, damage);
|
||||
SlapMenu(admin, player);
|
||||
}
|
||||
|
||||
private static void Slay(CCSPlayerController admin, CCSPlayerController player)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Slay(admin, player);
|
||||
}
|
||||
|
||||
private static void KickMenu(CCSPlayerController admin, CCSPlayerController player)
|
||||
{
|
||||
ReasonMenu.OpenMenu(admin, PenaltyType.Kick,
|
||||
$"{CS2_SimpleAdmin._localizer?["sa_kick"] ?? "Kick"}: {player.PlayerName}", player, (_, _, reason) =>
|
||||
{
|
||||
if (player is { IsValid: true })
|
||||
Kick(admin, player, reason);
|
||||
});
|
||||
|
||||
// var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_kick"] ?? "Kick"}: {player?.PlayerName}");
|
||||
//
|
||||
// foreach (var option in CS2_SimpleAdmin.Instance.Config.MenuConfigs.KickReasons)
|
||||
// {
|
||||
// menu?.AddMenuOption(option, (_, _) =>
|
||||
// {
|
||||
// if (player is { IsValid: true })
|
||||
// Kick(admin, player, option);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void Kick(CCSPlayerController admin, CCSPlayerController player, string? reason)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Instance.Kick(admin, player, reason, admin.PlayerName);
|
||||
}
|
||||
|
||||
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) =>
|
||||
{
|
||||
if (player is { IsValid: true })
|
||||
Ban(admin, player, duration, reason);
|
||||
|
||||
CS2_SimpleAdmin.MenuApi?.CloseMenu(admin);
|
||||
});
|
||||
}
|
||||
|
||||
private static void Ban(CCSPlayerController admin, CCSPlayerController player, int duration, string reason)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Instance.Ban(admin, player, duration, reason, admin.PlayerName);
|
||||
}
|
||||
|
||||
private static void WarnMenu(CCSPlayerController admin, CCSPlayerController player, int duration)
|
||||
{
|
||||
ReasonMenu.OpenMenu(admin, PenaltyType.Warn,
|
||||
$"{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}");
|
||||
//
|
||||
// foreach (var option in CS2_SimpleAdmin.Instance.Config.MenuConfigs.WarnReasons)
|
||||
// {
|
||||
// menu?.AddMenuOption(option, (_, _) =>
|
||||
// {
|
||||
// if (player is { IsValid: true })
|
||||
// Warn(admin, player, duration, option);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void Warn(CCSPlayerController admin, CCSPlayerController player, int duration, string reason)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Instance.Warn(admin, player, duration, reason, admin.PlayerName);
|
||||
}
|
||||
|
||||
internal static void GagMenu(CCSPlayerController admin, CCSPlayerController player, int duration)
|
||||
{
|
||||
ReasonMenu.OpenMenu(admin, PenaltyType.Gag,
|
||||
$"{CS2_SimpleAdmin._localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player, (_, _, reason) =>
|
||||
{
|
||||
if (player is { IsValid: true })
|
||||
Gag(admin, player, duration, reason);
|
||||
});
|
||||
|
||||
// var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_gag"] ?? "Gag"}: {player?.PlayerName}");
|
||||
//
|
||||
// foreach (var option in CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons)
|
||||
// {
|
||||
// menu?.AddMenuOption(option, (_, _) =>
|
||||
// {
|
||||
// if (player is { IsValid: true })
|
||||
// Gag(admin, player, duration, option);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void Gag(CCSPlayerController admin, CCSPlayerController player, int duration, string reason)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Instance.Gag(admin, player, duration, reason);
|
||||
}
|
||||
|
||||
internal static void MuteMenu(CCSPlayerController admin, CCSPlayerController player, int duration)
|
||||
{
|
||||
ReasonMenu.OpenMenu(admin, PenaltyType.Mute,
|
||||
$"{CS2_SimpleAdmin._localizer?["sa_mute"] ?? "mute"}: {player.PlayerName}", player, (_, _, reason) =>
|
||||
{
|
||||
if (player is { IsValid: true })
|
||||
Mute(admin, player, duration, reason);
|
||||
});
|
||||
|
||||
// // TODO: Localize and make options in config?
|
||||
// var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_mute"] ?? "Mute"}: {player?.PlayerName}");
|
||||
//
|
||||
// foreach (var option in CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons)
|
||||
// {
|
||||
// menu?.AddMenuOption(option, (_, _) =>
|
||||
// {
|
||||
// if (player is { IsValid: true })
|
||||
// Mute(admin, player, duration, option);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void Mute(CCSPlayerController admin, CCSPlayerController player, int duration, string reason)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Instance.Mute(admin, player, duration, reason);
|
||||
}
|
||||
|
||||
internal static void SilenceMenu(CCSPlayerController admin, CCSPlayerController player, int duration)
|
||||
{
|
||||
ReasonMenu.OpenMenu(admin, PenaltyType.Silence,
|
||||
$"{CS2_SimpleAdmin._localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player, (_, _, reason) =>
|
||||
{
|
||||
if (player is { IsValid: true })
|
||||
Silence(admin, player, duration, reason);
|
||||
});
|
||||
|
||||
// // TODO: Localize and make options in config?
|
||||
// var menu = AdminMenu.CreateMenu($"{CS2_SimpleAdmin._localizer?["sa_silence"] ?? "Silence"}: {player?.PlayerName}");
|
||||
//
|
||||
// foreach (var option in CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons)
|
||||
// {
|
||||
// menu?.AddMenuOption(option, (_, _) =>
|
||||
// {
|
||||
// if (player is { IsValid: true })
|
||||
// Silence(admin, player, duration, option);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void Silence(CCSPlayerController admin, CCSPlayerController player, int duration, string reason)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.Instance.Silence(admin, player, duration, reason);
|
||||
}
|
||||
|
||||
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<ChatMenuOptionData> options =
|
||||
[
|
||||
new(CS2_SimpleAdmin._localizer?["sa_team_ct"] ?? "CT", () => ForceTeam(admin, player, "ct", CsTeam.CounterTerrorist)),
|
||||
new(CS2_SimpleAdmin._localizer?["sa_team_t"] ?? "T", () => ForceTeam(admin, player, "t", CsTeam.Terrorist)),
|
||||
new(CS2_SimpleAdmin._localizer?["sa_team_swap"] ?? "Swap", () => ForceTeam(admin, player, "swap", CsTeam.Spectator)),
|
||||
new(CS2_SimpleAdmin._localizer?["sa_team_spec"] ?? "Spec", () => ForceTeam(admin, player, "spec", CsTeam.Spectator)),
|
||||
];
|
||||
|
||||
foreach (var menuOptionData in options)
|
||||
{
|
||||
var menuName = menuOptionData.Name;
|
||||
menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void ForceTeam(CCSPlayerController admin, CCSPlayerController player, string teamName, CsTeam teamNum)
|
||||
{
|
||||
if (player is not { IsValid: true }) return;
|
||||
|
||||
CS2_SimpleAdmin.ChangeTeam(admin, player, teamName, teamNum, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class ManageServerMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin)
|
||||
{
|
||||
if (!admin.IsValid)
|
||||
return;
|
||||
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
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")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var menu = AdminMenu.CreateMenu(localizer?["sa_menu_server_manage"] ?? "Server Manage");
|
||||
List<ChatMenuOptionData> options = [];
|
||||
|
||||
// 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)
|
||||
{
|
||||
options.Add(new ChatMenuOptionData(localizer?["sa_menu_pluginsmanager_title"] ?? "Manage Plugins", () => admin.ExecuteClientCommandFromServer("css_pluginsmanager")));
|
||||
}
|
||||
|
||||
if (hasMap)
|
||||
{
|
||||
options.Add(new ChatMenuOptionData(localizer?["sa_changemap"] ?? "Change Map", () => ChangeMapMenu(admin)));
|
||||
}
|
||||
|
||||
options.Add(new ChatMenuOptionData(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 (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void ChangeMapMenu(CCSPlayerController admin)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu(CS2_SimpleAdmin._localizer?["sa_changemap"] ?? "Change Map");
|
||||
List<ChatMenuOptionData> options = [];
|
||||
|
||||
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)
|
||||
{
|
||||
var menuName = menuOptionData.Name;
|
||||
menu?.AddMenuOption(menuName, (_, _) => { menuOptionData.Action.Invoke(); }, menuOptionData.Disabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
private static void ExecuteChangeMap(CCSPlayerController admin, string mapName, bool workshop)
|
||||
{
|
||||
if (workshop)
|
||||
CS2_SimpleAdmin.Instance.ChangeWorkshopMap(admin, mapName);
|
||||
else
|
||||
CS2_SimpleAdmin.Instance.ChangeMap(admin, mapName);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,29 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Translations;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using PanoramaUiKit.Shared.Api;
|
||||
using PanoramaUiKit.Shared.Menus;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
/// <summary>
|
||||
/// Describes a menu and renders it through the Panorama UI Kit.
|
||||
/// Sub-menus are pushed on top of their parent, the kit draws the back button.
|
||||
/// </summary>
|
||||
public class MenuBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Bumped every time a menu is opened for a player, so an option can tell whether its action opened another one.
|
||||
/// </summary>
|
||||
private static readonly Dictionary<ulong, int> OpenCounters = [];
|
||||
|
||||
private readonly string _title;
|
||||
private readonly CCSPlayerController? _player;
|
||||
private readonly IStringLocalizer? _localizer;
|
||||
private readonly List<MenuOption> _options = [];
|
||||
private MenuBuilder? _parentMenu;
|
||||
private Action<CCSPlayerController>? _backAction;
|
||||
private Action<CCSPlayerController>? _resetAction;
|
||||
private bool _isSubMenu;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for player-localized menu with translation key
|
||||
|
|
@ -24,7 +36,7 @@ public class MenuBuilder
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for static title (backward compatibility)
|
||||
/// Constructor for static title
|
||||
/// </summary>
|
||||
public MenuBuilder(string title)
|
||||
{
|
||||
|
|
@ -33,21 +45,6 @@ public class MenuBuilder
|
|||
_localizer = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the localized title for the player
|
||||
/// </summary>
|
||||
private string GetLocalizedTitle()
|
||||
{
|
||||
if (_player != null && _localizer != null)
|
||||
{
|
||||
using (new WithTemporaryCulture(_player.GetLanguage()))
|
||||
{
|
||||
return _localizer[_title];
|
||||
}
|
||||
}
|
||||
return _title;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu option with an action.
|
||||
/// </summary>
|
||||
|
|
@ -56,7 +53,9 @@ public class MenuBuilder
|
|||
/// <param name="disabled">Whether the option is disabled</param>
|
||||
/// <param name="permission">Required permission</param>
|
||||
/// <param name="isTranslationKey">If true, name is a translation key to be localized</param>
|
||||
public MenuBuilder AddOption(string name, Action<CCSPlayerController> action, bool disabled = false, string? permission = null, bool isTranslationKey = false)
|
||||
/// <param name="keepOpen">If true, the menu stays open after the action</param>
|
||||
public MenuBuilder AddOption(string name, Action<CCSPlayerController> action, bool disabled = false, string? permission = null,
|
||||
bool isTranslationKey = false, bool keepOpen = false)
|
||||
{
|
||||
_options.Add(new MenuOption
|
||||
{
|
||||
|
|
@ -64,46 +63,18 @@ public class MenuBuilder
|
|||
Action = action,
|
||||
Disabled = disabled,
|
||||
Permission = permission,
|
||||
IsTranslationKey = isTranslationKey
|
||||
IsTranslationKey = isTranslationKey,
|
||||
KeepOpen = keepOpen
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the localized name for a menu option
|
||||
/// </summary>
|
||||
private string GetLocalizedOptionName(MenuOption option)
|
||||
{
|
||||
if (option.IsTranslationKey && _player != null && _localizer != null)
|
||||
{
|
||||
using (new WithTemporaryCulture(_player.GetLanguage()))
|
||||
{
|
||||
return _localizer[option.Name];
|
||||
}
|
||||
}
|
||||
return option.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu option that opens a submenu.
|
||||
/// </summary>
|
||||
public MenuBuilder AddSubMenu(string name, Func<MenuBuilder> subMenuFactory, bool disabled = false, string? permission = null)
|
||||
{
|
||||
_options.Add(new MenuOption
|
||||
{
|
||||
Name = name,
|
||||
Action = player =>
|
||||
{
|
||||
var subMenu = subMenuFactory();
|
||||
subMenu.SetParent(this);
|
||||
// Automatically add back button to submenu
|
||||
subMenu.WithBackButton();
|
||||
subMenu.OpenMenu(player);
|
||||
},
|
||||
Disabled = disabled,
|
||||
Permission = permission
|
||||
});
|
||||
return this;
|
||||
return AddSubMenu(name, _ => subMenuFactory(), disabled, permission);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -114,14 +85,7 @@ public class MenuBuilder
|
|||
_options.Add(new MenuOption
|
||||
{
|
||||
Name = name,
|
||||
Action = player =>
|
||||
{
|
||||
var subMenu = subMenuFactory(player);
|
||||
subMenu.SetParent(this);
|
||||
// Automatically add back button to submenu
|
||||
subMenu.WithBackButton();
|
||||
subMenu.OpenMenu(player);
|
||||
},
|
||||
SubMenuFactory = subMenuFactory,
|
||||
Disabled = disabled,
|
||||
Permission = permission
|
||||
});
|
||||
|
|
@ -129,66 +93,50 @@ public class MenuBuilder
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a back button to return to the previous menu.
|
||||
/// Opens this menu on top of the current one, with a back button.
|
||||
/// </summary>
|
||||
public MenuBuilder WithBackButton()
|
||||
{
|
||||
if (_parentMenu != null)
|
||||
{
|
||||
_backAction = player => _parentMenu.OpenMenu(player);
|
||||
|
||||
// Add back option at the end of menu
|
||||
// AddOption(backButtonText, _backAction);
|
||||
}
|
||||
_isSubMenu = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the parent menu (for navigation).
|
||||
/// </summary>
|
||||
private void SetParent(MenuBuilder parent)
|
||||
{
|
||||
_parentMenu = parent;
|
||||
_backAction = player => _parentMenu.OpenMenu(player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the menu for a player.
|
||||
/// </summary>
|
||||
/// <param name="player">The player to open the menu for.</param>
|
||||
public void OpenMenu(CCSPlayerController player)
|
||||
{
|
||||
if (!player.IsValid) return;
|
||||
|
||||
// Get localized title
|
||||
var localizedTitle = GetLocalizedTitle();
|
||||
|
||||
// Use MenuManager dependency
|
||||
var menu = Helper.CreateMenu(localizedTitle, _backAction);
|
||||
if (menu == null) return;
|
||||
|
||||
foreach (var option in _options)
|
||||
if (!player.IsValid)
|
||||
{
|
||||
// Check permissions if required
|
||||
if (!string.IsNullOrEmpty(option.Permission))
|
||||
{
|
||||
var steamId = new CounterStrikeSharp.API.Modules.Entities.SteamID(player.SteamID);
|
||||
if (!CounterStrikeSharp.API.Modules.Admin.AdminManager.PlayerHasPermissions(steamId, option.Permission))
|
||||
{
|
||||
continue; // Skip option if player doesn't have permission
|
||||
}
|
||||
}
|
||||
|
||||
// Get localized option name
|
||||
var localizedName = GetLocalizedOptionName(option);
|
||||
|
||||
menu.AddMenuOption(localizedName, (menuPlayer, menuOption) =>
|
||||
{
|
||||
option.Action?.Invoke(menuPlayer);
|
||||
}, option.Disabled);
|
||||
return;
|
||||
}
|
||||
|
||||
menu.Open(player);
|
||||
IPanoramaUiKit? kit = UiKit.Instance;
|
||||
if (kit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MenuOptions menu = Build(player);
|
||||
BumpOpenCounter(player);
|
||||
|
||||
if (_isSubMenu)
|
||||
{
|
||||
kit.Menus.Push(player, menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
kit.Menus.Open(player, menu);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes any SimpleAdmin menu open for the player.
|
||||
/// </summary>
|
||||
public static void CloseMenu(CCSPlayerController player)
|
||||
{
|
||||
UiKit.Instance?.Menus.Close(player, UiKit.MenuLayout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -201,26 +149,101 @@ public class MenuBuilder
|
|||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a reset action for the menu.
|
||||
/// </summary>
|
||||
/// <param name="resetAction">The action to execute on reset.</param>
|
||||
/// <returns>This MenuBuilder instance for chaining.</returns>
|
||||
public MenuBuilder WithResetAction(Action<CCSPlayerController> resetAction)
|
||||
private MenuOptions Build(CCSPlayerController player)
|
||||
{
|
||||
_resetAction = resetAction;
|
||||
return this;
|
||||
List<MenuEntry> entries = [];
|
||||
SteamID steamId = new SteamID(player.SteamID);
|
||||
|
||||
foreach (MenuOption option in _options)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(option.Permission) && !AdminManager.PlayerHasPermissions(steamId, option.Permission))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string label = GetLocalizedOptionName(option);
|
||||
MenuEntry entry;
|
||||
|
||||
if (option.SubMenuFactory != null)
|
||||
{
|
||||
Func<CCSPlayerController, MenuBuilder> subMenuFactory = option.SubMenuFactory;
|
||||
entry = MenuEntry.Open(label, menuPlayer =>
|
||||
{
|
||||
BumpOpenCounter(menuPlayer);
|
||||
return subMenuFactory(menuPlayer).Build(menuPlayer);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = MenuEntry.Button(label, menuPlayer => RunOption(option, menuPlayer));
|
||||
}
|
||||
|
||||
if (option.Disabled)
|
||||
{
|
||||
entry = entry with { Disabled = true };
|
||||
}
|
||||
|
||||
entries.Add(entry);
|
||||
}
|
||||
|
||||
return new MenuOptions
|
||||
{
|
||||
Layout = UiKit.MenuLayout,
|
||||
Title = GetLocalizedTitle(),
|
||||
Entries = entries
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets a custom back action for the menu.
|
||||
/// Runs the option, then closes the menu unless the option keeps it open or its action opened another menu.
|
||||
/// </summary>
|
||||
/// <param name="backAction">The action to execute when going back (nullable).</param>
|
||||
/// <returns>This MenuBuilder instance for chaining.</returns>
|
||||
public MenuBuilder WithBackAction(Action<CCSPlayerController>? backAction)
|
||||
private static void RunOption(MenuOption option, CCSPlayerController player)
|
||||
{
|
||||
_backAction = backAction;
|
||||
return this;
|
||||
int counterBefore = GetOpenCounter(player);
|
||||
|
||||
option.Action?.Invoke(player);
|
||||
|
||||
if (!option.KeepOpen && player.IsValid && GetOpenCounter(player) == counterBefore)
|
||||
{
|
||||
CloseMenu(player);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetOpenCounter(CCSPlayerController player)
|
||||
{
|
||||
OpenCounters.TryGetValue(player.SteamID, out int counter);
|
||||
return counter;
|
||||
}
|
||||
|
||||
private static void BumpOpenCounter(CCSPlayerController player)
|
||||
{
|
||||
OpenCounters[player.SteamID] = GetOpenCounter(player) + 1;
|
||||
}
|
||||
|
||||
private string GetLocalizedTitle()
|
||||
{
|
||||
if (_player == null || _localizer == null)
|
||||
{
|
||||
return _title;
|
||||
}
|
||||
|
||||
using (new WithTemporaryCulture(_player.GetLanguage()))
|
||||
{
|
||||
return _localizer[_title];
|
||||
}
|
||||
}
|
||||
|
||||
private string GetLocalizedOptionName(MenuOption option)
|
||||
{
|
||||
if (!option.IsTranslationKey || _player == null || _localizer == null)
|
||||
{
|
||||
return option.Name;
|
||||
}
|
||||
|
||||
using (new WithTemporaryCulture(_player.GetLanguage()))
|
||||
{
|
||||
return _localizer[option.Name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,8 +254,9 @@ public class MenuOption
|
|||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public Action<CCSPlayerController>? Action { get; set; }
|
||||
public Func<CCSPlayerController, MenuBuilder>? SubMenuFactory { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public string? Permission { get; set; }
|
||||
public bool IsTranslationKey { get; set; }
|
||||
public bool KeepOpen { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -2,6 +2,7 @@ using CounterStrikeSharp.API.Core;
|
|||
using CounterStrikeSharp.API.Core.Translations;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
|
|
@ -125,7 +126,11 @@ public class MenuManager
|
|||
/// <param name="menuId">The menu to unregister.</param>
|
||||
public void UnregisterMenu(string categoryId, string menuId)
|
||||
{
|
||||
if (!_menuCategories.TryGetValue(categoryId, out var category)) return;
|
||||
if (!_menuCategories.TryGetValue(categoryId, out MenuCategory? category))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
category.MenuFactories.Remove(menuId);
|
||||
_menuCategories[categoryId].MenuNames.Remove(menuId);
|
||||
_menuCategories[categoryId].MenuPermissions.Remove(menuId);
|
||||
|
|
@ -139,16 +144,21 @@ public class MenuManager
|
|||
/// <returns>A MenuBuilder instance for the main menu.</returns>
|
||||
public MenuBuilder CreateMainMenu(CCSPlayerController player)
|
||||
{
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
var mainMenu = new MenuBuilder("sa_title", player, localizer);
|
||||
IStringLocalizer? localizer = CS2_SimpleAdmin._localizer;
|
||||
MenuBuilder mainMenu = new MenuBuilder("sa_title", player, localizer);
|
||||
|
||||
foreach (var category in _menuCategories.Values)
|
||||
foreach (MenuCategory category in _menuCategories.Values)
|
||||
{
|
||||
if (category.MenuFactories.Count <= 0) continue;
|
||||
// Check category permissions
|
||||
var steamId = new SteamID(player.SteamID);
|
||||
if (!AdminManager.PlayerHasPermissions(steamId, category.Permission))
|
||||
if (category.MenuFactories.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Check category permissions
|
||||
SteamID steamId = new SteamID(player.SteamID);
|
||||
if (!AdminManager.PlayerHasPermissions(steamId, category.Permission))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get localized category name for this player
|
||||
// If category has a module localizer, use it; otherwise use main plugin localizer
|
||||
|
|
@ -181,7 +191,7 @@ public class MenuManager
|
|||
/// <returns>A MenuBuilder instance for the category menu.</returns>
|
||||
private MenuBuilder CreateCategoryMenu(MenuCategory category, CCSPlayerController player)
|
||||
{
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
IStringLocalizer? localizer = CS2_SimpleAdmin._localizer;
|
||||
|
||||
// Get localized category name for this player
|
||||
// If category has a module localizer, use it; otherwise use main plugin localizer
|
||||
|
|
@ -198,18 +208,22 @@ public class MenuManager
|
|||
}
|
||||
}
|
||||
|
||||
var categoryMenu = new MenuBuilder(localizedCategoryName);
|
||||
MenuBuilder categoryMenu = new MenuBuilder(localizedCategoryName);
|
||||
|
||||
foreach (var kvp in category.MenuFactories)
|
||||
foreach (KeyValuePair<string, Func<CCSPlayerController, MenuBuilder>> kvp in category.MenuFactories)
|
||||
{
|
||||
var menuId = kvp.Key;
|
||||
var menuFactory = kvp.Value;
|
||||
var menuName = category.MenuNames.TryGetValue(menuId, out var name) ? name : menuId;
|
||||
var permission = category.MenuPermissions.TryGetValue(menuId, out var perm) ? perm : null;
|
||||
var commandName = category.MenuCommandNames.TryGetValue(menuId, out var cmd) ? cmd : null;
|
||||
string menuId = kvp.Key;
|
||||
Func<CCSPlayerController, MenuBuilder> menuFactory = kvp.Value;
|
||||
if (!category.MenuNames.TryGetValue(menuId, out string? menuName))
|
||||
{
|
||||
menuName = menuId;
|
||||
}
|
||||
|
||||
category.MenuPermissions.TryGetValue(menuId, out string? permission);
|
||||
category.MenuCommandNames.TryGetValue(menuId, out string? commandName);
|
||||
|
||||
// Check permissions with command override support
|
||||
var steamId = new SteamID(player.SteamID);
|
||||
SteamID steamId = new SteamID(player.SteamID);
|
||||
|
||||
// If commandName is provided, check for permission overrides
|
||||
if (!string.IsNullOrEmpty(commandName))
|
||||
|
|
@ -219,7 +233,7 @@ public class MenuManager
|
|||
// Check if command has overridden permissions
|
||||
if (AdminManager.CommandIsOverriden(commandName))
|
||||
{
|
||||
var overriddenPermission = AdminManager.GetPermissionOverrides(commandName);
|
||||
string[] overriddenPermission = AdminManager.GetPermissionOverrides(commandName);
|
||||
hasPermission = AdminManager.PlayerHasPermissions(steamId, overriddenPermission);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(permission))
|
||||
|
|
@ -234,13 +248,17 @@ public class MenuManager
|
|||
}
|
||||
|
||||
if (!hasPermission)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Fallback to standard permission check if no commandName provided
|
||||
else if (!string.IsNullOrEmpty(permission))
|
||||
{
|
||||
if (!AdminManager.PlayerHasPermissions(steamId, permission))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Get localized menu name for this player
|
||||
|
|
@ -248,7 +266,7 @@ public class MenuManager
|
|||
string localizedMenuName;
|
||||
using (new WithTemporaryCulture(player.GetLanguage()))
|
||||
{
|
||||
if (category.MenuLocalizers.TryGetValue(menuId, out var menuLocalizer))
|
||||
if (category.MenuLocalizers.TryGetValue(menuId, out IStringLocalizer? menuLocalizer))
|
||||
{
|
||||
// Menu has its own module localizer
|
||||
localizedMenuName = menuLocalizer[menuName] ?? menuName;
|
||||
|
|
@ -278,9 +296,9 @@ public class MenuManager
|
|||
/// <param name="player">The player to open the menu for.</param>
|
||||
public void OpenMainMenu(CCSPlayerController player)
|
||||
{
|
||||
var localizer = CS2_SimpleAdmin._localizer;
|
||||
|
||||
var steamId = new SteamID(player.SteamID);
|
||||
IStringLocalizer? localizer = CS2_SimpleAdmin._localizer;
|
||||
|
||||
SteamID steamId = new SteamID(player.SteamID);
|
||||
if (!AdminManager.PlayerHasPermissions(steamId, "@css/generic"))
|
||||
{
|
||||
player.PrintToChat(localizer?["sa_prefix"] ?? "[SimpleAdmin] " +
|
||||
|
|
@ -303,17 +321,6 @@ public class MenuManager
|
|||
// RegisterCategory("fun", "sa_menu_fun_commands", "@css/generic");
|
||||
RegisterCategory("admin", "sa_menu_admins_manage", "@css/root");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public method for creating category menus (for API usage).
|
||||
/// </summary>
|
||||
/// <param name="category">The menu category to create.</param>
|
||||
/// <param name="player">The player to create the menu for.</param>
|
||||
/// <returns>A MenuBuilder instance for the category menu.</returns>
|
||||
public MenuBuilder CreateCategoryMenuPublic(MenuCategory category, CCSPlayerController player)
|
||||
{
|
||||
return CreateCategoryMenu(category, player);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using System.Web;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class PlayersMenu
|
||||
{
|
||||
public static void OpenRealPlayersMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||
{
|
||||
OpenMenu(admin, menuName, onSelectAction, p => !p.IsBot);
|
||||
}
|
||||
|
||||
public static void OpenAdminPlayersMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController?, bool>? enableFilter = null)
|
||||
{
|
||||
OpenMenu(admin, menuName, onSelectAction, p => AdminManager.GetPlayerAdminData(p)?.Flags.Count > 0);
|
||||
}
|
||||
|
||||
public static void OpenAliveMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||
{
|
||||
OpenMenu(admin, menuName, onSelectAction, p => p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE);
|
||||
}
|
||||
|
||||
public static void OpenDeadMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController?, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||
{
|
||||
OpenMenu(admin, menuName, onSelectAction, p => p.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE);
|
||||
}
|
||||
|
||||
public static void OpenMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu(menuName);
|
||||
|
||||
var players = Helper.GetValidPlayersWithBots();
|
||||
|
||||
foreach (var player in players)
|
||||
{
|
||||
var playerName = player != null && player.PlayerName.Length > 26 ? player.PlayerName[..26] : player?.PlayerName;
|
||||
|
||||
var optionName = HttpUtility.HtmlEncode(playerName);
|
||||
if (player != null && enableFilter != null && !enableFilter(player))
|
||||
continue;
|
||||
|
||||
var enabled = admin.CanTarget(player);
|
||||
var capturedPlayer = player; // Capture in local variable to avoid closure issues
|
||||
|
||||
if (optionName != null)
|
||||
menu?.AddMenuOption(optionName, (controller, option) =>
|
||||
{
|
||||
if (capturedPlayer != null) onSelectAction.Invoke(admin, capturedPlayer);
|
||||
},
|
||||
!enabled);
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CS2_SimpleAdmin.Models;
|
||||
using CS2_SimpleAdminApi;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
public static class ReasonMenu
|
||||
{
|
||||
public static void OpenMenu(CCSPlayerController admin, PenaltyType penaltyType, string menuName, CCSPlayerController player, Action<CCSPlayerController, CCSPlayerController, string> onSelectAction)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu(menuName);
|
||||
|
||||
var reasons = penaltyType switch
|
||||
{
|
||||
PenaltyType.Ban => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons,
|
||||
PenaltyType.Kick => CS2_SimpleAdmin.Instance.Config.MenuConfigs.KickReasons,
|
||||
PenaltyType.Mute => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons,
|
||||
PenaltyType.Warn => CS2_SimpleAdmin.Instance.Config.MenuConfigs.WarnReasons,
|
||||
PenaltyType.Gag => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons,
|
||||
PenaltyType.Silence => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons,
|
||||
_ => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons
|
||||
};
|
||||
|
||||
foreach (var reason in reasons)
|
||||
{
|
||||
menu?.AddMenuOption(reason, (_, _) => onSelectAction(admin, player, reason));
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
|
||||
public static void OpenMenu(CCSPlayerController admin, PenaltyType penaltyType, string menuName, DisconnectedPlayer player, Action<CCSPlayerController, DisconnectedPlayer, string> onSelectAction)
|
||||
{
|
||||
var menu = AdminMenu.CreateMenu(menuName);
|
||||
|
||||
var reasons = penaltyType switch
|
||||
{
|
||||
PenaltyType.Ban => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons,
|
||||
PenaltyType.Kick => CS2_SimpleAdmin.Instance.Config.MenuConfigs.KickReasons,
|
||||
PenaltyType.Mute => CS2_SimpleAdmin.Instance.Config.MenuConfigs.MuteReasons,
|
||||
PenaltyType.Warn => CS2_SimpleAdmin.Instance.Config.MenuConfigs.WarnReasons,
|
||||
_ => CS2_SimpleAdmin.Instance.Config.MenuConfigs.BanReasons
|
||||
};
|
||||
|
||||
foreach (var reason in reasons)
|
||||
{
|
||||
menu?.AddMenuOption(reason, (_, _) => onSelectAction(admin, player, reason));
|
||||
}
|
||||
|
||||
if (menu != null) AdminMenu.OpenMenu(admin, menu);
|
||||
}
|
||||
}
|
||||
81
CS2-SimpleAdmin/Menus/UiKit.cs
Normal file
81
CS2-SimpleAdmin/Menus/UiKit.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using CounterStrikeSharp.API.Core.Capabilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PanoramaUiKit.Shared.Api;
|
||||
using PanoramaUiKit.Shared.Banners;
|
||||
using PanoramaUiKit.Shared.Common;
|
||||
using PanoramaUiKit.Shared.Menus;
|
||||
using PanoramaUiKit.Shared.Toasts;
|
||||
using PanoramaUiKit.Shared.Votes;
|
||||
|
||||
namespace CS2_SimpleAdmin.Menus;
|
||||
|
||||
/// <summary>
|
||||
/// Access to the Panorama UI Kit plugin and the layouts SimpleAdmin draws on.
|
||||
/// </summary>
|
||||
internal static class UiKit
|
||||
{
|
||||
private static readonly PluginCapability<IPanoramaUiKit> Capability = new(IPanoramaUiKit.CapabilityName);
|
||||
|
||||
internal static MenuLayout MenuLayout { get; private set; } = new() { Name = "uikit_menu" };
|
||||
|
||||
internal static VoteLayout VoteLayout { get; private set; } = new() { Name = "uikit_vote" };
|
||||
|
||||
internal static BannerLayout BannerLayout { get; private set; } = new() { Name = "uikit_banner" };
|
||||
|
||||
internal static ToastLayout ToastLayout { get; private set; } = new() { Name = "uikit_toast" };
|
||||
|
||||
/// <summary>
|
||||
/// Resolved on every use so a hot reload of the kit is picked up.
|
||||
/// </summary>
|
||||
internal static IPanoramaUiKit? Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Capability.Get();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Configure(MenuConfig config)
|
||||
{
|
||||
MenuLayout = new MenuLayout { Name = config.MenuLayout };
|
||||
VoteLayout = new VoteLayout { Name = config.VoteLayout };
|
||||
BannerLayout = new BannerLayout { Name = config.BannerLayout };
|
||||
ToastLayout = new ToastLayout { Name = config.ToastLayout };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns the layouts up front: creating one on first use sends the client one big burst.
|
||||
/// </summary>
|
||||
internal static bool Preload(ILogger logger)
|
||||
{
|
||||
IPanoramaUiKit? kit = Instance;
|
||||
if (kit == null)
|
||||
{
|
||||
logger.LogError("Panorama UI Kit not found: install PanoramaUiKit and shared/PanoramaUiKit.Shared.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kit.Version != IPanoramaUiKit.ApiVersion)
|
||||
{
|
||||
logger.LogWarning("Panorama UI Kit API v{Running}, SimpleAdmin built against v{Built}.", kit.Version, IPanoramaUiKit.ApiVersion);
|
||||
}
|
||||
|
||||
UiLayout[] layouts = [MenuLayout, VoteLayout, BannerLayout, ToastLayout];
|
||||
foreach (UiLayout layout in layouts)
|
||||
{
|
||||
if (!kit.Preload(layout))
|
||||
{
|
||||
logger.LogError("Layout {Layout} was refused, see the Panorama UI Kit log.", layout);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue