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

BroadcastStuffGPCS.py (18098B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\net\BroadcastStuffGPCS.py
      2 import sys
      3 from collections import defaultdict
      4 import blue
      5 import bluepy
      6 import uthread
      7 from carbon.common.lib import const
      8 from carbon.common.script.net import machoNet, machoNetAddress, machoNetPacket
      9 from carbon.common.script.net.machoNetExceptions import UnMachoDestination
     10 from carbon.common.script.sys import basesession
     11 from carbon.common.script.sys.serviceConst import SERVICE_RUNNING, SERVICE_START_PENDING
     12 from eveexceptions import UserError
     13 
     14 class CoreBroadcastStuff:
     15     __guid__ = 'gpcs.CoreBroadcastStuff'
     16     __notifyRecvCount__ = defaultdict(lambda : 0)
     17     __notifyMissedCount__ = defaultdict(lambda : 0)
     18     __notifyRecvSourceCount__ = defaultdict(lambda : defaultdict(lambda : 0))
     19     __notifyMissedSourceCount__ = defaultdict(lambda : defaultdict(lambda : 0))
     20 
     21     def __init__(self):
     22         self.machoNet = None
     23         self.queue = []
     24         self.busrunning = 0
     25         self.busrate = 333
     26 
     27     def UpdateRecvNotificationStats(self, eventid, missed, source):
     28         if source.addressType == const.ADDRESS_TYPE_NODE:
     29             sourceId = source.nodeID
     30         elif source.addressType == const.ADDRESS_TYPE_CLIENT:
     31             sourceId = 'Client'
     32         else:
     33             sourceId = 'Unknown'
     34         if missed:
     35             CoreBroadcastStuff.__notifyMissedCount__[eventid] += 1
     36             CoreBroadcastStuff.__notifyMissedSourceCount__[eventid][sourceId] += 1
     37         else:
     38             CoreBroadcastStuff.__notifyRecvCount__[eventid] += 1
     39             CoreBroadcastStuff.__notifyRecvSourceCount__[eventid][sourceId] += 1
     40 
     41     def __BusDriver(self):
     42         try:
     43             while 1:
     44                 blue.pyos.synchro.SleepWallclock(self.busrate)
     45                 if self.machoNet is None:
     46                     continue
     47                 if self.machoNet.state not in (SERVICE_START_PENDING, SERVICE_RUNNING) or machoNet.mode != 'server':
     48                     return
     49                 queue = self.queue
     50                 self.queue = []
     51                 if queue:
     52                     if len(queue) == 1:
     53                         self.ScattercastWithoutTheStars(*queue[0])
     54                     else:
     55                         self.ProxyBroadcast('__PacketBus', queue)
     56                 return
     57 
     58         finally:
     59             self.busrunning = 0
     60 
     61     def NotifyUp(self, packet):
     62         if packet.payload[0]:
     63             self.machoNet.LogInfo('BroadcastStuff::Notify(', packet.destination.broadcastID, ',...)')
     64             if packet.destination.broadcastID.startswith('Process'):
     65                 sm.ChainEventWithoutTheStars(packet.destination.broadcastID, packet.payload[1])
     66             elif packet.destination.broadcastID.startswith('Do'):
     67                 sm.SendEventWithoutTheStars(packet.destination.broadcastID, packet.payload[1])
     68             elif packet.destination.broadcastID == '__MultiEvent':
     69                 for broadcast in packet.payload[1]:
     70                     broadcastID, args = broadcast
     71                     if broadcastID.startswith('Process'):
     72                         sm.ChainEventWithoutTheStars(broadcastID, args)
     73                     elif broadcastID.startswith('Do'):
     74                         sm.SendEventWithoutTheStars(broadcastID, args)
     75                     else:
     76                         sm.ScatterEventWithoutTheStars(broadcastID, args)
     77 
     78             elif packet.destination.broadcastID == '__PacketBus':
     79                 self.machoNet.LogInfo('PacketBus:  handling a packet bus packet')
     80                 merge = {}
     81                 for each in packet.payload[1][0]:
     82                     k = (each[0], each[1])
     83                     if k in merge:
     84                         merge[k].append((each[2], each[3]))
     85                     else:
     86                         merge[k] = [(each[2], each[3])]
     87 
     88                 for k, v in merge.iteritems():
     89                     if len(v) > 1:
     90                         self.ScattercastWithoutTheStars(k[0], k[1], '__MultiEvent', v)
     91                         self.machoNet.LogInfo('PacketBus:  scattercasting it to ', (k[0], k[1]), ' as __MultiEvent ', v)
     92                     else:
     93                         self.ScattercastWithoutTheStars(k[0], k[1], v[0][0], v[0][1])
     94                         self.machoNet.LogInfo('PacketBus:  scattercasting it to ', (k[0], k[1]), ' as ', v[0])
     95 
     96             else:
     97                 sm.ScatterEventWithoutTheStars(packet.destination.broadcastID, packet.payload[1])
     98             self.UpdateRecvNotificationStats(packet.destination.broadcastID, False, packet.source)
     99         else:
    100             packet.payload = packet.payload[1]
    101             self.ForwardNotifyUp(packet)
    102 
    103     def NotifyDown(self, packet):
    104         packet.payload = (0, packet.payload)
    105         self.ForwardNotifyDown(packet)
    106 
    107     def Queuedcast(self, idtype, ids, method, *args):
    108         with bluepy.Timer('machoNet::Queuedcast'):
    109             callTimer = basesession.CallTimer('Queuedcast::%s::%s (Broadcast\\Client)' % (method, idtype))
    110             try:
    111                 return self.QueuedcastWithoutTheStars(idtype, ids, method, args)
    112             finally:
    113                 callTimer.Done()
    114 
    115     def QueuedcastWithoutTheStars(self, idtype, ids, method, args):
    116         if ids:
    117             self.queue.append((idtype,
    118              tuple(ids),
    119              method,
    120              args))
    121             if not self.busrunning:
    122                 self.busrunning = 1
    123                 uthread.worker('MachoNet::BroadcastStuff::BusDriver', self.__BusDriver)
    124 
    125     def Scattercast(self, idtype, ids, method, *args):
    126         with bluepy.Timer('machoNet::Scattercast'):
    127             callTimer = basesession.CallTimer('Scattercast::%s::%s (Broadcast\\Client)' % (method, idtype))
    128             try:
    129                 return self.ScattercastWithoutTheStars(idtype, ids, method, args)
    130             finally:
    131                 callTimer.Done()
    132 
    133     def ScattercastWithoutTheStars(self, idtype, ids, method, args):
    134         if not idtype.startswith('+'):
    135             idtype = '*%s' % idtype
    136         if ids:
    137             self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype=idtype, narrowcast=ids), payload=(1, args)))
    138 
    139     def Objectcast(self, object, method, *args):
    140         with bluepy.Timer('machoNet::Objectcast'):
    141             callTimer = basesession.CallTimer('Objectcast::%s (Broadcast\\Client)' % method)
    142             try:
    143                 self.ObjectcastWithoutTheStars(object, method, args)
    144             finally:
    145                 callTimer.Done()
    146 
    147     def ObjectcastWithoutTheStars(self, object, method, args):
    148         objectID = basesession.GetObjectUUID(object)
    149         self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='objectID', narrowcast=[objectID]), payload=(1, args)))
    150 
    151     def Broadcast(self, method, *args):
    152         with bluepy.Timer('machoNet::Broadcast'):
    153             callTimer = basesession.CallTimer('Broadcast::%s (Broadcast\\Client)' % method)
    154             try:
    155                 packet = machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method), payload=(1, args))
    156                 self.ForwardNotifyDown(packet)
    157             finally:
    158                 callTimer.Done()
    159 
    160     def ClientBroadcast(self, method, *args):
    161         with bluepy.Timer('machoNet::ClientBroadcast'):
    162             callTimer = basesession.CallTimer('ClientBroadcast::%s (Broadcast\\Client)' % method)
    163             try:
    164                 packet = machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='clientID'), payload=(1, args))
    165                 self.ForwardNotifyDown(packet)
    166             finally:
    167                 callTimer.Done()
    168 
    169     def ClusterBroadcast(self, method, *args):
    170         with bluepy.Timer('machoNet::ClusterBroadcast'):
    171             callTimer = basesession.CallTimer('ClusterBroadcast::%s (Broadcast\\Client)' % method)
    172             try:
    173                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='nodeID'), payload=(1, args)))
    174                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='+nodeID', narrowcast=self.machoNet.GetConnectedProxyNodes()), payload=(1, args)))
    175                 if method.startswith('Process'):
    176                     sm.ChainEventWithoutTheStars(method, args)
    177                 elif method.startswith('Do'):
    178                     sm.SendEventWithoutTheStars(method, args)
    179                 else:
    180                     sm.ScatterEventWithoutTheStars(method, args)
    181             finally:
    182                 callTimer.Done()
    183 
    184     def ServerBroadcast(self, method, *args):
    185         with bluepy.Timer('machoNet::ServerBroadcast'):
    186             callTimer = basesession.CallTimer('ServerBroadcast::%s (Broadcast\\Client)' % method)
    187             try:
    188                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='nodeID'), payload=(1, args)))
    189                 if machoNet.mode == 'server':
    190                     if method.startswith('Process'):
    191                         sm.ChainEventWithoutTheStars(method, args)
    192                     elif method.startswith('Do'):
    193                         sm.SendEventWithoutTheStars(method, args)
    194                     else:
    195                         sm.ScatterEventWithoutTheStars(method, args)
    196             finally:
    197                 callTimer.Done()
    198 
    199     NodeBroadcast = ServerBroadcast
    200 
    201     def NarrowcastByNodeIDsWithoutTheStars(self, nodeids, method, args, kwargs):
    202         if len(nodeids):
    203             if 'sourceNodeID' in kwargs:
    204                 source = machoNetAddress.MachoAddress(nodeID=kwargs['sourceNodeID'], service=None, callID=None)
    205             else:
    206                 source = machoNetAddress.MachoAddress()
    207             destination = machoNetAddress.MachoAddress(broadcastID=method, idtype='nodeID', narrowcast=nodeids)
    208             self.ForwardNotifyDown(machoNetPacket.Notification(source=source, destination=destination, payload=(1, args)))
    209 
    210     def NarrowcastByNodeIDs(self, nodeids, method, *args, **kwargs):
    211         with bluepy.Timer('machoNet::NarrowcastByNodeIDs'):
    212             callTimer = basesession.CallTimer('NarrowcastByClientIDs::%s (Broadcast\\Client)' % method)
    213             try:
    214                 self.NarrowcastByNodeIDsWithoutTheStars(nodeids, method, args, kwargs)
    215             finally:
    216                 callTimer.Done()
    217 
    218     def SinglecastByServiceMaskWithoutTheStars(self, serviceMask, method, args, kwargs):
    219         destination = machoNetAddress.MachoAddress(broadcastID=method, idtype='serviceMask', narrowcast=[serviceMask])
    220         source = machoNetAddress.MachoAddress()
    221         self.ForwardNotifyDown(machoNetPacket.Notification(source=source, destination=destination, payload=(1, args)))
    222         if machoNet.mode == 'server' and self.machoNet.serviceMask & serviceMask:
    223             if method.startswith('Process'):
    224                 sm.ChainEventWithoutTheStars(method, args)
    225             elif method.startswith('Do'):
    226                 sm.SendEventWithoutTheStars(method, args)
    227             else:
    228                 sm.ScatterEventWithoutTheStars(method, args)
    229 
    230     def SinglecastByServiceMask(self, serviceMask, method, *args, **kwargs):
    231         with bluepy.Timer('machoNet::SinglecastByServiceMask'):
    232             callTimer = basesession.CallTimer('SinglecastByServiceMask:: %s (Broadcast\\Client)' % method)
    233             try:
    234                 self.SinglecastByServiceMaskWithoutTheStars(serviceMask, method, args, kwargs)
    235             finally:
    236                 callTimer.Done()
    237 
    238     def SinglecastByNodeID(self, nodeid, method, *args, **kwargs):
    239         with bluepy.Timer('machoNet::SinglecastByNodeID'):
    240             callTimer = basesession.CallTimer('SinglecastByNodeID::%s (Broadcast\\Client)' % method)
    241             try:
    242                 self.NarrowcastByNodeIDsWithoutTheStars([nodeid], method, args, kwargs)
    243             finally:
    244                 callTimer.Done()
    245 
    246     def ProxyBroadcast(self, method, *args):
    247         with bluepy.Timer('machoNet::ProxyBroadcast'):
    248             callTimer = basesession.CallTimer('ProxyBroadcast::%s (Broadcast\\Client)' % method)
    249             try:
    250                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='+nodeID', narrowcast=self.machoNet.GetConnectedProxyNodes()), payload=(1, args)))
    251                 if machoNet.mode == 'proxy':
    252                     if method.startswith('Process'):
    253                         sm.ChainEventWithoutTheStars(method, args)
    254                     elif method.startswith('Do'):
    255                         sm.SendEventWithoutTheStars(method, args)
    256                     else:
    257                         sm.ScatterEventWithoutTheStars(method, args)
    258             finally:
    259                 callTimer.Done()
    260 
    261     def NarrowcastByClientIDs(self, clientids, method, *args):
    262         with bluepy.Timer('machoNet::NarrowcastByClientIDs'):
    263             callTimer = basesession.CallTimer('NarrowcastByClientIDs::%s (Broadcast\\Client)' % method)
    264             try:
    265                 return self.NarrowcastByClientIDsWithoutTheStars(clientids, method, args)
    266             finally:
    267                 callTimer.Done()
    268 
    269     def NarrowcastByClientIDsWithoutTheStars(self, clientids, method, args):
    270         if len(clientids):
    271             packet = machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='clientID', narrowcast=clientids), payload=(1, args))
    272             self.ForwardNotifyDown(packet)
    273 
    274     def SinglecastByClientID(self, clientid, method, *args):
    275         with bluepy.Timer('machoNet::SinglecastByClientID'):
    276             callTimer = basesession.CallTimer('SinglecastByClientID::%s (Broadcast\\Client)' % method)
    277             try:
    278                 self.NarrowcastByClientIDsWithoutTheStars([clientid], method, args)
    279             finally:
    280                 callTimer.Done()
    281 
    282     def ReliableSinglecastByUserID(self, userid, method, *args):
    283         with bluepy.Timer('machoNet::ReliableSinglecastByUserID'):
    284             callTimer = basesession.CallTimer('ReliableSinglecastByUserID::%s (Broadcast\\Client)' % method)
    285             try:
    286                 clientIDs = sm.GetService('sessionMgr').GetClientIDsFromID('userid', userid, refresh=1)
    287                 self.NarrowcastByClientIDsWithoutTheStars(clientIDs, method, args)
    288             except UnMachoDestination as e:
    289                 self.machoNet.LogInfo('User ', userid, " was not reachable, so he didn't get this singlecast.  Should be fine and dandy.  reason=", e.payload)
    290                 sys.exc_clear()
    291             except UserError as e:
    292                 if e.msg != 'UnMachoDestination':
    293                     raise
    294                 self.machoNet.LogInfo('User ', userid, " was not reachable, so he didn't get this singlecast.  Should be fine and dandy.  reason=", e.msg)
    295                 sys.exc_clear()
    296             finally:
    297                 callTimer.Done()
    298 
    299     def NarrowcastByUserIDs(self, userids, method, *args):
    300         if not userids:
    301             return
    302         with bluepy.Timer('machoNet::NarrowcastByUserIDs'):
    303             callTimer = basesession.CallTimer('NarrowcastByUserIDs::%s (Broadcast\\Client)' % method)
    304             try:
    305                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='userid', narrowcast=userids), payload=(1, args)))
    306             finally:
    307                 callTimer.Done()
    308 
    309     def SinglecastByUserID(self, userid, method, *args):
    310         with bluepy.Timer('machoNet::SinglecastByUserID'):
    311             callTimer = basesession.CallTimer('SinglecastByUserID::%s (Broadcast\\Client)' % method)
    312             try:
    313                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='userid', narrowcast=[userid]), payload=(1, args)))
    314             finally:
    315                 callTimer.Done()
    316 
    317     def ReliableSinglecastByCharID(self, charid, method, *args):
    318         with bluepy.Timer('machoNet::ReliableSinglecastByCharID'):
    319             callTimer = basesession.CallTimer('ReliableSinglecastByCharID::%s (Broadcast\\Client)' % method)
    320             try:
    321                 clientIDs = sm.GetService('sessionMgr').GetClientIDsFromID('charid', charid, refresh=1)
    322                 self.NarrowcastByClientIDsWithoutTheStars(clientIDs, method, args)
    323             except UnMachoDestination as e:
    324                 self.machoNet.LogInfo('Character ', charid, " was not reachable, so he didn't get this singlecast.  Should be fine and dandy.  reason=", e.payload)
    325                 sys.exc_clear()
    326             except UserError as e:
    327                 if e.msg != 'UnMachoDestination':
    328                     raise
    329                 self.machoNet.LogInfo('Character ', charid, " was not reachable, so he didn't get this singlecast.  Should be fine and dandy.  reason=", e.msg)
    330                 sys.exc_clear()
    331             finally:
    332                 callTimer.Done()
    333 
    334     def NarrowcastByCharIDs(self, charids, method, *args):
    335         if not charids:
    336             return
    337         with bluepy.Timer('machoNet::NarrowcastByCharIDs'):
    338             callTimer = basesession.CallTimer('NarrowcastByCharIDs::%s (Broadcast\\Client)' % method)
    339             try:
    340                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='charid', narrowcast=charids), payload=(1, args)))
    341             finally:
    342                 callTimer.Done()
    343 
    344     def SinglecastByCharID(self, charid, method, *args):
    345         with bluepy.Timer('machoNet::SinglecastByCharID'):
    346             callTimer = basesession.CallTimer('SinglecastByCharID::%s (Broadcast\\Client)' % method)
    347             try:
    348                 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='charid', narrowcast=[charid]), payload=(1, args)))
    349             finally:
    350                 callTimer.Done()