fleetSvc.py (96431B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\fleetSvc.py 2 from __future__ import absolute_import 3 import copy 4 import yaml 5 import eveexceptions 6 import gametime 7 import uthread2 8 from carbon.common.lib.const import SEC, MIN 9 from caching.memoize import Memoize 10 from carbon.common.script.sys.service import Service 11 from carbon.common.script.util.format import FmtAmt 12 from carbonui.control.contextMenu.menuData import MenuData 13 from eve.client.script.ui.shared.agencyNew.contentGroups import contentGroupConst 14 import evefleet.fleetSetupConst as fsConst 15 from eve.client.script.ui.shared.fleet.fleetbroadcast import BroadcastSettings 16 from eve.client.script.ui.shared.fleet.fleetregister import RegisterFleetWindow 17 from eve.client.script.ui.shared.fleet.fleetwindow import FleetWindow 18 from eve.client.script.ui.shared.fleet.fleetJoinRequestWnd import FleetJoinRequestWindow 19 from eve.client.script.ui.shared.fleet.fleetCompositionWnd import FleetComposition 20 from evefleet.client.fleetFinder_allowedEntities import GetDiffInAllowedAndBanned 21 from eve.client.script.ui.shared.fleet.fleet import WingName, SquadronName 22 from eve.client.script.ui.shared.fleet.fleetWatchList import WatchListPanel 23 from eve.client.script.ui.shared.fleet.fleetBroadcastConst import BROADCAST_COLOR_SETTING, LISTEN_BROADCAST_SETTING, broadcastNames, flagToName, iconsByBroadcastType 24 from eve.client.script.ui.shared.fleet.fleetbroadcastexports import fleetBroadcastScopeSetting 25 from evefleet import BROADCAST_SHOW_OWN, WATCHLIST_COL_1, WATCHLIST_COL_2 26 from eve.client.script.ui.util.linkUtil import GetCharIDFromTextLink 27 from eve.common.script.net.eveMoniker import GetFleet 28 from eve.common.script.sys.eveCfg import GetActiveShip, IsDockedInStructure 29 from eve.common.script.sys.idCheckers import IsCharacter, IsEvePlayerCharacter, IsNPC 30 from eveexceptions import UserError 31 from eveexceptions.const import UE_LOCID, UE_OWNERID 32 import evelink.client 33 import evetypes 34 from evefleet.client.util import GetFleetSetupOptionHint 35 from evefleet.fleetAdvertObject import FleetAdvertObject 36 from evefleet.watchListOrder import FleetWatchListOrder 37 from inventorycommon.const import groupAsteroidBelt, groupMoon, groupPlanet, groupWarpGate, groupStargate, groupStation, groupSkyhook 38 import trinity 39 import uthread 40 from eve.client.script.ui.util import uix 41 import blue 42 from . import states as state 43 from eve.client.script.ui.shared.fleet import fleetbroadcastexports 44 import log 45 import carbonui.const as uiconst 46 import localization 47 import evefleet 48 from eve.client.script.util.eveMisc import CSPAChargedActionForMany, CSPAChargedAction 49 from eve.client.script.ui.shared.fleet.storeFleetSetupWnd import StoredFleetSetupListWnd 50 from eve.client.script.ui.shared.fleet.storeFleetSetupWnd import StoreFleetSetupWnd 51 import sharedSettings 52 from player_messaging.client import get_supressed_result, set_suppress_result 53 from player_messaging.client.ui_message import prompt_player_fsd_dialog 54 from utillib import KeyVal 55 from carbonui.uicore import uicore 56 from .messagebus.fleetMessenger import FleetMessenger 57 import eve.common.lib.appConst as const 58 from carbonui.util.various_unsorted import SortListOfTuples 59 from eve.client.script.ui.control.allUserEntries import AllUserEntries 60 from eve.client.script.ui.util import utilWindows 61 from uihider import CommandBlockerService 62 FLEETBROADCASTTIMEOUT = 15 63 UPDATEFLEETFINDERDELAY = 60 64 UPDATEFLEETMEMBERDELAY_SEC = 30 65 MIN_BROADCAST_TIME = 2 66 RECONNECT_DELAY = 10 67 FLEETCOMPOSITION_CACHE_TIME = 20 68 MAX_NUM_BROADCASTS = 500 69 MAX_NUM_LOOTEVENTS = 500 70 CONNOT_BE_MOVED_INCOMPATIBLE = -1 71 CANNOT_BE_MOVED = 0 72 CAN_BE_COMMANDER = 1 73 CAN_ONLY_BE_MEMBER = 2 74 WATCHLIST_MEMBER_INFO_SETTING_KEY = 'fleetWathlistMemberInfo' 75 cynoTypeNames = {const.typeCovertCynosuralFieldI: 'UI/Fleet/CynoCovert', 76 const.typeIndustrialCynosuralField: 'UI/Fleet/CynoIndustrial', 77 const.typeCynosuralFieldI: 'UI/Fleet/CynoStandard'} 78 79 class FleetSvc(Service): 80 __guid__ = 'svc.fleet' 81 __notifyevents__ = ['OnFleetBroadcast', 82 'ProcessSessionChange', 83 'OnFleetInvite', 84 'OnFleetJoin', 85 'OnFleetJoinReject', 86 'OnFleetLeave', 87 'OnFleetDisbanded', 88 'OnFleetMove', 89 'OnFleetMemberChanged', 90 'OnFleetMoveFailed', 91 'OnFleetWingAdded', 92 'OnFleetWingDeleted', 93 'OnFleetSquadAdded', 94 'OnFleetSquadDeleted', 95 'OnFleetStateChange', 96 'OnFleetJumpBeaconModuleChange', 97 'OnFleetJumpBeaconDeployableChange', 98 'OnBridgeModeChange', 99 'OnFleetWingNameChanged', 100 'OnFleetSquadNameChanged', 101 'OnFleetOptionsChanged', 102 'OnMemberlessFleetUnregistered', 103 'OnJoinedFleet', 104 'OnLeftFleet', 105 'OnFleetJoinRequest', 106 'OnFleetJoinRejected', 107 'OnJoinRequestUpdate', 108 'OnContactChange', 109 'OnFleetLootEvent', 110 'OnFleetMotdChanged', 111 'ProcessShutdown', 112 'OnSessionReset', 113 'OnFleetRespawnPointsUpdate'] 114 __startupdependencies__ = ['settings'] 115 __dependencies__ = ['sessionMgr', 'clientPathfinderService'] 116 message_bus = None 117 118 def Run(self, *etc): 119 Service.Run(self, *etc) 120 self.semaphore = uthread.Semaphore() 121 self.message_bus = FleetMessenger(sm.GetService('publicGatewaySvc')) 122 self.Clear() 123 sm.FavourMe(self.OnFleetMemberChanged) 124 fleetBroadcastScopeSetting.on_change.connect(self.OnFleetBroadcastScopeChanged) 125 126 def GetFleetSetups(self): 127 if self.fleetSetupsByName is None: 128 self.characterSettings = sm.GetService('characterSettings') 129 self.fleetSetupsByName = self.FetchFleetSetupsFromServer() 130 return self.fleetSetupsByName 131 132 def FetchFleetSetupsFromServer(self): 133 ret = {} 134 yamlStr = self.characterSettings.Get('fleetSetups') 135 if yamlStr is not None: 136 filters = yaml.safe_load(yamlStr) 137 ret = {f[fsConst.FS_NAME]:f for f in filters} 138 return ret 139 140 def Clear(self): 141 self.leader = None 142 self.initedFleet = None 143 self.members = {} 144 self.wings = {} 145 self.targetTags = {} 146 self.fleetState = None 147 self.activeModuleBeacons = {} 148 self.activeDeployableBeacons = {} 149 self.activeBridge = {} 150 self.fleetID = None 151 self.fleet = None 152 self.favorites = set() 153 self.favoriteOrder = FleetWatchListOrder() 154 self.options = KeyVal(isFreeMove=False, isRegistered=False, autoJoinSquadID=None) 155 self.isDamageUpdates = True 156 self.joinRequests = {} 157 self.CleanupBroadcasts() 158 self.currentBroadcastOnItem = {} 159 self.targetBroadcasts = {} 160 self.currentTargetBroadcast = {} 161 self.locationUpdateRegistrations = {} 162 self.lastBroadcast = KeyVal(name=None, timestamp=0) 163 self.broadcastHistory = [] 164 self.broadcastScope = fleetBroadcastScopeSetting.get() 165 self.updateThreadRunning = False 166 self.updateAdvertThreadRunning = False 167 self.currentFleetAd = None 168 self.lootHistory = [] 169 self.memberHistory = [] 170 self.fleetComposition = None 171 self.fleetCompositionTimestamp = 0 172 self.expectingInvite = None 173 self.motd = None 174 self.fleetSetupsByName = None 175 self.lastLoadedSetup = None 176 self.respawnPoints = [] 177 178 def CleanupBroadcasts(self): 179 for itemID, (gbID, gbState, data) in getattr(self, 'currentBroadcastOnItem', {}).iteritems(): 180 sm.GetService('stateSvc').SetState(itemID, gbState, False, gbID, *data) 181 182 def ProcessShutdown(self): 183 if session.fleetid and len(self.members) > 0: 184 self.LogNotice('I will attempt to reconnect to this fleet', session.fleetid, ' when the client starts up again') 185 settings.char.ui.Set('fleetReconnect', (session.fleetid, blue.os.GetWallclockTime())) 186 settingsSvc = sm.GetServiceIfRunning('settings') 187 if settingsSvc: 188 settingsSvc.SaveSettings() 189 190 def OnSessionReset(self): 191 self.Clear() 192 193 def OnFleetStateChange(self, fleetState): 194 self.fleetState = fleetState 195 196 def OnBridgeModeChange(self, shipID, solarsystemID, itemID, active): 197 self.LogInfo('OnBridgeModeChange called:', shipID, solarsystemID, itemID, active) 198 if active: 199 self.activeBridge[shipID] = (solarsystemID, itemID) 200 elif shipID in self.activeBridge: 201 del self.activeBridge[shipID] 202 203 def OnFleetJumpBeaconModuleChange(self, charID, solarsystemID, beaconID, typeID, active): 204 self.LogInfo('OnFleetJumpBeaconModuleChange:', charID, solarsystemID, beaconID, typeID, active) 205 if active: 206 self.activeModuleBeacons[charID] = (solarsystemID, beaconID, typeID) 207 else: 208 self.activeModuleBeacons.pop(charID, None) 209 210 def OnFleetJumpBeaconDeployableChange(self, deployableID, solarsystemID, beaconID, ownerID, active): 211 self.LogInfo('OnFleetJumpBeaconDeployableChange:', deployableID, solarsystemID, beaconID, active) 212 if active: 213 self.activeDeployableBeacons[deployableID] = (solarsystemID, beaconID, ownerID) 214 else: 215 self.activeDeployableBeacons.pop(deployableID, None) 216 217 def GetTargetTag(self, itemID): 218 if self.fleetState: 219 return self.fleetState.targetTags.get(itemID, None) 220 221 def HasActiveBridge(self, shipID): 222 return shipID in self.activeBridge 223 224 def GetActiveBeacons(self): 225 return self.activeModuleBeacons 226 227 def HasActiveBeacon(self, charID): 228 return charID in self.activeModuleBeacons 229 230 def GetActiveBridgeForShip(self, shipID): 231 if shipID not in self.activeBridge: 232 return None 233 return self.activeBridge[shipID] 234 235 def GetActiveBeaconForChar(self, charID): 236 if charID not in self.activeModuleBeacons: 237 return None 238 return self.activeModuleBeacons[charID] 239 240 def InitFleet(self): 241 if self.fleet is None: 242 return 243 oldOptions = self.options 244 initState = self.fleet.GetInitState() 245 self.fleetID = initState.fleetID 246 self.members = initState.members 247 self.wings = initState.wings 248 self.options = initState.options 249 self.motd = initState.motd 250 cfg.eveowners.Prime(self.members.keys()) 251 self.fleetMemberLocations = {} 252 if oldOptions != self.options: 253 sm.ScatterEvent('OnFleetOptionsChanged_Local', oldOptions, self.options) 254 sm.ScatterEvent('OnMyFleetInfoChanged') 255 sm.ScatterEvent('OnMyFleetInited') 256 uthread2.StartTasklet(self.TryToRestoreWatchlist) 257 258 def TryToRestoreWatchlist(self): 259 self._PruneWatchlistMemberSettings() 260 if not session.fleetid: 261 return 262 watchlistInfoForFleet = settings.char.ui.Get(WATCHLIST_MEMBER_INFO_SETTING_KEY, {}) 263 infoForCurrentFleet = watchlistInfoForFleet.get(session.fleetid, None) 264 if not infoForCurrentFleet: 265 return 266 _, charIDs, column1, column2 = infoForCurrentFleet 267 self.AddFavorite(charIDs, False, False) 268 favorites = self.GetFavorites() 269 column1CharIDs = [ x for x in column1 if x in favorites ] 270 column2CharIDs = [ x for x in column2 if x in favorites ] 271 if column1CharIDs: 272 self.UpdateWatchlistMemberOrder(column1CharIDs, WATCHLIST_COL_1, -1, False) 273 if column2CharIDs: 274 self.UpdateWatchlistMemberOrder(column2CharIDs, WATCHLIST_COL_2, -1, False) 275 sm.ScatterEvent('OnFleetFavoriteAdded') 276 277 def _PruneWatchlistMemberSettings(self): 278 try: 279 watchlistInfoForFleet = settings.char.ui.Get(WATCHLIST_MEMBER_INFO_SETTING_KEY, {}) 280 now = gametime.GetWallclockTime() 281 pruneTime = now - 3 * const.DAY 282 wasPruned = False 283 for fleetID, fleetInfo in watchlistInfoForFleet.items(): 284 timestamp, charIDs, column1, column2 = fleetInfo 285 if timestamp < pruneTime: 286 watchlistInfoForFleet.pop(fleetID, None) 287 wasPruned = True 288 289 if wasPruned: 290 settings.char.ui.Set(WATCHLIST_MEMBER_INFO_SETTING_KEY, watchlistInfoForFleet) 291 except Exception: 292 self.LogException('Failed to _PruneWatchlistSettings') 293 294 def SingleChoiceBox(self, title, body, choices, suppressID): 295 supp = get_supressed_result(suppressID) 296 if supp is not None and not uicore.uilib.Key(uiconst.VK_SHIFT): 297 return supp 298 ret, block = sm.GetService('gameui').RadioButtonMessageBox(text=body, title=title, buttons=uiconst.OKCANCEL, icon=uiconst.QUESTION, radioOptions=choices, height=210, width=300, suppText=localization.GetByLabel('UI/Common/SuppressionShowMessageRemember')) 299 if ret[0] in [uiconst.ID_CANCEL, uiconst.ID_CLOSE]: 300 return 301 retNum = 1 302 if ret[1] == 'radioboxOption2Selected': 303 retNum = 2 304 if block: 305 set_suppress_result(suppressID, retNum) 306 else: 307 set_suppress_result(suppressID, None) 308 return retNum 309 310 def CreateFleet(self, setupName = None, adInfoData = None): 311 if session.fleetid: 312 raise UserError('FleetError') 313 self.fleet = sm.RemoteSvc('fleetObjectHandler').CreateFleet() 314 self.LogInfo('Created fleet %s' % self.fleet) 315 createdAdData = self.fleet.Init(self.GetMyShipTypeID(), setupName, adInfoData=adInfoData) 316 self.InitFleet() 317 self.fleetID = self.fleet.GetFleetID() 318 if createdAdData: 319 createdAd = FleetAdvertObject(**createdAdData) 320 self._FinializeRegistration(createdAd, False) 321 return True 322 323 def StartNewFleet(self, setupName = None): 324 if self.fleet: 325 return 326 self.CreateFleet(setupName) 327 self.LogFleetCreation(self.fleetID, evefleet.CREATE_SOURCE_FLEET_FINDER_WND) 328 329 def Invite(self, charID, wingID, squadID, role): 330 if self.fleet is None: 331 if not self.CreateFleet(): 332 return 333 self.LogFleetCreation(self.fleetID, evefleet.CREATE_SOURCE_MENU) 334 if IsNPC(charID) or not IsCharacter(charID): 335 prompt_player_fsd_dialog('NotRealPilotInvite') 336 return 337 msgName = None 338 if charID != session.charid: 339 CSPAChargedAction('CSPAFleetCheck', self.fleet, 'Invite', charID, wingID, squadID, role) 340 341 def LeaveFleet(self): 342 if self.fleet is None and session.fleetid: 343 sm.RemoteSvc('fleetMgr').ForceLeaveFleet() 344 else: 345 self.fleet.LeaveFleet() 346 self.Clear() 347 348 def IsMember(self, charID): 349 return charID in self.members 350 351 def GetMembers(self): 352 return self.members 353 354 def GetWings(self): 355 if self.fleet is None: 356 return {} 357 return self.wings 358 359 def GetMembersInWing(self, wingID): 360 members = {} 361 for mid, m in self.members.iteritems(): 362 if m.wingID == wingID: 363 members[mid] = m 364 365 return members 366 367 def GetMembersInSquad(self, squadID): 368 members = {} 369 for mid, m in self.members.iteritems(): 370 if m.squadID == squadID: 371 members[mid] = m 372 373 return members 374 375 def ChangeWingName(self, wingID): 376 if self.fleet is None: 377 return 378 name = '' 379 ret = utilWindows.NamePopup(localization.GetByLabel('UI/Fleet/ChangeWingName'), localization.GetByLabel('UI/Common/Name/TypeInName'), name, maxLength=evefleet.MAX_NAME_LENGTH) 380 if ret is not None: 381 self.fleet.ChangeWingName(wingID, ret[:evefleet.MAX_NAME_LENGTH]) 382 383 def ChangeSquadName(self, squadID): 384 if self.fleet is None: 385 return 386 name = '' 387 ret = utilWindows.NamePopup(localization.GetByLabel('UI/Fleet/ChangeSquadName'), localization.GetByLabel('UI/Common/Name/TypeInName'), name, maxLength=evefleet.MAX_NAME_LENGTH) 388 if ret is not None: 389 self.fleet.ChangeSquadName(squadID, ret[:evefleet.MAX_NAME_LENGTH]) 390 391 def SetAcceptsFleetWarpValue(self, value): 392 self.fleet.SetTakesFleetWarp(value) 393 394 def SetAcceptConduitJumpsValue(self, value): 395 self.fleet.SetAcceptsConduitJumpsValue(value) 396 397 def SetAcceptRegroupValue(self, value): 398 self.fleet.SetAcceptsRegroupValue(value) 399 400 def TakesFleetWarp(self): 401 return self.members[session.charid].memberOptOuts.acceptsFleetWarp 402 403 def AcceptsConduitJumps(self): 404 return self.members[session.charid].memberOptOuts.acceptsConduitJumps 405 406 def AcceptsFleetRegroups(self): 407 return self.members[session.charid].memberOptOuts.acceptsFleetRegroups 408 409 def GetOptions(self): 410 return self.options 411 412 def SetOptions(self, isFreeMove = None): 413 options = copy.copy(self.options) 414 if isFreeMove != None: 415 options.isFreeMove = isFreeMove 416 return self.fleet.SetOptions(options) 417 418 def SetDamageUpdates(self, isit): 419 self.isDamageUpdates = isit 420 self.RegisterForDamageUpdates() 421 422 def IsDamageUpdates(self): 423 return self.isDamageUpdates 424 425 def GetJoinRequests(self): 426 if not self.joinRequests: 427 self.joinRequests = self.fleet.GetJoinRequests() 428 return self.joinRequests 429 430 def GetFleetHierarchy(self, members = None): 431 if members is None: 432 members = self.GetMembers() 433 ret = {'commander': None, 434 'wings': {}, 435 'squads': {}, 436 'name': ''} 437 for wingID, wing in self.GetWings().iteritems(): 438 ret['wings'][wingID] = {'commander': None, 439 'squads': wing.squads.keys(), 440 'name': wing.name} 441 for squadID, squad in wing.squads.iteritems(): 442 ret['squads'][squadID] = {'commander': None, 443 'members': [], 444 'name': squad.name} 445 446 for rec in members.itervalues(): 447 if rec.squadID: 448 self.AddToFleet(ret, rec) 449 450 return ret 451 452 def AddToFleet(self, fleet, rec): 453 try: 454 if rec.squadID != -1: 455 allSquads = fleet['squads'] 456 squad = allSquads[rec.squadID] 457 if rec.role == evefleet.fleetRoleSquadCmdr: 458 squad['commander'] = rec.charID 459 squad['members'].insert(0, rec.charID) 460 elif rec.role == evefleet.fleetRoleMember: 461 squad['members'].append(rec.charID) 462 else: 463 log.LogError('Unknown role in squad!', rec.role) 464 elif rec.wingID != -1: 465 allWings = fleet['wings'] 466 wing = allWings[rec.wingID] 467 if rec.role == evefleet.fleetRoleWingCmdr: 468 wing['commander'] = rec.charID 469 elif rec.role == evefleet.fleetRoleLeader: 470 fleet['commander'] = rec.charID 471 else: 472 log.LogTraceback("Don't know how to add this guy! {!r}".format(rec)) 473 except KeyError as e: 474 log.LogTraceback() 475 476 def CheckIfIsOKWithDemotion(self, role): 477 myself = self.members[session.charid] 478 if myself.job & evefleet.fleetJobCreator != 0: 479 return True 480 if myself.role < evefleet.fleetRoleSquadCmdr and role > myself.role and prompt_player_fsd_dialog('FleetConfirmDemoteSelf', {}, uiconst.YESNO) != uiconst.ID_YES: 481 return False 482 return True 483 484 def MoveMember(self, charID, wingID, squadID, role): 485 self.CheckIsInFleet() 486 if charID == session.charid: 487 if not self.CheckIfIsOKWithDemotion(role): 488 return 489 if self.fleet.MoveMember(charID, wingID, squadID, role): 490 sm.ScatterEvent('OnFleetMemberChanging', charID) 491 492 def MassMove(self, charIDs, wingID, squadID, role): 493 charIDs = self.FilterOutNonCharacters(charIDs) 494 if len(charIDs) == 1: 495 return self.MoveMember(charIDs[0], wingID, squadID, role) 496 if session.charid in charIDs: 497 isOkWithDemotion = self.CheckIfIsOKWithDemotion(role=role) 498 if not isOkWithDemotion: 499 charIDs.remove(session.charid) 500 if charIDs: 501 wereMoved = self.fleet.MassMoveMembers(charIDs, wingID, squadID, role) 502 if wereMoved: 503 sm.ScatterEvent('OnManyFleetMembersChanging', wereMoved) 504 505 def MassInvite(self, charIDs, wingID, squadID, role): 506 charIDs = self.FilterOutNonCharacters(charIDs) 507 if self.fleet is None and charIDs: 508 if not self.CreateFleet(): 509 return 510 if session.charid in charIDs: 511 charIDs.remove(session.charid) 512 if len(charIDs) == 1: 513 charID = charIDs[0] 514 self.Invite(charID, wingID, squadID, role) 515 if role == evefleet.fleetRoleMember: 516 prompt_player_fsd_dialog('CharacterAddedAsSquadMember', {'char': charID}) 517 elif role == evefleet.fleetRoleSquadCmdr: 518 prompt_player_fsd_dialog('CharacterAddedAsSquadCommander', {'char': charID}) 519 elif role == evefleet.fleetRoleWingCmdr: 520 prompt_player_fsd_dialog('CharacterAddedAsWingCommander', {'char': charID}) 521 elif role == evefleet.fleetRoleLeader: 522 prompt_player_fsd_dialog('CharacterAddedAsFleetCommander', {'char': charID}) 523 elif charIDs: 524 try: 525 CSPAChargedActionForMany('CSPAFleetCheckMany', self.fleet, 'MassInvite', charIDs, wingID, squadID, role) 526 except UserError as e: 527 if e.msg in ('FleetErrorMany', 'FleetNotAllowedMany', 'FleetNoPositionFoundMany', 'FleetTooManyMembersMany', 'FleetInviteMultipleErrors'): 528 notInvited = e.dict.get('notInvited', []) 529 charNameList = [ cfg.eveowners.Get(charID).name for charID in notInvited ] 530 charNames = ', '.join(charNameList) 531 if e.dict: 532 e.dict['namelist'] = charNames 533 raise UserError(e.msg, e.dict) 534 else: 535 raise 536 537 def FilterOutNonCharacters(self, charIDs): 538 realCharIDs = [ eachID for eachID in charIDs if not IsNPC(eachID) and IsCharacter(eachID) ] 539 return realCharIDs 540 541 def CreateWing(self): 542 self.CheckIsInFleet() 543 wingID = self.fleet.CreateWing() 544 if wingID: 545 self.CreateSquad(wingID) 546 547 def DeleteWing(self, wingID): 548 self.CheckIsInFleet() 549 self.fleet.DeleteWing(wingID) 550 551 def CreateSquad(self, wingID): 552 self.CheckIsInFleet() 553 self.fleet.CreateSquad(wingID) 554 555 def DeleteSquad(self, wingID): 556 self.CheckIsInFleet() 557 self.fleet.DeleteSquad(wingID) 558 559 def SetAutoJoinSquadID(self, squadID): 560 self.fleet.SetAutoJoinSquadID(squadID) 561 562 def MakeLeader(self, charID): 563 name = evelink.character_link(charID) 564 if prompt_player_fsd_dialog('ConfirmMakeFleetBoss', {'charName': name}, uiconst.YESNO, suppress=uiconst.ID_YES, default=uiconst.ID_NO) == uiconst.ID_YES: 565 self.fleet.MakeLeader(charID) 566 567 def KickMember(self, charID): 568 if charID == session.charid: 569 self.LeaveFleet() 570 else: 571 self.fleet.KickMember(charID) 572 573 def DisbandFleet(self): 574 if not self.IsBoss(): 575 raise UserError('CannotDisbandFleetIfNotBoss') 576 self.fleet.DisbandFleet() 577 578 def __VerifyRightsToRestrict(self, channel): 579 return True 580 ret = False 581 if session.fleetrole > 3: 582 ret = False 583 elif session.fleetrole == 3: 584 squads = self.GetFleetHierarchy()['squads'] 585 if squads[channel]['commander'] == session.charid: 586 ret = True 587 elif session.fleetrole == 2: 588 wings = self.GetFleetHierarchy()['wings'] 589 if wings[channel]['commander'] == session.charid: 590 ret = True 591 elif session.fleetrole == 1: 592 if session.fleetid == channel[1]: 593 ret = True 594 if not ret: 595 raise UserError('FleetNotAllowed') 596 597 def AddFavorite(self, charIDs, updateOrder = True, updateWnd = True): 598 self.CheckIsInFleet() 599 if session.charid in charIDs: 600 charIDs.remove(session.charid) 601 if not charIDs: 602 return 603 if len(self.favorites) >= evefleet.MAX_DAMAGE_SENDERS: 604 raise UserError('FleetTooManyFavorites', {'num': evefleet.MAX_DAMAGE_SENDERS}) 605 newCharIDs = [] 606 for eachCharID in charIDs: 607 if eachCharID not in self.members: 608 continue 609 if self.GetFavorite(eachCharID): 610 continue 611 newCharIDs.append(eachCharID) 612 613 if not newCharIDs: 614 return 615 newCharsAdded = [] 616 for eachCharID in newCharIDs: 617 if len(self.favorites) >= evefleet.MAX_DAMAGE_SENDERS: 618 break 619 self.favorites.add(eachCharID) 620 newCharsAdded.append(eachCharID) 621 622 if not newCharsAdded: 623 return 624 fav = self.GetWatchlistMembers() 625 sm.RemoteSvc('fleetMgr').AddToWatchlist(newCharsAdded, fav) 626 if updateOrder: 627 self.UpdateWatchlistMemberOrder(newCharsAdded, WATCHLIST_COL_1, -1, False) 628 else: 629 self.UpdateWatchlistSettings() 630 if updateWnd: 631 sm.ScatterEvent('OnFleetFavoriteAdded') 632 wnd = WatchListPanel.Open(showActions=False, panelName=localization.GetByLabel('UI/Fleet/WatchList')) 633 wnd.OnFleetFavoriteAdded() 634 635 def UpdateWatchlistMemberOrder(self, allAffectedIDs, scrollColumnID, idx, allowMove): 636 self.favoriteOrder.UpdateOrder(allAffectedIDs, scrollColumnID, idx, allowMove) 637 self.UpdateWatchlistSettings() 638 639 def UpdateWatchlistSettings(self): 640 try: 641 if not session.fleetid: 642 return 643 watchlistInfoForFleet = settings.char.ui.Get(WATCHLIST_MEMBER_INFO_SETTING_KEY, {}) 644 watchlistInfoForFleet[session.fleetid] = (gametime.GetWallclockTime(), 645 self.GetFavorites().copy(), 646 self.favoriteOrder.GetColumn1Order(), 647 self.favoriteOrder.GetColumn2Order()) 648 settings.char.ui.Set(WATCHLIST_MEMBER_INFO_SETTING_KEY, watchlistInfoForFleet) 649 except Exception: 650 self.LogException('Failed to update watchlist settings') 651 652 def AddFavoriteSquad(self, squadID): 653 squadMembers = [ memberID for memberID, m in self.members.iteritems() if m.squadID == squadID ] 654 self.AddFavorite(squadMembers) 655 656 def GetFavorite(self, charID): 657 return charID in self.favorites 658 659 def RemoveAllFavorites(self): 660 self.favorites.clear() 661 self.favoriteOrder.Reset() 662 self.UpdateWatchlistSettings() 663 sm.ScatterEvent('OnFleetFavoritesRemoved') 664 665 def RemoveFavorite(self, charID): 666 self.CheckIsInFleet() 667 self.favorites.discard(charID) 668 favs = self.GetWatchlistMembers() 669 sm.RemoteSvc('fleetMgr').RemoveFromWatchlist(charID, favs) 670 self.favoriteOrder.RemoveFromOrderedLists(charID) 671 sm.ScatterEvent('OnFleetFavoriteRemoved', charID) 672 self.UpdateWatchlistSettings() 673 674 def ClearWatchlistBroadcastHistory(self): 675 wnd = WatchListPanel.GetIfOpen() 676 if wnd and not wnd.destroyed: 677 wnd.ClearBroadcastHistory() 678 prompt_player_fsd_dialog('CustomNotify', {'notify': localization.GetByLabel('UI/Fleet/BroadcastIconsCleared')}) 679 680 def ChangeFavoriteSorting(self, charID, orderID = -1, *args): 681 if getattr(self, 'isChangingOrder', False): 682 return 683 try: 684 setattr(self, 'isChangingOrder', True) 685 favorite = self.GetFavorite(charID) 686 if not favorite: 687 return 688 favoriteIndex = favorite.orderID 689 if favoriteIndex < 0: 690 return 691 if favoriteIndex > len(self.favorites): 692 return 693 self.favorites.remove(favorite) 694 if orderID == -1: 695 orderID = len(self.favorites) 696 newFavorite = KeyVal(charID=charID, orderID=orderID) 697 self.favorites.insert(orderID, newFavorite) 698 finally: 699 setattr(self, 'isChangingOrder', False) 700 701 def CloseWatchlistWindow(self): 702 WatchListPanel.CloseIfOpen() 703 704 def CloseFleetSetupList(self): 705 StoredFleetSetupListWnd.CloseIfOpen() 706 707 def GetFavorites(self): 708 return self.favorites 709 710 def IsFavorite(self, charid): 711 return charid in self.favorites 712 713 def GetMemberInfo(self, charID, fleetHierarchy = None): 714 member = self.members.get(charID, None) 715 if member is None: 716 return 717 wing = self.wings.get(member.wingID, None) 718 wingName = squadName = '' 719 fleet = fleetHierarchy or self.GetFleetHierarchy() 720 if wing: 721 wingName = WingName(fleet, wingID=member.wingID) 722 squad = wing.squads.get(member.squadID, None) 723 if squad: 724 squadName = SquadronName(fleet, squadID=member.squadID) 725 jobName = '' 726 if member.job & evefleet.fleetJobCreator: 727 jobName = localization.GetByLabel('UI/Fleet/Ranks/Boss') 728 roleName = fleetbroadcastexports.GetRankName(member) 729 return KeyVal(charID=charID, charName=cfg.eveowners.Get(charID).name, wingID=member.wingID, wingName=wingName, squadID=member.squadID, squadName=squadName, role=member.role, roleName=roleName, job=member.job, jobName=jobName) 730 731 def GetWatchlistMembers(self): 732 if self.isDamageUpdates: 733 return self.favorites 734 735 def RegisterForDamageUpdates(self): 736 fav = self.GetWatchlistMembers() 737 sm.RemoteSvc('fleetMgr').RegisterForDamageUpdates(fav) 738 739 def Regroup(self): 740 bp = sm.GetService('michelle').GetRemotePark() 741 if bp is not None: 742 bp.CmdFleetRegroup() 743 prompt_player_fsd_dialog('CustomNotify', {'notify': localization.GetByLabel('UI/Fleet/Regrouping')}) 744 745 def GetNearestBall(self, fromBall = None, getDist = 0): 746 ballPark = sm.GetService('michelle').GetBallpark() 747 if not ballPark: 748 return 749 lst = [] 750 validNearBy = {groupAsteroidBelt, 751 groupMoon, 752 groupPlanet, 753 groupWarpGate, 754 groupStargate, 755 groupStation} | evetypes.GetGroupIDsByCategory(const.categoryStructure) 756 for ballID, ball in ballPark.balls.iteritems(): 757 slimItem = ballPark.GetInvItem(ballID) 758 if slimItem and slimItem.groupID in validNearBy: 759 if fromBall: 760 dist = trinity.TriVector(ball.x - fromBall.x, ball.y - fromBall.y, ball.z - fromBall.z).Length() 761 lst.append((dist, ball)) 762 else: 763 lst.append((ball.surfaceDist, slimItem)) 764 765 lst.sort() 766 if getDist: 767 return lst[0] 768 if lst: 769 return lst[0][1] 770 771 def CurrentFleetBroadcastOnItem(self, itemID, gbType = None): 772 currGBID, currGBType, currGBData = self.currentBroadcastOnItem.get(itemID, (None, None, None)) 773 if gbType in (None, currGBType): 774 return currGBData 775 else: 776 return 777 778 def GetCurrentFleetBroadcastOnItem(self, itemID): 779 return self.currentBroadcastOnItem.get(itemID, (None, None, None)) 780 781 def GetCurrentFleetBroadcasts(self): 782 return self.currentBroadcastOnItem 783 784 def CheckIsInFleet(self, inSpace = False): 785 if self.fleet is None: 786 if inSpace: 787 raise UserError('FleetNotInFleetInSpace') 788 raise UserError('FleetNotInFleet') 789 if inSpace: 790 if not session.solarsystemid: 791 raise UserError('FleetCannotDoInStation') 792 if IsDockedInStructure(): 793 raise UserError('FleetCannotDoInStructure') 794 795 def CheckCanAddFavorite(self, charid): 796 if charid == session.charid: 797 return False 798 if self.fleet is None: 799 return False 800 if not self.IsMember(charid): 801 return False 802 if self.IsFavorite(charid): 803 return False 804 return True 805 806 def CheckCanMoveFavorite(self, charid): 807 if charid == session.charid: 808 return False 809 if self.fleet is None: 810 return False 811 if not self.IsMember(charid): 812 return False 813 if self.IsFavorite(charid): 814 return True 815 return True 816 817 def GetFleetLocationAndInfo(self): 818 ret = sm.GetService('michelle').GetRemotePark().GetFleetLocationAndInfo() 819 for memberID, inf in ret.iteritems(): 820 ball = KeyVal(x=inf.pos[0], y=inf.pos[1], z=inf.pos[2]) 821 nearestBallID = self.GetNearestBall(ball).itemID 822 inf.nearestBallID = nearestBallID 823 824 return ret 825 826 def GetFleetComposition(self): 827 if self.fleet is None: 828 return 829 now = blue.os.GetWallclockTime() 830 if self.fleetCompositionTimestamp < now: 831 self.LogInfo('Fetching fleet composition') 832 self.fleetComposition = self.fleet.GetFleetComposition() 833 self.fleetCompositionTimestamp = now + FLEETCOMPOSITION_CACHE_TIME * SEC 834 return self.fleetComposition 835 836 def DistanceToFleetMate(self, solarSystemID, nearID): 837 toSystem = cfg.evelocations.Get(solarSystemID) 838 if toSystem is None or session.solarsystemid2 is None: 839 raise AttributeError('Invalid solarsystem') 840 fromSystem = cfg.evelocations.Get(session.solarsystemid2) 841 dist = uix.GetLightYearDistance(fromSystem, toSystem) 842 if dist is None: 843 prompt_player_fsd_dialog('MapDistanceUnknown', {'fromSystem': cfg.FormatConvert(UE_LOCID, session.solarsystemid2), 844 'toSystem': cfg.FormatConvert(UE_LOCID, solarSystemID)}) 845 else: 846 jumps = self.clientPathfinderService.GetJumpCountFromCurrent(solarSystemID) 847 prompt_player_fsd_dialog('MapDistance', {'fromSystem': cfg.FormatConvert(UE_LOCID, session.solarsystemid2), 848 'toSystem': cfg.FormatConvert(UE_LOCID, solarSystemID), 849 'dist': dist, 850 'jumps': jumps}) 851 852 def RejectJoinRequest(self, charID): 853 self.fleet.RejectJoinRequest(charID) 854 855 def CanUpdateAdvert(self): 856 if session.fleetid is None: 857 return False 858 if not self.IsBoss(): 859 return False 860 if not self.IsFleetRegistered(): 861 return False 862 return True 863 864 def IsFleetRegistered(self): 865 return getattr(self.options, 'isRegistered', False) 866 867 def RemoveAndUpdateFleetFinderAdvert(self, what): 868 if not self.CanUpdateAdvert(): 869 return 870 fleetAd = self.RemoveFleetFinderAdvert() 871 if fleetAd: 872 if prompt_player_fsd_dialog('FleetUpdateFleetFinderAd_%s' % what, {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 873 sm.GetService('agencyNew').OpenWindow(contentGroupConst.contentGroupFleetUpRegister) 874 875 def TryUpdateFleetFinderAdvertWithNewBoss(self): 876 if not self.CanUpdateAdvert(): 877 return 878 advertInfo = self.GetMyFleetFinderAdvert() 879 if advertInfo and advertInfo.updateOnBossChange: 880 allowedInfoFromStandings = self.GetAllowedAndBannedEntitiesFromStandings(advertInfo) 881 allowedEntitiesInfo = KeyVal(membergroups_allowedEntities=allowedInfoFromStandings['membergroupsAllowedEntities'], public_allowedEntities=allowedInfoFromStandings['publicAllowedEntities'], membergroups_disallowedEntities=allowedInfoFromStandings['membergroupsDisallowedEntities'], public_disallowedEntities=allowedInfoFromStandings['publicDisallowedEntities']) 882 fleetAdvert = self.UpdateFleetAdvertWithNewLeader(allowedEntitiesInfo) 883 if fleetAdvert: 884 self.currentFleetAd = fleetAdvert 885 prompt_player_fsd_dialog('FleetUpdateFleetFinderAd_NewBoss2') 886 return 887 self.currentFleetAd = None 888 self.RemoveAndUpdateFleetFinderAdvert('NewBoss') 889 890 def BroadcastTimeRestriction(self, name): 891 if self.IsTimeRestricted(name): 892 self.LogInfo('Will not send broadcast', name, 'as not enough time has passed since the last one') 893 return True 894 else: 895 self.lastBroadcast.name = name 896 self.lastBroadcast.timestamp = blue.os.GetWallclockTime() 897 return False 898 899 def IsTimeRestricted(self, name): 900 lastBroadcastTime = self.lastBroadcast.timestamp 901 if self.lastBroadcast.name == name: 902 nextAllowedBroadcast = lastBroadcastTime + MIN_BROADCAST_TIME * SEC 903 else: 904 nextAllowedBroadcast = lastBroadcastTime + int(float(MIN_BROADCAST_TIME) / 3.0 * float(SEC)) 905 if nextAllowedBroadcast > blue.os.GetWallclockTime(): 906 return True 907 return False 908 909 def SendGlobalBroadcast(self, name, itemID, typeID = None): 910 self.CheckIsInFleet(inSpace=True) 911 if self.BroadcastTimeRestriction(name): 912 return 913 if name not in evefleet.ALL_BROADCASTS: 914 raise RuntimeError('Illegal broadcast') 915 self.fleet.SendBroadcast(name, self.broadcastScope, itemID, typeID) 916 917 def SendBubbleBroadcast(self, name, itemID, typeID = None): 918 self.CheckIsInFleet(inSpace=True) 919 if self.BroadcastTimeRestriction(name): 920 return 921 if name not in evefleet.ALL_BROADCASTS: 922 raise RuntimeError('Illegal broadcast') 923 sm.RemoteSvc('fleetMgr').BroadcastToBubble(name, self.broadcastScope, itemID, typeID) 924 925 def SendSystemBroadcast(self, name, itemID, typeID = None): 926 self.CheckIsInFleet(inSpace=True) 927 if self.BroadcastTimeRestriction(name): 928 return 929 if name not in evefleet.ALL_BROADCASTS: 930 raise RuntimeError('Illegal broadcast') 931 sm.RemoteSvc('fleetMgr').BroadcastToSystem(name, self.broadcastScope, itemID, typeID) 932 933 def SendBroadcast_EnemySpotted(self): 934 nearestBall = self.GetNearestBall() 935 nearID = None 936 if nearestBall is not None: 937 nearID = nearestBall.itemID 938 self.SendGlobalBroadcast(evefleet.BROADCAST_ENEMY_SPOTTED, nearID) 939 940 def SendBroadcast_NeedBackup(self): 941 nearestBall = self.GetNearestBall() 942 nearID = None 943 if nearestBall is not None: 944 nearID = nearestBall.itemID 945 self.SendGlobalBroadcast(evefleet.BROADCAST_NEED_BACKUP, nearID) 946 947 def SendBroadcast_HoldPosition(self): 948 nearestBall = self.GetNearestBall() 949 nearID = None 950 if nearestBall is not None: 951 nearID = nearestBall.itemID 952 self.SendGlobalBroadcast(evefleet.BROADCAST_HOLD_POSITION, nearID) 953 954 def SendBroadcast_TravelTo(self, solarSystemID): 955 self.SendGlobalBroadcast(evefleet.BROADCAST_TRAVEL_TO, solarSystemID) 956 957 def SendBroadcast_HealArmor(self): 958 self.SendBubbleBroadcast(evefleet.BROADCAST_HEAL_ARMOR, session.shipid) 959 960 def SendBroadcast_HealShield(self): 961 self.SendBubbleBroadcast(evefleet.BROADCAST_HEAL_SHIELD, session.shipid) 962 963 def SendBroadcast_HealCapacitor(self): 964 self.SendBubbleBroadcast(evefleet.BROADCAST_HEAL_CAPACITOR, session.shipid) 965 966 def SendBroadcast_Target(self, itemID): 967 self.SendBubbleBroadcast(evefleet.BROADCAST_TARGET, itemID) 968 969 def SendBroadcast_Heal_Target(self, itemID): 970 self.SendBubbleBroadcast(evefleet.BROADCAST_REP_TARGET, itemID) 971 972 def SendBroadcast_WarpToItemID(self, itemID): 973 typeID = self._GetTypeIDForItemID(itemID) 974 if not self.CanAlignOrWarpToTypeID(typeID): 975 return 976 return self.SendBroadcast_WarpTo(itemID, typeID) 977 978 def SendBroadcast_AlignToItemID(self, itemID): 979 typeID = self._GetTypeIDForItemID(itemID) 980 if not self.CanAlignOrWarpToTypeID(typeID): 981 return 982 return self.SendBroadcast_AlignTo(itemID, typeID) 983 984 def SendBroadcast_JumpToItemID(self, itemID): 985 typeID = self._GetTypeIDForItemID(itemID) 986 if typeID is None or evetypes.GetGroupID(typeID) != const.groupStargate: 987 return 988 return self.SendBroadcast_JumpTo(itemID, typeID) 989 990 def _GetTypeIDForItemID(self, itemID): 991 bp = sm.GetService('michelle').GetBallpark() 992 slimItem = bp.GetInvItem(itemID) 993 if not slimItem: 994 return None 995 return slimItem.typeID 996 997 def CanAlignOrWarpToTypeID(self, typeID): 998 if typeID is None: 999 return False 1000 categoryID = evetypes.GetCategoryID(typeID) 1001 if categoryID in (const.categoryEntity, 1002 const.categoryDrone, 1003 const.categoryShip, 1004 const.categoryFighter): 1005 return False 1006 return True 1007 1008 def SendBroadcast_WarpTo(self, itemID, typeID): 1009 self.SendSystemBroadcast(evefleet.BROADCAST_WARP_TO, itemID, typeID) 1010 1011 def SendBroadcast_AlignTo(self, itemID, typeID): 1012 self.SendSystemBroadcast(evefleet.BROADCAST_ALIGN_TO, itemID, typeID) 1013 1014 def SendBroadcast_JumpTo(self, itemID, typeID): 1015 self.SendSystemBroadcast(evefleet.BROADCAST_JUMP_TO, itemID, typeID) 1016 1017 def SendBroadcast_InPosition(self): 1018 nearestBall = self.GetNearestBall() 1019 nearID = None 1020 typeID = None 1021 if nearestBall is not None: 1022 nearID = nearestBall.itemID 1023 typeID = nearestBall.typeID 1024 self.SendGlobalBroadcast(evefleet.BROADCAST_IN_POSITION, nearID, typeID) 1025 1026 def SendBroadcast_JumpBeacon(self): 1027 beacon = self.GetActiveBeaconForChar(session.charid) 1028 if beacon is None: 1029 raise UserError('NoActiveBeacon') 1030 self.SendGlobalBroadcast(evefleet.BROADCAST_JUMP_BEACON, beacon[1], beacon[2]) 1031 1032 def SendBroadcast_Location(self): 1033 locationID = session.solarsystemid2 1034 nearestBall = self.GetNearestBall() 1035 nearID = None 1036 if nearestBall is not None: 1037 nearID = nearestBall.itemID 1038 self.SendGlobalBroadcast('Location', nearID) 1039 1040 def SendBroadcast(self, broadcastID, *args): 1041 if broadcastID == evefleet.BROADCAST_LOCATION: 1042 self.SendBroadcast_Location(*args) 1043 elif broadcastID == evefleet.BROADCAST_JUMP_BEACON: 1044 self.SendBroadcast_JumpBeacon(*args) 1045 elif broadcastID == evefleet.BROADCAST_HOLD_POSITION: 1046 self.SendBroadcast_HoldPosition(*args) 1047 elif broadcastID == evefleet.BROADCAST_TRAVEL_TO: 1048 self.SendBroadcast_TravelTo(*args) 1049 elif broadcastID == evefleet.BROADCAST_JUMP_TO: 1050 self.SendBroadcast_JumpTo(*args) 1051 elif broadcastID == evefleet.BROADCAST_ALIGN_TO: 1052 self.SendBroadcast_AlignTo(*args) 1053 elif broadcastID == evefleet.BROADCAST_NEED_BACKUP: 1054 self.SendBroadcast_NeedBackup(*args) 1055 elif broadcastID == evefleet.BROADCAST_WARP_TO: 1056 self.SendBroadcast_WarpTo(*args) 1057 elif broadcastID == evefleet.BROADCAST_HEAL_CAPACITOR: 1058 self.SendBroadcast_HealCapacitor(*args) 1059 elif broadcastID == evefleet.BROADCAST_HEAL_SHIELD: 1060 self.SendBroadcast_HealShield(*args) 1061 elif broadcastID == evefleet.BROADCAST_HEAL_ARMOR: 1062 self.SendBroadcast_HealArmor(*args) 1063 elif broadcastID == evefleet.BROADCAST_TARGET: 1064 self.SendBroadcast_Target(*args) 1065 elif broadcastID == evefleet.BROADCAST_REP_TARGET: 1066 self.SendBroadcast_Heal_Target(*args) 1067 elif broadcastID == evefleet.BROADCAST_ENEMY_SPOTTED: 1068 self.SendBroadcast_EnemySpotted(*args) 1069 elif broadcastID == evefleet.BROADCAST_IN_POSITION: 1070 self.SendBroadcast_InPosition(*args) 1071 1072 def OnFleetWingNameChanged(self, wingID, name): 1073 self.wings = self.fleet.GetWings() 1074 sm.ScatterEvent('OnFleetWingNameChanged_Local', wingID, name) 1075 sm.ScatterEvent('OnMyFleetInfoChanged') 1076 1077 def OnFleetSquadNameChanged(self, squadID, name): 1078 self.wings = self.fleet.GetWings() 1079 sm.ScatterEvent('OnFleetSquadNameChanged_Local', squadID, name) 1080 sm.ScatterEvent('OnMyFleetInfoChanged') 1081 1082 def OnFleetInvite(self, fleetID, inviteID, msgName, msgDict): 1083 autoAccept = msgDict.get('autoAccept', False) 1084 __fleetMoniker = GetFleet(fleetID) 1085 if session.fleetid is not None: 1086 __fleetMoniker.RejectInvite(True) 1087 return 1088 if settings.user.ui.Get('autoRejectInvitations', 0) and self.expectingInvite != fleetID and not autoAccept: 1089 __fleetMoniker.RejectInvite(False) 1090 return 1091 if CommandBlockerService.instance().is_blocked(['window.open.fleetwindow']): 1092 __fleetMoniker.RejectInvite(False) 1093 return 1094 self.expectingInvite = None 1095 try: 1096 name = evelink.character_link(inviteID) 1097 msgDict['name'] = name 1098 if autoAccept or prompt_player_fsd_dialog(msgName, msgDict, uiconst.YESNO, default=uiconst.ID_NO, modal=False) == uiconst.ID_YES: 1099 self.sessionMgr.PerformSelectiveSessionChange('fleet.', 'fleet.acceptinvite', True, __fleetMoniker.AcceptInvite, self.GetMyShipTypeID()) 1100 self.fleet = __fleetMoniker 1101 self.InitFleet() 1102 else: 1103 __fleetMoniker.RejectInvite() 1104 except UserError as e: 1105 prompt_player_fsd_dialog(e.msg, e.dict) 1106 1107 def OnFleetJoin(self, member): 1108 if member.charID == session.charid: 1109 self.InitFleet() 1110 sm.GetService('tactical').InvalidateFlags() 1111 else: 1112 self.members[member.charID] = member 1113 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/MemberHistoryJoined', charID=member.charID, role=fleetbroadcastexports.GetRankName(member)) 1114 self.AddToMemberHistory(member.charID, label) 1115 self.UpdateFleetFinderInfo() 1116 sm.GetService('tactical').InvalidateFlagsExtraLimited(member.charID) 1117 sm.ScatterEvent('OnFleetJoin_Local', member) 1118 1119 def OnFleetJoinReject(self, memberID, reasonCode): 1120 if reasonCode and reasonCode in evefleet.fleetRejectionReasons: 1121 reason = localization.GetByLabel(evefleet.fleetRejectionReasons[reasonCode]) 1122 msg = localization.GetByLabel('UI/Fleet/InviteRejectedWithReason', charID=memberID, reason=reason) 1123 else: 1124 msg = localization.GetByLabel('UI/Fleet/InviteRejected', charID=memberID) 1125 prompt_player_fsd_dialog('CustomNotify', {'notify': msg}) 1126 1127 def OnFleetLeave(self, charID): 1128 self._OnFleetLeave(charID) 1129 1130 def _OnFleetLeave(self, charID): 1131 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/MemberHistoryLeft', charID=charID) 1132 self.AddToMemberHistory(charID, label) 1133 if charID == session.charid: 1134 self.Clear() 1135 if charID in self.members: 1136 rec = self.members.pop(charID) 1137 sm.GetService('tactical').InvalidateFlagsExtraLimited(charID) 1138 else: 1139 rec = KeyVal(charID=charID) 1140 if charID in self.activeModuleBeacons: 1141 del self.activeModuleBeacons[charID] 1142 if charID in self.activeBridge: 1143 del self.activeBridge[charID] 1144 if self.IsFavorite(charID): 1145 self.RemoveFavorite(charID) 1146 if charID == self.leader: 1147 self.leader = None 1148 if charID != session.charid: 1149 self.UpdateFleetFinderInfo() 1150 sm.ScatterEvent('OnFleetLeave_Local', rec) 1151 1152 def OnFleetDisbanded(self, charIDs): 1153 for charID in charIDs: 1154 self._OnFleetLeave(charID) 1155 1156 def OnFleetMemberChanged(self, charID, fleetID, oldWingID, oldSquadID, oldRole, oldJob, oldMemberOptOuts, newWingID, newSquadID, newRole, newJob, newMemberOptOuts, isOnlyMember): 1157 self.members[charID] = KeyVal() 1158 self.members[charID].charID = charID 1159 self.members[charID].wingID = newWingID 1160 self.members[charID].squadID = newSquadID 1161 self.members[charID].role = newRole 1162 self.members[charID].job = newJob 1163 self.members[charID].memberOptOuts = newMemberOptOuts 1164 sm.ScatterEvent('OnFleetMemberChanged_Local', charID, fleetID, oldWingID, oldSquadID, oldRole, oldJob, oldMemberOptOuts, newWingID, newSquadID, newRole, newJob, newMemberOptOuts) 1165 if oldRole != newRole: 1166 roleLabel = localization.GetByLabel('UI/Fleet/FleetBroadcast/MemberHistoryChangedRole', charID=charID, role=fleetbroadcastexports.GetRoleName(newRole)) 1167 self.AddToMemberHistory(charID, roleLabel) 1168 if oldJob != newJob: 1169 if newJob & evefleet.fleetJobCreator: 1170 jobLabel = localization.GetByLabel('UI/Fleet/FleetBroadcast/MemberHistoryIsBoss', charID=charID) 1171 else: 1172 jobLabel = localization.GetByLabel('UI/Fleet/FleetBroadcast/MemberHistoryIsNotBoss', charID=charID) 1173 self.AddToMemberHistory(charID, jobLabel) 1174 if newRole not in (None, -1): 1175 self.UpdateTargetBroadcasts(charID) 1176 if charID == session.charid: 1177 self.fleetCompositionTimestamp = 0 1178 sm.ScatterEvent('OnMyFleetInfoChanged') 1179 if oldJob & evefleet.fleetJobCreator == 0 and newJob & evefleet.fleetJobCreator > 0: 1180 self.TryUpdateFleetFinderAdvertWithNewBoss() 1181 elif oldJob & evefleet.fleetJobCreator > 0 and newJob & evefleet.fleetJobCreator == 0: 1182 self.currentFleetAd = None 1183 if newJob != oldJob or newRole != oldRole: 1184 info = self.GetMemberInfo(charID) 1185 if newJob != oldJob: 1186 r = info.jobName 1187 elif newRole != oldRole: 1188 r = info.roleName 1189 1190 def OnFleetMoveFailed(self, charID, isKicked): 1191 if isKicked: 1192 prompt_player_fsd_dialog('CustomNotify', {'notify': localization.GetByLabel('UI/Fleet/MoveFailedKicked', charID=charID)}) 1193 else: 1194 prompt_player_fsd_dialog('CustomNotify', {'notify': localization.GetByLabel('UI/Fleet/MoveFailed', charID=charID)}) 1195 1196 def OnFleetWingAdded(self, wingID): 1197 self.wings = self.fleet.GetWings() 1198 sm.ScatterEvent('OnFleetWingAdded_Local', wingID) 1199 1200 def OnFleetWingDeleted(self, wingID): 1201 self.wings = self.fleet.GetWings() 1202 sm.ScatterEvent('OnFleetWingDeleted_Local', wingID) 1203 1204 def OnFleetSquadAdded(self, wingID, squadID): 1205 self.wings = self.fleet.GetWings() 1206 sm.ScatterEvent('OnFleetSquadAdded_Local', wingID, squadID) 1207 1208 def OnFleetSquadDeleted(self, squadID): 1209 self.wings = self.fleet.GetWings() 1210 sm.ScatterEvent('OnFleetSquadDeleted_Local', squadID) 1211 1212 def OnFleetOptionsChanged(self, oldOptions, options): 1213 self.options = options 1214 if self.options.isRegistered != oldOptions.isRegistered: 1215 self.GetFleetAdsForChar_Memoized.clear_memoized() 1216 sm.ScatterEvent('OnFleetFinderAdvertChanged') 1217 if self.options.isRegistered: 1218 self.AddBroadcast('FleetFinderAdvertAdded', evefleet.BROADCAST_NONE, self.GetBossID(), broadcastName=localization.GetByLabel('UI/Fleet/FleetBroadcast/FleetFinderAdvertAdded')) 1219 if options.isFreeMove != oldOptions.isFreeMove: 1220 self.AddBroadcast('FleetOptionsChanged', evefleet.BROADCAST_NONE, self.GetBossID(), broadcastName=[localization.GetByLabel('UI/Fleet/FleetBroadcast/FreeMoveUnset'), localization.GetByLabel('UI/Fleet/FleetBroadcast/FreeMoveSet')][options.isFreeMove]) 1221 sm.ScatterEvent('OnFleetOptionsChanged_Local', oldOptions, options) 1222 1223 def OnMemberlessFleetUnregistered(self): 1224 self.GetFleetAdsForChar_Memoized.clear_memoized() 1225 1226 def OnJoinedFleet(self): 1227 self.RefreshFleetWindow() 1228 sm.GetService('cmd').OpenFleetWatchlist() 1229 1230 def OnLeftFleet(self): 1231 self.CloseFleetWindowAndReopenIfNeeded() 1232 self.CloseWatchlistWindow() 1233 self.CloseFleetCompositionWindow() 1234 self.CloseJoinRequestWindow() 1235 self.CloseRegisterFleetWindow() 1236 self.CloseFleetBroadcastWindow() 1237 self.CloseFleetSetupList() 1238 1239 def OnFleetJoinRequest(self, info): 1240 self.joinRequests[info.charID] = info 1241 prompt_player_fsd_dialog('FleetMemberJoinRequest', {'name': (UE_OWNERID, info.charID), 1242 'corpname': (UE_OWNERID, info.corpID)}) 1243 self.OpenJoinRequestWindow() 1244 1245 def OnFleetJoinRejected(self, charID): 1246 prompt_player_fsd_dialog('FleetJoinRequestRejected', {'name': (UE_OWNERID, charID)}) 1247 1248 def OnJoinRequestUpdate(self, joinRequests): 1249 self.joinRequests = joinRequests 1250 self.OpenJoinRequestWindow() 1251 1252 def OnContactChange(self, contactIDs, contactType = None): 1253 self.UpdateAllowedEntitiesInAdvert() 1254 1255 def OpenJoinRequestWindow(self): 1256 self.CloseJoinRequestWindow() 1257 FleetJoinRequestWindow.Open() 1258 1259 def CloseJoinRequestWindow(self): 1260 FleetJoinRequestWindow.CloseIfOpen() 1261 1262 def OpenFleetCompositionWindow(self): 1263 self.CloseFleetCompositionWindow() 1264 FleetComposition.Open() 1265 1266 def CloseFleetCompositionWindow(self): 1267 FleetComposition.CloseIfOpen() 1268 1269 def CloseFleetBroadcastWindow(self): 1270 BroadcastSettings.CloseIfOpen() 1271 1272 def OpenRegisterFleetWindow(self, info = None): 1273 if session.fleetid is None: 1274 raise UserError('FleetNotFound') 1275 if not self.IsBoss(): 1276 raise UserError('FleetNotCreator') 1277 if info is None and self.options.isRegistered: 1278 info = self.GetCurrentAdvertForMyFleet() 1279 self.CloseRegisterFleetWindow() 1280 RegisterFleetWindow.Open(fleetInfo=info) 1281 1282 def CloseRegisterFleetWindow(self): 1283 RegisterFleetWindow.CloseIfOpen() 1284 1285 def RefreshFleetWindow(self): 1286 self.InitFleet() 1287 self.CloseFleetWindow() 1288 FleetWindow.Open() 1289 1290 def CloseFleetWindowAndReopenIfNeeded(self): 1291 wnd = FleetWindow.GetIfOpen() 1292 if wnd: 1293 self.InitFleet() 1294 self.RefreshFleetWindow() 1295 1296 def CloseFleetWindow(self): 1297 FleetWindow.CloseIfOpen() 1298 1299 def AddBroadcast(self, name, scope, charID, solarSystemID = None, itemID = None, broadcastName = None, typeID = None): 1300 time = blue.os.GetWallclockTime() 1301 spaceAndOptionalGroupName = ' ' 1302 msgLocationID = itemID 1303 if typeID is not None and itemID is not None and name in [evefleet.BROADCAST_IN_POSITION, 1304 evefleet.BROADCAST_WARP_TO, 1305 evefleet.BROADCAST_ALIGN_TO, 1306 evefleet.BROADCAST_JUMP_TO, 1307 evefleet.BROADCAST_TRAVEL_TO]: 1308 groupID = evetypes.GetGroupID(typeID) 1309 if groupID in (groupStargate, groupSkyhook): 1310 spaceAndOptionalGroupName = ' %s ' % localization.CleanImportantMarkup(evetypes.GetGroupName(typeID)) 1311 if groupID == groupSkyhook: 1312 planetID = self._GetPlanetIDFromSlimItem(itemID) 1313 if planetID: 1314 msgLocationID = planetID 1315 typeIDForBroadcast = None 1316 if name == evefleet.BROADCAST_ENEMY_SPOTTED: 1317 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventEnemySpotted', charID=charID) 1318 elif name == evefleet.BROADCAST_NEED_BACKUP: 1319 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventNeedBackup', charID=charID) 1320 elif name == evefleet.BROADCAST_HEAL_ARMOR: 1321 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventHealArmor', charID=charID) 1322 label += self._GetTypeNameTextFromBroadcastedItemID(itemID) 1323 elif name == evefleet.BROADCAST_HEAL_SHIELD: 1324 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventHealShield', charID=charID) 1325 label += self._GetTypeNameTextFromBroadcastedItemID(itemID) 1326 elif name == evefleet.BROADCAST_HEAL_CAPACITOR: 1327 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventHealCapacitor', charID=charID) 1328 label += self._GetTypeNameTextFromBroadcastedItemID(itemID) 1329 elif name == evefleet.BROADCAST_IN_POSITION: 1330 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventInPosition2', charID=charID, locationID=msgLocationID, spaceAndOptionalGroupName=spaceAndOptionalGroupName) 1331 elif name == evefleet.BROADCAST_HOLD_POSITION: 1332 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventHoldPosition', charID=charID) 1333 elif name == evefleet.BROADCAST_JUMP_BEACON: 1334 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventJumpToBeacon', charID=charID) 1335 typeIDForBroadcast = typeID 1336 elif name == evefleet.BROADCAST_LOCATION: 1337 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventLocation', charID=charID, solarsystemID=solarSystemID) 1338 elif name == evefleet.BROADCAST_WARP_TO: 1339 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventWarpTo2', charID=charID, locationID=msgLocationID, spaceAndOptionalGroupName=spaceAndOptionalGroupName) 1340 elif name == evefleet.BROADCAST_ALIGN_TO: 1341 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventAlignTo2', charID=charID, locationID=msgLocationID, spaceAndOptionalGroupName=spaceAndOptionalGroupName) 1342 elif name == evefleet.BROADCAST_JUMP_TO: 1343 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventJumpTo2', charID=charID, locationID=msgLocationID, spaceAndOptionalGroupName=spaceAndOptionalGroupName) 1344 elif name == evefleet.BROADCAST_TRAVEL_TO: 1345 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventTravelTo2', charID=charID, locationID=msgLocationID, spaceAndOptionalGroupName=spaceAndOptionalGroupName) 1346 elif name == evefleet.BROADCAST_TARGET: 1347 targetName, targetTypeName = self._GetTargetNameAndType(itemID) 1348 if targetName is not None and targetTypeName is not None: 1349 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventTargetWithType', targetName=targetName, targetTypeName=targetTypeName) 1350 else: 1351 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventTarget') 1352 elif name == evefleet.BROADCAST_REP_TARGET: 1353 targetName, targetTypeName = self._GetTargetNameAndType(itemID) 1354 if targetName is not None and targetTypeName is not None: 1355 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventHealTargetWithType', targetName=targetName, targetTypeName=targetTypeName) 1356 else: 1357 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/BroadcastEventHealTarget') 1358 elif broadcastName is not None: 1359 label = broadcastName 1360 else: 1361 log.LogTraceback('Unknown broadcast label:%s' % name) 1362 label = 'Unknown broadcast label:%s' % name 1363 where = fleetbroadcastexports.GetBroadcastWhere(name) 1364 broadcast = KeyVal(name=name, charID=charID, solarSystemID=solarSystemID, itemID=itemID, time=time, broadcastLabel=label, scope=scope, where=where, typeID=typeIDForBroadcast) 1365 self.broadcastHistory.insert(0, broadcast) 1366 if len(self.broadcastHistory) > MAX_NUM_BROADCASTS: 1367 self.broadcastHistory.pop() 1368 if self.WantBroadcast(name, charID): 1369 sm.ScatterEvent('OnFleetBroadcast_Local', broadcast) 1370 1371 def _GetTargetNameAndType(self, itemID): 1372 m = sm.GetService('michelle') 1373 bp = m.GetBallpark() 1374 slimItem = bp.GetInvItem(itemID) 1375 if slimItem is None: 1376 return (None, None) 1377 targetName = uix.GetSlimItemName(slimItem) 1378 targetTypeName = evetypes.GetName(slimItem.typeID) 1379 return (targetName, targetTypeName) 1380 1381 def _GetTypeNameTextFromBroadcastedItemID(self, itemID): 1382 bp = sm.GetService('michelle').GetBallpark() 1383 if not bp: 1384 return '' 1385 slimItem = bp.GetInvItem(itemID) 1386 if slimItem is not None: 1387 return ' (%s)' % evetypes.GetName(slimItem.typeID) 1388 return '' 1389 1390 def _GetPlanetIDFromSlimItem(self, itemID): 1391 bp = sm.GetService('michelle').GetBallpark() 1392 if not bp: 1393 return 1394 slimItem = bp.GetInvItem(itemID) 1395 if slimItem is not None: 1396 return slimItem.planetID 1397 1398 def WantBroadcast(self, name, charID): 1399 if name not in iconsByBroadcastType: 1400 name = 'Event' 1401 if charID == session.charid: 1402 if settings.user.ui.Get(LISTEN_BROADCAST_SETTING % BROADCAST_SHOW_OWN, False): 1403 return True 1404 if settings.user.ui.Get(LISTEN_BROADCAST_SETTING % name, True): 1405 return True 1406 return False 1407 1408 def OnFleetBroadcast(self, name, scope, charID, solarSystemID, itemID, typeID): 1409 self.LogInfo('OnFleetBroadcast', name, scope, charID, solarSystemID, itemID, ' I now have', len(self.broadcastHistory) + 1, 'broadcasts in my history') 1410 self.AddBroadcast(name, scope, charID, solarSystemID, itemID, typeID=typeID) 1411 if name == evefleet.BROADCAST_TARGET: 1412 targets = self.targetBroadcasts.setdefault(charID, []) 1413 if itemID in targets: 1414 targets.remove(itemID) 1415 targets.insert(0, itemID) 1416 else: 1417 targets.append(itemID) 1418 self.UpdateTargetBroadcasts(charID) 1419 else: 1420 stateID = getattr(state, 'gb%s' % name) 1421 self.BroadcastState(itemID, stateID, charID) 1422 1423 def BroadcastState(self, itemID, brState, *data): 1424 gbID = self.NewFleetBroadcastID() 1425 self.currentBroadcastOnItem[itemID] = (gbID, brState, data) 1426 sm.GetService('stateSvc').SetState(itemID, brState, True, gbID, *data) 1427 blue.pyos.synchro.SleepWallclock(FLEETBROADCASTTIMEOUT * 1000) 1428 savedgbid, savedgbtype, saveddata = self.currentBroadcastOnItem.get(itemID, (None, None, None)) 1429 if savedgbid == gbID: 1430 sm.GetService('stateSvc').SetState(itemID, brState, False, gbID, *data) 1431 del self.currentBroadcastOnItem[itemID] 1432 1433 def CycleBroadcastScope(self): 1434 if self.broadcastScope == evefleet.BROADCAST_DOWN: 1435 newScope = evefleet.BROADCAST_UP 1436 elif self.broadcastScope == evefleet.BROADCAST_UP: 1437 newScope = evefleet.BROADCAST_ALL 1438 else: 1439 newScope = evefleet.BROADCAST_DOWN 1440 fleetBroadcastScopeSetting.set(newScope) 1441 1442 def OnFleetBroadcastScopeChanged(self, value): 1443 self.broadcastScope = value 1444 prompt_player_fsd_dialog('FleetBroadcastScopeChange', {'name': fleetbroadcastexports.GetBroadcastScopeName(self.broadcastScope)}) 1445 sm.ScatterEvent('OnBroadcastScopeChange') 1446 1447 def OnFleetLootEvent(self, lootEvents): 1448 for k, v in lootEvents.iteritems(): 1449 loot = KeyVal(charID=k[0], solarSystemID=session.solarsystemid2, typeID=k[1], quantity=v, time=blue.os.GetWallclockTime()) 1450 for i, l in enumerate(self.lootHistory): 1451 if (l.typeID, l.charID, l.solarSystemID) == (loot.typeID, loot.charID, loot.solarSystemID): 1452 self.lootHistory[i].quantity += loot.quantity 1453 self.lootHistory[i].time = loot.time 1454 break 1455 else: 1456 self.lootHistory.insert(0, loot) 1457 1458 if len(self.lootHistory) > MAX_NUM_LOOTEVENTS: 1459 self.lootHistory.pop() 1460 sm.ScatterEvent('OnFleetLootEvent_Local') 1461 1462 def GetLootHistory(self): 1463 return self.lootHistory 1464 1465 def GetBroadcastHistory(self): 1466 history = [ h for h in self.broadcastHistory if self.WantBroadcast(h.name, h.charID) ] 1467 return history 1468 1469 def AddToMemberHistory(self, charID, event): 1470 self.memberHistory.insert(0, KeyVal(charID=charID, event=event, time=blue.os.GetWallclockTime())) 1471 if len(self.memberHistory) > MAX_NUM_BROADCASTS: 1472 self.memberHistory.pop() 1473 1474 def GetMemberHistory(self): 1475 return self.memberHistory 1476 1477 def UpdateTargetBroadcasts(self, charID): 1478 1479 def BroadcastWithLabel(itemID, label): 1480 gbID = self.NewFleetBroadcastID() 1481 self.currentTargetBroadcast[itemID] = gbID 1482 self.BroadcastState(itemID, state.gbTarget, charID, label) 1483 if self.currentTargetBroadcast.get(itemID) == gbID: 1484 self.targetBroadcasts[charID].remove(itemID) 1485 1486 role = self.members[charID].role 1487 for i, id_ in enumerate(self.targetBroadcasts.get(charID, [])): 1488 gbID, gbType, data = self.currentBroadcastOnItem.get(id_, (None, None, None)) 1489 if gbType == state.gbTarget: 1490 prevCharID, number = data 1491 if self.IsSuperior(charID, prevCharID): 1492 continue 1493 if role == evefleet.fleetRoleSquadCmdr: 1494 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/TargetCodeFleet', targetID=i + 1) 1495 elif role == evefleet.fleetRoleSquadCmdr: 1496 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/TargetCodeWing', targetID=i + 1) 1497 elif role == evefleet.fleetRoleSquadCmdr: 1498 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/TargetCodeSquad', targetID=i + 1) 1499 else: 1500 label = localization.GetByLabel('UI/Fleet/FleetBroadcast/TargetCodeMember', targetID=i + 1) 1501 uthread.pool('FleetSvc::UpdateTargetBroadcasts', BroadcastWithLabel, id_, label) 1502 1503 @Memoize 1504 def GetRankOrder(self): 1505 return [evefleet.fleetRoleMember, 1506 evefleet.fleetRoleSquadCmdr, 1507 evefleet.fleetRoleWingCmdr, 1508 evefleet.fleetRoleLeader] 1509 1510 def IsSuperior(self, charID, otherCharID): 1511 1512 def Rank(charID): 1513 return self.GetRankOrder().index(self.members[charID].role) 1514 1515 return Rank(charID) > Rank(otherCharID) 1516 1517 def NewFleetBroadcastID(self): 1518 if not hasattr(self, 'lastFleetBroadcastID'): 1519 self.lastFleetBroadcastID = 0 1520 self.lastFleetBroadcastID += 1 1521 return self.lastFleetBroadcastID 1522 1523 def ProcessSessionChange(self, isRemote, session, change): 1524 if 'fleetid' in change: 1525 self.activeModuleBeacons = {} 1526 self.activeDeployableBeacons = {} 1527 self.activeBridge = {} 1528 self.initedFleet = None 1529 myrec = self.members.get(session.charid, KeyVal(charID=session.charid)) 1530 self.members = {} 1531 self.leader = None 1532 if change['fleetid'][1] is None: 1533 self.fleet = None 1534 self.favorites.clear() 1535 self.favoriteOrder.Reset() 1536 sm.ScatterEvent('OnFleetLeave_Local', myrec) 1537 sm.ScatterEvent('OnLeftFleet') 1538 else: 1539 sm.ScatterEvent('OnJoinedFleet') 1540 sm.GetService('tactical').InvalidateFlags() 1541 if 'solarsystemid' in change: 1542 self.CleanupBroadcasts() 1543 if session.solarsystemid is not None and session.fleetid is not None: 1544 self.RegisterForDamageUpdates() 1545 self.UpdateFleetInfo() 1546 if 'shipid' in change or 'structureid' in change: 1547 self.UpdateFleetInfo() 1548 if 'charid' in change: 1549 if change['charid'][1] is not None: 1550 uthread.new(self.AttemptReconnectLazy) 1551 if 'corpid' in change: 1552 uthread.new(self.RemoveAndUpdateFleetFinderAdvert, 'ChangedCorp') 1553 1554 def AttemptReconnectLazy(self): 1555 blue.pyos.synchro.SleepSim(RECONNECT_DELAY * 1000) 1556 try: 1557 if session.fleetid is not None or session.charid is None: 1558 return 1559 fleetReconnect = settings.char.ui.Get('fleetReconnect', None) 1560 if fleetReconnect: 1561 if fleetReconnect[1] > blue.os.GetWallclockTime() - evefleet.RECONNECT_TIMEOUT * MIN: 1562 self.LogNotice('I will try to reconnect to a lost fleet', fleetReconnect[0]) 1563 fleet = GetFleet(fleetReconnect[0]) 1564 fleet.Reconnect() 1565 else: 1566 self.LogInfo('Reconnect request', fleetReconnect, ' out of date') 1567 except Exception as e: 1568 self.LogWarn('Unable to reconnect. Error =', e) 1569 finally: 1570 settings.char.ui.Set('fleetReconnect', None) 1571 1572 def UpdateFleetFinderInfo(self): 1573 if session.fleetid is None: 1574 return 1575 if not self.updateAdvertThreadRunning and self.IsBoss() and self.options.isRegistered: 1576 self.updateAdvertThreadRunning = True 1577 uthread.worker('Fleet::UpdateAdvertInfoThread', self.UpdateAdvertInfoThread) 1578 1579 def UpdateAdvertInfoThread(self): 1580 try: 1581 self.LogInfo('Starting UpdateAdvertInfoThread...') 1582 self.updateAdvertThreadRunning = True 1583 blue.pyos.synchro.SleepWallclock(UPDATEFLEETFINDERDELAY * 1000) 1584 if session.fleetid is None: 1585 return 1586 if self.IsBoss() and self.options.isRegistered: 1587 numMembers = len(self.members) 1588 allowedInfoFromStandings = self.GetAllowedAndBannedEntitiesFromStandings(self.currentFleetAd) 1589 allowedDiffBundle = GetDiffInAllowedAndBanned(self.currentFleetAd, allowedInfoFromStandings) 1590 self.LogInfo('Calling UpdateAdvertInfo', session.solarsystemid2, numMembers, allowedDiffBundle) 1591 advertInfo = self.UpdateAdvertInfo(numMembers, KeyVal(allowedDiffBundle)) 1592 if advertInfo: 1593 self.currentFleetAd = advertInfo 1594 finally: 1595 self.updateAdvertThreadRunning = False 1596 1597 def GetAllowedAndBannedEntitiesFromStandings(self, currentAd): 1598 membergroupsAllowedEntities = set() 1599 publicAllowedEntities = set() 1600 membergroupsDisallowedEntities = set() 1601 publicDisallowedEntities = set() 1602 ret = {'membergroupsAllowedEntities': membergroupsAllowedEntities, 1603 'publicAllowedEntities': publicAllowedEntities, 1604 'membergroupsDisallowedEntities': membergroupsDisallowedEntities, 1605 'publicDisallowedEntities': publicDisallowedEntities} 1606 addressbookSvc = sm.GetService('addressbook') 1607 if currentAd.IsOpenToMemberEntities(): 1608 membergroupsMinStanding = currentAd.membergroups_minStanding 1609 if membergroupsMinStanding is None: 1610 membergroupsAllowedEntities.update(self.GetAllowedGroupIDs(KeyVal(inviteScope=currentAd.inviteScope))) 1611 else: 1612 atOrAboveStanding, belowStanding = addressbookSvc.GetContactsAboveAndBelowRelationship(membergroupsMinStanding) 1613 membergroupsAllowedEntities.update(atOrAboveStanding) 1614 if membergroupsMinStanding <= 0: 1615 membergroupsDisallowedEntities.update(belowStanding) 1616 publicMinStanding = currentAd.public_minStanding 1617 if publicMinStanding is not None: 1618 atOrAboveStanding, belowStanding = addressbookSvc.GetContactsAboveAndBelowRelationship(publicMinStanding) 1619 publicAllowedEntities.update(atOrAboveStanding) 1620 if publicMinStanding <= 0: 1621 publicDisallowedEntities.update(belowStanding) 1622 return ret 1623 1624 def UpdateAllowedEntitiesInAdvert(self): 1625 if session.fleetid is None or not self.IsBoss() or not self.options.isRegistered: 1626 return 1627 allowedInfoFromStandings = self.GetAllowedAndBannedEntitiesFromStandings(self.currentFleetAd) 1628 advertInfo = self.UpdateAdvertAllowedEntities(allowedInfoFromStandings) 1629 self.currentFleetAd = advertInfo 1630 1631 def UpdateFleetInfo(self): 1632 if session.fleetid is None: 1633 return 1634 self.UpdateFleetFinderInfo() 1635 if not self.updateThreadRunning: 1636 self.updateThreadRunning = True 1637 uthread.worker('Fleet::UpdateFleetInfoThread', self.UpdateFleetInfoThread) 1638 1639 def UpdateFleetInfoThread(self): 1640 try: 1641 self.LogInfo('Starting UpdateFleetInfoThread...') 1642 self.updateThreadRunning = True 1643 blue.pyos.synchro.SleepWallclock(UPDATEFLEETMEMBERDELAY_SEC * 1000) 1644 if session.fleetid is None: 1645 return 1646 self.LogInfo('Calling UpdateMemberInfo') 1647 self.fleet.UpdateMemberInfo(self.GetMyShipTypeID()) 1648 finally: 1649 self.updateThreadRunning = False 1650 1651 def OnFleetMove(self): 1652 oldSquadID = session.squadid 1653 oldWingID = session.wingid 1654 self.sessionMgr.PerformSelectiveSessionChange('fleet.', 'fleet.finishmove', True, self.fleet.FinishMove) 1655 1656 def IsBoss(self): 1657 myrec = self.GetMembers().get(session.charid) 1658 return bool(myrec and myrec.job & evefleet.fleetJobCreator) 1659 1660 def IsCommanderOrBoss(self): 1661 return self.IsBoss() or session.fleetrole in evefleet.fleetCmdrRoles 1662 1663 def GetAutoJoinSquadID(self): 1664 if not session.fleetid: 1665 return 1666 return self.options.autoJoinSquadID 1667 1668 def GetBossID(self): 1669 myrec = self.GetMembers() 1670 for mid, m in self.members.iteritems(): 1671 if m.job & evefleet.fleetJobCreator: 1672 return mid 1673 1674 def IsMySubordinate(self, charID): 1675 member = self.members.get(charID, None) 1676 if member is None: 1677 return False 1678 isSubordinate = False 1679 if session.fleetrole == evefleet.fleetRoleLeader or session.fleetrole == evefleet.fleetRoleWingCmdr and member.wingID == session.wingid or session.fleetrole == evefleet.fleetRoleSquadCmdr and member.squadID == session.squadid: 1680 isSubordinate = True 1681 return isSubordinate 1682 1683 def CreateAndRegisterFleet(self, adInfo): 1684 if session.fleetid: 1685 if adInfo: 1686 self.RegisterFleet(adInfo) 1687 elif self.IsFleetRegistered(): 1688 self.RemoveFleetFinderAdvert() 1689 else: 1690 adInfoData = adInfo.GetData() if adInfo else None 1691 self.CreateFleet(adInfoData=adInfoData) 1692 self.LogFleetCreation(self.fleetID, evefleet.CREATE_SOURCE_FLEETUP) 1693 self.GetFleetAdsForChar_Memoized.clear_memoized() 1694 1695 def RegisterFleet(self, adInfo): 1696 self.LogInfo('RegisterFleet', adInfo.GetData()) 1697 if session.fleetid is None: 1698 raise UserError('FleetNotFound') 1699 if not self.IsBoss(): 1700 raise UserError('FleetNotCreator') 1701 isEdit = self.options.isRegistered 1702 createdAdInfo = self.AddFleetFinderAdvert(adInfo) 1703 self._FinializeRegistration(createdAdInfo, isEdit) 1704 1705 def _FinializeRegistration(self, createdAd, isEdit): 1706 if isEdit: 1707 sm.ScatterEvent('OnFleetFinderAdvertChanged') 1708 self.currentFleetAd = createdAd 1709 settings.char.ui.Set('fleetAdvert_lastAdvert', createdAd.GetData(fullAdvancedOptions=False)) 1710 1711 def UnregisterFleet(self): 1712 if session.fleetid is None: 1713 raise UserError('FleetNotFound') 1714 if not self.IsBoss(): 1715 raise UserError('FleetNotCreator') 1716 if prompt_player_fsd_dialog('FleetRemoveFleetFinderAd', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1717 self.RemoveFleetFinderAdvert() 1718 self.currentFleetAd = None 1719 1720 def GetFleetAdsForChar(self): 1721 fleetAdvertDictsForFleets = sm.ProxySvc('fleetProxy').GetAvailableFleetAds() 1722 return {k:FleetAdvertObject(**v) for k, v in fleetAdvertDictsForFleets.iteritems()} 1723 1724 @Memoize(0.5) 1725 def GetFleetAdsForChar_Memoized(self): 1726 return self.GetFleetAdsForChar() 1727 1728 def ApplyToJoinFleet(self, fleetID, autoAccept = False): 1729 if session.fleetid is not None: 1730 if session.fleetid == fleetID: 1731 raise UserError('FleetYouAreAlreadyInFleet') 1732 confirmChangeFleet = self._ConfirmChangeFleet() 1733 if not confirmChangeFleet: 1734 return 1735 self.LeaveFleet() 1736 self.expectingInvite = fleetID 1737 ret = sm.ProxySvc('fleetProxy').ApplyToJoinFleet(fleetID, autoAccept) 1738 if ret: 1739 raise UserError('FleetApplicationReceived') 1740 1741 def _ConfirmChangeFleet(self): 1742 userInput = prompt_player_fsd_dialog('AskChangeFleet', buttons=uiconst.YESNO) 1743 return userInput == uiconst.ID_YES 1744 1745 def AskJoinFleetFromLink(self, fleetID): 1746 fleets = self.GetFleetAdsForChar() 1747 if fleetID not in fleets: 1748 raise UserError('FleetJoinFleetFromLinkError') 1749 self.ApplyToJoinFleet(fleetID) 1750 self.LogFleetJoinAttempts(fleetID, evefleet.JOIN_SOURCE_LINK) 1751 1752 def GetCurrentAdvertForMyFleet(self): 1753 if session.fleetid is None or not self.options.isRegistered: 1754 return 1755 fleetAd = self.GetMyFleetFinderAdvert() 1756 if fleetAd is None: 1757 return 1758 fleetAd.standing = None 1759 if fleetAd.Get('solarSystemID', 0): 1760 mapSvc = sm.GetService('map') 1761 numJumps = self.clientPathfinderService.GetJumpCountFromCurrent(fleetAd.solarSystemID) 1762 fleetAd.numJumps = numJumps 1763 constellationID = mapSvc.GetParent(fleetAd.solarSystemID) 1764 fleetAd.regionID = mapSvc.GetParent(constellationID) 1765 fleetAd.standing = sm.GetService('standing').GetStanding(session.charid, fleetAd.leader.charID) 1766 return fleetAd 1767 1768 def SetListenBroadcast(self, name, isit): 1769 if name not in iconsByBroadcastType and name != BROADCAST_SHOW_OWN: 1770 name = 'Event' 1771 settings.user.ui.Set(LISTEN_BROADCAST_SETTING % name, isit) 1772 sm.ScatterEvent('OnFleetBroadcastFilterChange') 1773 1774 def GetMyShipTypeID(self): 1775 shipTypeID = None 1776 if session.shipid and session.solarsystemid: 1777 shipTypeID = sm.GetService('godma').GetItem(session.shipid).typeID 1778 elif GetActiveShip(): 1779 activeShipID = GetActiveShip() 1780 dl = sm.GetService('clientDogmaIM').GetDogmaLocation() 1781 shipItem = dl.GetItem(activeShipID) 1782 shipTypeID = shipItem.typeID 1783 return shipTypeID 1784 1785 def SetRemoteMotd(self, motd): 1786 self.CheckIsInFleet() 1787 self.fleet.SetMotdEx(motd) 1788 1789 def GetMotd(self): 1790 self.CheckIsInFleet() 1791 if self.motd is None: 1792 self.motd = self.fleet.GetMotd() 1793 return self.motd 1794 1795 def OnFleetMotdChanged(self, motd, reloadMotd): 1796 self.LogInfo('OnFleetMotdChanged', motd, session.fleetid) 1797 self.CheckIsInFleet() 1798 self.motd = motd 1799 channelWindow = sm.GetService('XmppChat').GetGroupChatWindow('fleet_' + str(session.fleetid)) 1800 if channelWindow is not None and reloadMotd: 1801 channelWindow.SetMotd(sender=None, text=motd) 1802 else: 1803 self.LogError('OnFleetMotdChanged could not find fleet chat window', session.fleetid) 1804 1805 def OnDropCommanderDropData(self, dragObject, draggedGuys, receivingNode, *args): 1806 groupType = receivingNode.groupType 1807 groupID = getattr(receivingNode, 'groupID', None) 1808 canMove = self.CanMoveAtLeastOneToThisEntry(draggedGuys, receivingNode, groupType, groupID) 1809 if canMove in (CANNOT_BE_MOVED, CONNOT_BE_MOVED_INCOMPATIBLE): 1810 return 1811 if groupType == 'squad': 1812 return self.DropOnSquadCommander(draggedGuys, groupID, canMove) 1813 if groupType == 'wing': 1814 return self.DropOnWingcommander(draggedGuys, groupID, canMove) 1815 if groupType == 'fleet': 1816 return self.DropOnFleetCommander(draggedGuys, canMove) 1817 if groupType == 'fleetMember': 1818 return self.DropOnFleetMember(draggedGuys, receivingNode) 1819 1820 def DropOnSquadCommander(self, draggedGuys, newSquadID, canMove, *args): 1821 newWingID = self.FindWingID(newSquadID) 1822 if newWingID is None: 1823 return 1824 if canMove == CAN_BE_COMMANDER and len(draggedGuys) == 1: 1825 role = evefleet.fleetRoleSquadCmdr 1826 else: 1827 role = evefleet.fleetRoleMember 1828 self.HandleDroppingInGroup(draggedGuys, newWingID, newSquadID, role=role) 1829 1830 def DropOnWingcommander(self, draggedGuys, newWingID, canMove): 1831 if canMove == CAN_BE_COMMANDER and len(draggedGuys) == 1: 1832 role = evefleet.fleetRoleWingCmdr 1833 else: 1834 role = evefleet.fleetRoleMember 1835 self.HandleDroppingInGroup(draggedGuys, newWingID, None, role=role) 1836 1837 def DropOnFleetCommander(self, draggedGuys, canMove): 1838 members = self.GetMembers() 1839 if canMove == CAN_BE_COMMANDER and len(draggedGuys) == 1: 1840 role = evefleet.fleetRoleLeader 1841 else: 1842 role = evefleet.fleetRoleMember 1843 self.HandleDroppingInGroup(draggedGuys, None, None, role=role) 1844 1845 def DropOnFleetMember(self, draggedGuys, receivingNode): 1846 droppedOnMember = receivingNode.member 1847 newWingID = droppedOnMember.get('wingID', None) 1848 newSquadID = droppedOnMember.get('squadID', None) 1849 self.HandleDroppingInGroup(draggedGuys, newWingID, newSquadID) 1850 1851 def HandleDroppingInGroup(self, draggedGuys, newWingID, newSquadID, role = evefleet.fleetRoleMember): 1852 self.CheckIsInFleet() 1853 members = self.GetMembers() 1854 tryMove = [] 1855 tryInvite = [] 1856 1857 def SkipBecauseAlreadyInWing(eachCharID): 1858 if role != evefleet.fleetRoleMember: 1859 return False 1860 member = members[eachCharID] 1861 if newWingID and newSquadID is None and newWingID == member.get('wingID', None): 1862 return True 1863 return False 1864 1865 for eachDraggedGuy in draggedGuys: 1866 charID = eachDraggedGuy.charID 1867 if charID in members: 1868 if newWingID is None and newSquadID is None and role != evefleet.fleetRoleLeader: 1869 continue 1870 if not SkipBecauseAlreadyInWing(charID): 1871 tryMove.append(charID) 1872 else: 1873 tryInvite.append(charID) 1874 1875 self.MassMove(tryMove, newWingID, newSquadID, role=role) 1876 self.MassInvite(tryInvite, newWingID, newSquadID, role=role) 1877 1878 def FindWingID(self, squadID): 1879 for wingID, wingInfo in self.wings.iteritems(): 1880 if getattr(wingInfo, 'squads', {}): 1881 if squadID in wingInfo['squads']: 1882 return wingID 1883 1884 def CanMoveToSquad(self, canMoveAll, draggedGuy, groupType, isFreeMove, myMemberInfo, receivingNode, isMultiMove): 1885 members = self.GetMembers() 1886 if groupType == 'fleetMember': 1887 droppedOnMember = receivingNode.member 1888 newWingID = droppedOnMember.get('wingID', None) 1889 newSquadID = droppedOnMember.get('squadID', None) 1890 allowedMove = CAN_ONLY_BE_MEMBER 1891 else: 1892 shiftDown = uicore.uilib.Key(uiconst.VK_SHIFT) 1893 newSquadID = receivingNode.groupID 1894 squadCommander = self.GetSquadCommander(newSquadID) 1895 newWingID = None 1896 if squadCommander: 1897 allowedMove = CAN_ONLY_BE_MEMBER 1898 newWingID = squadCommander.get('wingID', None) 1899 elif isMultiMove or shiftDown: 1900 allowedMove = CAN_ONLY_BE_MEMBER 1901 else: 1902 allowedMove = CAN_BE_COMMANDER 1903 if newWingID is None: 1904 newWingID = self.FindWingID(newSquadID) 1905 if newWingID is None: 1906 return CANNOT_BE_MOVED 1907 memberCount = len([ guy for guy in members.itervalues() if guy.squadID == newSquadID and guy.charID != draggedGuy.charID ]) 1908 if memberCount >= evefleet.MAX_MEMBERS_IN_SQUAD: 1909 return CANNOT_BE_MOVED 1910 elif canMoveAll or isFreeMove: 1911 return allowedMove 1912 draggedGuysMemberInfo = self.GetDraggedGuysMemberInfo(draggedGuy) 1913 if newWingID != session.wingid or draggedGuysMemberInfo and draggedGuysMemberInfo.wingID != session.wingid: 1914 return CANNOT_BE_MOVED 1915 elif myMemberInfo.role == evefleet.fleetRoleWingCmdr: 1916 return allowedMove 1917 elif not draggedGuysMemberInfo and myMemberInfo.role == evefleet.fleetRoleSquadCmdr and session.squadid == newSquadID: 1918 return allowedMove 1919 else: 1920 return CANNOT_BE_MOVED 1921 1922 def CanMoveAtLeastOneToThisEntry(self, draggedGuys, receivingNode, groupType, groupID): 1923 isMultiMove = len(draggedGuys) > 1 1924 moveSet = {self.CanMoveToThisEntry(eachGuy, receivingNode, groupType, groupID, isMultiMove) for eachGuy in draggedGuys} 1925 if len(draggedGuys) == 1 and CAN_BE_COMMANDER in moveSet: 1926 return CAN_BE_COMMANDER 1927 if CAN_ONLY_BE_MEMBER in moveSet or CAN_BE_COMMANDER in moveSet: 1928 return CAN_ONLY_BE_MEMBER 1929 return CANNOT_BE_MOVED 1930 1931 def CanMoveToThisEntry(self, draggedGuy, receivingNode, groupType, groupID, isMultiMove = False): 1932 guid = getattr(draggedGuy, '__guid__', None) 1933 if guid not in AllUserEntries() + ['TextLink']: 1934 return CONNOT_BE_MOVED_INCOMPATIBLE 1935 if guid == 'TextLink': 1936 charID = GetCharIDFromTextLink(draggedGuy) 1937 if not charID: 1938 return CONNOT_BE_MOVED_INCOMPATIBLE 1939 draggedGuy.charID = charID 1940 if not IsEvePlayerCharacter(draggedGuy.charID): 1941 return CONNOT_BE_MOVED_INCOMPATIBLE 1942 members = self.GetMembers() 1943 myMemberInfo = members[session.charid] 1944 canMoveAll = myMemberInfo.role == evefleet.fleetRoleLeader or myMemberInfo.job & evefleet.fleetJobCreator 1945 shiftDown = uicore.uilib.Key(uiconst.VK_SHIFT) 1946 isFreeMove = False 1947 if self.GetOptions().isFreeMove and draggedGuy.charID == session.charid: 1948 isFreeMove = True 1949 if groupType == 'fleet': 1950 if not canMoveAll: 1951 return CANNOT_BE_MOVED 1952 fleetCommander = self.GetFleetCommander() 1953 if fleetCommander or isMultiMove or shiftDown: 1954 return CAN_ONLY_BE_MEMBER 1955 return CAN_BE_COMMANDER 1956 if groupType == 'wing': 1957 newWingID = groupID 1958 wingCommander = self.GetWingCommander(newWingID) 1959 if wingCommander or isMultiMove or shiftDown: 1960 return CAN_ONLY_BE_MEMBER 1961 if canMoveAll: 1962 return CAN_BE_COMMANDER 1963 elif groupType in ('squad', 'fleetMember'): 1964 return self.CanMoveToSquad(canMoveAll, draggedGuy, groupType, isFreeMove, myMemberInfo, receivingNode, isMultiMove) 1965 return CANNOT_BE_MOVED 1966 1967 def GetFleetCommander(self): 1968 members = self.GetMembers() 1969 for eachMember in members.itervalues(): 1970 if eachMember.role == evefleet.fleetRoleLeader: 1971 return eachMember 1972 1973 def GetWingCommander(self, wingID): 1974 members = self.GetMembers() 1975 for eachGuy in members.itervalues(): 1976 if eachGuy.wingID == wingID and eachGuy.role == evefleet.fleetRoleWingCmdr: 1977 return eachGuy 1978 1979 def GetSquadCommander(self, squadID): 1980 members = self.GetMembers() 1981 for eachGuy in members.itervalues(): 1982 if eachGuy.squadID == squadID and eachGuy.role == evefleet.fleetRoleSquadCmdr: 1983 return eachGuy 1984 1985 def GetDraggedGuysMemberInfo(self, draggedGuy): 1986 members = self.GetMembers() 1987 if draggedGuy.charID in members: 1988 return members[draggedGuy.charID] 1989 1990 def ValidateWingsHaveValidNames(self): 1991 wingNames = set() 1992 for wing in self.GetWings().itervalues(): 1993 wingName = wing.name.lower().strip() 1994 if not wingName or wingName in wingNames: 1995 raise UserError('GiveWingsUniqueNames') 1996 wingNames.add(wingName) 1997 1998 def StoreSetup(self): 1999 if self.fleet is None: 2000 return 2001 self.ValidateWingsHaveValidNames() 2002 name = self.lastLoadedSetup or '' 2003 currentMotd = self.GetMotd() 2004 currentMaxSize = self.fleet.GetFleetMaxSize() 2005 defaultSquadID = self.GetAutoJoinSquadID() 2006 defaultSquadName = None 2007 if defaultSquadID: 2008 fleet = self.GetFleetHierarchy() 2009 sq = fleet['squads'].get(defaultSquadID, None) 2010 if sq: 2011 defaultSquadName = sq['name'] or localization.GetByLabel('UI/Fleet/FleetWindow/UnnamedSquad') 2012 currentFleetInfo = KeyVal(oldSetupName=self.lastLoadedSetup, currentMotd=currentMotd, currentOptions=self.options, currentMaxSize=currentMaxSize, currentDefaultSquadName=defaultSquadName) 2013 wnd = StoreFleetSetupWnd(currentFleetInfo=currentFleetInfo) 2014 if wnd.ShowModal() != 1: 2015 return 2016 if wnd.result is not None: 2017 self.StoreFleetSetup(wnd.result) 2018 2019 def GetSetups(self): 2020 m = MenuData() 2021 fleetSetupsByName = self.GetFleetSetups() 2022 listOfSetups = sorted(fleetSetupsByName.values(), key=lambda x: x[fsConst.FS_NAME].lower()) 2023 for eachSetup in listOfSetups: 2024 setupName = eachSetup[fsConst.FS_NAME] 2025 hint = GetFleetSetupOptionHint(eachSetup) 2026 m.AddEntry(setupName, func=lambda sn = setupName: self.LoadSetup(sn), hint=hint) 2027 2028 return m 2029 2030 def StoreFleetSetup(self, storeOptions): 2031 wingsInfo = {} 2032 wings = self.GetWings().values() 2033 defaultSquadID = self.GetAutoJoinSquadID() 2034 wings = sorted(wings, key=lambda x: x.get('wingID', None)) 2035 defaultSquadSetting = None 2036 for wingIdx, wing in enumerate(wings): 2037 wingSquads = [] 2038 for squad in wing.squads.itervalues(): 2039 wingSquads.append((squad.squadID, squad.name)) 2040 2041 orderedWingSquads = sorted(wingSquads) 2042 orderedWingSquadIDs = [ x[0] for x in orderedWingSquads ] 2043 if defaultSquadID in orderedWingSquadIDs: 2044 sqIDx = orderedWingSquadIDs.index(defaultSquadID) 2045 _, sqdName = orderedWingSquads[sqIDx] 2046 defaultSquadSetting = (wing.name, sqIDx, sqdName) 2047 wingSquads = SortListOfTuples(orderedWingSquads) 2048 wingsInfo[wing.name.lower()] = {fsConst.FS_WING_NAME: wing.name, 2049 fsConst.FS_SQUAD_NAMES: wingSquads, 2050 fsConst.FS_WING_IDX: wingIdx} 2051 2052 setupName = storeOptions.setupName 2053 fleetSetupsByName = self.GetFleetSetups() 2054 fleetInfo = fleetSetupsByName.get(setupName, {}) 2055 fleetInfo[fsConst.FS_NAME] = setupName 2056 fleetInfo[fsConst.FS_WINGS_INFO] = wingsInfo 2057 if storeOptions.storeMotd: 2058 fleetInfo[fsConst.FS_MOTD] = self.GetMotd() 2059 else: 2060 fleetInfo.pop(fsConst.FS_MOTD, None) 2061 if storeOptions.storeFreeMove: 2062 fleetInfo[fsConst.FS_IS_FREE_MOVE] = self.options.isFreeMove 2063 else: 2064 fleetInfo.pop(fsConst.FS_IS_FREE_MOVE, None) 2065 if storeOptions.storeDefaultSquad and defaultSquadSetting: 2066 fleetInfo[fsConst.FS_DEFAULT_SQUAD] = defaultSquadSetting 2067 else: 2068 fleetInfo.pop(fsConst.FS_DEFAULT_SQUAD, None) 2069 if storeOptions.storeMaxSize: 2070 fleetInfo[fsConst.FS_MAX_SIZE] = self.fleet.GetFleetMaxSize() 2071 else: 2072 fleetInfo.pop(fsConst.FS_MAX_SIZE, None) 2073 fleetSetupsByName[setupName] = fleetInfo 2074 self.SaveSetupOnServer() 2075 2076 def SaveSetupOnServer(self): 2077 fleetSetupsByName = self.GetFleetSetups() 2078 yamlFilters = yaml.safe_dump(fleetSetupsByName.values()) 2079 self.characterSettings.Save('fleetSetups', yamlFilters) 2080 sm.ScatterEvent('OnFleetSetupChanged') 2081 2082 def DeleteFleetSetup(self, setupName): 2083 fleetSetupsByName = self.GetFleetSetups() 2084 setupRemoved = fleetSetupsByName.pop(setupName, None) 2085 if setupRemoved: 2086 self.SaveSetupOnServer() 2087 2088 def LoadSetup(self, setupName): 2089 prompt_player_fsd_dialog('AttemptingToLoadFleet') 2090 self.lastLoadedSetup = setupName 2091 self.fleet.LoadFleetSetup(setupName) 2092 2093 def SetFleetMaxSize(self): 2094 currentMaxSize = self.fleet.GetFleetMaxSize() 2095 caption = localization.GetByLabel('UI/Fleet/FleetWindow/SetFleetMaxSize') 2096 minValue = 1 2097 maxValue = evefleet.MAX_MEMBERS_IN_FLEET 2098 hint = localization.GetByLabel('UI/Fleet/FleetWindow/SetFleetNumberBetween', max=FmtAmt(maxValue)) 2099 ret = uix.QtyPopup(maxValue, minValue, currentMaxSize, caption=caption, hint=hint) 2100 if ret and 'qty' in ret: 2101 qty = ret['qty'] 2102 self.fleet.SetFleetMaxSize(qty) 2103 2104 def LoadSharedBroadcastSettings(self, settingKey, settingName): 2105 if prompt_player_fsd_dialog('ConfirmLoadBroadcastSettings', {}, uiconst.YESNO, default=uiconst.ID_NO) != uiconst.ID_YES: 2106 return 2107 data = sharedSettings.GetDataFromSettingKey(settingKey, None, 'ItemFilterLoadingError') 2108 broadcastSettings = data['broadcastSettings'] 2109 broadcastSettingsDict = {flagToName.get(x[0]):(x[1], x[2]) for x in broadcastSettings} 2110 broadcastSettingsDict.update({x[0]:(x[1], x[2]) for x in broadcastSettings if x[0] == BROADCAST_SHOW_OWN}) 2111 for name, labelName in broadcastNames.iteritems(): 2112 settingsForName = broadcastSettingsDict.get(name) 2113 if settingsForName: 2114 checked, color = settingsForName 2115 else: 2116 checked, color = True, None 2117 if color: 2118 color = tuple(color) 2119 settings.user.ui.Set(LISTEN_BROADCAST_SETTING % name, checked) 2120 settings.user.ui.Set(BROADCAST_COLOR_SETTING % name, color) 2121 2122 settings.char.ui.Set('sharedBroadcastDragCont_name', settingName) 2123 sm.ScatterEvent('OnFleetBroadcastFilterChange') 2124 BroadcastSettings.CloseIfOpen() 2125 BroadcastSettings.Open() 2126 2127 def GetCynoTypeText(self, cynoTypeID): 2128 path = cynoTypeNames.get(cynoTypeID, None) 2129 if not path: 2130 return '' 2131 return localization.GetByLabel(path) 2132 2133 def GetAllowedGroupIDs(self, advertInfo): 2134 allowedGroups = set() 2135 if evefleet.IsOpenToCorp(advertInfo): 2136 allowedGroups.add(session.corpid) 2137 if session.allianceid is not None and evefleet.IsOpenToAlliance(advertInfo): 2138 allowedGroups.add(session.allianceid) 2139 if session.warfactionid is not None and evefleet.IsOpenToMilitia(advertInfo): 2140 allowedGroups.add(session.warfactionid) 2141 return allowedGroups 2142 2143 def OnFleetRespawnPointsUpdate(self, respawnPoints): 2144 self.respawnPoints = respawnPoints 2145 sm.ScatterEvent('OnFleetRespawnPointsUpdate_Local') 2146 2147 def GetRespawnPoints(self): 2148 return self.respawnPoints 2149 2150 @eveexceptions.EatsExceptions('protoClientLogs') 2151 def LogFleetCreation(self, fleetID, uiSource): 2152 self.message_bus.fleet_created(fleet_id=fleetID, ui_source=uiSource) 2153 2154 @eveexceptions.EatsExceptions('protoClientLogs') 2155 def LogFleetJoinAttempts(self, fleetID, uiSource): 2156 self.message_bus.applied_to_join(fleet_id=fleetID, ui_source=uiSource) 2157 2158 def AddFleetFinderAdvert(self, adInfoObject): 2159 adInfoData = adInfoObject.GetData() 2160 fleetAdvertDict = sm.ProxySvc('fleetProxy').AddFleetFinderAdvert(adInfoData) 2161 self.GetFleetAdsForChar_Memoized.clear_memoized() 2162 if fleetAdvertDict: 2163 return FleetAdvertObject(**fleetAdvertDict) 2164 2165 def UpdateFleetAdvertWithNewLeader(self, allowedEntitiesInfo): 2166 fleetAdvertDict = sm.ProxySvc('fleetProxy').UpdateFleetAdvertWithNewLeader(allowedEntitiesInfo) 2167 if fleetAdvertDict: 2168 return FleetAdvertObject(**fleetAdvertDict) 2169 2170 def RemoveFleetFinderAdvert(self): 2171 fleetAdvertDict = sm.ProxySvc('fleetProxy').RemoveFleetFinderAdvert() 2172 self.GetFleetAdsForChar_Memoized.clear_memoized() 2173 if fleetAdvertDict: 2174 return FleetAdvertObject(**fleetAdvertDict) 2175 2176 def GetMyFleetFinderAdvert(self): 2177 fleetAdvertDict = sm.ProxySvc('fleetProxy').GetMyFleetFinderAdvert() 2178 if fleetAdvertDict: 2179 return FleetAdvertObject(**fleetAdvertDict) 2180 2181 def UpdateAdvertInfo(self, numMembers, allowedDiffKeyVal): 2182 fleetAdvertDict = sm.ProxySvc('fleetProxy').UpdateAdvertInfo(numMembers, allowedDiffKeyVal) 2183 if fleetAdvertDict: 2184 return FleetAdvertObject(**fleetAdvertDict) 2185 2186 def UpdateAdvertAllowedEntities(self, allowedInfoFromStandings): 2187 fleetAdvertDict = sm.ProxySvc('fleetProxy').UpdateAdvertAllowedEntities(allowedInfoFromStandings) 2188 if fleetAdvertDict: 2189 return FleetAdvertObject(**fleetAdvertDict)