From e354ada838e86cf46f1a90ab83c561888ebac82d Mon Sep 17 00:00:00 2001 From: James Lu Date: Sat, 25 Jul 2015 18:20:49 -0700 Subject: [PATCH] relay: fix nick collision loop on SAVE + when both tagged UID and untagged UID exist on one net This fixes a clash when for example: both 42XAAAAAA and _42XAAAAAA exist on a network, and PyLink tries to relay both nicks as _42XAAAAAA/network. Also, this adds an oldnick argument to the SAVE protocol handler, which is then used by relay.normalizeNick to check whether the original pre-SAVE nick is also in use, in the event of nick collisions. --- plugins/relay.py | 7 ++++--- protocols/inspircd.py | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/relay.py b/plugins/relay.py index 5928424..c101987 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -25,7 +25,7 @@ def relayWhoisHandlers(irc, target): remotenick)] utils.whois_handlers.append(relayWhoisHandlers) -def normalizeNick(irc, netname, nick, separator=None): +def normalizeNick(irc, netname, nick, separator=None, oldnick=''): # Block until we know the IRC network's nick length (after capabilities # are sent) log.debug('(%s) normalizeNick: waiting for irc.connected', irc.name) @@ -59,7 +59,8 @@ def normalizeNick(irc, netname, nick, separator=None): nick = nick[:allowedlength] nick += suffix # FIXME: factorize - while utils.nickToUid(irc, nick) and not utils.isInternalClient(irc, utils.nickToUid(irc, nick)): + while utils.nickToUid(irc, nick) or utils.nickToUid(irc, oldnick) and not \ + utils.isInternalClient(irc, utils.nickToUid(irc, nick)): # The nick we want exists? Darn, create another one then, but only if # the target isn't an internal client! # Increase the separator length by 1 if the user was already tagged, @@ -901,7 +902,7 @@ def handle_save(irc, numeric, command, args): remotenet, remoteuser = realuser remoteirc = utils.networkobjects[remotenet] nick = remoteirc.users[remoteuser].nick - newnick = normalizeNick(irc, remotenet, nick) + newnick = normalizeNick(irc, remotenet, nick, oldnick=args['oldnick']) irc.proto.nickClient(irc, target, newnick) else: # Somebody else on the network (not a PyLink client) had a nick collision; diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 4984c1a..05f4f81 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -423,8 +423,9 @@ def handle_save(irc, numeric, command, args): # -> :0AL000001 NICK Derp_ 1433728673 # <- :70M SAVE 0AL000001 1433728673 user = args[0] + oldnick = irc.users[user].nick irc.users[user].nick = user - return {'target': user, 'ts': int(args[1])} + return {'target': user, 'ts': int(args[1]), 'oldnick': oldnick} def handle_fmode(irc, numeric, command, args): # <- :70MAAAAAA FMODE #chat 1433653462 +hhT 70MAAAAAA 70MAAAAAD