eveCfg.py (62645B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\common\script\sys\eveCfg.py 2 import cPickle 3 import copy 4 import logging 5 import math 6 import random 7 import re 8 import sqlite3 9 import sys 10 import types 11 import blue 12 import carbon.common.script.sys.cfg as sysCfg 13 import carbon.common.script.util.format as formatUtil 14 import eve.common.script.util.eveFormat as evefmtutil 15 import evetypes 16 import fsd.schemas.binaryLoader as fsdBinaryLoader 17 import fsdlite 18 import industry 19 import localization 20 import pytelemetry.zoning as telemetry 21 import remotefilecache 22 import uthread 23 import utillib 24 from caching.memoize import Memoize 25 from carbon.common.script.sys.crowset import CRowset 26 from characterdata.factions import iter_factions, get_faction_name 27 from characterdata.npccharacters import get_npc_character_name, iter_npc_characters 28 from eve.common.lib import appConst as const 29 from eve.common.script.util import standingUtil 30 from eveprefs import boot 31 from evestations.const import DOOMHEIM_STATION, NPCStation, NPCStationProps 32 from evestations.data import LOCATION_NPC_STATION_FORMATTER_NO_OP_NAME_RAW, LOCATION_NPC_STATION_FORMATTER_RAW, get_station_operation_name 33 from inventorycommon.const import CONTAINER_GROUPS 34 from inventorycommon.util import IsSubsystemFlagVisible, IsTypeContainer 35 from marketgroups.data import MarketGroupObject 36 from npcs.npccorporations import CorporationTicker, CorporationTickerProps, get_corporation_ticker_name, get_npc_corporation_name, iter_npc_corporation_ids, iter_npc_corporations 37 from player_messaging import PromptResult 38 from spacecomponents.common.helper import HasCargoBayComponent 39 import eve.common.script.sys.idCheckers as idCheckers 40 OWNER_AURA_IDENTIFIER = -1 41 OWNER_SYSTEM_IDENTIFIER = -2 42 logger = logging.getLogger(__name__) 43 44 class Standings(): 45 __guid__ = 'eveCfg.Standings' 46 __passbyvalue__ = 1 47 48 def __init__(self, fromID, fromFactionID, fromCorpID, fromCharID, toID, toFactionID, toCorpID, toCharID): 49 self.fromID, self.fromFactionID, self.fromCorpID, self.fromCharID, self.toID, self.toFactionID, self.toCorpID, self.toCharID = (fromID, 50 fromFactionID, 51 fromCorpID, 52 fromCharID, 53 toID, 54 toFactionID, 55 toCorpID, 56 toCharID) 57 self.faction = utillib.KeyVal(faction=0.0, corp=0.0, char=0.0) 58 self.corp = utillib.KeyVal(faction=0.0, corp=0.0, char=0.0) 59 self.char = utillib.KeyVal(faction=0.0, corp=0.0, char=0.0) 60 61 def __str__(self): 62 return 'Standing from %s toward %s: faction:(%s,%s,%s), corp:(%s,%s,%s), char:(%s,%s,%s)' % (self.fromID, 63 self.toID, 64 self.faction.faction, 65 self.faction.corp, 66 self.faction.char, 67 self.corp.faction, 68 self.corp.corp, 69 self.corp.char, 70 self.char.faction, 71 self.char.corp, 72 self.char.char) 73 74 def __repr__(self): 75 return self.__str__() 76 77 def CanUseAgent(self, level, agentTypeID = None, noL1Check = 1): 78 return CanUseAgent(level, agentTypeID, self.faction.char, self.corp.char, self.char.char, self.fromCorpID, self.fromFactionID, {}, noL1Check) 79 80 def __getattr__(self, theKey): 81 if theKey == 'minimum': 82 m = None 83 for each in (self.faction, self.corp, self.char): 84 for other in (each.faction, each.corp, each.char): 85 if other != 0.0 and (m is None or other < m): 86 m = other 87 88 if m is None: 89 return 0.0 90 return m 91 if theKey == 'maximum': 92 m = None 93 for each in (self.faction, self.corp, self.char): 94 for other in (each.faction, each.corp, each.char): 95 if other != 0.0 and (m is None or other > m): 96 m = other 97 98 if m is None: 99 return 0.0 100 return m 101 if theKey == 'direct': 102 if self.fromID == self.fromFactionID: 103 tmp = self.faction 104 elif self.fromID == self.fromCorpID: 105 tmp = self.corp 106 elif self.fromID == self.fromCharID: 107 tmp = self.char 108 if self.toID == self.toFactionID: 109 return tmp.faction 110 elif self.toID == self.toCorpID: 111 return tmp.corp 112 elif self.toID == self.toCharID: 113 return tmp.char 114 else: 115 return 0.0 116 else: 117 if theKey == 'all': 118 return [(self.fromFactionID, self.toFactionID, self.faction.faction), 119 (self.fromFactionID, self.toCorpID, self.faction.corp), 120 (self.fromFactionID, self.toCharID, self.faction.char), 121 (self.fromCorpID, self.toFactionID, self.corp.faction), 122 (self.fromCorpID, self.toCorpID, self.corp.corp), 123 (self.fromCorpID, self.toCharID, self.corp.char), 124 (self.fromCharID, self.toFactionID, self.char.faction), 125 (self.fromCharID, self.toCorpID, self.char.corp), 126 (self.fromCharID, self.toCharID, self.char.char)] 127 raise AttributeError(theKey) 128 129 130 def CanUseAgent(level, agentTypeID, fac, coc, cac, fromCorpID, fromFactionID, skills, noL1Check = 1): 131 if agentTypeID == const.agentTypeAura: 132 return True 133 elif level == 1 and agentTypeID != const.agentTypeResearchAgent and noL1Check: 134 return 1 135 m = (level - 1) * 2.0 - 1.0 136 if boot.role == 'client': 137 if not skills: 138 mySkills = sm.GetService('skills').GetSkill 139 for skillTypeID in (const.typeConnections, const.typeDiplomacy, const.typeCriminalConnections): 140 skillInfo = mySkills(skillTypeID) 141 if skillInfo: 142 skills[skillTypeID] = skillInfo 143 144 unused, facBonus = standingUtil.GetStandingBonus(fac, fromFactionID, skills) 145 unused, cocBonus = standingUtil.GetStandingBonus(coc, fromFactionID, skills) 146 unused, cacBonus = standingUtil.GetStandingBonus(cac, fromFactionID, skills) 147 if facBonus > 0.0: 148 fac = (1.0 - (1.0 - fac / 10.0) * (1.0 - facBonus / 10.0)) * 10.0 149 if cocBonus > 0.0: 150 coc = (1.0 - (1.0 - coc / 10.0) * (1.0 - cocBonus / 10.0)) * 10.0 151 if cacBonus > 0.0: 152 cac = (1.0 - (1.0 - cac / 10.0) * (1.0 - cacBonus / 10.0)) * 10.0 153 if max(fac, coc, cac) >= m and min(fac, coc, cac) > -2.0: 154 if agentTypeID == const.agentTypeResearchAgent and coc < m - 2.0: 155 return 0 156 return 1 157 else: 158 return 0 159 160 161 class EveDataConfig(sysCfg.DataConfig): 162 __guid__ = 'svc.eveDataconfig' 163 __replaceservice__ = 'dataconfig' 164 165 def __init__(self): 166 sysCfg.DataConfig.__init__(self) 167 168 def _CreateConfig(self): 169 return eveConfig 170 171 172 class EveConfig(sysCfg.Config): 173 __guid__ = 'util.EveConfig' 174 175 def __init__(self): 176 sysCfg.Config.__init__(self) 177 self.fmtMapping[const.UE_OWNERID] = lambda value, value2: cfg.eveowners.Get(value).ownerName 178 self.fmtMapping[const.UE_OWNERIDNICK] = lambda value, value2: cfg.eveowners.Get(value).ownerName.split(' ')[0] 179 self.fmtMapping[const.UE_LOCID] = lambda value, value2: cfg.evelocations.Get(value).locationName 180 self.fmtMapping[const.UE_TYPEID] = lambda value, value2: evetypes.GetName(value) 181 self.fmtMapping[const.UE_TYPEID2] = lambda value, value2: evetypes.GetDescription(value) 182 self.fmtMapping[const.UE_TYPEIDL] = lambda value, value2: cfg.FormatConvert(const.UE_LIST, [ (const.UE_TYPEID, x) for x in value ], value2) 183 self.fmtMapping[const.UE_BPTYPEID] = lambda value, value2: evetypes.GetName(cfg.blueprints.Get(value).blueprintTypeID) 184 self.fmtMapping[const.UE_GROUPID] = lambda value, value2: evetypes.GetGroupNameByGroup(value) 185 self.fmtMapping[const.UE_GROUPID2] = lambda value, value2: '' 186 self.fmtMapping[const.UE_CATID] = lambda value, value2: evetypes.GetCategoryNameByCategory(value) 187 self.fmtMapping[const.UE_CATID2] = lambda value, value2: '' 188 self.fmtMapping[const.UE_AMT] = lambda value, value2: formatUtil.FmtAmt(value) 189 self.fmtMapping[const.UE_AMT2] = lambda value, value2: evefmtutil.FmtISK(value) 190 self.fmtMapping[const.UE_AMT3] = lambda value, value2: evefmtutil.FmtISK(value) 191 self.fmtMapping[const.UE_ISK] = lambda value, value2: evefmtutil.FmtISK(value) 192 self.fmtMapping[const.UE_AUR] = lambda value, value2: evefmtutil.FmtAUR(value) 193 self.fmtMapping[const.UE_DIST] = lambda value, value2: formatUtil.FmtDist(value) 194 self.fmtMapping[const.UE_TYPEIDANDQUANTITY] = self.__FormatTypeIDAndQuantity 195 self.crystalgroups = [] 196 self.rawCelestialCache = {} 197 self.stationLocalizationData = {} 198 self._mapRegionCache = None 199 self._mapConstellationCache = None 200 self._mapSystemCache = None 201 self._mapJumpCache = None 202 self._mapSolarSystemContentCache = None 203 self._map_stargate_id_mapping = None 204 self.mapObjectsDb = None 205 self.staticMapDb = None 206 207 def Release(self): 208 sysCfg.Config.Release(self) 209 self.graphics = None 210 self.graphicEffects = None 211 self.eveowners = None 212 self.evelocations = None 213 self.rawCelestialCache = None 214 self.corptickernames = None 215 self.allianceshortnames = None 216 self.crystalgroups = None 217 self._ReleaseMapCache() 218 self.planetResources = None 219 self.planetBlacklist = None 220 self.overviewDefaults = None 221 self.overviewDefaultGroups = None 222 self.positions = None 223 self.messages = None 224 self.mapObjectsDb = None 225 226 def _ReleaseMapCache(self): 227 self._mapRegionCache = None 228 self._mapConstellationCache = None 229 self._mapSystemCache = None 230 self._mapJumpCache = None 231 self._mapSolarSystemContentCache = None 232 self._map_stargate_id_mapping = None 233 234 def GetStartupData(self): 235 sysCfg.Config.GetStartupData(self) 236 if self.IsClient(): 237 self.messages = _LoadMessagesFromFSD() 238 239 def IsClient(self): 240 return boot.role == 'client' 241 242 @telemetry.ZONE_METHOD 243 def GetMessage(self, key, dict = None, onNotFound = 'return', onDictMissing = 'error', languageID = None): 244 try: 245 msg = self.messages[key] 246 except KeyError: 247 return self._GetContentForMissingMessage(key, dict, languageID=languageID) 248 249 bodyID, titleID = msg.bodyID, msg.titleID 250 title, text = self._GetTitleAndTextForMessage(dict, titleID, bodyID, languageID=languageID) 251 return utillib.KeyVal(text=text, title=title, type=msg.dialogType, audio=msg.urlAudio, icon=msg.urlIcon, suppress=msg.suppressable, closable=msg.closable) 252 253 @telemetry.ZONE_METHOD 254 def GetMessageTypeAndText(self, key, paramDict, onNotFound = 'return', onDictMissing = 'error', languageID = None): 255 try: 256 msg = self.messages[key] 257 except KeyError: 258 return self._GetContentForMissingMessage(key, paramDict, languageID=languageID) 259 260 for k, v in paramDict.iteritems(): 261 if type(v) != types.TupleType: 262 continue 263 value2 = None 264 if len(v) >= 3: 265 value2 = v[2] 266 paramDict[k] = self.FormatConvert(v[0], v[1], value2) 267 268 text = localization.GetByMessageID(msg.bodyID, languageID=languageID, **paramDict) 269 return utillib.KeyVal(text=text, type=msg.dialogType) 270 271 def _GetContentForMissingMessage(self, key, paramDict, languageID): 272 if key != 'ErrMessageNotFound': 273 return self.GetMessage('ErrMessageNotFound', {'msgid': key, 274 'args': repr(paramDict)}, languageID=languageID) 275 else: 276 return utillib.KeyVal(text='Could not find message with key ' + key, title='Message not found', type='fatal', audio='', icon='', suppress=False) 277 278 def _GetTitleAndTextForMessage(self, paramDict, titleID, bodyID, languageID): 279 if paramDict is not None and paramDict != -1: 280 paramDict = self.__prepdict(paramDict) 281 title = localization.GetByMessageID(titleID, languageID=languageID, **paramDict) if titleID is not None else None 282 text = localization.GetByMessageID(bodyID, languageID=languageID, **paramDict) if bodyID is not None else None 283 else: 284 title = localization.GetByMessageID(titleID, languageID=languageID) if titleID is not None else None 285 text = localization.GetByMessageID(bodyID, languageID=languageID) if bodyID is not None else None 286 return (title, text) 287 288 def GetRawMessageTitle(self, key): 289 msg = self.messages.get(key, None) 290 if msg: 291 if msg.titleID is not None: 292 return localization._GetRawByMessageID(msg.titleID) 293 294 @Memoize 295 def GetSuppressValueForMessage(self, msgKey, msgParams): 296 constMapping = {'ID_YES': PromptResult.YES, 297 'ID_NO': PromptResult.NO, 298 False: None, 299 True: True} 300 try: 301 return constMapping[cfg.GetMessage(msgKey, msgParams).suppress] 302 except Exception: 303 return 304 305 def IsChargeCompatible(self, item): 306 if not item[const.ixSingleton]: 307 return 0 308 else: 309 return item[const.ixGroupID] in self.__chargecompatiblegroups__ 310 311 def IsContainer(self, item, doSpaceComponentCheck = True): 312 if not item.singleton: 313 return False 314 elif IsTypeContainer(item.typeID): 315 return True 316 elif doSpaceComponentCheck: 317 return idCheckers.IsSolarSystem(item.locationID) and HasCargoBayComponent(item.typeID) 318 else: 319 return False 320 321 def IsCargoContainer(self, item): 322 return item.singleton and item.groupID in CONTAINER_GROUPS 323 324 def AppGetStartupData(self): 325 self.LoadCfgData() 326 327 def LoadSqliteDB(self, fileName): 328 res = blue.ResFile() 329 if boot.role == 'client' and blue.pyos.packaged: 330 mapObjectsResPath = blue.paths.ResolvePath('bin:/staticdata/{fileName}.db'.format(fileName=fileName)) 331 else: 332 mapObjectsResPath = blue.paths.ResolvePath('res:/staticdata/{fileName}.db'.format(fileName=fileName)) 333 if not res.Open(mapObjectsResPath): 334 cfg.LogError('Could not find file %s.' % mapObjectsResPath) 335 else: 336 dbConnection = sqlite3.connect(mapObjectsResPath) 337 dbConnection.row_factory = sqlite3.Row 338 res.Close() 339 return dbConnection 340 341 def LoadCfgData(self): 342 cfg.LogNotice('App LoadCfgData') 343 remotefilecache.prefetch_folder('res:/staticdata') 344 sysCfg.Config.LoadCfgData(self) 345 self.fsdDustIcons = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/dustIcons.static') 346 self.messages = _LoadMessagesFromFSD() 347 cfg.LogNotice('Done Loading static data') 348 if self.IsClient(): 349 self.mapObjectsDb = self.LoadSqliteDB('mapObjects') 350 self.mapCelestialLocationCache = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/locationCache.static') 351 self.mapFactionsOwningSolarSystems = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/factionsOwningSolarSystems.static', 'res:/staticdata/factionsOwningSolarSystems.schema', optimize=False) 352 infoBubbleData = fsdlite.EveStorage(data='infoBubbleElements', cache='infoBubbles.static') 353 self.infoBubbleElements = {int(k):v for k, v in infoBubbleData['infoBubbleElements'].items()} 354 self.infoBubbleFactions = {int(k):v for k, v in infoBubbleData['infoBubbleFactions'].items()} 355 self.infoBubbleGroups = {int(k):v for k, v in infoBubbleData['infoBubbleGroups'].items()} 356 self.infoBubbleTypeElements = {int(k):v['elements'] for k, v in infoBubbleData['infoBubbleTypeElements'].items()} 357 self.infoBubbleTypeBonuses = {int(k):v for k, v in infoBubbleData['infoBubbleTypeBonuses'].items()} 358 self.certificates = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/certificates.static', optimize=False) 359 self.LoadTypesUsedByBlueprints() 360 else: 361 self.securityForSystemsWithPlanetsInLocation = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/securityForSystemsWithPlanetsInLocation.static') 362 self.staticMapDb = self.LoadSqliteDB('staticMap') 363 self.LoadStationLocalizationData() 364 cfg.LogNotice('Done loading sqlite data') 365 self.LoadPlanetBlacklist() 366 self.LoadCrpTickerNames() 367 self.LoadEveOwners() 368 self.LoadEveLocations() 369 cfg.LogNotice('Done loading owner and location data') 370 self.blueprints = industry.BlueprintStorage() 371 allianceshortnameRowHeader = blue.DBRowDescriptor((('allianceID', const.DBTYPE_I4), ('shortName', const.DBTYPE_WSTR))) 372 self.allianceshortnameRowset = CRowset(allianceshortnameRowHeader, []) 373 self.allianceshortnames = sysCfg.Recordset(AllShortNames, 'allianceID', 'GetAllianceShortNamesEx', 'GetMultiAllianceShortNamesEx') 374 self.ConvertData(self.allianceshortnameRowset, self.allianceshortnames) 375 positionRowHeader = blue.DBRowDescriptor((('itemID', const.DBTYPE_I8), 376 ('x', const.DBTYPE_R5), 377 ('y', const.DBTYPE_R5), 378 ('z', const.DBTYPE_R5), 379 ('yaw', const.DBTYPE_R4), 380 ('pitch', const.DBTYPE_R4), 381 ('roll', const.DBTYPE_R4))) 382 positionRowset = CRowset(positionRowHeader, []) 383 self.positions = sysCfg.Recordset(Position, 'itemID', 'GetPositionEx', 'GetPositionsEx') 384 self.ConvertData(positionRowset, self.positions) 385 cfg.LogNotice('Done loading alliance and position data') 386 if self.IsClient(): 387 self._averageMarketPrice = {} 388 uthread.new(self.GetAveragePricesThread) 389 else: 390 self._averageMarketPrice = self.GetConfigSvc().GetAverageMarketPrices() 391 cfg.LogNotice('Done loading market data') 392 self.__chargecompatiblegroups__ = (const.groupFrequencyMiningLaser, 393 const.groupEnergyWeapon, 394 const.groupProjectileWeapon, 395 const.groupMissileLauncher, 396 const.groupCapacitorBooster, 397 const.groupHybridWeapon, 398 const.groupScanProbeLauncher, 399 const.groupComputerInterfaceNode, 400 const.groupMissileLauncherBomb, 401 const.groupMissileLauncherCruise, 402 const.groupMissileLauncherDefender, 403 const.groupMissileLauncherAssault, 404 const.groupMissileLauncherSiege, 405 const.groupMissileLauncherHeavy, 406 const.groupMissileLauncherHeavyAssault, 407 const.groupMissileLauncherRocket, 408 const.groupMissileLauncherStandard, 409 const.groupMissileLauncherXLTorpedo, 410 const.groupMissileLauncherXLCruise, 411 const.groupMissileLauncherRapidTorpedo, 412 const.groupMissileLauncherFestival, 413 const.groupMissileLauncherDot, 414 const.groupBubbleProbeLauncher, 415 const.groupSensorBooster, 416 const.groupStructureECM, 417 const.groupRemoteSensorBooster, 418 const.groupRemoteSensorDamper, 419 const.groupTrackingComputer, 420 const.groupTrackingDisruptor, 421 const.groupTrackingLink, 422 const.groupWarpDisruptFieldGenerator, 423 const.groupFueledShieldBooster, 424 const.groupFueledArmorRepairer, 425 const.groupSurveyProbeLauncher, 426 const.groupMissileLauncherRapidHeavy, 427 const.groupDroneTrackingModules, 428 const.groupMissileGuidanceComputer, 429 const.groupStructureAreaMissileLauncher, 430 const.groupStructureECMScript, 431 const.groupStructureFlakMissileLauncher, 432 const.groupStructureMissileLauncher, 433 const.groupFlexArmorHardener, 434 const.groupFlexShieldHardener, 435 const.groupFueledRemoteShieldBooster, 436 const.groupFueledRemoteArmorRepairer, 437 const.groupCommandBurstModule, 438 const.groupStructureWarpDisruptor, 439 const.groupStructureFestivalLauncher, 440 const.groupPrecursorTurret, 441 const.groupStasisNullifier, 442 const.groupChainLightningTurret, 443 const.groupStructureDefenseBattery) 444 445 def LoadTypesUsedByBlueprints(self): 446 res = blue.ResFile() 447 resPath = 'res:/staticdata/blueprintsByMaterialTypeIDs.pickle' 448 if not res.open('%s' % resPath): 449 self.LogError('Could not load Blueprints by material Cache data file: %s' % resPath) 450 else: 451 try: 452 pickleData = res.Read() 453 self.blueprintsByMaterialTypeIDs = cPickle.loads(pickleData) 454 finally: 455 res.Close() 456 457 def LoadPlanetBlacklist(self): 458 self.planetBlacklist = self.GetConfigSvc().GetBlackListedPlanets() 459 460 def LoadCrpTickerNames(self): 461 self.corptickernames = sysCfg.Recordset(CrpTickerNames, 'corporationID', 'GetCorpTickerNamesEx', 'GetMultiCorpTickerNamesEx') 462 tickers = [] 463 for corporationID in iter_npc_corporation_ids(): 464 tickers.append(CorporationTicker(corporationID=corporationID, tickerName=get_corporation_ticker_name(corporationID), shape1=None, shape2=None, shape3=None, color1=None, color2=None, color3=None)) 465 466 self.corptickernames.PopulateDataset(CorporationTickerProps, tickers) 467 468 @telemetry.ZONE_METHOD 469 def __prepdict(self, dict): 470 dict = copy.deepcopy(dict) 471 if charsession: 472 for k, v in {'session.char': (const.UE_OWNERID, charsession.charid), 473 'session.nick': (const.UE_OWNERIDNICK, charsession.charid), 474 'session.corp': (const.UE_OWNERID, charsession.corpid), 475 'session.station': (const.UE_LOCID, charsession.stationid), 476 'session.solarsystem': (const.UE_LOCID, charsession.solarsystemid2), 477 'session.constellation': (const.UE_LOCID, charsession.constellationid), 478 'session.region': (const.UE_LOCID, charsession.regionid), 479 'session.location': (const.UE_LOCID, charsession.locationid)}.iteritems(): 480 if v[1] is not None: 481 dict[k] = v 482 483 for k, v in dict.iteritems(): 484 if type(v) != types.TupleType: 485 continue 486 value2 = None 487 if len(v) >= 3: 488 value2 = v[2] 489 dict[k] = self.FormatConvert(v[0], v[1], value2) 490 491 return dict 492 493 def __FormatTypeIDAndQuantity(self, typeID, quantity): 494 return localization.GetByLabel('UI/Common/QuantityAndItem', quantity=quantity, item=typeID) 495 496 def GetAveragePricesThread(self): 497 blue.pyos.synchro.SleepWallclock(2000) 498 self._averageMarketPrice = self.GetConfigSvc().GetAverageMarketPrices() 499 500 def GetCrystalGroups(self): 501 if not self.crystalgroups: 502 crystalGroupIDs = [ groupID for groupID in evetypes.GetGroupIDsByCategory(const.categoryCharge) if localization.CleanImportantMarkup(evetypes.GetGroupNameByGroup(groupID, 'en')).endswith('Crystal') ] 503 self.crystalgroups.extend(crystalGroupIDs) 504 scriptGroupIDs = [ groupID for groupID in evetypes.GetGroupIDsByCategory(const.categoryCharge) if localization.CleanImportantMarkup(evetypes.GetGroupNameByGroup(groupID, 'en')).endswith('Script') ] 505 self.crystalgroups.extend(scriptGroupIDs) 506 return self.crystalgroups 507 508 def GetLocationWormholeClass(self, solarSystemID): 509 system = self.mapSystemCache[solarSystemID] 510 return getattr(system, 'wormholeClassID', const.INVALID_WORMHOLE_CLASS_ID) 511 512 def GetNebula(self, solarSystemID, constellationID, regionID, returnPath = True): 513 if returnPath: 514 return self.mapRegionCache.Get(regionID).nebulaPath 515 else: 516 return self.mapRegionCache.Get(regionID).nebulaID 517 518 @telemetry.ZONE_METHOD 519 def LoadEveOwners(self): 520 rowDescriptor = self.GetOwnersRowDescriptor() 521 self.eveowners = sysCfg.Recordset(EveOwners, 'ownerID', 'GetOwnersEx', 'GetMultiOwnersEx') 522 self.eveowners.header = ['ownerID', 523 'ownerName', 524 'typeID', 525 'gender', 526 'ownerNameID'] 527 for factionID, faction in iter_factions(): 528 if self.IsClient(): 529 factionName = get_faction_name(factionID, faction, important=True) 530 else: 531 factionName = get_faction_name(factionID, faction) 532 self.eveowners.data[factionID] = blue.DBRow(rowDescriptor, [factionID, 533 factionName, 534 const.typeFaction, 535 None, 536 faction.nameID]) 537 538 for corporationID, corporation in iter_npc_corporations(): 539 if self.IsClient(): 540 corporationName = get_npc_corporation_name(corporationID, corporation, important=True) 541 else: 542 corporationName = get_npc_corporation_name(corporationID, corporation) 543 self.eveowners.data[corporationID] = blue.DBRow(rowDescriptor, [corporationID, 544 corporationName, 545 const.typeCorporation, 546 None, 547 corporation.nameID]) 548 549 for charID, character in iter_npc_characters(): 550 if self.IsClient(): 551 important = True 552 else: 553 important = False 554 npcName = get_npc_character_name(charID, character, important=important) 555 try: 556 self.eveowners.data[charID] = blue.DBRow(rowDescriptor, [charID, 557 npcName, 558 const.typeCharacter, 559 character.gender, 560 character.nameID]) 561 except KeyError: 562 self.LogError('ERROR: NPC missing from eveowner table - PLEASE FIX THIS!', charID, npcName) 563 564 self.eveowners.data[1] = blue.DBRow(rowDescriptor, [1, 565 localization.GetByLabel(OWNER_NAME_OVERRIDES[OWNER_SYSTEM_IDENTIFIER]), 566 0, 567 None, 568 None]) 569 570 def UpdateEveOwnerName(self, ownerID, ownerName): 571 owner = self.eveowners.Get(ownerID) 572 self.eveowners.data[ownerID] = blue.DBRow(self.GetOwnersRowDescriptor(), [ownerID, 573 ownerName, 574 owner.typeID, 575 owner.gender, 576 owner.ownerNameID]) 577 578 def GetOwnersRowDescriptor(self): 579 return blue.DBRowDescriptor((('ownerID', const.DBTYPE_I4), 580 ('ownerName', const.DBTYPE_WSTR), 581 ('typeID', const.DBTYPE_I4), 582 ('gender', const.DBTYPE_I2), 583 ('ownerNameID', const.DBTYPE_I4))) 584 585 def GetLocationRowDescriptor(self): 586 return blue.DBRowDescriptor((('locationID', const.DBTYPE_I8), 587 ('locationName', const.DBTYPE_WSTR), 588 ('solarSystemID', const.DBTYPE_I8), 589 ('x', const.DBTYPE_R5), 590 ('y', const.DBTYPE_R5), 591 ('z', const.DBTYPE_R5), 592 ('locationNameID', const.DBTYPE_I4))) 593 594 @property 595 def mapRegionCache(self): 596 if not self._mapRegionCache: 597 self._mapRegionCache = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/regions.static', 'res:/staticdata/regions.schema', optimize=False) 598 return self._mapRegionCache 599 600 @property 601 def mapConstellationCache(self): 602 if not self._mapConstellationCache: 603 self._mapConstellationCache = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/constellations.static', 'res:/staticdata/constellations.schema', optimize=False) 604 return self._mapConstellationCache 605 606 @property 607 def mapSystemCache(self): 608 if not self._mapSystemCache: 609 self._mapSystemCache = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/systems.static', 'res:/staticdata/systems.schema', optimize=False) 610 return self._mapSystemCache 611 612 @property 613 def mapJumpCache(self): 614 if not self._mapJumpCache: 615 self._mapJumpCache = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/jumps.static', 'res:/staticdata/jumps.schema', optimize=False) 616 return self._mapJumpCache 617 618 @property 619 def mapSolarSystemContentCache(self): 620 if not self._mapSolarSystemContentCache: 621 self._mapSolarSystemContentCache = fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/solarSystemContent.static') 622 return self._mapSolarSystemContentCache 623 624 @property 625 def mapStargateIdMappingCache(self): 626 if not self._map_stargate_id_mapping: 627 self._map_stargate_id_mapping = {} 628 for solarSystemID, solarSystem in self.mapSolarSystemContentCache.iteritems(): 629 for stargate_id, stargate in solarSystem.stargates.iteritems(): 630 self._map_stargate_id_mapping[stargate_id] = stargate.destination 631 self._map_stargate_id_mapping[stargate.destination] = stargate_id 632 633 return self._map_stargate_id_mapping 634 635 @telemetry.ZONE_METHOD 636 def LoadEveLocations(self): 637 rowDescriptor = self.GetLocationRowDescriptor() 638 self.evelocations = sysCfg.Recordset(EveLocations, 'locationID', 'GetLocationsEx', 'GetMultiLocationsEx', 'GetLocationsLocal') 639 self.evelocations.header = ['locationID', 640 'locationName', 641 'solarSystemID', 642 'x', 643 'y', 644 'z', 645 'locationNameID'] 646 for regionID, region in self.mapRegionCache.iteritems(): 647 regionName = localization.GetImportantByMessageID(region.nameID) 648 self.evelocations.data[regionID] = blue.DBRow(rowDescriptor, [regionID, 649 regionName, 650 None, 651 region.center[0], 652 region.center[1], 653 region.center[2], 654 region.nameID]) 655 656 for constellationID, constellation in self.mapConstellationCache.iteritems(): 657 constellationName = localization.GetImportantByMessageID(constellation.nameID) 658 self.evelocations.data[constellationID] = blue.DBRow(rowDescriptor, [constellationID, 659 constellationName, 660 None, 661 constellation.center.x, 662 constellation.center.y, 663 constellation.center.z, 664 constellation.nameID]) 665 666 for solarSystemID, solarSystem in self.mapSystemCache.iteritems(): 667 solarSystemName = localization.GetImportantByMessageID(solarSystem.nameID) 668 self.evelocations.data[solarSystemID] = blue.DBRow(rowDescriptor, [solarSystemID, 669 solarSystemName, 670 solarSystemID, 671 solarSystem.center.x, 672 solarSystem.center.y, 673 solarSystem.center.z, 674 solarSystem.nameID]) 675 676 self.LoadOldStationsInfo() 677 self.LoadNPCStations() 678 localStations = {} 679 if self.IsClient(): 680 localStations = self.PrimeStationCelestials() 681 for row in self.stations: 682 if self.IsClient() and row.stationID in localStations: 683 stationName = self.GetNPCStationNameFromLocalRow(localStations[row.stationID]) 684 else: 685 stationName = row.stationName 686 stationName = unicode(stationName) 687 self.evelocations.data[row.stationID] = blue.DBRow(rowDescriptor, [row.stationID, 688 stationName, 689 row.solarSystemID, 690 row.x, 691 row.y, 692 row.z, 693 None]) 694 695 self.LoadStationLocalizationData() 696 697 @telemetry.ZONE_METHOD 698 def LoadStationLocalizationData(self): 699 if self.IsClient(): 700 db = self.mapObjectsDb 701 key = 'stationID' 702 sql = 'SELECT stationID, celestialIndex, orbitIndex, useOperationName FROM npcStations' 703 else: 704 db = self.staticMapDb 705 key = 'id' 706 sql = 'SELECT id, celestialIndex, orbitIndex, useOperationName FROM NpcStations' 707 cursor = db.execute(sql) 708 self.stationLocalizationData = {row[key]:(row['celestialIndex'], row['orbitIndex'], row['useOperationName']) for row in cursor} 709 710 def LoadNPCStations(self): 711 npcStations = [] 712 for stationID, data in self.mapSolarSystemContentCache.npcStations.iteritems(): 713 position = data.position 714 npcStations.append(NPCStation(stationID=stationID, stationName=data.stationName, x=position[0], y=position[1], z=position[2], stationTypeID=data.typeID, solarSystemID=data.solarSystemID, orbitID=data.orbitID, ownerID=data.ownerID)) 715 716 npcStations.append(DOOMHEIM_STATION) 717 self.stations = sysCfg.Recordset(sysCfg.Row, 'stationID', (NPCStationProps, npcStations)) 718 719 def LoadOldStationsInfo(self): 720 self.oldStations = sysCfg.Recordset(sysCfg.Row, 'stationID') 721 if self.IsClient(): 722 uthread.new(self._LoadOldStationsInfo) 723 else: 724 self._LoadOldStationsInfo() 725 726 def _LoadOldStationsInfo(self): 727 oldStations = self.GetConfigSvc().GetOldStationData() 728 if oldStations: 729 self.oldStations = sysCfg.Recordset(sysCfg.Row, 'stationID', (oldStations.columns, oldStations.values())) 730 731 @telemetry.ZONE_METHOD 732 def PrimeStationCelestials(self): 733 if boot.role != 'client': 734 raise RuntimeError('PrimeStationCelestials::Non-client based call to PrimeStationCelestials!') 735 sql = 'SELECT *\n FROM npcStations\n ' 736 stations = self.mapObjectsDb.execute(sql) 737 localStations = {} 738 primeList = [] 739 for station in stations: 740 if station['orbitID'] is not None: 741 primeList.append(station['orbitID']) 742 localStations[station['stationID']] = station 743 744 cfg.evelocations.Prime(primeList) 745 return localStations 746 747 @telemetry.ZONE_METHOD 748 def GetMarketGroup(self, marketGroupID): 749 if boot.role != 'client': 750 raise RuntimeError('GetMarketGroup::Non-clientbased call made!!') 751 return MarketGroupObject(marketGroupID) 752 753 @telemetry.ZONE_METHOD 754 def GetLocationsLocalBySystem(self, solarSystemID, requireLocalizedTexts = True, doYields = False): 755 if boot.role != 'client': 756 raise RuntimeError('GetLocationsLocalBySystem::Non-clientbased call made!!') 757 solarSystemObjectRowDescriptor = blue.DBRowDescriptor((('groupID', const.DBTYPE_I4), 758 ('typeID', const.DBTYPE_I4), 759 ('itemID', const.DBTYPE_I8), 760 ('itemName', const.DBTYPE_WSTR), 761 ('locationID', const.DBTYPE_I4), 762 ('orbitID', const.DBTYPE_I4), 763 ('connector', const.DBTYPE_BOOL), 764 ('x', const.DBTYPE_R5), 765 ('y', const.DBTYPE_R5), 766 ('z', const.DBTYPE_R5), 767 ('celestialIndex', const.DBTYPE_I4), 768 ('orbitIndex', const.DBTYPE_I4))) 769 sql = ' SELECT *\n FROM celestials\n WHERE solarSystemID = %d' % solarSystemID 770 data = [] 771 rs = self.mapObjectsDb.execute(sql) 772 for row in rs: 773 try: 774 celestialName = self.GetCelestialNameFromLocalRow(row, requireLocalizedTexts) 775 data.append(blue.DBRow(solarSystemObjectRowDescriptor, [row['groupID'], 776 row['typeID'], 777 row['celestialID'], 778 celestialName, 779 solarSystemID, 780 row['orbitID'], 781 0, 782 row['x'], 783 row['y'], 784 row['z'], 785 row['celestialIndex'], 786 row['orbitIndex']])) 787 except IndexError as e: 788 rowContents = 'Row: ' 789 if row: 790 rowContents = ', '.join([ '%s=%s' % (key, row[key]) for key in row.keys() ]) 791 error = 'GetLocationsLocalBySystem: Failed getting local celestial data!\nRow is: %s\nError is: %s' % (rowContents, e) 792 self.LogError(error) 793 794 if doYields: 795 blue.synchro.Yield() 796 797 sql = '\n SELECT *\n FROM npcStations\n WHERE solarSystemID = %d\n ' % solarSystemID 798 rs = self.mapObjectsDb.execute(sql) 799 for row in rs: 800 try: 801 celestialName = self.GetNPCStationNameFromLocalRow(row, requireLocalizedTexts) 802 data.append(blue.DBRow(solarSystemObjectRowDescriptor, [evetypes.GetGroupID(row['typeID']), 803 row['typeID'], 804 row['stationID'], 805 celestialName, 806 solarSystemID, 807 row['orbitID'], 808 0, 809 row['x'], 810 row['y'], 811 row['z'], 812 row['celestialIndex'], 813 row['orbitIndex']])) 814 except IndexError as e: 815 rowContents = 'Row: ' 816 if row: 817 rowContents = ', '.join([ '%s=%s' % (key, row[key]) for key in row.keys() ]) 818 error = 'GetLocationsLocalBySystem: Failed getting local station data!\nRow is: %s\nError is: %s' % (rowContents, e) 819 self.LogError(error) 820 821 if doYields: 822 blue.synchro.Yield() 823 824 data = CRowset(solarSystemObjectRowDescriptor, data) 825 return data 826 827 @telemetry.ZONE_METHOD 828 def GetLocationsLocal(self, keys): 829 if boot.role != 'client': 830 raise RuntimeError('GetLocationsLocal::Non-clientbased call made!!') 831 rowDescriptor = self.GetLocationRowDescriptor() 832 data = [] 833 keyString = ','.join([ str(x) for x in keys ]) 834 sql = 'SELECT *\n FROM celestials\n WHERE celestialID IN (%s)' % keyString 835 rs = self.mapObjectsDb.execute(sql) 836 for row in rs: 837 celestialNameData = self._GetCelestialNameDataFromLocalRow(row) 838 self.rawCelestialCache[row['celestialID']] = celestialNameData 839 celestialName = localization.GetImportantByLabel(celestialNameData[0], **celestialNameData[1]) 840 data.append(blue.DBRow(rowDescriptor, [row['celestialID'], 841 celestialName, 842 row['solarSystemID'], 843 row['x'], 844 row['y'], 845 row['z'], 846 None])) 847 848 data = CRowset(rowDescriptor, data) 849 return (data.columns, data) 850 851 @telemetry.ZONE_METHOD 852 def GetNPCStationNameFromLocalRow(self, row, requireLocalizedTexts = True): 853 orbitID = row['orbitID'] 854 if row['celestialIndex'] is None: 855 orbitID = row['solarSystemID'] 856 if not requireLocalizedTexts: 857 return '' 858 if row['useOperationName']: 859 labelPath = 'UI/Locations/LocationNPCStationFormatter' 860 operationName = get_station_operation_name(row['operationID']) 861 operationNameEN = get_station_operation_name(row['operationID'], localization.const.LOCALE_SHORT_ENGLISH) 862 else: 863 labelPath = 'UI/Locations/LocationNPCStationFormatter_NoOpName' 864 operationName = '' 865 operationNameEN = '' 866 locName = localization.GetByLabel(labelPath, orbitID=orbitID, corporationID=row['ownerID'], operationName=operationName) 867 locNameEN = localization.GetByLabel(labelPath, localization.const.LOCALE_SHORT_ENGLISH, orbitID=orbitID, corporationID=row['ownerID'], operationName=operationNameEN) 868 return localization.FormatImportantString(locName, locNameEN) 869 870 def GetNpcStationName(self, stationID, solarSystemID, ownerID, operationID, languageID = None): 871 celestialIndex, orbitIndex, useOperationName = self.stationLocalizationData[stationID] 872 if celestialIndex is None: 873 orbit_name = None 874 elif orbitIndex is not None: 875 orbit_name = localization.GetByLabel('UI/Locations/LocationMoonFormatter', solarSystemID=solarSystemID, romanCelestialIndex=formatUtil.IntToRoman(celestialIndex), orbitIndex=orbitIndex, languageID=languageID) 876 else: 877 orbit_name = localization.GetByLabel('UI/Locations/LocationPlanetFormatter', solarSystemID=solarSystemID, romanCelestialIndex=formatUtil.IntToRoman(celestialIndex), languageID=languageID) 878 corp = self.eveowners.Get(ownerID) 879 corp_name = corp.GetRawName(languageID=languageID) 880 operation_name = get_station_operation_name(operationID, languageID) 881 if useOperationName: 882 return localization.GetByLabel(LOCATION_NPC_STATION_FORMATTER_RAW, orbitName=orbit_name, npcOrganizationName=corp_name, operationName=operation_name) 883 return localization.GetByLabel(LOCATION_NPC_STATION_FORMATTER_NO_OP_NAME_RAW, orbitName=orbit_name, npcOrganizationName=corp_name) 884 885 @telemetry.ZONE_METHOD 886 def _GetCelestialNameDataFromLocalRow(self, row): 887 celestialGroupID = row['groupID'] 888 celestialNameID = row['celestialNameID'] 889 celestialNameData = (None, None) 890 if celestialNameID is not None and celestialGroupID != const.groupStargate: 891 celestialNameData = ('UI/Util/GenericText', {'text': celestialNameID}) 892 elif celestialGroupID == const.groupAsteroidBelt: 893 celestialNameData = ('UI/Locations/LocationAsteroidBeltFormatter', {'solarSystemID': row['solarSystemID'], 894 'romanCelestialIndex': formatUtil.IntToRoman(row['celestialIndex']), 895 'typeID': row['typeID'], 896 'orbitIndex': row['orbitIndex']}) 897 elif celestialGroupID == const.groupMoon: 898 celestialNameData = ('UI/Locations/LocationMoonFormatter', {'solarSystemID': row['solarSystemID'], 899 'romanCelestialIndex': formatUtil.IntToRoman(row['celestialIndex']), 900 'orbitIndex': row['orbitIndex']}) 901 elif celestialGroupID == const.groupPlanet: 902 celestialNameData = ('UI/Locations/LocationPlanetFormatter', {'solarSystemID': row['solarSystemID'], 903 'romanCelestialIndex': formatUtil.IntToRoman(row['celestialIndex'])}) 904 elif celestialGroupID == const.groupStargate: 905 celestialNameData = ('UI/Locations/LocationStargateFormatter', {'destinationSystemID': row['celestialNameID']}) 906 elif celestialGroupID == const.groupSun: 907 celestialNameData = ('UI/Locations/LocationStarFormatter', {'solarSystemID': row['solarSystemID']}) 908 return celestialNameData 909 910 @telemetry.ZONE_METHOD 911 def GetCelestialNameFromLocalRow(self, row, requireLocalizedTexts = True): 912 if not requireLocalizedTexts: 913 return '' 914 lbl, kwargs = self._GetCelestialNameDataFromLocalRow(row) 915 if lbl: 916 return localization.GetByLabel(lbl, **kwargs) 917 918 def ReloadLocalizedNames(self): 919 self.LoadEveOwners() 920 self.LoadEveLocations() 921 922 def GetShipGroupByClassType(self): 923 try: 924 return self.shipGroupByClassType 925 except AttributeError: 926 self.shipGroupByClassType = {const.GROUP_CAPSULES: (const.groupCapsule,), 927 const.GROUP_FRIGATES: (const.groupShuttle, 928 const.groupRookieship, 929 const.groupFrigate, 930 const.groupAssaultFrigate, 931 const.groupCovertOps, 932 const.groupElectronicAttackShips, 933 const.groupPrototypeExplorationShip, 934 const.groupInterceptor, 935 const.groupStealthBomber, 936 const.groupExpeditionFrigate, 937 const.groupLogisticsFrigate), 938 const.GROUP_DESTROYERS: (const.groupDestroyer, 939 const.groupInterdictor, 940 const.groupTacticalDestroyer, 941 const.groupCommandDestroyer), 942 const.GROUP_CRUISERS: (const.groupCruiser, 943 const.groupStrategicCruiser, 944 const.groupCombatReconShip, 945 const.groupForceReconShip, 946 const.groupHeavyAssaultCruiser, 947 const.groupHeavyInterdictors, 948 const.groupLogistics, 949 const.groupFlagCruiser, 950 const.groupSpecialEditionYacht), 951 const.GROUP_BATTLECRUISERS: (const.groupBattlecruiser, 952 const.groupAttackBattlecruiser, 953 const.groupCommandShip, 954 const.groupExpeditionCommandShip), 955 const.GROUP_BATTLESHIPS: (const.groupBattleship, const.groupBlackOps, const.groupMarauders), 956 const.GROUP_CAPITALSHIPS: (const.groupCarrier, 957 const.groupCommandCarrier, 958 const.groupCapitalIndustrialShip, 959 const.groupDreadnought, 960 const.groupTitan, 961 const.groupSupercarrier, 962 const.groupForceAux, 963 const.groupLancerDreadnought), 964 const.GROUP_INDUSTRIALS: (const.groupBlockadeRunner, 965 const.groupExhumer, 966 const.groupFreighter, 967 const.groupIndustrial, 968 const.groupIndustrialCommandShip, 969 const.groupJumpFreighter, 970 const.groupMiningBarge, 971 const.groupTransportShip), 972 const.GROUP_POS: tuple((groupID for groupID in evetypes.GetGroupIDsByCategory(const.categoryStarbase))), 973 const.GROUP_STRUCTURES: tuple((groupID for groupID in evetypes.GetGroupIDsByCategory(const.categoryStructure)))} 974 975 return self.shipGroupByClassType 976 977 def GetShipClassTypeByGroupID(self, groupID): 978 for classTypeID, groupIDs in self.GetShipGroupByClassType().iteritems(): 979 if groupID in groupIDs: 980 return classTypeID 981 982 983 eveConfig = EveConfig() 984 985 def GetStrippedEnglishMessage(messageID): 986 msg = localization._GetRawByMessageID(messageID, 'en-us') 987 if msg: 988 regex = '</localized>|<localized>|<localized .*?>|<localized *=.*?>' 989 return ''.join(re.split(regex, msg)) 990 else: 991 return '' 992 993 994 def CfgFsdDustIcons(): 995 return cfg.fsdDustIcons 996 997 998 def CfgAverageMarketPrice(): 999 return cfg._averageMarketPrice 1000 1001 1002 class Region(sysCfg.Row): 1003 __guid__ = 'eveCfg.Region' 1004 __slots__ = tuple() 1005 1006 def __getattr__(self, name): 1007 if name == 'regionName': 1008 if self.regionID < const.mapWormholeRegionMin: 1009 return sysCfg.Row.__getattr__(self, 'regionName') 1010 else: 1011 return 'Unknown' 1012 return sysCfg.Row.__getattr__(self, name) 1013 1014 def __str__(self): 1015 return 'Region ID: %d, name: %s' % (self.regionID, self.regionName) 1016 1017 1018 class Constellation(sysCfg.Row): 1019 __guid__ = 'eveCfg.Constellation' 1020 __slots__ = tuple() 1021 1022 def __getattr__(self, name): 1023 if name == 'constellationName': 1024 if self.constellationID < const.mapWormholeConstellationMin: 1025 return sysCfg.Row.__getattr__(self, 'constellationName') 1026 else: 1027 return 'Unknown' 1028 return sysCfg.Row.__getattr__(self, name) 1029 1030 def __str__(self): 1031 return 'Constellation ID: %d, name: %s' % (self.constellationID, self.constellationName) 1032 1033 1034 class SolarSystem(sysCfg.Row): 1035 __guid__ = 'eveCfg.SolarSystem' 1036 __slots__ = tuple() 1037 1038 def __getattr__(self, name): 1039 if name == 'pseudoSecurity': 1040 value = sysCfg.Row.__getattr__(self, 'security') 1041 if value > 0.0 and value < 0.05: 1042 return 0.05 1043 else: 1044 return value 1045 return sysCfg.Row.__getattr__(self, name) 1046 1047 def __str__(self): 1048 return 'SolarSystem ID: %d, name: %s' % (self.solarSystemID, self.solarSystemName) 1049 1050 1051 def StackSize(item): 1052 if item[const.ixQuantity] < 0: 1053 return 1 1054 return item[const.ixQuantity] 1055 1056 1057 def Singleton(item): 1058 if item[const.ixQuantity] < 0: 1059 return -item[const.ixQuantity] 1060 if 30000000 <= item[const.ixLocationID] < 40000000: 1061 return 1 1062 return 0 1063 1064 1065 def CheckShipHasFighterBay(shipID): 1066 item = sm.GetService('godma').GetItem(shipID) 1067 if not item: 1068 return False 1069 godmaSM = sm.GetService('godma').GetStateManager() 1070 return godmaSM.GetType(item.typeID).fighterCapacity > 0 1071 1072 1073 def IsPreviewable(typeID): 1074 if not evetypes.Exists(typeID): 1075 return False 1076 if IsApparel(typeID): 1077 return True 1078 if IsShipSkin(typeID): 1079 return True 1080 if evetypes.GetGraphicID(typeID) is None: 1081 return False 1082 return evetypes.GetCategoryID(typeID) in const.previewCategories or evetypes.GetGroupID(typeID) in const.previewGroups 1083 1084 1085 def IsShip(typeID): 1086 if not evetypes.Exists(typeID): 1087 return False 1088 return evetypes.GetCategoryID(typeID) == const.categoryShip 1089 1090 1091 def IsShipSkin(typeID): 1092 if not evetypes.Exists(typeID): 1093 return False 1094 return evetypes.GetCategoryID(typeID) == const.categoryShipSkin 1095 1096 1097 def IsApparel(typeID): 1098 if not evetypes.Exists(typeID): 1099 return False 1100 return evetypes.GetCategoryID(typeID) == const.categoryApparel 1101 1102 1103 def IsBlueprint(typeID): 1104 if not evetypes.Exists(typeID): 1105 return False 1106 return evetypes.GetCategoryID(typeID) == const.categoryBlueprint 1107 1108 1109 def IsPlaceable(typeID): 1110 if not evetypes.Exists(typeID): 1111 return False 1112 return evetypes.GetCategoryID(typeID) == const.categoryPlaceables 1113 1114 1115 def GetCharacterType(characterID): 1116 if idCheckers.IsEveUser(characterID): 1117 return 'capsuleer' 1118 else: 1119 return 'unknown' 1120 1121 1122 def IsOutlawStatus(securityStatus): 1123 if securityStatus is None: 1124 return False 1125 else: 1126 return round(securityStatus, 1) <= const.outlawSecurityStatus 1127 1128 1129 OWNER_NAME_OVERRIDES = {OWNER_AURA_IDENTIFIER: 'UI/Agents/AuraAgentName', 1130 OWNER_SYSTEM_IDENTIFIER: 'UI/Chat/ChatEngine/EveSystem'} 1131 1132 class EveOwners(sysCfg.Row): 1133 __guid__ = 'cfg.EveOwners' 1134 __slots__ = tuple() 1135 1136 def __getattr__(self, name): 1137 if name == 'name' or name == 'description': 1138 name = 'ownerName' 1139 elif name == 'groupID': 1140 typeID = sysCfg.Row.__getattr__(self, 'typeID') 1141 if typeID is None: 1142 return 1143 return evetypes.GetGroupID(typeID) 1144 ownerNameID = sysCfg.Row.__getattr__(self, 'ownerNameID') 1145 if name == 'ownerName' and boot.role != 'client' and ownerNameID is not None: 1146 return localization.GetByMessageID(ownerNameID) 1147 return sysCfg.Row.__getattr__(self, name) 1148 1149 def __str__(self): 1150 return 'EveOwner ID: %d, "%s"' % (self.ownerID, self.ownerName) 1151 1152 def GetRawName(self, languageID = None): 1153 if self.ownerNameID is not None: 1154 if self.ownerNameID in OWNER_NAME_OVERRIDES: 1155 return localization.GetByLabel(OWNER_NAME_OVERRIDES[self.ownerNameID], languageID) 1156 return localization.GetByMessageID(self.ownerNameID, languageID) 1157 return self.name 1158 1159 def IsSystem(self): 1160 return self.ownerID <= 15 1161 1162 def IsNPC(self): 1163 return idCheckers.IsNPC(self.ownerID) 1164 1165 def IsCharacter(self): 1166 return self.groupID == const.groupCharacter 1167 1168 def IsCorporation(self): 1169 return self.groupID == const.groupCorporation 1170 1171 def IsAlliance(self): 1172 return self.typeID == const.typeAlliance 1173 1174 def IsFaction(self): 1175 return self.groupID == const.groupFaction 1176 1177 def Type(self): 1178 raise evetypes.TypeNotFoundException('Not supported anymore to get a whole type, please change the caller. Hint: you have self.typeID') 1179 1180 def Group(self): 1181 raise evetypes.TypeNotFoundException('Not supported anymore to get a whole group, please change the caller. Hint: you have self.groupID') 1182 1183 1184 class CrpTickerNames(sysCfg.Row): 1185 __guid__ = 'cfg.CrpTickerNames' 1186 __slots__ = tuple() 1187 1188 def __getattr__(self, name): 1189 if name == 'name' or name == 'description': 1190 return sysCfg.Row.__getattr__(self, 'tickerName') 1191 else: 1192 return sysCfg.Row.__getattr__(self, name) 1193 1194 def __str__(self): 1195 return 'CorpTicker ID: %d, "%s"' % (self.corporationID, self.tickerName) 1196 1197 1198 class AllShortNames(sysCfg.Row): 1199 __guid__ = 'cfg.AllShortNames' 1200 __slots__ = tuple() 1201 1202 def __getattr__(self, name): 1203 if name == 'name' or name == 'description': 1204 return sysCfg.Row.__getattr__(self, 'shortName') 1205 else: 1206 return sysCfg.Row.__getattr__(self, name) 1207 1208 def __str__(self): 1209 return 'AllianceShortName ID: %d, "%s"' % (self.allianceID, self.shortName) 1210 1211 1212 class EveLocations(sysCfg.Row): 1213 __guid__ = 'dbrow.Location' 1214 __slots__ = ('cachedLocationName',) 1215 1216 def __init__(self, header, line): 1217 sysCfg.Row.__init__(self, header, line) 1218 self.cachedLocationName = None 1219 1220 def __setattr__(self, name, value): 1221 if name in EveLocations.__slots__: 1222 object.__setattr__(self, name, value) 1223 else: 1224 sysCfg.Row.__setattr__(self, name, value) 1225 1226 def __getattr__(self, name): 1227 if name == 'name' or name == 'description' or name == 'locationName': 1228 if self.cachedLocationName is not None: 1229 return self.cachedLocationName 1230 locationName = sysCfg.Row.__getattr__(self, 'locationName') 1231 if boot.role == 'client' and idCheckers.IsAbyssalSpaceSystem(self.locationID): 1232 locationName = localization.GetByLabel('UI/Common/Unknown') 1233 elif (locationName is None or len(locationName) == 0) and self.locationNameID is not None: 1234 if isinstance(self.locationNameID, (int, long)): 1235 locationName = localization.GetImportantByMessageID(self.locationNameID) 1236 elif isinstance(self.locationNameID, tuple): 1237 locationName = localization.GetImportantByLabel(self.locationNameID[0], **self.locationNameID[1]) 1238 if boot.role == 'client': 1239 self.cachedLocationName = locationName 1240 elif boot.role != 'client' and self.locationNameID is not None: 1241 locationName = localization.GetByMessageID(self.locationNameID) 1242 return locationName 1243 return sysCfg.Row.__getattr__(self, name) 1244 1245 def __str__(self): 1246 return 'EveLocation ID: %d, "%s"' % (self.locationID, self.locationName) 1247 1248 def GetRawName(self, languageID = None): 1249 if self.locationNameID is not None: 1250 return localization.GetByMessageID(self.locationNameID, languageID) 1251 if self.locationID in cfg.rawCelestialCache: 1252 lbl, kwargs = cfg.rawCelestialCache[self.locationID] 1253 return localization.GetByLabel(lbl, languageID, **kwargs) 1254 return self.name 1255 1256 def Station(self): 1257 return cfg.GetSvc('stationSvc').GetStation(self.id) 1258 1259 1260 class RamCompletedStatus(sysCfg.Row): 1261 __guid__ = 'cfg.RamCompletedStatus' 1262 __slots__ = tuple() 1263 1264 def __getattr__(self, name): 1265 if name == 'name': 1266 name = 'completedStatusText' 1267 value = sysCfg.Row.__getattr__(self, name) 1268 if name == 'completedStatusText': 1269 value = localization.GetByMessageID(self.completedStatusTextID) 1270 elif name == 'description': 1271 return localization.GetByMessageID(self.descriptionID) 1272 return value 1273 1274 def __str__(self): 1275 try: 1276 return 'RamCompletedStatus ID: %d, "%s"' % (self.completedStatus, self.completedStatusText) 1277 except: 1278 sys.exc_clear() 1279 return 'RamCompletedStatus containing crappy data' 1280 1281 1282 class RamActivity(sysCfg.Row): 1283 __guid__ = 'cfg.RamActivity' 1284 __slots__ = tuple() 1285 1286 def __getattr__(self, name): 1287 if name in ('activityName', 'name'): 1288 return localization.GetByMessageID(self.activityNameID) 1289 if name == 'description': 1290 return localization.GetByMessageID(self.descriptionID) 1291 return sysCfg.Row.__getattr__(self, name) 1292 1293 def __str__(self): 1294 try: 1295 return 'RamActivity ID: %d, "%s"' % (self.activityID, self.activityName) 1296 except: 1297 sys.exc_clear() 1298 return 'RamActivity containing crappy data' 1299 1300 1301 class OverviewDefault(sysCfg.Row): 1302 __guid__ = 'eveCfg.OverviewDefault' 1303 __slots__ = tuple() 1304 1305 def __getattr__(self, name): 1306 if name == '_overviewName': 1307 return sysCfg.Row.__getattr__(self, 'overviewName') 1308 if name in ('name', 'overviewName'): 1309 return localization.GetByMessageID(self.overviewNameID) 1310 value = sysCfg.Row.__getattr__(self, name) 1311 return value 1312 1313 def __str__(self): 1314 return 'DefaultOverview ID: %d, "%s"' % (self.overviewID, self.overviewName) 1315 1316 1317 class Position(sysCfg.Row): 1318 __guid__ = 'cfg.Position' 1319 __slots__ = tuple() 1320 1321 @property 1322 def latitude(self): 1323 return self.x 1324 1325 @property 1326 def longitude(self): 1327 return self.y 1328 1329 @property 1330 def radius(self): 1331 return self.z 1332 1333 1334 def _LoadMessagesFromFSD(): 1335 return fsdBinaryLoader.LoadFSDDataForCFG('res:/staticdata/dialogs.static', 'res:/staticdata/dialogs.schema', optimize=False) 1336 1337 1338 def IsPolarisFrigate(typeID): 1339 return typeID in (const.typePolarisCenturion, 1340 const.typePolarisCenturionFrigate, 1341 const.typePolarisInspectorFrigate, 1342 const.typePolarisLegatusFrigate, 1343 const.typePolarisEnigmaFrigate) 1344 1345 1346 def MakeConstantName(val, prefix): 1347 name = val.replace(' ', '') 1348 if name == '': 1349 name = 'invalidName_' + val 1350 name = prefix + name[0].upper() + name[1:] 1351 ret = '' 1352 okey = range(ord('a'), ord('z') + 1) + range(ord('A'), ord('Z') + 1) + range(ord('0'), ord('9') + 1) 1353 for ch in name: 1354 if ord(ch) in okey: 1355 ret += ch 1356 1357 if ret == '': 1358 ret = 'invalidName_' + ret 1359 elif ord(ret[0]) in range(ord('0'), ord('9') + 1): 1360 ret = '_' + ret 1361 return ret 1362 1363 1364 locationPathByFlagID = {const.flagCargo: 'UI/Ship/CargoHold', 1365 const.flagDroneBay: 'UI/Ship/DroneBay', 1366 const.flagShipHangar: 'UI/Ship/ShipMaintenanceBay', 1367 const.flagSpecializedFuelBay: 'UI/Ship/FuelBay', 1368 const.flagGeneralMiningHold: 'UI/Ship/GeneralMiningHold', 1369 const.flagSpecializedIceHold: 'UI/Ship/IceHold', 1370 const.flagSpecialAsteroidHold: 'UI/Ship/AsteroidHold', 1371 const.flagSpecializedGasHold: 'UI/Ship/GasHold', 1372 const.flagSpecializedMineralHold: 'UI/Ship/MineralHold', 1373 const.flagSpecializedSalvageHold: 'UI/Ship/SalvageHold', 1374 const.flagSpecializedShipHold: 'UI/Ship/ShipHold', 1375 const.flagSpecializedSmallShipHold: 'UI/Ship/SmallShipHold', 1376 const.flagSpecializedMediumShipHold: 'UI/Ship/MediumShipHold', 1377 const.flagSpecializedLargeShipHold: 'UI/Ship/LargeShipHold', 1378 const.flagSpecializedIndustrialShipHold: 'UI/Ship/IndustrialShipHold', 1379 const.flagSpecializedAmmoHold: 'UI/Ship/AmmoHold', 1380 const.flagSpecializedCommandCenterHold: 'UI/Ship/CommandCenterHold', 1381 const.flagSpecializedPlanetaryCommoditiesHold: 'UI/Ship/PlanetaryCommoditiesHold', 1382 const.flagSpecializedMaterialBay: 'UI/Ship/MaterialBay', 1383 const.flagFighterBay: 'UI/Ship/FighterBay', 1384 const.flagFrigateEscapeBay: 'UI/Ship/FrigateEscapeBay'} 1385 1386 def GetShipFlagLocationName(flagID): 1387 if flagID in const.hiSlotFlags: 1388 locationPath = 'UI/Ship/HighSlot' 1389 elif flagID in const.medSlotFlags: 1390 locationPath = 'UI/Ship/MediumSlot' 1391 elif flagID in const.loSlotFlags: 1392 locationPath = 'UI/Ship/LowSlot' 1393 elif flagID in const.rigSlotFlags: 1394 locationPath = 'UI/Ship/RigSlot' 1395 elif IsSubsystemFlagVisible(flagID): 1396 locationPath = 'UI/Ship/Subsystem' 1397 elif flagID in const.flagCorpSAGs: 1398 locationPath = 'UI/Corporations/Common/CorporateHangar' 1399 elif flagID in const.fighterTubeFlags: 1400 locationPath = 'UI/Ship/FighterLaunchTube' 1401 else: 1402 locationPath = locationPathByFlagID.get(flagID, '') 1403 if locationPath: 1404 return localization.GetByLabel(locationPath) 1405 else: 1406 return '' 1407 1408 1409 def GetSunWarpInPoint(ballID, position, radius): 1410 offset = 100000 1411 x = position[0] + (radius + offset) * math.cos(radius) 1412 y = position[1] + radius / 5 1413 z = position[2] - (radius + offset) * math.sin(radius) 1414 return (x, y, z) 1415 1416 1417 def GetPlanetWarpInPoint(ballID, position, radius): 1418 dx = float(position[0]) 1419 dz = float(-position[2]) 1420 f = float(dz) / float(math.sqrt(dx ** 2 + dz ** 2)) 1421 if dz > 0 and dx > 0 or dz < 0 and dx > 0: 1422 f *= -1.0 1423 theta = math.asin(f) 1424 myRandom = random.Random(ballID) 1425 rr = (myRandom.random() - 1.0) / 3.0 1426 theta += rr 1427 offset = 1000000 1428 FACTOR = 20.0 1429 dd = math.pow((FACTOR - 5.0 * math.log10(radius / 1000000) - 0.5) / FACTOR, FACTOR) * FACTOR 1430 dd = min(10.0, max(0.0, dd)) 1431 dd += 0.5 1432 offset += radius * dd 1433 d = radius + offset 1434 x = 1000000 1435 z = 0 1436 x = position[0] + math.sin(theta) * d 1437 y = position[1] + radius * math.sin(rr) * 0.5 1438 z = position[2] - math.cos(theta) * d 1439 return (x, y, z) 1440 1441 1442 def GetWarpInPoint(ballID, position, radius): 1443 offset = 5000000 1444 p = const.jumpRadiusFactor / 100.0 1445 x = position[0] + (radius + offset) * math.cos(radius) 1446 y = position[1] + p * radius - 7500.0 1447 z = position[2] - (radius + offset) * math.sin(radius) 1448 return (x, y, z) 1449 1450 1451 def GetActiveShip(): 1452 return session.shipid 1453 1454 1455 def InSpace(): 1456 return bool(session.solarsystemid) and bool(session.shipid) and session.structureid in (session.shipid, None) 1457 1458 1459 def InShip(): 1460 return bool(session.shipid) and bool(session.shipid != session.structureid) 1461 1462 1463 def InShipInSpace(): 1464 return bool(session.solarsystemid) and bool(session.shipid) and not bool(session.structureid) 1465 1466 1467 def IsDocked(): 1468 return bool(session.stationid) or IsDockedInStructure() 1469 1470 1471 def InStructure(): 1472 return bool(session.structureid) 1473 1474 1475 def IsDockedInStructure(): 1476 return bool(session.structureid) and bool(session.structureid != session.shipid) 1477 1478 1479 def IsControllingStructure(): 1480 return bool(session.structureid) and bool(session.structureid == session.shipid) 1481 1482 1483 def IsAtLocation(locationID): 1484 if locationID is None: 1485 return False 1486 elif InStructure(): 1487 return locationID == session.structureid 1488 else: 1489 return locationID == session.locationid 1490 1491 1492 def IsBookmarkModerator(corpRole): 1493 return corpRole & const.corpRoleChatManager == const.corpRoleChatManager