war_cso.py (13762B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\wars\war_cso.py 2 import gametime 3 from carbon.common.script.sys.service import Service 4 from carbon.common.script.sys.serviceConst import SERVICE_RUNNING, SERVICE_START_PENDING 5 from eve.client.script.ui.shared.neocom.corporation import corpUISignals 6 from eve.client.script.ui.util.searchUtil import GetResultsByGroupID 7 from eve.common.script.net import eveMoniker 8 from eve.common.script.search.const import MatchBy, ResultType 9 from eve.common.script.sys.idCheckers import IsNPC 10 import blue 11 import uthread 12 import evewar.util as warUtil 13 from evewar import warConst 14 from evewar.util import IsAtWar, IsWarInHostileState, IsWarFinished, IsWarInSpoolup, IsWarInCooldown 15 import eve.common.lib.appConst as appConst 16 17 class Wars(Service): 18 __exportedcalls__ = {'GetWars': [], 19 'GetRelationship': [], 20 'AreInAnyHostileWarStates': []} 21 __guid__ = 'svc.war' 22 __notifyevents__ = ['OnWarChanged', 'OnSessionChanged'] 23 __servicename__ = 'war' 24 __displayname__ = 'War Client Service' 25 __dependencies__ = [] 26 27 def __init__(self): 28 Service.__init__(self) 29 self.warsByOwnerID = {} 30 self.warsByWarID = {} 31 self.warsEnded = set() 32 self.warsStarted = set() 33 34 def GetDependencies(self): 35 return self.__dependencies__ 36 37 def Run(self, memStream = None): 38 self.LogInfo('Starting War') 39 self.state = SERVICE_START_PENDING 40 self.__warMoniker = None 41 self.__warMonikerOwnerID = None 42 self.state = SERVICE_RUNNING 43 uthread.new(self.CheckForStartOrEndOfWar) 44 45 def Stop(self, memStream = None): 46 self.__warMoniker = None 47 self.__warMonikerOwnerID = None 48 49 def RefreshMoniker(self): 50 if self.__warMoniker is not None: 51 self.__warMoniker.UnBind() 52 53 def GetMoniker(self): 54 if self.__warMoniker is None: 55 self.__warMoniker = eveMoniker.GetWar() 56 self.__warMonikerOwnerID = session.allianceid or session.corpid 57 if self.__warMonikerOwnerID != (session.allianceid or session.corpid): 58 if self.__warMoniker is not None: 59 self.__warMoniker.Unbind() 60 self.__warMoniker = eveMoniker.GetWar() 61 self.__warMonikerOwnerID = session.allianceid or session.corpid 62 self.__warMoniker.Bind() 63 return self.__warMoniker 64 65 def OnSessionChanged(self, isRemote, sess, change): 66 if 'allianceid' not in change and 'corpid' not in change: 67 return 68 if 'charid' in change and change['charid'][0] is None: 69 return 70 if session.allianceid: 71 self.warsByOwnerID.pop(session.allianceid, None) 72 self.warsByOwnerID.pop(session.corpid, None) 73 currentlyAtWar = self.IsPlayerCurrentlyAtWarOrInFW() 74 sm.ScatterEvent('OnWarStatusUpdated', currentlyAtWar, doAlert=True) 75 76 def OnWarChanged(self, war, ownerIDs, change): 77 try: 78 warsByOwnerID = {ownerID:warIDs for ownerID, (lastUpdated, warIDs) in self.warsByOwnerID.iteritems()} 79 warUtil.HandleWarChange(war, self.warsByWarID, warsByOwnerID, ownerIDs, change) 80 except Exception: 81 self.LogException() 82 finally: 83 corpUISignals.on_war_changed(war, ownerIDs, change) 84 sm.GetService('stateSvc').RemoveWarOwners(ownerIDs) 85 sm.GetService('tactical').InvalidateFlags() 86 sm.ScatterEvent('OnWarStatusUpdated', self.IsPlayerCurrentlyAtWarOrInFW(), doAlert=True) 87 88 def GetWars(self, ownerID, forceRefresh = 0): 89 if ownerID in self.warsByOwnerID: 90 if forceRefresh or blue.os.TimeDiffInMs(self.warsByOwnerID[ownerID][0], blue.os.GetWallclockTime()) > 12 * (appConst.HOUR / appConst.MSEC): 91 del self.warsByOwnerID[ownerID] 92 if ownerID not in self.warsByOwnerID: 93 wars = self.GetMoniker().GetWars(ownerID) 94 self.PopulateCacheAndCleanupWars(ownerID, wars) 95 warIDs = self.warsByOwnerID[ownerID][1] 96 return {warID:self.warsByWarID[warID] for warID in warIDs if warID in self.warsByWarID} 97 98 def PopulateCacheAndCleanupWars(self, ownerID, wars): 99 self.warsByWarID.update({war.warID:war for war in wars.itervalues()}) 100 warsByOwnerID = {war.warID for war in wars.itervalues()} 101 self.warsByOwnerID[ownerID] = (blue.os.GetWallclockTime(), warsByOwnerID) 102 usedWarIDs = set() 103 for lastUpdated, warIDs in self.warsByOwnerID.itervalues(): 104 usedWarIDs.update(warIDs) 105 106 for warID in self.warsByWarID.keys(): 107 if warID not in usedWarIDs: 108 del self.warsByWarID[warID] 109 110 def PrimeWarsForOwners(self, ownerIDs): 111 ownersToFetch = set() 112 for ownerID in ownerIDs: 113 if ownerID in self.warsByOwnerID: 114 if blue.os.TimeDiffInMs(self.warsByOwnerID[ownerID][0], blue.os.GetWallclockTime()) > 12 * (appConst.HOUR / appConst.MSEC): 115 ownersToFetch.add(ownerID) 116 else: 117 ownersToFetch.add(ownerID) 118 119 if ownersToFetch: 120 warsByOwnerIDs = sm.RemoteSvc('warsInfoMgr').GetWarsByOwners(ownersToFetch) 121 for ownerID, wars in warsByOwnerIDs.iteritems(): 122 self.PopulateCacheAndCleanupWars(ownerID, wars) 123 124 def GetRelationship(self, ownerID): 125 if ownerID == session.corpid: 126 return warConst.warRelationshipYourCorp 127 if ownerID == session.allianceid: 128 return warConst.warRelationshipYourAlliance 129 myWarEntityID = session.corpid if session.allianceid is None else session.allianceid 130 wars = self.GetWars(myWarEntityID) 131 entities = (ownerID, myWarEntityID) 132 if IsAtWar(wars.itervalues(), entities, blue.os.GetWallclockTime()): 133 return warConst.warRelationshipAtWarCanFight 134 for war in wars.itervalues(): 135 if myWarEntityID == war.againstID and ownerID in war.allies: 136 return warConst.warRelationshipAlliesAtWar 137 if ownerID == war.againstID and myWarEntityID in war.allies: 138 return warConst.warRelationshipAlliesAtWar 139 if ownerID in war.allies and myWarEntityID in war.allies: 140 return warConst.warRelationshipAlliesAtWar 141 142 return warConst.warRelationshipUnknown 143 144 def AreInAnyHostileWarStates(self, ownerID): 145 if ownerID not in self.warsByOwnerID: 146 self.GetWars(ownerID) 147 warsForOwnerID = self.warsByOwnerID[ownerID] 148 timestamp, warIDs = warsForOwnerID[0], warsForOwnerID[1] 149 for warID in warIDs: 150 war = self.warsByWarID[warID] 151 if (ownerID in {war.declaredByID, war.againstID} or ownerID in war.allies) and IsWarInHostileState(war, blue.os.GetWallclockTime()): 152 return True 153 154 return False 155 156 def CheckForStartOrEndOfWar(self): 157 while self.state == SERVICE_RUNNING: 158 if session.charid: 159 try: 160 self._CheckForWarStartingOrEnding() 161 except Exception: 162 self.LogException() 163 164 blue.pyos.synchro.SleepWallclock(10000) 165 166 def _CheckForWarStartingOrEnding(self): 167 wars = self.GetWars(session.allianceid or session.corpid) 168 now = blue.os.GetWallclockTime() 169 yesterday = now - appConst.DAY - appConst.HOUR 170 ownersToUpdate = set() 171 warStartedOrExpired = False 172 for war in wars.itervalues(): 173 if IsWarFinished(war) and war.warID not in self.warsEnded: 174 ownersToUpdate.update([war.declaredByID, war.againstID]) 175 self.warsEnded.add(war.warID) 176 warStartedOrExpired = True 177 elif IsWarInHostileState(war, now) and yesterday <= war.timeStarted < now and war.warID not in self.warsStarted: 178 ownersToUpdate.update([war.declaredByID, war.againstID] + war.allies.keys()) 179 self.warsStarted.add(war.warID) 180 warStartedOrExpired = True 181 182 if ownersToUpdate: 183 sm.GetService('stateSvc').RemoveWarOwners(ownersToUpdate) 184 sm.GetService('tactical').InvalidateFlags() 185 if warStartedOrExpired: 186 currentlyAtWar = self.IsPlayerCurrentlyAtWarOrInFW() 187 sm.ScatterEvent('OnWarStatusUpdated', currentlyAtWar, doAlert=True) 188 189 def GetAllyNegotiations(self): 190 warMoniker = self.GetMoniker() 191 return filter(lambda x: x.warNegotiationTypeID == warConst.WAR_NEGOTIATION_TYPE_ALLY_OFFER, warMoniker.GetNegotiations()) 192 193 def GetSurrenderNegotiations(self, warID): 194 warMoniker = self.GetMoniker() 195 return filter(lambda x: x.warNegotiationTypeID == warConst.WAR_NEGOTIATION_TYPE_SURRENDER_OFFER and x.warID == warID, warMoniker.GetNegotiations()) 196 197 def CreateWarAllyOffer(self, warID, iskValue, defenderID, message): 198 warMoniker = self.GetMoniker() 199 warMoniker.CreateWarAllyOffer(warID, iskValue, defenderID, message) 200 201 def RetractWarAllyOffer(self, warNegotiationID): 202 self.GetMoniker().RetractWarAllyOffer(warNegotiationID) 203 204 def CreateSurrenderNegotiation(self, warID, iskValue, message): 205 warMoniker = self.GetMoniker() 206 warMoniker.CreateSurrenderNegotiation(warID, iskValue, message) 207 208 def GetWarNegotiation(self, warNegotiationID): 209 return self.GetMoniker().GetWarNegotiation(warNegotiationID) 210 211 def AcceptAllyNegotiation(self, warNegotiationID): 212 warMoniker = self.GetMoniker() 213 warMoniker.AcceptAllyNegotiation(warNegotiationID) 214 215 def DeclineAllyOffer(self, warNegotiationID): 216 self.GetMoniker().DeclineAllyOffer(warNegotiationID) 217 218 def RetractMutualWar(self, warID): 219 warMoniker = self.GetMoniker() 220 warMoniker.RetractMutualWar(warID) 221 222 def AcceptSurrender(self, warNegotiationID): 223 warMoniker = self.GetMoniker() 224 warMoniker.AcceptSurrender(warNegotiationID) 225 226 def DeclineSurrender(self, warNegotiationID): 227 self.GetMoniker().DeclineSurrender(warNegotiationID) 228 229 def SetOpenForAllies(self, warID, state): 230 self.GetMoniker().SetOpenForAllies(warID, state) 231 232 def GMJoinDefender(self, warID, entityID): 233 warMoniker = self.GetMoniker() 234 warEntityID = session.corpid if session.allianceid is None else session.allianceid 235 warMoniker.GMJoinDefender(warID, entityID, warEntityID) 236 237 def GMActivateDefender(self, warID, allyID): 238 warMoniker = self.GetMoniker() 239 warMoniker.GMActivateDefender(warID, allyID) 240 241 def GMDeactivateDefender(self, warID, allyID): 242 warMoniker = self.GetMoniker() 243 warMoniker.GMDeactivateDefender(warID, allyID) 244 245 def GMExtendAllyContract(self, warID, allyID, time): 246 warMoniker = self.GetMoniker() 247 warMoniker.GMExtendAllyContract(warID, allyID, time) 248 249 def GMSetDeclareTime(self, warID, time): 250 mon = self.GetMoniker() 251 mon.GMSetDeclareTime(warID, time) 252 253 def GMSetWarFinishTime(self, warID, time): 254 mon = self.GetMoniker() 255 mon.GMSetWarFinishTime(warID, time) 256 257 def IsAllyInWar(self, warID): 258 warEntityID = session.allianceid or session.corpid 259 war = self.warsByWarID.get(warID, None) 260 if war is None: 261 return False 262 allyRow = war.allies.get(warEntityID, None) 263 if allyRow is not None and allyRow.timeFinished > blue.os.GetWallclockTime(): 264 return True 265 return False 266 267 def IsPlayerCurrentlyAtWarOrInFW(self): 268 if session.warfactionid: 269 return True 270 ownerID = session.allianceid or session.corpid 271 return self._IsOwnerAtWar(ownerID) 272 273 def _IsOwnerAtWar(self, ownerID): 274 if ownerID not in self.warsByOwnerID: 275 self.GetWars(ownerID) 276 timestampAndWars = self.warsByOwnerID.get(ownerID, None) 277 if not timestampAndWars: 278 return False 279 ownerWars = timestampAndWars[1] 280 now = gametime.GetWallclockTime() 281 for eachWarID in ownerWars: 282 eachWar = self.warsByWarID.get(eachWarID) 283 if not eachWar: 284 continue 285 if IsWarInSpoolup(eachWar): 286 continue 287 if IsWarFinished(eachWar): 288 continue 289 if ownerID not in (eachWar.declaredByID, eachWar.againstID) and ownerID in getattr(eachWar, 'allies', ()): 290 allyRow = eachWar.allies[ownerID] 291 if allyRow.timeStarted > now or allyRow.timeFinished < now: 292 continue 293 if eachWar.timeFinished is None or IsWarInCooldown(eachWar): 294 return True 295 296 return False 297 298 def SearchForWarableEntity(self, searchStr, exact): 299 searchBy = MatchBy.exact_phrase_only if exact else MatchBy.partial_terms 300 warableResult, allResultsByGroupID = uthread.parallel([(sm.RemoteSvc('lookupSvc').LookupWarableCorporationsOrAlliances, (searchStr, exact)), (GetResultsByGroupID, (searchStr, [ResultType.corporation], searchBy))]) 301 warableByID = {x.ownerID:x for x in warableResult} 302 allCorpResults = allResultsByGroupID.get(ResultType.corporation, []) 303 nonWarableCorpIDs = {x for x in allCorpResults if x not in warableByID and not IsNPC(x)} 304 cfg.eveowners.Prime(nonWarableCorpIDs) 305 searchStrLower = searchStr.lower() 306 corpIDsThatStartWithSearchStr = [ x for x in nonWarableCorpIDs if cfg.eveowners.Get(x).name.lower().startswith(searchStrLower) ] 307 return (warableByID, corpIDsThatStartWithSearchStr) 308 309 def GetPeaceTreaties(self): 310 outgoingTreaties, incomingTreaties = sm.RemoteSvc('peaceTreatyMgr').GetPeaceTreatiesForSession() 311 return (outgoingTreaties, incomingTreaties)