Initial simple Colloquy 2 parser implementation
-------------------------------------------------------------------------------
-- Colloquy 2 -- Protocol Parser
--
-- Copyright (c) 2005 Rob Kendrick <rjek@rjek.com>
-- Daniel Silverstone <dsilvers@digital-scurf.org>
--
-- This code handles the parsing of the C2 protocol, and dispatching commands
-- to their handler functions.
--
-- Modules can add hooks into the parser to add new commands, and remove them
-- as an when they feel they want to.
--
-- A handler function is passed four parameters. These are:
-- connection: The connection object that the command should be executed as
-- tag: The client's chosen prefix tag for this command
-- command: The command's token/name (ie, 'SAY')
-- parameters: The rest of the data as-is.
-------------------------------------------------------------------------------
local handlers = { }
local setHandler = function(token, handler, permissions, comment)
-- Sets a handler for a token to the parser.
-- token: Token we're dealing with (ie, 'SAY' or 'QUIT')
-- handler: Function to call to deal with this, or nil to remove it.
-- permissions: A function to call to see if the current user has permission
-- to execute this command. It is passed the user's connection
-- object, and the command's name, and its parameter data.
-- comment: Normally just the name of the module providing this handler
--
-- Return value: nil on success, otherwise an error string. This will
-- almost certainly be 'Token already handled'
if handler then
handlers[token] = {
handler = handler,
permissions = permissions,
comment = comment
}
else
handlers[token] = nil
end
return nil
end
local doParse = function(connection, data)
-- Parses and executes a command from a client
-- connection: Connection of the client we're doing this as
-- data: A single line of data that we've received from them.
--
-- Return value: Always nil
local handler
local null, null, tag, command, parameters =
string.find(data, "(%S*) (%S*) ?(.*)")
handler = handlers[command]
if handler then
if handler.permissions(connection, command, parameters) then
pcall(handler, connection, tag, command, parameters)
else
connection:send(tag .. " ERROR Insufficient privilege")
end
else
connection:send(tag .. " ERROR Unhandled command")
end
return nil
end
parser = {
set = setHandler,
parse = doParse
}