NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

eveMachoNet.py (31487B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\common\script\net\eveMachoNet.py
      2 import sys
      3 from collections import defaultdict
      4 from itertools import ifilter
      5 import carbon.common.script.net.machoNet as macho
      6 import log
      7 from carbon.common.script.net.machoNet import MachoNetService
      8 from carbon.common.script.sys import basesession
      9 from carbon.common.script.sys.serviceConst import ROLEMASK_ELEVATEDPLAYER
     10 from cluster import SERVICE_BEYONCE, SERVICE_CHATX, SERVICE_STATION, SERVICE_PLANETMGR, SERVICE_POLARIS
     11 from eve.common.lib import appConst as const
     12 from eve.common.script.sys.idCheckers import IsKnownSpaceSystem
     13 from eveexceptions import ExceptionEater
     14 from eveprefs import prefs, boot
     15 from stringutil import strx
     16 
     17 class EveMachoNetService(macho.MachoNetService):
     18     __guid__ = 'svc.eveMachoNet'
     19     __replaceservice__ = 'machoNet'
     20     __startupdependencies__ = MachoNetService.__startupdependencies__
     21     if boot.role in ('server', 'proxy'):
     22         __startupdependencies__.extend(['eventLog'])
     23     __gpcsmethodnames__ = {'Broadcast',
     24      'ClusterBroadcast',
     25      'ConnectToAllNeighboringServices',
     26      'ConnectToAllServices',
     27      'ConnectToAllSiblingServices',
     28      'ConnectToRemoteService',
     29      'NarrowcastByAllianceIDs',
     30      'NarrowcastByCharIDs',
     31      'NarrowcastByClientIDs',
     32      'NarrowcastByClientIDsWithoutTheStars',
     33      'NarrowcastByCorporationIDs',
     34      'NarrowcastByFleetIDs',
     35      'NarrowcastByNodeIDs',
     36      'NarrowcastByShipIDs',
     37      'NarrowcastBySolarSystemID2s',
     38      'NarrowcastBySolarSystemIDs',
     39      'NarrowcastByStationIDs',
     40      'NarrowcastByStructureIDs',
     41      'NarrowcastByUserIDs',
     42      'SinglecastByServiceMask',
     43      'NodeBroadcast',
     44      'Objectcast',
     45      'ObjectcastWithoutTheStars',
     46      'OnObjectPublicAttributesUpdated',
     47      'ProxyBroadcast',
     48      'Queuedcast',
     49      'QueuedcastWithoutTheStars',
     50      'ReliableSinglecastByCharID',
     51      'ReliableSinglecastByUserID',
     52      'RemoteServiceCall',
     53      'RemoteServiceCallWithoutTheStars',
     54      'RemoteServiceNotify',
     55      'RemoteServiceNotifyWithoutTheStars',
     56      'ResetAutoResolveCache',
     57      'Scattercast',
     58      'ScattercastWithoutTheStars',
     59      'ServerBroadcast',
     60      'SinglecastByAllianceID',
     61      'SinglecastByRegionID',
     62      'SinglecastByCharID',
     63      'SinglecastByClientID',
     64      'SinglecastByCorporationID',
     65      'SinglecastByFleetID',
     66      'SinglecastByNodeID',
     67      'SinglecastByShipID',
     68      'SinglecastBySolarSystemID',
     69      'SinglecastBySolarSystemID2',
     70      'SinglecastByStationID',
     71      'SinglecastByStructureID',
     72      'SinglecastByUserID'}
     73     __server_scattercast_session_variables__ = {'userid',
     74      'charid',
     75      'shipid',
     76      'objectID',
     77      'fleetid',
     78      'wingid',
     79      'squadid'}
     80     __notifyevents__ = MachoNetService.__notifyevents__
     81     __notifyevents__.add('OnGlobalConfigChanged')
     82     MachoNetService.metricsMap.update({'EVE:Online': const.zmetricCounter_EVEOnline,
     83      'EVE:Trial': const.zmetricCounter_EVETrial})
     84 
     85     def __init__(self):
     86         MachoNetService.__init__(self)
     87         self.logAllClientCalls = prefs.GetValue('logAllClientCalls', None)
     88         self.clientCallLogChannel = log.Channel(str(macho.mode), 'ClientCalls')
     89         self.sessionWatchIDs = None
     90         try:
     91             self.sessionWatchIDs = ({int(s) for s in strx(prefs.GetValue('sessionWatch_userID', '')).split(',') if s},
     92              {int(s) for s in strx(prefs.GetValue('sessionWatch_charID', '')).split(',') if s},
     93              {int(s) for s in strx(prefs.GetValue('sessionWatch_corpID', '')).split(',') if s},
     94              {int(s) for s in strx(prefs.GetValue('sessionWatch_userType', '')).split(',') if s})
     95             if len(self.sessionWatchIDs[0]) == 0 and len(self.sessionWatchIDs[1]) == 0 and len(self.sessionWatchIDs[2]) == 0 and len(self.sessionWatchIDs[3]) == 0:
     96                 self.sessionWatchIDs = None
     97         except:
     98             log.LogException()
     99             sys.exc_clear()
    100 
    101         self.clusterSolarsystemStatistics = ({}, {}, 0)
    102         self.clusterSolarsystemStatisticsForClient = ({}, {}, 0)
    103 
    104     def Run(self, memStream = None):
    105         super(EveMachoNetService, self).Run(memStream)
    106         if macho.mode == 'server' and self.connectToCluster:
    107             self.dbzuser = self.DB2.GetSchema('zuser')
    108         if macho.mode in ('server', 'proxy') and prefs.GetValue('seclogEnabled', False):
    109             self.eventLog.SetupChannel('security', {'persistInterval': 1000,
    110              'logPath': prefs.GetValue('seclogPath', 'c:\\seclog'),
    111              'maxEvents': 10000000,
    112              'maxEventLength': 100000,
    113              'delimeter': '\\t',
    114              'logFileNameFormat': 'seclog_%(dateTime)s_%(nodeID)s.txt',
    115              'logFileCycleMinutes': 5})
    116 
    117     def GetClusterGameStatistics(self, key, default):
    118         if key == 'EVE':
    119             return self.clusterSolarsystemStatistics
    120         else:
    121             return default
    122 
    123     def GetClusterGameStatisticsForClient(self, key, default):
    124         if key == 'EVE':
    125             return self.clusterSolarsystemStatisticsForClient
    126         else:
    127             return default
    128 
    129     def SetClusterSessionCounts(self, clusterSessionStatistics):
    130         if clusterSessionStatistics is not None:
    131             self._AddToSessionCounter(clusterSessionStatistics)
    132             if len(self.clusterSessionStatsHistory) == self.proxyStatSmoothie:
    133                 oldestStatistics = self.clusterSessionStatsHistory[0][1]
    134                 self._RemoveFromSessionCounter(oldestStatistics)
    135             numSamples = min(self.proxyStatSmoothie, len(self.clusterSessionStatsHistory) + 1)
    136             sol, station, c = self.clusterSolarsystemStatistics
    137             self.clusterSolarsystemStatistics = (sol, station, numSamples)
    138             self.SetClientSafeStatistics(sol, station, numSamples)
    139         MachoNetService.SetClusterSessionCounts(self, clusterSessionStatistics)
    140 
    141     def SetClientSafeStatistics(self, sol, station, numSamples):
    142         newSol = {}
    143         newStation = {}
    144         for counterDictionary, newDictionary in ((sol, newSol), (station, newStation)):
    145             for eachSolarsystemShortID, value in counterDictionary.iteritems():
    146                 solarSystemID = eachSolarsystemShortID + 30000000
    147                 if IsKnownSpaceSystem(solarSystemID):
    148                     newDictionary[eachSolarsystemShortID] = value
    149 
    150         self.clusterSolarsystemStatisticsForClient = (newSol, newStation, numSamples)
    151 
    152     def _AddToSessionCounter(self, statisticsToUse):
    153         self._AddOrRemoveFromCounter(statisticsToUse, modifier=1)
    154 
    155     def _RemoveFromSessionCounter(self, statisticsToUse):
    156         self._AddOrRemoveFromCounter(statisticsToUse, modifier=-1)
    157 
    158     def _AddOrRemoveFromCounter(self, statisticsToUse, modifier):
    159         sol, station, c = self.clusterSolarsystemStatistics
    160         if 'solarsystemid2' in statisticsToUse:
    161             solarsystemidCounts = self._GetSessionVariableCountsBySolarSystem(statisticsToUse, 'solarsystemid')
    162             dockedInStructuresBySolarSystemID = self.GetDockedInStructuresBySolarSystemID(statisticsToUse)
    163             for solarsystemid, solarsystemid2Count in self._GetSessionVariableCountsBySolarSystem(statisticsToUse, 'solarsystemid2').iteritems():
    164                 solID = solarsystemid - 30000000
    165                 sol[solID] = sol.get(solID, 0) + modifier * solarsystemid2Count
    166                 numInSpaceOrStructure = solarsystemidCounts.get(solarsystemid, 0)
    167                 numInSpace = numInSpaceOrStructure - dockedInStructuresBySolarSystemID.get(solarsystemid, 0)
    168                 stationCount = solarsystemid2Count - numInSpace
    169                 if stationCount > 0:
    170                     station[solID] = station.get(solID, 0) + modifier * stationCount
    171 
    172     def GetDockedInStructuresBySolarSystemID(self, clusterSessionStatistics):
    173         structureidCounts = self._GetSessionVariableCountsBySolarSystem(clusterSessionStatistics, 'structureid')
    174         dockedInStructuresBySolarSystemID = defaultdict(int)
    175         for eachStructureID, count in structureidCounts.iteritems():
    176             try:
    177                 structureLocation = cfg.evelocations.Get(eachStructureID)
    178                 dockedInStructuresBySolarSystemID[structureLocation.solarSystemID] += count
    179             except KeyError:
    180                 pass
    181 
    182         return dockedInStructuresBySolarSystemID
    183 
    184     def _GetSessionVariableCountsBySolarSystem(self, statisticsToUse, sessionVariable):
    185         if sessionVariable in statisticsToUse:
    186             return statisticsToUse[sessionVariable][1]
    187         else:
    188             return {}
    189 
    190     def _StoreMetricsToDB(self, metrics):
    191         try:
    192             MachoNetService._StoreMetricsToDB(self, metrics)
    193             onlineCount = metrics['EVE:Online'][0] if 'EVE:Online' in metrics else 0
    194             trialCount = metrics['EVE:Trial'][0] if 'EVE:Trial' in metrics else 0
    195             onlineCount2 = 0
    196             trialCount2 = 0
    197             self.dbzuser.OnlineCounts_Insert(onlineCount, trialCount, onlineCount2, trialCount2)
    198         except Exception:
    199             log.LogException()
    200             sys.exc_clear()
    201         except:
    202             log.LogException()
    203             raise
    204 
    205     def _GetNodeFromAddressFromDB(self, myNodeID, serviceMapping, address, suggestedNodeID, expectedLoadValue, serviceMask):
    206         if serviceMapping == SERVICE_BEYONCE and (address < const.minSolarSystem or address > const.maxSolarSystem):
    207             raise RuntimeError('Address is not a solar system (%s)' % address)
    208         return MachoNetService._GetNodeFromAddressFromDB(self, myNodeID, serviceMapping, address, suggestedNodeID, expectedLoadValue, serviceMask)
    209 
    210     def GuessNodeIDFromAddress(self, serviceName, address):
    211         return
    212         alternatives = []
    213         if serviceName in ('aggressionMgr', 'director', 'entity'):
    214             alternatives = [('beyonce', address)]
    215             for each in ('aggressionMgr', 'director', 'entity'):
    216                 alternatives.append((each, address))
    217 
    218         elif serviceName == 'brokerMgr':
    219             alternatives = [('station', address)]
    220         elif serviceName in ('i2', 'dogmaIM', 'invbroker', 'ship'):
    221             if address[1] == const.groupSolarSystem:
    222                 alternatives = [('beyonce', address[0])]
    223             elif address[1] == const.groupStation:
    224                 alternatives = [('station', address[0])]
    225             for each in ('i2', 'dogmaIM', 'invbroker', 'ship'):
    226                 alternatives.append((each, address))
    227 
    228         elif serviceName in ('corpStationMgr', 'factory', 'broker'):
    229             alternatives = [('station', address)]
    230         elif serviceName == 'tradeMgr':
    231             alternatives = [('station', address[0])]
    232         elif serviceName == 'station' and macho.mode == 'server':
    233             try:
    234                 key = ('beyonce', sm.services['stationSvc'].GetStation(address, prime=0).solarSystemID)
    235                 if key[1]:
    236                     alternatives.append(key)
    237             except Exception:
    238                 log.LogException('Could not locate the station you asked for without blocking')
    239                 sys.exc_clear()
    240 
    241         for alt_service, alt_address in alternatives:
    242             nodeID = self._addressCache.GetByServiceAddress(alt_service, alt_address)
    243             if nodeID is not None:
    244                 self._addressCache.SetServiceAddress(serviceName, address, nodeID)
    245                 return nodeID
    246 
    247     def _GetNodeFromAddressAdjustments(self, service, address):
    248         if macho.mode == 'server' and service == SERVICE_STATION:
    249             if address == const.doomheimStationID:
    250                 log.LogWarn('Getting node address for Doomheim station [%s].' % const.doomheimStationID)
    251                 stationAddress = const.eveUniverseLocationID
    252             else:
    253                 try:
    254                     stationAddress = sm.StartService('stationSvc').GetStation(address).solarSystemID
    255                 except Exception:
    256                     log.LogException()
    257                     raise RuntimeError('The station you asked for does not reside in any known solar system')
    258 
    259             key = (SERVICE_BEYONCE, stationAddress)
    260             service, address = key
    261         suggestedNodeID = None
    262         if service in ('beyonce', SERVICE_BEYONCE) and int(address) == 30000380:
    263             suggestedNodeID = self.GetNodeFromAddress(SERVICE_POLARIS, 0)
    264         if service in ('planetMgr', SERVICE_PLANETMGR):
    265             address = address % const.PLANETARYMGR_MOD
    266         return (suggestedNodeID, service, address)
    267 
    268     def _GetTransportIDsFromBroadcastAddress(self, address):
    269         if address.idtype is None:
    270             idtype = None
    271             scattered = 0
    272         elif address.idtype[0] in ('*', '+'):
    273             idtype = address.idtype[1:]
    274             scattered = 1
    275         else:
    276             idtype = address.idtype
    277             scattered = 0
    278         if len(address.narrowcast):
    279             clientIDs = []
    280             nodeIDs = []
    281             done = 0
    282             if idtype == 'clientID':
    283                 if macho.mode == 'server' and len(address.narrowcast) >= 2 * len(self.transportIDbyProxyNodeID):
    284                     nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    285                 else:
    286                     clientIDs = address.narrowcast
    287                 done = 1
    288             elif idtype == 'nodeID':
    289                 nodeIDs = address.narrowcast
    290                 done = 1
    291             elif idtype == 'serviceMask':
    292                 nodeIDs = self.ResolveServiceMaskToNodeIDs(address.narrowcast[0])
    293                 done = 1
    294             elif macho.mode == 'server':
    295                 if idtype in self.__server_scattercast_session_variables__:
    296                     if scattered:
    297                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    298                         done = 1
    299                 elif len(address.narrowcast) == 1:
    300                     if idtype == 'stationid':
    301                         nodeID = self.CheckAddressCache(SERVICE_STATION, address.narrowcast[0], lazyGetIfNotFound=True)
    302                         if self.GetNodeID() == nodeID:
    303                             if scattered:
    304                                 self.LogInfo('Scattercasting by stationID on the right node.  Ignored.')
    305                         else:
    306                             self.LogWarn('Sending a packet by stationid on the wrong node.  Resorting to a scattercast.')
    307                             self.LogWarn('nodeID: ', nodeID, ', my nodeID: ', self.GetNodeID(), ', stationID: ', address.narrowcast[0])
    308                             nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    309                             done = 1
    310                     elif idtype in ('solarsystemid', 'solarsystemid2'):
    311                         nodeID = self.CheckAddressCache(SERVICE_BEYONCE, address.narrowcast[0], lazyGetIfNotFound=True)
    312                         if self.GetNodeID() == nodeID:
    313                             if scattered:
    314                                 self.LogInfo('Scattercasting by solarsystemid on the right node.  Ignored.')
    315                         else:
    316                             self.LogWarn('Sending a packet by solarsystemid on the wrong node.  Resorting to a scattercast.')
    317                             self.LogWarn('nodeID: ', nodeID, ', my nodeID: ', self.GetNodeID(), ', solarsystemid(2): ', address.narrowcast[0])
    318                             nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    319                             done = 1
    320                     elif idtype == 'corpid':
    321                         nodeID = self.CheckAddressCache(SERVICE_CHATX, address.narrowcast[0] % 200, lazyGetIfNotFound=True)
    322                         if self.GetNodeID() == nodeID:
    323                             if scattered:
    324                                 self.LogInfo('Scattercasting by corpid on the right node.  Ignored.')
    325                         else:
    326                             self.LogWarn('Sending a packet by corpid on the wrong node.  Resorting to a scattercast.')
    327                             self.LogWarn('nodeID: ', nodeID, ', my nodeID: ', self.GetNodeID(), ', corpID: ', address.narrowcast[0])
    328                             nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    329                             done = 1
    330                     elif idtype == 'allianceid':
    331                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    332                         done = 1
    333                     elif idtype == 'regionid':
    334                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    335                         done = 1
    336                     elif idtype == 'structureid':
    337                         try:
    338                             solarSystemID = cfg.evelocations.Get(address.narrowcast[0]).solarSystemID
    339                         except AttributeError:
    340                             solarSystemID = sm.GetService('structureDirectory').GetStructureInfo_(address.narrowcast[0]).solarSystemID
    341 
    342                         nodeID = self.CheckAddressCache(SERVICE_BEYONCE, solarSystemID, lazyGetIfNotFound=True)
    343                         if self.GetNodeID() == nodeID:
    344                             if scattered:
    345                                 self.LogInfo('Scattercasting by solarsystemid on the right node.  Ignored.')
    346                         else:
    347                             self.LogWarn('Sending a packet by structureid on the wrong node.  Resorting to a scattercast.')
    348                             self.LogWarn('nodeID: ', nodeID, ', my nodeID: ', self.GetNodeID(), ', structureid: ', address.narrowcast[0], 'solarSystemID: ', solarSystemID)
    349                             nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    350                             done = 1
    351                     else:
    352                         self.LogWarn('Sending a packet by some funky address type (', idtype, ').  Resorting to scattercast')
    353                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    354                         done = 1
    355                 elif idtype == 'corpid&corprole' and len(address.narrowcast[0]) == 1:
    356                     nodeID = self.CheckAddressCache(SERVICE_CHATX, address.narrowcast[0][0] % 200, lazyGetIfNotFound=True)
    357                     if self.GetNodeID() == nodeID:
    358                         if scattered:
    359                             self.LogInfo('Scattercasting by corpid&corprole on the right node.  Ignored.')
    360                     else:
    361                         self.LogWarn('Sending a packet by corpid&corprole on the wrong node.  Resorting to a scattercast.')
    362                         self.LogWarn('nodeID: ', nodeID, ', my nodeID: ', self.GetNodeID(), ', corpID: ', address.narrowcast[0][0])
    363                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    364                         done = 1
    365                 elif idtype in ('stationid&corpid&corprole', 'stationid&corpid') and len(address.narrowcast[0]) == 1 and len(address.narrowcast[1]) == 1:
    366                     stationNodeID = self.CheckAddressCache(SERVICE_STATION, address.narrowcast[0][0], lazyGetIfNotFound=True)
    367                     corpNodeID = self.CheckAddressCache(SERVICE_CHATX, address.narrowcast[1][0] % 200, lazyGetIfNotFound=True)
    368                     if self.GetNodeID() in (stationNodeID, corpNodeID):
    369                         if scattered:
    370                             self.LogInfo('Scattercasting by stationid&corpid&corprole on the station node or corp node.  Ignored.')
    371                     else:
    372                         self.LogWarn('Sending a packet by stationid&corpid&corprole on the wrong node.  Resorting to a scattercast.')
    373                         self.LogWarn('corpNodeID: ', corpNodeID, ', stationNodeID: ', stationNodeID, ', my nodeID: ', self.GetNodeID(), ', corpID: ', address.narrowcast[1][0], ', stationID: ', address.narrowcast[0][0])
    374                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    375                         done = 1
    376                 elif idtype == 'corpid&corprole&solarsystemid' and len(address.narrowcast[0]) == 1 and len(address.narrowcast[2]) == 1:
    377                     solNodeID = self.CheckAddressCache(SERVICE_BEYONCE, address.narrowcast[2][0], lazyGetIfNotFound=True)
    378                     corpNodeID = self.CheckAddressCache(SERVICE_CHATX, address.narrowcast[0][0] % 200, lazyGetIfNotFound=True)
    379                     if self.GetNodeID() in (solNodeID, corpNodeID):
    380                         if scattered:
    381                             self.LogInfo('Scattercasting by corpid&corprole&solarsystemid on the solarsystem node or corp node.  Ignored.')
    382                     else:
    383                         self.LogWarn('Sending a packet by corpid&corprole&solarsystemid on the wrong node.  Resorting to a scattercast.')
    384                         self.LogWarn('corpNodeID: ', corpNodeID, ', solNodeID: ', solNodeID, ', my nodeID: ', self.GetNodeID(), ', corpID: ', address.narrowcast[0][0], ', solarsystemID: ', address.narrowcast[2][0])
    385                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    386                         done = 1
    387                 elif idtype in ('corpid&solarsystemid', 'solarsystemid&corpid') and len(address.narrowcast[0]) == 1 and len(address.narrowcast[1]) == 1:
    388                     if idtype == 'solarsystemid&corpid':
    389                         idxSol = 0
    390                         idxCorp = 1
    391                     else:
    392                         idxSol = 1
    393                         idxCorp = 0
    394                     solNodeID = self.CheckAddressCache(SERVICE_BEYONCE, address.narrowcast[idxSol][0], lazyGetIfNotFound=True)
    395                     corpNodeID = self.CheckAddressCache(SERVICE_CHATX, address.narrowcast[idxCorp][0] % 200, lazyGetIfNotFound=True)
    396                     if self.GetNodeID() in (solNodeID, corpNodeID):
    397                         if scattered:
    398                             self.LogInfo('Scattercasting by corpid&corprole&solarsystemid on the solarsystem node or corp node.  Ignored.')
    399                     else:
    400                         self.LogWarn('Sending a packet by corpid&corprole&solarsystemid on the wrong node.  Resorting to a scattercast.')
    401                         self.LogWarn('corpNodeID: ', corpNodeID, ', solNodeID: ', solNodeID, ', my nodeID: ', self.GetNodeID(), ', corpID: ', address.narrowcast[idxCorp][0], ', solarsystemID: ', address.narrowcast[idxSol][0])
    402                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    403                         done = 1
    404                 elif idtype == 'allianceid&corprole':
    405                     nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    406                     done = 1
    407                 else:
    408                     if not scattered:
    409                         self.LogWarn('Sending a packet via a non-scattered complex address that resorts to a scattercast.  address: ', address)
    410                     else:
    411                         self.LogInfo('Sending a packet via a scattered complex address.  address: ', address)
    412                     nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    413                     done = 1
    414             if not done:
    415                 notfound = []
    416                 if len(address.narrowcast) == 1 and (idtype, address.narrowcast[0]) in self.spam:
    417                     spam = 1
    418                 elif macho.mode == 'server':
    419                     if self.transportIDbyProxyNodeID:
    420                         spam, clientIDs, notfound = basesession.FindClientsAndHoles(idtype, address.narrowcast, len(self.transportIDbyProxyNodeID) * 2)
    421                     else:
    422                         spam, clientIDs, notfound = basesession.FindClientsAndHoles(idtype, address.narrowcast, 20)
    423                 else:
    424                     spam, clientIDs, notfound = basesession.FindClientsAndHoles(idtype, address.narrowcast, None)
    425                 if len(address.narrowcast) == 1 and spam:
    426                     self.LogInfo('Interpreting ', address.narrowcast, ' as a persistant spam address.')
    427                     if len(self.spam) > 1000:
    428                         self.spam.clear()
    429                     self.spam.add((idtype, address.narrowcast[0]))
    430                 if spam or macho.mode == 'server' and address.idtype[0] == '*' and len(notfound):
    431                     clientIDs = []
    432                     if macho.mode == 'server':
    433                         nodeIDs = self.transportIDbyProxyNodeID.iterkeys()
    434                     else:
    435                         nodeIDs = self.transportIDbySolNodeID.iterkeys()
    436             transportIDs = set()
    437             if macho.mode == 'server' and self.transportIDbyProxyNodeID:
    438                 for clientID in ifilter(None, clientIDs):
    439                     try:
    440                         nodeID = self.GetProxyNodeIDFromClientID(clientID)
    441                     except Exception as e:
    442                         self.LogWarn('Unable to map clientID', repr(clientID), 'to proxyID. Dropping message Exception type=', type(e), ' args=', e.args)
    443                         continue
    444 
    445                     if nodeID in self.transportIDbyProxyNodeID:
    446                         transportIDs.add(self.transportIDbyProxyNodeID[nodeID])
    447                         if len(transportIDs) == len(self.transportIDbyProxyNodeID):
    448                             if len(transportIDs) > 2:
    449                                 self.LogInfo('All proxies targeted in a clientID based routing decision. If this happens frequently, the caller might consider a better casting method.', address)
    450                             break
    451 
    452             else:
    453                 for each in clientIDs:
    454                     if each in self.transportIDbyClientID and self.transportIDbyClientID[each] in self.transportsByID:
    455                         transportIDs.add(self.transportIDbyClientID[each])
    456                     else:
    457                         self.LogInfo('Transport for client ', each, ' not found while sending narrowcast.')
    458 
    459             for nodeId in nodeIDs:
    460                 if macho.mode == 'server' and nodeId in self.transportIDbyProxyNodeID and self.transportIDbyProxyNodeID[nodeId] in self.transportsByID:
    461                     transportIDs.add(self.transportIDbyProxyNodeID[nodeId])
    462                 elif macho.mode == 'proxy' and nodeId in self.transportIDbySolNodeID and self.transportIDbySolNodeID[nodeId] in self.transportsByID:
    463                     transportIDs.add(self.transportIDbySolNodeID[nodeId])
    464                 elif nodeId in self.transportIDbyAppNodeID and self.transportIDbyAppNodeID[nodeId] in self.transportsByID:
    465                     transportIDs.add(self.transportIDbyAppNodeID[nodeId])
    466                 elif nodeId in self.transportIDbySolNodeID and self.transportIDbySolNodeID[nodeId] in self.transportsByID:
    467                     transportIDs.add(self.transportIDbySolNodeID[nodeId])
    468                 else:
    469                     self.LogInfo('Transport for node ', nodeId, ' not found while sending narrowcast.')
    470 
    471             transportIDs = list(transportIDs)
    472         elif idtype == 'nodeID':
    473             if address.idtype[0] == '+':
    474                 transportIDs = self.transportIDbyProxyNodeID.values()
    475             else:
    476                 transportIDs = self.transportIDbySolNodeID.values()
    477         elif macho.mode == 'server':
    478             transportIDs = self.transportsByID.keys()
    479         else:
    480             transportIDs = self.transportIDbyClientID.values()
    481         if transportIDs:
    482             self.broadcastsResolved.Add(len(transportIDs))
    483         else:
    484             self.broadcastsMissed.Add()
    485         return transportIDs
    486 
    487     def OnGlobalConfigChanged(self, config):
    488         if 'oldShutdown' in config:
    489             val = int(config['oldShutdown'])
    490             self.LogNotice('Setting oldShutdown to', val)
    491             prefs.SetValue('oldShutdown', val)
    492         settings = {}
    493         if 'stacklessioVersion' in config:
    494             settings['version'] = int(config['stacklessioVersion'])
    495         if 'stacklessioUseNoblock' in config:
    496             settings['useNoblock'] = bool(config['stacklessioUseNoblock'])
    497         if 'stacklessioAllocChunkSize' in config:
    498             settings['allocChunkSize'] = int(config['stacklessioAllocChunkSize'])
    499         if settings:
    500             import stacklessio._socket
    501             stacklessio._socket.apply_settings(settings)
    502             self.LogNotice('Applied stacklessio settings for client: ', repr(settings))
    503 
    504     def LogClientCall(self, session, objectName, method, args, kwargs):
    505         with ExceptionEater('LogClientCall'):
    506 
    507             def CleanKeywordArgs(kwargs):
    508                 if not kwargs or 'machoVersion' not in kwargs:
    509                     return kwargs
    510                 cleanKwargs = kwargs.copy()
    511                 del cleanKwargs['machoVersion']
    512                 return cleanKwargs
    513 
    514             excludedMethods = ['GetTime']
    515             if method in excludedMethods:
    516                 return
    517             charID = getattr(session, 'charid', None)
    518             userID = getattr(session, 'userid', None)
    519             solarSystemID = getattr(session, 'solarsystemid2', None)
    520             argString = None
    521             if self.eventLog.IsChannelOpen('security'):
    522                 argString = repr(args)
    523                 kwargString = repr(CleanKeywordArgs(kwargs))
    524                 self.eventLog.LogOwnerEvent('ClientCall', charID, solarSystemID, userID, objectName, method, len(argString), argString[:1024], len(kwargString), kwargString[:1024], eventLogChannel='security')
    525             logAll = self.logAllClientCalls
    526             if logAll is None and prefs.clusterMode == 'LOCAL':
    527                 logAll = 1
    528             if logAll:
    529                 self.clientCallLogChannel = log.Channel(str(macho.mode), 'ClientCalls')
    530                 callerInfo = 'User %s' % session.userid
    531                 try:
    532                     callerInfo = 'Char %s (%s)' % (session.charid, cfg.eveowners.Get(session.charid).name)
    533                 except:
    534                     pass
    535 
    536                 kwargsTxt = ''
    537                 if kwargs:
    538                     kk = CleanKeywordArgs(kwargs)
    539                     if kk:
    540                         kwargsTxt = '. kwargs = %s' % repr(kk)
    541                 self.clientCallLogChannel.Log('%s called %s.%s%s%s' % (callerInfo,
    542                  objectName,
    543                  method,
    544                  repr(args)[:128],
    545                  kwargsTxt[:128]), log.LGNOTICE)
    546             if not self.sessionWatchIDs:
    547                 return
    548             if not charID:
    549                 return
    550             corpID = getattr(session, 'corpid', None)
    551             userType = getattr(session, 'userType', None)
    552             logIt = False
    553             if userID in self.sessionWatchIDs[0]:
    554                 logIt = True
    555             elif charID in self.sessionWatchIDs[1]:
    556                 logIt = True
    557             elif corpID in self.sessionWatchIDs[2]:
    558                 logIt = True
    559             elif userType in self.sessionWatchIDs[3]:
    560                 logIt = True
    561             elif session.role & ROLEMASK_ELEVATEDPLAYER:
    562                 logIt = True
    563             if logIt:
    564                 if argString is None:
    565                     argString = repr(args)
    566                     kwargString = repr(CleanKeywordArgs(kwargs))
    567                 self.eventLog.LogOwnerEvent('ClientCall', charID, solarSystemID, userID, objectName, method, len(argString), argString[:1024], len(kwargString), kwargString[:1024])
    568                 self.eventLog.LogOwnerEventJson('ClientCall', charID, solarSystemID, userID=userID, objectName=objectName, method=method, argsLen=len(argString), args=argString[:1024], kwargsLen=len(kwargString), kwargs=kwargString[:1024])
    569 
    570     def IsValidNodeID(self, node_id):
    571         if node_id == self.nodeID:
    572             return True
    573         if self.GetTransportOfNode(node_id) is not None:
    574             return True
    575         return False