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

clientPathfinderService.py (15970B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\util\clientPathfinderService.py
      2 import gametime
      3 import logging
      4 import pyEvePathfinder
      5 import uthread2
      6 import six
      7 from carbon.common.lib import telemetry
      8 from carbon.common.script.sys.service import Service
      9 from eve.common.lib import appConst as const
     10 from eve.common.script.sys import idCheckers
     11 from eve.common.script.sys.idCheckers import IsSolarSystem
     12 from evePathfinder.eveMapWrapper import EveMapWrapper
     13 from evePathfinder.lightYearDistances import LightYearDistanceFinder
     14 from evePathfinder.pathfinder import ClientPathfinder
     15 from evePathfinder.stateinterface import AutopilotPathfinderInterface, StandardPathfinderInterface
     16 from signals import Signal
     17 from stargate.client.gate_signals import on_lock_changed, on_lock_added, on_lock_removed, on_lock_changed_in_restricted_system
     18 from stargate.client.gateLockController import GateLockController
     19 from stargate.client import get_gate_lock_messenger
     20 from threadutils import be_nice
     21 logger = logging.getLogger(__name__)
     22 PATHFINDER_WAIT_TIMEOUT_SECONDS = 60
     23 
     24 def ConvertStationIDToSolarSystemIDIfNecessary(waypointID):
     25     if idCheckers.IsStation(waypointID):
     26         return cfg.stations.Get(waypointID).solarSystemID
     27     if idCheckers.IsSolarSystem(waypointID):
     28         return waypointID
     29     structure = sm.GetService('structureDirectory').GetStructureInfo(waypointID)
     30     if structure is not None:
     31         return structure.solarSystemID
     32     return waypointID
     33 
     34 
     35 def GetCurrentSolarSystemID():
     36     return session.solarsystemid2
     37 
     38 
     39 def UpdatesAutopilot(func):
     40 
     41     def Wrapper(*args, **kwargs):
     42         func(*args, **kwargs)
     43         sm.ScatterEvent('OnAutopilotUpdated')
     44 
     45     return Wrapper
     46 
     47 
     48 class PathfinderWaitTimoutError(Exception):
     49     pass
     50 
     51 
     52 def WaitForPathfinderInitialization(func):
     53 
     54     def Wrapper(self, *args, **kwargs):
     55         startTime = gametime.GetWallclockTime()
     56         while not self.initialized or self.clientPathfinder is None:
     57             if gametime.GetSecondsSinceWallclockTime(startTime) > PATHFINDER_WAIT_TIMEOUT_SECONDS:
     58                 raise PathfinderWaitTimoutError()
     59             uthread2.sleep(0.1)
     60 
     61         return func(self, *args, **kwargs)
     62 
     63     return Wrapper
     64 
     65 
     66 class ClientPathfinderService(Service):
     67     __exportedcalls__ = {}
     68     __guid__ = 'svc.clientPathfinderService'
     69     __servicename__ = 'pathfinderSvc'
     70     __displayname__ = 'Client Pathfinder Service'
     71     __dependencies__ = ['settings',
     72      'map',
     73      'objectCaching',
     74      'securitySvc']
     75     __notifyevents__ = ['OnCharacterSessionChanged', 'OnSecurityModified', 'OnSessionReset']
     76     _PATHFINDER_IGNORED_GATES = ()
     77 
     78     def Run(self, memStream = None):
     79         self.clientPathfinder = None
     80         self.lastJumpGatesLoaded = {}
     81         self.lightYearDistanceFinder = None
     82         self._gate_lock_controller = GateLockController.get_instance(get_gate_lock_messenger(sm.GetService('publicGatewaySvc')))
     83         self.on_pathfinder_initialized = Signal('on_pathfinder_initialized')
     84         self.initialized = False
     85         self.LogInfo('Starting Client Pathfinder Service')
     86 
     87     def OnCharacterSessionChanged(self, _oldCharacterID, newCharacterID):
     88         if newCharacterID is not None:
     89             self.Initialize()
     90 
     91     def OnSessionReset(self):
     92         self.lastJumpGatesLoaded.clear()
     93         self.initialized = False
     94 
     95     def OnSecurityModified(self, solarSystemID, modifierAmount, newSecurity):
     96         if self.clientPathfinder is not None:
     97             self.clientPathfinder.pathfinderCore.newPathfinderMap.SetSolarSystemSecurity(solarSystemID, newSecurity)
     98             sm.GetService('autoPilot').OptimizeRoute()
     99             sm.ScatterEvent('OnAutopilotUpdated')
    100 
    101     def UpdateJumpGates(self):
    102         availableJumpThroughStructures = self.GetAvailableJumpGateJumps(cfg.mapJumpCache)
    103         if self.lastJumpGatesLoaded == availableJumpThroughStructures:
    104             return
    105         self.lastJumpGatesLoaded = availableJumpThroughStructures
    106         self.ForceUpdatePathfinderCore()
    107 
    108     def ForceUpdatePathfinderCore(self):
    109         pathfinderCore = self.CreatePathfinderCore(cfg.mapRegionCache, cfg.mapSystemCache, cfg.mapJumpCache, self.securitySvc.get_modified_security_level, self.GetJumpGateTuple(self.lastJumpGatesLoaded), ClientPathfinderService._PATHFINDER_IGNORED_GATES)
    110         self.clientPathfinder.UpdatePathfinderCore(pathfinderCore)
    111 
    112     @telemetry.ZONE_METHOD
    113     def CreatePathfinderCore(self, mapRegionCache, mapSystemCache, mapJumpCache, get_security_level_func, one_way_jump_tuples = (), ignored_stargate_ids = ()):
    114         eve_map = EveMapWrapper()
    115         eve_map.add_regions(mapRegionCache)
    116         eve_map.add_solar_systems(mapSystemCache, get_security_level_func)
    117         restricted_system_ids = self._gate_lock_controller.get_restricted_systems()
    118         solar_system_to_emanation_lock_details_dict = self._gate_lock_controller.get_solar_system_to_lock_details_dict()
    119         for jump in mapJumpCache:
    120             if jump.stargateID in ignored_stargate_ids:
    121                 logger.info('ClientPathfinderService - client pathfinder has ignored (excluded) jump from Stargate %s (in SolarSystem %s) to reach SolarSystem %s', jump.stargateID, jump.fromSystemID, jump.toSystemID)
    122             elif jump.fromSystemID in restricted_system_ids or jump.toSystemID in restricted_system_ids:
    123                 opposite_gate_id = cfg.mapStargateIdMappingCache[jump.stargateID]
    124                 for fromSystemID, toSystemID, stargateID in ((jump.fromSystemID, jump.toSystemID, jump.stargateID), (jump.toSystemID, jump.fromSystemID, opposite_gate_id)):
    125                     if session.solarsystemid2 != fromSystemID and fromSystemID in restricted_system_ids:
    126                         logger.info('Emanation Lock - client pathfinder has excluded jumping from Stargate %s (in SolarSystem %s) to reach SolarSystem %s', stargateID, fromSystemID, toSystemID)
    127                         continue
    128                     emanation_lock_details = solar_system_to_emanation_lock_details_dict.get(fromSystemID)
    129                     logger.info('Emanation Lock - %s', emanation_lock_details)
    130                     if emanation_lock_details is not None and stargateID != emanation_lock_details.gate_id:
    131                         logger.info('Emanation Lock - client pathfinder has excluded jumping from Stargate %s (in SolarSystem %s) to reach SolarSystem %s', stargateID, fromSystemID, toSystemID)
    132                         continue
    133                     logger.info('Emanation Lock - client pathfinder has included jump from Stargate %s (in SolarSystem %s) to reach SolarSystem %s', stargateID, fromSystemID, toSystemID)
    134                     eve_map.add_jump(fromSystemID, toSystemID)
    135 
    136             else:
    137                 eve_map.add_jump(jump.fromSystemID, jump.toSystemID)
    138                 eve_map.add_jump(jump.toSystemID, jump.fromSystemID)
    139             be_nice()
    140 
    141         eve_map.add_one_way_jumps(one_way_jump_tuples)
    142         eve_map.finalize()
    143         return eve_map.create_core()
    144 
    145     def on_emanation_lock_added(self, lock_details):
    146         if not self.initialized:
    147             self.on_pathfinder_initialized.connect(self._on_emanation_lock_updated_delayed)
    148             return
    149         self._on_emanation_locks_updated()
    150 
    151     def _on_emanation_lock_updated_delayed(self):
    152         self.on_pathfinder_initialized.disconnect(self._on_emanation_lock_updated_delayed)
    153         self._on_emanation_locks_updated()
    154 
    155     def on_emanation_lock_removed(self, lock_details):
    156         self._on_emanation_locks_updated()
    157 
    158     def on_lock_changed_in_restricted_system(self, lock_details, previous_lock):
    159         if not self.initialized:
    160             self.on_pathfinder_initialized.connect(self._on_emanation_lock_updated_delayed)
    161             return
    162         self._on_emanation_locks_updated()
    163 
    164     def on_emanation_lock_changed(self, lock_details, previous_lock):
    165         if lock_details is None and previous_lock is None:
    166             return
    167         self._on_emanation_locks_updated()
    168 
    169     def _on_emanation_locks_updated(self):
    170         self.ForceUpdatePathfinderCore()
    171         sm.GetService('starmap').UpdateRoute()
    172 
    173     def Initialize(self):
    174         self.LogInfo('Initializing the pathfinding internals')
    175         self.lastPKversionNumber = -1
    176         self.lastTrigTaleVersionNumber = -1
    177         if self.clientPathfinder is None:
    178             on_lock_changed.connect(self.on_emanation_lock_changed)
    179             on_lock_changed_in_restricted_system.connect(self.on_lock_changed_in_restricted_system)
    180             on_lock_added.connect(self.on_emanation_lock_added)
    181             on_lock_removed.connect(self.on_emanation_lock_removed)
    182         availableJumpThroughStructures = self.GetAvailableJumpGateJumps(cfg.mapJumpCache)
    183         self.lastJumpGatesLoaded = availableJumpThroughStructures
    184         pathfinderCore = self.CreatePathfinderCore(cfg.mapRegionCache, cfg.mapSystemCache, cfg.mapJumpCache, self.securitySvc.get_modified_security_level, self.GetJumpGateTuple(availableJumpThroughStructures), ClientPathfinderService._PATHFINDER_IGNORED_GATES)
    185         autopilotStateInterface = AutopilotPathfinderInterface(self.map, self.UpdatePodKillList, self.GetTriglavianTaleAvoidanceSystems, self.GetEdencomSystemsAvoidanceList, settings.char.ui)
    186         standardStateInterface = StandardPathfinderInterface()
    187         self.clientPathfinder = ClientPathfinder(pathfinderCore, standardStateInterface, autopilotStateInterface, ConvertStationIDToSolarSystemIDIfNecessary, GetCurrentSolarSystemID)
    188         self.initialized = True
    189         self.on_pathfinder_initialized()
    190 
    191     def GetAvailableJumpGateJumps(self, mapJumpCache):
    192         availableJumpGates = {}
    193         if not settings.char.ui.Get('pathFinder_includeJumpGates', False):
    194             return availableJumpGates
    195         stargateJumps = set()
    196         for jump in mapJumpCache:
    197             stargateJumps.add((jump.fromSystemID, jump.toSystemID))
    198             stargateJumps.add((jump.toSystemID, jump.fromSystemID))
    199 
    200         mapsSvc = sm.GetService('map')
    201         mapsSvc.GetJumpBridgesWithMyAccess.clear_memoized()
    202         jumpBridgesGates, hasAccessTo, hasNoAccessTo = mapsSvc.GetJumpBridgesWithMyAccess()
    203         for structureA, structureB in jumpBridgesGates:
    204             solarSystemA = structureA.solarSystemID
    205             solarSystemB = structureB.solarSystemID
    206             if not IsSolarSystem(solarSystemA) or not IsSolarSystem(solarSystemB):
    207                 continue
    208             if structureA.structureID in hasAccessTo and (solarSystemA, solarSystemB) not in stargateJumps:
    209                 availableJumpGates[solarSystemA, solarSystemB] = structureA.structureID
    210             if structureB.structureID in hasAccessTo and (solarSystemB, solarSystemA) not in stargateJumps:
    211                 availableJumpGates[solarSystemB, solarSystemA] = structureB.structureID
    212 
    213         return availableJumpGates
    214 
    215     def GetJumpGateTuple(self, availableJumps):
    216         return [ (k[0], k[1], v) for k, v in availableJumps.iteritems() ]
    217 
    218     def UpdatePodKillList(self, podKillList):
    219         args = (const.mapHistoryStatKills, 24)
    220         if self.lastPKversionNumber == -1 or self.lastPKversionNumber != self.objectCaching.GetCachedMethodCallVersion(None, 'map', 'GetHistory', args):
    221             unfilteredSystemHistory = sm.RemoteSvc('map').GetHistory(*args)
    222             self.lastPKversionNumber = self.objectCaching.GetCachedMethodCallVersion(None, 'map', 'GetHistory', args)
    223             podKillList = []
    224             for system in unfilteredSystemHistory:
    225                 if system.value3 > 0:
    226                     podKillList.append(system.solarSystemID)
    227 
    228             podKillList.sort()
    229         return podKillList
    230 
    231     def GetTriglavianTaleAvoidanceSystems(self):
    232         return sm.GetService('map').GetTriglavianMinorVictorySystems()
    233 
    234     def GetEdencomSystemsAvoidanceList(self):
    235         return sm.GetService('map').GetEdencomAvoidanceSystems()
    236 
    237     def AddAvoidanceItem(self, *args, **kwds):
    238         self.clientPathfinder.AddAvoidanceItem(*args, **kwds)
    239         sm.ScatterEvent('OnAutopilotUpdated')
    240         sm.ScatterEvent('OnAvoidanceItemsChanged')
    241 
    242     def RemoveAvoidanceItem(self, *args, **kwds):
    243         self.clientPathfinder.RemoveAvoidanceItem(*args, **kwds)
    244         sm.ScatterEvent('OnAutopilotUpdated')
    245         sm.ScatterEvent('OnAvoidanceItemsChanged')
    246 
    247     def GetLastKnownJumpGates(self):
    248         return self.lastJumpGatesLoaded
    249 
    250     def GetMandatoryAvoidanceItems(self):
    251         return self._gate_lock_controller.get_restricted_systems()
    252 
    253     @WaitForPathfinderInitialization
    254     def GetAvoidanceItems(self, *args, **kwargs):
    255         return self.clientPathfinder.GetAvoidanceItems(*args, **kwargs)
    256 
    257     @WaitForPathfinderInitialization
    258     def GetAutopilotRouteType(self, *args, **kwargs):
    259         return self.clientPathfinder.GetAutopilotRouteType(*args, **kwargs)
    260 
    261     @WaitForPathfinderInitialization
    262     def GetWaypointPath(self, *args, **kwargs):
    263         return self.clientPathfinder.GetWaypointPath(*args, **kwargs)
    264 
    265     @WaitForPathfinderInitialization
    266     def GetJumpCountsBetweenSystemPairs(self, *args, **kwargs):
    267         return self.clientPathfinder.GetJumpCountsBetweenSystemPairs(*args, **kwargs)
    268 
    269     @WaitForPathfinderInitialization
    270     def GetPathBetween(self, *args, **kwargs):
    271         return self.clientPathfinder.GetPathBetween(*args, **kwargs)
    272 
    273     @WaitForPathfinderInitialization
    274     def GetAutopilotPathBetween(self, *args, **kwargs):
    275         return self.clientPathfinder.GetAutopilotPathBetween(*args, **kwargs)
    276 
    277     @WaitForPathfinderInitialization
    278     def GetJumpCount(self, *args, **kwargs):
    279         return self.clientPathfinder.GetJumpCount(*args, **kwargs)
    280 
    281     @WaitForPathfinderInitialization
    282     def GetAutopilotJumpCount(self, *args, **kwargs):
    283         return self.clientPathfinder.GetAutopilotJumpCount(*args, **kwargs)
    284 
    285     @WaitForPathfinderInitialization
    286     def GetJumpCountFromCurrent(self, *args, **kwargs):
    287         return self.clientPathfinder.GetJumpCountFromCurrent(*args, **kwargs)
    288 
    289     @WaitForPathfinderInitialization
    290     def GetSystemsWithinAutopilotJumpRange(self, *args, **kwargs):
    291         return self.clientPathfinder.GetSystemsWithinAutopilotJumpRange(*args, **kwargs)
    292 
    293     @WaitForPathfinderInitialization
    294     def GetSystemsWithinJumpRange(self, *args, **kwargs):
    295         return self.clientPathfinder.GetSystemsWithinJumpRange(*args, **kwargs)
    296 
    297     @WaitForPathfinderInitialization
    298     def GetExpandedAvoidanceItems(self, *args, **kwargs):
    299         return self.clientPathfinder.GetExpandedAvoidanceItems(*args, **kwargs)
    300 
    301     @WaitForPathfinderInitialization
    302     def GetNoRouteFoundText(self, *args, **kwargs):
    303         return self.clientPathfinder.GetNoRouteFoundText(*args, **kwargs)
    304 
    305     @WaitForPathfinderInitialization
    306     def GetNoRouteFoundTextAutopilot(self, *args, **kwargs):
    307         return self.clientPathfinder.GetNoRouteFoundTextAutopilot(*args, **kwargs)
    308 
    309     @UpdatesAutopilot
    310     def SetPodKillAvoidance(self, *args, **kwargs):
    311         self.clientPathfinder.SetPodKillAvoidance(*args, **kwargs)
    312 
    313     @UpdatesAutopilot
    314     def SetTriglavianTaleAvoidance(self, *args, **kwargs):
    315         self.clientPathfinder.SetTriglavianTaleAvoidance(*args, **kwargs)
    316 
    317     @UpdatesAutopilot
    318     def SetEdencomSystemsAvoidance(self, *args, **kwargs):
    319         self.clientPathfinder.SetEdencomSystemsAvoidance(*args, **kwargs)
    320 
    321     @UpdatesAutopilot
    322     def SetSystemAvoidance(self, *args, **kwargs):
    323         self.clientPathfinder.SetSystemAvoidance(*args, **kwargs)
    324 
    325     @UpdatesAutopilot
    326     def SetAutopilotRouteType(self, *args, **kwargs):
    327         self.clientPathfinder.SetAutopilotRouteType(*args, **kwargs)
    328 
    329     @UpdatesAutopilot
    330     def SetSecurityPenaltyFactor(self, *args, **kwargs):
    331         self.clientPathfinder.SetSecurityPenaltyFactor(*args, **kwargs)
    332 
    333     def GetLightYearDistanceFinder(self):
    334         if not self.lightYearDistanceFinder:
    335             self.lightYearDistanceFinder = LightYearDistanceFinder()
    336         return self.lightYearDistanceFinder