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

insider.py (85792B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\devtools\script\insider.py
      2 from __future__ import print_function
      3 import eveformat
      4 import serverInfo
      5 from agentinteraction.debugwindow import CareerAgentDebugWnd
      6 from carbon.common.script.sys import service, serviceConst
      7 from carbon.common.script.sys.serviceConst import ROLEMASK_ELEVATEDPLAYER, ROLE_GMH, ROLE_GML, ROLE_PROGRAMMER, ROLE_QA
      8 from carbon.common.script.util.format import FmtDate
      9 from carbonui.control.contextMenu.menuData import MenuData
     10 from carbonui.control.contextMenu.menuEntryData import MenuEntryData, MenuEntryDataCheckbox
     11 from carbonui.control.window import Window
     12 from carbonui.primitives.fill import Fill
     13 from clientsettings.setting import SessionSettingBool
     14 from carbonui.util.color import Color
     15 from eve.client.script.ui import eveColor
     16 from eve.client.script.ui.shared.mapView.mapViewSettings import useFakeMapColorData, mapDebugModeActive
     17 from eve.client.script.ui.skillTree.skillTreeDockablePanel import SkillTreeDockablePanel
     18 from eve.devtools.script.form_sounds import InsiderSoundPlayer
     19 from eve.devtools.script.form_viewer import BinkVideoViewer
     20 from eve.devtools.script.glow import GlowTestWindow
     21 from eve.devtools.script.mapEditor.mapEditorWnd import MapEditorWnd
     22 from eve.devtools.script.quasarHijackWnd import ServerRequestHijackWindow, ClientRequestHijackWindow
     23 from eve.devtools.script.svc_invtools import InvToolsWnd
     24 from eve.devtools.script.svc_settingsMgr import SettingsMgr
     25 from eve.devtools.script.type_browser import TypeBrowser
     26 from eve.devtools.script.warpVector import WarpVectorWnd
     27 from eveclientqatools.shaderDebugger import ShaderDebugger
     28 from eveclientqatools.textureViewer import TextureWindow
     29 from eveicon.client.browser import IconBrowserWindow
     30 from eve.devtools.script.menu_bar import MenuBar
     31 from eve.devtools.script.shipEmblems import ShipEmblemsTool
     32 from eve.devtools.script.uiAnimationTest import TestAnimationsWnd
     33 from eve.client.script.environment.spaceObject.nonInteractableObject import NonInteractableObject
     34 from carbonui.button.group import ButtonGroup
     35 from eve.client.script.ui.control.fileDialog import FileDialog
     36 from imagecaching.demo.image_cache_demo_window import ImageCacheDemoWindow
     37 from player_messaging.client.ui_message import message_player, prompt_player_fsd_dialog
     38 from eve.client.script.ui.cosmetics.ship.shipSKINRWindow import ShipSKINRWindow
     39 from eve.client.script.ui.cosmetics.structure.paintToolWnd import PaintToolWnd
     40 from eve.client.script.ui.omega.upsell.omegaUpsellWindow import OmegaUpsellWindow
     41 from eve.client.script.ui.omega.qa.clone_grade_wnd import CloneGradeQAWindow
     42 from eve.client.script.ui.util import uix
     43 from eve.client.script.ui.util.gradientEdit import GradientEditor
     44 from eve.client.script.ui.view.hangarView import HangarView
     45 from eve.common.script.sys import idCheckers
     46 from eve.devtools.script import localizationTools
     47 from eve.devtools.script.abyssal_content_tool import AbyssalContentToolWindow
     48 from eve.devtools.script.abyssal_npc_spawn_tool import AbyssalNpcSpawnToolWindow
     49 from eve.devtools.script.behaviortools.cluster_debugger import ClusterVisualizerWindow
     50 from eve.devtools.script.cameraTool import CameraTool
     51 from eve.devtools.script.colors import ColorPicker
     52 from eve.devtools.script.colorThemeEditor import ColorThemeEditor
     53 from eve.devtools.script.connectiontest import ConnectionLoopTest
     54 from eve.devtools.script.textStyleTest import TextStyleTest
     55 from eve.devtools.script.uiDebugger import UIDebugger
     56 from eve.devtools.script.uiEventListener import UIEventListener
     57 from eve.devtools.script.uiPerformanceTestWnd import UIPerformanceTestWnd
     58 from eve.devtools.script.uiScaling import UIScaling
     59 from eve.devtools.script.uiSpriteTest import UISpriteTest
     60 from eve.devtools.script.windowManager import WindowManager
     61 from inventorycommon import const as invconst
     62 import evetypes
     63 import blue
     64 import sys
     65 import os
     66 from eve.devtools.script.auto_bot_window import AutoBotWindow
     67 import eve.devtools.script.behaviortools.clientdebugadaptors
     68 import trinity
     69 import types
     70 import uthread
     71 import log
     72 import carbonui.const as uiconst
     73 import eveclientqatools.gfxpreviewer as gfxpreviewer
     74 import eveclientqatools.tablereports as gfxreports
     75 import eveclientqatools.corpseviewer as corpseviewer
     76 import eveclientqatools.blueobjectviewer as blueobjviewer
     77 from eveclientqatools import impactVisualizationWnd
     78 from eveclientqatools.environmentTemplateDebugger import EnvironmentTemplateDebugger
     79 from eveclientqatools.environmentTemplateSwitcher import EnvironmentTemplateSwitcher
     80 from eveclientqatools.moonMiningDebug import OpenMoonMiningDebugWindow
     81 from eveclientqatools.performancebenchmark import PerformanceBenchmarkWindow
     82 from eveclientqatools.skyBoxEffectDebugger import SkyBoxEffectDebugger
     83 from eveclientqatools.typevalidationtools import TypeValidationWindow
     84 from eve.devtools.script.uiControlCatalog.controlCatalogWindow import ControlCatalogWindow
     85 from eve.devtools.script.cycleNebulaPanel import CycleNebulaPanel
     86 from eve.devtools.script.renderjobprofiler import RenderJobProfiler
     87 import evegraphics.settings as gfxsettings
     88 from eveclientqatools.explosions import ExplosionDebugger
     89 from eveclientqatools.postProcessDebugger import OpenPostProcessDebugger
     90 from eve.devtools.script.tournamentRefereeTools import RefWindowSpawningWindow
     91 from eve.devtools.script.form_tournament import TournamentWindow
     92 from eve.devtools.script.sunwidget import SunWidgetWindow
     93 from eveclientqatools.audio import AudioActionLog, AudioPrioritizationDebugger, AudioPrioritizationIntrospectionDebugger, AudioEmitterDebugger, MusicDebugger, SoundbankDebugger, SoundPrioritizationConfiguration, SpatialAudioConfiguration
     94 from UITree import UITree
     95 from eve.devtools.script.enginetools import EngineToolsLauncher
     96 from eveexceptions import UserError
     97 from fsdBuiltData.common.graphicIDs import GetGraphicFile
     98 from fsdBuiltData.client.travelEffects import GetTravelEffectsGuids
     99 from eve.devtools.script.graphstest import TestGraph
    100 from carbonui.graphs.datafortesting import TogglePriceHistoryTestData
    101 from carbonui.uicore import uicore
    102 from eveservices.menu import StartMenuService
    103 from eveclientqatools.sofpreviewer.viewcontroller import SofPreviewerController
    104 from eveclientqatools.modelstatedebugger import ModelStateDebuggerController
    105 from carbonui.control.contextMenu.contextMenu import CreateMenuView
    106 from carbonui.control.contextMenu.menuDataFactory import CreateMenuDataFromRawTuples
    107 from maptags.client.repository import reset_map_tag_cache_signal
    108 from menu import MenuList
    109 import uihider
    110 from redeem.client.insider import get_insider_qa_menu
    111 from shipprogression.boarding_moment import qa as boarding_moment_qa
    112 from shipprogression.shipUnlockSvc import GetShipUnlockService
    113 FILE_BUNKERS = 'Bunkers.txt'
    114 FILE_ENTITIES = 'Entities.txt'
    115 FILE_GATES = 'GateTest.txt'
    116 FILE_STELLAR = 'StellarReport.txt'
    117 FILE_BELTS = 'BeltTest.txt'
    118 FILE_FWREPORT = 'FacWarReport.txt'
    119 ICON_VISIBILITY_ON = 'res:/UI/Texture/classes/insider/visibility_on_18.png'
    120 ICON_VISIBILITY_OFF = 'res:/UI/Texture/classes/insider/visibility_off_18.png'
    121 Progress = lambda title, text, current, total: sm.GetService('loading').ProgressWnd(title, text, current, total)
    122 qa_green_screen_setting = SessionSettingBool(False)
    123 
    124 class InsiderWnd(Window):
    125     default_top = 0
    126     default_left = '__center__'
    127     default_windowID = 'insider'
    128     default_iconNum = 'res:/UI/Texture/windowIcons/insider.png'
    129     default_isLightBackground = True
    130     default_isCompact = True
    131     default_apply_content_padding = False
    132 
    133     def ApplyAttributes(self, attributes):
    134         Window.ApplyAttributes(self, attributes)
    135         self.MakeUnResizeable()
    136         self.MakeUncollapseable()
    137         self.SetCaption('Insider')
    138         self.SetScope(uiconst.SCOPE_ALL)
    139 
    140     def _OnClose(self, *args):
    141         settings.public.ui.Set('Insider', False)
    142 
    143     def Reload(self, *args):
    144         pass
    145 
    146 
    147 class InsiderService(service.Service):
    148     __module__ = __name__
    149     __doc__ = 'Insider v2.0'
    150     __exportedcalls__ = {'Show': []}
    151     __guid__ = 'svc.insider'
    152     __servicename__ = 'insider'
    153     __displayname__ = 'Insider Service'
    154     __startupdependencies__ = ['stateSvc', 'uihider']
    155     __notifyevents__ = ['OnSessionChanged',
    156      'OnUIRefresh',
    157      'OnLoadScene',
    158      'OnViewStateChanged',
    159      'OnBallparkModelsLoaded']
    160 
    161     def __init__(self):
    162         super(InsiderService, self).__init__()
    163         self._res_live_reloader = None
    164         self.controlCatalogInstanceID = 0
    165         if self.IsResourceLiveReloadingAvailable():
    166             from eve.devtools.script.res_live_reload import ResLiveReloader
    167             self._res_live_reloader = ResLiveReloader()
    168 
    169     def Run(self, memStream = None):
    170         super(InsiderService, self).Run()
    171         self.UpdateResourceLiveReloader()
    172 
    173     def HealRemoveAllContainers(self):
    174         containers = [invconst.groupAuditLogSecureContainer,
    175          invconst.groupCargoContainer,
    176          invconst.groupFreightContainer,
    177          invconst.groupSecureCargoContainer,
    178          invconst.groupWreck]
    179         for entry in containers:
    180             self.HealRemove(entry)
    181 
    182     def HealRemove(self, type, group = True):
    183         targets = []
    184         bp = sm.GetService('michelle').GetBallpark()
    185         if bp:
    186             if group:
    187                 for ballID in bp.balls.keys():
    188                     item = bp.GetInvItem(ballID)
    189                     if item and item.groupID == type:
    190                         targets.append(item.itemID)
    191 
    192             else:
    193                 for ballID in bp.balls.keys():
    194                     item = bp.GetInvItem(ballID)
    195                     if item and item.categoryID == type:
    196                         if type == invconst.categoryStarbase:
    197                             if sm.GetService('pwn').GetStructureState(item)[0] == 'unanchored':
    198                                 targets.append(item.itemID)
    199                         elif type == invconst.categoryShip:
    200                             if not bp.GetBall(ballID).isInteractive:
    201                                 targets.append(item.itemID)
    202                         else:
    203                             targets.append(item.itemID)
    204 
    205             for itemID in targets:
    206                 sm.GetService('slash').SlashCmd('heal %d 0' % itemID)
    207 
    208             blue.pyos.synchro.SleepSim(250)
    209 
    210     def SlashBtnClick(self, cmd):
    211         return lambda : sm.GetService('slash').SlashCmd(cmd)
    212 
    213     def GetInsiderDir(self, *args):
    214         path = os.path.normpath(blue.sysinfo.GetUserDocumentsDirectory())
    215         path = os.path.join(path, 'EVE', 'insider')
    216         return path
    217 
    218     def GetTimestamp(self, *args):
    219         invalidChars = '\\/:*?"<>| '
    220         timestamp = FmtDate(blue.os.GetWallclockTime())
    221         for char in invalidChars:
    222             timestamp = timestamp.replace(char, '.')
    223 
    224         return timestamp
    225 
    226     def WaitOutSession(self, *args):
    227         if blue.os.GetSimTime() <= session.nextSessionChange:
    228             ms = 1000 + 1000 * (session.nextSessionChange - blue.os.GetSimTime()) / 10000000
    229             blue.pyos.synchro.SleepSim(ms)
    230 
    231     @staticmethod
    232     def MakeMenu(list, anchor):
    233         mv = CreateMenuView(CreateMenuDataFromRawTuples(list), None, None)
    234         anchorwindow = InsiderWnd.GetIfOpen()
    235         x = max(anchorwindow.GetChild(anchor).GetAbsolute()[0], 0)
    236         y = anchorwindow.top + anchorwindow.height
    237         if anchorwindow.top + anchorwindow.height + mv.height > uicore.desktop.height:
    238             mv.top = min(anchorwindow.top - mv.height, y)
    239         else:
    240             mv.top = min(uicore.desktop.width - mv.height, y)
    241         mv.left = min(uicore.desktop.width - mv.width, x)
    242         uicore.layer.menu.children.insert(0, mv)
    243 
    244     def TravelTo(self, destination, *args):
    245         try:
    246             sm.GetService('slash').SlashCmd('/tr me %s' % destination)
    247         except UserError as e:
    248             if e.msg == 'SystemCheck_TransferFailed_Loading':
    249                 prompt_player_fsd_dialog('CustomNotify', {'notify': 'Spooling up system. Please wait.'})
    250                 blue.pyos.synchro.SleepSim(10000)
    251                 sm.GetService('slash').SlashCmd('/tr me %s' % destination)
    252             sys.exc_clear()
    253 
    254     def TravelToLocation(self, destination, *args):
    255         if idCheckers.IsSolarSystem(destination):
    256             currentSys = session.solarsystemid2
    257             while currentSys != destination:
    258                 self.TravelTo(destination)
    259                 currentSys = session.solarsystemid2
    260 
    261         else:
    262             try:
    263                 self.TravelTo(destination)
    264             except UserError as e:
    265                 prompt_player_fsd_dialog('CustomNotify', {'notify': 'Spooling up system. Please wait.'})
    266                 blue.pyos.synchro.SleepSim(10000)
    267                 self.TravelTo(destination)
    268 
    269             sys.exc_clear()
    270 
    271     def RegionBunkerTest(self, positive = True, faction = 'All', *args):
    272         amarr = [10000036, 10000038]
    273         caldari = [10000033, 10000069]
    274         gallente = [10000064, 10000068, 10000048]
    275         minmatar = [10000030, 10000042]
    276         all = amarr + caldari + gallente + minmatar
    277         lookUp = {'amarr': amarr,
    278          'caldari': caldari,
    279          'gallente': gallente,
    280          'minmatar': minmatar,
    281          'all': all}
    282 
    283         def Populate(regionID):
    284             constellations = []
    285             systems = []
    286             constellations = sm.GetService('map').GetChildren(regionID)
    287             for sys in constellations:
    288                 systems += sm.GetService('map').GetChildren(sys)
    289 
    290             return systems
    291 
    292         allSystems = []
    293         systemsInFacWar = []
    294         systemsNotInFacWar = []
    295         if faction:
    296             regions = lookUp[faction.lower()]
    297             for region in regions:
    298                 allSystems += Populate(region)
    299 
    300             fwWarzoneSvc = sm.GetService('fwWarzoneSvc')
    301             for system in allSystems:
    302                 if fwWarzoneSvc.IsWarzoneSolarSystem(system):
    303                     systemsInFacWar.append(system)
    304                 else:
    305                     systemsNotInFacWar.append(system)
    306 
    307             if positive:
    308                 testSystems = systemsInFacWar
    309                 testType = 'Positive'
    310             else:
    311                 testSystems = systemsNotInFacWar
    312                 testType = 'Negative'
    313             testLength = len(testSystems)
    314             testMinutes = testLength / 2
    315             if prompt_player_fsd_dialog('CustomQuestion', {'header': 'Search for bunkers?',
    316              'question': 'Do you really want to search the region for bunkers? It is %d systems, and will take approximately %d minutes to run.' % (testLength, testMinutes)}, uiconst.YESNO) == uiconst.ID_YES:
    317                 filename = '%s.%s.%s.%s' % (self.GetTimestamp(),
    318                  faction,
    319                  testType,
    320                  FILE_BUNKERS)
    321                 TARGET = os.path.join(self.GetInsiderDir(), filename)
    322                 f = blue.classes.CreateInstance('blue.ResFile')
    323                 if not f.Open(TARGET, 0):
    324                     f.Create(TARGET)
    325                 f.Write('Bunker typeID\tBunker Name\tBunker itemID\tSystem Occupier\tSystem Sovereignty\tSystem Name\tSystem ID\tConstellation Name\tConstellation ID\tRegion Name\tRegion ID')
    326                 f.Write('\r\n')
    327                 for system in testSystems:
    328                     self.WaitOutSession()
    329                     self.TravelToLocation(system)
    330                     bunkers = []
    331                     blue.pyos.synchro.SleepSim(5000)
    332                     bp = sm.GetService('michelle').GetBallpark()
    333                     if bp:
    334                         for ballID in bp.balls.keys():
    335                             item = bp.GetInvItem(ballID)
    336                             if item and item.groupID in (invconst.groupControlBunker,):
    337                                 bunkers.append(item)
    338 
    339                     systemName = cfg.evelocations.Get(system).name
    340                     constellation = cfg.evelocations.Get(session.constellationid).name
    341                     region = cfg.evelocations.Get(session.regionid).name
    342                     systemSov = cfg.eveowners.Get(sm.RemoteSvc('stationSvc').GetSolarSystem(system).factionID).name
    343                     if bunkers:
    344                         for bunker in bunkers:
    345                             bunkertypeID = bunker.typeID
    346                             bunkerName = evetypes.GetName(bunkertypeID)
    347                             bunkeritemID = bunker.itemID
    348                             occupierID = sm.GetService('facwar').GetSystemOccupier(system)
    349                             systemOccupier = cfg.eveowners.Get(occupierID).name
    350                             f.Write('%s' % bunkertypeID)
    351                             f.Write('\t%s' % bunkerName.encode('utf8'))
    352                             f.Write('\t%s' % bunkeritemID)
    353                             f.Write('\t%s' % systemOccupier.encode('utf8'))
    354                             f.Write('\t%s' % systemSov.encode('utf8'))
    355                             f.Write('\t%s' % systemName.encode('utf8'))
    356                             f.Write('\t%s' % system)
    357                             f.Write('\t%s' % constellation.encode('utf8'))
    358                             f.Write('\t%s' % session.constellationid)
    359                             f.Write('\t%s' % region.encode('utf8'))
    360                             f.Write('\t%s' % session.regionid)
    361                             f.Write('\r\n')
    362 
    363                     else:
    364                         bunkertypeID = '-'
    365                         bunkerName = '-'
    366                         bunkeritemID = '-'
    367                         systemOccupier = '-'
    368                         f.Write('%s' % bunkertypeID)
    369                         f.Write('\t%s' % bunkerName.encode('utf8'))
    370                         f.Write('\t%s' % bunkeritemID)
    371                         f.Write('\t%s' % systemOccupier.encode('utf8'))
    372                         f.Write('\t%s' % systemSov.encode('utf8'))
    373                         f.Write('\t%s' % systemName.encode('utf8'))
    374                         f.Write('\t%s' % system)
    375                         f.Write('\t%s' % constellation.encode('utf8'))
    376                         f.Write('\t%s' % session.constellationid)
    377                         f.Write('\t%s' % region.encode('utf8'))
    378                         f.Write('\t%s' % session.regionid)
    379                         f.Write('\r\n')
    380 
    381         try:
    382             f.Close()
    383         except:
    384             sys.exc_clear()
    385 
    386     def EntitySpawn(self, label = None, chosenGroup = None, *args):
    387         entityDict = {}
    388         lootEntities = []
    389         respawnEntities = []
    390         if label:
    391             label = label.replace(' ', '_')
    392             label = label.replace("'", '')
    393         if chosenGroup.__class__ != list:
    394             chosenGroup = [chosenGroup]
    395         for group in chosenGroup:
    396             if evetypes.GetCategoryIDByGroup(group) in (invconst.categoryEntity,):
    397                 entityDict[group] = []
    398 
    399         for typeID in evetypes.GetTypeIDsByGroups(entityDict.keys()):
    400             entityDict[evetypes.GetGroupID(typeID)].append(typeID)
    401 
    402         for values in entityDict.itervalues():
    403             for typeID in values:
    404                 name = evetypes.GetName(typeID)
    405                 if not name.lower().__contains__('test'):
    406                     lootEntities.append(typeID)
    407 
    408         if prompt_player_fsd_dialog('CustomQuestion', {'header': 'Spawn NPCs?',
    409          'question': "Do you really want to spawn all those NPCs? It's quite alot (%d entities in %d groups)" % (len(lootEntities), len(entityDict))}, uiconst.YESNO) == uiconst.ID_YES:
    410             filename = '%s.%s.%s' % (self.GetTimestamp(), label, FILE_ENTITIES)
    411             TARGET = os.path.join(self.GetInsiderDir(), filename)
    412             f = blue.classes.CreateInstance('blue.ResFile')
    413             if not f.Open(TARGET, 0):
    414                 f.Create(TARGET)
    415             f.Write('Status\tLoot\tEmpty\tTypeID\tEntity Type\tWreck Type\tEntity Name\tWreck Name\tWreck State')
    416             f.Write('\r\n')
    417             for entity in lootEntities:
    418                 dudSpawn = False
    419                 if evetypes.GetIsGroupAnchoredByGroup(evetypes.GetGroupID(entity)):
    420                     respawnEntities.append(entity)
    421                     print('appended entity %s' % entity)
    422                     continue
    423                 else:
    424                     blue.pyos.synchro.SleepSim(1000)
    425                     sm.GetService('slash').SlashCmd('/entity deploy 10 %d' % entity)
    426                 blue.pyos.synchro.SleepSim(1000)
    427                 sm.GetService('slash').SlashCmd('/nuke')
    428                 blue.pyos.synchro.SleepSim(2000)
    429                 wrecks = []
    430                 count = 1000
    431                 while not wrecks and count:
    432                     count -= 1
    433                     bp = sm.GetService('michelle').GetBallpark()
    434                     for ballID in bp.balls.keys():
    435                         item = bp.GetInvItem(ballID)
    436                         if item and item.groupID in (invconst.groupWreck, invconst.groupCargoContainer):
    437                             wrecks.append(item.itemID)
    438 
    439                 if not wrecks:
    440                     blue.pyos.synchro.SleepSim(5000)
    441                     bp = sm.GetService('michelle').GetBallpark()
    442                     for ballID in bp.balls.keys():
    443                         item = bp.GetInvItem(ballID)
    444                         if item and item.groupID in (invconst.groupWreck, invconst.groupCargoContainer):
    445                             wrecks.append(item.itemID)
    446 
    447                 if not wrecks:
    448                     dudSpawn = True
    449                 emptyWreck = int()
    450                 okWreck = int()
    451                 entityType = evetypes.GetGroupName(entity)
    452                 entityName = evetypes.GetName(entity)
    453                 idealWreckName = '%s Wreck' % entityName
    454                 if not dudSpawn:
    455                     actualWreckName = 'None'
    456                     for wreckID in wrecks:
    457                         empty = self.stateSvc.CheckWreckEmpty(bp.GetInvItem(wreckID))
    458                         if empty:
    459                             emptyWreck += 1
    460                         else:
    461                             okWreck += 1
    462                         actualWreckName = cfg.evelocations.Get(wreckID).name
    463                         wreckType = evetypes.GetName(sm.GetService('michelle').GetBallpark().GetInvItem(wreckID).typeID)
    464 
    465                     wreckNameState = 'Error'
    466                     if idealWreckName == actualWreckName:
    467                         wreckNameState = 'OK'
    468                     try:
    469                         if okWreck > emptyWreck:
    470                             f.Write('OK')
    471                             f.Write('\t%s' % okWreck)
    472                             f.Write('\t%s' % emptyWreck)
    473                             f.Write('\t%s' % entity)
    474                             f.Write('\t%s' % entityType.encode('utf8'))
    475                             f.Write('\t%s' % wreckType.encode('utf8'))
    476                             f.Write('\t%s' % entityName.encode('utf8'))
    477                             f.Write('\t%s' % actualWreckName.encode('utf8'))
    478                             f.Write('\t%s' % wreckNameState)
    479                             f.Write('\r\n')
    480                         elif not okWreck:
    481                             f.Write('Critical')
    482                             f.Write('\t-\t-\t%s' % entity)
    483                             f.Write('\t%s' % entityType.encode('utf8'))
    484                             f.Write('\t%s' % wreckType.encode('utf8'))
    485                             f.Write('\t%s' % entityName.encode('utf8'))
    486                             f.Write('\t%s' % actualWreckName.encode('utf8'))
    487                             f.Write('\t%s' % wreckNameState)
    488                             f.Write('\r\n')
    489                         else:
    490                             f.Write('Warning')
    491                             f.Write('\t%s' % okWreck)
    492                             f.Write('\t%s' % emptyWreck)
    493                             f.Write('\t%s' % entity)
    494                             f.Write('\t%s' % entityType.encode('utf8'))
    495                             f.Write('\t%s' % wreckType.encode('utf8'))
    496                             f.Write('\t%s' % entityName.encode('utf8'))
    497                             f.Write('\t%s' % actualWreckName.encode('utf8'))
    498                             f.Write('\t%s' % wreckNameState)
    499                             f.Write('\r\n')
    500                     except:
    501                         sys.exc_clear()
    502                         f.Write('\r\n')
    503                         f.Write('Fail')
    504                         f.Write('\t-\t-\t%s' % entity)
    505                         f.Write('\t%s' % entityType.encode('utf8'))
    506                         f.Write('\t%s' % entityName.encode('utf8'))
    507                         f.Write('\r\n')
    508 
    509                 else:
    510                     f.Write('Null')
    511                     f.Write('\t-\t-\t%s' % entity)
    512                     f.Write('\t%s' % entityType.encode('utf8'))
    513                     f.Write('\t%s' % entityName.encode('utf8'))
    514                     f.Write('\tNone\tNone\tNone')
    515                     f.Write('\r\n')
    516                 self.HealRemove(invconst.groupWreck)
    517                 self.HealRemove(invconst.groupCargoContainer)
    518 
    519             if respawnEntities:
    520                 f.Write('\r\n')
    521                 f.Write('The following entities respawn over time and were not tested:')
    522                 f.Write('\r\n')
    523                 for entity in respawnEntities:
    524                     entityType = evetypes.GetGroupName(entity)
    525                     entityName = evetypes.GetName(entity)
    526                     f.Write('Unspawned')
    527                     f.Write('\t\t\t%s' % entity)
    528                     f.Write('\t%s' % entityType.encode('utf8'))
    529                     f.Write('\t%s' % entityName.encode('utf8'))
    530                     f.Write('\r\n')
    531 
    532         try:
    533             f.Close()
    534         except:
    535             sys.exc_clear()
    536 
    537     def RegionGateTest(self, constellation = None, *args):
    538 
    539         def Populate(areaOfInterest):
    540             data = {}
    541             systems = []
    542             mapSvc = sm.GetService('map')
    543             systemmapSvc = sm.GetService('systemmap')
    544             if areaOfInterest.__class__ != list:
    545                 areaOfInterest = [areaOfInterest]
    546             for constellation in areaOfInterest:
    547                 systems += mapSvc.GetChildren(constellation)
    548 
    549             for system in systems:
    550                 title = 'Examining Systems...'
    551                 systemName = cfg.evelocations.Get(system).name
    552                 constellationID = cfg.evelocations.Get(mapSvc.GetParent(system))
    553                 constellationName = cfg.evelocations.Get(constellationID).name
    554                 regionID = cfg.evelocations.Get(mapSvc.GetParent(constellationID.id))
    555                 regionName = cfg.evelocations.Get(regionID).name
    556                 text = '%s, %s, %s' % (systemName, constellationName, regionName)
    557                 Progress(title, text, systems.index(system), len(systems))
    558                 systemItems = systemmapSvc.GetSolarsystemData(system)
    559                 systemItems = systemItems.Index('itemID')
    560                 stargates = {}
    561                 for object in systemItems:
    562                     item = systemItems[object]
    563                     if evetypes.GetGroupID(item.typeID) in (invconst.groupStargate,):
    564                         stargates[item.itemName] = {'gateID': item.itemID,
    565                          'destGateID': item.destinations[0]}
    566 
    567                 data[system] = stargates
    568 
    569             Progress('Mapping Complete!', 'Done!', 1, 1)
    570             return data
    571 
    572         def Wait(count, *args):
    573             blue.pyos.synchro.SleepSim(count * 1000)
    574 
    575         sysCount = int()
    576         jumpCount = int()
    577         regionData = Populate(constellation)
    578         for k, v in regionData.iteritems():
    579             sysCount += 1
    580             jumpCount += len(v)
    581 
    582         approxDuration = jumpCount * 0.5
    583         if prompt_player_fsd_dialog('CustomQuestion', {'header': 'Travel the universe?',
    584          'question': 'Do you really want to visit all the gates in this region? It will take approximately %d minutes.' % approxDuration}, uiconst.YESNO) == uiconst.ID_YES:
    585             filename = '%s.%s.%s' % (self.GetTimestamp(), cfg.evelocations.Get(session.regionid).name, FILE_GATES)
    586             f = blue.classes.CreateInstance('blue.ResFile')
    587             TARGET = os.path.join(self.GetInsiderDir(), filename)
    588             if not f.Open(TARGET, 0):
    589                 f.Create(TARGET)
    590             gok = int()
    591             gfail = int()
    592             sok = int()
    593             sfail = int()
    594             stargates = []
    595             self.WaitOutSession()
    596             for system, gates in regionData.iteritems():
    597                 f.Write('%s' % cfg.evelocations.Get(system).name.encode('utf8'))
    598                 f.Write('\r\n')
    599                 for name, info in gates.iteritems():
    600                     sysdest = name.split('(')[1].split(')')[0]
    601                     f.Write('-> %s' % sysdest.encode('utf8'))
    602                     f.Write('\r\n')
    603                     sysdestID = sm.RemoteSvc('lookupSvc').LookupLocationsByGroup(invconst.groupSolarSystem, sysdest)
    604                     for each in sysdestID:
    605                         sysdestID = each.itemID
    606 
    607                     Wait(5)
    608                     self.TravelToLocation(system)
    609                     Wait(5)
    610                     bp = sm.GetService('michelle').GetBallpark()
    611                     for ballID in bp.balls.keys():
    612                         item = bp.GetInvItem(ballID)
    613                         if item and item.groupID in (invconst.groupStargate,):
    614                             stargates.append(item.itemID)
    615 
    616                     if info['gateID'] in stargates:
    617                         self.TravelToLocation(info['gateID'])
    618                         self.WaitOutSession()
    619                         Wait(5)
    620                         try:
    621                             sm.GetService('sessionMgr').PerformSessionChange('autopilot', sm.GetService('michelle').GetRemotePark().CmdStargateJump, info['gateID'], info['destGateID'], session.shipid)
    622                             Wait(10)
    623                         except:
    624                             sys.exc_clear()
    625                             f.Write('\t\tERROR: Jump failed')
    626                             f.Write('\r\n')
    627 
    628                     stargates = []
    629                     bp = sm.GetService('michelle').GetBallpark()
    630                     for ballID in bp.balls.keys():
    631                         item = bp.GetInvItem(ballID)
    632                         if item and item.groupID in (invconst.groupStargate,):
    633                             data = sm.GetService('tactical').GetEntryData(item, bp.GetBall(item.itemID))
    634                             distance = data.ball().surfaceDist
    635                             stargates.append(item.itemID)
    636 
    637                     if info['destGateID'] in stargates:
    638                         item = bp.GetInvItem(info['destGateID'])
    639                         distance = sm.GetService('tactical').GetEntryData(item, bp.GetBall(item.itemID)).ball().surfaceDist
    640                         if distance < 50000:
    641                             gok += 1
    642                             f.Write('\t\tGate: OK')
    643                             f.Write('\r\n')
    644                         else:
    645                             f.Write('\t\tGate: There, but distant')
    646                             f.Write('\r\n')
    647                     else:
    648                         gfail += 1
    649                         f.Write('\t\tGate: FAIL')
    650                         f.Write('\r\n')
    651                     if cfg.evelocations.Get(session.locationid).name == sysdest:
    652                         sok += 1
    653                         f.Write('\t\tSystem: OK')
    654                         f.Write('\r\n')
    655                     else:
    656                         sfail += 1
    657                         f.Write('\t\tSystem: FAIL')
    658                         f.Write('\r\n')
    659                     self.WaitOutSession()
    660 
    661                 f.Write('-----------------')
    662                 f.Write('\r\n')
    663 
    664             f.Write('Gates:')
    665             f.Write('\r\n')
    666             f.Write('\tOK: %s' % gok)
    667             f.Write('\r\n')
    668             f.Write('\tFAIL: %s' % gfail)
    669             f.Write('\r\n')
    670             f.Write('Systems:')
    671             f.Write('\r\n')
    672             f.Write('\tOK: %s' % sok)
    673             f.Write('\r\n')
    674             f.Write('\tFAIL: %s' % sfail)
    675             f.Write('\r\n')
    676             f.Close()
    677 
    678     def StoreRegionData(self, *args):
    679         constellations = []
    680         systems = []
    681         constellations = sm.GetService('map').GetChildren(session.regionid)
    682         for sys in constellations:
    683             systems += sm.GetService('map').GetChildren(sys)
    684 
    685         regionName = cfg.evelocations.Get(session.regionid).name
    686         filename = '%s.%s.%s' % (self.GetTimestamp(), regionName, FILE_STELLAR)
    687         f = blue.classes.CreateInstance('blue.ResFile')
    688         TARGET = os.path.join(self.GetInsiderDir(), filename)
    689         if not f.Open(TARGET, 0):
    690             f.Create(TARGET)
    691         f.Write('Object itemID\tObject typeID\tObject Type\tName\tLocation ID\tDestination\tx\ty\tz\tObject orbitID')
    692         f.Write('\r\n')
    693         for system in systems:
    694             title = 'Examining Systems...'
    695             systemName = cfg.evelocations.Get(system).name
    696             constellationID = cfg.evelocations.Get(sm.GetService('map').GetParent(system))
    697             constellationName = cfg.evelocations.Get(constellationID).name
    698             text = '%s, %s' % (systemName, constellationName)
    699             Progress(title, text, systems.index(system), len(systems))
    700             systemItems = sm.GetService('systemmap').GetSolarsystemData(system)
    701             for object in systemItems:
    702                 f.Write('%s' % object.itemID)
    703                 f.Write('\t%s' % object.typeID)
    704                 f.Write('\t%s' % evetypes.GetName(object.typeID).encode('utf8'))
    705                 f.Write('\t%s' % object.itemName.encode('utf8'))
    706                 f.Write('\t%s' % object.locationID)
    707                 f.Write('\t%s' % object.destinations.__str__())
    708                 f.Write('\t%g' % object.x)
    709                 f.Write('\t%g' % object.y)
    710                 f.Write('\t%g' % object.z)
    711                 f.Write('\t%s' % object.orbitID)
    712                 f.Write('\r\n')
    713 
    714         try:
    715             f.Close()
    716         except:
    717             sys.exc_clear()
    718 
    719         Progress('Mapping Complete!', 'Done!', 1, 1)
    720 
    721     def RegionBeltTest(self, constellation = None, *args):
    722 
    723         def Populate(areaOfInterest):
    724             systems = []
    725             belts = []
    726             if areaOfInterest.__class__ != list:
    727                 areaOfInterest = [areaOfInterest]
    728             for constellation in areaOfInterest:
    729                 systems += sm.GetService('map').GetChildren(constellation)
    730 
    731             for system in systems:
    732                 title = 'Examining Systems...'
    733                 systemName = cfg.evelocations.Get(system).name
    734                 constellationID = cfg.evelocations.Get(sm.GetService('map').GetParent(system))
    735                 constellationName = cfg.evelocations.Get(constellationID).name
    736                 regionID = cfg.evelocations.Get(sm.GetService('map').GetParent(constellationID.id))
    737                 regionName = cfg.evelocations.Get(regionID).name
    738                 text = '%s, %s, %s' % (systemName, constellationName, regionName)
    739                 Progress(title, text, systems.index(system), len(systems))
    740                 systemItems = sm.GetService('systemmap').GetSolarsystemData(system)
    741                 systemItems = systemItems.Index('itemID')
    742                 for object in systemItems:
    743                     item = systemItems[object]
    744                     if evetypes.GetGroupID(item.typeID) in (invconst.groupAsteroidBelt,):
    745                         belts.append(item.itemID)
    746 
    747             Progress('Mapping Complete!', 'Done!', 1, 1)
    748             return (belts, systems)
    749 
    750         def Wait(count, *args):
    751             blue.pyos.synchro.SleepSim(count * 1000)
    752 
    753         if not constellation:
    754             return
    755         regionBeltData, regionSystemData = Populate(constellation)
    756         sysCount = len(regionSystemData)
    757         approxDuration = sysCount * 0.5
    758         if prompt_player_fsd_dialog('CustomQuestion', {'header': 'Travel the universe?',
    759          'question': 'Do you really want to visit all the belts in this region? It will take approximately %d minutes.' % approxDuration}, uiconst.YESNO) == uiconst.ID_YES:
    760             filename = '%s.%s.%s' % (self.GetTimestamp(), cfg.evelocations.Get(session.regionid).name, FILE_BELTS)
    761             f = blue.classes.CreateInstance('blue.ResFile')
    762             TARGET = os.path.join(self.GetInsiderDir(), filename)
    763             if not f.Open(TARGET, 0):
    764                 f.Create(TARGET)
    765             asteroidGroups = []
    766             for groupID in evetypes.GetGroupIDsByCategory(invconst.categoryAsteroid):
    767                 asteroidGroups.append(groupID)
    768 
    769             f.Write('Solarsystem itemID\tSolarsystem Name\tBelt itemID\tBelt Name\tAsteroid Types Present')
    770             f.Write('\r\n')
    771             for belt in regionBeltData:
    772                 survey = []
    773                 try:
    774                     self.TravelToLocation(belt)
    775                 except:
    776                     sys.exc_clear()
    777                     self.WaitOutSession()
    778                     self.TravelToLocation(belt)
    779 
    780                 Wait(5)
    781                 bp = sm.GetService('michelle').GetBallpark()
    782                 gotBelt = False
    783                 bpCount = int()
    784                 while not gotBelt:
    785                     for ballID in bp.balls.keys():
    786                         item = bp.GetInvItem(ballID)
    787                         if item and item.itemID == belt:
    788                             gotBelt = True
    789                             break
    790 
    791                     bpCount += 1
    792                     if bpCount > 10:
    793                         break
    794                     Wait(5)
    795                     bp = sm.GetService('michelle').GetBallpark()
    796 
    797                 if gotBelt:
    798                     for ballID in bp.balls.keys():
    799                         item = bp.GetInvItem(ballID)
    800                         if item and item.groupID in asteroidGroups:
    801                             if survey.__contains__(item.typeID):
    802                                 pass
    803                             else:
    804                                 survey.append(item.typeID)
    805 
    806                     if not survey:
    807                         Wait(5)
    808                         bp = sm.GetService('michelle').GetBallpark()
    809                         for ballID in bp.balls.keys():
    810                             item = bp.GetInvItem(ballID)
    811                             if item and item.groupID in asteroidGroups:
    812                                 if survey.__contains__(item.typeID):
    813                                     pass
    814                                 else:
    815                                     survey.append(item.typeID)
    816 
    817                     survey.sort()
    818                     f.Write('%s' % session.locationid)
    819                     f.Write('\t%s' % cfg.evelocations.Get(session.solarsystemid2).name.encode('utf8'))
    820                     f.Write('\t%s' % belt)
    821                     f.Write('\t%s' % cfg.evelocations.Get(belt).name.encode('utf8'))
    822                     f.Write('\t')
    823                     for asteroid in survey:
    824                         f.Write('%s, ' % evetypes.GetName(asteroid).encode('utf8'))
    825 
    826                     f.Write('\r\n')
    827 
    828             try:
    829                 f.Close()
    830             except:
    831                 sys.exc_clear()
    832 
    833     def _V3TestingLoop(self, path):
    834         myShip = sm.GetService('michelle').GetBallpark().GetBall(session.shipid)
    835         myShip.model.display = False
    836         f = open(path, 'rt')
    837         fc = f.readlines()
    838         errorCount = 0
    839         i = 1
    840         scene = sm.StartService('sceneManager').GetRegisteredScene('default')
    841         if scene is not None:
    842             for li in fc:
    843                 log.LogError('LOADING ' + str(i) + ' of ' + str(len(fc)) + ' : ' + str(int(li)))
    844                 redFile = GetGraphicFile(int(li))
    845                 log.LogError(redFile)
    846                 if redFile is None:
    847                     errorCount += 1
    848                 else:
    849                     ship = trinity.Load(redFile)
    850                     scene.objects.append(ship)
    851                     blue.synchro.Sleep(2000)
    852                     scene.objects.remove(ship)
    853                 i += 1
    854 
    855         log.LogError('FINISHED V3 testing...')
    856         log.LogError('DETECTED at least ' + str(errorCount) + ' problems!')
    857         myShip.model.display = True
    858 
    859     def CycleNebulas(self, *args):
    860         CycleNebulaPanel(parent=uicore.layer.main, name='CycleNebulaPanel', caption='Cycle Nebulas')
    861 
    862     def _RenderJobProfiler(self, *args):
    863         RenderJobProfiler()
    864 
    865     def _CrashVideoDriver(self, *_):
    866         from trinity.crashdriver import crash
    867         uthread.new(crash)
    868 
    869     @property
    870     def _SofPreviewerViewController(self):
    871         if not hasattr(self, '__sofpreviewerViewController'):
    872             self.__sofpreviewerViewController = SofPreviewerController()
    873         return self.__sofpreviewerViewController
    874 
    875     def V3Testing(self, *args):
    876         log.LogError('Starting V3 testing...')
    877         dlgRes = FileDialog.SelectFiles(fileExtensions=['.txt'], multiSelect=False)
    878         if dlgRes is not None:
    879             scriptPath = dlgRes.Get('files')[0]
    880             log.LogWarn('script: ' + str(scriptPath))
    881             uthread.new(self._V3TestingLoop, str(scriptPath))
    882 
    883     def Automated(self, *args):
    884         allIDs = []
    885         usedIDs = []
    886         spawnMenu = MenuList()
    887         fw = MenuList()
    888         entitySpawnGroups = ['Asteroid Angel Cartel',
    889          'Asteroid Blood Raiders',
    890          'Asteroid Guristas',
    891          'Asteroid Rogue Drone',
    892          "Asteroid Sansha's Nation",
    893          'Asteroid Serpentis',
    894          'Deadspace Angel Cartel',
    895          'Deadspace Blood Raiders',
    896          'Deadspace Guristas',
    897          'Deadspace Overseer',
    898          'Deadspace Rogue Drone',
    899          "Deadspace Sansha's Nation",
    900          'Deadspace Serpentis',
    901          'Mission Amarr Empire',
    902          'Mission CONCORD',
    903          'Mission Caldari State',
    904          'Mission Drone',
    905          'Mission Gallente Federation',
    906          'Mission Generic',
    907          'Mission Khanid',
    908          'Mission Minmatar Republic',
    909          'Mission Mordu',
    910          'Mission Thukker',
    911          'Storyline',
    912          'Other']
    913         noLootEntities = [invconst.groupConcordDrone, invconst.groupFactionDrone, invconst.groupPoliceDrone]
    914         dontSpawn = [invconst.groupBillboard,
    915          invconst.groupSentryGun,
    916          invconst.groupCapturePointTower,
    917          invconst.groupProtectiveSentryGun,
    918          invconst.groupCustomsOfficial]
    919         entitiesDict = {}
    920         nameDict = {}
    921         entityByGroup = {}
    922         for groupID in evetypes.GetGroupIDsByCategory(invconst.categoryEntity):
    923             if groupID not in noLootEntities:
    924                 if groupID not in dontSpawn:
    925                     entitiesDict[groupID] = []
    926 
    927         for typeID in evetypes.GetTypeIDsByGroups(entitiesDict.keys()):
    928             entitiesDict[evetypes.GetGroupID(typeID)].append(typeID)
    929 
    930         for id in entitiesDict.iterkeys():
    931             nameDict[id] = [evetypes.GetGroupNameByGroup(id)]
    932 
    933         for group in entitySpawnGroups:
    934             for id, name in nameDict.iteritems():
    935                 if name[0].lower().startswith(group.lower()):
    936                     if group in entityByGroup:
    937                         entityByGroup[group].append(id)
    938                         usedIDs.append(id)
    939                         allIDs.append(id)
    940                     else:
    941                         entityByGroup[group] = [id]
    942                         usedIDs.append(id)
    943                         allIDs.append(id)
    944 
    945         for id in nameDict.iterkeys():
    946             if id not in usedIDs:
    947                 if 'Other' in entityByGroup:
    948                     entityByGroup['Other'].append(id)
    949                     allIDs.append(id)
    950                 else:
    951                     entityByGroup['Other'] = [id]
    952                     allIDs.append(id)
    953 
    954         for displayName, idList in entityByGroup.iteritems():
    955             spawnMenu.append((displayName, lambda label = displayName, ids = idList: self.EntitySpawn(label, ids)))
    956 
    957         spawnMenu.sort()
    958         spawnMenu.append(None)
    959         spawnMenu.append(('No loot entities', lambda label = 'noloot', ids = noLootEntities: self.EntitySpawn(label, ids)))
    960         spawnMenu.append(None)
    961         spawnMenu.append(('<color=0xffff8080>All', lambda label = 'All', ids = allIDs: self.EntitySpawn(label, ids)))
    962         if session.regionid:
    963             beltMenu = MenuList()
    964             constellationInRegion = cfg.mapRegionCache[session.regionid].constellationIDs
    965             for constellationID in constellationInRegion:
    966                 label = cfg.evelocations.Get(constellationID).name
    967                 beltMenu.append((label, lambda ids = constellationID: self.RegionBeltTest(ids)))
    968 
    969             beltMenu.sort()
    970             beltMenu.append(None)
    971             beltMenu.append(('<color=0xffff8080>All', lambda ids = constellationInRegion: self.RegionBeltTest(ids)))
    972             gateMenu = MenuList()
    973             for constellationID in constellationInRegion:
    974                 label = cfg.evelocations.Get(constellationID).name
    975                 gateMenu.append((label, lambda ids = constellationID: self.RegionGateTest(ids)))
    976 
    977             gateMenu.sort()
    978             gateMenu.append(None)
    979             gateMenu.append(('<color=0xffff8080>All', lambda ids = constellationInRegion: self.RegionGateTest(ids)))
    980             (fw.append(('FW Bunker Locations', [('Amarr - Positive', lambda : self.RegionBunkerTest(True, 'Amarr')),
    981                ('Amarr - Negative', lambda : self.RegionBunkerTest(False, 'Amarr')),
    982                None,
    983                ('Caldari - Positive', lambda : self.RegionBunkerTest(True, 'Caldari')),
    984                ('Caldari - Negative', lambda : self.RegionBunkerTest(False, 'Caldari')),
    985                None,
    986                ('Gallente - Positive', lambda : self.RegionBunkerTest(True, 'Gallente')),
    987                ('Gallente - Negative', lambda : self.RegionBunkerTest(False, 'Gallente')),
    988                None,
    989                ('Minmatar - Positive', lambda : self.RegionBunkerTest(True, 'Minmatar')),
    990                ('Minmatar - Negative', lambda : self.RegionBunkerTest(False, 'Minmatar')),
    991                None,
    992                ('<color=0xffff8080>All - Positive', lambda : self.RegionBunkerTest(True, 'All')),
    993                ('<color=0xffff8080>All - Negative', lambda : self.RegionBunkerTest(False, 'All'))])),)
    994             fw.append(None)
    995             fw.append(('NPC Loot Test', spawnMenu))
    996             fw.append(None)
    997             fw.append(('Belt Contents Survey', beltMenu))
    998             fw.append(('Gate Jump Test', gateMenu))
    999             fw.append(None)
   1000             fw.append(('Client ReConnection Loop', lambda : ConnectionLoopTest.Open()))
   1001             fw.append(None)
   1002             fw.append(('Stellar Objects Report', lambda : self.StoreRegionData()))
   1003             fw.append(None)
   1004             fw.append(('Spambot 2000', lambda : sm.GetService('cspam').Show()))
   1005             fw.append(None)
   1006             fw.append(('Type Validation', TypeValidationWindow.Open))
   1007         return fw
   1008 
   1009     def OnSessionChanged(self, isRemote, sess, change):
   1010         debugRenderJob = None
   1011         for job in trinity.renderJobs.recurring:
   1012             if job.name == 'DebugRender':
   1013                 debugRenderJob = job
   1014                 break
   1015 
   1016         if debugRenderJob:
   1017             trinity.renderJobs.recurring.remove(debugRenderJob)
   1018         AudioEmitterDebugger.EnableDebuggerInScene()
   1019 
   1020     def OnLoadScene(self, scene, key):
   1021         AudioEmitterDebugger.EnableDebuggerInScene()
   1022 
   1023     def OnBallparkModelsLoaded(self):
   1024         AudioEmitterDebugger.EnableDebuggerInScene()
   1025 
   1026     def OnViewStateChanged(self, oldView, newView):
   1027         AudioEmitterDebugger.EnableDebuggerInScene()
   1028 
   1029     def QAMenu(self, *args):
   1030         m = MenuList()
   1031         m.append(('Automated Tasks', self.Automated()))
   1032         m.append(None)
   1033 
   1034         def SetAntiAliasing(aaType):
   1035             gfxsettings.Set(gfxsettings.GFX_ANTI_ALIASING, aaType, False)
   1036             sm.ScatterEvent('OnGraphicSettingsChanged', [gfxsettings.GFX_ANTI_ALIASING])
   1037 
   1038         def ToggleGreenscreen():
   1039             qa_green_screen_setting.toggle()
   1040             scm = sm.GetService('sceneManager')
   1041             scene = scm.GetRegisteredScene('default')
   1042             scene.backgroundRenderingEnabled = not qa_green_screen_setting.is_enabled()
   1043             clearStep = scm.fisRenderJob.GetStep('CLEAR')
   1044             clearStep.color = (0, 1, 0, 1)
   1045 
   1046         def ToggleSceneGraphics():
   1047             scm = sm.GetService('sceneManager')
   1048             scene = scm.GetRegisteredScene('default')
   1049             rj = scm.fisRenderJob
   1050             rj.renderDriver.enableRendering = not rj.renderDriver.enableRendering
   1051 
   1052         def RemoveSun():
   1053             solarsystem = cfg.mapSolarSystemContentCache[session.solarsystemid]
   1054             sunID = solarsystem.star.id
   1055             sm.GetService('michelle').GetBall(sunID).Release()
   1056 
   1057         def EnableSpaceMouseInMaps():
   1058             from eve.client.script.ui.shared.mapView import mapViewNavigation
   1059             mapViewNavigation.spaceMouseSupportEnabled = True
   1060 
   1061         def ToggleNonInteractability():
   1062             m = sm.GetService('michelle')
   1063             bp = m.GetBallpark()
   1064             for ball, slim in bp.GetBallsAndItems():
   1065                 if isinstance(ball, NonInteractableObject) and hasattr(getattr(ball, 'model'), 'isPickable'):
   1066                     ball.model.isPickable = not ball.model.isPickable
   1067 
   1068         def SetLag(time):
   1069             time = float(time)
   1070             blue.os.slugTimeMinMs = time
   1071             blue.os.slugTimeMaxMs = time
   1072 
   1073         def SetReflectionProbe(use):
   1074             scm = sm.GetService('sceneManager')
   1075             scene = scm.GetActiveScene()
   1076             scene.reflectionProbe = trinity.Tr2ReflectionProbe() if use else None
   1077 
   1078         def CreateEffectOverrideLambda(guid):
   1079             return lambda : sm.GetService('subway').SetEffectOverride(guid)
   1080 
   1081         def CreateOverrideHangarSceneLambda(sceneType):
   1082             return lambda : HangarView.SetHangarOverride(sceneType)
   1083 
   1084         def ToggleDroneBehaviorSystem():
   1085             scm = sm.GetService('sceneManager')
   1086             scene = scm.GetActiveScene()
   1087             droneSystem = scene.objects.Find('trinity.EveChildBehaviorSystem')
   1088             for sys in droneSystem:
   1089                 sys.display = not sys.display
   1090 
   1091         def GetSceneVisulaizationMethods():
   1092             return {getattr(trinity.EveVisualizeMethod, n):n for n in dir(trinity.EveVisualizeMethod) if not callable(getattr(trinity.EveVisualizeMethod, n))}
   1093 
   1094         def SetSceneVisualizationCallback(value):
   1095 
   1096             def __inner__():
   1097                 sm.GetService('sceneManager').GetActiveScene().visualizeMethod = value
   1098                 sm.GetService('sceneManager').GetFisRenderJob().renderDriver.visualizeMethod = value
   1099 
   1100             return __inner__
   1101 
   1102         def GetSceneVisualization():
   1103             return sm.GetService('sceneManager').GetActiveScene().visualizeMethod
   1104 
   1105         m.append(('Audio', [('Audio Introspection', AudioActionLog.Open),
   1106           ('Music Debugger', MusicDebugger.Open),
   1107           ('Reload Soundbanks', SoundbankDebugger.Toggle),
   1108           ('%s Audio Emitters' % ['Show', 'Hide'][sm.GetService('audio').GetDebugDisplayAllEmitters()], AudioEmitterDebugger.Toggle),
   1109           ('%s Audio Prioritization' % ['Enable', 'Disable'][AudioPrioritizationDebugger.GetCullingEnabled()], AudioPrioritizationDebugger.Toggle),
   1110           ('Audio Emitter Priority', AudioPrioritizationIntrospectionDebugger.Open),
   1111           ('Sound Prioritization Configuration', SoundPrioritizationConfiguration.Open),
   1112           ('%s Spatial Audio' % ['Enable', 'Disable'][SpatialAudioConfiguration.GetSpatialAudioEnabled()], SpatialAudioConfiguration.Toggle)]))
   1113         m.append(('Graphics', [('Tools', (('Environment Template', (('Debugger', EnvironmentTemplateDebugger().ShowUI), ('Switcher', EnvironmentTemplateSwitcher().ShowUI))),
   1114             ('Explosions', ExplosionDebugger().ShowUI),
   1115             ('Moon Mining', OpenMoonMiningDebugWindow),
   1116             ('PostProcess', OpenPostProcessDebugger),
   1117             ('Sky Box Effect', SkyBoxEffectDebugger().ShowUI),
   1118             ('SOF Previewer', lambda : self._SofPreviewerViewController.ShowUI()),
   1119             ('Sun', lambda : SunWidgetWindow()),
   1120             ('Scene Debugging', [('Visualizations', [ (v + (' - Selected' if GetSceneVisualization() == k else ''), SetSceneVisualizationCallback(k)) for k, v in GetSceneVisulaizationMethods().iteritems() ]), ('Shader Debugger', lambda : ShaderDebugger(object=sm.GetService('sceneManager').GetActiveScene()))]))),
   1121           ('Scene Textures', OpenSceneTextures),
   1122           ('V3 testing', lambda : self.V3Testing()),
   1123           ('Cycle nebulas', lambda : self.CycleNebulas()),
   1124           ('Toggle non interactable object picking', lambda : ToggleNonInteractability()),
   1125           ('Performance Benchmark', lambda : PerformanceBenchmarkWindow()),
   1126           ('Render Job Profiler', self._RenderJobProfiler),
   1127           ('Crash Video Driver', self._CrashVideoDriver),
   1128           ('Corpse Previewer', corpseviewer.CorpsePreviewer(sm.GetService('sceneManager')).ShowUI),
   1129           ('Asset Previewer', gfxpreviewer.AssetPreviewer(sm.GetService('sceneManager')).ShowUI),
   1130           ('Warp Effect Debug', gfxreports.ShowWarpEffectReport),
   1131           ('Flight Controls Debug', sm.GetService('flightControls').simulation.ToggleDebug),
   1132           ('Toggle Drone Behavior System', ToggleDroneBehaviorSystem),
   1133           ('Hangar Override', tuple([(['None', 'None - Selected'][HangarView.HANGAR_TYPE_OVERRIDE is None], CreateOverrideHangarSceneLambda(None))] + [ ([ht, '%s - Selected' % ht][HangarView.HANGAR_TYPE_OVERRIDE == ht], CreateOverrideHangarSceneLambda(ht)) for ht in HangarView.HANGAR_TYPE_OVERRIDE_VALUES ])),
   1134           ('SSAO Quality', (('Disabled', lambda : SetSSAOQuality(0)),
   1135             ('Low', lambda : SetSSAOQuality(1)),
   1136             ('Medium', lambda : SetSSAOQuality(2)),
   1137             ('High', lambda : SetSSAOQuality(3)))),
   1138           ('GDPR', (('Enable', lambda : EnableGDPR(True)), ('Disable', lambda : EnableGDPR(False)))),
   1139           ('Upscaling', ((['Enable', 'Disable'][IsUpscalingEnabled()] + ' Upscaling', lambda : EnableUpscaling(not IsUpscalingEnabled())), (['Enable', 'Disable'][IsUpscalingDebugViewEnabled()] + ' Debug View', lambda : ToggleUpscalingDebugView()), (['Enable', 'Disable'][IsUpscalingFrameGenDebugViewEnabled()] + ' Frame Generation Debug View', lambda : ToggleUpscalingFrameGenDebugView()))),
   1140           ('Raytracing', (('Enable', lambda : EnableRaytracing(True)), ('Disable', lambda : EnableRaytracing(False)))),
   1141           ('Jump Effects', (('%s New Jump Effects' % ['Enable', 'Disable'][sm.GetService('subway').Enabled()], sm.GetService('subway').Toggle),
   1142             ('%s Jump Effect Kill Switch' % ['Enable', 'Disable'][sm.GetService('subway').FORCE_KILL_SWITCH], sm.GetService('subway').ToggleKillSwitch),
   1143             ('Set Jump Delay', SetJumpDelay),
   1144             ('Jump Effect Overrides', [('None' + ['', ' - enabled'][sm.GetService('subway').JUMP_EFFECT_OVERRIDE == None], CreateEffectOverrideLambda(None))] + [ (guid + ['', ' - enabled'][sm.GetService('subway').JUMP_EFFECT_OVERRIDE == guid], CreateEffectOverrideLambda(guid)) for guid in GetTravelEffectsGuids() ]))),
   1145           ('Green Background', ToggleGreenscreen),
   1146           ('Delete Sun', RemoveSun),
   1147           ('Toggle Graphics', ToggleSceneGraphics),
   1148           ('AntiAliasing', (('Disabled', lambda : SetAntiAliasing(gfxsettings.AA_QUALITY_DISABLED)),
   1149             ('Low TAA', lambda : SetAntiAliasing(gfxsettings.AA_QUALITY_TAA_LOW)),
   1150             ('Medium TAA', lambda : SetAntiAliasing(gfxsettings.AA_QUALITY_TAA_MEDIUM)),
   1151             ('High TAA', lambda : SetAntiAliasing(gfxsettings.AA_QUALITY_TAA_HIGH)))),
   1152           ('Reflection probe', (('Enable', lambda : SetReflectionProbe(True)), ('Disable', lambda : SetReflectionProbe(False)))),
   1153           ('Enable SpaceMouse In Maps', EnableSpaceMouseInMaps),
   1154           ('Set Lag in MS', (('None', lambda : SetLag(0)),
   1155             ('50', lambda : SetLag(50)),
   1156             ('100', lambda : SetLag(100)),
   1157             ('500', lambda : SetLag(500)),
   1158             ('1000', lambda : SetLag(1000)),
   1159             ('2000', lambda : SetLag(2000)),
   1160             ('3000', lambda : SetLag(3000)))),
   1161           None,
   1162           ('Managed RT Report', gfxreports.ShowManagedRTReport),
   1163           ('Blue Resources', gfxreports.ShowBlueResourceReport),
   1164           None,
   1165           ('LOD Report', gfxreports.ShowLODOverviewReport),
   1166           ('Explosion Pool Report', gfxreports.ShowExplosionPoolReport),
   1167           ('Effect Activation Report', gfxreports.ShowEffectActivationReport),
   1168           None,
   1169           ('Planet Texture Report', gfxreports.ShowPlanetTextureReport),
   1170           ('Planet Status Report', gfxreports.ShowPlanetStatusReport),
   1171           None,
   1172           ('Inspect Scene', lambda : blueobjviewer.Show(sm.GetService('sceneManager').GetActiveScene())),
   1173           ('Inspect RenderJob', lambda : blueobjviewer.Show(sm.GetService('sceneManager').fisRenderJob))]))
   1174         from eve.client.script.ui.shared.launchdarkly.debugwindow import LaunchDarklyDebugWindow
   1175         from eve.devtools.script.methodcallsmonitor import MethodCallsMonitor
   1176         m.append(('Network', [(MethodCallsMonitor.default_caption, MethodCallsMonitor.Open), ('LaunchDarkly', LaunchDarklyDebugWindow.Open)]))
   1177         m.append(('Quasar', [("Client Request Hijacker ('eve_public')", ClientRequestHijackWindow.Open), ("Server Request Hijacker ('eve')", ServerRequestHijackWindow.Open)]))
   1178         m.append(None)
   1179         m.append(('Abyssal Deadspace', [('Abyssal Content Tool', AbyssalContentToolWindow.Open), ('Abyssal Npc Spawn Tool', AbyssalNpcSpawnToolWindow.Open)]))
   1180         from achievement_system.client.qa.menu import get_insider_qa_menu as achievements_qa_insider_menu
   1181         m.append(achievements_qa_insider_menu())
   1182         import assetholding.client.qa as asset_holding
   1183         m.append(asset_holding.get_insider_qa_menu())
   1184         m.append(('Camera', [('Debug Camera', lambda : CameraTool.Open())]))
   1185         if session.stationid is not None:
   1186             m.append(('Hangar', [('Model state debugger', lambda : ModelStateDebuggerController(itemID=None).ShowUI())]))
   1187         m.append(uihider.qa.get_command_blocker_menu())
   1188         from cosmetics.client.character.title.qa.menu import get_insider_qa_menu as titles_qa_insider_menu
   1189         m.append(titles_qa_insider_menu())
   1190         import communitytracks.client.qa.menu as community_tracks
   1191         m.append(community_tracks.get_insider_menu())
   1192         import freelanceprojects.client.contributionmethods.qa.menu as contribution_methods
   1193         m.append(contribution_methods.get_insider_menu())
   1194 
   1195         def open_emanation_locks_esp():
   1196             esp_url = serverInfo.GetServerInfo().espUrl
   1197             action = 'gm/emanationLocks.py?action=EmanationLockDetails&character_id=' + str(session.charid)
   1198             blue.os.ShellExecute('http://%s/%s' % (esp_url, action))
   1199 
   1200         m.append(('Emanation Locks Eve Server Page', open_emanation_locks_esp))
   1201         import dynamicresources.client.ess.bracket.debug
   1202         m.append(dynamicresources.get_insider_qa_menu())
   1203         from freelanceprojects.client.qa.freelance_qa_tools import get_insider_qa_menu as freelance_projects_menu
   1204         m.append(freelance_projects_menu())
   1205         from campaigns.client.qa.insider import get_insider_qa_menu as campaigns_menu
   1206         m.append(campaigns_menu())
   1207         import homestation.client
   1208         m.append(homestation.get_insider_qa_menu())
   1209         import raffles.client
   1210         m.append(raffles.get_insider_qa_menu())
   1211         m.append(('Jump Clones', [('Reset last clone jump time', ResetLastCloneJumpTime)]))
   1212         m.append(('Map', [('Starmap : Clear cache', lambda : sm.GetService('starmap').ClearMapCache()),
   1213           ('Map : Open Map Editor', OpenMapEditor),
   1214           MenuEntryDataCheckbox('Use Mock Data', setting=useFakeMapColorData, hint='You need to load the filters again'),
   1215           MenuEntryDataCheckbox('Use Debug Circle', setting=mapDebugModeActive)]))
   1216         m.append(('Map Tags', [('Clear cache', lambda : reset_map_tag_cache_signal())]))
   1217         m.append(('Market', (('Toggle Market Price History Test Data', TogglePriceHistoryTestData),)))
   1218         import sovereignty.mercenaryden.client.qa.insider as mercenary_dens
   1219         m.append(mercenary_dens.get_insider_qa_menu())
   1220         m.append(('New Eden Store', [('Clear cache', lambda : sm.GetService('vgsService').ClearCache())]))
   1221         import redeem.client
   1222         m.append(get_insider_qa_menu())
   1223         m.append(MenuEntryData('Contextual Offers', subMenuData=[MenuEntryData('Trigger test offer 1', sm.GetService('contextualOfferSvc').Debug_AddMockOffer1), MenuEntryData('Trigger test offer 2', sm.GetService('contextualOfferSvc').Debug_AddMockOffer2), MenuEntryData('Trigger test offer 3', sm.GetService('contextualOfferSvc').Debug_AddMockOffer3)]))
   1224         m.append(('Scope Network', [('Reload FSD Seasons', lambda : self.ReloadFsdData())]))
   1225         m.append(('Skills', (('Skill Tree Window', SkillTreeDockablePanel.Open), ('Reset Ship Progression', GetShipUnlockService().QA_ResetAll))))
   1226         from cosmetics.client.ships.qa.skin_states_table import SkinStatesTableWindow
   1227         from cosmetics.client.ships.qa.skin_licenses_table import SkinLicensesTableWindow
   1228         from cosmetics.client.ships.qa.component_licenses_table import ComponentLicensesTableWindow
   1229         m.append(('Ship Cosmetics', (('Ship Emblems', ShipEmblemsTool.Open),
   1230           ('Cached Ship Skin States', SkinStatesTableWindow.Open),
   1231           ('Component Licenses', ComponentLicensesTableWindow.Open),
   1232           ('Skin Licenses', SkinLicensesTableWindow.Open))))
   1233         import cosmetics.client.messengers.entitlements.corporation.structure.qa as structureCosmeticsQA
   1234         m.append(structureCosmeticsQA.get_insider_qa_menu())
   1235         m.append(('Structure SKINR', (('Structure SKINR', PaintToolWnd.Open),)))
   1236         m.append(('Ship SKINR', (('Ship SKINR', ShipSKINRWindow.Open),)))
   1237         m.append(('Omega', (('Clone Grade', CloneGradeQAWindow.Open),)))
   1238         import dailygoals.client.qa as dailygoalsQA
   1239         m.append(dailygoalsQA.get_insider_qa_menu())
   1240         m.append(('Tutorial UI Hider', (('Reveal All',
   1241            self.uihider.get_ui_hider().reveal_everything,
   1242            (),
   1243            (ICON_VISIBILITY_ON, 18)), ('Hide All',
   1244            self.uihider.get_ui_hider().hide_everything,
   1245            (),
   1246            (ICON_VISIBILITY_OFF, 18)))))
   1247         m.append(('Overview Blocker', (('Unblock',
   1248            sm.GetService('overviewPresetSvc').UnblockOverview,
   1249            (),
   1250            (ICON_VISIBILITY_ON, 18)), ('Block',
   1251            sm.GetService('overviewPresetSvc').BlockOverview,
   1252            (),
   1253            (ICON_VISIBILITY_OFF, 18)))))
   1254         from uiblinker.insider import get_ui_blinker_menu
   1255         m.append(get_ui_blinker_menu())
   1256         m.append(('Career Agents', (('Open Debug window', CareerAgentDebugWnd.Open),)))
   1257         m.append(MenuEntryData(text='Boarding Moment', subMenuData=[MenuEntryDataCheckbox(text='QA UI', setting=boarding_moment_qa.overlay_setting), MenuEntryData('Reset boarding moments', boarding_moment_qa.clear_data)]))
   1258         from eve.devtools.script.dotWeapons import DotWeaponWnd
   1259         from eve.devtools.script.crystalDamageTrackerWnd import CrystaDamageTrackerWnd
   1260         m.append(MenuEntryData('Inspace Debug Wnds', subMenuData=[MenuEntryData('Open Warp Vector window', lambda : WarpVectorWnd.Open()), MenuEntryData('Open DOT Weapons window', lambda : DotWeaponWnd.Open()), MenuEntryData('Open Crystal Damage window', lambda : CrystaDamageTrackerWnd.Open())]))
   1261         m.append(None)
   1262         m.append(('Open Impact window', lambda : impactVisualizationWnd.ImpactVisualizationWnd.Open()))
   1263         from nodegraph.client.ui.window import NodeGraphEditorWindow
   1264         m.append(('Open Node Graph Editor', lambda : NodeGraphEditorWindow.Open()))
   1265         m.append(None)
   1266         m.append(('Auto Bot', AutoBotWindow.Open))
   1267         m.append(None)
   1268         m.append(('Cluster Visualizer', ClusterVisualizerWindow.Open))
   1269         return m
   1270 
   1271     def ReloadFsdData(self):
   1272         svc = sm.RemoteSvc('seasonManager')
   1273         svc.reload_fsd_data()
   1274 
   1275     def ImplantsMenu(self, *args):
   1276         m = MenuList()
   1277         implantsmenu = sm.GetService('implant').ImplantMenu()
   1278         for entry in implantsmenu:
   1279             try:
   1280                 m.append((entry[0], entry[1]))
   1281             except:
   1282                 sys.exc_clear()
   1283                 m.append(None)
   1284 
   1285         return m
   1286 
   1287     def DroneMenu(self, *args):
   1288         m = MenuList()
   1289         dronemenu = sm.GetService('charge').DroneMenu()
   1290         fighterMenu = sm.GetService('fighters').FightersMenu()
   1291         for menu in [dronemenu, fighterMenu]:
   1292             for entry in menu:
   1293                 try:
   1294                     m.append((entry[0], entry[1]))
   1295                 except:
   1296                     sys.exc_clear()
   1297                     m.append(None)
   1298 
   1299         return m
   1300 
   1301     def ChargeMenu(self, *args):
   1302         m = MenuList()
   1303         chargemenu = sm.GetService('charge').ChargeMenu()
   1304         for entry in chargemenu:
   1305             try:
   1306                 if entry.__class__ == dict:
   1307                     m.append((entry['label'], None))
   1308                     m.append(None)
   1309                 else:
   1310                     m.append((entry[0], entry[1]))
   1311             except:
   1312                 sys.exc_clear()
   1313                 m.append(None)
   1314 
   1315         return m
   1316 
   1317     def ToggleMyShip(self):
   1318         ship = sm.GetService('michelle').GetBall(session.shipid)
   1319         if ship and ship.model:
   1320             ship.model.display = not ship.model.display
   1321 
   1322     def ShipMenu(self, *args):
   1323         shipmenu = sm.StartService('copycat').GetMenu_Ship()
   1324         if shipmenu is None:
   1325             return
   1326         shipmenu += [None, ('Show/Hide My Ship', self.ToggleMyShip)]
   1327         menu = MenuList()
   1328         submenu = MenuList()
   1329         for menuentry in shipmenu:
   1330             if isinstance(menuentry, types.TupleType):
   1331                 if len(menuentry) == 2:
   1332                     display, func = menuentry
   1333                     if isinstance(func, types.TupleType):
   1334                         subFunc = func[1]()
   1335                         for entry in subFunc:
   1336                             if isinstance(entry, types.TupleType):
   1337                                 submenu.append((entry, None))
   1338                                 submenu.append(None)
   1339                             elif isinstance(entry, types.DictType):
   1340                                 submenu.append((entry['label'], entry['action'], entry['args']))
   1341 
   1342                         if len(submenu) == 0:
   1343                             submenu = [('Nothing found', None)]
   1344                         menu.append((display, submenu))
   1345                         submenu = MenuList()
   1346                     else:
   1347                         menu.append((display, func))
   1348                 elif len(menuentry) == 3:
   1349                     display, func, args = menuentry
   1350                     menu.append((display, func, args))
   1351             elif isinstance(menuentry, types.NoneType):
   1352                 menu.append(None)
   1353 
   1354         return menu
   1355 
   1356     def MacroMenu(self, *args):
   1357         m = MenuList()
   1358         lines = sm.GetService('slash').GetMacros()
   1359         lines.sort()
   1360         for macroName, comseq in lines:
   1361             m.append((macroName, self.SlashBtnClick(comseq)))
   1362 
   1363         return m
   1364 
   1365     def UIMenu(self, *args):
   1366         menu = MenuData(iconSize=18)
   1367         menu.AddCaption('Tools')
   1368         menu.AddEntry(text='Animations', func=lambda : TestAnimationsWnd.Open(), texturePath='res:/UI/Texture/classes/insider/animation_18.png')
   1369         menu.AddEntry(text='Color Picker', func=lambda : ColorPicker.Open(), texturePath='res:/UI/Texture/classes/insider/color_picker_18.png')
   1370         if not blue.pyos.packaged:
   1371             menu.AddEntry(text='Control Catalog', func=lambda : self.OpenControlCatalogWindow(), texturePath='res:/UI/Texture/classes/insider/control_catalog_18.png')
   1372         menu.AddEntry(text='Debugger', func=lambda : UIDebugger.Open(), texturePath='res:/UI/Texture/classes/insider/ui_debugger_18.png')
   1373         menu.AddEntry(text='Event Listener', func=lambda : UIEventListener.Open(), texturePath='res:/UI/Texture/classes/insider/event_listener_18.png')
   1374         menu.AddEntry(text='Gradient Editor', func=lambda : GradientEditor.Open(), texturePath='res:/UI/Texture/classes/insider/gradient_18.png')
   1375         menu.AddEntry(text='Icons', func=lambda : IconBrowserWindow.Open(), texturePath='res:/UI/Texture/classes/insider/icons_18.png')
   1376         menu.AddEntry(text='Keybindings Overview', func=self.OpenKeyboardWindow, texturePath='res:/UI/Texture/classes/insider/keyboard_18.png')
   1377         menu.AddEntry(text='Sprites', func=lambda : UISpriteTest.Open(), texturePath='res:/UI/Texture/classes/insider/image_18.png')
   1378         menu.AddEntry(text='Toggle Black Background', func=self.ToggleBlackBackground, texturePath='res:/UI/Texture/classes/insider/lightbulb_18.png')
   1379         menu.AddEntry(text='Tree', func=lambda : UITree.Open(), texturePath='res:/UI/Texture/classes/insider/ui_tree_18.png')
   1380         menu.AddEntry(text='Window Manager', func=lambda : WindowManager.Open(), texturePath='res:/UI/Texture/classes/insider/window_manager_18.png')
   1381         menu.AddSeparator()
   1382         menu.AddCaption('Live Reload')
   1383         menu.AppendMenuEntryData(self.GetLabelLiveReloadOption())
   1384         menu.AppendMenuEntryData(self.GetLiveReloadUiTexturesOption())
   1385         menu.AddEntry(text='Manual Reload', subMenuData=[MenuEntryData(text='Localization', func=self.ReloadFSDLocalizationPickles, texturePath='res:/UI/Texture/classes/insider/localization_18.png'), MenuEntryData(text='Shaders', func=self.ReloadUIShader, texturePath='res:/UI/Texture/classes/insider/shader_18.png'), MenuEntryData(text='Textures', func=self.ReloadUITextures, texturePath='res:/UI/Texture/classes/insider/image_18.png')])
   1386         menu.AddSeparator()
   1387         menu.AddCaption('Tests')
   1388         menu.AddEntry(text='Button Bazaar', func=open_button_bazaar, texturePath='res:/UI/Texture/classes/insider/button_bazaar_18.png')
   1389         menu.AppendMenuEntryData(self.GetGammaCorrectTextOption())
   1390         menu.AddEntry(text='Glow', func=lambda : GlowTestWindow.Open(), texturePath='res:/UI/Texture/classes/insider/glow_18.png')
   1391         menu.AddEntry(text='Graphs', func=lambda : TestGraph.Open(), texturePath='res:/UI/Texture/classes/insider/chart_18.png')
   1392         menu.AppendMenuEntryData(self.GetLinearColorSpaceOption())
   1393         menu.AddEntry(text='Notifications', func=open_notification_dev_window, texturePath='res:/UI/Texture/classes/insider/notification_18.png')
   1394         menu.AddEntry(text='Performance', func=lambda : UIPerformanceTestWnd.Open(), texturePath='res:/UI/Texture/classes/insider/fire_18.png')
   1395         menu.AddEntry(text='Text Styles', func=TextStyleTest.Open, texturePath='res:/UI/Texture/classes/insider/text_styles_18.png')
   1396         menu.AddEntry(text='Theme', func=lambda : ColorThemeEditor.Open(), texturePath='res:/UI/Texture/classes/insider/theme_18.png')
   1397         menu.AddEntry(text='UI Scale', func=lambda : UIScaling.Open(), texturePath='res:/UI/Texture/classes/insider/ui_scale_18.png')
   1398         return menu
   1399 
   1400     def OpenControlCatalogWindow(self):
   1401         self.controlCatalogInstanceID += 1
   1402         ControlCatalogWindow.Open(windowInstanceID=str(self.controlCatalogInstanceID))
   1403 
   1404     def GetLiveReloadUiTexturesOption(self):
   1405         return self.GetToggleOption(label='Textures', callback=self.ToggleResourceLiveReload, enabled=self.IsResourceLiveReloadingEnabled())
   1406 
   1407     def IsResourceLiveReloadingAvailable(self):
   1408         return not blue.pyos.packaged
   1409 
   1410     def IsResourceLiveReloadingEnabled(self):
   1411         if not self.IsResourceLiveReloadingAvailable():
   1412             return False
   1413         return settings.public.ui.Get('insider.res_live_reload_enabled', True)
   1414 
   1415     def ToggleResourceLiveReload(self):
   1416         if not self.IsResourceLiveReloadingAvailable():
   1417             prompt_player_fsd_dialog('CustomNotify', {'notify': 'Texture live reloading is not available in built clients.'})
   1418             return
   1419         is_enabled = self.IsResourceLiveReloadingEnabled()
   1420         settings.public.ui.Set('insider.res_live_reload_enabled', not is_enabled)
   1421         self.UpdateResourceLiveReloader()
   1422 
   1423     def UpdateResourceLiveReloader(self):
   1424         if not self.IsResourceLiveReloadingAvailable():
   1425             return
   1426         if self.IsResourceLiveReloadingEnabled():
   1427             self._res_live_reloader.start()
   1428         else:
   1429             self._res_live_reloader.stop()
   1430 
   1431     def GetGammaCorrectTextOption(self):
   1432         return self.GetToggleOption(label='Gamma Correct Text', callback=self.ToggleUIGammaCorrectText, enabled=uicore.desktop.renderObject.gammaCorrectText)
   1433 
   1434     def ToggleUIGammaCorrectText(self):
   1435         uicore.desktop.renderObject.gammaCorrectText = not uicore.desktop.renderObject.gammaCorrectText
   1436 
   1437     def GetLinearColorSpaceOption(self):
   1438         return self.GetToggleOption(label='Linear Color Space', callback=self.ToggleUILinearColorSpace, enabled=uicore.desktop.renderObject.useLinearColorSpace)
   1439 
   1440     def GetToggleOption(self, label, callback, enabled):
   1441         if enabled:
   1442             icon = 'res:/UI/Texture/classes/UtilMenu/checkBoxActive.png'
   1443         else:
   1444             icon = 'res:/UI/Texture/classes/UtilMenu/checkBoxInactive.png'
   1445         return MenuEntryData(text=label, func=callback, texturePath=icon)
   1446 
   1447     def GetLabelLiveReloadOption(self):
   1448         return self.GetToggleOption(label='Localization', callback=self.ToggleLabelLiveReloading, enabled=self.IsLabelLiveReloadEnabled())
   1449 
   1450     def ToggleUILinearColorSpace(self):
   1451         uicore.desktop.renderObject.useLinearColorSpace = not uicore.desktop.renderObject.useLinearColorSpace
   1452 
   1453     def TournamentMenu(self, *args):
   1454         toolMenu = MenuList()
   1455         toolMenu.append(('Tournament Camera Tool', TournamentWindow.Open))
   1456         toolMenu.append(('Tournament Referee Tool', RefWindowSpawningWindow.Open))
   1457         return toolMenu
   1458 
   1459     def ReloadFSDLocalizationPickles(self):
   1460         localizationTools.ReloadFSDLocalizationPickle()
   1461         msg = 'FSD localization pickles successfully reloaded on client'
   1462         if sm.RemoteSvc('localizationServer').ReloadFSDPickle():
   1463             msg += ' and server'
   1464         message_player(msg)
   1465 
   1466     def OpenKeyboardWindow(self):
   1467         from eve.client.script.ui.shared.shortcuts import KeyboardWnd
   1468         wnd = KeyboardWnd.GetIfOpen()
   1469         if wnd:
   1470             wnd.Close()
   1471         KeyboardWnd.Open()
   1472 
   1473     def ShowDogmaTimeWindow(self):
   1474         from eve.devtools.script.dogmaTimeWnd import OpenWindow
   1475         OpenWindow()
   1476 
   1477     def ReloadUITextures(self):
   1478         for resPath in blue.motherLode.GetNonCachedKeys():
   1479             isIcon = resPath.startswith('res:/dx9/model') and 'icons' in resPath
   1480             isTexture = resPath.startswith('res:/ui/texture')
   1481             isUberShader = 'ubershader' in resPath
   1482             if isIcon or isTexture or isUberShader:
   1483                 res = blue.motherLode.Lookup(resPath)
   1484                 if res:
   1485                     if hasattr(res, 'Reload'):
   1486                         res.Reload()
   1487 
   1488     def ReloadIcons(self):
   1489         for resPath in blue.motherLode.GetNonCachedKeys():
   1490             if resPath.startswith('res:/dx9/model') and 'icons' in resPath:
   1491                 res = blue.motherLode.Lookup(resPath)
   1492                 if res:
   1493                     if hasattr(res, 'Reload'):
   1494                         res.Reload()
   1495 
   1496     def ReloadUIShader(self):
   1497         res = blue.motherLode.Lookup('res:/graphics/effect.dx11/ui/ubershader.sm_hi')
   1498         if res:
   1499             res.Reload()
   1500         res = blue.motherLode.Lookup('res:/graphics/effect.dx11/ui/ubershader.sm_lo')
   1501         if res:
   1502             res.Reload()
   1503 
   1504     def ToggleBlackBackground(self):
   1505         for c in uicore.desktop.children:
   1506             if c.name == 'colorFill':
   1507                 c.Close()
   1508                 break
   1509         else:
   1510             color = Color.FUCHSIA if uicore.uilib.Key(uiconst.VK_SHIFT) else Color.BLACK
   1511             c = Fill(name='colorFill', parent=uicore.desktop, color=color)
   1512 
   1513     def ToggleLabelLiveReloading(self):
   1514         if blue.pyos.packaged:
   1515             message = 'This feature is not available in a built client'
   1516         else:
   1517             isEnabled = localizationTools.localization.ToggleLabelOverride()
   1518             message = 'Localization label live reloading is '
   1519             message += 'enabled' if isEnabled else 'disabled'
   1520         message_player(message)
   1521 
   1522     def IsLabelLiveReloadEnabled(self):
   1523         if blue.pyos.packaged:
   1524             return False
   1525         else:
   1526             import localization.labelOverride
   1527             return localization.labelOverride.GetConfigValue()
   1528 
   1529     def ToolMenu(self, *args):
   1530         toolMenu = MenuList()
   1531         toolMenu.append(('Settings', [('Export', sm.GetService('settingsLoader').Export, ()), ('Load', sm.GetService('settingsLoader').Load, ())]))
   1532         toolMenu.append(('Convert Dogma Datetime', self.ShowDogmaTimeWindow))
   1533         if session.role & ROLE_GML:
   1534             toolMenu.append(('Fighter debugger', lambda : sm.GetService('fighters').ShowDebugWindow()))
   1535             toolMenu.append(('WWise Sound Player', InsiderSoundPlayer.Open))
   1536             toolMenu.append(('Video Player', BinkVideoViewer.Open))
   1537             toolMenu.append(('Ballpark exporter', lambda : sm.GetService('ballparkExporter').Show()))
   1538             toolMenu.append(('Destroyable Items', lambda : sm.GetService('destroyableItems').ConstructLayout()))
   1539             toolMenu.append(('Grid Utilities', lambda : sm.GetService('gridutils').ConstructLayout()))
   1540             toolMenu.append(('Starbase Tools', lambda : sm.GetService('poser').Show()))
   1541         if session.role & ROLE_GMH:
   1542             toolMenu.append(('Inventory Tools', InvToolsWnd.Open))
   1543             toolMenu.append(('Settings Manager', SettingsMgr.Open))
   1544         if session.role & ROLE_QA:
   1545             toolMenu.append(('Module Test', lambda : sm.GetService('modtest').Show()))
   1546             toolMenu.append(('Skill Tool', lambda : sm.GetService('trainer').Show()))
   1547             toolMenu.append(('Image Cache Demo', ImageCacheDemoWindow.Open))
   1548         if session.role & ROLEMASK_ELEVATEDPLAYER:
   1549             toolMenu.append(('Copycat', lambda : sm.GetService('copycat').Show()))
   1550             toolMenu.append(('Cap Simulator', lambda : sm.GetService('capsim').Show()))
   1551             toolMenu.append(('Slash Console', lambda : sm.GetService('slash').ConstructLayout()))
   1552             toolMenu.append(('Type Browser', TypeBrowser.Open))
   1553         toolMenu.sort()
   1554         if session.role & ROLE_PROGRAMMER:
   1555             toolMenu.append(None)
   1556             toolMenu.append((eveformat.color('Python Console', eveColor.WARNING_ORANGE), lambda : sm.GetService('console').ConstructLayout()))
   1557         toolMenu.append(None)
   1558         action = 'gd/npc.py?action=BrowseSolarSystem&solarSystemID=' + str(session.solarsystemid2)
   1559         toolMenu.append(('Solar system NPC info', StartMenuService().GetFromESP, (action,)))
   1560         if trinity.IsFpsEnabled():
   1561             toolMenu.append(('Turn FPS Monitor OFF', self._SetFpsRender, (False,)))
   1562         else:
   1563             toolMenu.append(('Turn FPS Monitor ON', self._SetFpsRender, (True,)))
   1564         toolMenu.append(('Engine tools', lambda : EngineToolsLauncher.Open()))
   1565         toolMenu.append(('Attach Loglite', lambda : blue.AttachToLogServer()))
   1566         toolMenu.append(('Report Bug', lambda : sm.GetService('bugReporting').StartCreateBugReport()))
   1567         toolMenu.append(('Shared texture viewer', self.SharedTextureViewer))
   1568         return toolMenu
   1569 
   1570     def _SetFpsRender(self, isEnabled):
   1571         trinity.SetFpsEnabled(isEnabled)
   1572         settings.public.ui.Set('isFpsRenderJobEnabled', isEnabled)
   1573 
   1574     def SharedTextureViewer(self):
   1575         from eve.devtools.script.sharedtextureviewer import SharedTextureViewer
   1576         SharedTextureViewer.Open()
   1577 
   1578     def Hide(self, *args):
   1579         self.Show(show=False)
   1580 
   1581     def Reload(self):
   1582         self.Hide()
   1583         self.Show(force=True)
   1584         prompt_player_fsd_dialog('CustomNotify', {'notify': 'Insider has been reloaded.'})
   1585 
   1586     def OnUIRefresh(self):
   1587         InsiderWnd.CloseIfOpen()
   1588         self.Show(force=True)
   1589 
   1590     def Show(self, show = True, force = False):
   1591         if not session.role & serviceConst.ROLEMASK_ELEVATEDPLAYER:
   1592             return
   1593         INSIDERDIR = self.GetInsiderDir()
   1594         if not os.path.exists(INSIDERDIR):
   1595             os.mkdir(INSIDERDIR)
   1596         InsiderWnd.CloseIfOpen()
   1597         if not show:
   1598             return
   1599         settings.public.ui.Set('Insider', show)
   1600         btn = []
   1601         menus = MenuList([['Tools', self.ToolMenu, serviceConst.ROLE_GML],
   1602          ['Macro', self.MacroMenu, serviceConst.ROLE_GML],
   1603          ['Ship', self.ShipMenu, serviceConst.ROLE_GML],
   1604          ['Charges', self.ChargeMenu, serviceConst.ROLE_GML],
   1605          ['Drones', self.DroneMenu, serviceConst.ROLE_GML],
   1606          ['Implants', self.ImplantsMenu, serviceConst.ROLE_GML],
   1607          ['QA', self.QAMenu, serviceConst.ROLE_QA],
   1608          ['UI', self.UIMenu, serviceConst.ROLE_QA],
   1609          ['Tournament', self.TournamentMenu, serviceConst.ROLE_TOURNAMENT]])
   1610         for label, func, role in menus:
   1611             if session.role & role:
   1612                 btn.append([label,
   1613                  func,
   1614                  None,
   1615                  None])
   1616 
   1617         wnd = InsiderWnd.Open()
   1618         if wnd:
   1619 
   1620             def resize_window():
   1621                 if wnd.destroyed:
   1622                     return
   1623                 if len(wnd.header.extra_content.children) == 0:
   1624                     return
   1625                 window_width = wnd.width
   1626                 extra_content_width, _ = wnd.header.extra_content.GetCurrentAbsoluteSize()
   1627                 menu_bar_width = wnd.header.extra_content.children[0].width
   1628                 wnd.width = window_width - (extra_content_width - menu_bar_width)
   1629                 _, new_window_height = wnd.GetWindowSizeForContentSize(height=0)
   1630                 wnd.SetFixedHeight(new_window_height)
   1631 
   1632             toolbar = MenuBar(parent=wnd.header.extra_content, align=uiconst.TOLEFT, on_size_changed=resize_window)
   1633             for label, func, _, _ in btn:
   1634                 toolbar.AddMenu(text=label, entries=func)
   1635 
   1636     def Toggle(self, forceShow = False, *args):
   1637         if settings.public.ui.Get('Insider', False):
   1638             self.Hide()
   1639         else:
   1640             self.Show(force=forceShow)
   1641 
   1642     def WarpTo(self, itemID = None):
   1643         if itemID:
   1644             sm.GetService('slash').SlashCmd('warpto %d' % itemID)
   1645 
   1646 
   1647 def ResetLastCloneJumpTime():
   1648     sm.GetService('clonejump').GetLM().ResetLastCloneJumpTime()
   1649 
   1650 
   1651 def SetJumpDelay():
   1652     currentDelay = sm.GetService('subway').JUMP_FINISH_DELAY / 1000
   1653     result = uix.QtyPopup(minvalue=0, maxvalue=10000, caption='How long?', label='', hint='How long to stall jumps in seconds? (currently %d)' % currentDelay)
   1654     if result:
   1655         sm.GetService('subway').JUMP_FINISH_DELAY = result['qty'] * 1000
   1656 
   1657 
   1658 def open_button_bazaar():
   1659     import eve.devtools.script.buttonbazaar.window
   1660     eve.devtools.script.buttonbazaar.window.ButtonBazaarWindow.Open()
   1661 
   1662 
   1663 def open_notification_dev_window():
   1664     from notifications.client.development.notificationDevUI import NotificationDevWindow
   1665     NotificationDevWindow.Open()
   1666 
   1667 
   1668 def SetSSAOQuality(quality):
   1669     from trinity import sceneRenderJobSpace
   1670     sceneRenderJobSpace.SSAOSetting = quality
   1671     sm.GetService('sceneManager').fisRenderJob.SetSettingsBasedOnPerformancePreferences()
   1672 
   1673 
   1674 def EnableGDPR(enable):
   1675     trinity.ModifyGlobalEffectOptions([('BINDLESS_RENDERING', 'BINDLESS_RENDERING_ENABLED' if enable else 'BINDLESS_RENDERING_DISABLED')], [])
   1676     trinity.settings.SetValue('gdrEnabled', enable)
   1677 
   1678 
   1679 def EnableRaytracing(enabled):
   1680     trinity.settings.SetValue('raytracingEnabled', enabled)
   1681     if not enabled and gfxsettings.Get(gfxsettings.GFX_SHADOW_QUALITY) == 3:
   1682         gfxsettings.Set(gfxsettings.GFX_SHADOW_QUALITY, 2, False)
   1683         sm.GetService('sceneManager').fisRenderJob.SetSettingsBasedOnPerformancePreferences()
   1684 
   1685 
   1686 def EnableUpscaling(enabled):
   1687     trinity.settings.SetValue('newUpscalersEnabled', enabled)
   1688     trinity.device.UpdateAvailableUpscalingTechniques()
   1689     currentTechnique = gfxsettings.Get(gfxsettings.GFX_UPSCALING_TECHNIQUE)
   1690     if currentTechnique not in (gfxsettings.GFX_UPSCALING_TECHNIQUE_NONE, gfxsettings.GFX_UPSCALING_TECHNIQUE_FSR1):
   1691         gfxsettings.Set(gfxsettings.GFX_UPSCALING_TECHNIQUE, gfxsettings.GFX_UPSCALING_TECHNIQUE_NONE, False)
   1692         trinity.device.SetUpscaling(gfxsettings.GFX_UPSCALING_TECHNIQUE_NONE, gfxsettings.GFX_UPSCALING_SETTING_NATIVE, False)
   1693 
   1694 
   1695 def IsUpscalingEnabled():
   1696     return trinity.settings.GetValue('newUpscalersEnabled')
   1697 
   1698 
   1699 def IsUpscalingDebugViewEnabled():
   1700     return trinity.settings.GetValue('upscalingDebugView')
   1701 
   1702 
   1703 def ToggleUpscalingDebugView():
   1704     return trinity.settings.SetValue('upscalingDebugView', not IsUpscalingDebugViewEnabled())
   1705 
   1706 
   1707 def IsUpscalingFrameGenDebugViewEnabled():
   1708     return trinity.settings.GetValue('frameGenDebugView')
   1709 
   1710 
   1711 def ToggleUpscalingFrameGenDebugView():
   1712     return trinity.settings.SetValue('frameGenDebugView', not IsUpscalingFrameGenDebugViewEnabled())
   1713 
   1714 
   1715 def OpenSceneTextures():
   1716     rj = sm.GetService('sceneManager').GetFisRenderJob()
   1717     renderDriver = blue.FindInterface(rj, 'EveSpaceSceneRenderDriver')
   1718     if len(renderDriver) == 0:
   1719         return
   1720     renderDriver = renderDriver[0]
   1721 
   1722     def onClose():
   1723         rj = sm.GetService('sceneManager').GetFisRenderJob()
   1724         renderDriver = blue.FindInterface(rj, 'EveSpaceSceneRenderDriver')[0]
   1725         renderDriver.debugMode = False
   1726 
   1727     renderDriver.debugMode = True
   1728     blue.synchro.Yield()
   1729     uthread.new(TextureWindow, renderDriver=renderDriver, onCloseCallback=onClose)
   1730 
   1731 
   1732 def OpenMapEditor():
   1733     wnd = MapEditorWnd.GetIfOpen()
   1734     if wnd:
   1735         wnd.Maximize()
   1736     else:
   1737         MapEditorWnd.Open()