I suppose you know what this does or what this is supposed to do. Anyway, I've seen a few of these questions asked here and to prevent further issues I've created this small system.
Snippet:
_ExCmd <- {
// --------------------------------------------------------------------------------------------
m__Listeners = array(256, null),
// --------------------------------------------------------------------------------------------
Attach = function(symbol, listener)
{
// Check symbol type
if (typeof(symbol) != "integer")
{
throw "the symbol must be a decimal identifier of an ASCII character";
}
// Check symbol range
else if (symbol < 0 || symbol > 255)
{
throw "the specified ASCII character identifier is out of range";
}
// Look for blocked symbols
else if (symbol == ' ')
{
throw "the specified ASCII character identifier is not allowed";
}
// Check listener type
else if (typeof(listener) != "function")
{
throw "the specified listener is not an executable function";
}
// Store the listener for the specified symbol
else
{
// Overwrite existing!
m__Listeners[symbol] = listener;
}
}
// --------------------------------------------------------------------------------------------
Dettach = function(symbol)
{
// Check symbol type
if (typeof(symbol) != "integer")
{
throw "the symbol must be a decimal identifier of an ASCII character";
}
// Check symbol range
else if (symbol < 0 || symbol > 255)
{
throw "the specified ASCII character identifier is out of range";
}
// Look for blocked symbols
else if (symbol == ' ')
{
throw "the specified ASCII character identifier is not allowed";
}
// Remove the listener for the specified symbol
else
{
m__Listeners[symbol] = null;
}
}
// --------------------------------------------------------------------------------------------
Verify = function(player, text)
{
// Test the validity of the specified text
if (typeof(text) == "string" && text.len() > 1)
{
// Try to remove any spaces at the beginning of the string
text = lstrip(text);
// Grab the symbol from the specified text
local symbol = text[0];
// Remove the symbol from the specified text
text = lstrip(text.slice(1));
// See if the text is valid and there's a listener to the found symbol
if (text.len() && m__Listeners[symbol] != null)
{
// Attempt to find the command separator
local split = text.find(" ");
// See if the command had any arguments
if (split)
{
m__Listeners[symbol].pcall(this, player, text.slice(0, split), text.slice(++split));
}
else
{
m__Listeners[symbol].pcall(this, player, lstrip(text), "");
}
// There was a command and was called
return true;
}
}
// At this point there's no valid command here
return false;
}
}
You need the following modification to your onPlayerChat(...) event:
function onPlayerChat(player, text)
{
// See if this is a command first!
if (_ExCmd.Verify(player, text)) return 0;
// Rest of the code...
}
Example usage:
function SharedCommand(player, cmd, text)
{
print(cmd + "==" + text);
}
function AtCommand(player, cmd, text)
{
print(cmd + "++" + text);
}
// Unique function
_ExCmd.Attach('!', AtCommand);
// Shared function
_ExCmd.Attach('$', SharedCommand);
_ExCmd.Attach('#', SharedCommand);
// Anonymous function
_ExCmd.Attach('@', function(player, cmd, text)
{
print(cmd + "__" + text);
});
Test cases:
print("--Testing: Invalid commands");
onPlayerChat(null, null);
onPlayerChat(null, "");
onPlayerChat(null, 32);
print("--Testing: Command with arguments");
onPlayerChat(null, "the command goes here");
onPlayerChat(null, "!the command goes here");
onPlayerChat(null, "@the command goes here");
onPlayerChat(null, "$the command goes here");
onPlayerChat(null, "#the command goes here");
onPlayerChat(null, "%the command goes here");
print("--Testing: Command without arguments but a trailing space");
onPlayerChat(null, "the ");
onPlayerChat(null, "!the ");
onPlayerChat(null, "@the ");
onPlayerChat(null, "$the ");
onPlayerChat(null, "#the ");
onPlayerChat(null, "%the ");
print("--Testing: Command without arguments but no trailing space");
onPlayerChat(null, "the");
onPlayerChat(null, "!the");
onPlayerChat(null, "@the");
onPlayerChat(null, "$the");
onPlayerChat(null, "#the");
onPlayerChat(null, "%the");
print("--Testing: Command with arguments and prepended space");
onPlayerChat(null, " the command goes here");
onPlayerChat(null, " !the command goes here");
onPlayerChat(null, " @the command goes here");
onPlayerChat(null, " $the command goes here");
onPlayerChat(null, " #the command goes here");
onPlayerChat(null, " %the command goes here");
print("--Testing: Command without arguments but a trailing space and prepended space");
onPlayerChat(null, " the ");
onPlayerChat(null, " !the ");
onPlayerChat(null, " @the ");
onPlayerChat(null, " $the ");
onPlayerChat(null, " #the ");
onPlayerChat(null, " %the ");
print("--Testing: Command without arguments but no trailing space and prepended space");
onPlayerChat(null, " the");
onPlayerChat(null, " !the");
onPlayerChat(null, " @the");
onPlayerChat(null, " $the");
onPlayerChat(null, " #the");
onPlayerChat(null, " %the");
print("--Testing: Command with arguments and extra spaces");
onPlayerChat(null, "the command goes here");
onPlayerChat(null, "! the command goes here");
onPlayerChat(null, "@ the command goes here");
onPlayerChat(null, "$ the command goes here");
onPlayerChat(null, "# the command goes here");
onPlayerChat(null, "% the command goes here");
print("--Testing: Command without arguments but a trailing space and extra spaces");
onPlayerChat(null, " the ");
onPlayerChat(null, "! the ");
onPlayerChat(null, "@ the ");
onPlayerChat(null, "$ the ");
onPlayerChat(null, "# the ");
onPlayerChat(null, "% the ");
print("--Testing: Command without arguments but no trailing space and extra spaces");
onPlayerChat(null, "the");
onPlayerChat(null, "! the");
onPlayerChat(null, "@ the");
onPlayerChat(null, "$ the");
onPlayerChat(null, "# the");
onPlayerChat(null, "% the");
And that's about it.