From cad55097f14d44a71911ffcb57e5aa140c81b77d Mon Sep 17 00:00:00 2001 From: James Lu Date: Wed, 30 Aug 2017 19:29:26 -0700 Subject: [PATCH] core: reuse existing service client UIDs for all service bots This prevents nick collision wars caused by spawn_service when an ENDBURST hook for the uplink is received multiple times. --- classes.py | 20 ++++++++++---------- coremods/service_support.py | 9 +++++---- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/classes.py b/classes.py index f6cd3f7..f98697f 100644 --- a/classes.py +++ b/classes.py @@ -468,16 +468,13 @@ class PyLinkNetworkCore(structures.DeprecatedAttributesObject, structures.CamelC if not userobj: return False - # Look for the "service" attribute in the User object, if one exists. - try: - sname = userobj.service - # Warn if the service name we fetched isn't a registered service. - if sname not in world.services.keys(): - log.warning("(%s) User %s / %s had a service bot record to a service that doesn't " - "exist (%s)!", self.name, uid, userobj.nick, sname) - return world.services.get(sname) - except AttributeError: - return False + # Look for the "service" attribute in the User object,sname = userobj.service + # Warn if the service name we fetched isn't a registered service. + sname = userobj.service + if sname not in world.services.keys(): + log.warning("(%s) User %s / %s had a service bot record to a service that doesn't " + "exist (%s)!", self.name, uid, userobj.nick, sname) + return world.services.get(sname) structures._BLACKLISTED_COPY_TYPES.append(PyLinkNetworkCore) @@ -1596,6 +1593,9 @@ class User(): # Cloaked host for IRCds that use it self.cloaked_host = None + # Stores service bot name if applicable + self.service = None + def __repr__(self): return 'User(%s/%s)' % (self.uid, self.nick) IrcUser = User diff --git a/coremods/service_support.py b/coremods/service_support.py index 9b8b2bf..9031520 100644 --- a/coremods/service_support.py +++ b/coremods/service_support.py @@ -22,10 +22,11 @@ def spawn_service(irc, source, command, args): # Get the ServiceBot object. sbot = world.services[name] - if name == 'pylink' and irc.pseudoclient: - # irc.pseudoclient already exists, for protocols like clientbot - log.debug('(%s) spawn_service: Using existing nick %r for service %r', irc.name, irc.pseudoclient.nick, name) - userobj = irc.pseudoclient + old_userobj = irc.users.get(sbot.uids.get(irc.name)) + if old_userobj and old_userobj.service: + # A client already exists, so reuse it. + log.debug('(%s) spawn_service: Using existing nick %r for service %r', irc.name, old_userobj.nick, name) + userobj = old_userobj userobj.opertype = "PyLink Service" userobj.manipulatable = sbot.manipulatable else: