Fix closure issues in menus and update dependencies

Captured player and duration variables in menu callbacks to prevent closure-related bugs. Updated package versions in project files and bumped plugin version to 1.7.8-beta-5. Improved player validation and message localization logic.
This commit is contained in:
Dawid Bepierszcz
2025-11-06 02:24:43 +01:00
parent 038641dbdf
commit 0dded66e5d
10 changed files with 113 additions and 88 deletions

View File

@@ -22,7 +22,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)"); public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
public override string ModuleAuthor => "daffyy & Dliix66"; public override string ModuleAuthor => "daffyy & Dliix66";
public override string ModuleVersion => "1.7.8-beta-4"; public override string ModuleVersion => "1.7.8-beta-5";
public override void Load(bool hotReload) public override void Load(bool hotReload)
{ {

View File

@@ -19,16 +19,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.340"> <PackageReference Include="CounterStrikeSharp.API" Version="1.0.346">
<PrivateAssets>none</PrivateAssets> <PrivateAssets>none</PrivateAssets>
<ExcludeAssets>runtime</ExcludeAssets> <ExcludeAssets>runtime</ExcludeAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Dapper" Version="2.1.66" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="MySqlConnector" Version="2.4.0" /> <PackageReference Include="MySqlConnector" Version="2.5.0-beta.1" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" /> <PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
<PackageReference Include="System.Linq.Async" Version="6.0.3" /> <PackageReference Include="System.Linq.Async" Version="7.0.0-preview.1.g24680b5469" />
<PackageReference Include="ZLinq" Version="1.5.2" /> <PackageReference Include="ZLinq" Version="1.5.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -64,7 +64,7 @@ internal static class Helper
public static List<CCSPlayerController> GetValidPlayers() public static List<CCSPlayerController> GetValidPlayers()
{ {
return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().ToList(); return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().Where(p => p.Connected == PlayerConnectedState.PlayerConnected).ToList();
} }
public static List<CCSPlayerController> GetValidPlayersWithBots() public static List<CCSPlayerController> GetValidPlayersWithBots()
@@ -583,27 +583,32 @@ internal static class Helper
} }
public static void DisplayCenterMessage( public static void DisplayCenterMessage(
CCSPlayerController player, CCSPlayerController player,
string messageKey, string messageKey,
string? callerName = null, string? callerName = null,
params object[] messageArgs) params object[] messageArgs)
{ {
if (CS2_SimpleAdmin._localizer == null) return; if (CS2_SimpleAdmin._localizer == null) return;
// Determine the localized message key
var localizedMessageKey = $"{messageKey}"; var localizedMessageKey = $"{messageKey}";
var formattedMessageArgs = messageArgs.Select(arg => arg?.ToString() ?? string.Empty).ToArray(); var formattedMessageArgs = messageArgs.Select(arg => arg?.ToString() ?? string.Empty).ToArray();
// Replace placeholder based on showActivityType
for (var i = 0; i < formattedMessageArgs.Length; i++) for (var i = 0; i < formattedMessageArgs.Length; i++)
{ {
var arg = formattedMessageArgs[i]; var arg = formattedMessageArgs[i]; // Convert argument to string if not null
// Replace "CALLER" placeholder in the argument string
formattedMessageArgs[i] = CS2_SimpleAdmin.Instance.Config.OtherSettings.ShowActivityType switch formattedMessageArgs[i] = CS2_SimpleAdmin.Instance.Config.OtherSettings.ShowActivityType switch
{ {
1 => arg.Replace("CALLER", CS2_SimpleAdmin._localizer["sa_admin"]), 1 => arg.Replace("CALLER", CS2_SimpleAdmin._localizer["sa_admin"]),
2 => arg.Replace("CALLER", callerName ?? "Console"),
_ => arg _ => arg
}; };
} }
// Print the localized message to the center of the screen for the player
using (new WithTemporaryCulture(player.GetLanguage())) using (new WithTemporaryCulture(player.GetLanguage()))
{ {
player.PrintToCenter(CS2_SimpleAdmin._localizer[localizedMessageKey, formattedMessageArgs.Cast<object>().ToArray()]); player.PrintToCenter(CS2_SimpleAdmin._localizer[localizedMessageKey, formattedMessageArgs.Cast<object>().ToArray()]);

View File

@@ -364,7 +364,12 @@ internal class PlayerManager
foreach (var player in bannedPlayers) foreach (var player in bannedPlayers)
{ {
if (!player.UserId.HasValue) continue; if (!player.UserId.HasValue) continue;
await Server.NextWorldUpdateAsync(() => Helper.KickPlayer((int)player.UserId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)); await Server.NextWorldUpdateAsync(() =>
{
if (Helper.GetPlayerFromSteamid64(player.SteamID) != null)
Helper.KickPlayer((int)player.UserId,
NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
});
} }
} }

View File

@@ -57,8 +57,9 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
slapMenu.AddSubMenu(playerName, () => CreateSlapDamageMenu(admin, player)); var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
slapMenu.AddSubMenu(playerName, () => CreateSlapDamageMenu(admin, capturedPlayer));
} }
return slapMenu.WithBackButton(); return slapMenu.WithBackButton();
@@ -112,12 +113,13 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
slayMenu.AddOption(playerName, _ => slayMenu.AddOption(playerName, _ =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Slay(admin, player); CS2_SimpleAdmin.Slay(admin, capturedPlayer);
} }
}); });
} }
@@ -139,13 +141,14 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
kickMenu.AddSubMenu(playerName, () => CreateReasonMenu(admin, player, "Kick", PenaltyType.Kick, var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
kickMenu.AddSubMenu(playerName, () => CreateReasonMenu(admin, capturedPlayer, "Kick", PenaltyType.Kick,
(_, _, reason) => (_, _, reason) =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.Kick(admin, player, reason, admin.PlayerName); CS2_SimpleAdmin.Instance.Kick(admin, capturedPlayer, reason, admin.PlayerName);
} }
})); }));
} }
@@ -167,14 +170,15 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
warnMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, player, "Warn", var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
(_, _, duration) => CreateReasonMenu(admin, player, "Warn", PenaltyType.Warn, warnMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, capturedPlayer, "Warn",
(_, _, duration) => CreateReasonMenu(admin, capturedPlayer, "Warn", PenaltyType.Warn,
(_, _, reason) => (_, _, reason) =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.Warn(admin, player, duration, reason, admin.PlayerName); CS2_SimpleAdmin.Instance.Warn(admin, capturedPlayer, duration, reason, admin.PlayerName);
} }
}))); })));
} }
@@ -196,14 +200,15 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
banMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, player, "Ban", var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
(_, _, duration) => CreateReasonMenu(admin, player, "Ban", PenaltyType.Ban, banMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, capturedPlayer, "Ban",
(_, _, duration) => CreateReasonMenu(admin, capturedPlayer, "Ban", PenaltyType.Ban,
(_, _, reason) => (_, _, reason) =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.Ban(admin, player, duration, reason, admin.PlayerName); CS2_SimpleAdmin.Instance.Ban(admin, capturedPlayer, duration, reason, admin.PlayerName);
} }
}))); })));
} }
@@ -225,14 +230,15 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
gagMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, player, "Gag", var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
(_, _, duration) => CreateReasonMenu(admin, player, "Gag", PenaltyType.Gag, gagMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, capturedPlayer, "Gag",
(_, _, duration) => CreateReasonMenu(admin, capturedPlayer, "Gag", PenaltyType.Gag,
(_, _, reason) => (_, _, reason) =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.Gag(admin, player, duration, reason); CS2_SimpleAdmin.Instance.Gag(admin, capturedPlayer, duration, reason);
} }
}))); })));
} }
@@ -254,14 +260,15 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
muteMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, player, "Mute", var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
(_, _, duration) => CreateReasonMenu(admin, player, "Mute", PenaltyType.Mute, muteMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, capturedPlayer, "Mute",
(_, _, duration) => CreateReasonMenu(admin, capturedPlayer, "Mute", PenaltyType.Mute,
(_, _, reason) => (_, _, reason) =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.Mute(admin, player, duration, reason); CS2_SimpleAdmin.Instance.Mute(admin, capturedPlayer, duration, reason);
} }
}))); })));
} }
@@ -283,14 +290,15 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
silenceMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, player, "Silence", var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
(_, _, duration) => CreateReasonMenu(admin, player, "Silence", PenaltyType.Silence, silenceMenu.AddSubMenu(playerName, () => CreateDurationMenu(admin, capturedPlayer, "Silence",
(_, _, duration) => CreateReasonMenu(admin, capturedPlayer, "Silence", PenaltyType.Silence,
(_, _, reason) => (_, _, reason) =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.Silence(admin, player, duration, reason); CS2_SimpleAdmin.Instance.Silence(admin, capturedPlayer, duration, reason);
} }
}))); })));
} }
@@ -312,8 +320,9 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
teamMenu.AddSubMenu(playerName, () => CreateTeamSelectionMenu(admin, player)); var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
teamMenu.AddSubMenu(playerName, () => CreateTeamSelectionMenu(admin, capturedPlayer));
} }
return teamMenu.WithBackButton(); return teamMenu.WithBackButton();
@@ -488,8 +497,9 @@ public abstract class BasicMenu
foreach (var player in players) foreach (var player in players)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
addAdminMenu.AddSubMenu(playerName, () => CreateAdminFlagsMenu(admin, player)); var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
addAdminMenu.AddSubMenu(playerName, () => CreateAdminFlagsMenu(admin, capturedPlayer));
} }
return addAdminMenu.WithBackButton(); return addAdminMenu.WithBackButton();
@@ -539,19 +549,20 @@ public abstract class BasicMenu
var localizer = CS2_SimpleAdmin._localizer; var localizer = CS2_SimpleAdmin._localizer;
var removeAdminMenu = new MenuBuilder("sa_admin_remove", admin, localizer); var removeAdminMenu = new MenuBuilder("sa_admin_remove", admin, localizer);
var adminPlayers = Helper.GetValidPlayers().Where(p => var adminPlayers = Helper.GetValidPlayers().Where(p =>
AdminManager.GetPlayerAdminData(p)?.Flags.Count > 0 && AdminManager.GetPlayerAdminData(p)?.Flags.Count > 0 &&
p != admin && p != admin &&
admin.CanTarget(p)); admin.CanTarget(p));
foreach (var player in adminPlayers) foreach (var player in adminPlayers)
{ {
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName; var capturedPlayer = player; // Capture to local variable to avoid closure issue
var playerName = capturedPlayer.PlayerName.Length > 26 ? capturedPlayer.PlayerName[..26] : capturedPlayer.PlayerName;
removeAdminMenu.AddOption(playerName, _ => removeAdminMenu.AddOption(playerName, _ =>
{ {
if (player.IsValid) if (capturedPlayer.IsValid)
{ {
CS2_SimpleAdmin.Instance.RemoveAdmin(admin, player.SteamID.ToString()); CS2_SimpleAdmin.Instance.RemoveAdmin(admin, capturedPlayer.SteamID.ToString());
} }
}); });
} }
@@ -583,10 +594,10 @@ public abstract class BasicMenu
/// <param name="admin">The admin player selecting duration.</param> /// <param name="admin">The admin player selecting duration.</param>
/// <param name="player">The target player for the penalty.</param> /// <param name="player">The target player for the penalty.</param>
/// <param name="actionName">The name of the penalty action (e.g., "Kick", "Ban").</param> /// <param name="actionName">The name of the penalty action (e.g., "Kick", "Ban").</param>
/// <param name="onSelectAction">Callback action executed when duration is selected.</param> /// <param name="onSelectAction">Callback function that returns the next menu when duration is selected.</param>
/// <returns>A MenuBuilder instance for the duration menu.</returns> /// <returns>A MenuBuilder instance for the duration menu.</returns>
private static MenuBuilder CreateDurationMenu(CCSPlayerController admin, CCSPlayerController player, string actionName, private static MenuBuilder CreateDurationMenu(CCSPlayerController admin, CCSPlayerController player, string actionName,
Action<CCSPlayerController, CCSPlayerController, int> onSelectAction) Func<CCSPlayerController, CCSPlayerController, int, MenuBuilder> onSelectAction)
{ {
var localizer = CS2_SimpleAdmin._localizer; var localizer = CS2_SimpleAdmin._localizer;
@@ -614,10 +625,8 @@ public abstract class BasicMenu
foreach (var durationItem in CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations) foreach (var durationItem in CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations)
{ {
durationMenu.AddOption(durationItem.Name, _ => var capturedDuration = durationItem.Duration; // Capture to avoid closure issue
{ durationMenu.AddSubMenu(durationItem.Name, () => onSelectAction(admin, player, capturedDuration));
onSelectAction(admin, player, durationItem.Duration);
});
} }
return durationMenu.WithBackButton(); return durationMenu.WithBackButton();

View File

@@ -8,12 +8,28 @@ public static class DurationMenu
public static void OpenMenu(CCSPlayerController admin, string menuName, CCSPlayerController player, Action<CCSPlayerController, CCSPlayerController, int> onSelectAction) public static void OpenMenu(CCSPlayerController admin, string menuName, CCSPlayerController player, Action<CCSPlayerController, CCSPlayerController, int> onSelectAction)
{ {
var menu = AdminMenu.CreateMenu(menuName); var menu = AdminMenu.CreateMenu(menuName);
foreach (var durationItem in CS2_SimpleAdmin.Instance.Config.MenuConfigs.Durations) 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)
{ {
menu?.AddMenuOption(durationItem.Name, (_, _) => { onSelectAction(admin, player, durationItem.Duration); }); var duration = durationItem.Duration; // Capture in local variable
var name = durationItem.Name;
menu.AddMenuOption(name, (controller, option) =>
{
capturedAction(capturedAdmin, capturedPlayer, duration);
});
} }
if (menu != null) AdminMenu.OpenMenu(admin, menu); AdminMenu.OpenMenu(admin, menu);
} }
public static void OpenMenu(CCSPlayerController admin, string menuName, DisconnectedPlayer player, Action<CCSPlayerController, DisconnectedPlayer, int> onSelectAction) public static void OpenMenu(CCSPlayerController admin, string menuName, DisconnectedPlayer player, Action<CCSPlayerController, DisconnectedPlayer, int> onSelectAction)

View File

@@ -49,25 +49,27 @@ public static class ManagePlayersMenu
if (AdminManager.CommandIsOverriden("css_warn") if (AdminManager.CommandIsOverriden("css_warn")
? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_warn")) ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_warn"))
: AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/kick")) : 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)))); 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) 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)))); 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 (hasChat)
{ {
if (AdminManager.CommandIsOverriden("css_gag") if (AdminManager.CommandIsOverriden("css_gag")
? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gag")) ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_gag"))
: AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) : 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)))); 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") if (AdminManager.CommandIsOverriden("css_mute")
? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_mute")) ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_mute"))
: AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) : 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)))); 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") if (AdminManager.CommandIsOverriden("css_silence")
? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_silence")) ? AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), AdminManager.GetPermissionOverrides("css_silence"))
: AdminManager.PlayerHasPermissions(new SteamID(admin.SteamID), "@css/chat")) : 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)))); 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") if (AdminManager.CommandIsOverriden("css_team")
@@ -159,22 +161,9 @@ public static class ManagePlayersMenu
{ {
if (player is { IsValid: true }) if (player is { IsValid: true })
Ban(admin, player, duration, reason); Ban(admin, player, duration, reason);
CS2_SimpleAdmin.MenuApi?.CloseMenu(admin); 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);
} }
private static void Ban(CCSPlayerController admin, CCSPlayerController player, int duration, string reason) private static void Ban(CCSPlayerController admin, CCSPlayerController player, int duration, string reason)

View File

@@ -41,11 +41,12 @@ public static class PlayersMenu
continue; continue;
var enabled = admin.CanTarget(player); var enabled = admin.CanTarget(player);
var capturedPlayer = player; // Capture in local variable to avoid closure issues
if (optionName != null) if (optionName != null)
menu?.AddMenuOption(optionName, (_, _) => menu?.AddMenuOption(optionName, (controller, option) =>
{ {
if (player != null) onSelectAction.Invoke(admin, player); if (capturedPlayer != null) onSelectAction.Invoke(admin, capturedPlayer);
}, },
!enabled); !enabled);
} }

View File

@@ -1 +1 @@
1.7.8-beta-4 1.7.8-beta-5

View File

@@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.340" /> <PackageReference Include="CounterStrikeSharp.API" Version="1.0.346" />
</ItemGroup> </ItemGroup>
</Project> </Project>