using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Commands; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands.Targeting; using CounterStrikeSharp.API.Modules.Entities; using CS2_SimpleAdmin.Managers; using CS2_SimpleAdmin.Menus; using CS2_SimpleAdminApi; using Microsoft.Extensions.Localization; namespace CS2_SimpleAdmin.Api; public class CS2_SimpleAdminApi : ICS2_SimpleAdminApi { public event Action? OnSimpleAdminReady; public void OnSimpleAdminReadyEvent() => OnSimpleAdminReady?.Invoke(); public PlayerInfo GetPlayerInfo(CCSPlayerController player) { return !player.UserId.HasValue ? throw new KeyNotFoundException("Player with specific UserId not found") : CS2_SimpleAdmin.PlayersInfo[player.SteamID]; } public string GetConnectionString() => CS2_SimpleAdmin.Instance.DbConnectionString; public string GetServerAddress() => CS2_SimpleAdmin.IpAddress; public int? GetServerId() => CS2_SimpleAdmin.ServerId; public Dictionary> GetPlayerMuteStatus( CCSPlayerController player) { return PlayerPenaltyManager.GetAllPlayerPenalties(player.Slot); } public event Action? OnPlayerPenaltied; public event Action? OnPlayerPenaltiedAdded; public event Action? OnAdminShowActivity; public event Action? OnAdminToggleSilent; public void OnPlayerPenaltiedEvent(PlayerInfo player, PlayerInfo? admin, PenaltyType penaltyType, string reason, int duration, int? penaltyId) => OnPlayerPenaltied?.Invoke(player, admin, penaltyType, reason, duration, penaltyId, CS2_SimpleAdmin.ServerId); public void OnPlayerPenaltiedAddedEvent(SteamID player, PlayerInfo? admin, PenaltyType penaltyType, string reason, int duration, int? penaltyId) => OnPlayerPenaltiedAdded?.Invoke(player, admin, penaltyType, reason, duration, penaltyId, CS2_SimpleAdmin.ServerId); public void OnAdminShowActivityEvent(string messageKey, string? callerName = null, bool dontPublish = false, params object[] messageArgs) => OnAdminShowActivity?.Invoke(messageKey, callerName, dontPublish, messageArgs); public void OnAdminToggleSilentEvent(int slot, bool status) => OnAdminToggleSilent?.Invoke(slot, status); public void IssuePenalty(CCSPlayerController player, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1) { switch (penaltyType) { case PenaltyType.Ban: { CS2_SimpleAdmin.Instance.Ban(admin, player, duration, reason); break; } case PenaltyType.Kick: { CS2_SimpleAdmin.Instance.Kick(admin, player, reason); break; } case PenaltyType.Gag: { CS2_SimpleAdmin.Instance.Gag(admin, player, duration, reason); break; } case PenaltyType.Mute: { CS2_SimpleAdmin.Instance.Mute(admin, player, duration, reason); break; } case PenaltyType.Silence: { CS2_SimpleAdmin.Instance.Silence(admin, player, duration, reason); break; } case PenaltyType.Warn: { CS2_SimpleAdmin.Instance.Warn(admin, player, duration, reason); break; } default: throw new ArgumentOutOfRangeException(nameof(penaltyType), penaltyType, null); } } public void IssuePenalty(SteamID steamid, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1) { switch (penaltyType) { case PenaltyType.Ban: { CS2_SimpleAdmin.Instance.AddBan(admin, steamid, duration, reason); break; } case PenaltyType.Gag: { CS2_SimpleAdmin.Instance.AddGag(admin, steamid, duration, reason); break; } case PenaltyType.Mute: { CS2_SimpleAdmin.Instance.AddMute(admin, steamid, duration, reason); break; } case PenaltyType.Silence: { CS2_SimpleAdmin.Instance.AddSilence(admin, steamid, duration, reason); break; } case PenaltyType.Warn: { CS2_SimpleAdmin.Instance.AddWarn(admin, steamid, duration, reason); break; } default: throw new ArgumentOutOfRangeException(nameof(penaltyType), penaltyType, null); } } public void LogCommand(CCSPlayerController? caller, string command) { Helper.LogCommand(caller, command); } public void LogCommand(CCSPlayerController? caller, CommandInfo command) { Helper.LogCommand(caller, command); } public bool IsAdminSilent(CCSPlayerController player) { return CS2_SimpleAdmin.SilentPlayers.Contains(player.Slot); } public HashSet ListSilentAdminsSlots() { return CS2_SimpleAdmin.SilentPlayers; } public void RegisterCommand(string name, string? description, CommandInfo.CommandCallback callback) { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Command name cannot be null or empty.", nameof(name)); ArgumentNullException.ThrowIfNull(callback); var definition = new CommandDefinition(name, description ?? "No description", callback); if (!RegisterCommands._commandDefinitions.TryGetValue(name, out var list)) { list = new List(); RegisterCommands._commandDefinitions[name] = list; } list.Add(definition); } public void UnRegisterCommand(string commandName) { var definitions = RegisterCommands._commandDefinitions[commandName]; if (definitions.Count == 0) return; foreach (var definition in definitions) { CS2_SimpleAdmin.Instance.RemoveCommand(commandName, definition.Callback); } } public TargetResult? GetTarget(CommandInfo command) { return CS2_SimpleAdmin.GetTarget(command); } public void ShowAdminActivity(string messageKey, string? callerName = null, bool dontPublish = false, params object[] messageArgs) { Helper.ShowAdminActivity(messageKey, callerName, dontPublish, messageArgs); } public void ShowAdminActivityTranslated(string translatedMessage, string? callerName = null, bool dontPublish = false) { Helper.ShowAdminActivityTranslated(translatedMessage, callerName, dontPublish); } public void ShowAdminActivityLocalized(object moduleLocalizer, string messageKey, string? callerName = null, bool dontPublish = false, params object[] messageArgs) { if (moduleLocalizer is not IStringLocalizer localizer) throw new InvalidOperationException("moduleLocalizer must be an IStringLocalizer instance"); Helper.ShowAdminActivityLocalized(localizer, messageKey, callerName, dontPublish, messageArgs); } public void RegisterMenuCategory(string categoryId, string categoryName, string permission = "@css/generic") { Menus.MenuManager.Instance.RegisterCategory(categoryId, categoryName, permission); } public void RegisterMenuCategory(string categoryId, string categoryNameKey, string permission, object moduleLocalizer) { if (moduleLocalizer is not IStringLocalizer localizer) throw new InvalidOperationException("moduleLocalizer must be an IStringLocalizer instance"); Menus.MenuManager.Instance.RegisterCategory(categoryId, categoryNameKey, permission, localizer); } public void RegisterMenu(string categoryId, string menuId, string menuName, Func menuFactory, string? permission = null, string? commandName = null) { Menus.MenuManager.Instance.RegisterMenu(categoryId, menuId, menuName, BuilderFactory, permission, commandName); return; MenuBuilder BuilderFactory(CCSPlayerController player) { if (menuFactory(player) is not MenuBuilder menuBuilder) throw new InvalidOperationException("Menu factory must return MenuBuilder"); // Dodaj automatyczną obsługę przycisku 'Wróć' menuBuilder.WithBackAction(p => { if (Menus.MenuManager.Instance.GetMenuCategories().TryGetValue(categoryId, out var category)) { Menus.MenuManager.Instance.CreateCategoryMenuPublic(category, p).OpenMenu(p); } else { Menus.MenuManager.Instance.OpenMainMenu(p); } }); return menuBuilder; } } public void RegisterMenu(string categoryId, string menuId, string menuName, Func menuFactory, string? permission = null, string? commandName = null) { Menus.MenuManager.Instance.RegisterMenu(categoryId, menuId, menuName, BuilderFactory, permission, commandName); return; MenuBuilder BuilderFactory(CCSPlayerController player) { var context = new MenuContext(categoryId, menuId, menuName, permission, commandName); if (menuFactory(player, context) is not MenuBuilder menuBuilder) throw new InvalidOperationException("Menu factory must return MenuBuilder"); // Dodaj automatyczną obsługę przycisku 'Wróć' menuBuilder.WithBackAction(p => { if (Menus.MenuManager.Instance.GetMenuCategories().TryGetValue(categoryId, out var category)) { Menus.MenuManager.Instance.CreateCategoryMenuPublic(category, p).OpenMenu(p); } else { Menus.MenuManager.Instance.OpenMainMenu(p); } }); return menuBuilder; } } public void RegisterMenu(string categoryId, string menuId, string menuNameKey, Func menuFactory, string? permission, string? commandName, object moduleLocalizer) { if (moduleLocalizer is not IStringLocalizer localizer) throw new InvalidOperationException("moduleLocalizer must be an IStringLocalizer instance"); Menus.MenuManager.Instance.RegisterMenu(categoryId, menuId, menuNameKey, BuilderFactory, permission, commandName, localizer); return; MenuBuilder BuilderFactory(CCSPlayerController player) { var context = new MenuContext(categoryId, menuId, menuNameKey, permission, commandName); if (menuFactory(player, context) is not MenuBuilder menuBuilder) throw new InvalidOperationException("Menu factory must return MenuBuilder"); // Dodaj automatyczną obsługę przycisku 'Wróć' menuBuilder.WithBackAction(p => { if (Menus.MenuManager.Instance.GetMenuCategories().TryGetValue(categoryId, out var category)) { Menus.MenuManager.Instance.CreateCategoryMenuPublic(category, p).OpenMenu(p); } else { Menus.MenuManager.Instance.OpenMainMenu(p); } }); return menuBuilder; } } public void UnregisterMenu(string categoryId, string menuId) { Menus.MenuManager.Instance.UnregisterMenu(categoryId, menuId); } public object CreateMenuWithBack(string title, string categoryId, CCSPlayerController player) { var builder = new MenuBuilder(title); builder.WithBackAction(p => { if (Menus.MenuManager.Instance.GetMenuCategories().TryGetValue(categoryId, out var category)) { Menus.MenuManager.Instance.CreateCategoryMenuPublic(category, p).OpenMenu(p); } else { Menus.MenuManager.Instance.OpenMainMenu(p); } }); return builder; } public object CreateMenuWithBack(MenuContext context, CCSPlayerController player) { // Get translated title if module has localizer string title = context.MenuTitle; if (Menus.MenuManager.Instance.GetMenuCategories().TryGetValue(context.CategoryId, out var category)) { // Check if this specific menu has a localizer if (category.MenuLocalizers.TryGetValue(context.MenuId, out var menuLocalizer)) { using (new WithTemporaryCulture(player.GetLanguage())) { title = menuLocalizer[context.MenuTitle] ?? context.MenuTitle; } } // Fallback to category localizer else if (category.ModuleLocalizer != null) { using (new WithTemporaryCulture(player.GetLanguage())) { title = category.ModuleLocalizer[context.MenuTitle] ?? context.MenuTitle; } } } return CreateMenuWithBack(title, context.CategoryId, player); } public List GetValidPlayers() { return Helper.GetValidPlayers(); } public object CreateMenuWithPlayers(string title, string categoryId, CCSPlayerController admin, Func filter, Action onSelect) { var menu = (MenuBuilder)CreateMenuWithBack(title, categoryId, admin); var players = Helper.GetValidPlayers().Where(filter); foreach (var player in players) { var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; menu.AddOption(playerName, _ => { if (player.IsValid) { onSelect(admin, player); } }); } return menu; } public object CreateMenuWithPlayers(MenuContext context, CCSPlayerController admin, Func filter, Action onSelect) { // Get translated title if module has localizer string title = context.MenuTitle; if (Menus.MenuManager.Instance.GetMenuCategories().TryGetValue(context.CategoryId, out var category)) { // Check if this specific menu has a localizer if (category.MenuLocalizers.TryGetValue(context.MenuId, out var menuLocalizer)) { using (new WithTemporaryCulture(admin.GetLanguage())) { title = menuLocalizer[context.MenuTitle] ?? context.MenuTitle; } } // Fallback to category localizer else if (category.ModuleLocalizer != null) { using (new WithTemporaryCulture(admin.GetLanguage())) { title = category.ModuleLocalizer[context.MenuTitle] ?? context.MenuTitle; } } } return CreateMenuWithPlayers(title, context.CategoryId, admin, filter, onSelect); } public void AddMenuOption(object menu, string name, Action action, bool disabled = false, string? permission = null) { if (menu is not MenuBuilder menuBuilder) throw new InvalidOperationException("Menu must be a MenuBuilder instance"); menuBuilder.AddOption(name, action, disabled, permission); } public void AddSubMenu(object menu, string name, Func subMenuFactory, bool disabled = false, string? permission = null) { if (menu is not MenuBuilder menuBuilder) throw new InvalidOperationException("Menu must be a MenuBuilder instance"); menuBuilder.AddSubMenu(name, player => { var subMenu = subMenuFactory(player); if (subMenu is not MenuBuilder builder) throw new InvalidOperationException("SubMenu factory must return MenuBuilder"); return builder; }, disabled, permission); } public void OpenMenu(object menu, CCSPlayerController player) { if (menu is not MenuBuilder menuBuilder) throw new InvalidOperationException("Menu must be a MenuBuilder instance"); menuBuilder.OpenMenu(player); } }