3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 09:19:23 +01:00

clientbot: overload _getUid() to deal with nick collisions between virtual clients and Clientbot users

Closes #327.

(cherry picked from commit 05e2d6d060)
This commit is contained in:
James Lu 2016-10-14 22:29:13 -07:00
parent eb64190228
commit 405b886ba2

View File

@ -283,6 +283,27 @@ class ClientbotWrapperProtocol(Protocol):
else: else:
return # Nothing changed return # Nothing changed
def _getUid(self, nick, ident='unknown', host='unknown.host'):
"""
Fetches the UID for the given nick, creating one if it does not already exist.
Limited (internal) nick collision checking is done here to prevent Clientbot users from
being confused with virtual clients, and vice versa."""
# If this sender isn't known or it is one of our virtual clients, spawn a new one.
# spawnClient() will take care of any nick collisions caused by new, Clientbot users
# taking the same nick as one of our virtual clients.
idsource = self.irc.nickToUid(nick)
is_internal = self.irc.isInternalClient(idsource)
if (not idsource) or (is_internal and self.irc.pseudoclient and idsource != self.irc.pseudoclient.uid):
if idsource:
log.debug('(%s) Nick-colliding virtual client %s/%s', self.irc.name, idsource, nick)
self.irc.callHooks([self.irc.sid, 'CLIENTBOT_NICKCOLLIDE', {'target': idsource, 'parse_as': 'SAVE'}])
idsource = self.spawnClient(nick, ident, host, server=self.irc.uplink, realname=FALLBACK_REALNAME).uid
return idsource
def handle_events(self, data): def handle_events(self, data):
"""Event handler for the RFC1459/2812 (clientbot) protocol.""" """Event handler for the RFC1459/2812 (clientbot) protocol."""
data = data.split(" ") data = data.split(" ")
@ -310,11 +331,7 @@ class ClientbotWrapperProtocol(Protocol):
else: else:
# Sender is a nick!user@host prefix. Split it into its relevant parts. # Sender is a nick!user@host prefix. Split it into its relevant parts.
nick, ident, host = utils.splitHostmask(sender) nick, ident, host = utils.splitHostmask(sender)
idsource = self.irc.nickToUid(nick) idsource = self._getUid(nick, ident, host)
if (not idsource) and self.irc.pseudoclient:
# We don't know the sender, so it most be new.
idsource = self.spawnClient(nick, ident, host, server=self.irc.uplink, realname=FALLBACK_REALNAME).uid
try: try:
func = getattr(self, 'handle_'+command.lower()) func = getattr(self, 'handle_'+command.lower())
@ -403,7 +420,7 @@ class ClientbotWrapperProtocol(Protocol):
# Get the PUID for the given nick. If one doesn't exist, spawn # Get the PUID for the given nick. If one doesn't exist, spawn
# a new virtual user. TODO: wait for WHO responses for each nick before # a new virtual user. TODO: wait for WHO responses for each nick before
# spawning in order to get a real ident/host. # spawning in order to get a real ident/host.
idsource = self.irc.nickToUid(nick) or self.spawnClient(nick, server=self.irc.uplink, realname=FALLBACK_REALNAME).uid idsource = self._getUid(nick)
# Queue these virtual users to be joined if they're not already in the channel, # Queue these virtual users to be joined if they're not already in the channel,
# or we're waiting for a kick acknowledgment for them. # or we're waiting for a kick acknowledgment for them.
@ -631,8 +648,9 @@ class ClientbotWrapperProtocol(Protocol):
if utils.isChannel(target): if utils.isChannel(target):
target = self.irc.toLower(target) target = self.irc.toLower(target)
else: else:
target = self._getUid(target) target = self.irc.nickToUid(target)
return {'target': target, 'text': args[1]} if target:
return {'target': target, 'text': args[1]}
def handle_quit(self, source, command, args): def handle_quit(self, source, command, args):
"""Handles incoming QUITs.""" """Handles incoming QUITs."""