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

debugSvc.py (8890B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\sys\debugSvc.py
      2 from __future__ import print_function
      3 import cStringIO
      4 import code
      5 import marshal
      6 import pprint
      7 import random
      8 import sys
      9 import traceback
     10 from collections import OrderedDict
     11 import log
     12 import blue
     13 import evecrypto.crypto as Crypto
     14 from carbon.common.script.net import machoNet
     15 from carbon.common.script.sys import sessions
     16 from carbon.common.script.sys.service import Service
     17 from carbon.common.script.sys.serviceConst import ROLE_PROGRAMMER
     18 from eveprefs import boot
     19 
     20 class Utf8IO(object):
     21     encoding = 'utf-8'
     22 
     23     def __init__(self):
     24         self._sio = cStringIO.StringIO()
     25 
     26     def __getattr__(self, attr):
     27         return getattr(self._sio, attr)
     28 
     29 
     30 class debugSvc(Service):
     31     __guid__ = 'svc.debug'
     32     __displayname__ = 'Debug Service'
     33     __exportedcalls__ = {'Exec': [ROLE_PROGRAMMER],
     34      'Eval': [ROLE_PROGRAMMER],
     35      'Log': [ROLE_PROGRAMMER],
     36      'GetLogEvents': [ROLE_PROGRAMMER]}
     37     __notifyevents__ = ['OnDebugLog']
     38     __dependencies__ = ['machoNet']
     39 
     40     def Run(self, memStream = None):
     41         self.logEvents = {}
     42 
     43     def GetOptions(self):
     44         ret = OrderedDict()
     45         if boot.role == 'server':
     46             ret.update({'all': 'All Proxy and Sol Servers',
     47              'remote': 'Any Proxy',
     48              'local': 'Locally',
     49              'proxies': 'All Proxies',
     50              'servers': 'All Sol Servers'})
     51             for nodeID in sm.services['machoNet'].GetConnectedProxyNodes():
     52                 transport = sm.services['machoNet'].GetTransportOfNode(nodeID)
     53                 ret[nodeID] = 'Proxy %d (%s)' % (nodeID, transport.transport.address)
     54 
     55             for nodeID in sm.services['machoNet'].GetConnectedSolNodes():
     56                 transport = sm.services['machoNet'].GetTransportOfNode(nodeID)
     57                 ret[nodeID] = 'Sol %d (%s)' % (nodeID, transport.transport.address)
     58 
     59         else:
     60             ret.update({'all': 'All Proxy and Sol Servers',
     61              'remote': 'Any Proxy',
     62              'local': 'Locally',
     63              'proxies': 'All Proxies',
     64              'servers': 'All Sol Servers'})
     65             for nodeID in sm.services['machoNet'].GetConnectedProxyNodes():
     66                 transport = sm.services['machoNet'].GetTransportOfNode(nodeID)
     67                 ret[nodeID] = 'Proxy %d (%s)' % (nodeID, transport.transport.address)
     68 
     69             for nodeID in sm.services['machoNet'].GetConnectedSolNodes():
     70                 transport = sm.services['machoNet'].GetTransportOfNode(nodeID)
     71                 ret[nodeID] = 'Sol %d (%s)' % (nodeID, transport.transport.address)
     72 
     73         for s in sessions.GetSessions():
     74             clientID = getattr(s, 'clientID', None)
     75             if clientID and clientID / 10000000000L:
     76                 charID = getattr(s, 'charid', None)
     77                 userID = getattr(s, 'userid', None)
     78                 if charID:
     79                     ret[-clientID] = self.GetClientDisplayString(clientID, charID)
     80                 elif userID:
     81                     ret[-clientID] = 'Client #%d (user #%d)' % (clientID, userID)
     82                 else:
     83                     ret[-clientID] = 'Client #%d' % clientID
     84 
     85         return ret
     86 
     87     def GetClientDisplayString(self, clientID, charID):
     88         return 'Client #%d (char #%d)' % (clientID, charID)
     89 
     90     def Eval(self, code = None, signedCode = None, marshaledCode = None, **params):
     91         if machoNet.mode == 'client':
     92             return
     93         if machoNet.mode == 'client' and signedCode is None:
     94             raise RuntimeError('Eval Failed - Must sign code for clients')
     95         if marshaledCode is not None:
     96             code = marshal.loads(marshaledCode)
     97         if signedCode is not None:
     98             marshaledCode, verified = Crypto.Verify(signedCode)
     99             if not verified:
    100                 raise RuntimeError('Eval Failed - Signature Verification Failure')
    101             code = marshal.loads(marshaledCode)
    102         if not hasattr(session, 'debugContext'):
    103             session.__dict__['debugContext'] = {'__name__': 'debugContext',
    104              '__builtins__': __builtins__}
    105         session.debugContext.update(params)
    106         return eval(code, session.debugContext)
    107 
    108     def OnDebugLog(self, txt, lvl, isClient):
    109         if isClient and not machoNet.mode == 'client':
    110             return
    111         self.Log(txt, lvl)
    112 
    113     def Exec(self, code = None, signedCode = None, node = None, console = False, noprompt = False, **params):
    114         if machoNet.mode == 'client':
    115             return
    116         svc = None
    117         if node is not None:
    118             try:
    119                 lnode = node.lower()
    120             except AttributeError:
    121                 pass
    122             else:
    123                 if lnode == 'remote':
    124                     if boot.role == 'server':
    125                         svc, many = self.session.ConnectToRemoteService('debug', random.choice(sm.services['machoNet'].GetConnectedProxyNodes())), False
    126                     else:
    127                         svc, many = self.session.ConnectToRemoteService('debug'), False
    128                 elif lnode == 'proxies':
    129                     svc, many = self.session.ConnectToAllProxyServerServices('debug'), True
    130                 elif lnode == 'servers':
    131                     svc, many = self.session.ConnectToAllSolServerServices('debug'), True
    132                 elif lnode == 'all':
    133                     svc, many = self.session.ConnectToAllServices('debug'), True
    134                 elif lnode == 'local':
    135                     svc = 0
    136 
    137             try:
    138                 lnode = long(node)
    139             except ValueError:
    140                 pass
    141             else:
    142                 if lnode < 0:
    143                     svc, many = self.session.ConnectToClientService('debug', 'clientID', -lnode), False
    144                 else:
    145                     svc, many = self.session.ConnectToRemoteService('debug', lnode), False
    146 
    147             if svc is None:
    148                 raise RuntimeError('Exec failed: Invalid node %s' % repr(node))
    149         if not svc:
    150             if machoNet.mode == 'client' and signedCode is None:
    151                 raise RuntimeError('Exec Failed - Must sign code for clients')
    152             if signedCode is not None:
    153                 code, verified = Crypto.Verify(signedCode)
    154                 if not verified:
    155                     raise RuntimeError('Exec Failed - Signature Verification Failure')
    156             if console:
    157                 return self._ExecConsole(code, noprompt)
    158             else:
    159                 return self._Exec(code, params)
    160         else:
    161             noprompt = many
    162             ret = svc.Exec(code, signedCode, None, console, noprompt, **params)
    163             if many:
    164                 ret2 = dict([ (each[1], each[2]) for each in ret ])
    165                 return pprint.pformat(ret2) + '\n'
    166             return ret
    167 
    168     def _Exec(self, code, params):
    169         buffdude = cStringIO.StringIO()
    170         temp = (sys.stdout, sys.stderr)
    171         sys.stdout = buffdude
    172         sys.stderr = buffdude
    173         try:
    174             if not hasattr(session, 'debugContext'):
    175                 session.__dict__['debugContext'] = {'__name__': 'debugContext',
    176                  '__builtins__': __builtins__}
    177             session.debugContext.update(params)
    178             exec code in session.debugContext
    179         except:
    180             traceback.print_exc()
    181             sys.exc_clear()
    182         finally:
    183             sys.stdout, sys.stderr = temp
    184 
    185         return buffdude.getvalue()
    186 
    187     def Log(self, txt, lvl):
    188         txt = str(txt)
    189         lvl = int(lvl)
    190         pst = ''
    191         if machoNet.mode == 'client':
    192             pre = '[ Debug ]'
    193             pst = repr(session)
    194         else:
    195             nodeID = sm.GetService('machoNet').GetNodeID()
    196             pre = '[ Debug ] - Node %s - ' % nodeID
    197         log.general.Log('%s %s' % (pre, txt), lvl)
    198         if pst:
    199             log.general.Log(pst, lvl)
    200         self.logEvents[blue.os.GetWallclockTimeNow()] = txt
    201 
    202     def GetLogEvents(self):
    203         return self.logEvents
    204 
    205     def _ExecConsole(self, text, noprompt):
    206         buffdude = Utf8IO()
    207         temp = (sys.stdout, sys.stderr)
    208         sys.stdout = sys.stderr = buffdude
    209         try:
    210             if not hasattr(session, 'debugConsole'):
    211                 session.debugConsole = code.InteractiveConsole()
    212             console = session.debugConsole
    213             if '\n' in text:
    214                 symbol = 'exec'
    215                 if not text.endswith('\n'):
    216                     text += '\n'
    217             else:
    218                 symbol = 'single'
    219             if noprompt:
    220                 console.push(text, symbol)
    221             else:
    222                 print(text)
    223                 incomplete = console.push(text, symbol)
    224                 print('...' if incomplete else '>>>', end=' ')
    225             if not noprompt:
    226                 print('', end=' ')
    227         finally:
    228             sys.stdout, sys.stderr = temp
    229 
    230         return buffdude.getvalue()