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

tale_service.py (6313B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\taleclient\tale_service.py
      2 from collections import OrderedDict
      3 from carbon.common.script.sys.service import Service
      4 from datetime import datetime, timedelta
      5 from logging import getLogger
      6 from taleclient.listener.listener_signals import on_started_notice, on_stopped_notice
      7 from taleclient.listener.notice_listener import TalesNoticeListener
      8 from talecommon.active_tale_thin import ActiveTaleThin
      9 from talecommon.const import templateClass
     10 from taleclient.active_tale import ActiveTale
     11 from caching import Memoize
     12 from signals import Signal
     13 if False:
     14     from typing import Dict, List
     15 on_active_tale_added = Signal(signalName='on_active_tale_added')
     16 on_active_tale_updated = Signal(signalName='on_active_tale_updated')
     17 on_active_tale_removed = Signal(signalName='on_active_tale_removed')
     18 _ACTIVE_TALES_CACHE_TTL = 600
     19 logger = getLogger(__name__)
     20 
     21 class TaleService(Service):
     22     __guid__ = 'svc.tale'
     23     __displayname__ = 'Tale Client Service'
     24     __notifyevents__ = ['OnTaleData',
     25      'OnTaleRemove',
     26      'OnInfluenceUpdate',
     27      'OnSessionChanged']
     28     __startupdependencies__ = ['publicGatewaySvc']
     29 
     30     def __init__(self):
     31         super(TaleService, self).__init__()
     32         self._notice_listener = TalesNoticeListener(sm.GetService('publicGatewaySvc'))
     33         self._active_tales_in_system = OrderedDict()
     34         self._active_tales_by_template = {}
     35         logger.info('Tales - Tale service initialized.')
     36         on_started_notice.connect(self._on_tale_started_notice)
     37         on_stopped_notice.connect(self._on_tale_stopped_notice)
     38 
     39     def __del__(self):
     40         on_started_notice.disconnect(self._on_tale_started_notice)
     41         on_stopped_notice.disconnect(self._on_tale_stopped_notice)
     42 
     43     def OnSessionChanged(self, isremote, sess, change):
     44         if 'solarsystemid2' in change or 'charid' in change:
     45             self._remove_irrelevant_tales_in_system()
     46             self._clear_active_tales_cache()
     47 
     48     def OnTaleData(self, solarSystemID, data):
     49         if solarSystemID != session.solarsystemid2:
     50             return
     51         for tale in data.itervalues():
     52             self._add_active_tale_in_system(tale)
     53 
     54     def OnTaleRemove(self, taleID, templateClassID, templateID):
     55         self._remove_active_tale_in_system(taleID)
     56 
     57     def OnInfluenceUpdate(self, taleID, newInfluenceData):
     58         if taleID in self._active_tales_in_system:
     59             self._active_tales_in_system[taleID].influence = newInfluenceData.influence
     60             on_active_tale_updated(taleID)
     61 
     62     def get_active_tale_in_system(self, tale_id):
     63         return self._active_tales_in_system.get(tale_id, None)
     64 
     65     def get_active_world_event_tales_in_system(self):
     66         return self._get_active_tales_in_system(templateClass.worldEvents)
     67 
     68     def _get_active_tales_in_system(self, template_class_id):
     69         return [ tale for tale in self._active_tales_in_system.itervalues() if tale.template_class_id == template_class_id ]
     70 
     71     def _add_active_tale_in_system(self, tale):
     72         if getattr(tale, 'objectiveChainID', None) is None:
     73             return
     74         if tale.taleID not in self._active_tales_in_system:
     75             self._active_tales_in_system[tale.taleID] = ActiveTale(tale)
     76             on_active_tale_added(tale.taleID)
     77             sm.GetService('infoPanel').UpdateWorldEventsPanel()
     78         else:
     79             self._active_tales_in_system[tale.taleID].update(tale)
     80             on_active_tale_updated(tale.taleID)
     81 
     82     def _remove_active_tale_in_system(self, tale_id):
     83         if tale_id not in self._active_tales_in_system:
     84             return
     85         tale = self._active_tales_in_system.pop(tale_id, None)
     86         if tale:
     87             tale.close()
     88             on_active_tale_removed(tale.tale_id)
     89             sm.GetService('infoPanel').UpdateWorldEventsPanel()
     90 
     91     def _remove_irrelevant_tales_in_system(self):
     92         for tale_id in self._active_tales_in_system.keys():
     93             if self._active_tales_in_system[tale_id].solar_system_id != session.solarsystemid2:
     94                 tale = self._active_tales_in_system.pop(tale_id, None)
     95                 if tale:
     96                     tale.close()
     97                     on_active_tale_removed(tale.tale_id)
     98 
     99         sm.GetService('infoPanel').UpdateWorldEventsPanel()
    100 
    101     def get_active_tales_by_template_id(self, template_id):
    102         if template_id is None:
    103             logger.warning('Tales - requesting active tales by template ID without a template ID')
    104             return []
    105         if template_id not in self._active_tales_by_template:
    106             logger.info('Tales - active tales for template %s cache does not exist, creating.' % template_id)
    107             self._active_tales_by_template[template_id] = _TaleByTemplateCache(template_id)
    108         if self._active_tales_by_template[template_id].is_expired():
    109             logger.info('Tales - active tales for template %s cache is expired, refreshing.' % template_id)
    110             self._active_tales_by_template[template_id].tales = [ ActiveTaleThin(tale_id=raw_data['tale_id'], template_id=raw_data['template_id'], solar_system_id=raw_data['solar_system_id'], start_date=raw_data['start_date'], end_date=raw_data['end_date']) for raw_data in sm.RemoteSvc('taleMgr').get_active_tales_by_template(template_id) ]
    111         return self._active_tales_by_template[template_id].tales
    112 
    113     def _on_tale_started_notice(self, *args):
    114         self._clear_active_tales_cache()
    115 
    116     def _on_tale_stopped_notice(self, *args):
    117         self._clear_active_tales_cache()
    118 
    119     def _clear_active_tales_cache(self):
    120         self._active_tales_by_template = {}
    121 
    122     @Memoize(15)
    123     def get_global_world_event_tales(self):
    124         return sm.RemoteSvc('taleMgr').GetGlobalWorldEventTales()
    125 
    126 
    127 class _TaleByTemplateCache(object):
    128 
    129     def __init__(self, template_id):
    130         self.template_id = template_id
    131         self._tales = []
    132         self._timestamp = None
    133 
    134     @property
    135     def tales(self):
    136         return self._tales
    137 
    138     @tales.setter
    139     def tales(self, value):
    140         self._tales = value
    141         self._timestamp = datetime.now()
    142 
    143     def is_expired(self):
    144         if self._timestamp is None:
    145             return True
    146         elapsed = datetime.now() - self._timestamp
    147         return elapsed > timedelta(seconds=_ACTIVE_TALES_CACHE_TTL)