I am a IRCop on a server and run a game script on a large channel. I want to check if a nick is registered (identified) before the game will respond to users.
What is the best way to determine if a nick is registered? I know when you /whois nick, raw 307 states when they are registered and also /ns status nick returns if the nick is registered. Are there any other methods that I can use? How can I put this in an alias that will be used as an identifier (if ($registered.nick($nick) == $true) ... )
To put the least load on the server, I suggest to use the /who command (flag "r" in usermodes token).
- /who the channel once after you (or the bot) joined, parse the raw replies and store the registration status of all nicks to a distinct hash table
- use all the respective events to keept the hash table data up to date (remove nicks on part/quit/kick/nickchange; who-and-add new nicknames on join/nickchange)
- note that no such approach will ever be without flaw: the user may always register/drop/ns logout his current nick... but it's as close as you can get without *massive* overhead.
I don't really think it would be massive overhead if you just do the following and then you don't have to worry about whether or not they identify later.
- User tries using a bot command.
- If the user isn't in the hash table of registered nicks, check if the nick is registered.
- If so, add the nick to the hash table. This won't have to be done again unless the nick leaves the channel.
- If not, don't do anything with the nick, but put in a delay before checking again so the user cannot spam the bot commands without being registered. Make it something like once every 10-30 seconds. If the user identifies, then after the timer is done, the nick will be added to the hash table the next time a bot command is done by that user. They will still have to wait for the 10-30 seconds before being allowed to use the commands, but that's not a big problem, imo.
- When a person leaves the channel (part/quit), remove them from the hash table if they are in the table.
- When a person changes their nick, update their nick in the hash table if they are in the table.
This way, you don't have a lot of overhead because: You aren't checking everyone. You are only checking a registered user once. You are only checking an unregistered user once ever X seconds and only if a command is used. You don't check anyone who isn't playing the game.
That should work alright, I think.
I did consider that approach. However, while it would reduce server overhead, it would increase script overhead: Due to the delayed /who reply you would have to exchange simple, direct text event processing with a scripted command queue.
Furthermore, you'd possibly have to put the commands of all the players on hold (not only commands of nicks that are new or did "time out"), depending on whether sequential command processing is required for the game...
another strategy could be to use the +R mode
//mode $me +R
if the irc network supports +R mode, then your bot will not see any CTCP or NOTICE from a nick that's not identified to nickserv. If the users communicate with the bot via /notice, then the bot wouldn't need to do anything since it wouldn't see the non-identified chatter. Some networks also have a +M mode that can be given to a channel, which would prevent someone from typing text into the channel window unless they're identified.
thanks for all the ideas. I did it like this:
after I join the channel a timer is set to one minute.
the timer triggers all the users into chunks of 16 at a time (since nickserv responds to /ns status <nick1> thru <nick16>).
nickserv then is sent the chunked nicks status requests every 5 seconds.
if the nick's status is 3, then they are added to a hash table along with $ctime as the data. if the nick is already in the hash table, nickserv is not sent a status request for that nick.
as nicks join the channel, (and are not in the hash table as registered) they are chunked as well and nickserv status requests are sent out every couple minutes OR they are sent instantly if 16 nicks join within a couple of minutes (no worries about flooding, we have channel flood protection).
a timer that is triggered every few hours is then triggered to check all the nicks in the hash table. if the nick is older than 21 days (due to nicks that are not used are released after 21 days) then they are removed from the hash table.