[Bug]: Argument issue with + / - commands
Prerequisites
- [x] I have checked that my issue doesn't exist yet in the issue tracker
Operating System and Version
Debian GNU/Linux 12 (bookworm)
Game / AppID and Version
CS:S (240)
SourceMod Version
SourceMod 1.13.0.7224
Metamod:Source Version
Metamod:Source version 1.12.0-dev+1217
Version Verification
- [x] I have updated SourceMod to the latest version and the issue persists
- [x] I have updated SourceMod to the latest snapshot and the issue persists
- [x] I have updated Metamod:Source to the latest snapshot and the issue persists
Updated SourceMod Version
SourceMod Version: 1.13.0.7245
Updated Metamod:Source Version
Metamod:Source version 2.0.0-dev+1353
Description
Number of arguments returns more than actually provided. GetCmdArg return a "15" and GetCmdArgString adds a " 15". Using the command via server console does not have any issues.
Steps to Reproduce
#pragma semicolon 1
#pragma newdecls required
public void OnPluginStart()
{
RegConsoleCmd("+sm_test5", Command_Test5, "Test command");
RegConsoleCmd("-sm_test5", Command_Test5, "Test command");
}
Action Command_Test5(int client, int args)
{
char sCommand[32];
GetCmdArg(0, sCommand, sizeof(sCommand));
ReplyToCommand(client, "command: '%s' args: %d", sCommand, args);
char sArguments[128];
GetCmdArgString(sArguments, sizeof(sArguments));
ReplyToCommand(client, "GetCmdArgString: '%s' args: %d", sArguments, args);
for(int i = 1; i <= args; i++)
{
GetCmdArg(i, sArguments, sizeof(sArguments));
ReplyToCommand(client, "GetCmdArg %d: '%s'", i, sArguments);
}
return Plugin_Handled;
}
Relevant Log Output
bind e "+sm_test5"
command: '+sm_test5' args: 1
GetCmdArgString: '15' args: 1
GetCmdArg 1: '15'
command: '-sm_test5' args: 1
GetCmdArgString: '15' args: 1
GetCmdArg 1: '15'
bind e "+sm_test5 quack"
command: '+sm_test5' args: 2
GetCmdArgString: 'quack 15' args: 2
GetCmdArg 1: 'quack'
GetCmdArg 2: '15'
command: '-sm_test5' args: 2
GetCmdArgString: 'quack 15' args: 2
GetCmdArg 1: 'quack'
GetCmdArg 2: '15'
~So far what I have looked. When bind plus or minus plugin command to keyboard button -> plugin command callback gets one extra argument, when push button. And last argument holds key index which command has binded, ex. value 15 is keyboard button 'e'. 26 is 'p'. 25 is 'o'. Not sure, is this behaviour coming from game itself or sourcemod.~
~I try look more.~
Ok, this is in game engine behaviour. When keyboard button is binded with + "button command", it will start carry button key index, it is last argument in command callback. This is for keep tracking when "button command" is pushed down or released (key events).
You can test like this in game console: bind p "+whatever" and in game when you push button many times, you see key release -
Unknown command: +whatever
Unknown command: -whatever
Unknown command: +whatever
Unknown command: -whatever
Unknown command: +whatever
Unknown command: -whatever
you not need create SM command for see this behaviour.
Perhaps I am only one, who would like to still keep this game engine feature in Sourcemod.
After all, you have a way to get button name. This work also on AddCommandListener.
char ButtonCodeName[][] =
{
"",
"0","1","2","3","4","5","6","7","8","9",
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"KP_INS","KP_END","KP_DOWNARROW","KP_PGDN","KP_LEFTARROW","KP_5","KP_RIGHTARROW","KP_HOME","KP_UPARROW","KP_PGUP","KP_SLASH","KP_MULTIPLY","KP_MINUS","KP_PLUS","KP_ENTER","KP_DEL",
"[","]","SEMICOLON","'","`",",",".","/","\\","-","=",
"ENTER","SPACE","BACKSPACE","TAB","CAPSLOCK","NUMLOCK","ESCAPE","SCROLLLOCK","INS","DEL","HOME","END","PGUP","PGDN","PAUSE","SHIFT","RSHIFT","ALT","RALT","CTRL","RCTRL","LWIN","RWIN","APP","UPARROW","LEFTARROW","DOWNARROW","RIGHTARROW",
"F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12",
"CAPSLOCKTOGGLE","NUMLOCKTOGGLE","SCROLLLOCKTOGGLE",
"MOUSE1","MOUSE2","MOUSE3","MOUSE4","MOUSE5","MWHEELUP","MWHEELDOWN"
// lot of joystic buttons
}
#define BUTTONS_MAX 195 // Not 100% sure
public void OnPluginStart()
{
RegConsoleCmd("+sm_test", test);
RegConsoleCmd("-sm_test", test);
}
public Action test(int client, int args)
{
int arguments = args;
int code = 0;
char cmd[20];
char button_name[20];
char buffer[256];
GetCmdArg(0, cmd, sizeof(cmd));
// When button command +command
if(arguments >= 1 && (cmd[0] == '+' || cmd[0] == '-'))
{
// look last argument
GetCmdArg(arguments, button_name, sizeof(button_name));
code = StringToInt(button_name);
if(0 < code < BUTTONS_MAX) // in button range
{
arguments = arguments - 1; // decrease argument count by one
}
else
{
code = 0; // invalid
}
button_name[0] = '\0'; // clear string
}
GetCmdArgString(buffer, sizeof(buffer));
// arguments count have decreased, button found
if(arguments < args && code > 0)
{
// name button
if(code >= sizeof(ButtonCodeName))
{
Format(button_name, sizeof(button_name), "joystic");
}
else
{
Format(button_name, sizeof(button_name), "%s", ButtonCodeName[code]);
}
// remove last argument from buffer[]
if(arguments <= 0)
{
buffer[0] = '\0';
}
else
{
int index = FindCharInString(buffer, ' ', true);
if(index != -1)
buffer[index] = '\0';
}
}
// Results!
PrintToServer("\ncommand: %s\n\
button: %s\n\
GetCmdArgString: %s\n\
args: %i/%i",
cmd, button_name, buffer, arguments, args);
for(int x = 1; x <= arguments; x++)
{
GetCmdArg(x, buffer, sizeof(buffer));
PrintToServer("GetCmdArg %i: %s", arguments, buffer);
}
return Plugin_Handled;
}
Results
bind p "+sm_test"
command: +sm_test
button: p
GetCmdArgString:
args: 0/1
command: -sm_test
button: p
GetCmdArgString:
args: 0/1
bind p "+sm_test quack"
command: +sm_test
button: p
GetCmdArgString: quack
args: 1/2
GetCmdArg 1: quack
command: -sm_test
button: p
GetCmdArgString: quack
args: 1/2
GetCmdArg 1: quack
+sm_test
command: +sm_test
button:
GetCmdArgString:
args: 0/0
+sm_test quack
command: +sm_test
button:
GetCmdArgString: quack
args: 1/1
GetCmdArg 1: quack