Contents
DMDirc
I am one of the developers for an IRC Client called DMDirc (More information can be found on the site).
I’m primarily in charge of the actual IRC Parser, and the plugin system however I have also developed some of the other plugins such as the DCC Plugin.
DFBnc
I also develop an IRC “Bouncer” called DFBnc which is based around the DMDirc IRCParser.
The combination of these 2 applications has contributed to the ideas of these proposals.
IRC List Modes
Whilst developing the parser for DMDirc I noticed that the current way listmodes work is rather flawed, At the moment there is no usable standard for getting the current listmodes of a channel on an irc network.
Each ircd uses its own list modes, and numerics for giving the information, there is no easy way to be able to parse these lists reliably without checking EVERY ircd to see what numerics it uses, and even that isn’t enough.
Take for example freenode’s hyperion IRCD, and the following commands:
MODE #Channel +d %moded!user@host
MODE #Channel +d moded!user@host
MODE #Channel +q modeq!user@host
MODE #Channel +b modeb!user@host
This will:
- set a ban on a user with the host “modeb!user@host”
- silence a user with the host “modeq!user@host”
- ban anyone with a realname of “%moded!user@host”
- ban anyone with a realname of “moded!user@host”
Seems easy enough? - if you are in the channel at the time the mode is set, you can easily see what mode it is (b, q, d). However a new client joining doesn’t see this, instead they issue the following command:
MODE #Channel bqd
to which they get the following response back:
:pratchett.freenode.net 367 DFTest #Channel modeb!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 367 DFTest #Channel %modeq!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 368 DFTest #Channel :End of Channel Ban List
:pratchett.freenode.net 367 DFTest #Channel moded!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 367 DFTest #Channel %moded!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 368 DFTest #Channel :End of Channel Ban List
There is no easy way to know which were set as mode d, and which were mode b as they come from the same numeric. (Of course you could statefully remember which modes you asked for in which order - but on dancer/hyperion using “bdq” not “bqd” returns the exact same - q and b are merged into one, which would still require some hard-coded knowledge. There is also still the problem that not all IRCDs use the same numeric for everything)
RPL_ISUPPORT
allows IRC parser/client developers to dynamically discover what modes are
available on the IRCD, yet the raw numerics for each type of list mode still need to be hardcoded.
My Proposal
To aid in the design of IRC Parsers, I propose an addition to RPL_ISUPPORT
and a new
command.
The addition to RPL_ISUPPORT
is a LISTMODE=997
option.
This new option would let clients know that there is an easy-to-parse/sensible way to get the current list
modes on a channel, the LISTMODE
command. (ie /LISTMODE #Channel bdq
or
(/LISTMODE #Channel *
for all list modes))
The LISTMODE
commands given above would return the following:
:pratchett.freenode.net 997 DFTest #Channel b modeb!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 997 DFTest #Channel d %moded!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 997 DFTest #Channel d moded!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 997 DFTest #Channel q %modeq!user@host DFTest!i=shane@dataforce.org.uk 1173715309
:pratchett.freenode.net 998 DFTest #Channel :End of Channel List Modes
The numeric used for the individual items is the same as specified in RPL_ISUPPORT
(in this
case 997) and the End of list modes
uses LISTMODE+1
for its numeric. This allows
ircds to use what ever numeric they want that is free - without clients needing to know what numeric each IRCD
uses in advance.
The addition of the /LISTMODE
command and not just altering the current /MODE
command is to maintain backwards compatibility with older clients.
Error Handling
Error handling is similar to that for the traditional /MODE
request:
- If a client requests modes for a channel they are not on,
ERR_NOTONCHANNEL
(Numeric 442) should be returned - If a client requests a mode that is not a list mode or not a mode at all, then
ERR_UNKNOWNMODE
(Numeric 472) should be given for each invalid mode. - If a client requests a mode that they do not have access to see (eg +e or +I on Hybrid-based ircds) then
ERR_CHANOPRIVSNEEDED
(Numeric 482) should be returned.
If a request for “*” is given, then the only error permitted is ERR_NOTONCHANNEL
.
Existing list mode information
To the best of my knowledge, the information on the dmdirc wiki provides a complete list of current numerics used by various IRCDs, and is what the DMDirc parser uses for parsing list modes
Known Implementations
At the moment as far as I am aware the only IRC Client/Parser that understands the LISTMODE
option/command is DMDirc (however smuxi appears
to be considering it, and the only server that allows
its use is WeIRCd (irc://irc.eloxoph.com/) and the only “bouncer” that allows its use is DFBnc-Java.
Questions, Comments, Corrections
Any questions about this should be sent to IRCDevel@Dataforce.org.uk, or contact Dataforce in #DMDirc on Quakenet or Freenode
Changelog
- 2009-11-25 - Added Error Handling.
Timestamped IRC
Unlike the previous proposal, this one is much less generic and has a somewhat specific use case, but nevertheless seems useful enough to implement and document.
When a user reconnects to a bouncer, they often do so either in the midst of ongoing conversations or during a periods of downtime for channels. In the first case, the user may need to wait a while before jumping in, and in the latter case the user probably won’t even know.
Often the solution to the first case is to provide a “backbuffer” of conversation, the last X lines or so.
This can be replayed as a series of notices (which then looks out of place) or as a series of
PRIVMSG
s as they arrived to the BNC. Both of these work well for the first case, but often provide
no hint about when these occurred, unless a timestamp is hacked into the line either at the start or
end which again looks out of place.
Since this was written, an alternative has been proposed by the IRCv3 working group, the server-time extension which covers the same use-cases as this proposal, but is implemented using server capabilities.
My Proposal
Therefore, a possible solution to both is to provide a timestamp alongside the replayed
PRIVMSG
, and allow the IRC Client to display this however it sees fit.
As before, I propose an addition to RPL_ISUPPORT
and a new command.
The addition to RPL_ISUPPORT
is a TIMESTAMPEDIRC
option.
This new option would let clients know that the servers supports TimestampedIRC. The client could then
enable it with a TIMESTAMPEDIRC
command. (ie /TIMESTAMPEDIRC ON
)
Once enabled, certain types of messages can include timestamp data. My suggestion is to add this at the very beginning of the line, as follows:
@1316145182038@:Dataforce!Shane@dataforce.org.uk PRIVMSG #DMDirc :Test Message
Clients can then check for the presence of ‘@’ at the start of the line to see if a timestamp has been included, and then they can find the end of it with the next ‘@’ symbol, anything beyond then should be parsed as normal. It is important to note that IRC lines must still remain under 512 characters long, even with the timestamp prepended to the start.
The timestamp is based on the java’s System.currentTimeMillis()
, so where milliseconds are
unsupported, timestamps should be multiplied or divided by 1000 as appropriate.
It is suggested that not every line be timestamped to cut down on processing time, only those where it makes sense. Clients that understand timestamping are free to ignore any timestamps they see fit, as the timestamp is only a suggestion.
Timezones and clock skew
Obviously, not all servers are in perfect sync with each other time wise, different timezones, or skewed clock. This has been taken into consideration.
Once a client has signalled their desire to start using timestamps with /TIMESTAMPEDIRC
or
/TIMESTAMPEDIRC ON
, the server responds with something like:
:my.server.name TSIRC 1 1316146177387 :Timestamped IRC Enabled
The parameter of note here is the 4th parameter, this is the current time on the server and can be used by the client to determine the difference between timestamps which it can then use when processing any timestamped messages.
Currently, the 3rd parameter is “1” if TimestampedIRC has been enabled, or “0” if it was disabled
(/TIMESTAMPEDIRC OFF
). A server can (if it so wishes) refuse to enable TimestampedIRC by always
setting this to 0.
Known Implementations
At the moment as far as I am aware the only IRC Client/Parser that understands the TIMESTAMPEDIRC option/command is DMDirc, no servers currently support it, and the only “bouncer” that allows its use is DFBnc-Java.
Questions, Comments, Corrections
Any questions about this should be sent to Dataforce@Dataforce.org.uk, or contact Dataforce in #DMDirc on Quakenet or Freenode
Changelog
- 2011-10-16 - First draft.