ojii/txircd — pull request #12 by ElementalAlchemist (2012-09-17 02:50:39+00:00)
Title: MODE Command

Well, this was fun.

After tons of parsing and rewriting output and realizing that I forgot to check permissions on the status modes (we can't have a halfop giving someone +a, can we?), I've finally completed what turned out to be this monster that is processing the MODE command.

What it does:
- Accepts a MODE command from a user
- If no + or - is provided at the start of the mode string, + is assumed as per standards (not sure whether documented or de facto)
- Checks before processing whether the user is at least a halfop in the channel
- Looks at the mode type
- prefix mode
- list mode
- parameter mode
- requiring on both set and unset
- requiring only on set
- non-parameter modes ("easy mode")
- consumes parameters as necessary, performing whatever processing
- Writes the output to describe what changes actually happened rather than just whichever were provided regardless
- Limits mode changes to 20 in one line (I've seen 4, 6, 19, and 20 allowed by different IRCds. If you want a different limit, go for it.)
- Lists the contents of list mode lists when requested
- Uses "329" instead of irc.RPL_CREATIONTIME because apparently twisted doesn't think RPL_CREATIONTIME is a thing

I went ahead and also added TODOs to various places so that the modes other than 't' and a basic level of status in the channel actually mean something in the future. Modes 's' and 'p' don't have TODOs yet because irc_LIST and irc_WHOIS aren't implemented, but those'll matter when we get that far.

I'm not sure style-wise how I feel about the repetition of the bit with the output rewriter, but otherwise it seems to work for me.

There's a bug where it creates channels if you're requesting modes for nonexistent or invalid channels, which seems to be a bug with how the 'in' operator works with the channels dictionary. Other than that, I haven't encountered any bugs in my testing. Feel free to add your own testing and point out any omissions.