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

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)