【UPDATE 1.7.1a】

🆕  What's new and what's changed:
- Fixed 2x player lock text
- Added immunity check when using css_addX
- MenuManagerCS2 has been updated
- Added return of lock ID by api (check example_module)
- Fixed reasons for locks, no longer need to use `“”` if there is a space in them
- Improved handling of lock times, from now on you can use:
-- 1mo - 1 month
-- 1w - 1 week
-- 1d - 1 day
-- 1h - 1 hour
-- 1m - 1 minute
-- 1 - 1 minute
You can also combine it, e.g:
10d5h - 10 days and 5 hours
2w3d - 2 weeks and 3 days
1w1d1h1 - 1 week, 1 day and 1 minute
So for example css_ban player 10d5h Super reason for my ban
- Added a `rcon_password` column in the `sa_servers` table that populates with the rcon password
- Fixed `banid` and banning
- Fixed too fast kick (it was caused by checking players online)

⚠️  **Remember to update all files + api**
This commit is contained in:
Dawid Bepierszcz
2025-01-08 19:24:47 +01:00
parent 8af805632a
commit 3f1b6b3bf7
25 changed files with 532 additions and 253 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -25,14 +25,14 @@ public class CS2_SimpleAdminApi : ICS2_SimpleAdminApi
return PlayerPenaltyManager.GetAllPlayerPenalties(player.Slot); return PlayerPenaltyManager.GetAllPlayerPenalties(player.Slot);
} }
public event Action<PlayerInfo, PlayerInfo?, PenaltyType, string, int, int?>? OnPlayerPenaltied; public event Action<PlayerInfo, PlayerInfo?, PenaltyType, string, int, int?, int?>? OnPlayerPenaltied;
public event Action<SteamID, PlayerInfo?, PenaltyType, string, int, int?>? OnPlayerPenaltiedAdded; public event Action<SteamID, PlayerInfo?, PenaltyType, string, int, int?, int?>? OnPlayerPenaltiedAdded;
public void OnPlayerPenaltiedEvent(PlayerInfo player, PlayerInfo? admin, PenaltyType penaltyType, string reason, public void OnPlayerPenaltiedEvent(PlayerInfo player, PlayerInfo? admin, PenaltyType penaltyType, string reason,
int duration = -1) => OnPlayerPenaltied?.Invoke(player, admin, penaltyType, reason, duration, CS2_SimpleAdmin.ServerId); 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, public void OnPlayerPenaltiedAddedEvent(SteamID player, PlayerInfo? admin, PenaltyType penaltyType, string reason,
int duration) => OnPlayerPenaltiedAdded?.Invoke(player, admin, penaltyType, reason, duration, CS2_SimpleAdmin.ServerId); int duration, int? penaltyId) => OnPlayerPenaltiedAdded?.Invoke(player, admin, penaltyType, reason, duration, penaltyId, CS2_SimpleAdmin.ServerId);
public void IssuePenalty(CCSPlayerController player, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1) public void IssuePenalty(CCSPlayerController player, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1)
{ {

View File

@@ -19,7 +19,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.0a"; public override string ModuleVersion => "1.7.1a";
public override void Load(bool hotReload) public override void Load(bool hotReload)
{ {

View File

@@ -78,7 +78,8 @@ public static class RegisterCommands
new CommandMapping("css_respawn", CS2_SimpleAdmin.Instance.OnRespawnCommand), new CommandMapping("css_respawn", CS2_SimpleAdmin.Instance.OnRespawnCommand),
new CommandMapping("css_tp", CS2_SimpleAdmin.Instance.OnGotoCommand), new CommandMapping("css_tp", CS2_SimpleAdmin.Instance.OnGotoCommand),
new CommandMapping("css_bring", CS2_SimpleAdmin.Instance.OnBringCommand), new CommandMapping("css_bring", CS2_SimpleAdmin.Instance.OnBringCommand),
new CommandMapping("css_pluginsmanager", CS2_SimpleAdmin.Instance.OnPluginManagerCommand) new CommandMapping("css_pluginsmanager", CS2_SimpleAdmin.Instance.OnPluginManagerCommand),
new CommandMapping("css_adminvoice", CS2_SimpleAdmin.Instance.OnAdminVoiceCommand)
]; ];
public static void InitializeCommands() public static void InitializeCommands()
@@ -160,7 +161,8 @@ public static class RegisterCommands
{ "css_respawn", new Command { Aliases = ["css_respawn"] } }, { "css_respawn", new Command { Aliases = ["css_respawn"] } },
{ "css_tp", new Command { Aliases = ["css_tp", "css_tpto", "css_goto"] } }, { "css_tp", new Command { Aliases = ["css_tp", "css_tpto", "css_goto"] } },
{ "css_bring", new Command { Aliases = ["css_bring", "css_tphere"] } }, { "css_bring", new Command { Aliases = ["css_bring", "css_tphere"] } },
{ "css_pluginsmanager", new Command { Aliases = ["css_pluginsmanager", "css_pluginmanager"] } } { "css_pluginsmanager", new Command { Aliases = ["css_pluginsmanager", "css_pluginmanager"] } },
{ "css_adminvoice", new Command { Aliases = ["css_adminvoice", "css_listenall"] } }
} }
}; };

View File

