def who_reply(cli, bot_server, bot_nick, chan, ident, host, server, nick, status, hopcount_gecos): """Handle WHO replies for servers without WHOX support. Ordering and meaning of arguments for a bare WHO response: 0 - The IRCClient instance (like everywhere else) 1 - The server the requester (i.e. the bot) is on 2 - The nickname of the requester (i.e. the bot) 3 - The channel the request was made on 4 - The ident of the user in this reply 5 - The hostname of the user in this reply 6 - The server the user in this reply is on 7 - The nickname of the user in this reply 8 - The status (H = Not away, G = Away, * = IRC operator, @ = Opped in the channel in 4, + = Voiced in the channel in 4) 9 - The hop count and realname (gecos) This fires off the "who_result" event, and dispatches it with three arguments, the game state namespace, a Channel, and a User. Less important attributes can be accessed via the event.params namespace. """ hop, realname = hopcount_gecos.split(" ", 1) hop = int(hop) # We throw away the information about the operness of the user, but we probably don't need to care about that # We also don't directly pass which modes they have, since that's already on the channel/user is_away = ("G" in status) modes = {Features["PREFIX"].get(s) for s in status} - {None} user = users._add(cli, nick=nick, ident=ident, host=host, realname=realname) # FIXME ch = None if not channels.predicate(chan): # returns True if it's not a channel ch = channels.add(chan, cli) if ch not in user.channels: user.channels[ch] = modes ch.users.add(user) for mode in modes: if mode not in ch.modes: ch.modes[mode] = set() ch.modes[mode].add(user) event = Event("who_result", {}, away=is_away, data=0, ip_address=None, server=server, hop_count=hop, idle_time=None, extended_who=False) event.dispatch(var, ch, user) if ch is channels.Main and not users.exists(nick): # FIXME users.add(nick, ident=ident, host=host, account="*", inchan=True, modes=modes, moded=set())
def extended_who_reply(cli, bot_server, bot_nick, data, chan, ident, ip_address, host, server, nick, status, hop, idle, account, realname): """Handle WHOX responses for servers that support it. An extended WHO (WHOX) is caracterised by a second parameter to the request That parameter must be '%' followed by at least one of 'tcuihsnfdlar' If the 't' specifier is present, the specifiers must be followed by a comma and at most 3 bytes This is the ordering if all parameters are present, but not all of them are required If a parameter depends on a specifier, it will be stated at the front If a specifier is not given, the parameter will be omitted in the reply Ordering and meaning of arguments for an extended WHO (WHOX) response: 0 - - The IRCClient instance (like everywhere else) 1 - - The server the requester (i.e. the bot) is on 2 - - The nickname of the requester (i.e. the bot) 3 - t - The data sent alongside the request 4 - c - The channel the request was made on 5 - u - The ident of the user in this reply 6 - i - The IP address of the user in this reply 7 - h - The hostname of the user in this reply 8 - s - The server the user in this reply is on 9 - n - The nickname of the user in this reply 10 - f - Status (H = Not away, G = Away, * = IRC operator, @ = Opped in the channel in 5, + = Voiced in the channel in 5) 11 - d - The hop count 12 - l - The idle time (or 0 for users on other servers) 13 - a - The services account name (or 0 if none/not logged in) 14 - r - The realname (gecos) This fires off the "who_result" event, and dispatches it with three arguments, the game state namespace, a Channel, and a User. Less important attributes can be accessed via the event.params namespace. """ if account == "0": account = None hop = int(hop) idle = int(idle) is_away = ("G" in status) data = int.from_bytes(data.encode(Features["CHARSET"]), "little") modes = {Features["PREFIX"].get(s) for s in status} - {None} user = users._add(cli, nick=nick, ident=ident, host=host, realname=realname, account=account) # FIXME ch = None if not channels.predicate(chan): ch = channels.add(chan, cli) if ch not in user.channels: user.channels[ch] = modes ch.users.add(user) for mode in modes: if mode not in ch.modes: ch.modes[mode] = set() ch.modes[mode].add(user) event = Event("who_result", {}, away=is_away, data=data, ip_address=ip_address, server=server, hop_count=hop, idle_time=idle, extended_who=True) event.dispatch(var, ch, user) if ch is channels.Main and not users.exists(nick): # FIXME users.add(nick, ident=ident, host=host, account=account, inchan=True, modes=modes, moded=set())