jRandomSkills/jRandomSkills - SRC Files/src/command/Command.cs
Juzlus 2ae293d1aa v1.2.2.b3
## 📋 Changelog

- #### General:
    - ###### Updated Chinese language translation by [by: [@Ericzzrbb](hhttps://github.com/Ericzzrbb)].
    - ###### Fixed a bug where a player could be given multiple skills at once while the HUD displayed only one (the player list was never cleared on map change and had no duplicate protection on join). [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Fixed skill names and descriptions showing the raw translation key on Turkish servers (culture-sensitive lowercasing) - affected skills starting with "I" (e.g. Illiterate, Impostor, InfiniteAmmo, Iana). [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### RayTrace-based skills and the skill-use button no longer throw when the RayTrace module is not installed - they now degrade gracefully instead of crashing. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Fixed the skill-use button (when bound to Use/E) blocking option selection inside WSAD target menus. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Performance: cached reflection lookups in `SkillAction` and `SkillsInfo.GetValue`, and de-duplicated the repeated event-dispatch logic on hot paths (OnTick, OnTakeDamage, etc.). [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Stability: removed dead methods that threw `NotImplementedException`, hardened team-score handling, and reset all skill state on round start / map change. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Build: post-build copy paths now follow the active `$(Configuration)` and `$(TargetFramework)`. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Added new Turkish translation strings for the skill notifications listed below. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Fixed bot-related messages so they now display correctly in the chat of the controlling player.
    - ###### When a player takes control of a bot, all active skill effects affecting that bot are now correctly transferred to the controlling player.
    - ###### Prevented bots from automatically using skills while being controlled by a player.

- #### Skill improvements:
    - ###### Wallhack:
        - ###### Fixed enemy outlines briefly flashing for everyone when the skill holder dies. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Area Reaper:
        - ###### Teammates (CT) are now notified which bombsite (A/B) was sealed. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Wild Throw:
        - ###### Now notifies the targeted player, consistent with other targeted skills. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Careful Bullets / Darkness / Deaf / Glitch / Jammer / Jump Ban / Magnifier / Poison / Primary Ban / Wild Throw:
        - ###### The targeted player is now notified when the effect ends after the skill holder dies. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
    - ###### Careful Bullets:
        - ###### Added damage-taken sound effects when missing a shot
    - ###### C4 Camouflage / Ninja:
        - ###### Fixed a bug where dying with invisibility active and taking control of a bot would grant invisibility to the bot as well.
    - ###### Poison:
        - ###### Added damage-taken sound effects.
    - ###### Primary Ban:
        - ###### Changed mechanic to directly block shooting weapons instead of forcing a weapon switch to the knife.
    - ###### Hot Bomb:
        - ###### Replaced the bomb-burning sound effects.
        - ###### Added a notification when the burning effect ends and the bomb returns to its normal color.
2026-06-29 06:12:53 +02:00

