crimewatchSvc.py (27223B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\crimewatchSvc.py 2 import clonegrade 3 import dogma.data 4 import blue 5 import uthread 6 import utillib 7 from carbon.common.script.sys.service import Service 8 from chroma import Color 9 from corruptionsuppression.systemEffects import DoesConcordReact 10 from crimewatch.const import containerGroupsWithLootRights 11 from crimewatch.util import IsItemFreeForAggression 12 from eve.client.script.ui.crimewatch.duelInviteWindow import DuelInviteWindow 13 from eve.common.lib import appConst as const 14 from eve.common.script.net import eveMoniker 15 from eve.common.script.sys import eveCfg, idCheckers 16 from eve.common.script.sys.eveCfg import IsControllingStructure 17 from eve.common.script.util import facwarCommon 18 from eveuniverse.security import is_high_sec_or_higher, is_low_sec_or_higher, is_safe_sec_solar_system 19 from inventorycommon.const import categoryStructure 20 from inventorycommon.util import IsNPC 21 from localization.formatters.timeIntervalFormatters import GetByLabel 22 from omega.client.clone_grade_svc import get_clone_grade_svc 23 from security.client.securityColor import get_security_status_color 24 from spacecomponents.common.components.enforcecriminalflag import has_enforce_suspect_flag, has_enforce_criminal_flag 25 from spacecomponents.common.helper import HasEnforceCriminalFlagComponent 26 from evewar import warConst 27 from eve.common.script.sys.idCheckers import IsWormholeSystem 28 from eve.common.script.util.facwarCommon import IsSameFwFaction, IsCombatEnemyFaction 29 30 class CrimewatchService(Service): 31 __guid__ = 'svc.crimewatchSvc' 32 __dependencies__ = ['michelle', 33 'godma', 34 'war', 35 'facwar', 36 'corp', 37 'securitySvc'] 38 __startupdependencies__ = [] 39 __notifyevents__ = ['ProcessSessionChange', 40 'OnWeaponsTimerUpdate', 41 'OnPvpTimerUpdate', 42 'OnNpcTimerUpdate', 43 'OnCriminalTimerUpdate', 44 'OnDisapprovalTimerUpdate', 45 'OnSystemCriminalFlagUpdates', 46 'OnSystemDisapprovalFlagUpdates', 47 'OnCrimewatchEngagementCreated', 48 'OnCrimewatchEngagementEnded', 49 'OnCrimewatchEngagementStartTimeout', 50 'OnCrimewatchEngagementStopTimeout', 51 'OnDuelChallenge', 52 'OnSecurityStatusUpdate', 53 'OnJumpTimersUpdated', 54 'OnCorpAggressionSettingsChange', 55 'OnSessionReset', 56 'OnSubscriptionChanged', 57 'OnSessionChanged'] 58 59 def Run(self, *args): 60 Service.Run(self, *args) 61 self.Initialize() 62 63 def Initialize(self): 64 self.weaponsTimerState = None 65 self.weaponsTimerExpiry = None 66 self.pvpTimerState = None 67 self.pvpTimerExpiry = None 68 self.npcTimerState = None 69 self.npcTimerExpiry = None 70 self.criminalTimerState = None 71 self.criminalTimerExpiry = None 72 self.disapprovalTimerState = None 73 self.disapprovalTimerExpiry = None 74 self.criminalFlagsByCharID = {} 75 self.disapprovalFlagsByCharID = {} 76 self.myEngagements = {} 77 self.safetyLevel = const.shipSafetyLevelFull 78 self.duelWindow = None 79 self.mySecurityStatus = None 80 self.jumpTimers = None 81 self.corpAggressionSettings = None 82 83 def OnSubscriptionChanged(self): 84 if session.charid and session.solarsystemid: 85 _, _, _, safetyLevel = eveMoniker.CharGetCrimewatchLocation().GetClientStates() 86 self._UpdateSafetyLevel(safetyLevel) 87 sm.ScatterEvent('OnReCheckAlphaLock') 88 89 def ProcessSessionChange(self, isRemote, session, change): 90 if 'locationid' in change or 'charid' in change: 91 myCombatTimers, myEngagements, flaggedCharacters, _ = eveMoniker.CharGetCrimewatchLocation().GetClientStates() 92 self.LogInfo('ProcessSessionChange', myCombatTimers, myEngagements, flaggedCharacters) 93 weaponTimerState, pvpTimerState, npcTimerState, criminalTimerState, disapprovalTimerState = myCombatTimers 94 self.weaponsTimerState, self.weaponsTimerExpiry = weaponTimerState 95 self.pvpTimerState, self.pvpTimerExpiry = pvpTimerState 96 self.npcTimerState, self.npcTimerExpiry = npcTimerState 97 self.criminalTimerState, self.criminalTimerExpiry = criminalTimerState 98 self.disapprovalTimerState, self.disapprovalTimerExpiry = disapprovalTimerState 99 self.myEngagements = myEngagements 100 sm.ScatterEvent('OnCombatTimersUpdated') 101 criminals, suspects = flaggedCharacters 102 self.criminalFlagsByCharID.clear() 103 self.UpdateSuspectsAndCriminals(criminals, suspects) 104 if self.duelWindow is not None: 105 self.duelWindow.Close() 106 self.duelWindow = None 107 if 'corpid' in change: 108 self.RefreshCorpAggressionSettings() 109 110 def OnSessionChanged(self, isRemote, session, change): 111 if not session.solarsystemid: 112 return 113 if 'solarsystemid' in change or 'shipid' in change: 114 _, _, _, safetyLevel = eveMoniker.CharGetCrimewatchLocation().GetClientStates() 115 self.LogInfo('OnSessionChanged', safetyLevel) 116 self._UpdateSafetyLevel(safetyLevel) 117 118 def _ReCheckAlphaLock(self): 119 if self._IsAlphaClone(): 120 sm.ScatterEvent('OnReCheckAlphaLock') 121 122 def _IsAlphaClone(self): 123 clone_grade = get_clone_grade_svc().get_clone_grade_with_grace_period() 124 return clone_grade == clonegrade.CLONE_STATE_ALPHA 125 126 def OnSessionReset(self): 127 self.Initialize() 128 129 def _UpdateSafetyLevel(self, safetyLevel): 130 if self.IsSafetyLockedToFullLevel(): 131 safetyLevel = const.shipSafetyLevelFull 132 old = self.safetyLevel 133 self.safetyLevel = safetyLevel 134 if self.safetyLevel != old: 135 sm.ScatterEvent('OnSafetyLevelChanged', self.safetyLevel) 136 elif self._IsAlphaClone(): 137 sm.ScatterEvent('OnReCheckAlphaLock') 138 139 def IsSafetyLockedToFullLevel(self): 140 if not session.solarsystemid: 141 return False 142 if is_safe_sec_solar_system(session.solarsystemid): 143 color = Color(*get_security_status_color(1.0)).hex_argb 144 return GetByLabel('UI/Crimewatch/SafetyLevel/SafetyLockedToFullInSafeSec', color=color) 145 if IsControllingStructure(): 146 securityClass = self.securitySvc.get_modified_security_class(session.solarsystemid) 147 if is_high_sec_or_higher(securityClass): 148 color = Color(*get_security_status_color(0.9)).hex_argb 149 return GetByLabel('UI/Crimewatch/SafetyLevel/SafetyLockedToFullInHighSecStructures', color=color) 150 return False 151 152 def IsSafetyAlphaLocked(self): 153 if self._IsAlphaClone(): 154 if session.solarsystemid2: 155 securityClass = self.securitySvc.get_modified_security_class(session.solarsystemid2) 156 return is_high_sec_or_higher(securityClass) 157 return False 158 159 def GetSlimItemDataForCharID(self, charID): 160 slimItem = None 161 if eveCfg.InShipInSpace(): 162 ballpark = self.michelle.GetBallpark() 163 if ballpark: 164 for _slimItem in ballpark.slimItems.itervalues(): 165 if _slimItem.charID == charID: 166 slimItem = _slimItem 167 break 168 169 if slimItem is None: 170 pubInfo = sm.RemoteSvc('charMgr').GetPublicInfo(charID) 171 info = cfg.eveowners.Get(charID) 172 slimItem = utillib.KeyVal() 173 slimItem.charID = charID 174 slimItem.typeID = info.typeID 175 slimItem.corpID = pubInfo.corporationID 176 slimItem.warFactionID = pubInfo.warFactionID 177 slimItem.allianceID = pubInfo.allianceID 178 slimItem.securityStatus = self.GetCharacterSecurityStatus(charID) 179 slimItem.groupID = const.groupCharacter 180 slimItem.categoryID = const.categoryOwner 181 slimItem.itemID = None 182 slimItem.ownerID = charID 183 return slimItem 184 185 def UpdateSuspectsAndCriminals(self, criminals, suspects, decriminalizedCharIDs = ()): 186 for charID in decriminalizedCharIDs: 187 try: 188 del self.criminalFlagsByCharID[charID] 189 except KeyError: 190 pass 191 192 for charID in criminals: 193 self.criminalFlagsByCharID[charID] = const.criminalTimerStateActiveCriminal 194 195 for charID in suspects: 196 self.criminalFlagsByCharID[charID] = const.criminalTimerStateActiveSuspect 197 198 criminalizedCharIDs = set(self.criminalFlagsByCharID.iterkeys()) 199 sm.ScatterEvent('OnSuspectsAndCriminalsUpdate', criminalizedCharIDs, set(decriminalizedCharIDs)) 200 201 def UpdateDisapprovals(self, newNaughtyChars, noLongerNaughty): 202 for charID in noLongerNaughty: 203 self.disapprovalFlagsByCharID.pop(charID, None) 204 205 for charID in newNaughtyChars: 206 self.disapprovalFlagsByCharID[charID] = const.disapprovalTimerStateActive 207 208 sm.ScatterEvent('OnDisapprovalUpdate', newNaughtyChars, noLongerNaughty) 209 210 def OnWeaponsTimerUpdate(self, state, expiryTime): 211 self.LogInfo('OnWeaponsTimerUpdate', state, expiryTime) 212 self.weaponsTimerState = state 213 self.weaponsTimerExpiry = expiryTime 214 215 def OnPvpTimerUpdate(self, state, expiryTime): 216 self.LogInfo('OnPvpTimerUpdate', state, expiryTime) 217 self.pvpTimerState = state 218 self.pvpTimerExpiry = expiryTime 219 220 def OnNpcTimerUpdate(self, state, expiryTime): 221 self.LogInfo('OnNpcTimerUpdate', state, expiryTime) 222 self.npcTimerState = state 223 self.npcTimerExpiry = expiryTime 224 225 def OnCriminalTimerUpdate(self, state, expiryTime): 226 self.LogInfo('OnCriminalTimerUpdate', state, expiryTime) 227 self.criminalTimerState = state 228 self.criminalTimerExpiry = expiryTime 229 230 def OnDisapprovalTimerUpdate(self, state, expiryTime): 231 self.LogInfo('OnDisapprovalTimerUpdate', state, expiryTime) 232 self.disapprovalTimerState = state 233 self.disapprovalTimerExpiry = expiryTime 234 235 def OnSystemCriminalFlagUpdates(self, newIdles, newSuspects, newCriminals): 236 self.LogInfo('OnSystemCriminalFlagUpdates', newIdles, newSuspects, newCriminals) 237 self.UpdateSuspectsAndCriminals(newCriminals, newSuspects, newIdles) 238 239 def OnSystemDisapprovalFlagUpdates(self, newIdles, newNaughyBoysAndGirls): 240 self.LogInfo('OnSystemDisapprovalFlagUpdates', newIdles, newNaughyBoysAndGirls) 241 self.UpdateDisapprovals(newNaughyBoysAndGirls, newIdles) 242 243 def OnCrimewatchEngagementCreated(self, otherCharId, timeout): 244 self.LogInfo('OnCrimewatchEngagementCreated', otherCharId, timeout) 245 self.myEngagements[otherCharId] = timeout 246 sm.ScatterEvent('OnCrimewatchEngagementUpdated', otherCharId, timeout) 247 if self.duelWindow is not None and self.duelWindow.charID == otherCharId: 248 self.duelWindow.Close() 249 self.duelWindow = None 250 251 def OnCrimewatchEngagementEnded(self, otherCharId): 252 self.LogInfo('OnCrimewatchEngagementEnded', otherCharId) 253 if otherCharId in self.myEngagements: 254 del self.myEngagements[otherCharId] 255 sm.ScatterEvent('OnCrimewatchEngagementUpdated', otherCharId, None) 256 257 def OnCrimewatchEngagementStartTimeout(self, otherCharId, timeout): 258 self.LogInfo('OnCrimewatchEngagementStartTimeout', otherCharId, timeout) 259 self.myEngagements[otherCharId] = timeout 260 sm.ScatterEvent('OnCrimewatchEngagementUpdated', otherCharId, timeout) 261 262 def OnCrimewatchEngagementStopTimeout(self, otherCharId): 263 self.LogInfo('OnCrimewatchEngagementStopTimeout', otherCharId) 264 self.myEngagements[otherCharId] = const.crimewatchEngagementTimeoutOngoing 265 sm.ScatterEvent('OnCrimewatchEngagementUpdated', otherCharId, const.crimewatchEngagementTimeoutOngoing) 266 267 def GetMyEngagements(self): 268 return self.myEngagements.copy() 269 270 def GetMyBoosters(self): 271 if not session.charid: 272 return [] 273 myGodmaItem = sm.GetService('godma').GetItem(session.charid) 274 if hasattr(myGodmaItem, 'boosters'): 275 return myGodmaItem.boosters 276 return [] 277 278 def GetBoosterEffects(self, booster): 279 godma = sm.GetService('godma') 280 dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation() 281 staticMgr = dogmaLocation.dogmaStaticMgr 282 boosterEffectsNegative = [] 283 boosterEffectsPositive = [] 284 if booster: 285 boosterEffects = staticMgr.GetPassiveFilteredEffectsByType(booster.boosterTypeID) 286 for effectID in boosterEffects: 287 eff = dogma.data.get_effect(effectID) 288 chanceAttributeID = staticMgr.effects[effectID].fittingUsageChanceAttributeID 289 if chanceAttributeID and effectID in booster.sideEffectIDs: 290 boosterEffectsNegative.append(eff) 291 if not chanceAttributeID: 292 boosterEffectsPositive.append(eff) 293 294 return {'negative': boosterEffectsNegative, 295 'positive': boosterEffectsPositive} 296 297 def GetWeaponsTimer(self): 298 return (self.weaponsTimerState, self.weaponsTimerExpiry) 299 300 def GetNpcTimer(self): 301 return (self.npcTimerState, self.npcTimerExpiry) 302 303 def GetPvpTimer(self): 304 return (self.pvpTimerState, self.pvpTimerExpiry) 305 306 def GetCriminalTimer(self): 307 return (self.criminalTimerState, self.criminalTimerExpiry) 308 309 def GetDisapprovalTimer(self): 310 return (self.disapprovalTimerState, self.disapprovalTimerExpiry) 311 312 def GetSafetyLevel(self): 313 return self.safetyLevel 314 315 def SetSafetyLevel(self, safetyLevel): 316 eveMoniker.CharGetCrimewatchLocation().SetSafetyLevel(safetyLevel) 317 self.safetyLevel = safetyLevel 318 sm.ScatterEvent('OnSafetyLevelChanged', self.safetyLevel) 319 320 def IsCriminal(self, charID): 321 return self.criminalFlagsByCharID.get(charID) == const.criminalTimerStateActiveCriminal 322 323 def IsSuspect(self, charID): 324 return self.criminalFlagsByCharID.get(charID) == const.criminalTimerStateActiveSuspect 325 326 def IsDisapproved(self, charID): 327 return self.disapprovalFlagsByCharID.get(charID) == const.disapprovalTimerStateActive 328 329 def IsCriminallyFlagged(self, charID): 330 return charID in self.criminalFlagsByCharID 331 332 def IsDisapprovalFlagged(self, charID): 333 return charID in self.disapprovalFlagsByCharID 334 335 def HasLimitedEngagmentWith(self, charID): 336 return charID in self.myEngagements 337 338 def HaveWeaponsTimer(self): 339 return self.weaponsTimerState != const.weaponsTimerStateIdle 340 341 def GetRequiredSafetyLevelForActivatingAccelerationGate(self, gateID): 342 bp = self.michelle.GetBallpark() 343 item = bp.GetInvItem(gateID) 344 if item is None: 345 return (const.shipSafetyLevelFull, None, None) 346 if item.isFactionWarfareGate or item.isInsurgencyGate: 347 if session.warfactionid is None: 348 return (const.shipSafetyLevelPartial, 'DunGateNonFactionWarfareSafetyPreventsSuspect', None) 349 sameFactionOrEnemy = IsCombatEnemyFaction(session.warfactionid, item.ownerID) or IsSameFwFaction(session.warfactionid, item.ownerID) 350 if not sameFactionOrEnemy: 351 return (const.shipSafetyLevelPartial, 'DunGateNonFactionWarfareSafetyPreventsSuspect', None) 352 if item.dunKeyLock == const.dungeonKeySoftLockOwnerSuspect: 353 gateOwnerID = item.dunOwnerLock 354 if not gateOwnerID or item.dunOwnerLock == session.charid or sm.GetService('fleet').IsMember(item.dunOwnerLock): 355 return (const.shipSafetyLevelFull, None, None) 356 else: 357 return (const.shipSafetyLevelPartial, 'DunGateFactionCampaignSuspectSiteSafetyPreventsSuspect', 'ConfirmActivateGateSuspect') 358 return (const.shipSafetyLevelFull, None, None) 359 360 def GetRequiredSafetyLevelForAssistanc(self, targetID): 361 if self.IsCriminal(targetID): 362 return const.shipSafetyLevelNone 363 elif self.IsSuspect(targetID): 364 return const.shipSafetyLevelPartial 365 else: 366 return const.shipSafetyLevelFull 367 368 def GetSafetyLevelRestrictionForAttackingTarget(self, targetID, effect = None): 369 securityClass = self.securitySvc.get_modified_security_class(session.solarsystemid) 370 minSafetyLevel = const.shipSafetyLevelFull 371 if is_low_sec_or_higher(securityClass): 372 item = self.michelle.GetItem(targetID) 373 if not item: 374 if effect.rangeAttributeID is not None: 375 minSafetyLevel = const.shipSafetyLevelNone 376 elif idCheckers.IsSystemOrNPC(item.ownerID): 377 minSafetyLevel = self._GetMinimumSafetyLevelForNpc(item, securityClass) 378 elif not self.CanAttackFreely(item): 379 if is_high_sec_or_higher(securityClass): 380 if not DoesConcordReact(sm.GetService('clientDogmaIM').GetDogmaLocation(), item.groupID, True): 381 minSafetyLevel = const.shipSafetyLevelPartial 382 else: 383 minSafetyLevel = const.shipSafetyLevelNone 384 elif item.groupID == const.groupCapsule: 385 minSafetyLevel = const.shipSafetyLevelNone 386 else: 387 minSafetyLevel = const.shipSafetyLevelPartial 388 return minSafetyLevel 389 390 def GetSafetyLevelRestrictionForAidingTarget(self, targetID): 391 secClass = self.securitySvc.get_modified_security_class(session.solarsystemid) 392 minSafetyLevel = const.shipSafetyLevelFull 393 if is_low_sec_or_higher(secClass): 394 item = self.michelle.GetItem(targetID) 395 if item and item.ownerID != session.charid: 396 if self.IsCriminallyFlagged(item.ownerID): 397 if self.IsCriminal(item.ownerID): 398 minSafetyLevel = const.shipSafetyLevelNone 399 elif self.IsSuspect(item.ownerID): 400 minSafetyLevel = const.shipSafetyLevelPartial 401 else: 402 minSafetyLevel = const.shipSafetyLevelFull 403 return minSafetyLevel 404 405 def CanAttackFreely(self, item): 406 if idCheckers.IsSystem(item.ownerID) or item.ownerID == session.charid: 407 return True 408 securityClass = self.securitySvc.get_modified_security_class(session.solarsystemid) 409 if securityClass == const.securityClassZeroSec: 410 return True 411 if self.IsCriminallyFlagged(item.ownerID): 412 return True 413 if self.HasLimitedEngagmentWith(item.ownerID): 414 return True 415 if idCheckers.IsCharacter(item.ownerID) and eveCfg.IsOutlawStatus(item.securityStatus): 416 return True 417 if session.warfactionid: 418 if hasattr(item, 'warFactionID') and facwarCommon.IsCombatEnemyFaction(item.warFactionID, session.warfactionid): 419 return True 420 belongToPlayerCorp = not IsNPC(session.corpid) 421 if belongToPlayerCorp and not is_safe_sec_solar_system(session.solarsystemid): 422 if item.ownerID == session.corpid: 423 if self.GetCorpAggressionSettings().IsFriendlyFireLegalAtTime(blue.os.GetWallclockTime()): 424 return True 425 otherCorpID = getattr(item, 'corpID', None) 426 if otherCorpID is not None: 427 if otherCorpID == session.corpid: 428 if self.GetCorpAggressionSettings().IsFriendlyFireLegalAtTime(blue.os.GetWallclockTime()): 429 return True 430 if self.war.GetRelationship(otherCorpID) == warConst.warRelationshipAtWarCanFight: 431 return True 432 otherAllianceID = getattr(item, 'allianceID', None) 433 if otherAllianceID is not None: 434 if self.war.GetRelationship(otherAllianceID) == warConst.warRelationshipAtWarCanFight: 435 return True 436 if IsItemFreeForAggression(item.groupID): 437 return True 438 return False 439 440 def _GetActiveEffectsByItem(self, itemID): 441 effectIDs = set() 442 item = self.michelle.GetItem(itemID) 443 if item is not None: 444 for row in dogma.data.get_type_effects(item.typeID): 445 effectID, isDefault = row.effectID, row.isDefault 446 if isDefault: 447 effectIDs.add(effectID) 448 449 return [ dogma.data.get_effect(effectID) for effectID in effectIDs ] 450 451 def IsAnyEffectOffensive(self, itemIDs): 452 for itemID in itemIDs: 453 for effect in self._GetActiveEffectsByItem(itemID): 454 if effect.isOffensive: 455 return True 456 457 return False 458 459 def GetRequiredSafetyLevelForEffect(self, effect, targetID = None): 460 requiredSafetyLevel = const.shipSafetyLevelFull 461 if effect is not None: 462 if targetID is None and effect.effectCategory == const.dgmEffTarget: 463 targetID = sm.GetService('target').GetActiveTargetID() 464 if targetID is None: 465 return requiredSafetyLevel 466 requiredSafetyLevel = const.shipSafetyLevelFull 467 if effect.isOffensive: 468 requiredSafetyLevel = self.GetSafetyLevelRestrictionForAttackingTarget(targetID, effect) 469 elif effect.isAssistance: 470 requiredSafetyLevel = self.GetSafetyLevelRestrictionForAidingTarget(targetID) 471 return requiredSafetyLevel 472 473 def CheckUnsafe(self, requiredSafetyLevel): 474 if requiredSafetyLevel < self.safetyLevel: 475 return True 476 else: 477 return False 478 479 def SafetyActivated(self, requiredSafetyLevel): 480 self.LogInfo('Safeties activated', self.safetyLevel, requiredSafetyLevel) 481 sm.ScatterEvent('OnCrimewatchSafetyCheckFailed') 482 483 def CheckCanTakeItems(self, containerID): 484 if session.solarsystemid is None: 485 return True 486 bp = self.michelle.GetBallpark() 487 if bp and not IsWormholeSystem(bp.solarsystemID) and self.GetSafetyLevel() == const.shipSafetyLevelFull: 488 item = bp.GetInvItem(containerID) 489 if item is not None: 490 if item.groupID in containerGroupsWithLootRights: 491 bp = self.michelle.GetBallpark() 492 if bp and not bp.HaveLootRight(containerID): 493 return False 494 return True 495 496 def IsOkToScoopItem(self, itemID): 497 securityClass = self.securitySvc.get_modified_security_class(session.solarsystemid) 498 if securityClass == const.securityClassZeroSec: 499 return True 500 if self.GetSafetyLevel() != const.shipSafetyLevelFull: 501 return True 502 bp = self.michelle.GetBallpark() 503 if not bp: 504 return True 505 item = bp.GetInvItem(itemID) 506 if item is not None: 507 if item.categoryID == categoryStructure and item.ownerID not in (session.charid, session.corpid): 508 return False 509 return True 510 511 def GetRequiredSafetyLevelForEngagingDrones(self, droneIDs, targetID): 512 safetyLevel = const.shipSafetyLevelFull 513 if targetID is not None: 514 effects = [] 515 for droneID in droneIDs: 516 effects += self._GetActiveEffectsByItem(droneID) 517 518 if effects: 519 safetyLevels = [ self.GetRequiredSafetyLevelForEffect(effect, targetID) for effect in effects ] 520 safetyLevel = min(safetyLevels) 521 return safetyLevel 522 523 def OnDuelChallenge(self, fromCharID, fromCorpID, fromAllianceID, expiryTime): 524 self.LogInfo('OnDuelChallenge', fromCharID, fromCorpID, fromAllianceID, expiryTime) 525 wnd = DuelInviteWindow(charID=fromCharID, corpID=fromCorpID, allianceID=fromAllianceID) 526 try: 527 self.duelWindow = wnd 528 wnd.StartTimeout(expiryTime) 529 result = wnd.ShowDialog(modal=False) 530 accept = None 531 if 'accept' in wnd.result: 532 accept = True 533 elif 'decline' in wnd.result: 534 accept = False 535 if 'block' in wnd.result: 536 uthread.new(sm.GetService('addressbook').BlockOwner, fromCharID) 537 if accept is not None: 538 eveMoniker.CharGetCrimewatchLocation().RespondToDuelChallenge(fromCharID, expiryTime, accept) 539 finally: 540 self.duelWindow = None 541 542 def StartDuel(self, charID): 543 if charID in self.myEngagements: 544 self.LogInfo('The char', charID, 'is already in limited engagement with us. No duel request sent.') 545 else: 546 eveMoniker.CharGetCrimewatchLocation().StartDuelChallenge(charID) 547 548 def GetMySecurityStatus(self): 549 if self.mySecurityStatus is None: 550 self.mySecurityStatus = eveMoniker.CharGetCrimewatchLocation().GetMySecurityStatus() 551 return self.mySecurityStatus 552 553 def GetCharacterSecurityStatus(self, charID): 554 return eveMoniker.CharGetCrimewatchLocation().GetCharacterSecurityStatus(charID) 555 556 def OnSecurityStatusUpdate(self, newSecurityStatus): 557 self.mySecurityStatus = newSecurityStatus 558 559 def GetSecurityStatusTransactions(self): 560 return eveMoniker.CharGetCrimewatchLocation().GetSecurityStatusTransactions() 561 562 def GetJumpTimers(self): 563 if self.jumpTimers is None: 564 self.jumpTimers = sm.RemoteSvc('jumpTimers').GetTimers(session.charid) 565 return self.jumpTimers 566 567 def OnJumpTimersUpdated(self, *args): 568 self.jumpTimers = args 569 570 def RefreshCorpAggressionSettings(self): 571 self.corpAggressionSettings = self.corp.GetCorpRegistry().GetAggressionSettings() 572 573 def GetCorpAggressionSettings(self): 574 if self.corpAggressionSettings is None: 575 self.RefreshCorpAggressionSettings() 576 return self.corpAggressionSettings 577 578 def OnCorpAggressionSettingsChange(self, aggressionSettings): 579 self.corpAggressionSettings = aggressionSettings 580 581 def _GetMinimumSafetyLevelForNpc(self, item, securityClass): 582 if item.ownerID == const.ownerCONCORD: 583 return const.shipSafetyLevelNone 584 if item.groupID in const.illegalTargetNpcOwnedGroups: 585 if is_high_sec_or_higher(securityClass): 586 return const.shipSafetyLevelNone 587 else: 588 return const.shipSafetyLevelPartial 589 elif HasEnforceCriminalFlagComponent(item.typeID): 590 if has_enforce_criminal_flag(item.typeID): 591 return const.shipSafetyLevelNone 592 if has_enforce_suspect_flag(item.typeID): 593 return const.shipSafetyLevelPartial 594 return const.shipSafetyLevelFull 595 596 def GetSecurityWhereAttacked(self): 597 characterSecurity = sm.GetService('crimewatchSvc').GetMySecurityStatus() 598 if characterSecurity <= -4.5: 599 return 0.5 600 if characterSecurity <= -4.0: 601 return 0.6 602 if characterSecurity <= -3.5: 603 return 0.7 604 if characterSecurity <= -3.0: 605 return 0.8 606 if characterSecurity <= -2.5: 607 return 0.9 608 if characterSecurity <= -2.0: 609 return 1.0