sovereigntyResourceSvc.py (16053B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\sovereigntyResourceSvc.py 2 import datetime 3 import logging 4 import traceback 5 import uthread 6 from caching import Memoize 7 from carbon.common.script.sys.service import Service 8 from gametime import GetWallclockTime 9 from publicGateway.grpc.exceptions import GenericException 10 from sovereignty.resource.client.data_sources import ConfigurationDataSource, get_current_planetary_data, get_versioned_planetary_data 11 from sovereignty.resource.client.reagent_split_production_simulation import get_next_split_harvest_time_and_amount, get_reagent_split_production_data_at_time, get_next_split_amounts 12 from sovereignty.resource.shared.planetary_resources_cache import DataUnavailableError, PlanetaryResourcesCache, TTL 13 from sovereignty.skyhook.client.data_sources import SkyhooksLocalDataSource 14 from sovereignty.resource.client.messenger import SovereigntyResourceMessenger, FakeResourceExternalMessenger 15 from sovereignty.skyhook.client.notice_listener import ExternalNoticeListener as SkyhookNoticeListener 16 from sovereignty.hub.client.notice_listener import ExternalNoticeListener as HubNoticeListener 17 from sovereignty.skyhook.client.errors import SkyhookAccessForbiddenError, SkyhookNotFoundError 18 from sovereignty.skyhook.client.messenger import SkyhookMessenger, FakeSkyhookMessenger 19 from sovereignty.skyhook.data_type import PlanetAndSkyhookTheftVulnerabilityData 20 from spacecomponents.client.components.orbitalSkyhook import UpdateSkyhookOnReagentsUpdated, UpdateSkyhookOnTheftVulnerabilityChanged 21 from stackless_response_router.exceptions import TimeoutException 22 logger = logging.getLogger(__name__) 23 24 class SovereigntyResourceSvc(Service): 25 __guid__ = 'svc.sovereigntyResourceSvc' 26 __servicename__ = 'Sovereignty Resources' 27 __displayname__ = 'Sovereignty Resources Service' 28 __startupdependencies__ = ['publicGatewaySvc'] 29 __notifyevents__ = ['OnSessionChanged', 'OnSkyhookFirstActivation'] 30 sovResourceMessenger = None 31 planetProductionStaticData = None 32 localSkyhooksData = None 33 skyhookNoticeListener = None 34 hubNoticeListener = None 35 skyhookMessenger = None 36 37 def __init__(self): 38 super(SovereigntyResourceSvc, self).__init__() 39 40 def Run(self, memStream = None): 41 super(SovereigntyResourceSvc, self).Run(memStream=memStream) 42 USE_FAKE_DATA = False 43 if USE_FAKE_DATA: 44 self.sovResourceMessenger = FakeResourceExternalMessenger() 45 self.skyhookMessenger = FakeSkyhookMessenger() 46 else: 47 self.sovResourceMessenger = SovereigntyResourceMessenger(self.publicGatewaySvc) 48 self.skyhookMessenger = SkyhookMessenger(self.publicGatewaySvc) 49 planet_data_cache = PlanetaryResourcesCache(lambda current_version: get_current_planetary_data(self.sovResourceMessenger, current_version), lambda version: get_versioned_planetary_data(self.sovResourceMessenger, version), TTL) 50 self.planetProductionStaticData = ConfigurationDataSource(self.sovResourceMessenger, planet_data_cache) 51 self.localSkyhooksData = SkyhooksLocalDataSource(self.skyhookMessenger) 52 self.skyhookNoticeListener = SkyhookNoticeListener(self.publicGatewaySvc) 53 self.skyhookNoticeListener.on_reagent_simulation_notice.connect(self._OnReagentSimUpdatedNotice) 54 self.skyhookNoticeListener.on_reagent_definition_notice.connect(self._OnReagentDefinitionUpdatedNotice) 55 self.skyhookNoticeListener.on_theft_vulnerability_window_started_notice.connect(self._OnTheftVulnerabilityWindowStartedNotice) 56 self.skyhookNoticeListener.on_theft_vulnerability_window_ended_notice.connect(self._OnTheftVulnerabilityWindowEndedNotice) 57 self.skyhookNoticeListener.on_theft_vulnerability_window_scheduled_notice.connect(self._OnTheftVulnerabilityWindowScheduledNotice) 58 self.skyhookNoticeListener.on_all_in_system_notice.connect(self._OnAllInSystemNotice) 59 self.skyhookNoticeListener.on_activation_changed_notice.connect(self._OnActivationChangedNotice) 60 self.skyhookNoticeListener.on_workforce_changed_notice.connect(self._OnWorkforceChanged) 61 self.localSkyhooksData.on_theft_vulnerability_status_changed.connect(self._OnCachedTheftVulnerabilityStatusChanged) 62 self.hubNoticeListener = HubNoticeListener(self.publicGatewaySvc) 63 self.hubNoticeListener.on_resources_simulated_notice.connect(self._OnResourcesSimulatedNotice) 64 65 def OnSessionChanged(self, isRemove, sess, change): 66 if 'solarsystemid2' in change: 67 self.localSkyhooksData.on_solarsystem_changed(sess.solarsystemid2) 68 self.GetMyCorporationSkyhooksMemoized.clear_memoized() 69 70 def OnSkyhookFirstActivation(self, skyhookID, planetID): 71 self.localSkyhooksData.flush_all_data() 72 vulnerability_data = self.GetTheftVulnerabilityForSkyhook(skyhookID) 73 vulnerable = vulnerability_data and vulnerability_data.vulnerable 74 UpdateSkyhookOnTheftVulnerabilityChanged(skyhookID, is_vulnerable_to_theft=vulnerable) 75 76 def _OnReagentSimUpdatedNotice(self, planetID, skyhookID, reagent_production_data_list): 77 self.localSkyhooksData.update_skyhook_simulations(skyhookID, reagent_production_data_list) 78 sm.ScatterEvent('OnReagentsUpdated', planetID, skyhookID) 79 UpdateSkyhookOnReagentsUpdated(planetID, skyhookID) 80 81 def _OnReagentDefinitionUpdatedNotice(self, planetID, skyhookID, reagent_production_data_list, resource_version): 82 self.localSkyhooksData.update_skyhook_configurations(skyhookID, reagent_production_data_list, resource_version) 83 sm.ScatterEvent('OnReagentsUpdated', planetID, skyhookID) 84 UpdateSkyhookOnReagentsUpdated(planetID, skyhookID) 85 86 def _OnAllInSystemNotice(self, solar_system_id, skyhook_data): 87 self.localSkyhooksData.flush_all_data() 88 self.localSkyhooksData.prime_from_notice(solar_system_id, skyhook_data) 89 90 def _OnTheftVulnerabilityWindowStartedNotice(self, skyhookID, end_datetime): 91 self.localSkyhooksData.update_skyhook_vulnerability_endtime(skyhookID, end_datetime, True) 92 93 def _OnTheftVulnerabilityWindowEndedNotice(self, skyhookID): 94 self.localSkyhooksData.update_skyhook_vulnerability(skyhookID, False) 95 96 def _OnTheftVulnerabilityWindowScheduledNotice(self, skyhookID, start_datetime, end_datetime): 97 self.localSkyhooksData.update_skyhook_vulnerability_schedule(skyhookID, start_datetime, end_datetime) 98 99 def _OnCachedTheftVulnerabilityStatusChanged(self, skyhookID, vulnerability_data): 100 vulnerable = vulnerability_data is not None and vulnerability_data.vulnerable 101 UpdateSkyhookOnTheftVulnerabilityChanged(skyhookID, is_vulnerable_to_theft=vulnerable) 102 103 def _OnWorkforceChanged(self, skyhookID, workforce): 104 self.localSkyhooksData.update_workforce(skyhookID, workforce) 105 106 def _OnResourcesSimulatedNotice(self, hubID, solarsystemID, availableHubResources): 107 sm.ScatterEvent('OnSovHubResourcesSimulated', hubID, solarsystemID, availableHubResources) 108 109 def _OnActivationChangedNotice(self, skyhookID, activationStatus): 110 self.localSkyhooksData.update_skyhook_activation_status(skyhookID, activationStatus) 111 112 def GetPlanetReagentType(self, planetID, version = None): 113 production_data = self.planetProductionStaticData.get_first_reagent_definition(planetID, version) 114 if production_data is not None: 115 return production_data.type_id 116 117 def GetPlanetReagentMaxAmounts(self, planetID, version = None): 118 production_data = self.planetProductionStaticData.get_first_reagent_definition(planetID, version) 119 if production_data is not None: 120 return (production_data.split_configuration.secure_capacity, production_data.split_configuration.insecure_capacity) 121 return (0, 0) 122 123 def GetPlanetReagentAmountAndPeriod(self, planetID, version = None): 124 productionData = self.planetProductionStaticData.get_first_reagent_definition(planetID, version) 125 if productionData is not None: 126 return (productionData.split_configuration.amount_per_period, productionData.split_configuration.period) 127 return (0, 0) 128 129 def GetAllPlanetPowerProduction(self, version = None): 130 return self.planetProductionStaticData.get_all_power_production(version) 131 132 def GetPlanetPowerProduction(self, planetID, version = None): 133 return self.planetProductionStaticData.get_power_production(planetID, version) 134 135 def GetAllPlanetWorkforceProduction(self, version = None): 136 return self.planetProductionStaticData.get_all_workforce_production(version) 137 138 def GetPlanetWorkforceProduction(self, planetID, version = None): 139 return self.planetProductionStaticData.get_workforce_production(planetID, version) 140 141 def IsProductionActiveAtSkyhook(self, skyhookID): 142 return self.localSkyhooksData.get_skyhook(skyhookID).active 143 144 def ActivateSkyhook(self, skyhookID): 145 return self.skyhookMessenger.activate(skyhookID) 146 147 def DeactivateSkyhook(self, skyhookID): 148 return self.skyhookMessenger.deactivate(skyhookID) 149 150 def GetReagentsInSkyhookNow(self, skyhookID): 151 skyhook = self.localSkyhooksData.get_skyhook(skyhookID) 152 if skyhook and len(skyhook.reagent_data) > 0: 153 now = GetWallclockTime() 154 production_data_now = get_reagent_split_production_data_at_time(skyhook.get_first_simulation(), skyhook.get_first_configuration(), now) 155 secure_amount = production_data_now.secure_amount 156 insecure_amount = production_data_now.insecure_amount 157 return (secure_amount, insecure_amount) 158 return (None, None) 159 160 def GetNextReagentHarvestTimeAndAmount(self, skyhookID): 161 skyhook = self.localSkyhooksData.get_skyhook(skyhookID) 162 if skyhook: 163 first_simulation = skyhook.get_first_simulation() 164 first_configuration = skyhook.get_first_configuration() 165 if first_simulation and first_configuration: 166 nextHarvestTime, amount, bothFull = get_next_split_harvest_time_and_amount(first_simulation, first_configuration, GetWallclockTime()) 167 return (nextHarvestTime, amount, bothFull) 168 return (None, None, False) 169 170 def GetNextReagentHarvestAmounts(self, skyhookID): 171 skyhook = self.localSkyhooksData.get_skyhook(skyhookID) 172 if skyhook: 173 first_simulation = skyhook.get_first_simulation() 174 first_configuration = skyhook.get_first_configuration() 175 if first_simulation and first_configuration: 176 secured, unsecured = get_next_split_amounts(first_simulation, first_configuration, GetWallclockTime()) 177 return (secured, unsecured) 178 return (None, None) 179 180 def GetNextHarvestPeriod(self, skyhookID): 181 skyhook = self.localSkyhooksData.get_skyhook(skyhookID) 182 if skyhook: 183 first_configuration = skyhook.get_first_configuration() 184 return first_configuration.period 185 186 def PrimeStaticDataForPlanets(self): 187 return self.planetProductionStaticData.prime_data() 188 189 def GetPlanetResourceInfoParallel(self, planetID, version = None): 190 parallelCalls = [(self.GetPlanetReagentType, (planetID, version)), 191 (self.GetPlanetReagentAmountAndPeriod, (planetID, version)), 192 (self.GetPlanetPowerProduction, (planetID, version)), 193 (self.GetPlanetWorkforceProduction, (planetID, version))] 194 reagentTypeID, reagentAmountsInfo, power, workforce = uthread.parallel(parallelCalls) 195 return (reagentTypeID, 196 reagentAmountsInfo, 197 power, 198 workforce) 199 200 def GetPlanetResourceInfo(self, planetID, version = None): 201 power = None 202 workforce = None 203 reagentAmountsInfo = None 204 reagentTypeID = self.GetPlanetReagentType(planetID, version) 205 if reagentTypeID: 206 reagentAmountsInfo = self.GetPlanetReagentAmountAndPeriod(planetID, version) 207 if not reagentTypeID: 208 power = self.GetPlanetPowerProduction(planetID, version) 209 if not power: 210 workforce = self.GetPlanetWorkforceProduction(planetID, version) 211 return (reagentTypeID, 212 reagentAmountsInfo, 213 power, 214 workforce) 215 216 def GetAvailableHubResources(self, hubID): 217 return self.sovResourceMessenger.get_available_hub_resources(hubID) 218 219 def GetMaxPowerAndWorkforce(self, solarSystemID, version = None): 220 solarSystemInfo = cfg.mapSystemCache.Get(solarSystemID) 221 planetItemIDs = solarSystemInfo.planetItemIDs 222 maxPower = 0 223 maxWorkforce = 0 224 for planetID in planetItemIDs: 225 power = self.planetProductionStaticData.get_power_production(planetID, version) 226 workforce = self.planetProductionStaticData.get_workforce_production(planetID, version) 227 maxPower += max(power, 0) 228 maxWorkforce += max(workforce, 0) 229 230 starID = cfg.mapSolarSystemContentCache[solarSystemID].star.id 231 starPower = self.planetProductionStaticData.get_power_production_for_star(starID) 232 maxPower += max(starPower, 0) 233 return (maxPower, maxWorkforce) 234 235 def GetMyCorporationSkyhooks(self): 236 return self.GetRemoteSvc().GetMyCorporationSkyhooks() 237 238 @Memoize(5) 239 def GetMyCorporationSkyhooksMemoized(self): 240 return self.GetMyCorporationSkyhooks() 241 242 def GetRemoteSvc(self): 243 return sm.RemoteSvc('colonyResourcesMgr') 244 245 def GetMyCorporationsSkyhookDetails(self): 246 try: 247 return self.skyhookMessenger.get_all_corporation(session.corpid) 248 except (GenericException, TimeoutException) as e: 249 raise DataUnavailableError(e) 250 251 @Memoize(5) 252 def GetMyCorporationsSkyhookDetailsMemoized(self): 253 return self.GetMyCorporationsSkyhookDetails() 254 255 @Memoize(15) 256 def GetTheftVulnerableSkyhookInfo(self): 257 system_info = {} 258 solar_systems = self.GetSolarSystemsWithTheftVulnerableSkyhooks() 259 for solar_system in solar_systems: 260 system_info[solar_system] = self.GetPlanetIDsAndTheftVulnerabilityData(solar_system) 261 262 return system_info 263 264 @Memoize(5) 265 def GetSolarSystemsWithTheftVulnerableSkyhooks(self): 266 try: 267 return self.skyhookMessenger.get_solar_systems_with_theft_vulnerable_skyhooks() 268 except (GenericException, TimeoutException) as e: 269 raise DataUnavailableError(e) 270 271 @Memoize(5) 272 def GetPlanetIDsAndTheftVulnerabilityData(self, solarSystemID): 273 vulnerability_data = self.skyhookMessenger.get_theft_vulnerable_skyhooks_in_solar_system(solarSystemID) 274 return vulnerability_data 275 276 def GetTheftVulnerabilityForSkyhook(self, skyhookID): 277 try: 278 local_skyhook_vulnerability_data = self.localSkyhooksData.get_skyhook_vulnerability(skyhookID) 279 except SkyhookNotFoundError: 280 local_skyhook_vulnerability_data = self._GetSkyhookData(skyhookID).vulnerability_data 281 282 return local_skyhook_vulnerability_data 283 284 def GetCurrentWorkforceForSkyhook(self, skyhookID): 285 local_skyhook_workforce = self.localSkyhooksData.get_skyhook_workforce(skyhookID) 286 if local_skyhook_workforce is not None: 287 logger.info(local_skyhook_workforce) 288 return local_skyhook_workforce 289 workforce = self._GetSkyhookData(skyhookID).workforce 290 return workforce 291 292 def GetSkyhook(self, skyhookID): 293 skyhook = self.localSkyhooksData.get_skyhook(skyhookID) 294 if skyhook is not None: 295 return skyhook 296 return self._GetSkyhookData(skyhookID) 297 298 def _GetSkyhookData(self, skyhookID): 299 try: 300 skyhook = self.skyhookMessenger.get(skyhookID) 301 except (GenericException, TimeoutException, SkyhookAccessForbiddenError) as e: 302 logger.warning('Failed to get skyhook data for skyhook %s - %s', skyhookID, traceback.format_exc()) 303 raise DataUnavailableError(e) 304 305 return skyhook