@@ -20,8 +20,6 @@ public partial class CS2_SimpleAdmin
if (command.ArgCount < 2) if (command.ArgCount < 2)
return; return;
var reason = _localizer?["sa_unknown"] ?? "Unknown";
var targets = GetTarget(command); var targets = GetTarget(command);
if (targets == null) return; if (targets == null) return;
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, Connected: PlayerConnectedState.PlayerConnected, IsHLTV: false }).ToList(); var playersToTarget = targets.Players.Where(player => player is { IsValid: true, Connected: PlayerConnectedState.PlayerConnected, IsHLTV: false }).ToList();
@@ -31,14 +29,17 @@ public partial class CS2_SimpleAdmin
return; return;
} }
if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) var reason = command.ArgCount >= 3
reason = command.GetArg(3); ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
var time = Helper.ParsePenaltyTime(command.GetArg(2));
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
if (!caller.CanTarget(player)) return; if (!caller.CanTarget(player)) return;
if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime) if (time < 0 && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime)
{ {
DurationMenu.OpenMenu(caller, $"{_localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player, DurationMenu.OpenMenu(caller, $"{_localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player,
ManagePlayersMenu.BanMenu); ManagePlayersMenu.BanMenu);
@@ -60,12 +61,6 @@ public partial class CS2_SimpleAdmin
? caller.PlayerName ? caller.PlayerName
: (_localizer?["sa_console"] ?? "Console"); : (_localizer?["sa_console"] ?? "Console");
// Freeze player pawn if alive
if (player.PawnIsAlive)
{
player.Pawn.Value?.Freeze();
}
// Get player and admin information // Get player and admin information
var playerInfo = PlayersInfo[player.UserId.Value]; var playerInfo = PlayersInfo[player.UserId.Value];
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
@@ -73,7 +68,8 @@ public partial class CS2_SimpleAdmin
// Asynchronously handle banning logic // Asynchronously handle banning logic
Task.Run(async () => Task.Run(async () =>
{ {
await BanManager.BanPlayer(playerInfo, adminInfo, reason, time); int? penaltyId = await BanManager.BanPlayer(playerInfo, adminInfo, reason, time);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Ban, reason, time, penaltyId);
}); });
// Update banned players list // Update banned players list
@@ -103,13 +99,7 @@ public partial class CS2_SimpleAdmin
// Schedule a kick timer // Schedule a kick timer
if (player.UserId.HasValue) if (player.UserId.HasValue)
{ {
AddTimer(Config.OtherSettings.KickTime, () => Helper.KickPlayer(player.UserId.Value, NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKBANADDED, Config.OtherSettings.KickTime);
{
if (player is { IsValid: true, UserId: not null })
{
Helper.KickPlayer(player.UserId.Value, NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKBANADDED);
}
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
// Execute ban command if necessary // Execute ban command if necessary
@@ -127,7 +117,6 @@ public partial class CS2_SimpleAdmin
} }
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Ban, _localizer); Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Ban, _localizer);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Ban, reason, time);
} }
[RequiresPermissions("@css/ban")] [RequiresPermissions("@css/ban")]
@@ -144,11 +133,12 @@ public partial class CS2_SimpleAdmin
} }
var steamid = steamId.SteamId64.ToString(); var steamid = steamId.SteamId64.ToString();
var reason = command.ArgCount >= 3 && !string.IsNullOrEmpty(command.GetArg(3)) var reason = command.ArgCount >= 3
? command.GetArg(3) ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown"; : _localizer?["sa_unknown"] ?? "Unknown";
int.TryParse(command.GetArg(2), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
if (!CheckValidBan(caller, time)) return; if (!CheckValidBan(caller, time)) return;
var adminInfo = caller != null && caller.UserId.HasValue var adminInfo = caller != null && caller.UserId.HasValue
@@ -168,10 +158,14 @@ public partial class CS2_SimpleAdmin
} }
else else
{ {
if (!caller.CanTarget(new SteamID(steamId.SteamId64)))
return;
// Asynchronous ban operation if player is not online or not found // Asynchronous ban operation if player is not online or not found
Task.Run(async () => Task.Run(async () =>
{ {
await BanManager.AddBanBySteamid(steamid, adminInfo, reason, time); int? penaltyId = await BanManager.AddBanBySteamid(steamid, adminInfo, reason, time);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Ban, reason, time, penaltyId);
}); });
Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Ban, _localizer); Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Ban, _localizer);
@@ -183,8 +177,6 @@ public partial class CS2_SimpleAdmin
if (UnlockedCommands) if (UnlockedCommands)
Server.ExecuteCommand($"banid 1 {steamId.SteamId3}"); Server.ExecuteCommand($"banid 1 {steamId.SteamId3}");
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Ban, reason, time);
} }
[RequiresPermissions("@css/ban")] [RequiresPermissions("@css/ban")]
@@ -202,11 +194,12 @@ public partial class CS2_SimpleAdmin
return; return;
} }
var reason = command.ArgCount >= 3 && !string.IsNullOrEmpty(command.GetArg(3)) var reason = command.ArgCount >= 3
? command.GetArg(3) ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown"; : _localizer?["sa_unknown"] ?? "Unknown";
int.TryParse(command.GetArg(2), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
if (!CheckValidBan(caller, time)) return; if (!CheckValidBan(caller, time)) return;
var adminInfo = caller != null && caller.UserId.HasValue var adminInfo = caller != null && caller.UserId.HasValue
@@ -270,7 +263,9 @@ public partial class CS2_SimpleAdmin
} }
var pattern = command.GetArg(1); var pattern = command.GetArg(1);
var reason = command.GetArg(2); var reason = command.ArgCount >= 2
? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
Task.Run(async () => await BanManager.UnbanPlayer(pattern, callerSteamId, reason)); Task.Run(async () => await BanManager.UnbanPlayer(pattern, callerSteamId, reason));
@@ -289,8 +284,6 @@ public partial class CS2_SimpleAdmin
if (command.ArgCount < 2) if (command.ArgCount < 2)
return; return;
var reason = _localizer?["sa_unknown"] ?? "Unknown";
var targets = GetTarget(command); var targets = GetTarget(command);
if (targets == null) return; if (targets == null) return;
var playersToTarget = targets.Players.Where(player => player.IsValid && player.Connected == PlayerConnectedState.PlayerConnected && !player.IsHLTV).ToList(); var playersToTarget = targets.Players.Where(player => player.IsValid && player.Connected == PlayerConnectedState.PlayerConnected && !player.IsHLTV).ToList();
@@ -302,10 +295,10 @@ public partial class CS2_SimpleAdmin
WarnManager warnManager = new(Database); WarnManager warnManager = new(Database);
int.TryParse(command.GetArg(2), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
var reason = command.ArgCount >= 3
if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
reason = command.GetArg(3); : _localizer?["sa_unknown"] ?? "Unknown";
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
@@ -342,7 +335,8 @@ public partial class CS2_SimpleAdmin
Task.Run(async () => Task.Run(async () =>
{ {
warnManager ??= new WarnManager(Database); warnManager ??= new WarnManager(Database);
await warnManager.WarnPlayer(playerInfo, adminInfo, reason, time); int? penaltyId = await warnManager.WarnPlayer(playerInfo, adminInfo, reason, time);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Warn, reason, time, penaltyId);
// Check for warn thresholds and execute punish command if applicable // Check for warn thresholds and execute punish command if applicable
var totalWarns = await warnManager.GetPlayerWarnsCount(player.SteamID.ToString()); var totalWarns = await warnManager.GetPlayerWarnsCount(player.SteamID.ToString());
@@ -392,7 +386,6 @@ public partial class CS2_SimpleAdmin
// Send Discord notification for the warning // Send Discord notification for the warning
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Warn, _localizer); Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Warn, _localizer);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Warn, reason, time);
} }
[RequiresPermissions("@css/kick")] [RequiresPermissions("@css/kick")]

View File

