The core protocol library. irc.tcl
exclusively handles the raw
stream protocol and event dispatch. All other responsibilities are
out-of-scope for it.
It exposes the irc
namespace, which contains the logic for
message-parsing, message validation, channel management, event
dispatch, and various utilities listed below.
irc.tcl
provides 2 ways to connect to an IRC server.
irc::connect
hostname port ?usetls?
Connects to hostname:port
, and sets up all the necessary state. If
usetls is set to true, the tls
module will be used to connect,
instead of the builtin socket
command. If unset, socket
will be used.
irc::enroll
chan ?meta?
Sets up the internal state necessary for chan
to be
used as an IRC socket. It is called internally by irc::connect
. This
command is exposed for the use-case where an IRC channel might have a
more bespoke acquisition process than a simple socket connection.
irc.tcl
provides an event dispatch system, via a fileevent
script registered on the IRC channel. Events are dispatched by matching
their patterns against incoming messages.
irc::listen
subcommand chan
Enable or disable the fileevent
script for the dispatch system.
irc::listen
on
chan
Apply the fileevent
wrapper to chan
. Returns the previous
fileevent
wrapper.
irc::listen
off
chan
Remove the fileevent
wrapper from chan
. Errors if it is not the
irc wrapper.
irc::listener
subcommand chan ?args ...?
Configure listener-type event handlers.
Listener-type handlers are scripts, executed in a sub-interpreter.
The script is executed as part of event handling, and is expected to
return to the main interpreter via after
periodically. For
application responsiveness and stability reasons, it is expected that
listener scripts will not take longer than 100ms to execute, though
this is not enforced. If consistent long-running computations are
required, consider using irc::extern
.
listener
-type scripts are spawned with the variable chan
set to the
channel they recieve dispatches over. This will be a dict
with
contents as described in
Event Dispatch Contents.
They are given access to the
Dispatch-aliased IRC commands.
When a listener is removed, it will recieve a message of just end
. It
should perform necessary cleanup quickly, and return, as the
application is likely exiting, and it may not be re-executed if it
yields.
irc::listener add
chan patlist script
Registers script
as a listener-type handler on chan
, matching
patlist
as described below. Returns an id
that can be passed to irc::listener remove
or irc::patlist
.
irc::listener remove
chan id
Unregisters the listener identified by id
from chan
.
irc::handler
subcommand chan ?args ...?
Configure handler-type event handlers.
Handler-type event handlers execute a script everytime a message is matched. For application responsiveness and stability reasons, it is expected that handler scripts will not take longer than 100ms to execute, though this is not enforced.
Handlers can be created with or without a stored interpreter. If created without, they will be spawned with a new interpreter for each message, and clean scope.
handler
-type scripts are spawned with the variable dispatch
set as
described in
Event Dispatch Contents.
They are given access to the
Dispatch-aliased irc
commands.
When a handler is removed, if it has a stored interpreter, it will be deleted. Applications with persistent state should take care to store it to disk after each command, or use one of the other dispatch types.
irc::handler add
chan patlist script ?interp?
Registers script
as a handler-type handler on chan
, matching
patlist
as described below. Returns an id
that can be passed to irc::extern remove
or irc::patlist
.
If interp
is supplied, script
will be added as a stored-interpreter
handler, with interp
as the stored-interpreter. The same alias setup
performed on internally created interpreters will be performed, once, on
the supplied interpreter, and dispatch
will be set just before
executing script
.
irc::extern remove
chan id
Unregisters the extern handler identified by id
from chan
.
irc::extern
subcommand chan ?args ...?
Configure extern-type event handlers.
Extern-type event handlers are backed by a pair of channels. One is for
message dispatch, one is for message replying. Dispatch comes in pairs
of lines, the first being the source channel and the second being the
raw IRC message. Replies are just single IRC messages. Due to this
asymmetry, it is OK to reuse a dispatch channel for multiple extern
handlers, but not OK to reuse a reply channel. You will need to make
use of FIFOs or pipes for I/O multiplexing.
When an extern-type handler is removed, the channel id and end
will
be written to it. The dispatch pipe is never closed by irc.tcl
. The
reply pipe will be closed immediately. Ensure code that uses multiple
handlers accounts for this.
irc::handler add
chan patlist ochan ichan
Registers ochan
and ichan
as the dispatch and reply pipes of a
extern-type handler on chan
, matching patlist
as
described below. Returns an id that can
be passed to irc::extern remove
or irc::patlist
.
irc::extern remove
chan id
Unregisters the extern handler identified by id
from chan
.
irc::patlist
chan id ?patlist?
Get or set the message pattern list for handler
id
on chan
. If patlist
is supplied, it will override the current
one and return patlist
, otherwise it will return the current pattern
list.
Message pattern lists are lists of lists of string match
patterns. Messages are matched on the command and the first N-1 params,
where N is the length of the message pattern. If the first N segments
all match, the match succeeds. If a message is shorter than a pattern,
the match fails. If any of the message patterns in the message pattern
list for a handler match, the handler is called.
# pattern:
*
# messages:
PRIVMSG #general :what's up gamers
# matches
PRIVMSG #amehut :bot, do something
# matches
PRIVMSG #bot :do something
# matches
PING foo
# matches
# pattern:
{{}}
# messages:
PRIVMSG #general :what's up gamers
# doesn't match
PRIVMSG #amehut :bot, do something
# doesn't match
PRIVMSG #bot :do something
# doesn't match
PING foo
# doesn't match
# pattern:
{{PRIVMSG * {bot, *}} {PRIVMSG #bot}}
# messages:
PRIVMSG #general :what's up gamers
# doesn't match
PRIVMSG #amehut :bot, do something
# matches
PRIVMSG #bot :do something
# matches
PING foo
# doesn't match
# pattern:
PING
# messages:
PRIVMSG #general :what's up gamers
# doesn't match
PRIVMSG #amehut :bot, do something
# doesn't match
PRIVMSG #bot :do something
# doesn't match
PING foo
# matches
The event dispatch dictionary contains the following properties:
rawmsg
: the raw IRC messagechan
: the source channeltags
: the tags portion of the messagesrc
: the source portion of the messagesrctype
: the type of message source, either servername
or user
srcparts
: the srcparts
dict, returned from irc::src parse
cmd
: the command of the messageparams
: the params of the messagemeta
: channel metadata, such as server hostnameirc
ComandsIn listener
and handlers
, the following commands are aliased:
irc::esc
irc::extern
irc::handler
irc::is
irc::listener
irc::msg
irc::patlist
irc::src
irc::tags
irc::unesc
Additionally, the relevant channel is share
d.