I'm working on an IRC library and three of the good important parts are more or less finished: parsing (transforming IRC lines into events), tracking (keeping track of user information for later retrieval), and command sending (similarly to the events, this is also object-oriented).
It all began when I wanted to the tracker to use an extended feature that appears to have originated with ircu; WHOX. Basically, it is a regular WHO with more possible parameters/flags. However, it gives you so much control that you can specify the fields you want returned. This means you can do the following:
1. WHO all nicknames like J*m, get ident(user) and nickname
2. WHO all nicknames like R*n, get nickname and hostname
There's a problem already; the replies you get back will match both of the original WHO queries perfectly. That is, if you are *only* listening to WHOX replies, you can mistake the reply for the first query to be the one for the second. Sure, you can use basic logic to determine if it is the reply that you really want, but there are certain cases that are basically impossible to use deduction on (this will be covered later -- it concerns conflicting numeric replies for different commands). I know that the WHOX specification has a trick you can use to avoid this problem entirely, but this is disabled on a major network (GameSurge), and it brings about a good question in its broken form: why can't IRC just be treated as queries, where each command (or a set of query-oriented commands) results in a concrete reply of some sort that we can work with ("this WHOIS failed" or "this is the data in the LINKS reply")
WHO/WHOIS/NAMES, etc. are all query commands; you send them, and either get back some listing or an error. They're the perfect sort of thing to design code around where you can do something like the following:
Code: Select all
WhoisReply userWhois = performAWhoisOnNickname("Jill");
Nope, it never can be. The problem is that WHOIS (and many other commands) share numeric replies with *other* commands. So, consider this:
Code: Select all
You PRIVMSG Jill You WHOIS Jill (using that cool sort of query code like above) The server replies with a single ERR_NOSUCHNICK.
I realize that you can use further deduction to deal with this dilemma, but it illustrates a key problem; commands share numerics with other commands, so numeric replies become useless, and you can never decide if a query failed or not. A human won't send outbound commands fast enough to normally run into this problem -- the human can also keep retrying commands based on the situation, although this is less-than-ideal for a bot.
Well, there's an obvious solution that won't work, either:
Turn *every* command into a query. That is, make sure you know all the possible replies for a command, that way you can match the reply to the command that was sent. This theoretically fixes the whole shared-numerics problem quite nicely and allows for even more neat querying abilities.
The monkeywrench thrown into this idea is PRIVMSGs and similar commands. Sure, it has well-defined reply numerics, but they are only for errors. If a PRIVMSG succeeds, you will never know. This breaks the whole send-a-command-wait-for-reply(ies)-to-it model, making it impossible to stack up commands to wait for their replies.
Maybe I am overlooking something that is obvious, but I believe it is essentially impossible to perform queries like that one line of code I provided. Sure, it could be done, but not safely. I believe I will be forced to give up and resort to dangerous guesses for my original issue with the whole WHOX thing, not to mention lack a neat way to pull bans lists and such. Perhaps someone else who's taken up similar endeavors has found a brilliant way to deal with this, or at least a way to minimize potential mixup of numerics!