Commands
SwiftlyS2's command system lets you register commands, hook client commands and chat, and manage permissions - via attributes or programmatically.
Registering Commands
With Attributes
Attach [Command] to a method matching void CommandListenerFunction(ICommandContext context).
[Command("heal", registerRaw: false, permission: "admins.commands.heal")]
public void OnHealCommand(ICommandContext context)
{
if (!context.IsSentByPlayer)
{
context.Reply("This command can only be used by players!");
return;
}
var player = context.Sender!;
}See APICommand for the full attribute reference - registerRaw skips the sw_ prefix; permission is checked before the handler runs (heal above registers as sw_heal, gated by admins.commands.heal).
Programmatically
Same signature, registered via APIICommandService.RegisterCommand - the returned Guid is for later unregistration.
public override void Load(bool hotReload)
{
var commandGuid = Core.Command.RegisterCommand("heal", OnHealCommand);
}Command Context
Every handler receives an APIICommandContext - Sender (APIIPlayer), IsSentByPlayer, Prefix, IsSlient, CommandName, Args, plus Reply/ReplyAsync.
Sender is null when the command is executed from server console. Always
check IsSentByPlayer before dereferencing Sender.
Unregistering Commands
Plugins auto-unregister their commands on unload. To do it manually, see APIICommandService.UnregisterCommand (by Guid or by name) and APIICommandService.IsCommandRegistered to check if a name is taken.
Command Aliases
Aliases register the same handler under extra command names.
With Attributes
Stack APICommandAlias on an already-[Command]-registered method - it allows multiple attributes per method, so heal can gain both hp and h:
[Command("heal")]
[CommandAlias("hp")]
[CommandAlias("h")]
public void OnHealCommand(ICommandContext context)
{
// reachable as sw_heal, sw_hp, sw_h
}Programmatically
// e.g. in Load():
Core.Command.RegisterCommandAlias("heal", "hp");See APIICommandService.RegisterCommandAlias for the full signature.
Introspection
Core.Command can enumerate what's registered, e.g. for a /plugins commands admin command - see APIICommandService.GetAllCommands, APIICommandService.GetCommandsByPlugin, APIICommandService.GetAllCommandsByPlugin and APIICommandService.GetAllCommandsInfo (the latter three return APICommandInfo entries).
Client Command Hooks
Intercept every console command a player sends (~ console), not just ones you registered - via APIClientCommandHookHandler or programmatically with APIICommandService.HookClientCommand/APIICommandService.UnhookClientCommand:
[ClientCommandHookHandler]
public HookResult OnClientCommand(int playerId, string commandLine)
{
if (commandLine.StartsWith("say"))
Console.WriteLine($"Player #{playerId} is using the say command");
return HookResult.Continue;
}Client Chat Hooks
Block or inspect chat messages before they reach other players - word filters, private chats, etc. Same shape, via APIClientChatHookHandler or APIICommandService.HookClientChat/APIICommandService.UnhookClientChat:
[ClientChatHookHandler]
public HookResult OnClientChat(int playerId, string text, bool teamonly)
{
return text.Contains("badword") ? HookResult.Stop : HookResult.Continue;
}HookResult.Stop silently drops the command/message from the player's
perspective - use deliberately.