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

dynamicResourceSvc.py (12916B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\dynamicResource\dynamicResourceSvc.py
      2 import datetimeutils
      3 import dynamicresources.client
      4 import locks
      5 import threadutils
      6 from carbon.common.script.sys.service import Service
      7 from carbon.common.script.sys.serviceManager import ServiceManager
      8 from dynamicresources.client import text
      9 from dynamicresources.common.ess.const import LINK_ERROR_ALREADY_LINKED, LINK_VALID, LINK_ERROR_SYSTEM_OFFLINE, LINK_ERROR_NOT_ON_GRID, LINK_ERROR_OUT_OF_RANGE, LINK_ERROR_INVALID_SHIP_TYPE, LINK_ERROR_LINK_OCCUPIED, ESS_LINKABLE_TYPES_LIST, ESS_MAX_LINK_DISTANCE_METERS, LINK_ERROR_NO_BALLPARK
     10 from dynamicresources.common.ess.data import get_key_by_type
     11 from evetypes import GetTypeIDsByListID
     12 from globalConfig import GetDynamicBountySystemEmergencyOffline, DYNAMIC_BOUNTY_SYSTEM_EMERGENCY_OFFLINE_CONFIG as DBS_OFFLINE_KEY, GetESSFeatureFlaggedOffline, ESS_FEATURE_FLAG_DISABLED_CONFIG as ESS_OFFLINE_KEY, GetESSReserveBankFeatureFlaggedOffline, ESS_RESERVE_BANK_DISABLED_CONFIG as RESERVE_OFFLINE_KEY
     13 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     14 from threadutils import expiring_memoize
     15 MAIN_BANK = 0
     16 RESERVE_BANK = 1
     17 
     18 class DynamicResourceSvc(Service):
     19     __guid__ = 'svc.dynamicResourceSvc'
     20     __servicename__ = 'DynamicResourceSvc'
     21     __startupdependencies__ = ['machoNet']
     22     __notifyevents__ = ['OnSystemDynamicBountyStateChanged',
     23      'OnSystemESSDataChanged',
     24      'OnSessionChanged',
     25      'OnGlobalConfigUpdated',
     26      'OnMainBankPlayerHackSuccess',
     27      'OnESSMainBankLinkNotification',
     28      'OnESSReserveBankLinkNotification',
     29      'OnMainBankPlayerLinkDisconnected',
     30      'OnReserveBankPlayerLinkDisconnected']
     31 
     32     def __init__(self):
     33         super(DynamicResourceSvc, self).__init__()
     34         self._ess_state_provider = None
     35         self._ess_settings = None
     36         self._is_ess_state_update_in_progress = False
     37         self._pending_ess_state_update = False
     38 
     39     def Run(self, memStream = None):
     40         super(DynamicResourceSvc, self).Run(memStream)
     41         self._ess_state_provider = dynamicresources.EssStateProvider(state=self._GetInitialEssState(), on_fetch_request=self._ForceUpdateEssStateProvider)
     42         self._ess_state_provider.mark_need_fetch()
     43         self._ess_settings = dynamicresources.EssSettings(service_manager=ServiceManager.Instance())
     44 
     45     @property
     46     def ess_state_provider(self):
     47         return self._ess_state_provider
     48 
     49     @property
     50     def ess_settings(self):
     51         return self._ess_settings
     52 
     53     @expiring_memoize(5400)
     54     def GetDynamicBountySettingForCurrentSystem(self):
     55         if GetDynamicBountySystemEmergencyOffline(self.machoNet):
     56             return (1.0, False)
     57         dynamicBountyMgr = sm.RemoteSvc('dynamicBountyMgr')
     58         output, dbsIsActive = dynamicBountyMgr.GetOutputForClientSolarSystem()
     59         return (output, dbsIsActive)
     60 
     61     @locks.SingletonCall
     62     @expiring_memoize(900)
     63     def GetESSDataForCurrentSystem(self):
     64         if GetESSFeatureFlaggedOffline(self.machoNet):
     65             return None
     66         return sm.RemoteSvc('essMgr').GetDataForClientSolarSystem()
     67 
     68     def IsPlayerLinkedToReserveBank(self):
     69         essSvc = sm.RemoteSvc('essMgr')
     70         return essSvc.IsClientLinkedToReserveBank()
     71 
     72     def CheckLinkEligibility(self, bank):
     73         if GetESSFeatureFlaggedOffline(self.machoNet):
     74             return LINK_ERROR_SYSTEM_OFFLINE
     75         state = self.ess_state_provider.state
     76         if state.offline:
     77             return LINK_ERROR_SYSTEM_OFFLINE
     78         if bank == MAIN_BANK:
     79             if state.reserve_bank.linked:
     80                 return LINK_ERROR_ALREADY_LINKED
     81             if state.main_bank.link is not None:
     82                 if state.main_bank.is_hacking(session.charid):
     83                     return LINK_ERROR_ALREADY_LINKED
     84                 else:
     85                     return LINK_ERROR_LINK_OCCUPIED
     86         if bank == RESERVE_BANK:
     87             if state.main_bank.link is not None and state.main_bank.link.character_id == session.charid:
     88                 return LINK_ERROR_ALREADY_LINKED
     89             if state.reserve_bank.linked:
     90                 return LINK_ERROR_ALREADY_LINKED
     91         shipID = session.shipid
     92         ballpark = sm.GetService('michelle').GetBallpark()
     93         if ballpark is None:
     94             return LINK_ERROR_NO_BALLPARK
     95         try:
     96             typeID = ballpark.slimItems[shipID].typeID
     97         except KeyError:
     98             typeID = None
     99 
    100         if typeID is None or typeID not in GetTypeIDsByListID(ESS_LINKABLE_TYPES_LIST):
    101             return LINK_ERROR_INVALID_SHIP_TYPE
    102         if ballpark.GetBall(state.ess_item_id) is None:
    103             return LINK_ERROR_NOT_ON_GRID
    104         dist = ballpark.DistanceBetween(shipID, state.ess_item_id)
    105         if dist > ESS_MAX_LINK_DISTANCE_METERS:
    106             return LINK_ERROR_OUT_OF_RANGE
    107         return LINK_VALID
    108 
    109     def RequestESSMainBankLink(self):
    110         eligibility = self.CheckLinkEligibility(MAIN_BANK)
    111         if eligibility != LINK_VALID:
    112             return eligibility
    113         essSvc = sm.RemoteSvc('essMgr')
    114         essSvc.AttemptLinkToMainBank()
    115 
    116     def RequestESSReserveBankLink(self):
    117         if GetESSReserveBankFeatureFlaggedOffline(self.machoNet) == True:
    118             return LINK_ERROR_SYSTEM_OFFLINE
    119         eligibility = self.CheckLinkEligibility(RESERVE_BANK)
    120         if eligibility != LINK_VALID:
    121             return eligibility
    122         essSvc = sm.RemoteSvc('essMgr')
    123         essSvc.AttemptLinkToReserveBank()
    124 
    125     def RequestESSMainBankUnlink(self):
    126         sm.RemoteSvc('essMgr').RequestMainBankUnlink()
    127 
    128     def RequestESSReserveBankUnlink(self):
    129         sm.RemoteSvc('essMgr').RequestReserveBankUnlink()
    130 
    131     def RequestUnlockReserveBank(self, typeID):
    132         essMgr = sm.RemoteSvc('essMgr')
    133         essMgr.RequestUnlockReserveBank(typeID)
    134 
    135     @expiring_memoize(300)
    136     def GetESSAccessHistoryForCurrentSystem(self):
    137         mainData = sm.RemoteSvc('essMgr').GetMainBankTheftsForClientSolarSystem()
    138         reserveData = sm.RemoteSvc('essMgr').GetReserveBankTheftsForClientSolarSystem()
    139         return {'main': mainData,
    140          'reserve': reserveData}
    141 
    142     def GetESSReserveBankKeysForCurrentSystem(self):
    143         dynamicResourceCacheMgr = sm.RemoteSvc('dynamicResourceCacheMgr')
    144         key_type_ids = dynamicResourceCacheMgr.GetESSReserveBankKeys(session.solarsystemid2)
    145         return [ get_key_by_type(type_id) for type_id in key_type_ids ]
    146 
    147     def OnSystemDynamicBountyStateChanged(self, systemID, rate):
    148         if systemID == session.solarsystemid2:
    149             self.GetDynamicBountySettingForCurrentSystem.prime_cache_result((self,), (rate, True))
    150             sm.ScatterEvent('OnDynamicBountyUpdate_Local')
    151 
    152     def OnSystemESSDataChanged(self, systemID, data):
    153         if systemID == session.solarsystemid2:
    154             self.GetESSDataForCurrentSystem.prime_cache_result((self,), data)
    155             self.GetESSAccessHistoryForCurrentSystem.clear_cache()
    156             self._NotifyEssDataChanged()
    157 
    158     def OnSessionChanged(self, isremote, session, change):
    159         if 'solarsystemid2' in change:
    160             self.GetDynamicBountySettingForCurrentSystem.clear_cache()
    161             sm.ScatterEvent('OnDynamicBountyUpdate_Local')
    162             self.GetESSDataForCurrentSystem.clear_cache()
    163             self.GetESSAccessHistoryForCurrentSystem.clear_cache()
    164             self._NotifyEssDataChanged()
    165 
    166     def OnGlobalConfigUpdated(self, key, val):
    167         if key == DBS_OFFLINE_KEY:
    168             self.GetDynamicBountySettingForCurrentSystem.clear_cache()
    169             sm.ScatterEvent('OnDynamicBountyUpdate_Local')
    170         if key == ESS_OFFLINE_KEY or key == RESERVE_OFFLINE_KEY:
    171             self.GetESSDataForCurrentSystem.clear_cache()
    172             self._NotifyEssDataChanged()
    173 
    174     def OnESSMainBankLinkNotification(self, solar_system_id):
    175         if is_current_system(solar_system_id):
    176             self.GetESSDataForCurrentSystem.clear_cache()
    177             self._NotifyEssDataChanged()
    178 
    179     def OnESSReserveBankLinkNotification(self, solar_system_id):
    180         if is_current_system(solar_system_id):
    181             self._ess_state_provider.evolve(reserve_bank=self._ess_state_provider.state.reserve_bank.evolve(linked=True))
    182 
    183     def OnMainBankPlayerHackSuccess(self, hack_data):
    184         if is_current_system(hack_data['solarSystemID']):
    185             self._ess_state_provider.evolve(main_bank=self._ess_state_provider.state.main_bank.evolve(link_result=dynamicresources.MainBankLinkResult(link_id=hack_data['linkID'], character_id=int(hack_data['characterID']), successful=True)))
    186 
    187     def OnMainBankPlayerLinkDisconnected(self, data):
    188         if is_current_system(data['solarSystemID']):
    189             self._ess_state_provider.evolve(main_bank=self._ess_state_provider.state.main_bank.evolve(link_result=dynamicresources.MainBankLinkResult(link_id=data['linkID'], character_id=data['characterID'], successful=False)))
    190             if data['characterID'] == session.charid:
    191                 message = text.unlink_reason_description(data['reason'])
    192                 if message:
    193                     prompt_player_fsd_dialog('CustomNotify', {'notify': message})
    194 
    195     def OnReserveBankPlayerLinkDisconnected(self, data):
    196         if is_current_system(data['solarSystemID']):
    197             self._ess_state_provider.evolve(reserve_bank=self._ess_state_provider.state.reserve_bank.evolve(linked=False))
    198             if data['characterID'] == session.charid:
    199                 message = text.unlink_reason_description(int(data['reason']))
    200                 if message:
    201                     prompt_player_fsd_dialog('CustomNotify', {'notify': message})
    202 
    203     def _NotifyEssDataChanged(self):
    204         self._UpdateEssStateProvider()
    205         sm.ScatterEvent('OnESSDataUpdate_Local')
    206 
    207     @threadutils.threaded
    208     def _ForceUpdateEssStateProvider(self):
    209         self._UpdateEssStateProvider(force=True)
    210 
    211     def _UpdateEssStateProvider(self, force = False):
    212         if self._is_ess_state_update_in_progress:
    213             self._pending_ess_state_update = True
    214             return
    215         self._is_ess_state_update_in_progress = True
    216         try:
    217             self._pending_ess_state_update = True
    218             while self._pending_ess_state_update:
    219                 self._pending_ess_state_update = False
    220                 if is_current_system(None):
    221                     self._ess_state_provider.evolve(status=dynamicresources.EssStatus.offline, ess_item_id=None)
    222                     continue
    223                 if not self._ess_state_provider.has_subscribers and not force:
    224                     self._ess_state_provider.mark_need_fetch()
    225                     continue
    226                 ess_data = self.GetESSDataForCurrentSystem()
    227                 if ess_data is None or ess_data['essID'] is None:
    228                     self._ess_state_provider.evolve(status=dynamicresources.EssStatus.offline, ess_item_id=None)
    229                     continue
    230                 current_state = self._ess_state_provider.state
    231                 main_bank_link = None
    232                 if ess_data['mainBankLink']:
    233                     main_bank_link = dynamicresources.MainBankLink(link_id=ess_data['mainBankLink']['linkID'], character_id=ess_data['mainBankLink']['characterID'], start=datetimeutils.filetime_to_datetime(ess_data['mainBankLink']['startedAt']), end=datetimeutils.filetime_to_datetime(ess_data['mainBankLink']['completesAt']))
    234                 last_pulse_start = ess_data['reserveBankLastPulseInitiated']
    235                 if last_pulse_start is not None:
    236                     last_pulse_start = datetimeutils.filetime_to_datetime(last_pulse_start)
    237                 pulses_remaining = ess_data['reserveBankPulsesRemaining']
    238                 link_count = ess_data['reserveBankActiveLinks']
    239                 linked = False
    240                 if pulses_remaining > 0 and link_count > 0:
    241                     linked = self.IsPlayerLinkedToReserveBank()
    242                 self._ess_state_provider.evolve(status=dynamicresources.EssStatus.online, ess_item_id=ess_data['essID'], main_bank=current_state.main_bank.evolve(balance=ess_data['mainValue'], link=main_bank_link), reserve_bank=dynamicresources.ReserveBankState(balance=ess_data['reserveValue'], pulses_total=ess_data['reserveBankPulsesTotal'], pulses_remaining=pulses_remaining, last_pulse_start=last_pulse_start, link_count=link_count, linked=linked))
    243 
    244         finally:
    245             self._is_ess_state_update_in_progress = False
    246 
    247     def _GetInitialEssState(self):
    248         return dynamicresources.EssState(status=dynamicresources.EssStatus.loading, ess_item_id=None, in_range=False, main_bank=dynamicresources.MainBankState(balance=0, link=None, link_result=None), reserve_bank=dynamicresources.ReserveBankState(balance=0, pulses_total=0, pulses_remaining=0, last_pulse_start=None, link_count=0, linked=False))
    249 
    250 
    251 def is_current_system(solar_system_id):
    252     return getattr(session, 'solarsystemid2', None) == solar_system_id