@@ -15,6 +15,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Globalization; using System.Globalization;
using System.Reflection; using System.Reflection;
using CounterStrikeSharp.API.ValveConstants.Protobuf;
using MenuManager; using MenuManager;
namespace CS2_SimpleAdmin; namespace CS2_SimpleAdmin;
@@ -40,7 +41,7 @@ public partial class CS2_SimpleAdmin
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
if (!player.UserId.HasValue) return; if (!player.UserId.HasValue) return;
if (!caller!.CanTarget(player)) return; if (!caller.CanTarget(player)) return;
userId = player.UserId.Value; userId = player.UserId.Value;
}); });
@@ -140,6 +141,38 @@ public partial class CS2_SimpleAdmin
}); });
} }
[RequiresPermissions("@css/chat")]
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_ONLY)]
public void OnAdminVoiceCommand(CCSPlayerController? caller, CommandInfo command)
{
if (caller == null || caller.IsValid == false)
return;
if (command.ArgCount > 1)
{
if (command.GetArg(2).ToLower().Equals("muteAll"))
{
foreach (var player in Helper.GetValidPlayers().Where(p => p != caller && !AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/chat")))
{
player.VoiceFlags = VoiceFlags.Muted;
}
}
if (command.GetArg(2).ToLower().Equals("unmuteAll"))
{
foreach (var player in Helper.GetValidPlayers().Where(p => p != caller))
{
if (PlayerPenaltyManager.GetPlayerPenalties(player.Slot, PenaltyType.Mute).Count == 0)
player.VoiceFlags = VoiceFlags.Normal;
}
}
return;
}
caller.VoiceFlags = caller.VoiceFlags == VoiceFlags.All ? VoiceFlags.Normal : VoiceFlags.All;
}
[RequiresPermissions("@css/generic")] [RequiresPermissions("@css/generic")]
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_ONLY)] [CommandHelper(whoCanExecute: CommandUsage.CLIENT_ONLY)]
public void OnAdminCommand(CCSPlayerController? caller, CommandInfo command) public void OnAdminCommand(CCSPlayerController? caller, CommandInfo command)
@@ -192,7 +225,7 @@ public partial class CS2_SimpleAdmin
var globalAdmin = command.GetArg(4).ToLower().Equals("-g") || command.GetArg(5).ToLower().Equals("-g") || var globalAdmin = command.GetArg(4).ToLower().Equals("-g") || command.GetArg(5).ToLower().Equals("-g") ||
command.GetArg(6).ToLower().Equals("-g"); command.GetArg(6).ToLower().Equals("-g");
int.TryParse(command.GetArg(4), out var immunity); int.TryParse(command.GetArg(4), out var immunity);
int.TryParse(command.GetArg(5), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(5)));
AddAdmin(caller, steamid, name, flags, immunity, time, globalAdmin, command); AddAdmin(caller, steamid, name, flags, immunity, time, globalAdmin, command);
} }
@@ -512,6 +545,23 @@ public partial class CS2_SimpleAdmin
ReasonMenu.OpenMenu(caller, PenaltyType.Ban, _localizer["sa_reason"], player, (_, _, reason) => ReasonMenu.OpenMenu(caller, PenaltyType.Ban, _localizer["sa_reason"], player, (_, _, reason) =>
{ {
caller.ExecuteClientCommandFromServer($"css_addban {player.SteamId.SteamId64} {duration} \"{reason}\""); caller.ExecuteClientCommandFromServer($"css_addban {player.SteamId.SteamId64} {duration} \"{reason}\"");
// Determine message keys and arguments based on ban time
var (_, activityMessageKey, _, adminActivityArgs) = duration == 0
? ("sa_player_ban_message_perm", "sa_admin_ban_message_perm",
[reason, "CALLER"],
["CALLER", player.Name, reason])
: ("sa_player_ban_message_time", "sa_admin_ban_message_time",
new object[] { reason, duration, "CALLER" },
new object[] { "CALLER", player.Name, reason, duration });
// Display admin activity message if necessary
if (!SilentPlayers.Contains(caller.Slot))
{
Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, adminActivityArgs);
}
MenuApi?.CloseMenu(caller);
})); }));
}); });
disconnectedMenuAction?.AddMenuOption(_localizer["sa_mute"], (_, _) => disconnectedMenuAction?.AddMenuOption(_localizer["sa_mute"], (_, _) =>
@@ -520,6 +570,23 @@ public partial class CS2_SimpleAdmin
ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) => ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) =>
{ {
caller.ExecuteClientCommandFromServer($"css_addmute {player.SteamId.SteamId64} {duration} \"{reason}\""); caller.ExecuteClientCommandFromServer($"css_addmute {player.SteamId.SteamId64} {duration} \"{reason}\"");
// Determine message keys and arguments based on mute time (permanent or timed)
var (_, activityMessageKey, _, adminActivityArgs) = duration == 0
? ("sa_player_mute_message_perm", "sa_admin_mute_message_perm",
[reason, "CALLER"],
["CALLER", player.Name, reason])
: ("sa_player_mute_message_time", "sa_admin_mute_message_time",
new object[] { reason, duration, "CALLER" },
new object[] { "CALLER", player.Name, reason, duration });
// Display admin activity message to other players
if (!SilentPlayers.Contains(caller.Slot))
{
Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, adminActivityArgs);
}
MenuApi?.CloseMenu(caller);
})); }));
}); });
disconnectedMenuAction?.AddMenuOption(_localizer["sa_gag"], (_, _) => disconnectedMenuAction?.AddMenuOption(_localizer["sa_gag"], (_, _) =>
@@ -528,6 +595,23 @@ public partial class CS2_SimpleAdmin
ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) => ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) =>
{ {
caller.ExecuteClientCommandFromServer($"css_addgag {player.SteamId.SteamId64} {duration} \"{reason}\""); caller.ExecuteClientCommandFromServer($"css_addgag {player.SteamId.SteamId64} {duration} \"{reason}\"");
// Determine message keys and arguments based on gag time (permanent or timed)
var (_, activityMessageKey, _, adminActivityArgs) = duration == 0
? ("sa_player_gag_message_perm", "sa_admin_gag_message_perm",
[reason, "CALLER"],
["CALLER", player.Name, reason])
: ("sa_player_gag_message_time", "sa_admin_gag_message_time",
new object[] { reason, duration, "CALLER" },
new object[] { "CALLER", player.Name, reason, duration});
// Display admin activity message to other players
if (!SilentPlayers.Contains(caller.Slot))
{
Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, adminActivityArgs);
}
MenuApi?.CloseMenu(caller);
})); }));
}); });
disconnectedMenuAction?.AddMenuOption(_localizer["sa_silence"], (_, _) => disconnectedMenuAction?.AddMenuOption(_localizer["sa_silence"], (_, _) =>
@@ -536,6 +620,23 @@ public partial class CS2_SimpleAdmin
ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) => ReasonMenu.OpenMenu(caller, PenaltyType.Mute, _localizer["sa_reason"], player, (_, _, reason) =>
{ {
caller.ExecuteClientCommandFromServer($"css_addsilence {player.SteamId.SteamId64} {duration} \"{reason}\""); caller.ExecuteClientCommandFromServer($"css_addsilence {player.SteamId.SteamId64} {duration} \"{reason}\"");
// Determine message keys and arguments based on silence time (permanent or timed)
var (_, activityMessageKey, _, adminActivityArgs) = duration == 0
? ("sa_player_silence_message_perm", "sa_admin_silence_message_perm",
[reason, "CALLER"],
["CALLER", player.Name, reason])
: ("sa_player_silence_message_time", "sa_admin_silence_message_time",
new object[] { reason, duration, "CALLER" },
new object[] { "CALLER", player.Name, reason, duration });
// Display admin activity message to other players
if (!SilentPlayers.Contains(caller.Slot))
{
Helper.ShowAdminActivity(activityMessageKey, caller.PlayerName, adminActivityArgs);
}
MenuApi?.CloseMenu(caller);
})); }));
}); });
@@ -565,7 +666,7 @@ public partial class CS2_SimpleAdmin
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
if (!player.UserId.HasValue) return; if (!player.UserId.HasValue) return;
if (!caller!.CanTarget(player)) return; if (!caller.CanTarget(player)) return;
var userId = player.UserId.Value; var userId = player.UserId.Value;
@@ -615,27 +716,27 @@ public partial class CS2_SimpleAdmin
{ {
if (caller != null) if (caller != null)
{ {
caller.PrintToConsole($"--------- PLAYER LIST ---------"); caller.PrintToConsole("--------- PLAYER LIST ---------");
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
caller.PrintToConsole( caller.PrintToConsole(
$"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(caller, "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")"); $"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(caller, "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")");
}); });
caller.PrintToConsole($"--------- END PLAYER LIST ---------"); caller.PrintToConsole("--------- END PLAYER LIST ---------");
} }
else else
{ {
Server.PrintToConsole($"--------- PLAYER LIST ---------"); Server.PrintToConsole("--------- PLAYER LIST ---------");
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")");
}); });
Server.PrintToConsole($"--------- END PLAYER LIST ---------"); Server.PrintToConsole("--------- END PLAYER LIST ---------");
} }
} }
else else
{ {
var playersJson = JsonConvert.SerializeObject(playersToTarget.Select((CCSPlayerController player) => var playersJson = JsonConvert.SerializeObject(playersToTarget.Select(player =>
{ {
var matchStats = player.ActionTrackingServices?.MatchStats; var matchStats = player.ActionTrackingServices?.MatchStats;
@@ -669,7 +770,6 @@ public partial class CS2_SimpleAdmin
public void OnKickCommand(CCSPlayerController? caller, CommandInfo command) public void OnKickCommand(CCSPlayerController? caller, CommandInfo command)
{ {
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
var reason = _localizer?["sa_unknown"] ?? "Unknown";
var targets = GetTarget(command); var targets = GetTarget(command);
@@ -682,8 +782,9 @@ public partial class CS2_SimpleAdmin
return; return;
} }
if (command.ArgCount >= 2 && command.GetArg(2).Length > 0) var reason = command.ArgCount >= 2
reason = command.GetArg(2); ? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
@@ -710,12 +811,6 @@ public partial class CS2_SimpleAdmin
var playerInfo = PlayersInfo[player.UserId.Value]; var playerInfo = PlayersInfo[player.UserId.Value];
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
// Freeze player pawn if alive
if (player.PawnIsAlive)
{
player.Pawn.Value?.Freeze();
}
// Determine message keys and arguments for the kick notification // Determine message keys and arguments for the kick notification
var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) =
("sa_player_kick_message", "sa_admin_kick_message", ("sa_player_kick_message", "sa_admin_kick_message",
@@ -734,13 +829,7 @@ public partial class CS2_SimpleAdmin
// Schedule the kick for the player // Schedule the kick for the player
if (player.UserId.HasValue) if (player.UserId.HasValue)
{ {
AddTimer(Config.OtherSettings.KickTime, () => Helper.KickPlayer(player.UserId.Value, NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED, Config.OtherSettings.KickTime);
{
if (player.IsValid)
{
Helper.KickPlayer(player.UserId.Value);
}
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
// Log the command and send Discord notification // Log the command and send Discord notification
@@ -749,7 +838,7 @@ public partial class CS2_SimpleAdmin
else else
Helper.LogCommand(caller, command); Helper.LogCommand(caller, command);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Kick, reason); SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Kick, reason, -1, null);
} }
[RequiresPermissions("@css/changemap")] [RequiresPermissions("@css/changemap")]

View File

@@ -2,6 +2,7 @@ using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Entities;
using CS2_SimpleAdmin.Managers; using CS2_SimpleAdmin.Managers;
using CS2_SimpleAdmin.Menus; using CS2_SimpleAdmin.Menus;
using CS2_SimpleAdminApi; using CS2_SimpleAdminApi;
@@ -17,8 +18,6 @@ public partial class CS2_SimpleAdmin
if (Database == null) return; if (Database == null) return;
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
var reason = _localizer?["sa_unknown"] ?? "Unknown";
var targets = GetTarget(command); var targets = GetTarget(command);
if (targets == null) return; if (targets == null) return;
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList(); var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
@@ -28,13 +27,16 @@ public partial class CS2_SimpleAdmin
return; return;
} }
if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) var reason = command.ArgCount >= 3
reason = command.GetArg(3); ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
var time = Helper.ParsePenaltyTime(command.GetArg(2));
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
if (!caller!.CanTarget(player)) return; if (!caller!.CanTarget(player)) return;
if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime) if (time < 0 && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime)
{ {
DurationMenu.OpenMenu(caller, $"{_localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player, DurationMenu.OpenMenu(caller, $"{_localizer?["sa_gag"] ?? "Gag"}: {player.PlayerName}", player,
ManagePlayersMenu.GagMenu); ManagePlayersMenu.GagMenu);
@@ -61,7 +63,8 @@ public partial class CS2_SimpleAdmin
// Asynchronously handle gag logic // Asynchronously handle gag logic
Task.Run(async () => Task.Run(async () =>
{ {
await MuteManager.MutePlayer(playerInfo, adminInfo, reason, time); int? penaltyId = await MuteManager.MutePlayer(playerInfo, adminInfo, reason, time);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Gag, reason, time, penaltyId);
}); });
// Add penalty to the player's penalty manager // Add penalty to the player's penalty manager
@@ -98,7 +101,6 @@ public partial class CS2_SimpleAdmin
} }
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Gag, _localizer); Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Gag, _localizer);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Gag, reason, time);
} }
[RequiresPermissions("@css/chat")] [RequiresPermissions("@css/chat")]
@@ -121,11 +123,11 @@ public partial class CS2_SimpleAdmin
} }
var steamid = steamId.SteamId64.ToString(); var steamid = steamId.SteamId64.ToString();
var reason = command.ArgCount >= 3 && command.GetArg(3).Length > 0 var reason = command.ArgCount >= 3
? command.GetArg(3) ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: (_localizer?["sa_unknown"] ?? "Unknown"); : _localizer?["sa_unknown"] ?? "Unknown";
int.TryParse(command.GetArg(2), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
if (!CheckValidMute(caller, time)) return; if (!CheckValidMute(caller, time)) return;
// Get player and admin info // Get player and admin info
@@ -145,10 +147,14 @@ public partial class CS2_SimpleAdmin
} }
else else
{ {
if (!caller.CanTarget(new SteamID(steamId.SteamId64)))
return;
// Asynchronous gag operation for offline players // Asynchronous gag operation for offline players
Task.Run(async () => Task.Run(async () =>
{ {
await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time); int? penaltyId = await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Gag, reason, time, penaltyId);
}); });
Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Gag, _localizer); Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Gag, _localizer);
@@ -158,7 +164,6 @@ public partial class CS2_SimpleAdmin
// Log the gag command and respond to the command // Log the gag command and respond to the command
Helper.LogCommand(caller, command); Helper.LogCommand(caller, command);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Gag, reason, time);
} }
[RequiresPermissions("@css/chat")] [RequiresPermissions("@css/chat")]
@@ -169,7 +174,9 @@ public partial class CS2_SimpleAdmin
var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console"; var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console";
var pattern = command.GetArg(1); var pattern = command.GetArg(1);
var reason = command.GetArg(2); var reason = command.ArgCount >= 2
? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
if (pattern.Length <= 1) if (pattern.Length <= 1)
{ {
@@ -235,8 +242,6 @@ public partial class CS2_SimpleAdmin
if (Database == null) return; if (Database == null) return;
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
var reason = _localizer?["sa_unknown"] ?? "Unknown";
var targets = GetTarget(command); var targets = GetTarget(command);
if (targets == null) return; if (targets == null) return;
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList(); var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
@@ -246,13 +251,16 @@ public partial class CS2_SimpleAdmin
return; return;
} }
if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) var reason = command.ArgCount >= 3
reason = command.GetArg(3); ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
var time = Helper.ParsePenaltyTime(command.GetArg(2));
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
if (!caller!.CanTarget(player)) return; if (!caller!.CanTarget(player)) return;
if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime) if (time < 0 && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime)
{ {
DurationMenu.OpenMenu(caller, $"{_localizer?["sa_mute"] ?? "Mute"}: {player.PlayerName}", player, DurationMenu.OpenMenu(caller, $"{_localizer?["sa_mute"] ?? "Mute"}: {player.PlayerName}", player,
ManagePlayersMenu.MuteMenu); ManagePlayersMenu.MuteMenu);
@@ -282,7 +290,8 @@ public partial class CS2_SimpleAdmin
// Asynchronously handle mute logic // Asynchronously handle mute logic
Task.Run(async () => Task.Run(async () =>
{ {
await MuteManager.MutePlayer(playerInfo, adminInfo, reason, time, 1); int? penaltyId = await MuteManager.MutePlayer(playerInfo, adminInfo, reason, time, 1);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Mute, reason, time, penaltyId);
}); });
// Add penalty to the player's penalty manager // Add penalty to the player's penalty manager
@@ -319,7 +328,6 @@ public partial class CS2_SimpleAdmin
} }
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Mute, _localizer); Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Mute, _localizer);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Mute, reason, time);
} }
[RequiresPermissions("@css/chat")] [RequiresPermissions("@css/chat")]
@@ -342,11 +350,11 @@ public partial class CS2_SimpleAdmin
} }
var steamid = steamId.SteamId64.ToString(); var steamid = steamId.SteamId64.ToString();
var reason = command.ArgCount >= 3 && command.GetArg(3).Length > 0 var reason = command.ArgCount >= 3
? command.GetArg(3) ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: (_localizer?["sa_unknown"] ?? "Unknown"); : _localizer?["sa_unknown"] ?? "Unknown";
int.TryParse(command.GetArg(2), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
if (!CheckValidMute(caller, time)) return; if (!CheckValidMute(caller, time)) return;
// Get player and admin info // Get player and admin info
@@ -366,10 +374,14 @@ public partial class CS2_SimpleAdmin
} }
else else
{ {
if (!caller.CanTarget(new SteamID(steamId.SteamId64)))
return;
// Asynchronous mute operation for offline players // Asynchronous mute operation for offline players
Task.Run(async () => Task.Run(async () =>
{ {
await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 1); int? penaltyId = await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 1);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Mute, reason, time, penaltyId);
}); });
Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Mute, _localizer); Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Mute, _localizer);
@@ -379,7 +391,6 @@ public partial class CS2_SimpleAdmin
// Log the mute command and respond to the command // Log the mute command and respond to the command
Helper.LogCommand(caller, command); Helper.LogCommand(caller, command);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Mute, reason, time);
} }
[RequiresPermissions("@css/chat")] [RequiresPermissions("@css/chat")]
@@ -390,7 +401,9 @@ public partial class CS2_SimpleAdmin
var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console"; var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console";
var pattern = command.GetArg(1); var pattern = command.GetArg(1);
var reason = command.GetArg(2); var reason = command.ArgCount >= 2
? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
if (pattern.Length <= 1) if (pattern.Length <= 1)
{ {
@@ -458,8 +471,6 @@ public partial class CS2_SimpleAdmin
if (Database == null) return; if (Database == null) return;
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
var reason = _localizer?["sa_unknown"] ?? "Unknown";
var targets = GetTarget(command); var targets = GetTarget(command);
if (targets == null) return; if (targets == null) return;
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList(); var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
@@ -469,13 +480,16 @@ public partial class CS2_SimpleAdmin
return; return;
} }
if (command.ArgCount >= 3 && command.GetArg(3).Length > 0) var reason = command.ArgCount >= 3
reason = command.GetArg(3); ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
var time = Helper.ParsePenaltyTime(command.GetArg(2));
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
if (!caller!.CanTarget(player)) return; if (!caller!.CanTarget(player)) return;
if (!int.TryParse(command.GetArg(2), out var time) && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime) if (time < 0 && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime)
{ {
DurationMenu.OpenMenu(caller, $"{_localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player, DurationMenu.OpenMenu(caller, $"{_localizer?["sa_silence"] ?? "Silence"}: {player.PlayerName}", player,
ManagePlayersMenu.SilenceMenu); ManagePlayersMenu.SilenceMenu);
@@ -502,7 +516,8 @@ public partial class CS2_SimpleAdmin
// Asynchronously handle silence logic // Asynchronously handle silence logic
Task.Run(async () => Task.Run(async () =>
{ {
await MuteManager.MutePlayer(playerInfo, adminInfo, reason, time, 2); // Assuming 2 is the type for silence int? penaltyId = await MuteManager.MutePlayer(playerInfo, adminInfo, reason, time, 2); // Assuming 2 is the type for silence
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Silence, reason, time, penaltyId);
}); });
// Add penalty to the player's penalty manager // Add penalty to the player's penalty manager
@@ -540,7 +555,6 @@ public partial class CS2_SimpleAdmin
} }
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Silence, _localizer); Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Silence, _localizer);
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Silence, reason, time);
} }
[RequiresPermissions("@css/chat")] [RequiresPermissions("@css/chat")]
@@ -563,11 +577,11 @@ public partial class CS2_SimpleAdmin
} }
var steamid = steamId.SteamId64.ToString(); var steamid = steamId.SteamId64.ToString();
var reason = command.ArgCount >= 3 && command.GetArg(3).Length > 0 var reason = command.ArgCount >= 3
? command.GetArg(3) ? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg))
: (_localizer?["sa_unknown"] ?? "Unknown"); : _localizer?["sa_unknown"] ?? "Unknown";
int.TryParse(command.GetArg(2), out var time); var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
if (!CheckValidMute(caller, time)) return; if (!CheckValidMute(caller, time)) return;
// Get player and admin info // Get player and admin info
@@ -587,10 +601,14 @@ public partial class CS2_SimpleAdmin
} }
else else
{ {
if (!caller.CanTarget(new SteamID(steamId.SteamId64)))
return;
// Asynchronous silence operation for offline players // Asynchronous silence operation for offline players
Task.Run(async () => Task.Run(async () =>
{ {
await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 2); int? penaltyId = await MuteManager.AddMuteBySteamid(steamid, adminInfo, reason, time, 2);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Silence, reason, time, penaltyId);
}); });
Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Silence, _localizer); Helper.SendDiscordPenaltyMessage(caller, steamid, reason, time, PenaltyType.Silence, _localizer);
@@ -600,7 +618,6 @@ public partial class CS2_SimpleAdmin
// Log the silence command and respond to the command // Log the silence command and respond to the command
Helper.LogCommand(caller, command); Helper.LogCommand(caller, command);
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Silence, reason, time);
} }
[RequiresPermissions("@css/chat")] [RequiresPermissions("@css/chat")]
@@ -611,7 +628,9 @@ public partial class CS2_SimpleAdmin
var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console"; var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console";
var pattern = command.GetArg(1); var pattern = command.GetArg(1);
var reason = command.GetArg(2); var reason = command.ArgCount >= 2
? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg))
: _localizer?["sa_unknown"] ?? "Unknown";
if (pattern.Length <= 1) if (pattern.Length <= 1)
{ {

View File

@@ -0,0 +1 @@
ALTER TABLE `sa_servers` ADD `rcon_password` varchar(128) NULL AFTER `hostname`;

View File

@@ -59,7 +59,7 @@ public partial class CS2_SimpleAdmin
new ServerManager().LoadServerData(); new ServerManager().LoadServerData();
} }
[GameEventHandler] [GameEventHandler(HookMode.Pre)]
public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info) public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
{ {
var player = @event.Userid; var player = @event.Userid;
@@ -103,7 +103,12 @@ public partial class CS2_SimpleAdmin
GravityPlayers.Remove(player); GravityPlayers.Remove(player);
if (player.UserId.HasValue) if (player.UserId.HasValue)
{
if (@event.Reason == 149)
info.DontBroadcast = true;
PlayersInfo.TryRemove(player.UserId.Value, out _); PlayersInfo.TryRemove(player.UserId.Value, out _);
}
var authorizedSteamId = player.AuthorizedSteamID; var authorizedSteamId = player.AuthorizedSteamID;
if (authorizedSteamId == null || !PermissionManager.AdminCache.TryGetValue(authorizedSteamId, if (authorizedSteamId == null || !PermissionManager.AdminCache.TryGetValue(authorizedSteamId,
@@ -151,7 +156,11 @@ public partial class CS2_SimpleAdmin
if (player == null || !player.IsValid || player.IsBot) if (player == null || !player.IsValid || player.IsBot)
return HookResult.Continue; return HookResult.Continue;
new PlayerManager().LoadPlayerData(player); if (player.UserId.HasValue && PlayersInfo.TryGetValue(player.UserId.Value, out PlayerInfo? value) &&
value.WaitingForKick)
return HookResult.Continue;
new PlayerManager().LoadPlayerData(player, true);
return HookResult.Continue; return HookResult.Continue;
} }

View File

@@ -36,6 +36,14 @@ public static class PlayerExtensions
AdminManager.GetPlayerImmunity(controller) >= AdminManager.GetPlayerImmunity(target); AdminManager.GetPlayerImmunity(controller) >= AdminManager.GetPlayerImmunity(target);
} }
public static bool CanTarget(this CCSPlayerController? controller, SteamID steamId)
{
if (controller is null) return true;
return AdminManager.CanPlayerTarget(new SteamID(controller.SteamID), steamId) ||
AdminManager.GetPlayerImmunity(controller) >= AdminManager.GetPlayerImmunity(steamId);
}
public static void SetSpeed(this CCSPlayerController? controller, float speed) public static void SetSpeed(this CCSPlayerController? controller, float speed)
{ {
var playerPawnValue = controller?.PlayerPawn.Value; var playerPawnValue = controller?.PlayerPawn.Value;

View File

@@ -79,11 +79,11 @@ internal static class Helper
); );
} }
public static bool IsValidSteamId64(string input) // public static bool IsValidSteamId64(string input)
{ // {
const string pattern = @"^\d{17}$"; // const string pattern = @"^\d{17}$";
return Regex.IsMatch(input, pattern); // return Regex.IsMatch(input, pattern);
} // }
public static bool ValidateSteamId(string input, out SteamID? steamId) public static bool ValidateSteamId(string input, out SteamID? steamId)
{ {
@@ -137,14 +137,35 @@ internal static class Helper
} }
} }
public static void KickPlayer(int userId, NetworkDisconnectionReason reason = NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED) public static void KickPlayer(int userId, NetworkDisconnectionReason reason = NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED, int delay = 0)
{ {
var player = Utilities.GetPlayerFromUserid(userId); var player = Utilities.GetPlayerFromUserid(userId);
if (player == null || !player.IsValid || player.IsHLTV) if (player == null || !player.IsValid || player.IsHLTV)
return; return;
if (player.UserId.HasValue)
CS2_SimpleAdmin.PlayersInfo[player.UserId.Value].WaitingForKick = true;
player.CommitSuicide(true, true);
if (delay > 0)
{
CS2_SimpleAdmin.Instance.AddTimer(delay, () =>
{
if (!player.IsValid || player.IsHLTV)
return;
player.Disconnect(reason); player.Disconnect(reason);
});
}
else
{
player.Disconnect(reason);
}
if (CS2_SimpleAdmin.UnlockedCommands && reason == NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
// if (!string.IsNullOrEmpty(reason)) // if (!string.IsNullOrEmpty(reason))
// { // {
@@ -159,9 +180,33 @@ internal static class Helper
// Server.ExecuteCommand($"kickid {userId} {reason}"); // Server.ExecuteCommand($"kickid {userId} {reason}");
} }
public static void KickPlayer(CCSPlayerController player, NetworkDisconnectionReason reason = NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED) public static void KickPlayer(CCSPlayerController player, NetworkDisconnectionReason reason = NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED, int delay = 0)
{
if (!player.IsValid || player.IsHLTV)
return;
if (player.UserId.HasValue)
CS2_SimpleAdmin.PlayersInfo[player.UserId.Value].WaitingForKick = true;
player.CommitSuicide(true, true);
if (delay > 0)
{
CS2_SimpleAdmin.Instance.AddTimer(delay, () =>
{
if (!player.IsValid || player.IsHLTV)
return;
player.Disconnect(reason);
});
}
else
{ {
player.Disconnect(reason); player.Disconnect(reason);
}
if (CS2_SimpleAdmin.UnlockedCommands && reason == NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
// if (!string.IsNullOrEmpty(reason)) // if (!string.IsNullOrEmpty(reason))
// { // {
@@ -176,6 +221,54 @@ internal static class Helper
// Server.ExecuteCommand($"kickid {userId} {reason}"); // Server.ExecuteCommand($"kickid {userId} {reason}");
} }
public static int ParsePenaltyTime(string time)
{
if (string.IsNullOrWhiteSpace(time))
{
CS2_SimpleAdmin._logger?.LogError("Time string cannot be null or empty.");
return -1;
}
var timeUnits = new Dictionary<string, int>
{
{ "m", 1 }, // Minute
{ "h", 60 }, // Hour
{ "d", 1440 }, // Day (24 * 60)
{ "w", 10080 }, // Week (7 * 24 * 60)
{ "mo", 43200 }, // Month (30 * 24 * 60)
{ "y", 525600 } // Year (365 * 24 * 60)
};
// Check if the input is purely numeric (e.g., "10" for 10 minutes)
if (int.TryParse(time, out var numericMinutes))
{
return numericMinutes;
}
int totalMinutes = 0;
var regex = new Regex(@"(\d+)([a-z]+)");
var matches = regex.Matches(time);
foreach (Match match in matches)
{
var value = int.Parse(match.Groups[1].Value); // Numeric part
var unit = match.Groups[2].Value; // Unit part
if (timeUnits.TryGetValue(unit, out var minutesPerUnit))
{
totalMinutes += value * minutesPerUnit;
}
else
{
throw new ArgumentException($"Invalid time unit '{unit}' in time string.", nameof(time));
}
}
return totalMinutes;
}
public static void PrintToCenterAll(string message) public static void PrintToCenterAll(string message)
{ {
Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false }).ToList().ForEach(controller => Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false }).ToList().ForEach(controller =>
@@ -632,28 +725,28 @@ internal static class Helper
commandString])); commandString]));
} }
public static IMenu? CreateMenu(string title) public static IMenu? CreateMenu(string title, Action<CCSPlayerController>? backAction = null)
{ {
var menuType = CS2_SimpleAdmin.Instance.Config.MenuConfigs.MenuType.ToLower(); var menuType = CS2_SimpleAdmin.Instance.Config.MenuConfigs.MenuType.ToLower();
var menu = menuType switch var menu = menuType switch
{ {
_ when menuType.Equals("selectable", StringComparison.CurrentCultureIgnoreCase) => _ when menuType.Equals("selectable", StringComparison.CurrentCultureIgnoreCase) =>
CS2_SimpleAdmin.MenuApi?.NewMenu(title), CS2_SimpleAdmin.MenuApi?.GetMenu(title),
_ when menuType.Equals("dynamic", StringComparison.CurrentCultureIgnoreCase) => _ when menuType.Equals("dynamic", StringComparison.CurrentCultureIgnoreCase) =>
CS2_SimpleAdmin.MenuApi?.NewMenuForcetype(title, MenuType.ButtonMenu), CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.ButtonMenu),
_ when menuType.Equals("center", StringComparison.CurrentCultureIgnoreCase) => _ when menuType.Equals("center", StringComparison.CurrentCultureIgnoreCase) =>
CS2_SimpleAdmin.MenuApi?.NewMenuForcetype(title, MenuType.CenterMenu), CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.CenterMenu),
_ when menuType.Equals("chat", StringComparison.CurrentCultureIgnoreCase) => _ when menuType.Equals("chat", StringComparison.CurrentCultureIgnoreCase) =>
CS2_SimpleAdmin.MenuApi?.NewMenuForcetype(title, MenuType.ChatMenu), CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.ChatMenu),
_ when menuType.Equals("console", StringComparison.CurrentCultureIgnoreCase) => _ when menuType.Equals("console", StringComparison.CurrentCultureIgnoreCase) =>
CS2_SimpleAdmin.MenuApi?.NewMenuForcetype(title, MenuType.ConsoleMenu), CS2_SimpleAdmin.MenuApi?.GetMenuForcetype(title, MenuType.ConsoleMenu),
_ => CS2_SimpleAdmin.MenuApi?.NewMenu(title) _ => CS2_SimpleAdmin.MenuApi?.GetMenu(title)
}; };
return menu; return menu;

