Extended Commands

Started by ., Sep 20, 2015, 08:12 PM

Previous topic - Next topic

.

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.
.