658 lines
No EOL
35 KiB
C#

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.Utils;
using src.menu;
using src.player;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.command
{
public static class Command
{
private static bool gamePaused = false;
private static Config.SettingsModel config = Config.LoadedConfig;
private static readonly ConcurrentDictionary<string, CommandInfo.CommandCallback> oldCommands = [];
private static readonly ConcurrentDictionary<uint, int> nextSkill = [];
private static readonly object setLock = new();
public static void Load()
{
config = Config.LoadedConfig;
if (config == null || config == null) return;
lock (setLock)
{
if (!oldCommands.IsEmpty)
{
foreach (var command in oldCommands)
Instance.RemoveCommand(command.Key, command.Value);
oldCommands.Clear();
}
var commands = new Dictionary<IEnumerable<string>, (string description, CommandInfo.CommandCallback handler)>
{
{ SplitCommands(config.NormalCommands.SetSkillCommand.Alias), ("Set skill", Command_SetSkill) },
{ SplitCommands(config.NormalCommands.SkillsListCommand.Alias), ("Delete all records", Command_SkillsListMenu) },
{ SplitCommands(config.NormalCommands.UseSkillCommand.Alias), ("Use/Type skill", Command_UseTypeSkill) },
{ SplitCommands(config.NormalCommands.ConsoleCommand.Alias), ("Console command", Command_CustomCommand) },
{ SplitCommands(config.NormalCommands.HealCommand.Alias), ("Heal", Command_Heal) },
{ SplitCommands(config.NormalCommands.HealthCommand.Alias), ("Set heath", Command_Health) },
{ SplitCommands(config.NormalCommands.PlantedBomb.Alias), ("Spawn planted bomb", Command_PlantedBomb) },
{ SplitCommands(config.NormalCommands.BotPlace.Alias), ("Place bot on your position", Command_BotPlace) },
{ SplitCommands(config.NormalCommands.HudCommand.Alias), ("Enable/Disable HUD", Command_HUD) },
{ SplitCommands(config.NormalCommands.SetStaticSkillCommand.Alias), ("Set static skill", Command_SetStaticSkill) },
{ SplitCommands(config.NormalCommands.ChangeLanguageCommand.Alias), ("Change language", Command_ChangeLanguage) },
{ SplitCommands(config.NormalCommands.ReloadCommand.Alias), ("Reaload configs", Command_Reload) },
{ SplitCommands(config.NormalCommands.NextCommand.Alias), ("Next skill", Command_Next) },
{ SplitCommands(config.VotingCommands.ChangeMapCommand.Alias), ("Change map", Command_ChangeMap) },
{ SplitCommands(config.VotingCommands.StartGameCommand.Alias), ("Start game", Command_StartGame) },
{ SplitCommands(config.VotingCommands.SwapCommand.Alias), ("Swap team", Command_Swap) },
{ SplitCommands(config.VotingCommands.ShuffleCommand.Alias), ("Shuffle team", Command_Shuffle) },
{ SplitCommands(config.VotingCommands.PauseCommand.Alias), ("Pause game", Command_Pause) },
{ SplitCommands(config.VotingCommands.SetScoreCommand.Alias), ("Set teams score", Command_SetScore) },
};
foreach (var commandPair in commands)
foreach (var command in commandPair.Key)
{
Instance.AddCommand($"css_{command}", commandPair.Value.description, commandPair.Value.handler);
oldCommands.TryAdd($"css_{command}", commandPair.Value.handler);
}
}
}
private static IEnumerable<string> SplitCommands(string commands)
{
return commands.Split(',').Select(c => c.Trim()).Where(c => !string.IsNullOrEmpty(c));
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_UseTypeSkill(CCSPlayerController? player, CommandInfo _)
{
player = PlayerManager.GetPlayerEvent(player);
if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null || playerInfo.IsDrawing) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
return;
string[] commands = _.ArgString.Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries);
Debug.WriteToDebug($"Player {player.PlayerName} used the skill: {playerInfo.Skill}");
if (commands == null || commands.Length == 0)
Instance.SkillAction(playerInfo.Skill.ToString(), "UseSkill", [player]);
else
Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [player, commands]);
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_SetSkill(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setskill {command.ArgString} command.");
if (!string.IsNullOrEmpty(config.NormalCommands.SetSkillCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetSkillCommand.Permissions)) return;
var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => p != null && p.IsValid
&& (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase)
|| p.PlayerName.Equals(command.GetArg(1), StringComparison.OrdinalIgnoreCase)));
if (command.ArgCount < 2)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("correct_form_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"));
return;
}
if (targetPlayer == null)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
return;
}
var skillName = command.ArgCount > 3 ? $"{command.GetArg(2)} {command.GetArg(3)}" : command.GetArg(2);
var skill = SkillData.Skills.FirstOrDefault(s => player != null && player.GetSkillName(s.Skill).Equals(skillName, StringComparison.OrdinalIgnoreCase) || s.Skill.ToString().Equals(skillName, StringComparison.OrdinalIgnoreCase));
if (skill == null)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("skill_not_found_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"));
return;
}
var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer.Index);
if (skillPlayer != null)
{
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
skillPlayer.Skill = skill.Skill;
skillPlayer.SpecialSkill = Skills.None;
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("done_setskill"));
return;
}
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
}
else
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("error_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"));
}
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_SkillsListMenu(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_skills {command.ArgString} command.");
if (player == null) return;
if (!string.IsNullOrEmpty(config.NormalCommands.SkillsListCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SkillsListCommand.Permissions)) return;
Menu.DisplaySkillsList(player);
}
[CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_ChangeMap(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_map {command.ArgString} command.");
if (player != null && player.IsValid)
if (!string.IsNullOrEmpty(config.VotingCommands.ChangeMapCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.ChangeMapCommand.Permissions))
{
if (!config.VotingCommands.ChangeMapCommand.EnableVoting) return;
player.Vote(VoteType.ChangeMap, command.ArgString);
return;
}
ChangeMap(command);
}
private static void ChangeMap(CommandInfo command)
{
string map = command.GetArg(1).ToLower();
if (string.IsNullOrEmpty(map))
{
command.ReplyToCommand($" {ChatColors.Red}{command.CallingPlayer?.GetTranslation("invalid_map")}");
return;
}
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} ({ChatColors.Green}{map}{ChatColors.Yellow})...", ["loading_map"]);
if (uint.TryParse(map, out _))
Server.ExecuteCommand($"host_workshop_map {map}");
else if (!Server.IsMapValid(map))
command.ReplyToCommand($" {ChatColors.Red}{command.CallingPlayer?.GetTranslation("invalid_map")}");
else
Server.ExecuteCommand($"changelevel {map}");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_StartGame(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_start {command.ArgString} command.");
if (player != null && player.IsValid)
if (!string.IsNullOrEmpty(config.VotingCommands.StartGameCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.StartGameCommand.Permissions))
{
if (!config.VotingCommands.StartGameCommand.EnableVoting) return;
player.Vote(VoteType.StartGame);
return;
}
StartGame(command);
}
private static void StartGame(CommandInfo command)
{
int cheats = command.GetArg(1) == "sv" ? 1 : 0;
foreach (string consoleCommand in cheats == 1
? Config.LoadedConfig.VotingCommands.StartGameCommand.SVStartParams.Split(";")
: Config.LoadedConfig.VotingCommands.StartGameCommand.StartParams.Split(";"))
Server.ExecuteCommand(consoleCommand);
if (Instance?.GameRules?.WarmupPeriod == true)
{
Server.ExecuteCommand("mp_warmup_end");
Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"]);
}
else
{
Server.ExecuteCommand("mp_restartgame 2");
Instance?.AddTimer(2.0f, () => Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"]), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_Swap(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_swap {command.ArgString} command.");
if (player != null && player.IsValid)
if (!string.IsNullOrEmpty(config.VotingCommands.SwapCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.SwapCommand.Permissions))
{
if (!config.VotingCommands.SwapCommand.EnableVoting) return;
player.Vote(VoteType.SwapTeam);
return;
}
Swap();
}
private static void Swap()
{
foreach (var player in Utilities.GetPlayers())
if (Instance.IsPlayerValid(player) && new CsTeam[] { CsTeam.CounterTerrorist, CsTeam.Terrorist }.Contains(player.Team))
player.SwitchTeam(player.Team == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist);
Server.ExecuteCommand($"endround");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_Shuffle(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_shuffle {command.ArgString} command.");
if (player != null && player.IsValid)
if (!string.IsNullOrEmpty(config.VotingCommands.ShuffleCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.ShuffleCommand.Permissions))
{
if (!config.VotingCommands.ShuffleCommand.EnableVoting) return;
player.Vote(VoteType.ShuffleTeam);
return;
}
Shuffle();
}
private static void Shuffle()
{
var players = Utilities.GetPlayers().FindAll(p => Instance.IsPlayerValid(p) && new CsTeam[] { CsTeam.CounterTerrorist, CsTeam.Terrorist }.Contains(p.Team));
double CTlimit = Instance.Random.Next(0, 2) == 0 ? Math.Floor(players.Count / 2.0) : Math.Ceiling(players.Count / 2.0);
foreach (var player in players.OrderBy(_ => Instance.Random.Next()).ToList())
{
player?.SwitchTeam(CTlimit > 0 ? CsTeam.CounterTerrorist : CsTeam.Terrorist);
CTlimit--;
}
Server.ExecuteCommand($"mp_restartgame 1");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_Pause(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_pause {command.ArgString} command.");
if (player != null && player.IsValid)
if (!string.IsNullOrEmpty(config.VotingCommands.PauseCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.PauseCommand.Permissions))
{
if (!config.VotingCommands.PauseCommand.EnableVoting) return;
player.Vote(VoteType.PauseGame);
return;
}
Pause();
}
private static void Pause()
{
Localization.PrintTranslationToChatAll($" {(gamePaused ? ChatColors.Green : ChatColors.Red)}{{0}}", [gamePaused ? "unpause" : "pause"]);
Server.ExecuteCommand(gamePaused ? "mp_unpause_match" : "mp_pause_match");
gamePaused = !gamePaused;
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_Heal(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_heal {command.ArgString} command.");
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (!string.IsNullOrEmpty(config.NormalCommands.HealCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HealCommand.Permissions)) return;
SkillUtils.AddHealth(player.PlayerPawn.Value, 100);
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("healed")}");
}
[CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_Health(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_health {command.ArgString} command.");
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (!string.IsNullOrEmpty(config.NormalCommands.HealthCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HealthCommand.Permissions)) return;
var pawn = player.PlayerPawn.Value;
if (int.TryParse(command.GetArg(1), out int health))
SkillUtils.AddHealth(pawn, health - pawn.Health, health);
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("set_health")}");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_PlantedBomb(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_plantedbomb {command.ArgString} command.");
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (!string.IsNullOrEmpty(config.NormalCommands.PlantedBomb.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.PlantedBomb.Permissions)) return;
CPlantedC4? bomb = Utilities.CreateEntityByName<CPlantedC4>("planted_c4");
if (bomb == null || !bomb.IsValid) return;
var pawn = player.PlayerPawn.Value;
bomb.Teleport(pawn.AbsOrigin, pawn.AbsRotation);
bomb.DispatchSpawn();
bomb.BombTicking = true;
if (!int.TryParse(command.GetArg(1), out int time))
time = 40;
bomb.C4Blow = Server.CurrentTime + time;
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("planted_bomb_spawned", [time])}");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_BotPlace(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_bot_place {command.ArgString} command.");
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (!string.IsNullOrEmpty(config.NormalCommands.BotPlace.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.BotPlace.Permissions)) return;
var pawn = player.PlayerPawn.Value;
if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE || pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
if (!int.TryParse(command.GetArg(1), out int botSlot))
botSlot = -1;
var bot = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.IsBot && p.PawnIsAlive && (botSlot == -1 || p.Slot == botSlot)).FirstOrDefault();
if (bot == null || bot.PlayerPawn.Value == null || !bot.PlayerPawn.Value.IsValid)
{
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed_not_found")}");
return;
}
bot.PlayerPawn.Value.Teleport(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z), new QAngle(pawn.AbsRotation.X, pawn.AbsRotation.Y, pawn.AbsRotation.Z), Vector.Zero);
bot.PlayerPawn.Value.TakesDamage = true;
if ((bool.TryParse(command.GetArg(2), out bool godmode) && godmode == true)
|| (int.TryParse(command.GetArg(2), out int godmodeInt) && godmodeInt == 1))
bot.PlayerPawn.Value.TakesDamage = false;
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed")}");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_HUD(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_hud {command.ArgString} command.");
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
if (!string.IsNullOrEmpty(config.NormalCommands.HudCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HudCommand.Permissions)) return;
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null) return;
playerInfo.DisplayHUD = !playerInfo.DisplayHUD;
SkillUtils.CloseMenu(player);
player.PrintToChat($" {(playerInfo.DisplayHUD ? ChatColors.Green : ChatColors.Red)}{player.GetTranslation(playerInfo.DisplayHUD ? "hud_on" : "hud_off")}");
}
[CommandHelper(minArgs: 2, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_SetScore(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setscore {command.ArgString} command.");
if (player != null && player.IsValid)
if (!string.IsNullOrEmpty(config.VotingCommands.SetScoreCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.SetScoreCommand.Permissions))
{
if (!config.VotingCommands.SetScoreCommand.EnableVoting) return;
player.Vote(VoteType.SetScore, command.ArgString);
return;
}
SetScore(player, command);
}
private static void SetScore(CCSPlayerController? player, CommandInfo command)
{
if (!int.TryParse(command.GetArg(1), out int ctScore) || !int.TryParse(command.GetArg(2), out int tScore))
{
if (player != null && player.IsValid)
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setscore"));
return;
}
SkillUtils.SetTeamScores((short)ctScore, (short)tScore, RoundEndReason.RoundDraw);
}
[CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_CustomCommand(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_console {command.ArgString} command.");
if (player == null) return;
if (!string.IsNullOrEmpty(config.NormalCommands.ConsoleCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.ConsoleCommand.Permissions)) return;
string param = command.ArgString;
Server.ExecuteCommand(param);
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_SetStaticSkill(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setstaticskill {command.ArgString} command.");
if (!string.IsNullOrEmpty(config.NormalCommands.SetStaticSkillCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetStaticSkillCommand.Permissions)) return;
var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => p != null && p.IsValid
&& (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase)
|| p.PlayerName.Equals(command.GetArg(1), StringComparison.OrdinalIgnoreCase)));
if (command.ArgCount < 2)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("correct_form_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"));
return;
}
if (targetPlayer == null)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
return;
}
var skillName = command.ArgCount > 3 ? $"{command.GetArg(2)} {command.GetArg(3)}" : command.GetArg(2);
var skill = SkillData.Skills.FirstOrDefault(s => player != null && player.GetSkillName(s.Skill).Equals(skillName, StringComparison.OrdinalIgnoreCase) || s.Skill.ToString().Equals(skillName, StringComparison.OrdinalIgnoreCase));
if (skill == null)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("skill_not_found_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"));
return;
}
var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer.Index);
if (skillPlayer != null)
{
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
skillPlayer.Skill = skill.Skill;
skillPlayer.SpecialSkill = src.player.Skills.None;
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
if (skill.Skill == src.player.Skills.None)
Event.staticSkills.TryRemove(targetPlayer.Index, out _);
else
Event.staticSkills.TryAdd(targetPlayer.Index, skill);
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("done_setskill"));
return;
}
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
}
else
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("error_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"));
}
}
[CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_ChangeLanguage(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_lang {command.ArgString} command.");
if (player == null || !player.IsValid) return;
if (!string.IsNullOrEmpty(config.NormalCommands.ChangeLanguageCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.ChangeLanguageCommand.Permissions)) return;
string fileName = Config.LoadedConfig.LanguageSystem.DefaultLangCode;
string newLangCode = command.GetArg(1).ToUpper();
foreach (var langInfo in Config.LoadedConfig.LanguageSystem.LanguageInfos)
if (langInfo.IsoCodes.Contains(newLangCode))
fileName = langInfo.FileName;
if (Localization.HasTranslation(newLangCode))
fileName = newLangCode.ToLower();
Localization.ChangePlayerLanguage(player, fileName);
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void Command_Reload(CCSPlayerController? player, CommandInfo command)
{
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_reload {command.ArgString} command.");
if (!string.IsNullOrEmpty(config.NormalCommands.ReloadCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.ReloadCommand.Permissions)) return;
lock (setLock)
{
Config.LoadConfig();
SkillsInfo.LoadSkillsInfo();
Localization.Load();
Load();
SkillData.Skills.Clear();
foreach (var skill in Enum.GetValues(typeof(Skills)))
if (SkillsInfo.GetValue<bool>(skill, "active"))
Instance.SkillAction(skill.ToString()!, "LoadSkill");
if (player != null && player.IsValid)
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("reload")}");
else
Server.PrintToConsole($" {ChatColors.Green}{Localization.GetTranslation("reload")}");
foreach (var target in Instance.SkillPlayer)
{
if (SkillsInfo.GetValue<bool>(target.Skill, "active") == false)
target.Skill = Event.noneSkill.Skill;
if (SkillsInfo.GetValue<bool>(target.SpecialSkill, "active") == false)
target.SpecialSkill = Event.noneSkill.Skill;
}
}
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_Next(CCSPlayerController? player, CommandInfo command)
{
if (player == null || !player.IsValid) return;
Debug.WriteToDebug($"Player {player.PlayerName} used the css_next {command.ArgString} command.");
if (!string.IsNullOrEmpty(config.NormalCommands.NextCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.NextCommand.Permissions)) return;
var skillsList = SkillData.Skills.OrderBy(s => s.Skill.ToString()).ToList();
if (skillsList.Count == 0) return;
string playerString = command.GetArg(1);
CCSPlayerController? targetPlayer = null;
if (!string.IsNullOrEmpty(playerString))
{
targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => p != null && p.IsValid
&& (p.SteamID.ToString().Equals(playerString, StringComparison.CurrentCultureIgnoreCase)
|| p.PlayerName.Equals(playerString, StringComparison.OrdinalIgnoreCase)));
if (targetPlayer == null)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
return;
}
}
if (targetPlayer == null)
return;
nextSkill.TryGetValue(targetPlayer.Index, out int currentIndex);
int nextIndex = (currentIndex + 1) % skillsList.Count;
string arg = command.GetArg(2);
if (!string.IsNullOrEmpty(arg))
{
if (arg == "-1")
nextIndex--;
else if (int.TryParse(arg, out int newIndex))
nextIndex = newIndex;
else
return;
}
var skill = skillsList[nextIndex];
player.PrintToChat(nextIndex.ToString());
var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer!.Index);
if (skillPlayer == null) return;
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
skillPlayer.Skill = skill.Skill;
skillPlayer.SpecialSkill = Skills.None;
nextSkill[targetPlayer.Index] = nextIndex;
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
}
}
}