View File

@@ -10,9 +10,9 @@ namespace CS2_SimpleAdmin.Managers;
internal class BanManager(Database.Database? database) internal class BanManager(Database.Database? database)
{ {
public async Task BanPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0) public async Task<int?> BanPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0)
{ {
if (database == null) return; if (database == null) return null;
DateTime now = Time.ActualDateTime(); DateTime now = Time.ActualDateTime();
DateTime futureTime = now.AddMinutes(time); DateTime futureTime = now.AddMinutes(time);
@@ -20,11 +20,16 @@ internal class BanManager(Database.Database? database)
await using MySqlConnection connection = await database.GetConnectionAsync(); await using MySqlConnection connection = await database.GetConnectionAsync();
try try
{ {
const string sql = const string sql = """
"INSERT INTO `sa_bans` (`player_steamid`, `player_name`, `player_ip`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " +
"VALUES (@playerSteamid, @playerName, @playerIp, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid)";
await connection.ExecuteAsync(sql, new INSERT INTO `sa_bans`
(`player_steamid`, `player_name`, `player_ip`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`)
VALUES
(@playerSteamid, @playerName, @playerIp, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid);
SELECT LAST_INSERT_ID();
""";
var banId = await connection.ExecuteScalarAsync<int?>(sql, new
{ {
playerSteamid = player.SteamId.SteamId64.ToString(), playerSteamid = player.SteamId.SteamId64.ToString(),
playerName = player.Name, playerName = player.Name,
@@ -37,15 +42,19 @@ internal class BanManager(Database.Database? database)
created = now, created = now,
serverid = CS2_SimpleAdmin.ServerId serverid = CS2_SimpleAdmin.ServerId
}); });
}
catch { }
}
public async Task AddBanBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0) return banId;
}
catch
{ {
if (database == null) return; return null;
}
}
if (string.IsNullOrEmpty(playerSteamId)) return; public async Task<int?> AddBanBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0)
{
if (database == null) return null;
if (string.IsNullOrEmpty(playerSteamId)) return null;
DateTime now = Time.ActualDateTime(); DateTime now = Time.ActualDateTime();
DateTime futureTime = now.AddMinutes(time); DateTime futureTime = now.AddMinutes(time);
@@ -54,10 +63,16 @@ internal class BanManager(Database.Database? database)
{ {
await using MySqlConnection connection = await database.GetConnectionAsync(); await using MySqlConnection connection = await database.GetConnectionAsync();
var sql = "INSERT INTO `sa_bans` (`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " + const string sql = """
"VALUES (@playerSteamid, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid)";
await connection.ExecuteAsync(sql, new INSERT INTO `sa_bans`
(`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`)
VALUES
(@playerSteamid, @adminSteamid, @adminName, @banReason, @duration, @ends, @created, @serverid);
SELECT LAST_INSERT_ID();
""";
var banId = await connection.ExecuteScalarAsync<int?>(sql, new
{ {
playerSteamid = playerSteamId, playerSteamid = playerSteamId,
adminSteamid = issuer?.SteamId.SteamId64.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", adminSteamid = issuer?.SteamId.SteamId64.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
@@ -68,8 +83,13 @@ internal class BanManager(Database.Database? database)
created = now, created = now,
serverid = CS2_SimpleAdmin.ServerId serverid = CS2_SimpleAdmin.ServerId
}); });
return banId;
}
catch (Exception)
{
return null;
} }
catch { }
} }
public async Task AddBanByIp(string playerIp, PlayerInfo? issuer, string reason, int time = 0) public async Task AddBanByIp(string playerIp, PlayerInfo? issuer, string reason, int time = 0)
@@ -383,7 +403,7 @@ internal class BanManager(Database.Database? database)
foreach (var player in filteredPlayers.Where(player => bannedSteamIds.Contains(player.SteamID) || foreach (var player in filteredPlayers.Where(player => bannedSteamIds.Contains(player.SteamID) ||
(checkIpBans && bannedIps.Contains(player.IpAddress ?? "")))) (checkIpBans && bannedIps.Contains(player.IpAddress ?? ""))))
{ {
if (!player.UserId.HasValue) continue; if (!player.UserId.HasValue || CS2_SimpleAdmin.PlayersInfo[player.UserId.Value].WaitingForKick) continue;
await Server.NextFrameAsync(() => await Server.NextFrameAsync(() =>
{ {

View File

@@ -6,9 +6,9 @@ namespace CS2_SimpleAdmin.Managers;
internal class MuteManager(Database.Database? database) internal class MuteManager(Database.Database? database)
{ {
public async Task MutePlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0, int type = 0) public async Task<int?> MutePlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0, int type = 0)
{ {
if (database == null) return; if (database == null) return null;
var now = Time.ActualDateTime(); var now = Time.ActualDateTime();
var futureTime = now.AddMinutes(time); var futureTime = now.AddMinutes(time);
@@ -23,11 +23,16 @@ internal class MuteManager(Database.Database? database)
try try
{ {
await using var connection = await database.GetConnectionAsync(); await using var connection = await database.GetConnectionAsync();
const string sql = const string sql = """
"INSERT INTO `sa_mutes` (`player_steamid`, `player_name`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `type`, `server_id`) " +
"VALUES (@playerSteamid, @playerName, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @type, @serverid)";
await connection.ExecuteAsync(sql, new INSERT INTO `sa_mutes`
(`player_steamid`, `player_name`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `type`, `server_id`)
VALUES
(@playerSteamid, @playerName, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @type, @serverid);
SELECT LAST_INSERT_ID();
""";
var muteId = await connection.ExecuteScalarAsync<int?>(sql, new
{ {
playerSteamid = player.SteamId.SteamId64.ToString(), playerSteamid = player.SteamId.SteamId64.ToString(),
playerName = player.Name, playerName = player.Name,
@@ -40,19 +45,20 @@ internal class MuteManager(Database.Database? database)
type = muteType, type = muteType,
serverid = CS2_SimpleAdmin.ServerId serverid = CS2_SimpleAdmin.ServerId
}); });
return muteId;
} }
catch (Exception ex) catch (Exception ex)
{ {
CS2_SimpleAdmin._logger?.LogError(ex.Message); CS2_SimpleAdmin._logger?.LogError(ex.Message);
}; return null;
}
} }
public async Task AddMuteBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0, int type = 0) public async Task<int?> AddMuteBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0, int type = 0)
{ {
if (database == null) return; if (database == null) return null;
if (string.IsNullOrEmpty(playerSteamId)) return null;
if (string.IsNullOrEmpty(playerSteamId)) return;
var now = Time.ActualDateTime(); var now = Time.ActualDateTime();
var futureTime = now.AddMinutes(time); var futureTime = now.AddMinutes(time);
@@ -67,10 +73,16 @@ internal class MuteManager(Database.Database? database)
try try
{ {
await using var connection = await database.GetConnectionAsync(); await using var connection = await database.GetConnectionAsync();
const string sql = "INSERT INTO `sa_mutes` (`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `type`, `server_id`) " + const string sql = """
"VALUES (@playerSteamid, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @type, @serverid)";
await connection.ExecuteAsync(sql, new INSERT INTO `sa_mutes`
(`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `type`, `server_id`)
VALUES
(@playerSteamid, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @type, @serverid);
SELECT LAST_INSERT_ID();
""";
var muteId = await connection.ExecuteScalarAsync<int?>(sql, new
{ {
playerSteamid = playerSteamId, playerSteamid = playerSteamId,
adminSteamid = issuer?.SteamId.SteamId64.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", adminSteamid = issuer?.SteamId.SteamId64.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
@@ -82,8 +94,13 @@ internal class MuteManager(Database.Database? database)
type = muteType, type = muteType,
serverid = CS2_SimpleAdmin.ServerId serverid = CS2_SimpleAdmin.ServerId
}); });
return muteId;
}
catch
{
return null;
} }
catch { };
} }
public async Task<List<dynamic>> IsPlayerMuted(string steamId) public async Task<List<dynamic>> IsPlayerMuted(string steamId)

View File

@@ -14,7 +14,7 @@ public class PlayerManager
{ {
private readonly CS2_SimpleAdminConfig _config = CS2_SimpleAdmin.Instance.Config; private readonly CS2_SimpleAdminConfig _config = CS2_SimpleAdmin.Instance.Config;
public void LoadPlayerData(CCSPlayerController player) public void LoadPlayerData(CCSPlayerController player, bool fullConnect = false)
{ {
if (player.IsBot || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1")) if (player.IsBot || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1"))
return; return;
@@ -125,15 +125,14 @@ public class PlayerManager
if (victim == null || !victim.UserId.HasValue) return; if (victim == null || !victim.UserId.HasValue) return;
if (CS2_SimpleAdmin.UnlockedCommands)
Server.ExecuteCommand($"banid 1 {userId}");
Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED); Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
}); });
return; return;
} }
if (fullConnect)
{
var warns = await CS2_SimpleAdmin.Instance.WarnManager.GetPlayerWarns(CS2_SimpleAdmin.PlayersInfo[userId], false); var warns = await CS2_SimpleAdmin.Instance.WarnManager.GetPlayerWarns(CS2_SimpleAdmin.PlayersInfo[userId], false);
var (totalMutes, totalGags, totalSilences) = var (totalMutes, totalGags, totalSilences) =
await CS2_SimpleAdmin.Instance.MuteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId]); await CS2_SimpleAdmin.Instance.MuteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId]);
@@ -184,8 +183,9 @@ public class PlayerManager
} }
} }
} }
}
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.NotifyPenaltiesToAdminOnConnect) if (CS2_SimpleAdmin.Instance.Config.OtherSettings.NotifyPenaltiesToAdminOnConnect && fullConnect)
{ {
await Server.NextFrameAsync(() => await Server.NextFrameAsync(() =>
{ {

View File

@@ -38,6 +38,7 @@ public class ServerManager
var address = $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue<int>()}"; var address = $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue<int>()}";
var hostname = ConVar.Find("hostname")!.StringValue; var hostname = ConVar.Find("hostname")!.StringValue;
var rconPassword = ConVar.Find("rcon_password")!.StringValue;
CS2_SimpleAdmin.IpAddress = address; CS2_SimpleAdmin.IpAddress = address;
CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress); CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress);
@@ -47,27 +48,28 @@ public class ServerManager
try try
{ {
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
var addressExists = await connection.ExecuteScalarAsync<bool>(
"SELECT COUNT(*) FROM sa_servers WHERE address = @address", int? serverId = await connection.ExecuteScalarAsync<int?>(
"SELECT id FROM sa_servers WHERE address = @address",
new { address }); new { address });
if (!addressExists) if (serverId == null)
{ {
await connection.ExecuteAsync( await connection.ExecuteAsync(
"INSERT INTO sa_servers (address, hostname) VALUES (@address, @hostname)", "INSERT INTO sa_servers (address, hostname, rcon_password) VALUES (@address, @hostname, @rconPassword)",
new { address, hostname }); new { address, hostname, rconPassword });
serverId = await connection.ExecuteScalarAsync<int>(
"SELECT id FROM sa_servers WHERE address = @address",
new { address });
} }
else else
{ {
await connection.ExecuteAsync( await connection.ExecuteAsync(
"UPDATE `sa_servers` SET `hostname` = @hostname WHERE `address` = @address", "UPDATE sa_servers SET hostname = @hostname, rcon_password = @rconPassword WHERE address = @address",
new { address, hostname }); new { address, hostname, rconPassword });
} }
int? serverId = await connection.ExecuteScalarAsync<int>(
"SELECT `id` FROM `sa_servers` WHERE `address` = @address",
new { address });
CS2_SimpleAdmin.ServerId = serverId; CS2_SimpleAdmin.ServerId = serverId;
if (CS2_SimpleAdmin.ServerId != null) if (CS2_SimpleAdmin.ServerId != null)

View File

@@ -6,9 +6,9 @@ namespace CS2_SimpleAdmin.Managers;
internal class WarnManager(Database.Database? database) internal class WarnManager(Database.Database? database)
{ {
public async Task WarnPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0) public async Task<int?> WarnPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0)
{ {
if (database == null) return; if (database == null) return null;
var now = Time.ActualDateTime(); var now = Time.ActualDateTime();
var futureTime = now.AddMinutes(time); var futureTime = now.AddMinutes(time);
@@ -16,11 +16,16 @@ internal class WarnManager(Database.Database? database)
try try
{ {
await using var connection = await database.GetConnectionAsync(); await using var connection = await database.GetConnectionAsync();
const string sql = const string sql = """
"INSERT INTO `sa_warns` (`player_steamid`, `player_name`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " +
"VALUES (@playerSteamid, @playerName, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @serverid)";
await connection.ExecuteAsync(sql, new INSERT INTO `sa_warns`
(`player_steamid`, `player_name`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`)
VALUES
(@playerSteamid, @playerName, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @serverid);
SELECT LAST_INSERT_ID();
""";
var warnId = await connection.ExecuteScalarAsync<int?>(sql, new
{ {
playerSteamid = player.SteamId.SteamId64.ToString(), playerSteamid = player.SteamId.SteamId64.ToString(),
playerName = player.Name, playerName = player.Name,
@@ -32,14 +37,19 @@ internal class WarnManager(Database.Database? database)
created = now, created = now,
serverid = CS2_SimpleAdmin.ServerId serverid = CS2_SimpleAdmin.ServerId
}); });
return warnId;
}
catch
{
return null;
} }
catch { };
} }
public async Task AddWarnBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0) public async Task<int?> AddWarnBySteamid(string playerSteamId, PlayerInfo? issuer, string reason, int time = 0)
{ {
if (database == null) return; if (database == null) return null;
if (string.IsNullOrEmpty(playerSteamId)) return; if (string.IsNullOrEmpty(playerSteamId)) return null;
var now = Time.ActualDateTime(); var now = Time.ActualDateTime();
var futureTime = now.AddMinutes(time); var futureTime = now.AddMinutes(time);
@@ -47,10 +57,16 @@ internal class WarnManager(Database.Database? database)
try try
{ {
await using var connection = await database.GetConnectionAsync(); await using var connection = await database.GetConnectionAsync();
const string sql = "INSERT INTO `sa_warns` (`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`) " + const string sql = """
"VALUES (@playerSteamid, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @serverid)";
await connection.ExecuteAsync(sql, new INSERT INTO `sa_warns`
(`player_steamid`, `admin_steamid`, `admin_name`, `reason`, `duration`, `ends`, `created`, `server_id`)
VALUES
(@playerSteamid, @adminSteamid, @adminName, @muteReason, @duration, @ends, @created, @serverid);
SELECT LAST_INSERT_ID();
""";
var warnId = await connection.ExecuteScalarAsync<int?>(sql, new
{ {
playerSteamid = playerSteamId, playerSteamid = playerSteamId,
adminSteamid = issuer?.SteamId.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", adminSteamid = issuer?.SteamId.ToString() ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console",
@@ -61,8 +77,13 @@ internal class WarnManager(Database.Database? database)
created = now, created = now,
serverid = CS2_SimpleAdmin.ServerId serverid = CS2_SimpleAdmin.ServerId
}); });
return warnId;
}
catch
{
return null;
} }
catch { };
} }
public async Task<List<dynamic>> GetPlayerWarns(PlayerInfo player, bool active = true) public async Task<List<dynamic>> GetPlayerWarns(PlayerInfo player, bool active = true)

View File

@@ -6,9 +6,9 @@ namespace CS2_SimpleAdmin.Menus;
public static class AdminMenu public static class AdminMenu
{ {
public static IMenu? CreateMenu(string title) public static IMenu? CreateMenu(string title, Action<CCSPlayerController>? backAction = null)
{ {
return Helper.CreateMenu(title); return Helper.CreateMenu(title, backAction);
// return CS2_SimpleAdmin.Instance.Config.UseChatMenu ? new ChatMenu(title) : new CenterHtmlMenu(title, CS2_SimpleAdmin.Instance); // return CS2_SimpleAdmin.Instance.Config.UseChatMenu ? new ChatMenu(title) : new CenterHtmlMenu(title, CS2_SimpleAdmin.Instance);
} }

View File

@@ -1 +1 @@
1.7.0a 1.7.1a

View File

@@ -17,8 +17,8 @@ public interface ICS2_SimpleAdminApi
public Dictionary<PenaltyType, List<(DateTime EndDateTime, int Duration, bool Passed)>> GetPlayerMuteStatus(CCSPlayerController player); public Dictionary<PenaltyType, List<(DateTime EndDateTime, int Duration, bool Passed)>> GetPlayerMuteStatus(CCSPlayerController player);
public event Action<PlayerInfo, PlayerInfo?, PenaltyType, string, int, int?>? OnPlayerPenaltied; public event Action<PlayerInfo, PlayerInfo?, PenaltyType, string, int, int?, int?>? OnPlayerPenaltied;
public event Action<SteamID, PlayerInfo?, PenaltyType, string, int, int?>? OnPlayerPenaltiedAdded; public event Action<SteamID, PlayerInfo?, PenaltyType, string, int, int?, int?>? OnPlayerPenaltiedAdded;
public void IssuePenalty(CCSPlayerController player, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1); public void IssuePenalty(CCSPlayerController player, CCSPlayerController? admin, PenaltyType penaltyType, string reason, int duration = -1);
public void LogCommand(CCSPlayerController? caller, string command); public void LogCommand(CCSPlayerController? caller, string command);

View File

@@ -25,6 +25,7 @@ public class PlayerInfo(
public int TotalGags { get; set; } = totalGags; public int TotalGags { get; set; } = totalGags;
public int TotalSilences { get; set; } = totalSilences; public int TotalSilences { get; set; } = totalSilences;
public int TotalWarns { get; set; } = totalWarns; public int TotalWarns { get; set; } = totalWarns;
public bool WaitingForKick { get; set; } = false;
public DiePosition? DiePosition { get; set; } public DiePosition? DiePosition { get; set; }
} }

View File

@@ -70,7 +70,7 @@ public class CS2_SimpleAdmin_ExampleModule: BasePlugin
} }
private void OnPlayerPenaltied(PlayerInfo player, PlayerInfo? admin, PenaltyType penaltyType, private void OnPlayerPenaltied(PlayerInfo player, PlayerInfo? admin, PenaltyType penaltyType,
string reason, int duration, int? serverId) string reason, int duration, int? penaltyId, int? serverId)
{ {
if (penaltyType == PenaltyType.Ban) if (penaltyType == PenaltyType.Ban)
{ {
@@ -82,6 +82,7 @@ public class CS2_SimpleAdmin_ExampleModule: BasePlugin
case PenaltyType.Ban: case PenaltyType.Ban:
{ {
Logger.LogInformation("Ban issued"); Logger.LogInformation("Ban issued");
Logger.LogInformation($"Id = {penaltyId}");
break; break;
} }
case PenaltyType.Kick: case PenaltyType.Kick:
@@ -92,6 +93,7 @@ public class CS2_SimpleAdmin_ExampleModule: BasePlugin
case PenaltyType.Gag: case PenaltyType.Gag:
{ {
Logger.LogInformation("Gag issued"); Logger.LogInformation("Gag issued");
Logger.LogInformation($"Id = {penaltyId}");
break; break;
} }
case PenaltyType.Mute: case PenaltyType.Mute:
@@ -120,13 +122,14 @@ public class CS2_SimpleAdmin_ExampleModule: BasePlugin
} }
private void OnPlayerPenaltiedAdded(SteamID steamId, PlayerInfo? admin, PenaltyType penaltyType, private void OnPlayerPenaltiedAdded(SteamID steamId, PlayerInfo? admin, PenaltyType penaltyType,
string reason, int duration, int? serverId) string reason, int duration, int? penaltyId, int? serverId)
{ {
switch (penaltyType) switch (penaltyType)
{ {
case PenaltyType.Ban: case PenaltyType.Ban:
{ {
Logger.LogInformation("Ban added"); Logger.LogInformation("Ban added");
Logger.LogInformation($"Id = {penaltyId}");
break; break;
} }
case PenaltyType.Kick: case PenaltyType.Kick:
@@ -137,6 +140,7 @@ public class CS2_SimpleAdmin_ExampleModule: BasePlugin
case PenaltyType.Gag: case PenaltyType.Gag:
{ {
Logger.LogInformation("Gag added"); Logger.LogInformation("Gag added");
Logger.LogInformation($"Id = {penaltyId}");
break; break;
} }
case PenaltyType.Mute: case PenaltyType.Mute: