From 3494d4f7948743cab82b1066d21252591a31c28f Mon Sep 17 00:00:00 2001 From: James Lu Date: Mon, 20 Jul 2015 18:05:42 -0700 Subject: [PATCH 1/2] inspircd: remove RSQUIT handler Events like this shouldn't be handled at the protocol level, ever. There's little point in adding this globally, since plugins should be able to choose what happens when they receive an SQUIT. --- protocols/inspircd.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 8823af7..9aedfcc 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -453,27 +453,6 @@ def handle_squit(irc, numeric, command, args): log.debug('(%s) Netsplit affected users: %s', irc.name, affected_users) return {'target': split_server, 'users': affected_users} -def handle_rsquit(irc, numeric, command, args): - # <- :1MLAAAAIG RSQUIT :ayy.lmao - # <- :1MLAAAAIG RSQUIT ayy.lmao :some reason - # RSQUIT is sent by opers to squit remote servers. - # Strangely, it takes a server name instead of a SID, and is - # allowed to be ignored entirely. - # If we receive a remote SQUIT, split the target server - # ONLY if the sender is identified with us. - target = args[0] - for (sid, server) in irc.servers.items(): - if server.name == target: - target = sid - if utils.isInternalServer(irc, target): - if irc.users[numeric].identified: - uplink = irc.servers[target].uplink - reason = 'Requested by %s' % irc.users[numeric].nick - _send(irc, uplink, 'SQUIT %s :%s' % (target, reason)) - return handle_squit(irc, numeric, 'SQUIT', [target, reason]) - else: - utils.msg(irc, numeric, 'Error: you are not authorized to split servers!', notice=True) - def handle_idle(irc, numeric, command, args): """Handle the IDLE command, sent between servers in remote WHOIS queries.""" # <- :70MAAAAAA IDLE 1MLAAAAIG From 72be5ca79cb56f4d3adc553a34598367ecedb94b Mon Sep 17 00:00:00 2001 From: James Lu Date: Mon, 20 Jul 2015 19:52:52 -0700 Subject: [PATCH 2/2] inspircd: make handle_part return a list of channels, not just one Some IRCds, like TS6, allow sending multiple channels (as a comma-separated list) in PART. Update relay accordingly. --- plugins/relay.py | 17 +++++++++-------- protocols/inspircd.py | 25 +++++++++++++------------ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/plugins/relay.py b/plugins/relay.py index a06c462..7fbfb84 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -258,15 +258,16 @@ def handle_nick(irc, numeric, command, args): utils.add_hook(handle_nick, 'NICK') def handle_part(irc, numeric, command, args): - channel = args['channel'] + channels = args['channels'] text = args['text'] - for netname, user in relayusers[(irc.name, numeric)].copy().items(): - remoteirc = utils.networkobjects[netname] - remotechan = findRemoteChan(irc, remoteirc, channel) - remoteirc.proto.partClient(remoteirc, user, remotechan, text) - if not remoteirc.users[user].channels: - remoteirc.proto.quitClient(remoteirc, user, 'Left all shared channels.') - del relayusers[(irc.name, numeric)][remoteirc.name] + for channel in channels: + for netname, user in relayusers[(irc.name, numeric)].copy().items(): + remoteirc = utils.networkobjects[netname] + remotechan = findRemoteChan(irc, remoteirc, channel) + remoteirc.proto.partClient(remoteirc, user, remotechan, text) + if not remoteirc.users[user].channels: + remoteirc.proto.quitClient(remoteirc, user, 'Left all shared channels.') + del relayusers[(irc.name, numeric)][remoteirc.name] utils.add_hook(handle_part, 'PART') def handle_privmsg(irc, numeric, command, args): diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 9aedfcc..f21c559 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -329,18 +329,19 @@ def handle_kick(irc, source, command, args): return {'channel': channel, 'target': kicked, 'text': args[2]} def handle_part(irc, source, command, args): - channel = args[0].lower() - # We should only get PART commands for channels that exist, right?? - irc.channels[channel].removeuser(source) - try: - irc.users[source].channels.discard(channel) - except KeyError: - log.debug("(%s) handle_part: KeyError trying to remove %r from %r's channel list?", irc.name, channel, source) - try: - reason = args[1] - except IndexError: - reason = '' - return {'channel': channel, 'text': reason} + channels = args[0].lower().split(',') + for channel in channels: + # We should only get PART commands for channels that exist, right?? + irc.channels[channel].removeuser(source) + try: + irc.users[source].channels.discard(channel) + except KeyError: + log.debug("(%s) handle_part: KeyError trying to remove %r from %r's channel list?", irc.name, channel, source) + try: + reason = args[1] + except IndexError: + reason = '' + return {'channels': channels, 'text': reason} def handle_error(irc, numeric, command, args): irc.connected = False