mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-11-07 20:17:04 +01:00
Migrate menus and votes to Panorama UI Kit
Replace MenuManagerCS2 with Panorama UI Kit for the admin menus and css_vote. Layout names (menu, vote, banner, toast) are configurable under MenuConfig and preloaded on startup; MenuType is removed and ConfigVersion bumped to 26. - Drop MenuManagerApi.dll and the old chat menu classes - Reference PanoramaUiKit.Shared.dll, bump CounterStrikeSharp to 1.0.376 - Add .editorconfig and CODING_CONVENTIONS.md, apply them codebase-wide - Remove the CS2-SimpleAdmin-docs site - Rewrite README for the fork
This commit is contained in:
parent
03a454b1b5
commit
460d8b2b85
112 changed files with 5559 additions and 36371 deletions
|
|
@ -11,9 +11,9 @@ public static class RegisterCommands
|
|||
{
|
||||
internal static readonly Dictionary<string, IList<CommandDefinition>> _commandDefinitions =
|
||||
new(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
|
||||
private delegate void CommandCallback(CCSPlayerController? caller, CommandInfo.CommandCallback callback);
|
||||
|
||||
|
||||
private static readonly string CommandsPath = Path.Combine(CS2_SimpleAdmin.ConfigDirectory, "Commands.json");
|
||||
private static readonly List<CommandMapping> CommandMappings =
|
||||
[
|
||||
|
|
@ -101,7 +101,7 @@ public static class RegisterCommands
|
|||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
private static void CreateConfig()
|
||||
{
|
||||
var commands = new CommandsConfig
|
||||
CommandsConfig commands = new CommandsConfig
|
||||
{
|
||||
Commands = new Dictionary<string, Command>
|
||||
{
|
||||
|
|
@ -161,14 +161,14 @@ public static class RegisterCommands
|
|||
{ "css_adminvoice", new Command { Aliases = ["css_adminvoice", "css_listenall"] } }
|
||||
}
|
||||
};
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
|
||||
JsonSerializerOptions options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(commands, options);
|
||||
string json = JsonSerializer.Serialize(commands, options);
|
||||
File.WriteAllText(CommandsPath, json);
|
||||
}
|
||||
|
||||
|
|
@ -179,46 +179,52 @@ public static class RegisterCommands
|
|||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
private static void Register()
|
||||
{
|
||||
var json = File.ReadAllText(CommandsPath);
|
||||
var commandsConfig = JsonSerializer.Deserialize<CommandsConfig>(json,
|
||||
string json = File.ReadAllText(CommandsPath);
|
||||
CommandsConfig? commandsConfig = JsonSerializer.Deserialize<CommandsConfig>(json,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
|
||||
if (commandsConfig?.Commands != null)
|
||||
{
|
||||
foreach (var command in commandsConfig.Commands)
|
||||
foreach (KeyValuePair<string, Command> command in commandsConfig.Commands)
|
||||
{
|
||||
if (command.Value.Aliases == null) continue;
|
||||
|
||||
if (command.Value.Aliases == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CS2_SimpleAdmin._logger?.LogInformation(
|
||||
$"Registering command: `{command.Key}` with aliases: `{string.Join(", ", command.Value.Aliases)}`");
|
||||
|
||||
var mapping = CommandMappings.FirstOrDefault(m => m.CommandKey == command.Key);
|
||||
if (mapping == null || command.Value.Aliases.Length == 0) continue;
|
||||
|
||||
foreach (var alias in command.Value.Aliases)
|
||||
|
||||
CommandMapping? mapping = CommandMappings.FirstOrDefault(m => m.CommandKey == command.Key);
|
||||
if (mapping == null || command.Value.Aliases.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string alias in command.Value.Aliases)
|
||||
{
|
||||
CS2_SimpleAdmin.Instance.AddCommand(alias, "", mapping.Callback);
|
||||
}
|
||||
}
|
||||
|
||||
// Commands added after Commands.json was generated are registered under their default name
|
||||
foreach (var mapping in CommandMappings.Where(m => !commandsConfig.Commands.ContainsKey(m.CommandKey)))
|
||||
foreach (CommandMapping? mapping in CommandMappings.Where(m => !commandsConfig.Commands.ContainsKey(m.CommandKey)))
|
||||
{
|
||||
CS2_SimpleAdmin._logger?.LogInformation($"Registering command: `{mapping.CommandKey}` (not in Commands.json, using default alias)");
|
||||
CS2_SimpleAdmin.Instance.AddCommand(mapping.CommandKey, "", mapping.Callback);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (name, definitions) in _commandDefinitions)
|
||||
|
||||
foreach ((string? name, IList<CommandDefinition>? definitions) in _commandDefinitions)
|
||||
{
|
||||
foreach (var definition in definitions)
|
||||
foreach (CommandDefinition definition in definitions)
|
||||
{
|
||||
CS2_SimpleAdmin._logger?.LogInformation($"Registering custom command: `{name}`");
|
||||
CS2_SimpleAdmin.Instance.AddCommand(name, definition.Description, definition.Callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents the JSON configuration structure for commands.
|
||||
/// </summary>
|
||||
|
|
@ -226,7 +232,7 @@ public static class RegisterCommands
|
|||
{
|
||||
public Dictionary<string, Command>? Commands { get; init; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a command definition containing a list of aliases.
|
||||
/// </summary>
|
||||
|
|
@ -234,7 +240,7 @@ public static class RegisterCommands
|
|||
{
|
||||
public string[]? Aliases { get; init; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Maps a command key to its respective command callback handler.
|
||||
/// </summary>
|
||||
|
|
@ -243,4 +249,4 @@ public static class RegisterCommands
|
|||
public string CommandKey { get; } = commandKey;
|
||||
public CommandInfo.CommandCallback Callback { get; } = callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using CounterStrikeSharp.API;
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.ValveConstants.Protobuf;
|
||||
using CS2_SimpleAdmin.Managers;
|
||||
|
|
@ -21,34 +22,38 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<#userid or name> [time in minutes/0 perm] [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnBanCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
if (command.ArgCount < 2)
|
||||
{
|
||||
return;
|
||||
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, Connected: PlayerConnectedState.Connected, IsHLTV: false }).ToList();
|
||||
}
|
||||
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player is { IsValid: true, Connected: PlayerConnectedState.Connected, IsHLTV: false }).ToList();
|
||||
|
||||
if (playersToTarget.Count > 1 && Config.OtherSettings.DisableDangerousCommands || playersToTarget.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var reason = command.ArgCount >= 3
|
||||
? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg)).Trim()
|
||||
: _localizer?["sa_unknown"] ?? "Unknown";
|
||||
|
||||
reason = string.IsNullOrWhiteSpace(reason) ? _localizer?["sa_unknown"] ?? "Unknown" : reason;
|
||||
var time = Helper.ParsePenaltyTime(command.GetArg(2));
|
||||
string reason = Helper.GetArgsReason(command, 3);
|
||||
int time = Helper.ParsePenaltyTime(command.GetArg(2));
|
||||
|
||||
playersToTarget.ForEach(player =>
|
||||
{
|
||||
if (!caller.CanTarget(player)) return;
|
||||
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (time < 0 && caller != null && caller.IsValid && Config.OtherSettings.ShowBanMenuIfNoTime)
|
||||
{
|
||||
DurationMenu.OpenMenu(caller, $"{_localizer?["sa_ban"] ?? "Ban"}: {player.PlayerName}", player,
|
||||
ManagePlayersMenu.BanMenu);
|
||||
BasicMenu.CreatePenaltyMenu(caller, player, PenaltyType.Ban).OpenMenu(caller);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -69,18 +74,27 @@ public partial class CS2_SimpleAdmin
|
|||
/// <param name="silent">If true, suppresses command logging.</param>
|
||||
internal void Ban(CCSPlayerController? caller, CCSPlayerController player, int time, string reason, string? callerName = null, BanManager? banManager = null, CommandInfo? command = null, bool silent = false)
|
||||
{
|
||||
if (DatabaseProvider == null || !player.IsValid || !player.UserId.HasValue) return;
|
||||
if (!caller.CanTarget(player)) return;
|
||||
if (!CheckValidBan(caller, time)) return;
|
||||
if (DatabaseProvider == null || !player.IsValid || !player.UserId.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CheckValidBan(caller, time))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set default caller name if not provided
|
||||
callerName = !string.IsNullOrEmpty(caller?.PlayerName)
|
||||
? caller.PlayerName
|
||||
: (_localizer?["sa_console"] ?? "Console");
|
||||
|
||||
callerName = Helper.GetCallerName(caller);
|
||||
|
||||
// Get player and admin information
|
||||
var playerInfo = PlayersInfo[player.SteamID];
|
||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.SteamID] : null;
|
||||
PlayerInfo playerInfo = PlayersInfo[player.SteamID];
|
||||
PlayerInfo? adminInfo = Helper.GetAdminInfo(caller);
|
||||
|
||||
// Asynchronously handle banning logic
|
||||
Task.Run(async () =>
|
||||
|
|
@ -93,13 +107,25 @@ public partial class CS2_SimpleAdmin
|
|||
});
|
||||
|
||||
// Determine message keys and arguments based on ban time
|
||||
var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = time == 0
|
||||
? ("sa_player_ban_message_perm", "sa_admin_ban_message_perm",
|
||||
[reason, "CALLER"],
|
||||
["CALLER", player.PlayerName, reason])
|
||||
: ("sa_player_ban_message_time", "sa_admin_ban_message_time",
|
||||
new object[] { reason, time, "CALLER" },
|
||||
new object[] { "CALLER", player.PlayerName, reason, time });
|
||||
string? messageKey;
|
||||
string? activityMessageKey;
|
||||
object[]? centerArgs;
|
||||
object[]? adminActivityArgs;
|
||||
|
||||
if (time == 0)
|
||||
{
|
||||
messageKey = "sa_player_ban_message_perm";
|
||||
activityMessageKey = "sa_admin_ban_message_perm";
|
||||
centerArgs = [reason, "CALLER"];
|
||||
adminActivityArgs = ["CALLER", player.PlayerName, reason];
|
||||
}
|
||||
else
|
||||
{
|
||||
messageKey = "sa_player_ban_message_time";
|
||||
activityMessageKey = "sa_admin_ban_message_time";
|
||||
centerArgs = new object[] { reason, time, "CALLER" };
|
||||
adminActivityArgs = new object[] { "CALLER", player.PlayerName, reason, time };
|
||||
}
|
||||
|
||||
// Display center message to the player
|
||||
Helper.DisplayCenterMessage(player, messageKey, callerName, centerArgs);
|
||||
|
|
@ -125,11 +151,15 @@ public partial class CS2_SimpleAdmin
|
|||
if (!silent)
|
||||
{
|
||||
if (command == null)
|
||||
Helper.LogCommand(caller, $"css_ban {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {time} {reason}");
|
||||
{
|
||||
Helper.LogCommand(caller, $"css_ban {Helper.GetLogName(player)} {time} {reason}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Helper.LogCommand(caller, command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Ban, _localizer);
|
||||
}
|
||||
|
||||
|
|
@ -144,23 +174,26 @@ public partial class CS2_SimpleAdmin
|
|||
internal void AddBan(CCSPlayerController? caller, SteamID steamid, int time, string reason, BanManager? banManager = null)
|
||||
{
|
||||
// Set default caller name if not provided
|
||||
var callerName = !string.IsNullOrEmpty(caller?.PlayerName)
|
||||
? caller.PlayerName
|
||||
: (_localizer?["sa_console"] ?? "Console");
|
||||
|
||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.SteamID] : null;
|
||||
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64);
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
PlayerInfo? adminInfo = Helper.GetAdminInfo(caller);
|
||||
CCSPlayerController? player = Helper.GetPlayerFromSteamid64(steamid.SteamId64);
|
||||
if (player != null && player.IsValid)
|
||||
{
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Ban(caller, player, time, reason, callerName, silent: true);
|
||||
//command.ReplyToCommand($"Banned player {player.PlayerName}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!caller.CanTarget(steamid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Asynchronous ban operation if player is not online or not found
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -171,7 +204,7 @@ public partial class CS2_SimpleAdmin
|
|||
penaltyId);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Helper.SendDiscordPenaltyMessage(caller, steamid.SteamId64.ToString(), reason, time, PenaltyType.Ban, _localizer);
|
||||
}
|
||||
}
|
||||
|
|
@ -185,34 +218,41 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<steamid> [time in minutes/0 perm] [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnAddBanCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (DatabaseProvider == null) return;
|
||||
var callerName = caller?.PlayerName ?? _localizer?["sa_console"] ?? "Console";
|
||||
if (command.ArgCount < 2 || string.IsNullOrEmpty(command.GetArg(1))) return;
|
||||
if (!Helper.ValidateSteamId(command.GetArg(1), out var steamId) || steamId == null)
|
||||
if (DatabaseProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string callerName = caller?.PlayerName ?? _localizer?["sa_console"] ?? "Console";
|
||||
if (command.ArgCount < 2 || string.IsNullOrEmpty(command.GetArg(1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Helper.ValidateSteamId(command.GetArg(1), out SteamID? steamId) || steamId == null)
|
||||
{
|
||||
command.ReplyToCommand("Invalid SteamID64.");
|
||||
return;
|
||||
}
|
||||
|
||||
var steamid = steamId.SteamId64;
|
||||
var reason = command.ArgCount >= 3
|
||||
? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg)).Trim()
|
||||
: _localizer?["sa_unknown"] ?? "Unknown";
|
||||
|
||||
reason = string.IsNullOrWhiteSpace(reason) ? _localizer?["sa_unknown"] ?? "Unknown" : reason;
|
||||
ulong steamid = steamId.SteamId64;
|
||||
string reason = Helper.GetArgsReason(command, 3);
|
||||
|
||||
var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
|
||||
if (!CheckValidBan(caller, time)) return;
|
||||
int time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
|
||||
if (!CheckValidBan(caller, time))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var adminInfo = caller != null && caller.UserId.HasValue
|
||||
? PlayersInfo[caller.SteamID]
|
||||
: null;
|
||||
PlayerInfo? adminInfo = Helper.GetAdminInfo(caller);
|
||||
|
||||
var player = Helper.GetPlayerFromSteamid64(steamid);
|
||||
CCSPlayerController? player = Helper.GetPlayerFromSteamid64(steamid);
|
||||
if (player != null && player.IsValid)
|
||||
{
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Ban(caller, player, time, reason, callerName, silent: true);
|
||||
//command.ReplyToCommand($"Banned player {player.PlayerName}.");
|
||||
|
|
@ -220,8 +260,10 @@ public partial class CS2_SimpleAdmin
|
|||
else
|
||||
{
|
||||
if (!caller.CanTarget(new SteamID(steamId.SteamId64)))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Asynchronous ban operation if player is not online or not found
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -232,7 +274,7 @@ public partial class CS2_SimpleAdmin
|
|||
penaltyId);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Helper.SendDiscordPenaltyMessage(caller, steamid.ToString(), reason, time, PenaltyType.Ban, _localizer);
|
||||
|
||||
command.ReplyToCommand($"Player with steamid {steamid} is not online. Ban has been added offline.");
|
||||
|
|
@ -241,7 +283,9 @@ public partial class CS2_SimpleAdmin
|
|||
Helper.LogCommand(caller, command);
|
||||
|
||||
if (UnlockedCommands)
|
||||
{
|
||||
Server.ExecuteCommand($"banid 1 {steamId.SteamId3}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -253,10 +297,18 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<ip> [time in minutes/0 perm] [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnBanIpCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (DatabaseProvider == null) return;
|
||||
var callerName = caller?.PlayerName ?? _localizer?["sa_console"] ?? "Console";
|
||||
if (command.ArgCount < 2 || string.IsNullOrEmpty(command.GetArg(1))) return;
|
||||
var ipAddress = command.GetArg(1);
|
||||
if (DatabaseProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string callerName = caller?.PlayerName ?? _localizer?["sa_console"] ?? "Console";
|
||||
if (command.ArgCount < 2 || string.IsNullOrEmpty(command.GetArg(1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string ipAddress = command.GetArg(1);
|
||||
|
||||
if (!Helper.IsValidIp(ipAddress))
|
||||
{
|
||||
|
|
@ -264,28 +316,31 @@ public partial class CS2_SimpleAdmin
|
|||
return;
|
||||
}
|
||||
|
||||
var reason = command.ArgCount >= 3
|
||||
? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg)).Trim()
|
||||
: _localizer?["sa_unknown"] ?? "Unknown";
|
||||
|
||||
reason = string.IsNullOrWhiteSpace(reason) ? _localizer?["sa_unknown"] ?? "Unknown" : reason;
|
||||
string reason = Helper.GetArgsReason(command, 3);
|
||||
|
||||
var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
|
||||
int 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
|
||||
? PlayersInfo[caller.SteamID]
|
||||
: null;
|
||||
PlayerInfo? adminInfo = Helper.GetAdminInfo(caller);
|
||||
|
||||
var players = Helper.GetPlayerFromIp(ipAddress);
|
||||
List<CCSPlayerController> players = Helper.GetPlayerFromIp(ipAddress);
|
||||
if (players.Count >= 1)
|
||||
{
|
||||
foreach (var player in players)
|
||||
foreach (CCSPlayerController player in players)
|
||||
{
|
||||
if (player == null || !player.IsValid) continue;
|
||||
if (player == null || !player.IsValid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Ban(caller, player, time, reason, callerName, silent: true);
|
||||
}
|
||||
|
|
@ -312,9 +367,12 @@ public partial class CS2_SimpleAdmin
|
|||
/// <returns>True if ban duration is valid; otherwise, false.</returns>
|
||||
private bool CheckValidBan(CCSPlayerController? caller, int duration)
|
||||
{
|
||||
if (caller == null) return true;
|
||||
if (caller == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var canPermBan = AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/permban");
|
||||
bool canPermBan = AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/permban");
|
||||
|
||||
if (duration <= 0 && !canPermBan)
|
||||
{
|
||||
|
|
@ -322,7 +380,10 @@ public partial class CS2_SimpleAdmin
|
|||
return false;
|
||||
}
|
||||
|
||||
if (duration <= Config.OtherSettings.MaxBanDuration || canPermBan) return true;
|
||||
if (duration <= Config.OtherSettings.MaxBanDuration || canPermBan)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
caller.PrintToChat($"{_localizer!["sa_prefix"]} {_localizer["sa_ban_max_duration_exceeded", Config.OtherSettings.MaxBanDuration]}");
|
||||
return false;
|
||||
|
|
@ -337,20 +398,20 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<steamid or name or ip> [reason]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnUnbanCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (DatabaseProvider == null) return;
|
||||
var callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console";
|
||||
if (DatabaseProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string callerSteamId = caller?.SteamID.ToString() ?? _localizer?["sa_console"] ?? "Console";
|
||||
if (command.GetArg(1).Length <= 1)
|
||||
{
|
||||
command.ReplyToCommand($"Too short pattern to search.");
|
||||
return;
|
||||
}
|
||||
|
||||
var pattern = command.GetArg(1);
|
||||
var reason = command.ArgCount >= 2
|
||||
? string.Join(" ", Enumerable.Range(2, command.ArgCount - 2).Select(command.GetArg)).Trim()
|
||||
: _localizer?["sa_unknown"] ?? "Unknown";
|
||||
|
||||
reason = string.IsNullOrWhiteSpace(reason) ? _localizer?["sa_unknown"] ?? "Unknown" : reason;
|
||||
string pattern = command.GetArg(1);
|
||||
string reason = Helper.GetArgsReason(command, 2);
|
||||
Task.Run(async () => await BanManager.UnbanPlayer(pattern, callerSteamId, reason));
|
||||
Helper.LogCommand(caller, command);
|
||||
command.ReplyToCommand($"Unbanned player with pattern {pattern}.");
|
||||
|
|
@ -366,26 +427,31 @@ public partial class CS2_SimpleAdmin
|
|||
public void OnWarnCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (DatabaseProvider == null)
|
||||
{
|
||||
return;
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
}
|
||||
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
if (command.ArgCount < 2)
|
||||
{
|
||||
return;
|
||||
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player.Connected == PlayerConnectedState.Connected && !player.IsHLTV).ToList();
|
||||
}
|
||||
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player.IsValid && player.Connected == PlayerConnectedState.Connected && !player.IsHLTV).ToList();
|
||||
|
||||
if (playersToTarget.Count > 1 && Config.OtherSettings.DisableDangerousCommands || playersToTarget.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
|
||||
var reason = command.ArgCount >= 3
|
||||
? string.Join(" ", Enumerable.Range(3, command.ArgCount - 3).Select(command.GetArg)).Trim()
|
||||
: _localizer?["sa_unknown"] ?? "Unknown";
|
||||
|
||||
reason = string.IsNullOrWhiteSpace(reason) ? _localizer?["sa_unknown"] ?? "Unknown" : reason;
|
||||
int time = Math.Max(0, Helper.ParsePenaltyTime(command.GetArg(2)));
|
||||
string reason = Helper.GetArgsReason(command, 3);
|
||||
|
||||
playersToTarget.ForEach(player =>
|
||||
{
|
||||
|
|
@ -407,14 +473,23 @@ public partial class CS2_SimpleAdmin
|
|||
/// <param name="command">Optional command info for logging.</param>
|
||||
internal void Warn(CCSPlayerController? caller, CCSPlayerController player, int time, string reason, string? callerName = null, CommandInfo? command = null)
|
||||
{
|
||||
if (DatabaseProvider == null || !player.IsValid || !player.UserId.HasValue) return;
|
||||
if (!caller.CanTarget(player)) return;
|
||||
if (!CheckValidBan(caller, time)) return;
|
||||
if (DatabaseProvider == null || !player.IsValid || !player.UserId.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CheckValidBan(caller, time))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set default caller name if not provided
|
||||
callerName = !string.IsNullOrEmpty(caller?.PlayerName)
|
||||
? caller.PlayerName
|
||||
: (_localizer?["sa_console"] ?? "Console");
|
||||
callerName = Helper.GetCallerName(caller);
|
||||
|
||||
// Freeze player pawn if alive
|
||||
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE)
|
||||
|
|
@ -424,8 +499,8 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
|
||||
// Get player and admin information
|
||||
var playerInfo = PlayersInfo[player.SteamID];
|
||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.SteamID] : null;
|
||||
PlayerInfo playerInfo = PlayersInfo[player.SteamID];
|
||||
PlayerInfo? adminInfo = Helper.GetAdminInfo(caller);
|
||||
|
||||
// Asynchronously handle warning logic
|
||||
Task.Run(async () =>
|
||||
|
|
@ -438,16 +513,20 @@ public partial class CS2_SimpleAdmin
|
|||
});
|
||||
|
||||
// Check for warn thresholds and execute punish command if applicable
|
||||
var totalWarns = await WarnManager.GetPlayerWarnsCount(player.SteamID);
|
||||
int totalWarns = await WarnManager.GetPlayerWarnsCount(player.SteamID);
|
||||
if (Config.WarnThreshold.Count > 0)
|
||||
{
|
||||
string? punishCommand = null;
|
||||
var lastKey = Config.WarnThreshold.Keys.Max();
|
||||
int lastKey = Config.WarnThreshold.Keys.Max();
|
||||
|
||||
if (totalWarns >= lastKey)
|
||||
{
|
||||
punishCommand = Config.WarnThreshold[lastKey];
|
||||
else if (Config.WarnThreshold.TryGetValue(totalWarns, out var value))
|
||||
}
|
||||
else if (Config.WarnThreshold.TryGetValue(totalWarns, out string? value))
|
||||
{
|
||||
punishCommand = value;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(punishCommand))
|
||||
{
|
||||
|
|
@ -460,13 +539,25 @@ public partial class CS2_SimpleAdmin
|
|||
});
|
||||
|
||||
// Determine message keys and arguments based on warning time
|
||||
var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = time == 0
|
||||
? ("sa_player_warn_message_perm", "sa_admin_warn_message_perm",
|
||||
new object[] { reason, "CALLER" },
|
||||
new object[] { "CALLER", player.PlayerName, reason })
|
||||
: ("sa_player_warn_message_time", "sa_admin_warn_message_time",
|
||||
[reason, time, "CALLER"],
|
||||
["CALLER", player.PlayerName, reason, time]);
|
||||
string? messageKey;
|
||||
string? activityMessageKey;
|
||||
object[]? centerArgs;
|
||||
object[]? adminActivityArgs;
|
||||
|
||||
if (time == 0)
|
||||
{
|
||||
messageKey = "sa_player_warn_message_perm";
|
||||
activityMessageKey = "sa_admin_warn_message_perm";
|
||||
centerArgs = new object[] { reason, "CALLER" };
|
||||
adminActivityArgs = new object[] { "CALLER", player.PlayerName, reason };
|
||||
}
|
||||
else
|
||||
{
|
||||
messageKey = "sa_player_warn_message_time";
|
||||
activityMessageKey = "sa_admin_warn_message_time";
|
||||
centerArgs = [reason, time, "CALLER"];
|
||||
adminActivityArgs = ["CALLER", player.PlayerName, reason, time];
|
||||
}
|
||||
|
||||
// Display center message to the playser
|
||||
Helper.DisplayCenterMessage(player, messageKey, callerName, centerArgs);
|
||||
|
|
@ -479,14 +570,18 @@ public partial class CS2_SimpleAdmin
|
|||
|
||||
// Log the warning command
|
||||
if (command == null)
|
||||
Helper.LogCommand(caller, $"css_warn {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {time} {reason}");
|
||||
{
|
||||
Helper.LogCommand(caller, $"css_warn {Helper.GetLogName(player)} {time} {reason}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Helper.LogCommand(caller, command);
|
||||
}
|
||||
|
||||
// Send Discord notification for the warning
|
||||
Helper.SendDiscordPenaltyMessage(caller, player, reason, time, PenaltyType.Warn, _localizer);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a warning to a player by their SteamID, including support for offline players.
|
||||
/// </summary>
|
||||
|
|
@ -498,18 +593,18 @@ public partial class CS2_SimpleAdmin
|
|||
internal void AddWarn(CCSPlayerController? caller, SteamID steamid, int time, string reason, WarnManager? warnManager = null)
|
||||
{
|
||||
// Set default caller name if not provided
|
||||
var callerName = !string.IsNullOrEmpty(caller?.PlayerName)
|
||||
? caller.PlayerName
|
||||
: (_localizer?["sa_console"] ?? "Console");
|
||||
|
||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.SteamID] : null;
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64);
|
||||
PlayerInfo? adminInfo = Helper.GetAdminInfo(caller);
|
||||
|
||||
CCSPlayerController? player = Helper.GetPlayerFromSteamid64(steamid.SteamId64);
|
||||
|
||||
if (player != null && player.IsValid)
|
||||
{
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Warn(caller, player, time, reason, callerName);
|
||||
//command.ReplyToCommand($"Banned player {player.PlayerName}.");
|
||||
|
|
@ -517,8 +612,10 @@ public partial class CS2_SimpleAdmin
|
|||
else
|
||||
{
|
||||
if (!caller.CanTarget(steamid))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Asynchronous ban operation if player is not online or not found
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -530,16 +627,20 @@ public partial class CS2_SimpleAdmin
|
|||
});
|
||||
|
||||
// Check for warn thresholds and execute punish command if applicable
|
||||
var totalWarns = await WarnManager.GetPlayerWarnsCount(steamid.SteamId64);
|
||||
int totalWarns = await WarnManager.GetPlayerWarnsCount(steamid.SteamId64);
|
||||
if (Config.WarnThreshold.Count > 0)
|
||||
{
|
||||
string? punishCommand = null;
|
||||
var lastKey = Config.WarnThreshold.Keys.Max();
|
||||
int lastKey = Config.WarnThreshold.Keys.Max();
|
||||
|
||||
if (totalWarns >= lastKey)
|
||||
{
|
||||
punishCommand = Config.WarnThreshold[lastKey];
|
||||
else if (Config.WarnThreshold.TryGetValue(totalWarns, out var value))
|
||||
}
|
||||
else if (Config.WarnThreshold.TryGetValue(totalWarns, out string? value))
|
||||
{
|
||||
punishCommand = value;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(punishCommand))
|
||||
{
|
||||
|
|
@ -550,11 +651,11 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Helper.SendDiscordPenaltyMessage(caller, steamid.SteamId64.ToString(), reason, time, PenaltyType.Warn, _localizer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles removing a warning (unwarn) by a pattern string.
|
||||
/// </summary>
|
||||
|
|
@ -564,7 +665,10 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<steamid or name or ip>", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnUnwarnCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (DatabaseProvider == null) return;
|
||||
if (DatabaseProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.GetArg(1).Length <= 1)
|
||||
{
|
||||
|
|
@ -572,9 +676,9 @@ public partial class CS2_SimpleAdmin
|
|||
return;
|
||||
}
|
||||
|
||||
var pattern = command.GetArg(1);
|
||||
string pattern = command.GetArg(1);
|
||||
Task.Run(async () => await WarnManager.UnwarnPlayer(pattern));
|
||||
Helper.LogCommand(caller, command);
|
||||
command.ReplyToCommand($"Unwarned player with pattern {pattern}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,21 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Translations;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using System.Text;
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CS2_SimpleAdmin.Menus;
|
||||
using PanoramaUiKit.Shared.Api;
|
||||
using PanoramaUiKit.Shared.Common;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
public partial class CS2_SimpleAdmin
|
||||
{
|
||||
private const float AnnouncementSeconds = 7f;
|
||||
|
||||
/// <summary>
|
||||
/// Sends a chat message only to admins that have chat permission.
|
||||
/// The message is encoded properly to handle UTF-8 characters.
|
||||
|
|
@ -23,16 +28,18 @@ public partial class CS2_SimpleAdmin
|
|||
{
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
var utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
|
||||
foreach (var player in Helper.GetValidPlayers()
|
||||
foreach (CCSPlayerController? player in Helper.GetValidPlayers()
|
||||
.Where(p => AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/chat")))
|
||||
{
|
||||
if (_localizer != null)
|
||||
{
|
||||
player.PrintToChat(_localizer["sa_adminchat_template_admin",
|
||||
caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName,
|
||||
Helper.GetCallerName(caller),
|
||||
utf8String]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,14 +52,17 @@ public partial class CS2_SimpleAdmin
|
|||
[RequiresPermissions("@css/chat")]
|
||||
public void OnAdminCustomSayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (command.GetCommandString[command.GetCommandString.IndexOf(' ')..].Length == 0) return;
|
||||
if (command.GetCommandString[command.GetCommandString.IndexOf(' ')..].Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
foreach (var player in Helper.GetValidPlayers())
|
||||
foreach (CCSPlayerController player in Helper.GetValidPlayers())
|
||||
{
|
||||
player.PrintToChat(utf8String.ReplaceColorTags());
|
||||
}
|
||||
|
|
@ -67,14 +77,17 @@ public partial class CS2_SimpleAdmin
|
|||
[RequiresPermissions("@css/chat")]
|
||||
public void OnAdminSayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (command.GetCommandString[command.GetCommandString.IndexOf(' ')..].Length == 0) return;
|
||||
if (command.GetCommandString[command.GetCommandString.IndexOf(' ')..].Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
var callerName = caller?.PlayerName;
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
string? callerName = caller?.PlayerName;
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
foreach (var player in Helper.GetValidPlayers())
|
||||
foreach (CCSPlayerController player in Helper.GetValidPlayers())
|
||||
{
|
||||
// The message always goes out (it is a broadcast, not an activity notice),
|
||||
// but the admin's name follows ShowActivityType like every other activity message.
|
||||
|
|
@ -93,19 +106,23 @@ public partial class CS2_SimpleAdmin
|
|||
[RequiresPermissions("@css/chat")]
|
||||
public void OnAdminPrivateSayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
|
||||
//Helper.LogCommand(caller, command);
|
||||
|
||||
var range = command.GetArg(0).Length + command.GetArg(1).Length + 2;
|
||||
var message = command.GetCommandString[range..];
|
||||
int range = command.GetArg(0).Length + command.GetArg(1).Length + 2;
|
||||
string message = command.GetCommandString[range..];
|
||||
|
||||
var utf8BytesString = Encoding.UTF8.GetBytes(message);
|
||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(message);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
|
||||
playersToTarget.ForEach(player =>
|
||||
{
|
||||
|
|
@ -116,7 +133,7 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts a center-screen message to all players.
|
||||
/// Broadcasts a message to all players in a Panorama UI Kit banner.
|
||||
/// </summary>
|
||||
/// <param name="caller">The admin or console sending the message.</param>
|
||||
/// <param name="command">The command input containing the message.</param>
|
||||
|
|
@ -124,15 +141,15 @@ public partial class CS2_SimpleAdmin
|
|||
[RequiresPermissions("@css/chat")]
|
||||
public void OnAdminCenterSayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
Helper.PrintToCenterAll(utf8String.ReplaceColorTags());
|
||||
UiKit.Instance?.Banner(UiKit.BannerLayout, StripColorTags(utf8String), UiStyle.Info, AnnouncementSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a HUD alert message to all players.
|
||||
/// Sends a message to all players in a Panorama UI Kit toast, titled with the admin's name.
|
||||
/// </summary>
|
||||
/// <param name="caller">The admin or console sending the message.</param>
|
||||
/// <param name="command">The command input containing the message.</param>
|
||||
|
|
@ -140,14 +157,31 @@ public partial class CS2_SimpleAdmin
|
|||
[RequiresPermissions("@css/chat")]
|
||||
public void OnAdminHudSayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
VirtualFunctions.ClientPrintAll(
|
||||
HudDestination.Alert,
|
||||
utf8String.ReplaceColorTags(),
|
||||
0, 0, 0, 0, 0);
|
||||
IPanoramaUiKit? kit = UiKit.Instance;
|
||||
if (kit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string message = StripColorTags(utf8String);
|
||||
string? callerName = caller?.PlayerName;
|
||||
|
||||
foreach (CCSPlayerController player in Helper.GetValidPlayers())
|
||||
{
|
||||
kit.Toast(player, UiKit.ToastLayout, Helper.ResolveActivityName(player, callerName), message, UiStyle.Info, AnnouncementSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Panorama does not render chat color tags such as {red}: drop them.
|
||||
/// </summary>
|
||||
private static string StripColorTags(string message)
|
||||
{
|
||||
return Regex.Replace(message, @"\{[A-Za-z]+\}", string.Empty).Trim();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,21 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Translations;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Menu;
|
||||
using CounterStrikeSharp.API.Modules.Timers;
|
||||
using CS2_SimpleAdmin.Menus;
|
||||
using PanoramaUiKit.Shared.Api;
|
||||
using PanoramaUiKit.Shared.Votes;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
public partial class CS2_SimpleAdmin
|
||||
{
|
||||
private const float VoteDurationSeconds = 30f;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the vote command, creates voting menu for players, and collects answers.
|
||||
/// Displays results after timeout and resets voting state.
|
||||
/// Handles the vote command: shows the vote screen to every player, collects one answer each
|
||||
/// and prints the results when the countdown ends.
|
||||
/// </summary>
|
||||
/// <param name="caller">The player/admin who initiated the vote, or null for console.</param>
|
||||
/// <param name="command">Command object containing question and options.</param>
|
||||
|
|
@ -19,80 +24,123 @@ public partial class CS2_SimpleAdmin
|
|||
public void OnVoteCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (command.ArgCount < 2 || _localizer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
VoteAnswers.Clear();
|
||||
|
||||
var question = command.GetArg(1);
|
||||
var answersCount = command.ArgCount;
|
||||
|
||||
if (caller == null || !SilentPlayers.Contains(caller.Slot))
|
||||
if (caller != null && SilentPlayers.Contains(caller.Slot))
|
||||
{
|
||||
for (var i = 2; i <= answersCount - 1; i++)
|
||||
{
|
||||
VoteAnswers.Add(command.GetArg(i), 0);
|
||||
}
|
||||
|
||||
foreach (var player in Helper.GetValidPlayers())
|
||||
{
|
||||
using (new WithTemporaryCulture(player.GetLanguage()))
|
||||
{
|
||||
IMenu? voteMenu = Helper.CreateMenu(_localizer["sa_admin_vote_menu_title", question]);
|
||||
if (voteMenu == null)
|
||||
return;
|
||||
//ChatMenu voteMenu = new(_localizer!["sa_admin_vote_menu_title", question]);
|
||||
|
||||
for (var i = 2; i <= answersCount - 1; i++)
|
||||
{
|
||||
voteMenu.AddMenuOption(command.GetArg(i), Helper.HandleVotes);
|
||||
}
|
||||
|
||||
voteMenu.PostSelectAction = PostSelectAction.Close;
|
||||
|
||||
Helper.PrintToCenterAll(_localizer["sa_admin_vote_message", caller == null ? _localizer["sa_console"] : caller.PlayerName, question]);
|
||||
|
||||
player.SendLocalizedMessage(_localizer,
|
||||
"sa_admin_vote_message",
|
||||
caller == null ? _localizer["sa_console"] : caller.PlayerName,
|
||||
question);
|
||||
|
||||
voteMenu.Open(player);
|
||||
|
||||
//MenuManager.OpenChatMenu(player, voteMenu);
|
||||
}
|
||||
}
|
||||
|
||||
VoteInProgress = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (VoteInProgress)
|
||||
IPanoramaUiKit? kit = UiKit.Instance;
|
||||
if (kit == null)
|
||||
{
|
||||
AddTimer(30, () =>
|
||||
return;
|
||||
}
|
||||
|
||||
string question = command.GetArg(1);
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
List<string> answers = [];
|
||||
for (int i = 2; i < command.ArgCount; i++)
|
||||
{
|
||||
answers.Add(command.GetArg(i));
|
||||
}
|
||||
|
||||
int[] counts = new int[answers.Count];
|
||||
Dictionary<ulong, int> ballots = [];
|
||||
|
||||
VoteInProgress = true;
|
||||
|
||||
foreach (CCSPlayerController player in Helper.GetValidPlayers())
|
||||
{
|
||||
kit.Votes.Show(player, BuildVote(player, question, answers, counts, null, OnVote));
|
||||
player.SendLocalizedMessage(_localizer, "sa_admin_vote_message", callerName, question);
|
||||
}
|
||||
|
||||
Helper.PrintToCenterAll(_localizer["sa_admin_vote_message", callerName, question]);
|
||||
|
||||
AddTimer(VoteDurationSeconds, () =>
|
||||
{
|
||||
UiKit.Instance?.Votes.HideAll(UiKit.VoteLayout);
|
||||
VoteInProgress = false;
|
||||
|
||||
if (_localizer == null)
|
||||
{
|
||||
foreach (var player in Helper.GetValidPlayers())
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (CCSPlayerController player in Helper.GetValidPlayers())
|
||||
{
|
||||
player.SendLocalizedMessage(_localizer, "sa_admin_vote_message_results", question);
|
||||
|
||||
for (int i = 0; i < answers.Count; i++)
|
||||
{
|
||||
if (_localizer != null)
|
||||
player.SendLocalizedMessage(_localizer,
|
||||
"sa_admin_vote_message_results",
|
||||
question);
|
||||
player.SendLocalizedMessage(_localizer, "sa_admin_vote_message_results_answer", answers[i], counts[i]);
|
||||
}
|
||||
}
|
||||
}, TimerFlags.STOP_ON_MAPCHANGE);
|
||||
|
||||
return;
|
||||
|
||||
void OnVote(VoteEvent vote)
|
||||
{
|
||||
if (!VoteInProgress || ballots.ContainsKey(vote.Player.SteamID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ballots[vote.Player.SteamID] = vote.Index;
|
||||
counts[vote.Index]++;
|
||||
|
||||
IPanoramaUiKit? currentKit = UiKit.Instance;
|
||||
if (currentKit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (CCSPlayerController player in Helper.GetValidPlayers())
|
||||
{
|
||||
int? selected = null;
|
||||
if (ballots.TryGetValue(player.SteamID, out int index))
|
||||
{
|
||||
selected = index;
|
||||
}
|
||||
|
||||
foreach (var (key, value) in VoteAnswers)
|
||||
{
|
||||
foreach (var player in Helper.GetValidPlayers())
|
||||
{
|
||||
if (_localizer != null)
|
||||
player.SendLocalizedMessage(_localizer,
|
||||
"sa_admin_vote_message_results_answer",
|
||||
key,
|
||||
value);
|
||||
}
|
||||
}
|
||||
VoteAnswers.Clear();
|
||||
VoteInProgress = false;
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
currentKit.Votes.Update(player, BuildVote(player, question, answers, counts, selected, OnVote));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vote screen for one player, locked once that player has voted.
|
||||
/// </summary>
|
||||
private static VoteOptions BuildVote(CCSPlayerController player, string question, List<string> answers, int[] counts,
|
||||
int? selected, Action<VoteEvent> onVote)
|
||||
{
|
||||
string title;
|
||||
using (new WithTemporaryCulture(player.GetLanguage()))
|
||||
{
|
||||
title = _localizer?["sa_admin_vote_menu_title", question] ?? question;
|
||||
}
|
||||
|
||||
List<VoteChoice> choices = [];
|
||||
for (int i = 0; i < answers.Count; i++)
|
||||
{
|
||||
choices.Add(new VoteChoice(answers[i], counts[i]));
|
||||
}
|
||||
|
||||
return new VoteOptions
|
||||
{
|
||||
Layout = UiKit.VoteLayout,
|
||||
Title = title,
|
||||
Choices = choices,
|
||||
Selected = selected,
|
||||
Locked = selected.HasValue,
|
||||
Seconds = VoteDurationSeconds,
|
||||
OnVote = onVote
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
// if (!caller.CanTarget(player)) return;
|
||||
//
|
||||
// // Set default caller name if not provided
|
||||
// callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
// callerName ??= Helper.GetCallerName(caller);
|
||||
//
|
||||
// // Toggle no-clip mode for the player
|
||||
// player.Pawn.Value?.ToggleNoclip();
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
//
|
||||
// // Log the command
|
||||
// if (command == null)
|
||||
// Helper.LogCommand(caller, $"css_noclip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||
// Helper.LogCommand(caller, $"css_noclip {Helper.GetLogName(player)}");
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
// [CommandHelper(minArgs: 1, usage: "<#userid or name>", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
// public void OnGodCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
// {
|
||||
// var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
// var callerName = Helper.GetCallerName(caller);
|
||||
// var targets = GetTarget(command);
|
||||
// if (targets == null) return;
|
||||
//
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
// if (!caller.CanTarget(player)) return;
|
||||
//
|
||||
// // Set default caller name if not provided
|
||||
// var callerName = caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
// var callerName = Helper.GetCallerName(caller);
|
||||
//
|
||||
// // Toggle god mode for the player
|
||||
// if (!GodPlayers.Add(player.Slot))
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
//
|
||||
// // Log the command
|
||||
// if (command == null)
|
||||
// Helper.LogCommand(caller, $"css_god {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||
// Helper.LogCommand(caller, $"css_god {Helper.GetLogName(player)}");
|
||||
//
|
||||
// // Determine message key and arguments for the god mode notification
|
||||
// var (activityMessageKey, adminActivityArgs) =
|
||||
|
|
@ -144,7 +144,7 @@
|
|||
// [RequiresPermissions("@css/slay")]
|
||||
// public void OnFreezeCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
// {
|
||||
// var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
// var callerName = Helper.GetCallerName(caller);
|
||||
// int.TryParse(command.GetArg(2), out var time);
|
||||
//
|
||||
// var targets = GetTarget(command);
|
||||
|
|
@ -171,7 +171,7 @@
|
|||
// [RequiresPermissions("@css/slay")]
|
||||
// public void OnResizeCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
// {
|
||||
// var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
// var callerName = Helper.GetCallerName(caller);
|
||||
// float.TryParse(command.GetArg(2), NumberStyles.Float, CultureInfo.InvariantCulture, out var size);
|
||||
//
|
||||
// var targets = GetTarget(command);
|
||||
|
|
@ -221,7 +221,7 @@
|
|||
// if (!caller.CanTarget(player)) return;
|
||||
//
|
||||
// // Set default caller name if not provided
|
||||
// callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
// callerName ??= Helper.GetCallerName(caller);
|
||||
//
|
||||
// // Freeze player pawn
|
||||
// player.Pawn.Value?.Freeze();
|
||||
|
|
@ -245,7 +245,7 @@
|
|||
//
|
||||
// // Log the command and send Discord notification
|
||||
// if (command == null)
|
||||
// Helper.LogCommand(caller, $"css_freeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {time}");
|
||||
// Helper.LogCommand(caller, $"css_freeze {Helper.GetLogName(player)} {time}");
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
|
|
@ -257,7 +257,7 @@
|
|||
// [RequiresPermissions("@css/slay")]
|
||||
// public void OnUnfreezeCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
// {
|
||||
// var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
// var callerName = Helper.GetCallerName(caller);
|
||||
//
|
||||
// var targets = GetTarget(command);
|
||||
// if (targets == null) return;
|
||||
|
|
@ -284,7 +284,7 @@
|
|||
// if (!caller.CanTarget(player)) return;
|
||||
//
|
||||
// // Set default caller name if not provided
|
||||
// callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
// callerName ??= Helper.GetCallerName(caller);
|
||||
//
|
||||
// // Unfreeze player pawn
|
||||
// player.Pawn.Value?.Unfreeze();
|
||||
|
|
@ -302,6 +302,6 @@
|
|||
//
|
||||
// // Log the command and send Discord notification
|
||||
// if (command == null)
|
||||
// Helper.LogCommand(caller, $"css_unfreeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||
// Helper.LogCommand(caller, $"css_unfreeze {Helper.GetLogName(player)}");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
using System.Globalization;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
|
@ -21,17 +20,20 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<#userid or name>", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnSlayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is {IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||
|
||||
playersToTarget.ForEach(player =>
|
||||
{
|
||||
Slay(caller, player, callerName, command);
|
||||
});
|
||||
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
}
|
||||
|
||||
|
|
@ -44,18 +46,25 @@ public partial class CS2_SimpleAdmin
|
|||
/// <param name="command">Optional command info for logging.</param>
|
||||
internal static void Slay(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
||||
{
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.Connected) return;
|
||||
if (!caller.CanTarget(player)) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set default caller name if not provided
|
||||
callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
callerName ??= Helper.GetCallerName(caller);
|
||||
|
||||
// Make the player commit suicide
|
||||
player.CommitSuicide(false, true);
|
||||
player.EmitSound("Player.Death");
|
||||
|
||||
// Determine message keys and arguments for the slay notification
|
||||
var (activityMessageKey, adminActivityArgs) =
|
||||
(string? activityMessageKey, object[]? adminActivityArgs) =
|
||||
("sa_admin_slay_message",
|
||||
new object[] { "CALLER", player.PlayerName });
|
||||
|
||||
|
|
@ -67,7 +76,9 @@ public partial class CS2_SimpleAdmin
|
|||
|
||||
// Log the command and send Discord notification
|
||||
if (command == null)
|
||||
Helper.LogCommand(caller, $"css_slay {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||
{
|
||||
Helper.LogCommand(caller, $"css_slay {Helper.GetLogName(player)}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -79,12 +90,15 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 1, usage: "<#userid or name> [damage]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnSlapCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var damage = 0;
|
||||
int damage = 0;
|
||||
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||
|
||||
if (command.ArgCount >= 2)
|
||||
{
|
||||
|
|
@ -94,14 +108,16 @@ public partial class CS2_SimpleAdmin
|
|||
playersToTarget.ForEach(player =>
|
||||
{
|
||||
if (player.Connected != PlayerConnectedState.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (caller!.CanTarget(player))
|
||||
{
|
||||
Slap(caller, player, damage, command);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
}
|
||||
|
||||
|
|
@ -114,26 +130,34 @@ public partial class CS2_SimpleAdmin
|
|||
/// <param name="command">Optional command info for logging.</param>
|
||||
internal static void Slap(CCSPlayerController? caller, CCSPlayerController player, int damage, CommandInfo? command = null)
|
||||
{
|
||||
if (!caller.CanTarget(player)) return;
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set default caller name if not provided
|
||||
var callerName = caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
// Apply slap damage to the player
|
||||
player.Pawn.Value?.Slap(damage);
|
||||
player.EmitSound("Player.DamageFall");
|
||||
|
||||
// Log the command
|
||||
if (command == null)
|
||||
Helper.LogCommand(caller, $"css_slap {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {damage}");
|
||||
|
||||
{
|
||||
Helper.LogCommand(caller, $"css_slap {Helper.GetLogName(player)} {damage}");
|
||||
}
|
||||
|
||||
// Determine message key and arguments for the slap notification
|
||||
var (activityMessageKey, adminActivityArgs) =
|
||||
(string? activityMessageKey, object[]? adminActivityArgs) =
|
||||
("sa_admin_slap_message",
|
||||
new object[] { "CALLER", player.PlayerName });
|
||||
|
||||
// Display admin activity message to other players
|
||||
if (caller != null && SilentPlayers.Contains(caller.Slot)) return;
|
||||
if (caller != null && SilentPlayers.Contains(caller.Slot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_localizer != null)
|
||||
{
|
||||
|
|
@ -150,15 +174,18 @@ public partial class CS2_SimpleAdmin
|
|||
[CommandHelper(minArgs: 2, usage: "<#userid or name> [<ct/tt/spec>] [-k]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnTeamCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
var teamName = command.GetArg(2).ToLower();
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
string teamName = command.GetArg(2).ToLower();
|
||||
string _teamName;
|
||||
var teamNum = CsTeam.Spectator;
|
||||
CsTeam teamNum = CsTeam.Spectator;
|
||||
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
|
||||
switch (teamName)
|
||||
{
|
||||
|
|
@ -185,13 +212,13 @@ public partial class CS2_SimpleAdmin
|
|||
break;
|
||||
}
|
||||
|
||||
var kill = command.GetArg(3).ToLower().Equals("-k");
|
||||
bool kill = command.GetArg(3).ToLower().Equals("-k");
|
||||
|
||||
playersToTarget.ForEach(player =>
|
||||
{
|
||||
ChangeTeam(caller, player, _teamName, teamNum, kill, command);
|
||||
});
|
||||
|
||||
|
||||
Helper.LogCommand(caller, command);
|
||||
}
|
||||
|
||||
|
|
@ -208,45 +235,79 @@ public partial class CS2_SimpleAdmin
|
|||
{
|
||||
// Check if the player is valid and connected
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the caller can target the player
|
||||
if (!caller.CanTarget(player)) return;
|
||||
if (!caller.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set default caller name if not provided
|
||||
var callerName = caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
// Change team based on the provided teamName and conditions
|
||||
if (!teamName.Equals("swap", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && teamNum != CsTeam.Spectator && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
||||
{
|
||||
player.SwitchTeam(teamNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.ChangeTeam(teamNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.TeamNum != (byte)CsTeam.Spectator)
|
||||
{
|
||||
var _teamNum = (CsTeam)player.TeamNum == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist;
|
||||
teamName = _teamNum == CsTeam.Terrorist ? "TT" : "CT";
|
||||
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
||||
player.SwitchTeam(_teamNum);
|
||||
CsTeam _teamNum;
|
||||
|
||||
if ((CsTeam)player.TeamNum == CsTeam.Terrorist)
|
||||
{
|
||||
_teamNum = CsTeam.CounterTerrorist;
|
||||
}
|
||||
else
|
||||
{
|
||||
_teamNum = CsTeam.Terrorist;
|
||||
}
|
||||
if (_teamNum == CsTeam.Terrorist)
|
||||
{
|
||||
teamName = "TT";
|
||||
}
|
||||
else
|
||||
{
|
||||
teamName = "CT";
|
||||
}
|
||||
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
||||
{
|
||||
player.SwitchTeam(_teamNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.ChangeTeam(_teamNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log the command
|
||||
if (command == null)
|
||||
{
|
||||
Helper.LogCommand(caller, $"css_team {player.PlayerName} {teamName}");
|
||||
}
|
||||
|
||||
// Determine message key and arguments for the team change notification
|
||||
var activityMessageKey = "sa_admin_team_message";
|
||||
var adminActivityArgs = new object[] { "CALLER", player.PlayerName, teamName };
|
||||
string activityMessageKey = "sa_admin_team_message";
|
||||
object[] adminActivityArgs = new object[] { "CALLER", player.PlayerName, teamName };
|
||||
|
||||
// Display admin activity message to other players
|
||||
if (caller != null && SilentPlayers.Contains(caller.Slot)) return;
|
||||
if (caller != null && SilentPlayers.Contains(caller.Slot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Helper.ShowAdminActivity(activityMessageKey, callerName, false, adminActivityArgs);
|
||||
}
|
||||
|
|
@ -261,21 +322,26 @@ public partial class CS2_SimpleAdmin
|
|||
public void OnRenameCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
// Set default caller name if not provided
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
// Get the new name from the command arguments
|
||||
var newName = command.GetArg(2);
|
||||
string newName = command.GetArg(2);
|
||||
|
||||
// Check if the new name is valid
|
||||
if (string.IsNullOrEmpty(newName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the targets based on the command
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter out valid players from the targets
|
||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
|
||||
// Log the command
|
||||
Helper.LogCommand(caller, command);
|
||||
|
|
@ -285,15 +351,19 @@ public partial class CS2_SimpleAdmin
|
|||
{
|
||||
// Check if the player is connected and can be targeted
|
||||
if (player.Connected != PlayerConnectedState.Connected || !caller!.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Determine message key and arguments for the rename notification
|
||||
var activityMessageKey = "sa_admin_rename_message";
|
||||
var adminActivityArgs = new object[] { "CALLER", player.PlayerName, newName };
|
||||
string activityMessageKey = "sa_admin_rename_message";
|
||||
object[] adminActivityArgs = new object[] { "CALLER", player.PlayerName, newName };
|
||||
|
||||
// Display admin activity message to other players
|
||||
if (caller != null && !SilentPlayers.Contains(caller.Slot))
|
||||
{
|
||||
Helper.ShowAdminActivity(activityMessageKey, callerName, false, adminActivityArgs);
|
||||
}
|
||||
|
||||
// Rename the player
|
||||
player.Rename(newName);
|
||||
|
|
@ -310,17 +380,20 @@ public partial class CS2_SimpleAdmin
|
|||
public void OnPrenameCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
// Set default caller name if not provided
|
||||
var callerName = caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName;
|
||||
string callerName = Helper.GetCallerName(caller);
|
||||
|
||||
// Get the new name from the command arguments
|
||||
var newName = command.GetArg(2);
|
||||
string newName = command.GetArg(2);
|
||||
|
||||
// Retrieve the targets based on the command
|
||||
var targets = GetTarget(command);
|
||||
if (targets == null) return;
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter out valid players from the targets
|
||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
List<CCSPlayerController> playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false }).ToList();
|
||||
|
||||
// Log the command
|
||||
Helper.LogCommand(caller, command);
|
||||
|
|
@ -330,20 +403,22 @@ public partial class CS2_SimpleAdmin
|
|||
{
|
||||
// Check if the player is connected and can be targeted
|
||||
if (player.Connected != PlayerConnectedState.Connected || !caller!.CanTarget(player))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Determine message key and arguments for the rename notification
|
||||
var activityMessageKey = "sa_admin_rename_message";
|
||||
var adminActivityArgs = new object[] { "CALLER", player.PlayerName, newName };
|
||||
string activityMessageKey = "sa_admin_rename_message";
|
||||
object[] adminActivityArgs = new object[] { "CALLER", player.PlayerName, newName };
|
||||
|
||||
// Display admin activity message to other players
|
||||
if (caller != null && !SilentPlayers.Contains(caller.Slot))
|
||||
{
|
||||
Helper.ShowAdminActivity(activityMessageKey, callerName, false, adminActivityArgs);
|
||||
}
|
||||
|
||||
|
||||
// Determine if the new name is valid and update the renamed players list
|
||||
var steamId = player.SteamID;
|
||||
ulong steamId = player.SteamID;
|
||||
if (!string.IsNullOrEmpty(newName))
|
||||
{
|
||||
RenamedPlayers[steamId] = newName;
|
||||
|
|
@ -370,51 +445,65 @@ public partial class CS2_SimpleAdmin
|
|||
IEnumerable<CCSPlayerController> playersToTeleport;
|
||||
CCSPlayerController? destinationPlayer;
|
||||
|
||||
var targets = GetTarget(command);
|
||||
TargetResult? targets = GetTarget(command);
|
||||
|
||||
if (command.ArgCount < 3)
|
||||
{
|
||||
if (caller == null || caller.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (targets == null || targets.Count() != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
destinationPlayer = targets.Players.FirstOrDefault(p =>
|
||||
p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.Connected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE });
|
||||
|
||||
if (destinationPlayer == null || !caller.CanTarget(destinationPlayer) || caller.PlayerPawn.Value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
playersToTeleport = [caller];
|
||||
}
|
||||
else
|
||||
{
|
||||
var destination = GetTarget(command, 2);
|
||||
TargetResult? destination = GetTarget(command, 2);
|
||||
if (targets == null || destination == null || destination.Count() != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
destinationPlayer = destination.Players.FirstOrDefault(p =>
|
||||
p is { IsValid: true, IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE });
|
||||
|
||||
if (destinationPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
playersToTeleport = targets.Players
|
||||
.Where(p => p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.Connected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE } && caller.CanTarget(p))
|
||||
.ToList();
|
||||
|
||||
if (!playersToTeleport.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Log command
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
foreach (var player in playersToTeleport)
|
||||
foreach (CCSPlayerController player in playersToTeleport)
|
||||
{
|
||||
if (player.PlayerPawn?.Value == null || destinationPlayer?.PlayerPawn?.Value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player.TeleportPlayer(destinationPlayer);
|
||||
|
||||
|
|
@ -453,7 +542,7 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Brings targeted player(s) to the caller or specified destination player's location.
|
||||
/// </summary>
|
||||
|
|
@ -469,11 +558,15 @@ public partial class CS2_SimpleAdmin
|
|||
if (command.ArgCount < 3)
|
||||
{
|
||||
if (caller == null || caller.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var targets = GetTarget(command);
|
||||
TargetResult? targets = GetTarget(command);
|
||||
if (targets == null || !targets.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
destinationPlayer = caller;
|
||||
|
||||
|
|
@ -483,20 +576,26 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
else
|
||||
{
|
||||
var destination = GetTarget(command);
|
||||
TargetResult? destination = GetTarget(command);
|
||||
if (destination == null || destination.Count() != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
destinationPlayer = destination.Players.FirstOrDefault(p =>
|
||||
p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.Connected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE });
|
||||
|
||||
if (destinationPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Rest args = targets to teleport
|
||||
var targets = GetTarget(command, 2);
|
||||
TargetResult? targets = GetTarget(command, 2);
|
||||
if (targets == null || !targets.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
playersToTeleport = targets.Players
|
||||
.Where(p => p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.Connected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE } && caller!.CanTarget(p))
|
||||
|
|
@ -504,15 +603,19 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
|
||||
if (destinationPlayer == null || !playersToTeleport.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Log command
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
foreach (var player in playersToTeleport)
|
||||
foreach (CCSPlayerController player in playersToTeleport)
|
||||
{
|
||||
if (player.PlayerPawn?.Value == null || destinationPlayer.PlayerPawn?.Value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Teleport
|
||||
player.TeleportPlayer(destinationPlayer);
|
||||
|
|
@ -624,4 +727,4 @@ public partial class CS2_SimpleAdmin
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue