sovSvc.py (19218B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\sovSvc.py 2 from collections import defaultdict 3 import blue 4 import utillib 5 from brennivin.threadutils import expiring_memoize 6 from carbon.common.script.sys.service import Service 7 from entosis.entosisConst import STRUCTURES_UPDATED 8 from eve.client.script.ui.shared.infoPanels.const.infoPanelConst import PANEL_LOCATION_INFO 9 from eve.client.script.ui.shared.sov.sovHubHackingResultWnd import SovHubHackingResultWnd 10 from eve.common.lib import appConst as const 11 from eve.common.script.sys import devIndexUtil, idCheckers 12 from eve.common.script.sys.idCheckers import IsKnownSpaceSystem 13 from entosis.occupancyCalculator import GetOccupancyMultiplier 14 from eveuniverse.security import is_low_sec_or_higher_solar_system 15 from inventorycommon.const import typeTerritorialClaimUnit, typeInfrastructureHub 16 import localization 17 from player_messaging.client.ui_message import prompt_player_fsd_dialog 18 from sovereignty.client.sovHub.dataTypes import UpgradeData 19 from sovereignty.data_types import SovClaimInfo 20 from sovereignty.hub.const import ALLOWED_DURATION_AFTER_SOVHUB_CLAIM 21 from utillib import KeyVal 22 import gametime 23 CLAIM_DAYS_TO_SECONDS = 86400 24 25 class SovService(Service): 26 __guid__ = 'svc.sov' 27 __dependencies__ = ['audio'] 28 __startupdependencies__ = ['fwWarzoneSvc'] 29 __notifyevents__ = ['ProcessSovStatusChanged', 30 'OnSessionChanged', 31 'OnSovereigntyAudioEvent', 32 'OnSolarSystemSovStructuresUpdated', 33 'OnSolarSystemDevIndexChanged', 34 'OnSovHubHacked'] 35 36 def __init__(self): 37 Service.__init__(self) 38 self.sovInfoBySystemID = {} 39 self.devIndexMgr = None 40 self.outpostData = None 41 42 def Run(self, *args): 43 Service.Run(self, *args) 44 self.indexLevels = [] 45 for level in devIndexUtil.GetDevIndexLevels()[const.attributeDevIndexMilitary].itervalues(): 46 self.indexLevels.append(level.maxLevel) 47 48 self.indexLevels.sort() 49 self.holdTimeLevels = devIndexUtil.GetTimeIndexLevels() 50 51 def GetTimeIndexValuesInDays(self): 52 return [ t / CLAIM_DAYS_TO_SECONDS for t in self.holdTimeLevels ] 53 54 def ProcessSovStatusChanged(self, *args): 55 solarSystemID, newStatus = args 56 if newStatus is None and solarSystemID in self.sovInfoBySystemID: 57 del self.sovInfoBySystemID[solarSystemID] 58 else: 59 self.sovInfoBySystemID[solarSystemID] = newStatus 60 if solarSystemID == session.solarsystemid2: 61 sm.ScatterEvent('OnSystemStatusChanged') 62 63 def GetSystemSovereigntyInfo(self, solarSystemID, forceUpdate = False): 64 fwOccupationState = self.fwWarzoneSvc.GetOccupationState(solarSystemID) 65 if fwOccupationState is not None: 66 return SovClaimInfo(None, None, fwOccupationState.occupierID) 67 if not forceUpdate and solarSystemID in self.sovInfoBySystemID: 68 self.LogInfo('GetSystemSovereigntyInfo: Returning cached sov info', self.sovInfoBySystemID[solarSystemID]) 69 return self.sovInfoBySystemID[solarSystemID] 70 sovClaimInfo = sm.RemoteSvc('sovMgr').GetSystemSovereigntyInfo(solarSystemID) 71 self.sovInfoBySystemID[solarSystemID] = sovClaimInfo 72 self.LogInfo('GetSystemSovereigntyInfo: Returning sov status from server:', sovClaimInfo) 73 return sovClaimInfo 74 75 @expiring_memoize(15) 76 def GetInfrastructureHubInfo(self, solarSystemID): 77 return sm.RemoteSvc('sovMgr').GetInfrastructureHubInfo(solarSystemID) 78 79 @expiring_memoize(30) 80 def GetSovStructuresInfoForSolarSystem(self, solarsystemID): 81 sovMgr = sm.RemoteSvc('sovMgr') 82 if solarsystemID == session.solarsystemid2: 83 solarSystemStructuresInfo = sovMgr.GetSovStructuresInfoForLocalSolarSystem() 84 else: 85 solarSystemStructuresInfo = sovMgr.GetSovStructuresInfoForSolarSystem(solarsystemID) 86 self.ModifyStructureInfoIfNeeded(solarSystemStructuresInfo, solarsystemID) 87 return solarSystemStructuresInfo 88 89 def GetSpecificSovStructuresInfoInSolarSystem(self, solarsystemID, itemID): 90 solarsystemStructureInfo = self.GetSovStructuresInfoForSolarSystem(solarsystemID) 91 for structureInfo in solarsystemStructureInfo: 92 if structureInfo.itemID == itemID: 93 return structureInfo 94 95 def ModifyStructureInfoIfNeeded(self, solarSystemStructuresInfo, solarsystemID): 96 if solarSystemStructuresInfo is None: 97 return 98 for structureInfo in solarSystemStructuresInfo: 99 structureInfo['solarSystemID'] = solarsystemID 100 structureInfo['constellationID'] = cfg.mapSystemCache.Get(solarsystemID).constellationID 101 102 def OnSolarSystemSovStructuresUpdated(self, solarsystemID, solarSystemStructuresInfo, changes = None): 103 self.LogInfo('OnSolarSystemSovStructuresUpdated', solarsystemID, solarSystemStructuresInfo) 104 self.ModifyStructureInfoIfNeeded(solarSystemStructuresInfo, solarsystemID) 105 self.GetSovStructuresInfoForSolarSystem.prime_cache_result((self, solarsystemID), solarSystemStructuresInfo) 106 if changes: 107 for sourceItemID, whatChanged in changes.iteritems(): 108 sm.ScatterEvent('OnSolarsystemSovStructureChanged', solarsystemID, whatChanged, sourceItemID) 109 110 else: 111 sm.ScatterEvent('OnSolarsystemSovStructureChanged', solarsystemID, whatChanged=set([STRUCTURES_UPDATED])) 112 113 def OnSolarSystemDevIndexChanged(self, solarsystemID): 114 if solarsystemID == session.solarsystemid2: 115 self.InvalidateCacheForGetDevelopmentIndicesForSystem(solarsystemID) 116 locationPanel = self.GetLocationPanel() 117 if locationPanel: 118 locationPanel.Update() 119 120 def GetLocationPanel(self): 121 infoPanelSvc = sm.GetService('infoPanel') 122 locationPanel = infoPanelSvc.GetPanelByTypeID(PANEL_LOCATION_INFO) 123 return locationPanel 124 125 def GetContestedState(self, solarSystemID): 126 return localization.GetByLabel('UI/Inflight/Brackets/SystemContested') 127 128 def GetKillLast24H(self, itemID): 129 historyDB = sm.RemoteSvc('map').GetHistory(const.mapHistoryStatKills, 24) 130 systems = set(sm.GetService('map').IterateSolarSystemIDs(itemID)) 131 totalKills = 0 132 totalPods = 0 133 for stats in historyDB: 134 if stats.solarSystemID in systems: 135 kills = stats.value1 - stats.value2 136 totalKills += kills 137 totalPods += stats.value3 138 139 return (totalKills, totalPods) 140 141 def AddToBucket(self, buckets, systemOwners, systemID): 142 self.counter += 1 143 sovID = systemOwners.get(systemID, None) 144 if sovID is None: 145 sovID = sm.GetService('map').GetItem(systemID).factionID 146 if sovID is not None: 147 count = buckets.get(sovID, 0) 148 buckets[sovID] = count + 1 149 150 def GetIdFromScope(self, scope): 151 if scope == 'world': 152 itemID = None 153 elif scope == 'region': 154 itemID = session.regionid 155 elif scope == 'constellation': 156 itemID = session.constellationid 157 else: 158 itemID = session.solarsystemid2 159 return itemID 160 161 def GetDevIndexMgr(self): 162 if self.devIndexMgr is None: 163 self.devIndexMgr = sm.RemoteSvc('devIndexManager') 164 return self.devIndexMgr 165 166 def GetIndexLevel(self, value, indexID, isUpgrade = False): 167 if indexID == const.attributeDevIndexUpgrade: 168 indexLevels = const.facwarSolarSystemUpgradeThresholds[1:] 169 elif indexID == const.attributeDevIndexSovereignty: 170 indexLevels = self.holdTimeLevels 171 else: 172 indexLevels = self.indexLevels 173 if value >= indexLevels[-1]: 174 return utillib.KeyVal(level=5, remainder=0.0) 175 for level, maxValue in enumerate(indexLevels): 176 if value < maxValue: 177 if level == 0: 178 minValue = 0.0 179 else: 180 minValue = float(indexLevels[level - 1]) 181 if value < 0: 182 remainder = 0 183 remainder = value - minValue 184 remainder = remainder / (maxValue - minValue) 185 if isUpgrade: 186 level = value 187 return utillib.KeyVal(level=level, remainder=remainder) 188 189 def GetLevelInfoForIndex(self, indexID, devIndex = None, solarsystemID = None): 190 if solarsystemID is None: 191 solarsystemID = session.solarsystemid2 192 increasing = False 193 if indexID == const.attributeDevIndexSovereignty: 194 iHubInfo = self.GetInfrastructureHubInfo(solarsystemID) 195 if iHubInfo: 196 currentTime = blue.os.GetWallclockTime() 197 timeDiff = currentTime - iHubInfo.claimTime 198 value = timeDiff / const.SEC 199 increasing = True 200 else: 201 value = 0 202 else: 203 if devIndex is None: 204 devIndex = self.GetDevelopmentIndicesForSystem(solarsystemID).get(indexID, None) 205 if devIndex is None: 206 self.LogError('The index', indexID, 'does not exist') 207 value = 0 208 increasing = True 209 else: 210 increasing = devIndex.increasing 211 value = devIndex.points 212 ret = self.GetIndexLevel(value, indexID) 213 ret.increasing = increasing 214 return ret 215 216 def GetAllDevelopmentIndicesMapped(self): 217 systemToIndexMap = {} 218 for indexInfo in sm.RemoteSvc('devIndexManager').GetAllDevelopmentIndices(): 219 systemToIndexMap[indexInfo.solarSystemID] = {const.attributeDevIndexMilitary: indexInfo.militaryPoints, 220 const.attributeDevIndexIndustrial: indexInfo.industrialPoints, 221 const.attributeDevIndexSovereignty: indexInfo.claimedFor * CLAIM_DAYS_TO_SECONDS} 222 223 return systemToIndexMap 224 225 def OnSessionChanged(self, isRemote, sess, change): 226 if 'solarsystemid2' in change: 227 self.devIndexMgr = None 228 self.outpostData = None 229 oldSolarSystemID2, newSolarSystemID2 = change['solarsystemid2'] 230 self.GetSovStructuresInfoForSolarSystem.remove_from_cache((self, newSolarSystemID2)) 231 self.GetInfrastructureHubInfo.remove_from_cache((self, newSolarSystemID2)) 232 233 def GetCurrentData(self, locationID): 234 fwData = {} 235 if IsKnownSpaceSystem(locationID): 236 constellationID = sm.GetService('map').GetParent(locationID) 237 data = sm.RemoteSvc('map').GetCurrentSovData(constellationID) 238 indexedData = data.Index('locationID') 239 sovData = [indexedData[locationID]] 240 fwData = sm.RemoteSvc('map').GetConstellationLPData(constellationID).Index('solarSystemID') 241 else: 242 if idCheckers.IsConstellation(locationID): 243 fwData = sm.RemoteSvc('map').GetConstellationLPData(locationID).Index('solarSystemID') 244 sovData = sm.RemoteSvc('map').GetCurrentSovData(locationID) 245 return (sovData, fwData) 246 247 def GetRecentActivity(self): 248 data = sm.RemoteSvc('map').GetRecentSovActivity() 249 return data 250 251 def GetDevIndexLevel(self, points): 252 ret = 0 253 for level, value in enumerate(self.indexLevels): 254 if value < points: 255 ret = level + 1 256 else: 257 break 258 259 return ret 260 261 def OnSovereigntyAudioEvent(self, eventID, textParams): 262 if eventID in const.sovAudioEventFiles: 263 self.audio.SendUIEvent(unicode(const.sovAudioEventFiles[eventID][0])) 264 if const.sovAudioEventFiles[eventID][1] is not None: 265 prompt_player_fsd_dialog(const.sovAudioEventFiles[eventID][1], textParams) 266 267 def InvalidateCacheForGetDevelopmentIndicesForSystem(self, solarsystemID): 268 self.GetDevelopmentIndicesForSystem.remove_from_cache((self, solarsystemID)) 269 sm.GetService('objectCaching').InvalidateCachedMethodCall('devIndexManager', 'GetDevelopmentIndicesForSystem', solarsystemID) 270 271 @expiring_memoize(120) 272 def GetDevelopmentIndicesForSystem(self, solarsystemID): 273 return self.GetDevIndexMgr().GetDevelopmentIndicesForSystem(solarsystemID) 274 275 def GetIndexInfoForSolarsystem(self, solarsystemID): 276 devIndices = self.GetDevelopmentIndicesForSystem(solarsystemID) 277 militaryIndex = devIndices.get(const.attributeDevIndexMilitary, None) 278 industrialIndex = devIndices.get(const.attributeDevIndexIndustrial, None) 279 strategicIndex = devIndices.get(const.attributeDevIndexSovereignty, None) 280 militaryIndexInfo = self.GetLevelInfoForIndex(const.attributeDevIndexMilitary, devIndex=militaryIndex, solarsystemID=solarsystemID) 281 industrialIndexInfo = self.GetLevelInfoForIndex(const.attributeDevIndexIndustrial, devIndex=industrialIndex, solarsystemID=solarsystemID) 282 strategicIndexInfo = self.GetLevelInfoForIndex(const.attributeDevIndexSovereignty, devIndex=strategicIndex, solarsystemID=solarsystemID) 283 ret = utillib.KeyVal(militaryIndexLevel=militaryIndexInfo.level, industrialIndexLevel=industrialIndexInfo.level, strategicIndexLevel=strategicIndexInfo.level, militaryIndexRemainder=militaryIndexInfo.remainder, industrialIndexRemainder=industrialIndexInfo.remainder, strategicIndexRemainder=strategicIndexInfo.remainder) 284 return ret 285 286 def GetSovInfoForSolarsystem(self, solarsystemID, isCapital): 287 indexInfo = self.GetIndexInfoForSolarsystem(solarsystemID) 288 multiplier = 1 / GetOccupancyMultiplier(indexInfo.industrialIndexLevel, indexInfo.militaryIndexLevel, indexInfo.strategicIndexLevel, isCapital) 289 sovInfo = self.GetSystemSovereigntyInfo(solarsystemID) 290 if sovInfo: 291 solSovOwnerID = sovInfo.allianceID 292 else: 293 solSovOwnerID = None 294 indexInfo.defenseMultiplier = multiplier 295 indexInfo.sovHolderID = solSovOwnerID 296 return indexInfo 297 298 def IsSystemConquarable(self, solarsystemID): 299 if not IsKnownSpaceSystem(solarsystemID): 300 return False 301 if is_low_sec_or_higher_solar_system(solarsystemID): 302 return False 303 solarSystem = cfg.mapSystemCache.get(solarsystemID, None) 304 factionID = getattr(solarSystem, 'factionID', None) 305 if factionID: 306 return False 307 return True 308 309 def GetSovereigntyStructuresInfoForAlliance(self): 310 if session.allianceid is None: 311 return 312 allianceSvc = sm.GetService('alliance') 313 alliance = allianceSvc.GetMoniker() 314 tcuRows, iHubRows, campaignScores = alliance.GetAllianceSovereigntyStructuresInfo() 315 scoresPerStructure = defaultdict(dict) 316 for campaignScore in campaignScores: 317 scoresPerStructure[campaignScore.sourceItemID][campaignScore.teamID] = campaignScore.score 318 319 structuresPerSolarsystem = defaultdict(list) 320 rowsPerType = [(tcuRows, typeTerritorialClaimUnit), (iHubRows, typeInfrastructureHub)] 321 for structureRows, structureType in rowsPerType: 322 for structureRow in structureRows: 323 structureInfo = KeyVal({'itemID': structureRow.structureID, 324 'typeID': structureType, 325 'campaignState': None, 326 'vulnerabilityState': None, 327 'defenseMultiplier': 1.0, 328 'solarSystemID': structureRow.solarSystemID}) 329 if structureType == typeInfrastructureHub: 330 structureInfo.corporationID = structureRow.corporationID 331 if structureRow.campaignStartTime and structureRow.campaignEventType: 332 structureInfo.campaignState = (structureRow.campaignEventType, 333 session.allianceid, 334 structureRow.campaignStartTime, 335 scoresPerStructure[structureRow.structureID]) 336 structureInfo.defenseMultiplier = structureRow.campaignOccupancyLevel 337 elif structureRow.vulnerableStartTime and structureRow.vulnerableEndTime: 338 structureInfo.vulnerabilityState = (structureRow.vulnerableStartTime, structureRow.vulnerableEndTime) 339 structureInfo.defenseMultiplier = structureRow.vulnerabilityOccupancyLevel 340 structuresPerSolarsystem[structureRow.solarSystemID].append(structureInfo) 341 342 return structuresPerSolarsystem 343 344 def GetMyCapitalSystem(self): 345 if session.allianceid: 346 capitalSystemInfo = sm.GetService('alliance').GetCapitalSystemInfo() 347 if capitalSystemInfo: 348 return capitalSystemInfo.currentCapitalSystem 349 350 def GetSovHubFuelAccessGroup(self, solarSystemID): 351 sovMgr = sm.RemoteSvc('sovMgr') 352 return sovMgr.GetSovHubFuelAccessGroup(solarSystemID) 353 354 def SetSovHubFuelAccessGroup(self, solarSystemID, fuelAccessGroupID): 355 sovMgr = sm.RemoteSvc('sovMgr') 356 return sovMgr.SetSovHubFuelAccessGroup(solarSystemID, fuelAccessGroupID) 357 358 def IsOnLocalSovHubFuelAccessGroup(self): 359 sovMgr = sm.RemoteSvc('sovMgr') 360 return sovMgr.IsOnLocalSovHubFuelAccessGroup() 361 362 def DestroySkyhooks(self, skyhookIDs): 363 return sm.RemoteSvc('sovMgr').DestroySkyhooks(skyhookIDs) 364 365 def AcquireSkyhooks(self, skyhookIDs, accessListID): 366 return sm.RemoteSvc('sovMgr').AcquireSkyhooks(skyhookIDs, accessListID) 367 368 def CanCleanUpSystem(self): 369 isStationManager = session.corprole & const.corpRoleStationManager 370 isDirector = session.corprole & const.corpRoleDirector 371 if not isStationManager and not isDirector: 372 return False 373 hubInfo = self.GetInfrastructureHubInfo(session.solarsystemid2) 374 if hubInfo is None or hubInfo.ownerID != session.corpid: 375 return False 376 seconds_since_claim = gametime.GetSecondsSinceWallclockTime(hubInfo.claimTime) 377 if seconds_since_claim > ALLOWED_DURATION_AFTER_SOVHUB_CLAIM: 378 return False 379 return True 380 381 def GetStructuresAvailableToCleanUp(self): 382 if not self.CanCleanUpSystem(): 383 return [] 384 result = [] 385 ballpark = sm.GetService('michelle').GetBallpark() 386 for ball_id in ballpark.balls.iterkeys(): 387 item = ballpark.GetInvItem(ball_id) 388 if item and idCheckers.IsSkyhook(item.typeID) and item.allianceID != session.allianceid: 389 result.append(item) 390 391 return result 392 393 def OnSovHubHacked(self, sovHubID, upgrades): 394 wnd = SovHubHackingResultWnd.GetIfOpen() 395 sovHubSvc = sm.GetService('sovHubSvc') 396 upgradesDataList = [] 397 for idx, upgradeInfo in enumerate(upgrades): 398 staticData = sovHubSvc.GetStaticDataForUpgrade(upgradeInfo.typeID) 399 u = UpgradeData(upgradeInfo.typeID, upgradeInfo.powerState, staticData, itemID=None) 400 upgradesDataList.append(u) 401 402 if wnd: 403 wnd.LoadWndWithResult(sovHubID, upgradesDataList) 404 wnd.Maximize() 405 else: 406 SovHubHackingResultWnd.Open(sovHubID=sovHubID, upgradesDataList=upgradesDataList)