Пример #1
0
class OperationReceiver(OperationReceiverBase):
    """
    Operation receiver
    """
    def __init__(self,
                 sender,
                 loadsTransferType,
                 dumpsTransferType,
                 streamer=None):
        """
        Constructor
        @param sender: operation sender
        @type sender: MAILBOX
        """
        OperationReceiverBase.__init__(self, sender, loadsTransferType,
                                       dumpsTransferType, streamer)
        self.onReceiveOperation = Event()

    def _onReceiveOperation(self, operation):
        self.onReceiveOperation(operation)

    def destroy(self):
        """
        Destructor
        """
        OperationReceiverBase.destroy(self)
        self.onReceiveOperation.clear()
        self.onReceiveOperation = None
        return
Пример #2
0
class DisposableEntity(object):
    def __init__(self):
        super(DisposableEntity, self).__init__()
        self.onModuleDispose = Event()
        self.__created = False
        self.__disposed = False

    def create(self):
        self.__created = True
        self.__disposed = False
        self._populate()

    def destroy(self):
        if self.__disposed:
            return
        self.onModuleDispose(self)
        self.onModuleDispose.clear()
        self._dispose()
        self.__disposed = True

    def _populate(self):
        pass

    def _dispose(self):
        pass

    def _isCreated(self):
        return self.__created

    def isDisposed(self):
        return self.__disposed
Пример #3
0
class _SettingsCache(object):
    def __init__(self):
        self.__intSettings = IntSettingsRequester()
        self.__waitForSync = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()

    def init(self):
        g_clientUpdateManager.addCallbacks({"intUserSettings": self._onResync})

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def settings(self):
        return self.__intSettings

    def _onResync(self, *args):
        self.__invalidateData()

    @async
    def update(self, callback=None):
        self.__invalidateData(callback)

    def getSectionSettings(self, section, defaultValue=0):
        return self.__intSettings.getSetting(section, defaultValue)

    def setSectionSettings(self, section, value):
        self.__intSettings.setSetting(section, value)

    def setSettings(self, settings):
        self.__intSettings.setSettings(settings)

    def getSetting(self, key, defaultValue=0):
        return self.__intSettings.getSetting(key, defaultValue)

    def getVersion(self, defaultValue=0):
        return self.__intSettings.getSetting("VERSION", defaultValue)

    def setVersion(self, value):
        self.__intSettings.setSetting("VERSION", value)

    def __invalidateData(self, callback=lambda *args: None):
        def cbWrapper(*args):
            self.__waitForSync = False
            self.onSyncCompleted()
            callback(*args)

        self.__waitForSync = True
        self.onSyncStarted()
        if BattleReplay.g_replayCtrl.isPlaying:
            cbWrapper(dict())
            return
        self.__intSettings.request()(cbWrapper)
Пример #4
0
class DisposableEntity(object):

    def __init__(self):
        super(DisposableEntity, self).__init__()
        self.onModuleDispose = Event()
        self.__created = False
        self.__disposed = False

    def create(self):
        self.__created = True
        self.__disposed = False
        self._populate()

    def destroy(self):
        if self.__disposed:
            return
        self.onModuleDispose(self)
        self.onModuleDispose.clear()
        self._dispose()
        self.__disposed = True

    def _populate(self):
        pass

    def _dispose(self):
        pass

    def _isCreated(self):
        return self.__created

    def isDisposed(self):
        return self.__disposed
Пример #5
0
class _ItemsCache(object):

    def __init__(self):
        self.__items = ItemsRequester()
        self.__waitForSync = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()

    def init(self):
        g_playerEvents.onInventoryResync += self._onResync
        g_playerEvents.onDossiersResync += self._onResync
        g_playerEvents.onStatsResync += self._onResync
        g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected
        g_playerEvents.onStatsResync -= self._onResync
        g_playerEvents.onDossiersResync -= self._onResync
        g_playerEvents.onInventoryResync -= self._onResync

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def items(self):
        return self.__items

    @async
    def update(self, diff = None, callback = None):
        self.__invalidateData(diff, callback)

    def clear(self):
        return self.items.clear()

    def _onResync(self, *args):
        if not self.__waitForSync:
            self.__invalidateData()

    def _onCenterIsLongDisconnected(self, isLongDisconnected):
        self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected)

    def __invalidateData(self, diff = None, callback = lambda *args: None):

        def cbWrapper(*args):
            self.__waitForSync = False
            self.onSyncCompleted()
            callback(*args)

        self.__waitForSync = True
        self.onSyncStarted()
        self.__items.invalidateCache(diff)
        self.__items.request()(cbWrapper)

    def isSynced(self):
        return self.items.isSynced()
Пример #6
0
class SoundEnv(object):
    """Root sound environment class. Contains of one music event and
    one ambient event, also has bunch of filters, that can be applied to
    the sound system at @start method
    """
    def __init__(self,
                 soundsCtrl,
                 envId,
                 music=None,
                 ambient=None,
                 filters=None):
        self._soundsCtrl = soundsCtrl
        self._music = music or EmptySound()
        self._ambient = ambient or EmptySound()
        self._filters = filters or []
        self.__envID = envId
        self.onChanged = Event()

    def start(self):
        self._soundsCtrl.system.onEnvStart(self.__envID)

    def stop(self):
        self.onChanged.clear()
        self._soundsCtrl.system.onEnvStop(self.__envID)
        self._ambient.clear()
        self._music.clear()

    def getMusicEvent(self):
        """:return: SoundEvent object instance
        """
        return self._music

    def getAmbientEvent(self):
        """:return: SoundEvent object instance
        """
        return self._ambient

    def getFilters(self):
        """:return: list, filters ids
        """
        return self._filters

    def _onChanged(self):
        self.onChanged(self)

    def _setAmbientParam(self, paramName, value):
        SOUND_DEBUG('Change ambient parameter', paramName, value)
        self._ambient.setParam(paramName, value)

    def _setMusicParam(self, paramName, value):
        SOUND_DEBUG('Change music parameter', paramName, value)
        self._music.setParam(paramName, value)

    def __repr__(self):
        return '%s(music = %s, ambient = %s, filters = %d)' % (
            self.__class__.__name__, self._music, self._ambient,
            len(self._filters))
class AvatarQuestsInterfaceClient(object):
    def __init__(self):
        """
        @type self: Avatar.Avatar
        """
        self.eQuestCompleted = Event()

    def onLeaveWorld(self):
        self.eQuestCompleted.clear()

    def onQuestCompleted(self, questID):
        self.eQuestCompleted(questID)
Пример #8
0
class SoundEnv(object):
    """Root sound environment class. Contains of one music event and
    one ambient event, also has bunch of filters, that can be applied to
    the sound system at @start method
    """

    def __init__(self, soundsCtrl, envId, music = None, ambient = None, filters = None):
        self._soundsCtrl = soundsCtrl
        self._music = music or EmptySound()
        self._ambient = ambient or EmptySound()
        self._filters = filters or []
        self.__envID = envId
        self.onChanged = Event()

    def start(self):
        self._soundsCtrl.system.onEnvStart(self.__envID)

    def stop(self):
        self.onChanged.clear()
        self._soundsCtrl.system.onEnvStop(self.__envID)

    def getMusicEvent(self):
        """:return: SoundEvent object instance
        """
        return self._music

    def getAmbientEvent(self):
        """:return: SoundEvent object instance
        """
        return self._ambient

    def getFilters(self):
        """:return: list, filters ids
        """
        return self._filters

    def _onChanged(self):
        self.onChanged(self)

    def _setAmbientParam(self, paramName, value):
        SOUND_DEBUG('Change ambient parameter', paramName, value)
        self._ambient.setParam(paramName, value)

    def _setMusicParam(self, paramName, value):
        SOUND_DEBUG('Change music parameter', paramName, value)
        self._music.setParam(paramName, value)

    def __repr__(self):
        return '%s(music = %s, ambient = %s, filters = %d)' % (self.__class__.__name__,
         self._music,
         self._ambient,
         len(self._filters))
class BCVehicleBuyView(BCVehicleBuyViewMeta):
    def __init__(self):
        super(BCVehicleBuyView, self).__init__()
        self.__academySelected = False
        self.onAcademyClicked = Event()

    def onAcademyClick(self):
        if not self.__academySelected:
            self.__academySelected = True
            self.onAcademyClicked()

    def _dispose(self):
        self.onAcademyClicked.clear()
        super(BCVehicleBuyView, self)._dispose()
Пример #10
0
class SoundEnv(object):
    def __init__(self,
                 soundsCtrl,
                 envId,
                 music=None,
                 ambient=None,
                 filters=None):
        self._soundsCtrl = soundsCtrl
        self._music = music or EmptySound()
        self._ambient = ambient or EmptySound()
        self._filters = filters or []
        self.__envID = envId
        self.onChanged = Event()

    def start(self):
        self._soundsCtrl.system.onEnvStart(self.__envID)

    def stop(self):
        self.onChanged.clear()
        self._soundsCtrl.system.onEnvStop(self.__envID)
        self._ambient.clear()
        self._music.clear()

    def getMusicEvent(self):
        return self._music

    def getAmbientEvent(self):
        return self._ambient

    def getFilters(self):
        return self._filters

    def _onChanged(self):
        self.onChanged(self)

    def _setAmbientParam(self, paramName, value):
        SOUND_DEBUG('Change ambient parameter', paramName, value)
        self._ambient.setParam(paramName, value)

    def _setMusicParam(self, paramName, value):
        SOUND_DEBUG('Change music parameter', paramName, value)
        self._music.setParam(paramName, value)

    def __repr__(self):
        return '%s(music = %s, ambient = %s, filters = %d)' % (
            self.__class__.__name__, self._music, self._ambient,
            len(self._filters))
class SiegeModeControl(InputHandlerCommand):
    def __init__(self):
        self.onSiegeStateChanged = Event()
        self.onRequestFail = Event()
        self.__currentState = VEHICLE_SIEGE_STATE.DISABLED

    def destroy(self):
        self.onSiegeStateChanged.clear()
        self.onRequestFail.clear()

    def handleKeyEvent(self, isDown, key, mods, event=None):
        cmdMap = CommandMapping.g_instance
        keyCaptured = cmdMap.isFired(
            CommandMapping.CMD_CM_VEHICLE_SWITCH_AUTOROTATION, key) and isDown
        if not keyCaptured:
            return False
        else:
            vehicle = BigWorld.player().getVehicleAttached()
            if vehicle is not None and vehicle.typeDescriptor.type.isDualgunVehicleType:
                return False
            if vehicle is not None and vehicle.isPlayerVehicle and vehicle.isAlive(
            ):
                self.__switchSiegeMode()
            return True

    def notifySiegeModeChanged(self, vehicle, newState, timeToNextMode):
        if not vehicle.isPlayerVehicle:
            return
        LOG_DEBUG('SiegeMode: new state received: {}'.format(
            (newState, timeToNextMode)))
        self.onSiegeStateChanged(newState, timeToNextMode)
        self.__currentState = newState
        self.__timeToNextMode = timeToNextMode

    def __switchSiegeMode(self):
        if BigWorld.player().deviceStates.get('engine') == 'destroyed':
            if self.__currentState not in VEHICLE_SIEGE_STATE.SWITCHING:
                self.onRequestFail()
            return
        if self.__currentState in (VEHICLE_SIEGE_STATE.SWITCHING_ON,
                                   VEHICLE_SIEGE_STATE.ENABLED):
            enableSiegeMode = False
        else:
            enableSiegeMode = True
        BigWorld.player().base.vehicle_changeSetting(
            VEHICLE_SETTING.SIEGE_MODE_ENABLED, enableSiegeMode)
Пример #12
0
class Command(PyObjectEntity):
    __slots__ = ('__event',)

    def __init__(self, name):
        super(Command, self).__init__(GUI.PyObjectCommand(name))
        self.__event = Event()

    @property
    def name(self):
        return self.proxy.name

    def execute(self, args=None):
        if args is not None:
            args = (args,)
        else:
            args = ()
        self.proxy.execute(*args)
        return

    def _unbind(self):
        self.__event.clear()
        super(Command, self)._unbind()

    def _cNotify(self, args=None):
        if args is not None:
            args = (args,)
        else:
            args = ()
        self.__event(*args)
        return

    def __iadd__(self, delegate):
        self.__event += delegate
        return self

    def __isub__(self, delegate):
        self.__event -= delegate
        return self
Пример #13
0
class AbstractLock(object):
    def __init__(self):
        super(AbstractLock, self).__init__()
        self.onLocked = Event()
        self.onUnlocked = Event()

    def dispose(self):
        self.onLocked.clear()
        self.onUnlocked.clear()

    def getID(self):
        raise NotImplementedError

    def lock(self):
        raise NotImplementedError

    def unlock(self):
        raise NotImplementedError

    def isLocked(self):
        raise NotImplementedError

    def tryLock(self):
        raise NotImplementedError
Пример #14
0
class ServerSettings(object):

    def __init__(self, serverSettings):
        self.onServerSettingsChange = Event()
        self.__serverSettings = serverSettings if serverSettings else {}
        if 'roaming' in self.__serverSettings:
            roamingSettings = self.__serverSettings['roaming']
            self.__roamingSettings = RoamingSettings(roamingSettings[0], roamingSettings[1], [ _ServerInfo(*s) for s in roamingSettings[2] ])
        else:
            self.__roamingSettings = RoamingSettings.defaults()
        if 'file_server' in self.__serverSettings:
            self.__fileServerSettings = _FileServerSettings(self.__serverSettings['file_server'])
        else:
            self.__fileServerSettings = _FileServerSettings.defaults()
        if 'regional_settings' in self.__serverSettings:
            self.__regionalSettings = makeTupleByDict(_RegionalSettings, self.__serverSettings['regional_settings'])
        else:
            self.__regionalSettings = _RegionalSettings.defaults()
        try:
            self.__eSportCurrentSeason = makeTupleByDict(_ESportCurrentSeason, self.__serverSettings)
        except TypeError:
            self.__eSportCurrentSeason = _ESportCurrentSeason.defaults()

        self.__updateClanProfile(self.__serverSettings)

    def update(self, serverSettingsDiff):
        self.__serverSettings.update(serverSettingsDiff)
        self.__updateClanProfile(serverSettingsDiff)
        self.onServerSettingsChange(serverSettingsDiff)

    def clear(self):
        self.onServerSettingsChange.clear()

    def getSettings(self):
        return self.__serverSettings

    @property
    def roaming(self):
        return self.__roamingSettings

    @property
    def fileServer(self):
        return self.__fileServerSettings

    @property
    def regionals(self):
        return self.__regionalSettings

    @property
    def eSportCurrentSeason(self):
        return self.__eSportCurrentSeason

    @property
    def clanProfile(self):
        return self.__clanProfile

    def isPotapovQuestEnabled(self):
        return self.isFalloutQuestEnabled() or self.isRegularQuestEnabled()

    def isRegularQuestEnabled(self):
        return self.__getGlobalSetting('isRegularQuestEnabled', True)

    def isFalloutQuestEnabled(self):
        return self.__getGlobalSetting('isFalloutQuestEnabled', True)

    def isBuyPotapovQuestTileEnabled(self):
        return self.__getGlobalSetting('isBuyPotapovQuestTileEnabled', False)

    def isBuyPotapovQuestSlotEnabled(self):
        return self.__getGlobalSetting('isBuyPotapovQuestSlotEnabled', False)

    def isFortBattlesEnabled(self):
        return not self.__getGlobalSetting('isFortBattlesDisabled', True)

    def isClubsEnabled(self):
        return self.__getGlobalSetting('isClubsEnabled', False)

    def isGoldFishEnabled(self):
        return self.__getGlobalSetting('isGoldFishEnabled', False)

    def isTutorialEnabled(self):
        return self.__getGlobalSetting('isTutorialEnabled', IS_TUTORIAL_ENABLED)

    def isSandboxEnabled(self):
        return self.__getGlobalSetting('isSandboxEnabled', False)

    def isPromoAutoViewsEnabled(self):
        return True

    def getForbiddenFortDefenseHours(self):
        return self.__getGlobalSetting('forbiddenFortDefenseHours', tuple())

    def getForbiddenSortieHours(self):
        return self.__getGlobalSetting('forbiddenSortieHours', tuple())

    def getForbiddenSortiePeripheryIDs(self):
        return self.__getGlobalSetting('forbiddenSortiePeripheryIDs', tuple())

    def getForbiddenRatedBattles(self):
        return self.__getGlobalSetting('forbiddenRatedBattles', {})

    def isPremiumInPostBattleEnabled(self):
        return self.__getGlobalSetting('isPremiumInPostBattleEnabled', True)

    def __getGlobalSetting(self, settingsName, default = None):
        return self.__serverSettings.get(settingsName, default)

    def __updateClanProfile(self, targetSettings):
        if 'clanProfile' in targetSettings:
            cProfile = targetSettings['clanProfile']
            self.__clanProfile = _ClanProfile(cProfile.get('isEnabled', False), cProfile.get('gateUrl', ''), cProfile.get('type', 'gateway'))
        else:
            self.__clanProfile = _ClanProfile.defaults()
Пример #15
0
class _CurrentVehicle():
    def __init__(self):
        self.__vehInvID = 0
        self.__changeCallbackID = None
        self.onChanged = Event()
        self.onChangeStarted = Event()
        self.__crew = {}

    def init(self):
        g_clientUpdateManager.addCallbacks({'inventory': self.onInventoryUpdate,
         'cache.vehsLock': self.onLocksUpdate})
        prbVehicle = self.__checkPrebattleLockedVehicle()
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        self.selectVehicle(prbVehicle or storedVehInvID)

    def destroy(self):
        self.__vehInvID = 0
        self.__clearChangeCallback()
        self.onChanged.clear()
        self.onChangeStarted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)
        g_hangarSpace.removeVehicle()
        self.selectNoVehicle()

    def onInventoryUpdate(self, invDiff):
        vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {})
        isVehicleSold = False
        isVehicleDescrChanged = False
        if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']:
            isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None
            isVehicleDescrChanged = not isVehicleSold
        if isVehicleSold or self.__vehInvID == 0:
            self.selectVehicle()
        elif 'repair' in vehsDiff:
            isRepaired = self.__vehInvID in vehsDiff['repair']
            if not GUI_ITEM_TYPE.TURRET in invDiff:
                isComponentsChanged = GUI_ITEM_TYPE.GUN in invDiff
                isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive, vehsDiff.itervalues())) > 0
                (isComponentsChanged or isRepaired or isVehicleDescrChanged) and self.refreshModel()
            (isVehicleChanged or isRepaired) and self.onChanged()

        if self.isPresent():
            self.__updateViewRange()

    def onLocksUpdate(self, locksDiff):
        if self.__vehInvID in locksDiff:
            self.refreshModel()

    def refreshModel(self):
        if self.isPresent() and self.isInHangar() and self.item.modelState:
            g_hangarSpace.updateVehicle(self.item)
        else:
            g_hangarSpace.removeVehicle()

    @property
    def invID(self):
        return self.__vehInvID

    @property
    def item(self):
        if self.__vehInvID > 0:
            return g_itemsCache.items.getVehicle(self.__vehInvID)
        else:
            return None

    def isPresent(self):
        return self.item is not None

    def isBroken(self):
        return self.isPresent() and self.item.isBroken

    def isDisabledInRoaming(self):
        return self.isPresent() and self.item.isDisabledInRoaming

    def isLocked(self):
        return self.isPresent() and self.item.isLocked

    def isClanLock(self):
        return self.isPresent() and self.item.clanLock > 0

    def isCrewFull(self):
        return self.isPresent() and self.item.isCrewFull

    def isInBattle(self):
        return self.isPresent() and self.item.isInBattle

    def isInHangar(self):
        return self.isPresent() and not self.item.isInBattle

    def isAwaitingBattle(self):
        return self.isPresent() and self.item.isAwaitingBattle

    def isAlive(self):
        return self.isPresent() and self.item.isAlive

    def isReadyToPrebattle(self):
        return self.isPresent() and self.item.isReadyToPrebattle

    def isReadyToFight(self):
        return self.isPresent() and self.item.isReadyToFight

    def isAutoLoadFull(self):
        if self.isPresent() and self.item.isAutoLoad:
            for shell in self.item.shells:
                if shell.count != shell.defaultCount:
                    return False

        return True

    def isAutoEquipFull(self):
        if self.isPresent() and self.item.isAutoEquip:
            return self.item.eqs == self.item.eqsLayout
        return True

    def selectVehicle(self, vehInvID = 0):
        vehicle = g_itemsCache.items.getVehicle(vehInvID)
        if vehicle is None:
            invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY)
            if len(invVehs):
                vehInvID = sorted(invVehs.itervalues())[0].invID
            else:
                vehInvID = 0
        self.__selectVehicle(vehInvID)
        return

    def selectNoVehicle(self):
        self.__selectVehicle(0)

    def getHangarMessage(self):
        if self.isPresent():
            state, stateLvl = self.item.getState()
            return ('#menu:currentVehicleStatus/' + state, stateLvl)
        return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL)

    def __selectVehicle(self, vehInvID):
        if vehInvID == self.__vehInvID:
            return
        Waiting.show('updateCurrentVehicle', isSingle=True)
        self.onChangeStarted()
        self.__vehInvID = vehInvID
        AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID)
        self.refreshModel()
        if not self.__changeCallbackID:
            self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone)

        if self.isPresent():
            self.__updateViewRange()

    def __updateViewRange(self):
        # Set Defaults
        xvm_conf = {}

        # Load configuration
        xvm_configuration_file = os.getcwd() + os.sep + 'res_mods' + os.sep + 'xvm' + os.sep + 'tankrange.xc'
        if not os.path.exists(xvm_configuration_file):
            LOG_NOTE("Configuration file missing (" + xvm_configuration_file + "). Creating.")
        else:
            data = ""
            blockComment = False

            f = codecs.open(xvm_configuration_file, 'r', '"utf-8-sig"')
            for line in f.read().split('\n'):
                line = line.strip()
                if line != "":
                    # Start of block comment
                    comment = line.find("/*")
                    if comment != -1 and comment == 0:
                        blockComment = True
                        continue

                    # End of block comment
                    comment = line.find("*/")
                    if comment != -1:
                        blockComment = False
                        continue

                    # Block Comment
                    if blockComment == True:
                        continue

                    # Start of line comment
                    comment = line.find("//")
                    if comment != -1 and comment == 0:
                        continue

                    # Remove end of line comments
                    position = 0
                    for i in range(0,line.count("//")):
                        comment = line.find("//", position+2)
                        if comment != -1:
                            colon = line.find(":")

                            startSpeach = line.find("\"", colon+1)
                            if startSpeach > comment:
                                line = line[:comment].strip()

                            endSpeach = line.find("\"", startSpeach+1)
                            if comment > endSpeach:
                                line = line[:comment].strip()

                        position += comment

                    if line != "":
                        data += line + '\n'
            f.close()

            xvm_conf = json.loads(data)

        # add spotting_limit option to old configs (new in 1.6)
        if not xvm_conf["tankrange"].has_key("spotting_limit"):
             LOG_NOTE("add missing spotting_limit option")
             xvm_conf["tankrange"]["spotting_limit"] = True

        # Get name
        tank_name = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.name.split(":")[1].lower().replace("-","_")
        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Tank Name: ", tank_name)

        # without a crew calculation Cancel
        if not self.isCrewFull():
            if xvm_conf['tankrange']['logging']:
                LOG_NOTE('no full crew')
            return

        # Remove current circles
        remaining = []
        for tank_data in xvm_conf["circles"]["special"]:
            if tank_data.keys()[0] != tank_name:
                remaining.append(tank_data)
        xvm_conf["circles"]["special"] = remaining

        # Get type
        if xvm_conf["tankrange"]["ignore_artillery"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags:
            f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"')
            f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2)))
            f.close()

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Ignoring " + vehicle_type + " tank.")
            return

        # Get view distance
        view_distance = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.turret["circularVisionRadius"]
        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Base View Range: ", view_distance)

        # Check for Ventilation
        ventilation = self.__isOptionalEquipped("improvedVentilation")
        if xvm_conf["tankrange"]["logging"] and ventilation:
            LOG_NOTE("Ventilation Found")

        # Check for Consumable
        consumable = self.__isConsumableEquipped("ration")
        if xvm_conf["tankrange"]["logging"] and consumable:
            LOG_NOTE("Premium Consumable Found")

        # Update crew
        self.__updateCrew()

        # Check for Brothers In Arms
        brothers_in_arms = True
        if len(self.__crew) == 0:
            brothers_in_arms = False
        else:
            for name, data in self.__crew.iteritems():
                if "brotherhood" not in data["skill"]:
                    brothers_in_arms = False

        if xvm_conf["tankrange"]["logging"] and brothers_in_arms:
            LOG_NOTE("BIA Found")

        # Calculate commander bonus
        commander_skill = 0
        if "commander" in self.__crew:
            commander_skill = self.__crew["commander"]["level"]

            if brothers_in_arms == True:
                commander_skill += 5
            if ventilation == True:
                commander_skill += 5
            if consumable == True:
                commander_skill += 10

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Commander Skill: ", commander_skill)

        # Calculate other bonuses
        other_bonus = 1.0
        for name, data in self.__crew.iteritems():
            # Calculate recon skills
            if "commander_eagleEye" in data["skill"]:
                other_bonus *= 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] )

                if xvm_conf["tankrange"]["logging"]:
                    LOG_NOTE("Recon Bonus: ", 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] ))

            # Calculate Situational Awareness Skill
            if "radioman_finder" in data["skill"]:
                other_bonus *= 1.0 + ( 0.0002 * data["skill"]["radioman_finder"] )

                if xvm_conf["tankrange"]["logging"]:
                    LOG_NOTE("Situational Awareness Bonus: ", 1.0 + ( 0.0003 * data["skill"]["radioman_finder"] ))

        # Check for Binoculars
        binoculars = self.__isOptionalEquipped("stereoscope")
        if xvm_conf["tankrange"]["logging"] and binoculars:
            LOG_NOTE("Binoculars Found")

        # Check for Coated Optics
        coated_optics = self.__isOptionalEquipped("coatedOptics")
        if xvm_conf["tankrange"]["logging"] and coated_optics:
            LOG_NOTE("Coated Optics Found")

        # Calculate final value
        view_distance = ((view_distance / 0.875) * (0.00375* commander_skill + 0.5)) * other_bonus

        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Other Bonus:", other_bonus)
            LOG_NOTE("Final View Range: ", view_distance)

        # Add binocular Circles
        if xvm_conf["tankrange"]["circle_binocular"]["enabled"] and binoculars:
            binocular_distance = view_distance * 1.25
            if xvm_conf["tankrange"]["spotting_limit"]:
                binocular_distance = min(445, binocular_distance);

            if not xvm_conf["tankrange"]["circle_binocular"]["filled"]:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "distance": binocular_distance } })
            else:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "thickness": (binocular_distance*0.25)-14, "distance": binocular_distance*0.5 } })

        # Add standard Circles
        if coated_optics == True:
            view_distance = min(view_distance * 1.1, 500)

        if xvm_conf["tankrange"]["circle_view"]["enabled"]:
            if xvm_conf["tankrange"]["spotting_limit"]:
                view_distance = min(445, view_distance);

            if not xvm_conf["tankrange"]["circle_view"]["filled"]:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "distance": view_distance } })
            else:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "thickness": (view_distance*0.25)-14, "distance": view_distance*0.5 } })


        # Add Artillery Range
        if xvm_conf["tankrange"]["circle_artillery"]["enabled"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags:
            artillery_range = 0
            for shell in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.gun["shots"]:
                artillery_range = max(artillery_range, round(math.pow(shell["speed"],2) / shell["gravity"]))

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Calculated Firing Range:", artillery_range)

            if not xvm_conf["tankrange"]["circle_artillery"]["filled"]:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "distance": artillery_range } })
            else:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "thickness": (artillery_range*0.25)-14, "distance": artillery_range*0.5 } })

        # Write result
        f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"')
        f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2, sort_keys=True)))
        f.close()

    @process
    def __updateCrew(self):
        from gui.shared.utils.requesters import Requester
        self.__crew.clear()

        barracks = yield Requester('tankman').getFromInventory()
        for tankman in barracks:
            for crewman in self.item.crew:
                if crewman[1] is not None and crewman[1].invID == tankman.inventoryId:
                    crew_member = { "level": tankman.descriptor.roleLevel, "skill": {} }

                    skills = []
                    for skill_name in tankman.descriptor.skills:
                        skills.append({ "name": skill_name, "level": 100 })

                    if len(skills) != 0:
                        skills[-1]["level"] = tankman.descriptor.lastSkillLevel

                    for skill in skills:
                        crew_member["skill"][skill["name"]] = skill["level"]

                    self.__crew[tankman.descriptor.role] = crew_member

    def __isOptionalEquipped(self, optional_name):
        for item in self.item.descriptor.optionalDevices:
            if item is not None and optional_name in item.name:
                return True
        return False

    def __isConsumableEquipped(self, consumable_name):
        from gui.shared.utils.requesters import VehicleItemsRequester

        for item in self.item.eqsLayout:
            if item is not None and consumable_name in item.descriptor.name:
                return True
        return False

    def __changeDone(self):
        self.__clearChangeCallback()
        if isPlayerAccount():
            self.onChanged()
        Waiting.hide('updateCurrentVehicle')

    def __clearChangeCallback(self):
        if self.__changeCallbackID is not None:
            BigWorld.cancelCallback(self.__changeCallbackID)
            self.__changeCallbackID = None

    def __checkPrebattleLockedVehicle(self):
        clientPrb = prb_control.getClientPrebattle()
        if clientPrb is not None:
            rosters = prb_control.getPrebattleRosters(prebattle=clientPrb)
            for rId, roster in rosters.iteritems():
                if BigWorld.player().id in roster:
                    vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '')
                    if len(vehCompDescr):
                        vehDescr = vehicles.VehicleDescr(vehCompDescr)
                        vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr)
                        if vehicle is not None:
                            return vehicle.invID

        return 0

    def __repr__(self):
        return 'CurrentVehicle(%s)' % str(self.item)
Пример #16
0
class SettingsCache(ISettingsCache):
    def __init__(self):
        self.__intSettings = IntSettingsRequester()
        self.__waitForSync = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()

    def init(self):
        g_clientUpdateManager.addCallbacks({'intUserSettings': self._onResync})

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def settings(self):
        return self.__intSettings

    def _onResync(self, *args):
        self.__invalidateData()

    @async
    def update(self, callback=None):
        self.__invalidateData(callback)

    def getSectionSettings(self, section, defaultValue=0):
        return self.__intSettings.getSetting(section, defaultValue)

    def setSectionSettings(self, section, value):
        self.__intSettings.setSetting(section, value)

    def setSettings(self, settings):
        self.__intSettings.setSettings(settings)

    def getSetting(self, key, defaultValue=0):
        return self.__intSettings.getSetting(key, defaultValue)

    def getVersion(self, defaultValue=0):
        return self.__intSettings.getSetting(VERSION, defaultValue)

    def setVersion(self, value):
        self.__intSettings.setSetting(VERSION, value)

    def delSettings(self, settings):
        self.__intSettings.delSettings(settings)

    def __invalidateData(self, callback=lambda *args: None):
        def cbWrapper(*args):
            self.__waitForSync = False
            self.onSyncCompleted()
            callback(*args)

        self.__waitForSync = True
        self.onSyncStarted()
        import BattleReplay
        if BattleReplay.g_replayCtrl.isPlaying:
            cbWrapper(dict())
            return
        self.__intSettings.request()(cbWrapper)
Пример #17
0
class NYScreen(NYHelperView, NYScreenMeta):
    _newYearController = dependency.descriptor(INewYearController)
    tabSlotsMapping = {'tree': ['top',
              'hanging',
              'garland',
              'gift'],
     'snowman': ['snowman'],
     'house': ['house_decoration', 'house_lamp'],
     'light': ['street_garland']}
    __background_alpha__ = 0.0

    def __init__(self, ctx = None):
        super(NYScreen, self).__init__(ctx)
        self.__currentTabId = None
        self._initialize(ctx)
        self.__mouseEvent = Event()
        return

    def onClose(self):
        self.__switchToHangar()

    def onCraftButtonClick(self):
        NYSoundEvents.playSound(NYSoundEvents.ON_CRAFT_CLICK)
        self._switchToCraft(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN)

    def onCollectionButtonClick(self):
        NYSoundEvents.playCloseCustomization(Mappings.ID_TO_ANCHOR[self.__currentTabId])
        self._switchToGroups(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN, tabId=self.__currentTabId)

    def onToyFragmentButtonClick(self):
        NYSoundEvents.playSound(NYSoundEvents.ON_TOY_FRAGMENT_CLICK)
        self._switchToBreak(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN)

    def onTabButtonClick(self, tabID):
        if tabID == self.__currentTabId:
            return
        self.__currentTabId = tabID
        self.as_enableBtnsS(False)
        NYSoundEvents.playSound(NYSoundEvents.ON_TAB_CLICK)
        if tabID in Mappings.ID_TO_ANCHOR:
            newState = Mappings.ID_TO_ANCHOR[tabID]
            if self._customizableObjMgr.state != newState:
                self._customizableObjMgr.switchTo(Mappings.ID_TO_ANCHOR[tabID], partial(self.__showViewById, tabID))
            else:
                self.__showViewById(tabID)

    def onAwardsButtonClick(self):
        NYSoundEvents.playCloseCustomization(Mappings.ID_TO_ANCHOR[self.__currentTabId])
        self._switchToRewards(previewAlias=VIEW_ALIAS.LOBBY_NY_SCREEN)

    def moveSpace(self, x, y, delta):
        self.__mouseEvent(x, y, delta)

    def _invalidate(self, ctx = None):
        super(NYScreen, self)._invalidate(ctx)
        self._initialize(ctx)

    def _initialize(self, ctx = None):
        if ctx and 'tabId' in ctx:
            self.__currentTabId = ctx['tabId']
        else:
            default = NY_CONSTANTS.SIDE_BAR_TREE_ID
            state = self._customizableObjMgr.state
            self.__currentTabId = Mappings.ANCHOR_TO_ID[state] if state in Mappings.ANCHOR_TO_ID else default

    def _populate(self):
        super(NYScreen, self)._populate()
        self._newYearController.boxStorage.onCountChanged += self.__onBoxCountChanged
        self._newYearController.onProgressChanged += self.__onProgressUpdated
        self._newYearController.onToyFragmentsChanged += self.__onToyFragmentsChanged
        self._newYearController.onInventoryUpdated += self.__onInventoryUpdated
        self._newYearController.onToysBreakStarted += self._onToysBreakStarted
        self._newYearController.onToysBreak += self._onToysBreak
        self._newYearController.onToysBreakFailed += self._onToysBreakFailed
        self.__linkCameraWithMouseEvents()
        NYSoundEvents.playOpenCustomization(self.__currentTabId)
        data, awardsCounter, progress = self.__makeVO()
        self.as_initS(data)
        self.as_updateNYAwardsCounterS(awardsCounter)
        self.__updateCounter()
        self.as_updateNYProgressS(progress)
        self.__onInventoryUpdated()

    def __onInventoryUpdated(self):
        newToys = dict.fromkeys(self.tabSlotsMapping.keys(), 0)
        for type, toys in self._newYearController.getInventory().iteritems():
            for toy in toys.values():
                for tab, slots in self.tabSlotsMapping.iteritems():
                    if type in slots:
                        newToys[tab] += toy.newCount
                        break

        for tab, newCount in newToys.iteritems():
            self.as_setTabButtonCounterS(tab, str(newCount))

    def _dispose(self):
        self._newYearController.boxStorage.onCountChanged -= self.__onBoxCountChanged
        self._newYearController.onProgressChanged -= self.__onProgressUpdated
        self._newYearController.onToyFragmentsChanged -= self.__onToyFragmentsChanged
        self._newYearController.onInventoryUpdated -= self.__onInventoryUpdated
        self._newYearController.onToysBreakStarted -= self._onToysBreakStarted
        self._newYearController.onToysBreak -= self._onToysBreak
        self._newYearController.onToysBreakFailed -= self._onToysBreakFailed
        self.__unlinkCameraFromMouseEvents()
        self.__mouseEvent.clear()
        super(NYScreen, self)._dispose()

    def __switchToHangar(self):
        self._customizableObjMgr.switchTo(None, lambda : self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR), scope=EVENT_BUS_SCOPE.LOBBY))
        return

    def _onToysBreakStarted(self):
        self.as_onBreakStartS()

    def _onToysBreak(self, toyIndexes, fromSlot):
        self.as_onBreakS()

    def _onToysBreakFailed(self):
        self.as_onBreakFailS()

    def __onProgressUpdated(self, nyProgress):
        self.as_updateNYLevelS(nyProgress.level)
        self.as_updateNYProgressS(nyProgress.progress / float(nyProgress.bound))

    def __onToyFragmentsChanged(self, fragmentsCount):
        self.as_updateNYTOYFragmentS(BigWorld.wg_getIntegralFormat(fragmentsCount))

    def __onBoxCountChanged(self, *args):
        self.__updateCounter()

    def __updateCounter(self):
        self.as_updateNYBoxCounterS(self._newYearController.boxStorage.count)

    def __makeVO(self):
        nyLevel, _, nyProgress, nyBound = self._newYearController.getProgress()
        normalizedProgress = nyProgress / float(nyBound)
        nyAwardsCounter = str(self.__getRewardsCounter())
        toyFragment = BigWorld.wg_getIntegralFormat(self._newYearController.getToyFragments())
        tabIndex = NewYearObjectIDs.ALL.index(self.__currentTabId)
        self.__currentTabId = None
        res = {'craftBtnLabel': NY.SCREEN_CRAFTBTN_LABEL,
         'sideBarData': UiTabs.ALL,
         'level': nyLevel,
         'toyFragment': toyFragment,
         'sideBarSelectedItemIndex': tabIndex}
        return (res, nyAwardsCounter, normalizedProgress)

    def __showViewById(self, tabID):
        self.as_showViewByIdS(tabID)
        self.as_enableBtnsS(True)

    def __linkCameraWithMouseEvents(self):
        cameraSwitcher = self._customizableObjMgr.getSwitchHandler(CameraSwitcher)
        if cameraSwitcher is not None:
            cameraSwitcher.subscribeToMouseEvents(self.__mouseEvent)
        return

    def __unlinkCameraFromMouseEvents(self):
        cameraSwitcher = self._customizableObjMgr.getSwitchHandler(CameraSwitcher)
        if cameraSwitcher is not None:
            cameraSwitcher.unsubscribeFromMouseEvents(self.__mouseEvent)
        return

    def __getRewardsCounter(self):
        discountSums = (sum(self._newYearController.vehDiscountsStorage.getDiscounts().values()), sum(self._newYearController.tankmanDiscountsStorage.getDiscounts().values()))
        counter = sum(discountSums)
        return counter
class CompanyBattleController(Notifiable):

    def __init__(self, eventsCache):
        self.__eventsCache = weakref.proxy(eventsCache)
        self.onCompanyStateChanged = Event()
        super(CompanyBattleController, self).__init__()
        self.__isLobbyLoaded = False
        self.__delayedCompanyState = []

    def start(self):
        g_eventBus.addListener(GUICommonEvent.LOBBY_VIEW_LOADED, self.__onLobbyInited)
        g_playerEvents.onAvatarBecomePlayer += self.__onAvatarBecomePlayer
        g_connectionManager.onDisconnected += self.__onDisconnected
        self.setNotificators()

    def stop(self):
        self.onCompanyStateChanged.clear()
        self.clearNotification()
        g_eventBus.removeListener(GUICommonEvent.LOBBY_VIEW_LOADED, self.__onLobbyInited)
        g_playerEvents.onAvatarBecomePlayer -= self.__onAvatarBecomePlayer
        g_connectionManager.onDisconnected -= self.__onDisconnected

    def setNotificators(self):
        battle = self.__eventsCache.getCompanyBattles()
        self.clearNotification()
        if battle.isValid():
            destroyingTimeLeft = battle.getDestroyingTimeLeft()
            if destroyingTimeLeft is not None:
                if destroyingTimeLeft <= 0:
                    self.__onCompanyFinished()
                else:
                    self.addNotificators(AcyclicNotifier(battle.getDestroyingTimeLeft, self.__onCompanyFinished))
            if battle.isCreationTimeCorrect():
                self.__onCompanyStarted()
            else:
                self.addNotificators(AcyclicNotifier(battle.getCreationTimeLeft, self.__onCompanyStarted))
            self.startNotification()
        else:
            self.__onCompanyFinished()
        return

    def __onLobbyInited(self, *args):
        self.__isLobbyLoaded = True
        self.__handlePostponed()

    def __onAvatarBecomePlayer(self):
        self.__isLobbyLoaded = False

    def __onDisconnected(self):
        self.__isLobbyLoaded = False

    def __onCompanyStarted(self):
        if self.__isLobbyLoaded:
            self.onCompanyStateChanged(True)
        else:
            self.__delayedCompanyState.append(True)

    def __onCompanyFinished(self):
        if self.__isLobbyLoaded:
            self.onCompanyStateChanged(False)
        else:
            self.__delayedCompanyState.append(False)

    def __handlePostponed(self):
        for companyState in self.__delayedCompanyState:
            self.onCompanyStateChanged(companyState)

        self.__delayedCompanyState = []
Пример #19
0
class _EventsCache(object):
    USER_QUESTS = (EVENT_TYPE.BATTLE_QUEST,
     EVENT_TYPE.TOKEN_QUEST,
     EVENT_TYPE.FORT_QUEST,
     EVENT_TYPE.PERSONAL_QUEST,
     EVENT_TYPE.POTAPOV_QUEST)
    SYSTEM_QUESTS = (EVENT_TYPE.REF_SYSTEM_QUEST,)

    def __init__(self):
        self.__progress = QuestsProgressRequester()
        self.__waitForSync = False
        self.__invalidateCbID = None
        self.__cache = defaultdict(dict)
        self.__actionsCache = defaultdict(lambda : defaultdict(dict))
        self.__questsDossierBonuses = defaultdict(set)
        self.__potapov = PQController(self)
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()
        return

    def init(self):
        self.__potapov.init()

    def fini(self):
        self.__potapov.fini()
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        self.__clearInvalidateCallback()

    def clear(self):
        quests_caches.clearNavInfo()

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def questsProgress(self):
        return self.__progress

    @property
    def potapov(self):
        return self.__potapov

    @async
    @process
    def update(self, diff = None, callback = None):
        yield self.__progress.request()
        isNeedToInvalidate = True
        isNeedToClearItemsCaches = False

        def _cbWrapper(*args):
            self.__potapov.update(diff)
            callback(*args)

        if diff is not None:
            isQPUpdated = 'quests' in diff
            isEventsDataUpdated = ('eventsData', '_r') in diff or 'eventsData' in diff
            isNeedToInvalidate = isQPUpdated or isEventsDataUpdated
            hasVehicleUnlocks = False
            for intCD in diff.get('stats', {}).get('unlocks', set()):
                if getTypeOfCompactDescr(intCD) == GUI_ITEM_TYPE.VEHICLE:
                    hasVehicleUnlocks = True
                    break

            isNeedToClearItemsCaches = 'inventory' in diff and GUI_ITEM_TYPE.VEHICLE in diff['inventory'] or hasVehicleUnlocks
        if isNeedToInvalidate:
            self.__invalidateData(_cbWrapper)
            return
        else:
            if isNeedToClearItemsCaches:
                self.__clearQuestsItemsCache()
            _cbWrapper(True)
            return

    def getQuests(self, filterFunc = None):
        filterFunc = filterFunc or (lambda a: True)

        def userFilterFunc(q):
            return not q.isHidden() and filterFunc(q)

        return self._getQuests(userFilterFunc)

    def getHiddenQuests(self, filterFunc = None):
        filterFunc = filterFunc or (lambda a: True)

        def hiddenFilterFunc(q):
            return q.isHidden() and filterFunc(q)

        return self._getQuests(hiddenFilterFunc)

    def getAllQuests(self, filterFunc = None, includePotapovQuests = False):
        return self._getQuests(filterFunc, includePotapovQuests)

    def getActions(self, filterFunc = None):
        actions = self.__getActionsData()
        filterFunc = filterFunc or (lambda a: True)
        result = {}
        for aData in actions:
            if 'id' in aData:
                a = self._makeAction(aData['id'], aData)
                if not filterFunc(a):
                    continue
                result[a.getID()] = a

        return result

    def getEventBattles(self):
        battles = self.__getEventBattles()
        if len(battles):
            return EventBattles(battles.get('vehicleTags', set()), battles.get('vehicles', []), bool(battles.get('enabled', 0)), battles.get('arenaTypeID'))
        else:
            return None

    def getEvents(self, filterFunc = None):
        svrEvents = self.getQuests(filterFunc)
        svrEvents.update(self.getActions(filterFunc))
        return svrEvents

    def getCurrentEvents(self):
        return self.getEvents(lambda q: q.getStartTimeLeft() <= 0 < q.getFinishTimeLeft())

    def getFutureEvents(self):
        return self.getEvents(lambda q: q.getStartTimeLeft() > 0)

    def getHistoricalBattles(self, hideExpired = True, filterFunc = None):
        battles = self.__getHistoricalBattlesData()
        filterFunc = filterFunc or (lambda a: True)
        result = {}
        for bID, bData in battles.iteritems():
            b = self._makeHistoricalBattle(bID, bData)
            if hideExpired and b.isOutOfDate():
                continue
            if not filterFunc(b):
                continue
            result[bID] = b

        return result

    def getItemAction(self, item, isBuying = True, forCredits = False):
        result = []
        type = ACTION_MODIFIER_TYPE.DISCOUNT if isBuying else ACTION_MODIFIER_TYPE.SELLING
        itemTypeID = item.itemTypeID
        nationID = item.nationID
        intCD = item.intCD
        values = self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(nationID, [])
        values += self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(15, [])
        for (key, value), actionID in values:
            if item.isPremium and key in ('creditsPrice', 'creditsPriceMultiplier') and not forCredits:
                continue
            result.append((value, actionID))

        result.extend(self.__actionsCache[ACTION_SECTION_TYPE.ITEM][type].get(itemTypeID, {}).get(intCD, tuple()))
        return result

    def getRentAction(self, item, rentPackage):
        result = []
        type = ACTION_MODIFIER_TYPE.RENT
        itemTypeID = item.itemTypeID
        nationID = item.nationID
        intCD = item.intCD
        values = self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(nationID, [])
        values += self.__actionsCache[ACTION_SECTION_TYPE.ALL][type].get(itemTypeID, {}).get(15, [])
        for (key, value), actionID in values:
            result.append((value, actionID))

        result.extend(self.__actionsCache[ACTION_SECTION_TYPE.ITEM][type].get(itemTypeID, {}).get((intCD, rentPackage), tuple()))
        return result

    def getEconomicsAction(self, name):
        result = self.__actionsCache[ACTION_SECTION_TYPE.ECONOMICS][ACTION_MODIFIER_TYPE.DISCOUNT].get(name, [])
        resultMult = self.__actionsCache[ACTION_SECTION_TYPE.ECONOMICS][ACTION_MODIFIER_TYPE.DISCOUNT].get('%sMultiplier' % name, [])
        return tuple(result + resultMult)

    def getCamouflageAction(self, vehicleIntCD):
        return self.__actionsCache[ACTION_SECTION_TYPE.CUSTOMIZATION][ACTION_MODIFIER_TYPE.DISCOUNT].get(vehicleIntCD, tuple())

    def getEmblemsAction(self, group):
        return self.__actionsCache[ACTION_SECTION_TYPE.CUSTOMIZATION][ACTION_MODIFIER_TYPE.DISCOUNT].get(group, tuple())

    def getQuestsDossierBonuses(self):
        return self.__questsDossierBonuses

    def getQuestsByTokenRequirement(self, token):
        result = []
        for q in self._getQuests(includePotapovQuests=True).itervalues():
            if token in map(lambda t: t.getID(), q.accountReqs.getTokens()):
                result.append(q)

        return result

    def getQuestsByTokenBonus(self, token):
        result = []
        for q in self._getQuests(includePotapovQuests=True).itervalues():
            for t in q.getBonuses('tokens'):
                if token in t.getTokens().keys():
                    result.append(q)
                    break

        return result

    def _getQuests(self, filterFunc = None, includePotapovQuests = False):
        quests = self.__getQuestsData()
        quests.update(self.__getFortQuestsData())
        quests.update(self.__getPersonalQuestsData())
        filterFunc = filterFunc or (lambda a: True)
        result = {}
        for qID, qData in quests.iteritems():
            q = self._makeQuest(qID, qData)
            if q.getDestroyingTimeLeft() <= 0:
                continue
            if not filterFunc(q):
                continue
            result[qID] = q

        if includePotapovQuests:
            for qID, q in self.potapov.getQuests().iteritems():
                if filterFunc(q):
                    result[qID] = q

        children, parents = self._makeQuestsRelations(result)
        for qID, q in result.iteritems():
            if qID in children:
                q.setChildren(children[qID])
            if qID in parents:
                q.setParents(parents[qID])

        return result

    def _onResync(self, *args):
        self.__invalidateData()

    def _makeQuest(self, qID, qData):
        storage = self.__cache['quests']
        if qID in storage:
            return storage[qID]
        q = storage[qID] = createQuest(qData.get('type', 0), qID, qData, self.__progress.getQuestProgress(qID), self.__progress.getTokenExpiryTime(qData.get('requiredToken')))
        return q

    def _makeAction(self, aID, aData):
        storage = self.__cache['actions']
        if aID in storage:
            return storage[aID]
        a = storage[aID] = Action(aID, aData)
        return a

    def _makeHistoricalBattle(self, bID, bData):
        storage = self.__cache['historicalBattles']
        if bID in storage:
            return storage[bID]
        b = storage[bID] = HistoricalBattle(bID, bData)
        return b

    @classmethod
    def _makeQuestsRelations(cls, quests):
        makeTokens = defaultdict(list)
        needTokens = defaultdict(list)
        for qID, q in quests.iteritems():
            tokens = q.getBonuses('tokens')
            if len(tokens):
                for t in tokens[0].getTokens():
                    makeTokens[t].append(qID)

            for t in q.accountReqs.getTokens():
                needTokens[qID].append(t.getID())

        children = defaultdict(dict)
        for parentID, tokensIDs in needTokens.iteritems():
            for tokenID in tokensIDs:
                children[parentID][tokenID] = makeTokens.get(tokenID, [])

        parents = defaultdict(dict)
        for parentID, tokens in children.iteritems():
            for tokenID, chn in tokens.iteritems():
                for childID in chn:
                    parents[childID][tokenID] = [parentID]

        return (children, parents)

    def __invalidateData(self, callback = lambda *args: None):
        self.__clearCache()
        self.__clearInvalidateCallback()
        self.__waitForSync = True
        self.onSyncStarted()

        def mergeValues(a, b):
            result = list(a)
            result.extend(b)
            return result

        for action in self.getActions().itervalues():
            for modifier in action.getModifiers():
                section = modifier.getSection()
                type = modifier.getType()
                itemType = modifier.getItemType()
                values = modifier.getValues(action)
                currentSection = self.__actionsCache[section][type]
                if itemType is not None:
                    currentSection = currentSection.setdefault(itemType, {})
                for k in values:
                    if k in currentSection:
                        currentSection[k] = mergeValues(currentSection[k], values[k])
                    else:
                        currentSection[k] = values[k]

        rareAchieves = set()
        invalidateTimeLeft = sys.maxint
        for q in self.getCurrentEvents().itervalues():
            dossierBonuses = q.getBonuses('dossier')
            if len(dossierBonuses):
                storage = self.__questsDossierBonuses[q.getID()]
                for bonus in dossierBonuses:
                    records = bonus.getRecords()
                    storage.update(records)
                    rareAchieves |= set((r for r in records if r[0] == ACHIEVEMENT_BLOCK.RARE))

            timeLeftInfo = q.getNearestActivityTimeLeft()
            if timeLeftInfo is not None:
                isAvailable, errorMsg = q.isAvailable()
                if not isAvailable:
                    if errorMsg in ('invalid_weekday', 'invalid_time_interval'):
                        invalidateTimeLeft = min(invalidateTimeLeft, timeLeftInfo[0])
                else:
                    intervalBeginTimeLeft, (intervalStart, intervalEnd) = timeLeftInfo
                    invalidateTimeLeft = min(invalidateTimeLeft, intervalBeginTimeLeft + intervalEnd - intervalStart)
            else:
                invalidateTimeLeft = min(invalidateTimeLeft, q.getFinishTimeLeft())

        g_rareAchievesCache.request(rareAchieves)
        for q in self.getFutureEvents().itervalues():
            timeLeftInfo = q.getNearestActivityTimeLeft()
            if timeLeftInfo is None:
                startTime = q.getStartTimeLeft()
            else:
                startTime = timeLeftInfo[0]
            invalidateTimeLeft = min(invalidateTimeLeft, startTime)

        for hb in self.getHistoricalBattles().itervalues():
            timeLeftInfo = hb.getNearestActivityTimeLeft()
            if timeLeftInfo is None:
                startTime = hb.getFinishTimeLeft()
            else:
                startTime = timeLeftInfo[0]
            invalidateTimeLeft = min(invalidateTimeLeft, startTime)

        if invalidateTimeLeft != sys.maxint:
            self.__loadInvalidateCallback(invalidateTimeLeft)
        self.__waitForSync = False
        self.onSyncCompleted()
        callback(True)
        from gui.shared import g_eventBus
        g_eventBus.handleEvent(events.LobbySimpleEvent(events.LobbySimpleEvent.EVENTS_UPDATED))
        return

    def __clearQuestsItemsCache(self):
        for qID, q in self._getQuests().iteritems():
            q.accountReqs.clearItemsCache()
            q.vehicleReqs.clearItemsCache()

    @classmethod
    def __getEventsData(cls, eventsTypeName):
        try:
            if isPlayerAccount():
                if eventsTypeName in BigWorld.player().eventsData:
                    return pickle.loads(zlib.decompress(BigWorld.player().eventsData[eventsTypeName]))
                return {}
            LOG_ERROR('Trying to get quests data from not account player', eventsTypeName, BigWorld.player())
        except Exception:
            LOG_CURRENT_EXCEPTION()

        return {}

    def __getQuestsData(self):
        return self.__getEventsData(EVENT_CLIENT_DATA.QUEST)

    def __getFortQuestsData(self):
        return self.__getEventsData(EVENT_CLIENT_DATA.FORT_QUEST)

    def __getPersonalQuestsData(self):
        return self.__getEventsData(EVENT_CLIENT_DATA.PERSONAL_QUEST)

    def __getActionsData(self):
        return self.__getEventsData(EVENT_CLIENT_DATA.ACTION)

    def __getEventBattles(self):
        return self.__getEventsData(EVENT_CLIENT_DATA.INGAME_EVENTS).get('eventBattles', {})

    def __getHistoricalBattlesData(self):
        return self.__getEventsData(EVENT_CLIENT_DATA.HISTORICAL_BATTLES)

    def __loadInvalidateCallback(self, duration):
        LOG_DEBUG('load quest window invalidation callback (secs)', duration)
        self.__clearInvalidateCallback()
        self.__invalidateCbID = BigWorld.callback(math.ceil(duration), self.__invalidateData)

    def __clearInvalidateCallback(self):
        if self.__invalidateCbID is not None:
            BigWorld.cancelCallback(self.__invalidateCbID)
            self.__invalidateCbID = None
        return

    def __clearCache(self):
        self.__questsDossierBonuses.clear()
        self.__actionsCache.clear()
        for storage in self.__cache.itervalues():
            storage.clear()
Пример #20
0
class _CurrentVehicle():

    def __init__(self):
        self.__vehInvID = 0
        self.__changeCallbackID = None
        self.onChanged = Event()
        self.onChangeStarted = Event()
        return

    def init(self):
        g_clientUpdateManager.addCallbacks({'inventory': self.onInventoryUpdate,
         'cache.vehsLock': self.onLocksUpdate})
        prbVehicle = self.__checkPrebattleLockedVehicle()
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        self.selectVehicle(prbVehicle or storedVehInvID)

    def destroy(self):
        self.__vehInvID = 0
        self.__clearChangeCallback()
        self.onChanged.clear()
        self.onChangeStarted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)
        g_hangarSpace.removeVehicle()
        self.selectNoVehicle()

    def onInventoryUpdate(self, invDiff):
        vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {})
        isVehicleSold = False
        isVehicleDescrChanged = False
        if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']:
            isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None
            isVehicleDescrChanged = not isVehicleSold
        if isVehicleSold or self.__vehInvID == 0:
            self.selectVehicle()
        elif 'repair' in vehsDiff:
            isRepaired = self.__vehInvID in vehsDiff['repair']
            if not GUI_ITEM_TYPE.TURRET in invDiff:
                isComponentsChanged = GUI_ITEM_TYPE.GUN in invDiff
                isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive, vehsDiff.itervalues())) > 0
                (isComponentsChanged or isRepaired or isVehicleDescrChanged) and self.refreshModel()
            (isVehicleChanged or isRepaired) and self.onChanged()
        return

    def onLocksUpdate(self, locksDiff):
        if self.__vehInvID in locksDiff:
            self.refreshModel()

    def refreshModel(self):
        if self.isPresent() and self.isInHangar() and self.item.modelState:
            g_hangarSpace.updateVehicle(self.item)
        else:
            g_hangarSpace.removeVehicle()

    @property
    def invID(self):
        return self.__vehInvID

    @property
    def item(self):
        if self.__vehInvID > 0:
            return g_itemsCache.items.getVehicle(self.__vehInvID)
        else:
            return None

    def isPresent(self):
        return self.item is not None

    def isBroken(self):
        return self.isPresent() and self.item.isBroken

    def isDisabledInRoaming(self):
        return self.isPresent() and self.item.isDisabledInRoaming

    def isLocked(self):
        return self.isPresent() and self.item.isLocked

    def isClanLock(self):
        return self.isPresent() and self.item.clanLock > 0

    def isCrewFull(self):
        return self.isPresent() and self.item.isCrewFull

    def isInBattle(self):
        return self.isPresent() and self.item.isInBattle

    def isInHangar(self):
        return self.isPresent() and not self.item.isInBattle

    def isAwaitingBattle(self):
        return self.isPresent() and self.item.isAwaitingBattle

    def isAlive(self):
        return self.isPresent() and self.item.isAlive

    def isReadyToPrebattle(self):
        return self.isPresent() and self.item.isReadyToPrebattle

    def isReadyToFight(self):
        return self.isPresent() and self.item.isReadyToFight

    def isAutoLoadFull(self):
        if self.isPresent() and self.item.isAutoLoad:
            for shell in self.item.shells:
                if shell.count != shell.defaultCount:
                    return False

        return True

    def isAutoEquipFull(self):
        if self.isPresent() and self.item.isAutoEquip:
            return self.item.eqs == self.item.eqsLayout
        return True

    def selectVehicle(self, vehInvID = 0):
        vehicle = g_itemsCache.items.getVehicle(vehInvID)
        if vehicle is None:
            invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY)
            if len(invVehs):
                vehInvID = sorted(invVehs.itervalues())[0].invID
            else:
                vehInvID = 0
        self.__selectVehicle(vehInvID)
        return

    def selectNoVehicle(self):
        self.__selectVehicle(0)

    def getHangarMessage(self):
        if self.isPresent():
            state, stateLvl = self.item.getState()
            return ('#menu:currentVehicleStatus/' + state, stateLvl)
        return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL)

    def __selectVehicle(self, vehInvID):
        if vehInvID == self.__vehInvID:
            return
        Waiting.show('updateCurrentVehicle', isSingle=True)
        self.onChangeStarted()
        self.__vehInvID = vehInvID
        AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID)
        self.refreshModel()
        if not self.__changeCallbackID:
            self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone)

    def __changeDone(self):
        self.__clearChangeCallback()
        if isPlayerAccount():
            self.onChanged()
        Waiting.hide('updateCurrentVehicle')

    def __clearChangeCallback(self):
        if self.__changeCallbackID is not None:
            BigWorld.cancelCallback(self.__changeCallbackID)
            self.__changeCallbackID = None
        return

    def __checkPrebattleLockedVehicle(self):
        clientPrb = prb_control.getClientPrebattle()
        if clientPrb is not None:
            rosters = prb_control.getPrebattleRosters(prebattle=clientPrb)
            for rId, roster in rosters.iteritems():
                if BigWorld.player().id in roster:
                    vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '')
                    if len(vehCompDescr):
                        vehDescr = vehicles.VehicleDescr(vehCompDescr)
                        vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr)
                        if vehicle is not None:
                            return vehicle.invID

        return 0

    def __repr__(self):
        return 'CurrentVehicle(%s)' % str(self.item)
Пример #21
0
class BaseAmmunitionPanelView(ViewImpl):
    _itemsCache = dependency.descriptor(IItemsCache)
    __slots__ = ('_ammunitionPanel', 'onSizeChanged', 'onPanelSectionSelected',
                 'onPanelSectionResized')

    def __init__(self, flags=ViewFlags.VIEW):
        settings = ViewSettings(R.views.lobby.tanksetup.AmmunitionPanel())
        settings.flags = flags
        settings.model = AmmunitionPanelViewModel()
        super(BaseAmmunitionPanelView, self).__init__(settings)
        self.onSizeChanged = Event()
        self.onPanelSectionSelected = Event()
        self.onPanelSectionResized = Event()

    def createToolTip(self, event):
        if event.contentID == R.views.common.tooltip_window.backport_tooltip_content.BackportTooltipContent(
        ):
            tooltipData = getSlotTooltipData(
                event, g_currentVehicle.item,
                self.viewModel.ammunitionPanel.getSelectedSlot())
            if tooltipData is not None:
                window = BackportTooltipWindow(tooltipData,
                                               self.getParentWindow())
                window.load()
                return window
        return super(BaseAmmunitionPanelView, self).createToolTip(event)

    def createToolTipContent(self, event, contentID):
        return ShellsInfo(
            event.contentID, g_currentVehicle.item
        ) if event.contentID == R.views.lobby.tanksetup.tooltips.ShellsInfo(
        ) else super(BaseAmmunitionPanelView, self).createToolTipContent(
            event, contentID)

    def createContextMenuContent(self, event):
        if event.contentID != R.views.common.BackportContextMenu():
            super(BaseAmmunitionPanelView,
                  self).createContextMenuContent(event)
        contextMenuData = getHangarContextMenuData(event, self.uniqueID)
        return BackportContextMenuContent(
            contextMenuData) if contextMenuData is not None else super(
                BaseAmmunitionPanelView, self).createContextMenuContent(event)

    def setHangarSwitchAnimState(self, isComplete):
        self.viewModel.setIsReady(isComplete)

    @property
    def viewModel(self):
        return super(BaseAmmunitionPanelView, self).getViewModel()

    def setLastSlotAction(self, *args, **kwargs):
        setLastSlotAction(self.viewModel, g_currentVehicle.item, *args,
                          **kwargs)

    def update(self, fullUpdate=True):
        if fullUpdate:
            clearLastSlotAction(self.viewModel)
        self.viewModel.setIsMaintenanceEnabled(not g_currentVehicle.isLocked())
        self.viewModel.setIsDisabled(self._getIsDisabled())
        self._ammunitionPanel.update(g_currentVehicle.item,
                                     fullUpdate=fullUpdate)

    def destroy(self):
        self.onSizeChanged.clear()
        self.onPanelSectionSelected.clear()
        self.onPanelSectionResized.clear()
        super(BaseAmmunitionPanelView, self).destroy()

    def _onLoading(self, *args, **kwargs):
        super(BaseAmmunitionPanelView, self)._onLoading(*args, **kwargs)
        self._ammunitionPanel = self._createAmmunitionPanel()
        self._ammunitionPanel.onLoading()

    def _onLoaded(self, *args, **kwargs):
        super(BaseAmmunitionPanelView, self)._onLoaded(*args, **kwargs)
        self.viewModel.setIsReady(True)

    def _initialize(self, *args, **kwargs):
        super(BaseAmmunitionPanelView, self)._initialize()
        self._addListeners()
        self._ammunitionPanel.initialize()
        self.update(fullUpdate=False)

    def _finalize(self):
        self._removeListeners()
        self._ammunitionPanel.finalize()
        super(BaseAmmunitionPanelView, self)._finalize()

    def _createAmmunitionPanel(self):
        return HangarAmmunitionPanel(self.viewModel.ammunitionPanel,
                                     g_currentVehicle.item)

    def _addListeners(self):
        self.viewModel.onViewSizeInitialized += self.__onViewSizeInitialized
        self.viewModel.ammunitionPanel.onSectionSelect += self._onPanelSectionSelected
        self.viewModel.ammunitionPanel.onSectionResized += self._onPanelSectionResized
        g_currentVehicle.onChangeStarted += self.__onVehicleChangeStarted
        g_currentVehicle.onChanged += self._currentVehicleChanged
        self._itemsCache.onSyncCompleted += self.__itemCacheChanged

    def _removeListeners(self):
        self.viewModel.onViewSizeInitialized -= self.__onViewSizeInitialized
        self.viewModel.ammunitionPanel.onSectionSelect -= self._onPanelSectionSelected
        self.viewModel.ammunitionPanel.onSectionResized -= self._onPanelSectionResized
        g_currentVehicle.onChangeStarted -= self.__onVehicleChangeStarted
        g_currentVehicle.onChanged -= self._currentVehicleChanged
        self._itemsCache.onSyncCompleted -= self.__itemCacheChanged

    def _onPanelSectionSelected(self, args):
        if not self._getIsDisabled():
            clearLastSlotAction(self.viewModel)
            self.onPanelSectionSelected(**args)

    def _onPanelSectionResized(self, kwargs):
        self.onPanelSectionResized(**kwargs)

    def _currentVehicleChanged(self):
        self.update()

    def __onVehicleChangeStarted(self):
        self.viewModel.setIsMaintenanceEnabled(False)
        self.viewModel.setIsDisabled(True)

    def __itemCacheChanged(self, *_):
        self.update(fullUpdate=False)

    @staticmethod
    def _getIsDisabled():
        return not g_currentVehicle.isInHangar() or g_currentVehicle.isLocked(
        ) or g_currentVehicle.isBroken()

    def __onViewSizeInitialized(self, args=None):
        self.onSizeChanged(args.get('width', 0), args.get('height', 0),
                           args.get('offsetY', 0))
Пример #22
0
class ServerSettings(object):
    def __init__(self, serverSettings):
        self.onServerSettingsChange = Event()
        self.__serverSettings = copy.deepcopy(
            serverSettings) if serverSettings else {}
        if 'roaming' in self.__serverSettings:
            roamingSettings = self.__serverSettings['roaming']
            self.__roamingSettings = RoamingSettings(
                roamingSettings[0], roamingSettings[1],
                [_ServerInfo(*s) for s in roamingSettings[2]])
        else:
            self.__roamingSettings = RoamingSettings.defaults()
        if 'file_server' in self.__serverSettings:
            self.__fileServerSettings = _FileServerSettings(
                self.__serverSettings['file_server'])
        else:
            self.__fileServerSettings = _FileServerSettings.defaults()
        if 'regional_settings' in self.__serverSettings:
            self.__regionalSettings = makeTupleByDict(
                _RegionalSettings, self.__serverSettings['regional_settings'])
        else:
            self.__regionalSettings = _RegionalSettings.defaults()
        try:
            self.__eSportCurrentSeason = makeTupleByDict(
                _ESportCurrentSeason, self.__serverSettings)
        except TypeError:
            self.__eSportCurrentSeason = _ESportCurrentSeason.defaults()

        if 'clanProfile' in self.__serverSettings:
            self.__updateClanProfile(self.__serverSettings)
        else:
            self.__clanProfile = _ClanProfile.defaults()
        if 'spgRedesignFeatures' in self.__serverSettings:
            self.__spgRedesignFeatures = makeTupleByDict(
                _SpgRedesignFeatures,
                self.__serverSettings['spgRedesignFeatures'])
        else:
            self.__spgRedesignFeatures = _SpgRedesignFeatures.defaults()
        if 'strongholdSettings' in self.__serverSettings:
            settings = self.__serverSettings['strongholdSettings']
            self.__strongholdSettings = _StrongholdSettings(
                settings.get('wgshHostUrl', ''))
        else:
            self.__strongholdSettings = _StrongholdSettings.defaults()
        if 'rankedBattles' in self.__serverSettings:
            self.__bwRankedBattles = makeTupleByDict(
                _BwRankedBattles, self.__serverSettings['rankedBattles'])
        else:
            self.__bwRankedBattles = _BwRankedBattles()
        if 'hallOfFame' in self.__serverSettings:
            self.__bwHallOfFame = makeTupleByDict(
                _BwHallOfFame, self.__serverSettings['hallOfFame'])
        else:
            self.__bwHallOfFame = _BwHallOfFame()
        if 'ranked_config' in self.__serverSettings:
            self.__rankedBattlesSettings = makeTupleByDict(
                _RankedBattlesConfig, self.__serverSettings['ranked_config'])
        else:
            self.__rankedBattlesSettings = _RankedBattlesConfig()

    def update(self, serverSettingsDiff):
        self.__serverSettings = updateDict(self.__serverSettings,
                                           serverSettingsDiff)
        if 'clanProfile' in serverSettingsDiff:
            self.__updateClanProfile(serverSettingsDiff)
        if 'spgRedesignFeatures' in self.__serverSettings:
            self.__spgRedesignFeatures = makeTupleByDict(
                _SpgRedesignFeatures,
                self.__serverSettings['spgRedesignFeatures'])
        if 'ranked_config' in serverSettingsDiff:
            self.__updateRanked(serverSettingsDiff)
        self.onServerSettingsChange(serverSettingsDiff)

    def clear(self):
        self.onServerSettingsChange.clear()

    def getSettings(self):
        return self.__serverSettings

    @property
    def roaming(self):
        return self.__roamingSettings

    @property
    def fileServer(self):
        return self.__fileServerSettings

    @property
    def regionals(self):
        return self.__regionalSettings

    @property
    def eSportCurrentSeason(self):
        return self.__eSportCurrentSeason

    @property
    def clanProfile(self):
        return self.__clanProfile

    @property
    def spgRedesignFeatures(self):
        return self.__spgRedesignFeatures

    @property
    def stronghold(self):
        return self.__strongholdSettings

    @property
    def bwRankedBattles(self):
        return self.__bwRankedBattles

    @property
    def bwHallOfFame(self):
        return self.__bwHallOfFame

    @property
    def rankedBattles(self):
        return self.__rankedBattlesSettings

    def isPotapovQuestEnabled(self):
        return self.isFalloutQuestEnabled() or self.isRegularQuestEnabled()

    def isRegularQuestEnabled(self):
        return self.__getGlobalSetting('isRegularQuestEnabled', True)

    def isFalloutQuestEnabled(self):
        return self.__getGlobalSetting('isFalloutQuestEnabled', True)

    def isBuyPotapovQuestTileEnabled(self):
        return self.__getGlobalSetting('isBuyPotapovQuestTileEnabled', False)

    def isBuyPotapovQuestSlotEnabled(self):
        return self.__getGlobalSetting('isBuyPotapovQuestSlotEnabled', False)

    def isStrongholdsEnabled(self):
        return self.__getGlobalSetting('strongholdSettings',
                                       {}).get('isStrongholdsEnabled', False)

    def isGoldFishEnabled(self):
        return self.__getGlobalSetting('isGoldFishEnabled', False)

    def isTutorialEnabled(self):
        return self.__getGlobalSetting(
            'isTutorialEnabled',
            IS_TUTORIAL_ENABLED) and not self.isBootcampEnabled()

    def isSandboxEnabled(self):
        return self.__getGlobalSetting('isSandboxEnabled', False)

    def isBootcampEnabled(self):
        return self.__getGlobalSetting('isBootcampEnabled', False)

    def isEpicRandomEnabled(self):
        return self.__getGlobalSetting('isEpicRandomEnabled', False)

    def isEpicRandomAchievementsEnabled(self):
        return self.__getGlobalSetting('isEpicRandomAchievementsEnabled',
                                       False)

    def isEpicRandomMarkOfMasteryEnabled(self):
        return self.__getGlobalSetting('isEpicRandomMarkOfMasteryEnabled',
                                       False)

    def isPromoAutoViewsEnabled(self):
        if self.isBootcampEnabled():
            from bootcamp.Bootcamp import g_bootcamp
            if g_bootcamp.isRunning():
                return False
        return True

    def isHofEnabled(self):
        return self.__getGlobalSetting('hallOfFame',
                                       {}).get('isHofEnabled', False)

    def getMaxSPGinSquads(self):
        return self.__getGlobalSetting('maxSPGinSquads', 0)

    def getRandomMapsForDemonstrator(self):
        return self.__getGlobalSetting('randomMapsForDemonstrator', {})

    def isPremiumInPostBattleEnabled(self):
        return self.__getGlobalSetting('isPremiumInPostBattleEnabled', True)

    def isVehicleComparingEnabled(self):
        return bool(self.__getGlobalSetting('isVehiclesCompareEnabled', True))

    def isEncyclopediaEnabled(self, tokensCount):
        switchState = self.__getGlobalSetting('isEncyclopediaEnabled')
        if switchState == SWITCH_STATE.ALL:
            state = True
        elif switchState == SWITCH_STATE.NONE:
            state = False
        elif switchState == SWITCH_STATE.TOKEN:
            state = tokensCount > 0
        else:
            LOG_ERROR(
                'Wrong activation state for encyclopedia. Encyclopedia is considered to be disabled'
            )
            state = False
        return state

    def isTemplateMatchmakerEnabled(self):
        return bool(
            self.__getGlobalSetting('isTemplateMatchmakerEnabled', True))

    def isTankmanRestoreEnabled(self):
        return self.__getGlobalSetting('isTankmanRestoreEnabled', True)

    def isVehicleRestoreEnabled(self):
        return self.__getGlobalSetting('isVehicleRestoreEnabled', True)

    def __getGlobalSetting(self, settingsName, default=None):
        return self.__serverSettings.get(settingsName, default)

    def __updateClanProfile(self, targetSettings):
        cProfile = targetSettings['clanProfile']
        self.__clanProfile = _ClanProfile(cProfile.get('isEnabled', False),
                                          cProfile.get('gateUrl', ''),
                                          cProfile.get('type', 'gateway'))

    def __updateRanked(self, targetSettings):
        self.__rankedBattlesSettings = self.__rankedBattlesSettings.replace(
            targetSettings['ranked_config'])
class ClientDamageProcessor(object):
    ATTACK_TIMEOUT = 3.5

    def __init__(self, config, gameEnvironment):
        self.PREDICATES = {'teammate': self._teammatePredicate,
         'type': self._typePredicate,
         'ACType': self._acTypePredicate}
        params = config[PARAMS_FIELD]
        self._reward = params[REWARD_FIELD]
        self._eventId = params[ID_FIELD]
        self._progressStep = params[PROGRESS_STEP_FIELD]
        self.eDamage = Event()
        self._gameEnvironment = gameEnvironment
        self._linkEvents(gameEnvironment)
        self._avatarsDamageRemainders = dict()
        self._currentTarget = 0
        self._targetWithAccumulatedDamage = 0
        self._targetAccumulator = 0
        self._createPredicates(params)

    def _createPredicates(self, config):
        self._predicates = []
        predicates = config[PREDICATES_FIELD]
        if predicates is not None:
            for pId in predicates:
                self._predicates.append((self.PREDICATES[pId], predicates[pId]))

        return

    def _processDamage(self, avatarId, health, lastDamagerId, oldHealth, maxHealth):
        damage = oldHealth - health
        if not (lastDamagerId == BigWorld.player().id and all((predicate(avatarId, result) for predicate, result in self._predicates))) or damage <= 0:
            return
        nowTime = BigWorld.time()
        savedTargetDamageInfo = self._avatarsDamageRemainders.get(avatarId, (0, nowTime))
        accumulatedDamage = damage + savedTargetDamageInfo[0]
        amount, reminder = getRewardableProgress(accumulatedDamage, maxHealth, self._progressStep)
        isAccumulatorTimeout = nowTime - savedTargetDamageInfo[1] > ClientDamageProcessor.ATTACK_TIMEOUT
        self._avatarsDamageRemainders[avatarId] = (reminder, nowTime)
        if not avatarId == self._currentTarget or isAccumulatorTimeout:
            self._currentTarget = avatarId
            self._targetAccumulator = 0
        reward = int(amount * self._reward)
        if reward != 0:
            self._targetAccumulator += reward
            accumulatorResetted = self._currentTarget != self._targetWithAccumulatedDamage or isAccumulatorTimeout
            self._targetWithAccumulatedDamage = self._currentTarget
            self.eDamage(self._eventId, reward, self._targetAccumulator, accumulatorResetted)
        elif isAccumulatorTimeout:
            self._targetWithAccumulatedDamage = 0

    def destroy(self):
        self._unlinkEvents(self._gameEnvironment)
        self._gameEnvironment = None
        self._avatarsDamageRemainders = None
        self.eDamage.clear()
        self.eDamage = None
        self.PREDICATES.clear()
        self._predicates = []
        return

    def _linkEvents(self, gameEnvironment):
        gameEnvironment.eAvatarAdded += self._onAvatarAdded
        gameEnvironment.eAvatarRemoved += self._onAvatarRemoved

    def _unlinkEvents(self, gameEnvironment):
        gameEnvironment.eAvatarAdded -= self._onAvatarAdded
        gameEnvironment.eAvatarRemoved -= self._onAvatarRemoved

    def _onAvatarAdded(self, avatar):
        avatar.eHealthChanged += self._processDamage

    def _onAvatarRemoved(self, avatar, isLeaveWorld):
        if isLeaveWorld:
            avatar.eHealthChanged -= self._processDamage

    def _teammatePredicate(self, victimEntityID, needRes):
        entity = BigWorld.entities.get(victimEntityID, None)
        if not entity:
            LOG_WARNING('ECO: _teammatePredicate: entity not found')
            return False
        else:
            player = BigWorld.player()
            return needRes == (player.teamIndex == entity.teamIndex)

    def _typePredicate(self, entityId, neededType):
        result = None
        entity = BigWorld.entities.get(entityId)
        if EntityHelpers.isTeamObject(entity):
            result = 'GroundObject'
        elif EntityHelpers.isPlayerAvatar(entity):
            result = 'Player'
        elif EntityHelpers.isAvatarBot(entity):
            clientArena = self._gameEnvironment.service('ClientArena')
            info = clientArena.getAvatarInfo(entityId)
            isDefender = info.get('defendSector')
            if bool(isDefender):
                result = 'Defender'
            elif bool(info.get('isBomber')):
                result = 'Bomber'
            else:
                result = 'Player'
        return result == neededType

    def _acTypePredicate(self, entityId, validTypes):
        clientArena = self._gameEnvironment.service('ClientArena')
        objectData = clientArena.allObjectsData[entityId]
        if 'ACType' not in objectData:
            return False
        try:
            typeName = GROUND_OBJECT_TYPE.getName(objectData['ACType'])
        except ValueError:
            return False

        validTypes = validTypes.split('|')
        return typeName in validTypes
Пример #24
0
class ContainerManager(ContainerManagerMeta, IContainerManager):
    """
    The container manager manages overlapping of views and their life time based on their type
    and scope. Performs loading of views through the specified loader.
    
    1. Overlapping of views
    UI consists of several layers. Each layer has its own Z index. It allows to control overlapping
    of views (views of the top level layer overlap views of underlying layers). The set of default
    layers depends on entry (application) type (lobby and battle have their own configuration).
    Each view can belong to one layer and it is defined by view's type. With each layer associated
    one view container that is managed by the container manager. There are two types of layers
    (view containers):
    - DefaultContainer - only one top level view can be placed in the container (layer) and if a
      new view is placed to it the previous one is destroyed;
    - PopUpContainer - several views can exist at the same time in one layer.
    Also any top level view can include a subview that is placed into a sub-container. If a top
    level view can include a sub-view, the sub-container is created after the top level view is loaded and
    initialized. When sub-view is loaded, it is placed into the top level view's sub-container. The sub-container
    is destroyed when the top level view is destroyed.
    
    2. Views life time
    The 'view scope' concept is introduced to simplify views lifetime management. View lifetime is
    defined by its scope and is controlled by the container manager through the scope controller.
    View scope defines when the view should be destroyed: if the parent view (parent scope) is
    destroyed, the subview is destroyed too. For details please see ScopeController description.
    """
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        self.__globalContainer = _GlobalViewContainer(weakref.proxy(self))
        for container in containers:
            raise isinstance(container, ViewContainer) or AssertionError
            self.__globalContainer.addChildContainer(container)

        self.__loader = loader
        self.__loader.onViewLoaded += self.__onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
        self.__viewCache = _ViewCollection()
        self.__chainMng = _ChainManager(weakref.proxy(self))

    def _dispose(self):
        self.__viewCache.destroy()
        self.__chainMng.destroy()
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__onViewLoaded
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                LOG_DEBUG('Destroy container {} ({})'.format(
                    viewType, container))
                container.destroy()

        self.__globalContainer.destroy()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        super(ContainerManager, self)._dispose()
        return

    def destroyViews(self, alias, name=None):
        def compareByAlias(view):
            return view.key.alias == alias

        def compareByAliasAndName(view):
            viewKey = view.key
            return viewKey.alias == alias and viewKey.name == name

        if name is None:
            comparator = compareByAlias
        else:
            comparator = compareByAliasAndName
        views = self.__scopeController.findViews(comparator)
        views.extend(self.__viewCache.findViews(comparator))
        for view in views:
            if not view.isDisposed():
                LOG_DEBUG('The view {} will be destroyed...'.format(view))
                view.destroy()

        viewKey = ViewKey(alias, name)
        chain = self.__chainMng.getChainByViewKey(viewKey)
        if chain is not None:
            chain.removeViewByViewKey(viewKey)
        return

    def loadChain(self, chainItems):
        """
        Loads the given views (chain items) one after the other.
        
        :param chainItems: list of ChainItem items.
        """
        chain = _LoadingChain(chainItems)
        if self.__chainMng.addChain(chain):
            chain.run()
        else:
            LOG_WARNING(
                'Could not add a new chain. Loading of chain [{}] is canceled.'
                .format(chainItems))
            chain.destroy()

    def load(self, loadParams, *args, **kwargs):
        """
        Loads a view with the given alias and puts it to the appropriate container (layer).
        
        :param loadParams: instance of ViewLoadParams
        :param args: args to be passed to view's constructor.
        :param kwargs: kwargs to be passed to view's constructor.
        :return: instance of view (loading or loaded). None if no view is loaded.
        """
        viewKey = loadParams.viewKey
        viewLoadingItem = self.__loader.getViewLoadingItem(viewKey)
        if viewLoadingItem is not None:
            LOG_DEBUG('View with key {} is already loading. item=[{}]'.format(
                viewKey, viewLoadingItem))
            view = viewLoadingItem.pyEntity
            if loadParams.loadMode == ViewLoadMode.DEFAULT:
                loadingViewLoadMode = viewLoadingItem.loadParams.loadMode
                if loadingViewLoadMode == ViewLoadMode.PRELOAD:
                    viewLoadingItem.loadParams = loadParams
                    self.__addLoadingView(view)
            elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                pass
            else:
                LOG_WARNING(
                    'Unsupported load mode {}. View loading will be skipped.'.
                    format(loadParams))
                view = None
        else:
            view = self.__globalContainer.findView(viewKey)
            if view is None:
                view = self.__viewCache.getView(viewKey)
                if view is None:
                    chain = self.__chainMng.getChainByViewKey(viewKey)
                    if chain is not None:
                        LOG_WARNING(
                            'View with loadParams={} is in the loading chain {}. The request will be skipped.'
                            .format(loadParams, chain))
                    else:
                        LOG_DEBUG(
                            'Load view with loadParams={}. Loader=[{}]'.format(
                                loadParams, self.__loader))
                        if loadParams.loadMode == ViewLoadMode.DEFAULT:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                            self.__addLoadingView(view)
                        elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                        else:
                            LOG_WARNING(
                                'Unsupported load mode {}. View loading will be skipped.'
                                .format(loadParams))
                elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                    LOG_DEBUG(
                        'View with key {} ({}) is already pre-loaded.'.format(
                            viewKey, view))
                elif loadParams.loadMode == ViewLoadMode.DEFAULT:
                    LOG_DEBUG(
                        'Load view with loadParams={} from the cache. Cache=[{}]'
                        .format(loadParams, self.__viewCache))
                    self.__viewCache.removeView(viewKey)
                    self.__showAndInitializeView(view)
                    view.validate(*args, **kwargs)
                else:
                    LOG_WARNING(
                        'Unsupported load mode {}. View loading will be skipped.'
                        .format(loadParams))
                    view = None
            else:
                LOG_DEBUG('View with key {} ({}) is already loaded.'.format(
                    viewKey, view))
                viewType = view.settings.type
                viewContainer = self.__globalContainer.findContainer(viewType)
                viewContainer.addView(view)
                view.validate(*args, **kwargs)
        return view

    def getContainer(self, viewType):
        """
        Returns container by the given type or None if there is no such container.
        
        :param viewType: viewType: View type. @see ViewTypes.
        """
        return self.__globalContainer.findContainer(viewType)

    def isModalViewsIsExists(self):
        """
        Returns True if a modal view exists, otherwise returns False.
        """
        for viewType in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria=None):
        """
        Gets view by the given type and criteria if it is defined.
        
        :param viewType: type of view. @see ViewTypes.
        :param criteria: criteria to find view in container.
        :return: instance of view.
        """
        container = self.__globalContainer.findContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria)
        else:
            LOG_WARNING('Could not found container {}.'.format(viewType))
            return

    def isViewAvailable(self, viewType, criteria=None):
        """
        If you want to get some view from some container, it`s may be
        unsafely operation. For example, I want to get a Hangar from a Lobby
        view. it`s a bad situation and method "getView" detects this state.
        Then, if you just want to detect an existing View, use isViewAvailable method.
        
        :param viewType: type of view. @see ViewTypes.
        :param criteria: criteria to find view in container.
        """
        container = self.__globalContainer.findContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False

    def showContainers(self, *viewTypes):
        """
        Shows containers for given view types.
        
        :param viewTypes: View types
        """
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        """
        Hides containers for given view types.
        
        :param viewTypes: View types
        """
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        """
        Returns True if a container with the given view type is shown, otherwise returns False.
        
        :param viewType: View types
        """
        return self.as_isContainerShownS(viewType)

    def clear(self):
        """
        Clears pop-ups containers.
        """
        for viewType in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                container.clear()

        return

    def closePopUps(self):
        """
        Closes all popUps: widows and dialogs.
        """
        self.as_closePopUpsS()

    def registerViewContainer(self, viewType, uniqueName):
        self.as_registerContainerS(viewType, uniqueName)
        LOG_DEBUG(
            'A new container [type={}, name={}] has been registered.'.format(
                viewType, uniqueName))

    def unregisterViewContainer(self, viewType):
        self.as_unregisterContainerS(viewType)
        LOG_DEBUG(
            'The container [type={}] has been unregistered.'.format(viewType))

    def __addLoadingView(self, pyView):
        viewType = pyView.settings.type
        viewContainer = self.__globalContainer.findContainer(viewType)
        if viewContainer is not None:
            viewContainer.addLoadingView(pyView)
        else:
            LOG_WARNING(
                'Loading of view {} is requested but the container {} is still not exist!'
                .format(pyView, viewType))
        self.__scopeController.addLoadingView(pyView, False)
        return

    def __showAndInitializeView(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR(
                'Type of view is not defined. View {} will be destroyed.',
                pyView)
            pyView.destroy()
            return False
        else:
            status = False
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                if ViewTypes.DEFAULT == viewType:
                    self.closePopUps()
                if container.addView(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    self.onViewAddedToContainer(container, pyView)
                    status = True
                else:
                    LOG_ERROR(
                        '{} view cannot be added to container {} and will be destroyed.'
                        .format(pyView, container))
                    pyView.destroy()
            else:
                LOG_ERROR(
                    'Type {} of view {} is not supported or container has not been properly created'
                    .format(viewType, pyView))
                pyView.destroy()
            return status

    def __addViewToCache(self, pyView):
        view = self.__viewCache.getView(pyView.key)
        if view is not None:
            LOG_UNEXPECTED(
                'The view with key {} is already in the cache.'.format(
                    pyView.key), pyView, view)
            if view != pyView:
                view.destroy()
                if self.__viewCache.addView(pyView):
                    LOG_DEBUG('View {} has been added to the cache {}'.format(
                        pyView, self.__viewCache))
                else:
                    LOG_DEBUG('Cannot add view {} in the cache {}'.format(
                        pyView, self.__viewCache))
        elif self.__viewCache.addView(pyView):
            LOG_DEBUG('View {} has been added to the cache {}'.format(
                pyView, self.__viewCache))
        else:
            LOG_DEBUG('Cannot add view {} in the cache {}'.format(
                pyView, self.__viewCache))
        return

    def __onViewLoaded(self, pyView, loadParams):
        loadMode = loadParams.loadMode
        if loadMode == ViewLoadMode.DEFAULT:
            if self.__scopeController.isViewLoading(pyView=pyView):
                self.__showAndInitializeView(pyView)
            else:
                LOG_DEBUG(
                    '{} view loading is cancelled because its scope has been destroyed.'
                    .format(pyView))
                pyView.destroy()
        elif loadMode == ViewLoadMode.PRELOAD:
            self.__addViewToCache(pyView)
        else:
            LOG_WARNING(
                'Unsupported load mode {}. View {} will be destroyed.'.format(
                    loadMode, pyView))
            pyView.destroy()
Пример #25
0
class StateManager:
    def __init__(self):
        self._stateId = LOADING
        self._stateName = STATE_MAP[self._stateId]
        self._stateMachine = None
        self._goBackSignalID = ON_GO_BACK
        self._awaitLoadPlaneResources = False
        self._createEvents()
        self._createStateMachine()
        self._initStateMachine()
        self._interManager = IntermissionStateManager(
            self, self._onIntermissionActivityChanged, self.eOpenInter,
            self.eCloseInter, self.eCloseInterForce)
        self._initStatesEffectController()
        self.___endDeathStateCallback = None
        return

    def _initStatesEffectController(self):
        from HUDStatesEffectsSettings import EFFECTS_MAP
        from EffectManager import g_instance
        self._statesEffectsCtrl = HUDStatesEffectsController(
            EFFECTS_MAP, g_instance)

    @property
    def state(self):
        return self._stateName

    def _createEvents(self):
        self.eStateChanged = Event()
        self.eToggleHUDVisibility = Event()
        self.eOpenInter = Event()
        self.eCloseInter = Event()
        self.eCloseInterForce = Event()

    def _createStateMachine(self):
        stateMapReverse = dict(((v, k) for k, v in STATE_MAP.iteritems()))

        def stateSetter(stateID, *args):
            self._onStateChanged(stateID)

        def stateGetter():
            return stateMapReverse.get(self._stateName, None)

        self._stateMachine = ExternalBitStateMachine(stateSetter, stateGetter,
                                                     None)
        return

    def _initStateMachine(self):
        self._stateMachine.addState(LOADING, None, None)
        self._stateMachine.addState(INTRO, None, None)
        self._stateMachine.addState(BATTLE_DEFAULT, None, None)
        self._stateMachine.addState(BATTLE_STATS, None, None)
        self._stateMachine.addState(OUTRO, None, None)
        self._stateMachine.addState(OUTRO_TAB, None, None)
        self._stateMachine.addState(RESPAWN_STATE, None, None)
        self._stateMachine.addState(DEATH_STATE, None, None)
        self._stateMachine.addState(DEATH_TAB_STATE, None, None)
        self._stateMachine.addState(LOADING_TAB, None, None)
        self._stateMachine.addState(INTRO_TAB, None, None)
        self._stateMachine.addState(RESPAWN_TAB, None, None)
        self._stateMachine.addState(RESPAWN_DISABLED_STATE, None, None)
        self._stateMachine.addState(RESPAWN_DISABLED_TAB_STATE, None, None)
        self._stateMachine.addState(PROMO_STATE, None, None)
        self._stateMachine.addTransition(LOADING, LOADING_TAB, TAB_DOWN)
        self._stateMachine.addTransition(LOADING_TAB, LOADING, TAB_UP)
        self._stateMachine.addTransition(LOADING | LOADING_TAB, BATTLE_DEFAULT,
                                         LOADING_FINISHED)
        self._stateMachine.addTransition(
            LOADING | LOADING_TAB, INTRO, HAS_CONTROL,
            lambda *args, **kwargs: self._showStartHint())
        self._stateMachine.addTransition(DEATH_STATE, DEATH_TAB_STATE,
                                         TAB_DOWN)
        self._stateMachine.addTransition(DEATH_TAB_STATE, DEATH_STATE, TAB_UP)
        self._stateMachine.addTransition(INTRO, INTRO_TAB, TAB_DOWN)
        self._stateMachine.addTransition(INTRO_TAB, INTRO, TAB_UP)
        self._stateMachine.addTransition(
            INTRO | LOADING, PRE_BATTLE, INTRO_FINISHED,
            lambda *args, **kwargs: self._showStartHint())
        self._stateMachine.addTransition(
            LOADING_TAB, PRE_BATTLE_TAB, INTRO_FINISHED,
            lambda *args, **kwargs: self._showStartHint())
        self._stateMachine.addTransition(INTRO_TAB, PRE_BATTLE_TAB,
                                         INTRO_FINISHED)
        self._stateMachine.addTransition(
            INTRO | INTRO_TAB | LOADING | LOADING_TAB, BATTLE_DEFAULT,
            ON_PRE_BATTLE_FINISH,
            lambda *args, **kwargs: self._showStartHint())
        self._stateMachine.addTransition(
            PRE_BATTLE, BATTLE_DEFAULT, ON_PRE_BATTLE_FINISH,
            lambda *args, **kwargs: self._goToBattle())
        self._stateMachine.addTransition(
            PRE_BATTLE_TAB, BATTLE_STATS, ON_PRE_BATTLE_FINISH,
            lambda *args, **kwargs: self._goToBattle())
        self._stateMachine.addTransition(PRE_BATTLE, PRE_BATTLE_TAB, TAB_DOWN)
        self._stateMachine.addTransition(PRE_BATTLE_TAB, PRE_BATTLE, TAB_UP)
        self._stateMachine.addTransition(RESPAWN_STATE, RESPAWN_TAB, TAB_DOWN)
        self._stateMachine.addTransition(RESPAWN_TAB, RESPAWN_STATE, TAB_UP)
        self._stateMachine.addTransition(
            RESPAWN_STATE | SPECTATOR_STATE | SPECTATOR_TACTICAL_STATE,
            BATTLE_DEFAULT, ON_END_RESPAWN,
            lambda *args, **kwargs: self._onRespawn())
        self._stateMachine.addTransition(
            RESPAWN_TAB | SPECTATOR_TAB_STATE | SPECTATOR_TAB_TACTICAL_STATE,
            BATTLE_STATS, ON_END_RESPAWN)
        self._stateMachine.addTransition(RESPAWN_DISABLED_STATE,
                                         RESPAWN_DISABLED_TAB_STATE, TAB_DOWN)
        self._stateMachine.addTransition(RESPAWN_DISABLED_TAB_STATE,
                                         RESPAWN_DISABLED_STATE, TAB_UP)
        self._stateMachine.addTransition(
            SPECTATOR_READY_STATES, SPECTATOR_STATE, ON_GO_TO_SPECTATOR,
            lambda *args, **kwargs: self._onSetSpectatorType(SPECTATOR_TYPE.
                                                             CINEMATIC))
        self._stateMachine.addTransition(
            SPECTATOR_READY_STATES, SPECTATOR_TACTICAL_STATE,
            ON_GO_TO_TACTICAL_SPECTATOR, lambda *args, **kwargs: self.
            _onSetSpectatorType(SPECTATOR_TYPE.TACTICAL))
        self._stateMachine.addTransition(
            ALL_SPECTATOR_STATES, RESPAWN_STATE, ON_GO_BACK, lambda *args, **
            kwargs: self._onSetSpectatorType(SPECTATOR_TYPE.NONE))
        self._stateMachine.addTransition(
            ALL_SPECTATOR_STATES, RESPAWN_DISABLED_STATE,
            ON_GO_BACK_NO_RESPAWN, lambda *args, **kwargs: self.
            _onSetSpectatorType(SPECTATOR_TYPE.NONE))
        self._stateMachine.addTransition(SPECTATOR_STATE, SPECTATOR_TAB_STATE,
                                         TAB_DOWN)
        self._stateMachine.addTransition(SPECTATOR_TAB_STATE, SPECTATOR_STATE,
                                         TAB_UP)
        self._stateMachine.addTransition(SPECTATOR_TACTICAL_STATE,
                                         SPECTATOR_TAB_TACTICAL_STATE,
                                         TAB_DOWN)
        self._stateMachine.addTransition(SPECTATOR_TAB_TACTICAL_STATE,
                                         SPECTATOR_TACTICAL_STATE, TAB_UP)
        self._stateMachine.addTransition(
            BATTLE_DEFAULT | BATTLE_STATS, DEATH_STATE, ON_DEATH,
            lambda *args, **kwargs: self._onDeath())
        self._stateMachine.addTransition(DEATH_STATE | DEATH_TAB_STATE,
                                         RESPAWN_STATE, ON_WAITE_RESPAWN)
        self._stateMachine.addTransition(
            LOADING | LOADING_TAB, RESPAWN_STATE, ON_WAITE_RESPAWN,
            lambda *args, **kwargs: self._connectToSpectator())
        self._stateMachine.addTransition(
            DEATH_STATE | DEATH_TAB_STATE, RESPAWN_DISABLED_STATE,
            ON_WAITE_DISABLED_RESPAWN,
            lambda *args, **kwargs: self._onRespawnDisabled())
        self._stateMachine.addTransition(
            LOADING | LOADING_TAB, RESPAWN_DISABLED_STATE,
            ON_WAITE_DISABLED_RESPAWN,
            lambda *args, **kwargs: self._connectToSpectator())
        self._stateMachine.addTransition(BATTLE_DEFAULT, BATTLE_STATS,
                                         TAB_DOWN)
        self._stateMachine.addTransition(BATTLE_STATS, BATTLE_DEFAULT, TAB_UP)
        self._stateMachine.addTransition(
            BATTLE_DEFAULT | BATTLE_STATS | RESPAWN_STATES
            | ALL_SPECTATOR_STATES | DEATH_STATE | DEATH_TAB_STATE, OUTRO,
            ON_OUTRO)
        self._stateMachine.addTransition(OUTRO, OUTRO_TAB, TAB_DOWN)
        self._stateMachine.addTransition(OUTRO_TAB, OUTRO, TAB_UP)
        self._stateMachine.addTransition(PROMO_STATE, BATTLE_DEFAULT,
                                         TOGGLE_PROMO)
        self._stateMachine.addTransition(ANY_STATE, PROMO_STATE, TOGGLE_PROMO)
        return

    def initSignals(self, features):
        self._playerAvatar = features.require(Feature.PLAYER_AVATAR)
        self._gameEnvironment = features.require(Feature.GAME_ENVIRONMENT)
        self._respawnModel = features.require(Feature.GAME_MODEL).respawn
        self._camera = features.require(Feature.CAMERA)
        self._clientArena = features.require(Feature.CLIENT_ARENA)
        inputProcessor = features.require(Feature.INPUT).commandProcessor
        sm = self._stateMachine
        inputProcessor.addListeners(InputMapping.CMD_VISIBILITY_HUD, None,
                                    None, self._onHUDVisibilityCommand)
        inputProcessor.addListeners(
            InputMapping.CMD_NEXT_VEHICLE_WHEN_DEAD,
            lambda: self._playerAvatar.switchObservee())
        inputProcessor.addListeners(InputMapping.CMD_INTERMISSION_MENU,
                                    self._onIntermissionPress)
        inputProcessor.addListeners(InputMapping.CMD_SHOW_TEAMS,
                                    lambda: self._onTabPressed(True),
                                    lambda: self._onTabPressed(False))
        inputProcessor.addListeners(InputMapping.CMD_HELP,
                                    lambda: self._onHelpPressed(True),
                                    lambda: self._onHelpPressed(False))
        inputProcessor.addListeners(
            InputMapping.CMD_GO_TO_SPECTATOR,
            lambda: self._onGoToSpectatorCommand(ON_GO_TO_SPECTATOR))
        inputProcessor.addListeners(
            InputMapping.CMD_GO_TO_TACTICAL_SPECTATOR,
            lambda: self._onGoToSpectatorCommand(ON_GO_TO_TACTICAL_SPECTATOR))
        inputProcessor.addListeners(InputMapping.CMD_SKIP_DEATH,
                                    self._skipDeath)
        inputProcessor.addListeners(InputMapping.CMD_SKIP_OUTRO,
                                    self._skipOutro)
        self._gameEnvironment.eIntroFinished += self._onIntroFinish
        self._gameEnvironment.eLoadingFinished += self._eLoadingFinished
        self._gameEnvironment.ePreBattleFinished += self._ePreBattleFinished
        self._gameEnvironment.eLoadingDeathFinished += self._eLoadingDeathFinished
        self._gameEnvironment.eAllIntreClosed += self._eAllIntreClosed
        self._gameEnvironment.eTogglePromoHUD += self.onPromoHUDToggle
        self._playerAvatar.onStateChanged += self._onPlayerStateChanged
        self._playerAvatar.eTacticalRespawnEnd += self._onTacticalRespawnEnd
        self._playerAvatar.eUpdateSpectator += self._onObserveeChanged
        self._playerAvatar.ePlaneModelLoaded += self._onPlaneModelLoaded
        self._clientArena.onBeforePlaneChanged += self._onBeforePlayerPlaneChanged
        self._addPredicates(inputProcessor)
        self._addAdditionalManager(features)
        return

    def _onStateChanged(self, newStateId):
        self._interManager.validateState(newStateId)
        self._stateId = newStateId
        self._stateName = STATE_MAP[newStateId]
        self.eStateChanged(self._stateName)
        self._updateDenyCursorHide()
        self.checkMouseState()
        self._updateAdditionalManager()
        self._statesEffectsCtrl.onHUDStateChanged(newStateId)

    def _updateAdditionalManager(self):
        self._respManager.changeState(self._stateId)

    def _addAdditionalManager(self, features):
        self._respManager = RespawnSilentCheckManager(
            features, RESPAWN_SILENT_CHECK_STATES)
        self._respManager.eRestDelay += self._onRespDelay

    def _onRespDelay(self):
        self._onGoToSpectatorCommand(ON_GO_TO_SPECTATOR)

    def _updateDenyCursorHide(self):
        self._gameEnvironment.eOnDenyCursorHideChanged(
            self._cursorVisibility())

    def _cursorVisibility(self):
        return self._interManager.isActive or self._stateId & MOUSE_VISIBILITY_STATES != 0

    def _onSetSpectatorType(self, sType, *args, **kwargs):
        self._playerAvatar.activateTacticalSpectator(sType)
        self._camera.onTacticalSpectator(
            self._playerAvatar.spectatorTypeWithTacticalMode)

    def _onObserveeChanged(self, newObserveeID):
        LOG_DEBUG('_onObserveeChanged', newObserveeID)
        if BigWorld.player().isObserverToBattleTransition:
            return
        if newObserveeID == 0:
            self._stateMachine.signal(self._goBackSignalID)

    def _onObserveeLost(self):
        if self.isRespawnAvailable():
            self._stateMachine.signal(self._goBackSignalID)
        else:
            self._stateMachine.signal(ON_GO_TO_SPECTATOR)

    def _onIntermissionActivityChanged(self, active):
        self._updateDenyCursorHide()

    def _onRespawnDisabled(self, *args, **kwargs):
        self._goBackSignalID = ON_GO_BACK_NO_RESPAWN

    def _onHUDVisibilityCommand(self, *args, **kwargs):
        LOG_DEBUG('HUD visibility command received')
        self.eToggleHUDVisibility()

    def _onIntermissionPress(self):
        chat = self._gameEnvironment.service('Chat')
        gamePlayHints = self._gameEnvironment.service('GamePlayHints')
        LOG_DEBUG('STATES TEST :  _onIntermissionPress ', self._stateId)
        if gamePlayHints.hintVisible:
            HUDExecutionManager.call(GameplayHintsSource.onDisableStartHint)
        elif chat.chatVisible:
            chat.hideChat()
        elif self._stateId & SPECTATOR_STATES:
            self._stateMachine.signal(self._goBackSignalID)
        else:
            self._stateMachine.signal(TAB_UP)
            self._interManager.onIntermissionPress(self._stateId)

    def _onHelpPressed(self, pressed):
        LOG_DEBUG('STATES TEST :  _onHelpPressed ', self._stateId)
        self._interManager.onHelpPress(pressed, self._stateId)

    def _onTabPressed(self, pressed):
        LOG_DEBUG('STATES TEST :  _onTabPressed ', self._stateId)
        if not self._interManager.isActive:
            if pressed:
                self._stateMachine.signal(TAB_DOWN)
            else:
                self._stateMachine.signal(TAB_UP)

    def _onBeforePlayerPlaneChanged(self, avatarID):
        if BigWorld.player().id == avatarID:
            self._awaitLoadPlaneResources = True

    def _onPlaneModelLoaded(self):
        if self._awaitLoadPlaneResources and BigWorld.player(
        ).state & EntityStates.GAME:
            self._stateMachine.signal(ON_END_RESPAWN)
        self._awaitLoadPlaneResources = False

    def _goToBattle(self, *args, **kwargs):
        """Reset camera for player to avoid some issues related to reconnect
        """
        self._camera.reset()
        self._requestShootingHint()

    def _onRespawn(self, *args, **kwargs):
        """Reset camera for player to avoid some issues related to reconnect
        """
        self._requestShootingHint()

    def _onDeath(self, *args, **kwargs):
        """Close start hint if it was visible when player died
        """
        gamePlayHints = self._gameEnvironment.service('GamePlayHints')
        gamePlayHints.setHintVisibility(False)

    def _showStartHint(self, *args, **kwargs):
        """Reset camera for player to avoid some issues related to reconnect
        """
        gamePlayHints = self._gameEnvironment.service('GamePlayHints')
        if self._playerAvatar.startHintAvailable and not gamePlayHints.hintVisible:
            HUDExecutionManager.call(GameplayHintsSource.onShowHint,
                                     HINTS_TYPE.START)

    def _connectToSpectator(self, *args, **kwargs):
        self._playerAvatar.skipDeadFallState()
        self._camera.switchToSpectator()

    def _onGoToSpectatorCommand(self, signalID):
        if self._stateId & ALL_SPECTATOR_STATES:
            self._stateMachine.signal(self._goBackSignalID)
        else:
            if self._playerAvatar.observeeID == 0:
                self._playerAvatar.switchObservee()
                return
            self._stateMachine.signal(signalID)

    def _requestShootingHint(self):
        if self._playerAvatar.shootingHintAvailable and not self._playerAvatar.startHintAvailable:
            HUDExecutionManager.call(GameplayHintsSource.onShowHint,
                                     HINTS_TYPE.SHOOTING)

    def isRespawnAvailable(self):
        return self._respawnModel.respawnAmount.get() != 0

    def goToCinemaSpectatorPredicate(self):
        res = self._stateId & CINEMA_SPECTATOR_READY_STATES
        return res

    def goToTacticalSpectatorPredicate(self):
        res = self._stateId & TACTICAL_SPECTATOR_READY_STATES
        return res

    def isChatAvailable(self):
        res = not self._stateId & SPECTATOR_STATES
        return res

    def _addPredicates(self, processor):
        processor.addPredicate(InputMapping.CMD_GO_TO_SPECTATOR,
                               self.goToCinemaSpectatorPredicate)
        processor.addPredicate(InputMapping.CMD_GO_TO_TACTICAL_SPECTATOR,
                               self.goToTacticalSpectatorPredicate)
        processor.addPredicate(InputMapping.CMD_GO_BACK,
                               self.isRespawnAvailable)
        processor.addPredicate(InputMapping.CMD_CHAT, self.isChatAvailable)

    def _skipOutro(self):
        if self._stateName == STATE_MAP[OUTRO]:
            self._playerAvatar.exitGame()

    def _skipDeath(self):
        if self._stateName == STATE_MAP[
                DEATH_STATE] or self._stateName == STATE_MAP[DEATH_TAB_STATE]:
            LOG_DEBUG(' STATES TEST :  _skipDeath ')
            signalID = ON_WAITE_RESPAWN if self.isRespawnAvailable(
            ) else ON_WAITE_DISABLED_RESPAWN
            BigWorld.callback(0, lambda: self._stateMachine.signal(signalID))

    def _eAllIntreClosed(self):
        LOG_DEBUG('STATES TEST :  onAllIntreClosed ')
        self._interManager.onAllIntermissionClosed()
        self.checkMouseState()

    def checkMouseState(self):
        Cursor.forceShowCursor(self._cursorVisibility())
        if self._stateId == BATTLE_DEFAULT and not self._interManager.isActive:
            self._playerAvatar.setFlyMouseInputAllowed(True)
        else:
            self._playerAvatar.setFlyMouseInputAllowed(False)

    def _onIntroFinish(self):
        LOG_DEBUG('STATES TEST :  _onIntroFinish ')
        self._stateMachine.signal(INTRO_FINISHED)

    def _eLoadingFinished(self):
        LOG_DEBUG('STATES TEST :  eLoadingFinished ')
        self._stateMachine.signal(HAS_CONTROL)

    def _ePreBattleFinished(self):
        LOG_DEBUG('STATES TEST :  _ePreBattleFinished ')
        self._stateMachine.signal(ON_PRE_BATTLE_FINISH)

    def _eLoadingDeathFinished(self):
        LOG_DEBUG(' STATES TEST :  _eLoadingDeathFinished ')
        self._endDeathState()

    def _onPlayerStateChanged(self, oldState, state):
        LOG_DEBUG(' STATES TEST :  currentState : ',
                  EntityStates.getStateName(state))
        if state & (EntityStates.DESTROYED | EntityStates.DESTROYED_FALL):
            if oldState & EntityStates.GAME_CONTROLLED:
                LOG_DEBUG(' STATES TEST : ', 'DEAD')
                self._stateMachine.signal(ON_DEATH)
                self.___endDeathStateCallback = BigWorld.callback(
                    10, self._endDeathState)
        if state & EntityStates.GAME:
            LOG_DEBUG('STATES TEST : ', 'START GAME AFTER RESPAWN')
            if not self._awaitLoadPlaneResources:
                self._stateMachine.signal(ON_END_RESPAWN)
        if state & EntityStates.OUTRO:
            LOG_DEBUG(' STATES TEST : ', ' OUTRO ')
            self._stateMachine.signal(ON_OUTRO)

    def _onTacticalRespawnEnd(self, *args, **kwargs):
        LOG_DEBUG(' STATES TEST : _onTacticalRespawnEnd')

    def _endDeathState(self):
        if self._stateName == STATE_MAP[
                DEATH_STATE] or self._stateName == STATE_MAP[
                    DEATH_TAB_STATE] or self._stateName == STATE_MAP[LOADING]:
            signalID = ON_WAITE_RESPAWN if self.isRespawnAvailable(
            ) else ON_WAITE_DISABLED_RESPAWN
            self._stateMachine.signal(signalID)

    def onPromoHUDToggle(self):
        self._stateMachine.signal(TOGGLE_PROMO)

    def dispose(self):
        if self.___endDeathStateCallback:
            BigWorld.cancelCallback(self.___endDeathStateCallback)
            self.___endDeathStateCallback = None
        self._statesEffectsCtrl.destroy()
        self._statesEffectsCtrl = None
        self._interManager.dispose()
        self._interManager = None
        self._respManager.eRestDelay -= self._onRespDelay
        self._respManager = None
        self._gameEnvironment.eIntroFinished -= self._onIntroFinish
        self._gameEnvironment.eLoadingFinished -= self._eLoadingFinished
        self._gameEnvironment.ePreBattleFinished -= self._ePreBattleFinished
        self._gameEnvironment.eLoadingDeathFinished -= self._eLoadingDeathFinished
        self._gameEnvironment.eAllIntreClosed -= self._eAllIntreClosed
        self._gameEnvironment.eTogglePromoHUD -= self.onPromoHUDToggle
        self._playerAvatar.onStateChanged -= self._onPlayerStateChanged
        self._playerAvatar.eTacticalRespawnEnd -= self._onTacticalRespawnEnd
        self._playerAvatar.eUpdateSpectator -= self._onObserveeChanged
        self._playerAvatar.ePlaneModelLoaded -= self._onPlaneModelLoaded
        self._clientArena.onBeforePlaneChanged -= self._onBeforePlayerPlaneChanged
        self._playerAvatar = None
        self._gameEnvironment = None
        self._respawnModel = None
        self._camera = None
        self.eStateChanged.clear()
        self._stateMachine.destroy()
        return
Пример #26
0
class ServerSettings(object):
    def __init__(self, serverSettings):
        self.onServerSettingsChange = Event()
        self.__serverSettings = serverSettings if serverSettings else {}
        if "roaming" in self.__serverSettings:
            roamingSettings = self.__serverSettings["roaming"]
            self.__roamingSettings = RoamingSettings(
                roamingSettings[0], roamingSettings[1], [_ServerInfo(*s) for s in roamingSettings[2]]
            )
        else:
            self.__roamingSettings = RoamingSettings.defaults()
        if "file_server" in self.__serverSettings:
            self.__fileServerSettings = _FileServerSettings(self.__serverSettings["file_server"])
        else:
            self.__fileServerSettings = _FileServerSettings.defaults()
        if "regional_settings" in self.__serverSettings:
            self.__regionalSettings = makeTupleByDict(_RegionalSettings, self.__serverSettings["regional_settings"])
        else:
            self.__regionalSettings = _RegionalSettings.defaults()
        try:
            self.__eSportCurrentSeason = makeTupleByDict(_ESportCurrentSeason, self.__serverSettings)
        except TypeError:
            self.__eSportCurrentSeason = _ESportCurrentSeason.defaults()

        self.__updateClanProfile(self.__serverSettings)

    def update(self, serverSettingsDiff):
        self.__serverSettings.update(serverSettingsDiff)
        self.__updateClanProfile(serverSettingsDiff)
        self.onServerSettingsChange(serverSettingsDiff)

    def clear(self):
        self.onServerSettingsChange.clear()

    def getSettings(self):
        return self.__serverSettings

    @property
    def roaming(self):
        return self.__roamingSettings

    @property
    def fileServer(self):
        return self.__fileServerSettings

    @property
    def regionals(self):
        return self.__regionalSettings

    @property
    def eSportCurrentSeason(self):
        return self.__eSportCurrentSeason

    @property
    def clanProfile(self):
        return self.__clanProfile

    def isPotapovQuestEnabled(self):
        return self.__getGlobalSetting("isPotapovQuestEnabled", False)

    def isFortBattlesEnabled(self):
        return not self.__getGlobalSetting("isFortBattlesDisabled", True)

    def isClubsEnabled(self):
        return self.__getGlobalSetting("isClubsEnabled", False)

    def isGoldFishEnabled(self):
        return self.__getGlobalSetting("isGoldFishEnabled", False)

    def isTutorialEnabled(self):
        return self.__getGlobalSetting("isTutorialEnabled", IS_TUTORIAL_ENABLED)

    def isSandboxEnabled(self):
        return self.__getGlobalSetting("isSandboxEnabled", False)

    def isPromoAutoViewsEnabled(self):
        return True

    def getForbiddenFortDefenseHours(self):
        return self.__getGlobalSetting("forbiddenFortDefenseHours", tuple())

    def getForbiddenSortieHours(self):
        return self.__getGlobalSetting("forbiddenSortieHours", tuple())

    def getForbiddenSortiePeripheryIDs(self):
        return self.__getGlobalSetting("forbiddenSortiePeripheryIDs", tuple())

    def getForbiddenRatedBattles(self):
        return self.__getGlobalSetting("forbiddenRatedBattles", {})

    def isPremiumInPostBattleEnabled(self):
        return self.__getGlobalSetting("isPremiumInPostBattleEnabled", True)

    def __getGlobalSetting(self, settingsName, default=None):
        return self.__serverSettings.get(settingsName, default)

    def __updateClanProfile(self, targetSettings):
        if "clanProfile" in targetSettings:
            cProfile = targetSettings["clanProfile"]
            self.__clanProfile = _ClanProfile(
                cProfile.get("isEnabled", False), cProfile.get("gateUrl", ""), cProfile.get("type", "gateway")
            )
        else:
            self.__clanProfile = _ClanProfile.defaults()
Пример #27
0
class ItemsCache(IItemsCache):

    def __init__(self):
        super(ItemsCache, self).__init__()
        goodies = GoodiesRequester()
        self.__items = ItemsRequester.ItemsRequester(InventoryRequester(), StatsRequester(), DossierRequester(), goodies, ShopRequester(goodies), RecycleBinRequester(), VehicleRotationRequester(), RankedRequester(), BattleRoyaleRequester(), BadgesRequester(), EpicMetaGameRequester(), TokensRequester(), dependency.instance(IFestivityFactory).getRequester(), BlueprintsRequester(), SessionStatsRequester(), AnonymizerRequester(), GiftSystemRequester())
        self.__compatVehiclesCache = CompatVehiclesCache()
        self.__waitForSync = False
        self.__syncFailed = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()
        self.onSyncFailed = Event()

    def init(self):
        g_playerEvents.onInventoryResync += self.__pe_onInventoryResync
        g_playerEvents.onDossiersResync += self.__pe_onDossiersResync
        g_playerEvents.onStatsResync += self.__pe_onStatsResync
        g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected

    def fini(self):
        self.__items.fini()
        self.__compatVehiclesCache.clear()
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        self.onSyncFailed.clear()
        g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected
        g_playerEvents.onStatsResync -= self.__pe_onStatsResync
        g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync
        g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def items(self):
        return self.__items

    @property
    def compatVehiclesCache(self):
        return self.__compatVehiclesCache

    @async
    def update(self, updateReason, diff=None, notify=True, callback=None):
        if diff is None or self.__syncFailed:
            self.__invalidateFullData(updateReason, notify, callback)
        else:
            self.__invalidateData(updateReason, diff, notify, callback)
        return

    def clear(self):
        LOG_DEBUG('Clearing items cache.')
        self.__compatVehiclesCache.clear()
        return self.items.clear()

    def request(self, callback):
        raise SoftException('This method should not be reached in this context')

    def onDisconnected(self):
        self.items.onDisconnected()

    def _onResync(self, reason):
        if not self.__waitForSync:
            self.__invalidateFullData(reason)

    def _onCenterIsLongDisconnected(self, isLongDisconnected):
        self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected)

    def __invalidateData(self, updateReason, diff, notify=True, callback=lambda *args: None):
        self.__waitForSync = True
        wasSyncFailed = self.__syncFailed
        self.__syncFailed = False
        self.onSyncStarted()
        if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed:
            invalidItems = self.__items.invalidateCache(diff)
        else:
            invalidItems = {}

        def cbWrapper(*args):
            self.__waitForSync = False
            if not self.isSynced():
                self.__syncFailed = True
                self.onSyncFailed(updateReason)
            else:
                self.__compatVehiclesCache.invalidateData(self, invalidItems)
                if notify:
                    self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def __invalidateFullData(self, updateReason, notify=True, callback=lambda *args: None):
        self.__waitForSync = True
        wasSyncFailed = self.__syncFailed
        self.__syncFailed = False
        self.onSyncStarted()

        def cbWrapper(*args):
            self.__waitForSync = False
            if not self.isSynced():
                self.__syncFailed = True
                self.onSyncFailed(updateReason)
            else:
                if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed:
                    invalidItems = self.__items.invalidateCache()
                else:
                    invalidItems = {}
                self.__compatVehiclesCache.invalidateFullData(self)
                if notify:
                    self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def isSynced(self):
        return self.items.isSynced()

    def __pe_onStatsResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.STATS_RESYNC)

    def __pe_onInventoryResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC)

    def __pe_onDossiersResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
Пример #28
0
class _QuestsCache(object):

    def __init__(self):
        self.__progress = QuestsProgress()
        self.__waitForSync = False
        self.__invalidateCbID = None
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()
        return

    def init(self):
        pass

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        self.__clearInvalidateCallback()

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def progress(self):
        return self.__progress

    @async
    def update(self, callback = None):
        self.__invalidateData(callback)

    @classmethod
    def makeQuestsGroups(cls, quests):
        tasks = []
        groups = defaultdict(lambda : [])
        for qID, q in quests.iteritems():
            if q.getGroupID() is None:
                tasks.append(q)
            elif q.isStrategic():
                tasks.append(q)
                groups[q.getGroupID()].insert(0, q)
            else:
                groups[q.getGroupID()].append(q)

        return (tasks, groups)

    def getQuests(self, filterFunc = None):
        quests = self.__getQuestsData()
        filterFunc = filterFunc or (lambda a: True)
        result = {}
        for qID, qData in quests.iteritems():
            q = Quest(qID, qData, self.__progress.getQuestProgress(qID))
            if q.getDestroyingTimeLeft() <= 0:
                continue
            if not filterFunc(q):
                continue
            result[qID] = q

        _, groups = self.makeQuestsGroups(result)
        for q in result.itervalues():
            if q.isSubtask() or q.isStrategic():
                q.setGroup(groups[q.getGroupID()])

        return result

    def getCurrentQuests(self):
        return self.getQuests(lambda q: q.getStartTimeLeft() <= 0 and q.getFinishTimeLeft() > 0)

    def getFutureQuests(self):
        return self.getQuests(lambda q: q.getStartTimeLeft() > 0)

    def _onResync(self, *args):
        self.__invalidateData()

    @classmethod
    def __getQuestGroupID(cls, qData):
        return qData.get('groupID') or None

    @classmethod
    def __getQuestSeqID(cls, qData):
        return qData.get('seqID', -1)

    def __invalidateData(self, callback = lambda *args: None):

        def cbWrapper(*args):
            self.__waitForSync = False
            self.onSyncCompleted()
            callback(*args)

        self.__clearInvalidateCallback()
        self.__waitForSync = True
        self.onSyncStarted()
        self.__progress.request()(cbWrapper)
        minFinishTimeLeft = sys.maxint
        for q in self.getCurrentQuests().itervalues():
            minFinishTimeLeft = min(minFinishTimeLeft, q.getFinishTimeLeft())

        for q in self.getFutureQuests().itervalues():
            minFinishTimeLeft = min(minFinishTimeLeft, q.getStartTimeLeft())

        if minFinishTimeLeft != sys.maxint:
            self.__loadInvalidateCallback(minFinishTimeLeft)
        from gui.shared import g_eventBus
        g_eventBus.handleEvent(events.LobbySimpleEvent(events.LobbySimpleEvent.QUESTS_UPDATED))

    def __getQuestsData(self):
        try:
            if isPlayerAccount():
                if 'questsClientData' in BigWorld.player().eventsData:
                    return pickle.loads(zlib.decompress(BigWorld.player().eventsData['questsClientData']))
                return {}
            LOG_ERROR('Trying to get quests data from not account player', BigWorld.player())
        except Exception:
            LOG_CURRENT_EXCEPTION()

        return {}

    def __loadInvalidateCallback(self, duration):
        LOG_DEBUG('load quest window invalidation callback (secs)', duration)
        self.__clearInvalidateCallback()
        self.__invalidateCbID = BigWorld.callback(math.ceil(duration), self.__invalidateData)

    def __clearInvalidateCallback(self):
        if self.__invalidateCbID is not None:
            BigWorld.cancelCallback(self.__invalidateCbID)
            self.__invalidateCbID = None
        return
Пример #29
0
class CustomizationCamera(object):
    def __init__(self):
        self.__cfg = getHangarSpaceConfig()
        self.__camSens = self.__cfg['cam_sens']
        self.__pitchConstraints = self.__cfg['cam_pitch_constr']
        self.__distConstraints = self.__cfg['cam_dist_constr']
        self.__yawCameraFilter = HangarCameraYawFilter(
            math.radians(self.__cfg['cam_yaw_constr'][0]),
            math.radians(self.__cfg['cam_yaw_constr'][1]), self.__camSens)
        self.__cam = None
        self.__prevCam = None
        self.__prevVerticalFov = None
        self.__nativeVerticalFov = None
        self.__currentVerticalFov = None
        self.__isActive = False
        self.__scrollEvent = Event()
        return

    def init(self):
        self.__cam = BigWorld.CursorCamera()
        self.__cam.pivotMaxDist = 0
        self.__cam.pivotMinDist = 0
        self.__cam.turningHalfLife = self.__cam.maxDistHalfLife = self.__cfg[
            'cam_fluency']
        self.__cam.movementHalfLife = 0.0
        self.__cam.pivotPosition = Math.Vector3()
        self.__cam.source = Math.Matrix()
        self.__cam.target = Math.Matrix()
        self.__cam.wg_applyParams()

    def destroy(self):
        self.deactivate()
        self.__cam = None
        self.__cfg = None
        self.__camSens = None
        self.__pitchConstraints = None
        self.__distConstraints = None
        self.__yawCameraFilter = None
        self.__scrollEvent.clear()
        return

    def activate(self, targetPos, cameraParams):
        if self.__isActive:
            return
        self.__prevCam = BigWorld.camera()
        self.__prevVerticalFov = BigWorld.projection().fov
        self.__cam.spaceID = self.__prevCam.spaceID
        self.__yawCameraFilter = HangarCameraYawFilter(
            math.radians(cameraParams.yawConstraints[0]),
            math.radians(cameraParams.yawConstraints[1]), self.__camSens)
        self.__pitchConstraints = cameraParams.pitchConstraints
        self.__distConstraints = cameraParams.distanceConstraints
        pivotY, pivotMaxDist, initYaw, initPitch = self.__calculateCursorCameraParams(
            targetPos, cameraParams)
        self.__cam.target.setTranslate(targetPos)
        self.__cam.pivotPosition = Math.Vector3(0.0, pivotY, 0.0)
        self.__cam.pivotMaxDist = pivotMaxDist
        sourceMat = Math.Matrix()
        sourceMat.setRotateYPR(Math.Vector3(initYaw, initPitch, 0.0))
        self.__cam.source = sourceMat
        self.__cam.wg_applyParams()
        BigWorld.camera(self.__cam)
        horizontalFov = math.radians(cameraParams.fov)
        self.__setHorizontalFov(horizontalFov)
        self.__currentVerticalFov = self.__nativeVerticalFov = BigWorld.projection(
        ).fov
        FovExtended.instance().onSetFovSettingEvent += self.__onSetFovSetting
        FovExtended.instance().onRefreshFovEvent += self.__onRefreshFov
        self.__isActive = True

    def deactivate(self):
        if not self.__isActive:
            return
        else:
            self.__isActive = False
            FovExtended.instance(
            ).onSetFovSettingEvent -= self.__onSetFovSetting
            FovExtended.instance().onRefreshFovEvent -= self.__onRefreshFov
            if self.__prevCam is not None:
                if self.__prevCam.spaceID != BigWorld.camera().spaceID:
                    return
                BigWorld.camera(self.__prevCam)
                self.__prevCam = None
            self.__restorePreviousFov()
            return

    def addScrollListener(self, listener):
        self.__scrollEvent += listener

    def removeScrollListener(self, listener):
        self.__scrollEvent -= listener

    def handleMouseEvent(self, dx, dy, dz):
        if self.__isActive:
            self.__processMouseEvent(dx, dy, dz)

    def __processMouseEvent(self, dx, dy, dz):
        sourceMat = Math.Matrix(self.__cam.source)
        yaw = sourceMat.yaw
        pitch = sourceMat.pitch
        dist = self.__cam.pivotMaxDist
        currentMatrix = Math.Matrix(self.__cam.invViewMatrix)
        currentYaw = currentMatrix.yaw
        yaw = self.__yawCameraFilter.getNextYaw(currentYaw, yaw, dx)
        prevDist = dist
        pitch -= dy * self.__camSens
        dist -= dz * self.__camSens
        pitch = mathUtils.clamp(math.radians(self.__pitchConstraints[0]),
                                math.radians(self.__pitchConstraints[1]),
                                pitch)
        dist = mathUtils.clamp(self.__distConstraints[0],
                               self.__distConstraints[1], dist)
        mat = Math.Matrix()
        mat.setRotateYPR(Math.Vector3(yaw, pitch, 0.0))
        self.__cam.source = mat
        self.__cam.pivotMaxDist = dist
        deltaDist = math.fabs(dist - prevDist)
        if dz != 0 and deltaDist > 0.01:
            self.__scrollEvent()

    @staticmethod
    def __calculateCursorCameraParams(targetPos, cameraParams):
        initMatrix = Math.Matrix(cameraParams.initMatrix)
        initDirection = initMatrix.applyToAxis(2)
        startPoint = initMatrix.translation
        xPlanePoint = startPoint + initMatrix.applyToAxis(0)
        zPlanePoint = startPoint + initDirection
        camHorizontalPlane = Math.Plane()
        camHorizontalPlane.init(startPoint, xPlanePoint, zPlanePoint)
        intersectedPoint = camHorizontalPlane.intersectRay(
            targetPos, Math.Vector3(0.0, 1.0, 0.0))
        correctedCamDirection = intersectedPoint - startPoint
        pivotVec = intersectedPoint - targetPos
        pivotY = pivotVec.y
        yawCorrection = correctedCamDirection.yaw - initDirection.yaw
        yawCorrectionMatrix = Math.Matrix()
        yawCorrectionMatrix.setRotateYPR(Math.Vector3(yawCorrection, 0.0, 0.0))
        initMatrix.postMultiply(yawCorrectionMatrix)
        return (pivotY, correctedCamDirection.length, initMatrix.yaw,
                -initMatrix.pitch)

    @staticmethod
    def __setHorizontalFov(horizontalFov):
        FovExtended.instance().setFovByAbsoluteValue(horizontalFov)

    def __onSetFovSetting(self):
        self.__prevVerticalFov = BigWorld.projection().fov
        BigWorld.projection().fov = self.__currentVerticalFov

    def __onRefreshFov(self):
        self.__currentVerticalFov = BigWorld.projection().fov

    def __restorePreviousFov(self):
        if self.__prevVerticalFov is None:
            return
        else:
            if math.fabs(self.__currentVerticalFov -
                         self.__nativeVerticalFov) > 1e-06:
                FovExtended.instance().resetFov()
            else:
                BigWorld.projection().fov = self.__prevVerticalFov
            self.__prevVerticalFov = None
            self.__currentVerticalFov = None
            self.__nativeVerticalFov = None
            return
Пример #30
0
class CustomizationItemCMHandler(AbstractContextMenuHandler):
    itemsCache = dependency.descriptor(IItemsCache)
    service = dependency.descriptor(ICustomizationService)

    def __init__(self, cmProxy, ctx=None):
        self._intCD = 0
        super(CustomizationItemCMHandler, self).__init__(
            cmProxy, ctx, {
                CustomizationOptions.BUY: 'buyItem',
                CustomizationOptions.SELL: 'sellItem',
                CustomizationOptions.REMOVE_FROM_TANK: 'removeItemFromTank'
            })
        self.onSelected = Event(self._eManager)
        self._item = self.itemsCache.items.getItemByCD(self._intCD)
        self._c11nView = self.app.containerManager.getContainer(
            ViewTypes.LOBBY_SUB).getView()

    def fini(self):
        self.onSelected.clear()
        self.onSelected = None
        super(CustomizationItemCMHandler, self).fini()
        return

    def buyItem(self):
        self.onSelected(CustomizationOptions.BUY, self._intCD)

    def sellItem(self):
        self.onSelected(CustomizationOptions.SELL, self._intCD)

    def removeItemFromTank(self):
        self.onSelected(CustomizationOptions.REMOVE_FROM_TANK, self._intCD)

    def _generateOptions(self, ctx=None):
        item = self.itemsCache.items.getItemByCD(self._intCD)
        buyPriceVO = getItemPricesVO(item.getBuyPrice())
        sellPriceVO = getItemPricesVO(item.getSellPrice())
        inventoryCount = self._c11nView.getItemInventoryCount(item)
        availableForSale = inventoryCount > 0 and item.getSellPrice(
        ) != ITEM_PRICE_EMPTY and not item.isRentable and not item.isHidden
        style = self._c11nView.getModifiedStyle()
        removeFromTankEnabled = style.intCD == item.intCD if style is not None else False
        for outfit in (self._c11nView.getModifiedOutfit(season)
                       for season in SeasonType.COMMON_SEASONS):
            if outfit.has(item):
                removeFromTankEnabled = True
                break

        accountMoney = self.itemsCache.items.stats.money
        availableForPurchase = not item.isHidden and not item.getBuyPrice(
        ) == ITEM_PRICE_EMPTY and item.getBuyPrice().price <= accountMoney
        showAlert = len(sellPriceVO[0]) > 1
        tooltipVO = None
        if showAlert:
            tooltipVO = packActionTooltipData(
                ACTION_TOOLTIPS_TYPE.ITEM, str(item.intCD), False,
                item.sellPrices.getSum().price,
                item.sellPrices.getSum().defPrice)
            price = sellPriceVO[0]['price']
            sellPriceVO[0] = {}
            sellPriceVO[0]['price'] = price
        return [
            self._makeItem(
                CustomizationOptions.BUY,
                MENU.cst_item_ctx_menu(CustomizationOptions.BUY), {
                    'data': {
                        'price': first(buyPriceVO)
                    } if availableForPurchase else None,
                    'enabled': availableForPurchase
                }, None, 'CurrencyContextMenuItem'),
            self._makeSeparator(),
            self._makeItem(
                CustomizationOptions.SELL,
                MENU.cst_item_ctx_menu(CustomizationOptions.SELL), {
                    'data': {
                        'price': first(sellPriceVO)
                    } if availableForSale else None,
                    'enabled': availableForSale,
                    'showAlert': showAlert,
                    'tooltipVO': tooltipVO
                }, None, 'CurrencyContextMenuItem'),
            self._makeSeparator(),
            self._makeItem(
                CustomizationOptions.REMOVE_FROM_TANK,
                MENU.cst_item_ctx_menu(CustomizationOptions.REMOVE_FROM_TANK),
                {'enabled': removeFromTankEnabled})
        ]

    def _initFlashValues(self, ctx):
        self._intCD = ctx.itemID
Пример #31
0
class _ItemsCache(object):
    def __init__(self):
        self.__items = ItemsRequester()
        self.__waitForSync = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()

    def init(self):
        g_playerEvents.onInventoryResync += self.__pe_onInventoryResync
        g_playerEvents.onDossiersResync += self.__pe_onDossiersResync
        g_playerEvents.onStatsResync += self.__pe_onStatsResync
        g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected
        g_playerEvents.onStatsResync -= self.__pe_onStatsResync
        g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync
        g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def items(self):
        return self.__items

    @async
    def update(self, updateReason, diff=None, callback=None):
        if diff is None:
            self.__invalidateFullData(updateReason, callback)
        else:
            self.__invalidateData(updateReason, diff, callback)

    def clear(self):
        LOG_DEBUG('Clearing items cache.')
        return self.items.clear()

    def _onResync(self, reason):
        if not self.__waitForSync:
            self.__invalidateFullData(reason)

    def _onCenterIsLongDisconnected(self, isLongDisconnected):
        self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected)

    def __invalidateData(self,
                         updateReason,
                         diff,
                         callback=lambda *args: None):
        self.__waitForSync = True
        self.onSyncStarted()
        if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC:
            invalidItems = self.__items.invalidateCache(diff)
        else:
            invalidItems = {}

        def cbWrapper(*args):
            self.__waitForSync = False
            self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def __invalidateFullData(self, updateReason, callback=lambda *args: None):
        self.__waitForSync = True
        self.onSyncStarted()

        def cbWrapper(*args):
            self.__waitForSync = False
            if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC:
                invalidItems = self.__items.invalidateCache()
            else:
                invalidItems = {}
            self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def isSynced(self):
        return self.items.isSynced()

    def __pe_onStatsResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.STATS_RESYNC)

    def __pe_onInventoryResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC)

    def __pe_onDossiersResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
Пример #32
0
class ServerSettings(object):
    def __init__(self, serverSettings):
        self.onServerSettingsChange = Event()
        self.set(serverSettings)

    def set(self, serverSettings):
        self.__serverSettings = copy.deepcopy(
            serverSettings) if serverSettings else {}
        if 'roaming' in self.__serverSettings:
            roamingSettings = self.__serverSettings['roaming']
            self.__roamingSettings = RoamingSettings(
                roamingSettings[0], roamingSettings[1],
                [_ServerInfo(*s) for s in roamingSettings[2]])
        else:
            self.__roamingSettings = RoamingSettings.defaults()
        if 'file_server' in self.__serverSettings:
            self.__fileServerSettings = _FileServerSettings(
                self.__serverSettings['file_server'])
        else:
            self.__fileServerSettings = _FileServerSettings.defaults()
        if 'regional_settings' in self.__serverSettings:
            self.__regionalSettings = makeTupleByDict(
                _RegionalSettings, self.__serverSettings['regional_settings'])
        else:
            self.__regionalSettings = _RegionalSettings.defaults()
        try:
            self.__eSportCurrentSeason = makeTupleByDict(
                _ESportCurrentSeason, self.__serverSettings)
        except TypeError:
            self.__eSportCurrentSeason = _ESportCurrentSeason.defaults()

        if 'wgcg' in self.__serverSettings:
            self.__updateWgcg(self.__serverSettings)
        else:
            self.__wgcg = _Wgcg.defaults()
        if 'clanProfile' in self.__serverSettings:
            self.__updateClanProfile(self.__serverSettings)
        else:
            self.__clanProfile = _ClanProfile.defaults()
        if 'spgRedesignFeatures' in self.__serverSettings:
            self.__spgRedesignFeatures = makeTupleByDict(
                _SpgRedesignFeatures,
                self.__serverSettings['spgRedesignFeatures'])
        else:
            self.__spgRedesignFeatures = _SpgRedesignFeatures.defaults()
        if 'strongholdSettings' in self.__serverSettings:
            settings = self.__serverSettings['strongholdSettings']
            self.__strongholdSettings = _StrongholdSettings(
                settings.get('wgshHostUrl', ''))
        else:
            self.__strongholdSettings = _StrongholdSettings.defaults()
        if 'frontlineSettings' in self.__serverSettings:
            settings = self.__serverSettings['frontlineSettings']
            self.__frontlineSettings = _FrontlineSettings(
                settings.get('flHostUrl', ''))
        else:
            self.__frontlineSettings = _FrontlineSettings.defaults()
        if 'rankedBattles' in self.__serverSettings:
            self.__bwRankedBattles = makeTupleByDict(
                _BwRankedBattles, self.__serverSettings['rankedBattles'])
        else:
            self.__bwRankedBattles = _BwRankedBattles.defaults()
        if 'hallOfFame' in self.__serverSettings:
            self.__bwHallOfFame = makeTupleByDict(
                _BwHallOfFame, self.__serverSettings['hallOfFame'])
        else:
            self.__bwHallOfFame = _BwHallOfFame.defaults()
        if 'ranked_config' in self.__serverSettings:
            self.__rankedBattlesSettings = makeTupleByDict(
                _RankedBattlesConfig, self.__serverSettings['ranked_config'])
        else:
            self.__rankedBattlesSettings = _RankedBattlesConfig.defaults()
        if 'wgm_offline_emergency_config' in self.__serverSettings:
            self.__wgmOfflineEmergencyConfig = makeTupleByDict(
                _WGMoneyOfflineEmergencyConfig,
                self.__serverSettings['wgm_offline_emergency_config'])
        else:
            self.__wgmOfflineEmergencyConfig = _WGMoneyOfflineEmergencyConfig.defaults(
            )
        if 'epic_config' in self.__serverSettings:
            LOG_DEBUG('epic_config', self.__serverSettings['epic_config'])
            self.__epicMetaGameSettings = makeTupleByDict(
                _EpicMetaGameConfig,
                self.__serverSettings['epic_config']['epicMetaGame'])
            self.__epicGameSettings = makeTupleByDict(
                _EpicGameConfig, self.__serverSettings['epic_config'])
        else:
            self.__epicMetaGameSettings = _EpicMetaGameConfig()
            self.__epicGameSettings = _EpicGameConfig()
        if 'telecom_config' in self.__serverSettings:
            self.__telecomConfig = _TelecomConfig(
                self.__serverSettings['telecom_config'])
        else:
            self.__telecomConfig = _TelecomConfig.defaults()
        self.onServerSettingsChange(serverSettings)

    def update(self, serverSettingsDiff):
        self.__serverSettings = updateDict(self.__serverSettings,
                                           serverSettingsDiff)
        if 'clanProfile' in serverSettingsDiff:
            self.__updateClanProfile(serverSettingsDiff)
        if 'spgRedesignFeatures' in self.__serverSettings:
            self.__spgRedesignFeatures = makeTupleByDict(
                _SpgRedesignFeatures,
                self.__serverSettings['spgRedesignFeatures'])
        if 'ranked_config' in serverSettingsDiff:
            self.__updateRanked(serverSettingsDiff)
        if 'hallOfFame' in serverSettingsDiff:
            self.__bwHallOfFame = makeTupleByDict(
                _BwHallOfFame, serverSettingsDiff['hallOfFame'])
        if 'wgcg' in serverSettingsDiff:
            self.__updateWgcg(serverSettingsDiff)
        if 'wgm_offline_emergency_config' in serverSettingsDiff:
            self.__wgmOfflineEmergencyConfig = makeTupleByDict(
                _WGMoneyOfflineEmergencyConfig,
                serverSettingsDiff['wgm_offline_emergency_config'])
        if 'epic_config' in serverSettingsDiff:
            self.__updateEpic(serverSettingsDiff)
        if 'telecom_config' in serverSettingsDiff:
            self.__telecomConfig = _TelecomConfig(
                self.__serverSettings['telecom_config'])
        self.onServerSettingsChange(serverSettingsDiff)

    def clear(self):
        self.onServerSettingsChange.clear()

    def getSettings(self):
        return self.__serverSettings

    @property
    def roaming(self):
        return self.__roamingSettings

    @property
    def fileServer(self):
        return self.__fileServerSettings

    @property
    def regionals(self):
        return self.__regionalSettings

    @property
    def eSportCurrentSeason(self):
        return self.__eSportCurrentSeason

    @property
    def clanProfile(self):
        return self.__clanProfile

    @property
    def wgcg(self):
        return self.__wgcg

    @property
    def spgRedesignFeatures(self):
        return self.__spgRedesignFeatures

    @property
    def stronghold(self):
        return self.__strongholdSettings

    @property
    def frontline(self):
        return self.__frontlineSettings

    @property
    def bwRankedBattles(self):
        return self.__bwRankedBattles

    @property
    def bwHallOfFame(self):
        return self.__bwHallOfFame

    @property
    def rankedBattles(self):
        return self.__rankedBattlesSettings

    @property
    def wgmOfflineEmergency(self):
        return self.__wgmOfflineEmergencyConfig

    @property
    def epicMetaGame(self):
        return self.__epicMetaGameSettings

    @property
    def epicBattles(self):
        return self.__epicGameSettings

    @property
    def telecomConfig(self):
        return self.__telecomConfig

    def isEpicBattleEnabled(self):
        return self.epicBattles.enabled > 0

    def isPersonalMissionsEnabled(self):
        return self.isRegularQuestEnabled()

    def isRegularQuestEnabled(self):
        return self.__getGlobalSetting('isRegularQuestEnabled', True)

    def isStrongholdsEnabled(self):
        return self.__getGlobalSetting('strongholdSettings',
                                       {}).get('isStrongholdsEnabled', False)

    def isLeaguesEnabled(self):
        return self.__getGlobalSetting('strongholdSettings',
                                       {}).get('isLeaguesEnabled', False)

    def isElenEnabled(self):
        return self.__getGlobalSetting('elenSettings',
                                       {}).get('isElenEnabled', True)

    def elenUpdateInterval(self):
        return self.__getGlobalSetting('elenSettings',
                                       {}).get('elenUpdateInterval', 60)

    def isGoldFishEnabled(self):
        return self.__getGlobalSetting('isGoldFishEnabled', False)

    def isTutorialEnabled(self):
        return self.__getGlobalSetting('isTutorialEnabled',
                                       IS_TUTORIAL_ENABLED)

    def isSandboxEnabled(self):
        return self.__getGlobalSetting('isSandboxEnabled', False)

    def isBootcampEnabled(self):
        return self.__getGlobalSetting('isBootcampEnabled', False)

    def isEpicRandomEnabled(self):
        return self.__getGlobalSetting('isEpicRandomEnabled', False)

    def isEpicRandomAchievementsEnabled(self):
        return self.__getGlobalSetting('isEpicRandomAchievementsEnabled',
                                       False)

    def isEpicRandomMarkOfMasteryEnabled(self):
        return self.__getGlobalSetting('isEpicRandomMarkOfMasteryEnabled',
                                       False)

    def isEpicRandomMarksOnGunEnabled(self):
        return self.__getGlobalSetting('isEpicRandomMarksOnGunEnabled', False)

    def isPromoAutoViewsEnabled(self):
        if self.isBootcampEnabled():
            from bootcamp.Bootcamp import g_bootcamp
            if g_bootcamp.isRunning():
                return False
        return True

    def isHofEnabled(self):
        return self.__getGlobalSetting('hallOfFame',
                                       {}).get('isHofEnabled', False)

    def getMaxSPGinSquads(self):
        return self.__getGlobalSetting('maxSPGinSquads', 0)

    def getRandomMapsForDemonstrator(self):
        return self.__getGlobalSetting('randomMapsForDemonstrator', {})

    def isPremiumInPostBattleEnabled(self):
        return self.__getGlobalSetting('isPremiumInPostBattleEnabled', True)

    def isVehicleComparingEnabled(self):
        return bool(self.__getGlobalSetting('isVehiclesCompareEnabled', True))

    def isEncyclopediaEnabled(self, tokensCount):
        switchState = self.__getGlobalSetting('isEncyclopediaEnabled')
        if switchState == SWITCH_STATE.ALL:
            state = True
        elif switchState == SWITCH_STATE.NONE:
            state = False
        elif switchState == SWITCH_STATE.TOKEN:
            state = tokensCount > 0
        else:
            LOG_ERROR(
                'Wrong activation state for encyclopedia. Encyclopedia is considered to be disabled'
            )
            state = False
        return state

    def isTankmanRestoreEnabled(self):
        return self.__getGlobalSetting('isTankmanRestoreEnabled', True)

    def isVehicleRestoreEnabled(self):
        return self.__getGlobalSetting('isVehicleRestoreEnabled', True)

    def isCustomizationEnabled(self):
        return self.__getGlobalSetting('isCustomizationEnabled', True)

    def getHeroVehicles(self):
        return self.__getGlobalSetting('hero_vehicles', {})

    def __getGlobalSetting(self, settingsName, default=None):
        return self.__serverSettings.get(settingsName, default)

    def __updateClanProfile(self, targetSettings):
        cProfile = targetSettings['clanProfile']
        self.__clanProfile = _ClanProfile(cProfile.get('isEnabled', False))

    def __updateWgcg(self, targetSettings):
        cProfile = targetSettings['wgcg']
        self.__wgcg = _Wgcg(cProfile.get('isEnabled', False),
                            cProfile.get('gateUrl', ''),
                            cProfile.get('type', 'gateway'),
                            cProfile.get('loginOnStart', False))

    def __updateRanked(self, targetSettings):
        self.__rankedBattlesSettings = self.__rankedBattlesSettings.replace(
            targetSettings['ranked_config'])

    def __updateEpic(self, targetSettings):
        self.__epicMetaGameSettings = self.__epicMetaGameSettings.replace(
            targetSettings['epic_config'])
        self.__epicGameSettings = self.__epicGameSettings.replace(
            targetSettings['epic_config'])
Пример #33
0
class DetailedEngineState(assembly_utility.Component):
    rpm = property(lambda self: self._rpm)
    gearNum = property(lambda self: self._gearNum)
    gearUp = property(lambda self: self._gearUp)
    mode = property(lambda self: self._mode)
    starting = property(lambda self: self.__starting)
    physicLoad = property(lambda self: self._physicLoad)
    relativeSpeed = property(lambda self: self._relativeSpeed)
    engineLoad = property(lambda self: self._engineLoad)
    roughnessValue = property(lambda self: self._roughnessValue)
    relativeRPM = property(lambda self: self._reativelRPM)
    _STOPPED = 0
    _IDLE = 1
    _MEDIUM = 2
    _HIGH = 3

    def __init__(self):
        self._rpm = 0.0
        self._reativelRPM = 0.0
        self._gearNum = 0
        self._mode = DetailedEngineState._STOPPED
        self.__starting = False
        self._gearUp = False
        self._physicLoad = 0.0
        self._relativeSpeed = 0.0
        self._maxClimbAngle = math.radians(20.0)
        self._engineLoad = self._STOPPED
        self._vehicle = None
        self._gearUpCbk = None
        self.__startEngineCbk = None
        self.__prevArenaPeriod = BigWorld.player().arena.period
        self.onEngineStart = Event()
        if self.__prevArenaPeriod == ARENA_PERIOD.BATTLE or self.__prevArenaPeriod == ARENA_PERIOD.PREBATTLE:
            self.__startEngineCbk = BigWorld.callback(0.1, self.__startEngineFunc)
        BigWorld.player().arena.onPeriodChange += self.__arenaPeriodChanged
        return

    def destroy(self):
        BigWorld.player().arena.onPeriodChange -= self.__arenaPeriodChanged
        if self.__startEngineCbk is not None:
            BigWorld.cancelCallback(self.__startEngineCbk)
        self._vehicle = None
        self._gearUpCbk = None
        self.onEngineStart.clear()
        self.onEngineStart = None
        return

    def __arenaPeriodChanged(self, *args):
        period = BigWorld.player().arena.period
        if period != self.__prevArenaPeriod and period == ARENA_PERIOD.PREBATTLE:
            self._mode = DetailedEngineState._STOPPED
            self.__prevArenaPeriod = period
            maxTime = BigWorld.player().arena.periodEndTime - BigWorld.serverTime()
            maxTime = maxTime * 0.7 if maxTime > 0.0 else 1.0
            time = uniform(0.0, maxTime)
            self.__startEngineCbk = BigWorld.callback(time, self.__startEngineFunc)
        elif period == ARENA_PERIOD.BATTLE:
            if self.__startEngineCbk is None and self._mode == DetailedEngineState._STOPPED:
                self.onEngineStart()
            self.__starting = False
        return

    def __startEngineFunc(self):
        self.__startEngineCbk = None
        self.__starting = True
        self._mode = DetailedEngineState._IDLE
        self.onEngineStart()
        return

    def setMode(self, mode):
        if mode > DetailedEngineState._STOPPED:
            if self._mode == DetailedEngineState._STOPPED:
                self.__starting = True
            else:
                self.__starting = False
        else:
            self.__starting = False
        self._mode = mode

    def start(self, vehicle):
        self._vehicle = vehicle
        self._maxClimbAngle = math.acos(self._vehicle.typeDescriptor.physics['minPlaneNormalY'])

    def refresh(self, delta):
        vehicleTypeDescriptor = self._vehicle.typeDescriptor
        vehicleSpeed = self._vehicle.speedInfo.value[0]
        if vehicleSpeed > 0.0:
            self._relativeSpeed = vehicleSpeed / vehicleTypeDescriptor.physics['speedLimits'][0]
        else:
            self._relativeSpeed = vehicleSpeed / vehicleTypeDescriptor.physics['speedLimits'][1]

    def setGearUpCallback(self, gearUpCbk):
        self._gearUpCbk = gearUpCbk

    def delGearUpCallback(self):
        self._gearUpCbk = None
        return
Пример #34
0
class _CurrentVehicle():

    def __init__(self):
        self.__vehInvID = 0
        self.__changeCallbackID = None
        self.__historicalBattle = None
        self.onChanged = Event()
        self.onChangeStarted = Event()
        return

    def init(self):
        g_clientUpdateManager.addCallbacks({'inventory': self.onInventoryUpdate,
         'cache.vehsLock': self.onLocksUpdate})
        game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged
        game_control.g_instance.rentals.onRentChangeNotify += self.onRentChange
        prbVehicle = self.__checkPrebattleLockedVehicle()
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        self.selectVehicle(prbVehicle or storedVehInvID)

    def destroy(self):
        self.__vehInvID = 0
        self.__clearChangeCallback()
        self.onChanged.clear()
        self.onChangeStarted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)
        game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged
        game_control.g_instance.rentals.onRentChangeNotify -= self.onRentChange
        g_hangarSpace.removeVehicle()
        self.selectNoVehicle()

    def onIgrTypeChanged(self, *args):
        if self.isPremiumIGR():
            self.onChanged()
        self.refreshModel()

    def onRentChange(self, vehicles):
        if self.isPresent():
            if self.item.intCD in vehicles:
                self.onChanged()

    def onInventoryUpdate(self, invDiff):
        vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {})
        isVehicleSold = False
        isVehicleDescrChanged = False
        if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']:
            isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None
            isVehicleDescrChanged = not isVehicleSold
        if isVehicleSold or self.__vehInvID == 0:
            self.selectVehicle()
        else:
            isRepaired = 'repair' in vehsDiff and self.__vehInvID in vehsDiff['repair']
            isCustomizationChanged = 'igrCustomizationLayout' in vehsDiff and self.__vehInvID in vehsDiff['igrCustomizationLayout']
            isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff
            isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive or (self.__vehInvID, '_r') in hive, vehsDiff.itervalues())) > 0
            if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged:
                self.refreshModel()
            if isVehicleChanged or isRepaired:
                self.onChanged()
        return

    def onLocksUpdate(self, locksDiff):
        if self.__vehInvID in locksDiff:
            self.refreshModel()

    def refreshModel(self):
        if self.isPresent() and self.isInHangar() and self.item.modelState:
            if self.__historicalBattle is not None:
                historical = g_tankActiveCamouflage['historical']
                if self.__historicalBattle.canParticipateWith(self.item.intCD) and self.item.intCD not in historical:
                    historical[self.item.intCD] = self.__historicalBattle.getArenaType().vehicleCamouflageKind
            if self.item.intCD not in g_tankActiveCamouflage:
                availableKinds = []
                currKind = 0
                for id, startTime, days in self.item.descriptor.camouflages:
                    if id is not None:
                        availableKinds.append(currKind)
                    currKind += 1

                if len(availableKinds) > 0:
                    g_tankActiveCamouflage[self.item.intCD] = random.choice(availableKinds)
            g_hangarSpace.updateVehicle(self.item, self.__historicalBattle)
        else:
            g_hangarSpace.removeVehicle()
        return

    @property
    def invID(self):
        return self.__vehInvID

    @property
    def item(self):
        if self.__vehInvID > 0:
            return g_itemsCache.items.getVehicle(self.__vehInvID)
        else:
            return None

    def isPresent(self):
        return self.item is not None

    def isBroken(self):
        return self.isPresent() and self.item.isBroken

    def isDisabledInRoaming(self):
        return self.isPresent() and self.item.isDisabledInRoaming

    def isLocked(self):
        return self.isPresent() and self.item.isLocked

    def isClanLock(self):
        return self.isPresent() and self.item.clanLock > 0

    def isCrewFull(self):
        return self.isPresent() and self.item.isCrewFull

    def isDisabledInRent(self):
        return self.isPresent() and self.item.rentalIsOver and self.item.isRented

    def isDisabledInPremIGR(self):
        return self.isPresent() and self.item.isDisabledInPremIGR

    def isPremiumIGR(self):
        return self.isPresent() and self.item.isPremiumIGR

    def isInPrebattle(self):
        return self.isPresent() and self.item.isInPrebattle

    def isInBattle(self):
        return self.isPresent() and self.item.isInBattle

    def isInHangar(self):
        return self.isPresent() and not self.item.isInBattle

    def isAwaitingBattle(self):
        return self.isPresent() and self.item.isAwaitingBattle

    def isAlive(self):
        return self.isPresent() and self.item.isAlive

    def isReadyToPrebattle(self):
        return self.isPresent() and self.item.isReadyToPrebattle

    def isReadyToFight(self):
        return self.isPresent() and self.item.isReadyToFight

    def isAutoLoadFull(self):
        if self.isPresent() and self.item.isAutoLoad:
            for shell in self.item.shells:
                if shell.count != shell.defaultCount:
                    return False

        return True

    def isAutoEquipFull(self):
        if self.isPresent() and self.item.isAutoEquip:
            for i, e in enumerate(self.item.eqsLayout):
                if e != self.item.eqs[i]:
                    return False

        return True

    def selectVehicle(self, vehInvID = 0):
        vehicle = g_itemsCache.items.getVehicle(vehInvID)
        if vehicle is None:
            invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY)
            if len(invVehs):
                vehInvID = sorted(invVehs.itervalues())[0].invID
            else:
                vehInvID = 0
        self.__selectVehicle(vehInvID)
        return

    def selectNoVehicle(self):
        self.__selectVehicle(0)

    def getHangarMessage(self):
        if self.isPresent():
            state, stateLvl = self.item.getState()
            if state == Vehicle.VEHICLE_STATE.IN_PREMIUM_IGR_ONLY:
                localization = '#menu:vehicle/igrRentLeft/%s'
                rentLeftStr = getRentLeftTimeStr(localization, self.item.rentLeftTime)
                icon = TextManager.getIcon(TextIcons.PREMIUM_IGR_BIG)
                if self.item.isRented:
                    message = i18n.makeString('#menu:currentVehicleStatus/' + state, icon=icon, time=rentLeftStr)
                else:
                    message = i18n.makeString('#menu:tankCarousel/vehicleStates/inPremiumIgrOnly', icon=icon)
                return (state, message, stateLvl)
            return (state, '#menu:currentVehicleStatus/' + state, stateLvl)
        return ('notpresent', MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL)

    def setHistoricalBattle(self, historicalBattle):
        g_tankActiveCamouflage['historical'] = {}
        self.__historicalBattle = historicalBattle
        self.refreshModel()
        self.onChanged()

    def __selectVehicle(self, vehInvID):
        if vehInvID == self.__vehInvID:
            return
        Waiting.show('updateCurrentVehicle', isSingle=True)
        self.onChangeStarted()
        self.__vehInvID = vehInvID
        AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID)
        self.refreshModel()
        if not self.__changeCallbackID:
            self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone)

    def __changeDone(self):
        self.__clearChangeCallback()
        if isPlayerAccount():
            self.onChanged()
        Waiting.hide('updateCurrentVehicle')

    def __clearChangeCallback(self):
        if self.__changeCallbackID is not None:
            BigWorld.cancelCallback(self.__changeCallbackID)
            self.__changeCallbackID = None
        return

    def __checkPrebattleLockedVehicle(self):
        clientPrb = prb_control.getClientPrebattle()
        if clientPrb is not None:
            rosters = prb_control.getPrebattleRosters(prebattle=clientPrb)
            for rId, roster in rosters.iteritems():
                if BigWorld.player().id in roster:
                    vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '')
                    if len(vehCompDescr):
                        vehDescr = vehicles.VehicleDescr(vehCompDescr)
                        vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr)
                        if vehicle is not None:
                            return vehicle.invID

        return 0

    def __repr__(self):
        return 'CurrentVehicle(%s)' % str(self.item)
Пример #35
0
class _ClanCache(object):

    def __init__(self):
        self.__waitForSync = False
        self.__fortProvider = ClientFortProvider()
        self.__clanMembersLen = None
        self.__clanMotto = ''
        self.__clanDescription = ''
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()
        return

    def init(self):
        pass

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()

    def onAccountShowGUI(self):
        self.__startFortProvider()

    def onAvatarBecomePlayer(self):
        self.__stopFortProvider()

    def onDisconnected(self):
        self.__stopFortProvider()

    @property
    def waitForSync(self):
        return self.__waitForSync

    @async
    def update(self, diff = None, callback = None):
        self.__invalidateData(diff, callback)

    def clear(self):
        pass

    @storage_getter('users')
    def usersStorage(self):
        return None

    @property
    def fortProvider(self):
        return self.__fortProvider

    @property
    def clanDBID(self):
        from gui.shared import g_itemsCache
        return g_itemsCache.items.stats.clanDBID

    @property
    def isInClan(self):
        """
        @return: is current player in clan
        """
        return self.clanDBID is not None and self.clanDBID != 0

    @property
    def clanMembers(self):
        members = set()
        if self.isInClan:
            members = set(self.usersStorage.getClanMembersIterator(False))
        return members

    @property
    def clanInfo(self):
        from gui.shared import g_itemsCache
        info = g_itemsCache.items.stats.clanInfo
        if info and len(info) > 1:
            return info
        else:
            return (None, None, -1, 0, 0)

    @property
    def clanName(self):
        return passCensor(html.escape(self.clanInfo[0]))

    @property
    def clanAbbrev(self):
        return self.clanInfo[1]

    @property
    def clanMotto(self):
        return self.__clanMotto

    @property
    def clanDescription(self):
        return self.__clanDescription

    @property
    def clanTag(self):
        result = self.clanAbbrev
        if result:
            return '[%s]' % result
        return result

    @property
    def clanCommanderName(self):
        for member in self.clanMembers:
            if member.getClanRole() == CLAN_MEMBER_FLAGS.LEADER:
                return member.getName()

        return None

    @property
    def clanRole(self):
        user = self.usersStorage.getUser(getAccountDatabaseID())
        if user:
            role = user.getClanRole()
        else:
            role = 0
        return role

    @property
    def isClanLeader(self):
        return self.clanRole == CLAN_MEMBER_FLAGS.LEADER

    @async
    @process
    def getClanEmblemID(self, callback):
        clanEmblem = None
        if self.isInClan:
            tID = 'clanInfo' + BigWorld.player().name
            clanEmblem = yield self.getClanEmblemTextureID(self.clanDBID, False, tID)
        callback(clanEmblem)
        return

    @async
    def getFileFromServer(self, clanId, fileType, callback):
        if not BigWorld.player().serverSettings['file_server'].has_key(fileType):
            LOG_ERROR("Invalid server's file type: %s" % fileType)
            self._valueResponse(0, (None, None), callback)
            return None
        else:
            clan_emblems = BigWorld.player().serverSettings['file_server'][fileType]
            BigWorld.player().customFilesCache.get(clan_emblems['url_template'] % clanId, lambda url, file: self._valueResponse(0, (url, file), callback), True)
            return None

    @async
    @process
    def getClanEmblemTextureID(self, clanDBID, isBig, textureID, callback):
        import imghdr
        if clanDBID is not None and clanDBID != 0:
            _, clanEmblemFile = yield self.getFileFromServer(clanDBID, 'clan_emblems_small' if not isBig else 'clan_emblems_big')
            if clanEmblemFile and imghdr.what(None, clanEmblemFile) is not None:
                BigWorld.wg_addTempScaleformTexture(textureID, clanEmblemFile)
                callback(textureID)
                return
        callback(None)
        return

    def getClanRoleUserString(self):
        position = self.clanInfo[3]
        return getClanRoleString(position)

    def onClanInfoReceived(self, clanDBID, clanName, clanAbbrev, clanMotto, clanDescription):
        self.__clanMotto = passCensor(html.escape(clanMotto))
        self.__clanDescription = passCensor(html.escape(clanDescription))

    def _valueResponse(self, resID, value, callback):
        if resID < 0:
            LOG_ERROR('[class %s] There is error while getting data from cache: %s[%d]' % (self.__class__.__name__, code2str(resID), resID))
            return callback(value)
        callback(value)

    def _onResync(self):
        if not self.__waitForSync:
            self.__invalidateData()

    def __invalidateData(self, diff = None, callback = lambda *args: None):
        if diff is not None:
            if 'stats' in diff and 'clanInfo' in diff['stats']:
                self.__fortProvider.resetState()
        callback(True)
        return

    def __startFortProvider(self):
        self.__clanMembersLen = len(self.clanMembers)
        g_messengerEvents.users.onClanMembersListChanged += self.__me_onClanMembersListChanged
        self.__fortProvider.start(self)

    def __stopFortProvider(self):
        self.__clanMembersLen = None
        g_messengerEvents.users.onClanMembersListChanged -= self.__me_onClanMembersListChanged
        self.__fortProvider.stop()
        return

    def __me_onClanMembersListChanged(self):
        clanMembersLen = len(self.clanMembers)
        if self.__clanMembersLen is not None and clanMembersLen != self.__clanMembersLen:
            self.__clanMembersLen = clanMembersLen
            self.__fortProvider.resetState()
        self.__fortProvider.notify('onClanMembersListChanged')
        return
Пример #36
0
class _ItemsCache(object):

    def __init__(self):
        self.__items = ItemsRequester()
        self.__waitForSync = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()

    def init(self):
        g_playerEvents.onInventoryResync += self.__pe_onInventoryResync
        g_playerEvents.onDossiersResync += self.__pe_onDossiersResync
        g_playerEvents.onStatsResync += self.__pe_onStatsResync
        g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected
        g_playerEvents.onStatsResync -= self.__pe_onStatsResync
        g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync
        g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def items(self):
        return self.__items

    @async
    def update(self, updateReason, diff = None, callback = None):
        if diff is None:
            self.__invalidateFullData(updateReason, callback)
        else:
            self.__invalidateData(updateReason, diff, callback)

    def clear(self):
        LOG_DEBUG('Clearing items cache.')
        return self.items.clear()

    def _onResync(self, reason):
        if not self.__waitForSync:
            self.__invalidateFullData(reason)

    def _onCenterIsLongDisconnected(self, isLongDisconnected):
        self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected)

    def __invalidateData(self, updateReason, diff, callback = lambda *args: None):
        self.__waitForSync = True
        self.onSyncStarted()
        if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC:
            invalidItems = self.__items.invalidateCache(diff)
        else:
            invalidItems = {}

        def cbWrapper(*args):
            self.__waitForSync = False
            self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def __invalidateFullData(self, updateReason, callback = lambda *args: None):
        self.__waitForSync = True
        self.onSyncStarted()

        def cbWrapper(*args):
            self.__waitForSync = False
            if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC:
                invalidItems = self.__items.invalidateCache()
            else:
                invalidItems = {}
            self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def isSynced(self):
        return self.items.isSynced()

    def __pe_onStatsResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.STATS_RESYNC)

    def __pe_onInventoryResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC)

    def __pe_onDossiersResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
Пример #37
0
class ContainerManager(ContainerManagerMeta):
    __DESTROY_ORDER = (ViewTypes.DEFAULT,
     ViewTypes.LOBBY_SUB,
     ViewTypes.WINDOW,
     ViewTypes.BROWSER,
     ViewTypes.TOP_WINDOW,
     ViewTypes.WAITING,
     ViewTypes.CURSOR,
     ViewTypes.SERVICE_LAYOUT)
    __CONTAINERS_TO_CLEAR = (ViewTypes.WINDOW, ViewTypes.BROWSER, ViewTypes.TOP_WINDOW)

    def __init__(self, loader):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {ViewTypes.DEFAULT: _DefaultContainer(proxy),
         ViewTypes.CURSOR: _DefaultContainer(proxy),
         ViewTypes.WAITING: _DefaultContainer(proxy),
         ViewTypes.WINDOW: _PopUpContainer(proxy),
         ViewTypes.BROWSER: _PopUpContainer(proxy),
         ViewTypes.TOP_WINDOW: _PopUpContainer(proxy),
         ViewTypes.SERVICE_LAYOUT: _DefaultContainer(proxy)}
        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name = None, *args, **kwargs):
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if len(result) > 0:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity
        return

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop((curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False
            return

    def addContainer(self, containerType, name, container = None):
        result = True
        if containerType not in self.__containers:
            if container is None:
                self.__containers[containerType] = _DefaultContainer(weakref.proxy(self))
                self.as_registerContainerS(containerType, name)
            elif isinstance(container, IViewContainer):
                self.__containers[containerType] = container
                self.as_registerContainerS(containerType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer', container)
                result = False
        else:
            LOG_ERROR('Container already registered', containerType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]
        else:
            return None

    def isModalViewsIsExists(self):
        if self.getContainer(ViewTypes.TOP_WINDOW).getViewCount(isModal=True) > 0:
            return True
        elif self.getContainer(ViewTypes.BROWSER).getViewCount(isModal=True) > 0:
            return True
        else:
            return self.getContainer(ViewTypes.WINDOW).getViewCount(isModal=True) > 0

    def getView(self, viewType, criteria = None):
        view = None
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria = None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False
            return

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for c in self.__CONTAINERS_TO_CLEAR:
            self.getContainer(c).clear()

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in self.__DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: ' + str(container) + '/' + viewType)
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()
        return

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG('"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView))
        return
Пример #38
0
class AvatarInputHandler(CallbackDelayer, ComponentSystem):
    bootcampCtrl = dependency.descriptor(IBootcampController)
    ctrl = property(lambda self: self.__curCtrl)
    ctrls = property(lambda self: self.__ctrls)
    isSPG = property(lambda self: self.__isSPG)
    isATSPG = property(lambda self: self.__isATSPG)
    isFlashBangAllowed = property(lambda self: self.__ctrls['video'] != self.__curCtrl)
    isDetached = property(lambda self: self.__isDetached)
    isGuiVisible = property(lambda self: self.__isGUIVisible)
    isStarted = property(lambda self: self.__isStarted)
    isObserverFPV = property(lambda self: BigWorld.player().isObserver() and BigWorld.player().isObserverFPV)
    remoteCameraSender = property(lambda self: self.__remoteCameraSender)
    __ctrlModeName = aih_global_binding.bindRW(_BINDING_ID.CTRL_MODE_NAME)
    __aimOffset = aih_global_binding.bindRW(_BINDING_ID.AIM_OFFSET)
    _DYNAMIC_CAMERAS_ENABLED_KEY = 'global/dynamicCameraEnabled'
    settingsCore = dependency.descriptor(ISettingsCore)

    @staticmethod
    def enableDynamicCamera(enable, useHorizontalStabilizer=True):
        for dynamicCameraClass in _DYNAMIC_CAMERAS:
            dynamicCameraClass.enableDynamicCamera(enable)

        SniperAimingSystem.setStabilizerSettings(useHorizontalStabilizer, True)

    @staticmethod
    def isCameraDynamic():
        for dynamicCameraClass in _DYNAMIC_CAMERAS:
            if not dynamicCameraClass.isCameraDynamic():
                return False

        return True

    @staticmethod
    def isSniperStabilized():
        return SniperAimingSystem.getStabilizerSettings()

    @property
    def ctrlModeName(self):
        return self.__ctrlModeName

    siegeModeControl = ComponentDescriptor()
    siegeModeSoundNotifications = ComponentDescriptor()
    steadyVehicleMatrixCalculator = ComponentDescriptor()

    def __init__(self):
        CallbackDelayer.__init__(self)
        ComponentSystem.__init__(self)
        self.__alwaysShowAimKey = None
        self.__showMarkersKey = None
        sec = self._readCfg()
        self.onCameraChanged = Event()
        self.onPostmortemVehicleChanged = Event()
        self.onPostmortemKillerVisionEnter = Event()
        self.onPostmortemKillerVisionExit = Event()
        self.__isArenaStarted = False
        self.__isStarted = False
        self.__targeting = _Targeting()
        self.__vertScreenshotCamera = _VertScreenshotCamera()
        self.__ctrls = dict()
        self.__killerVehicleID = None
        self.__isAutorotation = True
        self.__prevModeAutorotation = None
        self.__isSPG = False
        self.__isATSPG = False
        self.__setupCtrls(sec)
        self.__curCtrl = self.__ctrls[_CTRLS_FIRST]
        self.__ctrlModeName = _CTRLS_FIRST
        self.__isDetached = False
        self.__waitObserverCallback = None
        self.__observerVehicle = None
        self.__observerIsSwitching = False
        self.__commands = []
        self.__remoteCameraSender = None
        self.__isGUIVisible = False
        return

    def __constructComponents(self):
        player = BigWorld.player()
        if player.vehicleTypeDescriptor.hasSiegeMode:
            if not self.siegeModeControl:
                self.siegeModeControl = SiegeModeControl()
            self.__commands.append(self.siegeModeControl)
            self.siegeModeControl.onSiegeStateChanged += lambda *args: self.steadyVehicleMatrixCalculator.relinkSources()
            self.siegeModeSoundNotifications = SiegeModeSoundNotifications()
            self.siegeModeControl.onSiegeStateChanged += self.siegeModeSoundNotifications.onSiegeStateChanged
            self.siegeModeControl.onRequestFail += self.__onRequestFail
            self.siegeModeControl.onSiegeStateChanged += SiegeModeCameraShaker.shake
        if self.bootcampCtrl.isInBootcamp() and constants.HAS_DEV_RESOURCES:
            self.__commands.append(BootcampModeControl())

    def prerequisites(self):
        out = []
        for ctrl in self.__ctrls.itervalues():
            out += ctrl.prerequisites()

        return out

    def handleKeyEvent(self, event):
        import game
        isDown, key, mods, isRepeat = game.convertKeyEvent(event)
        if isRepeat:
            return False
        elif self.__isStarted and self.__isDetached:
            if self.__curCtrl.alwaysReceiveKeyEvents() and not self.isObserverFPV or CommandMapping.g_instance.isFired(CommandMapping.CMD_CM_LOCK_TARGET, key):
                self.__curCtrl.handleKeyEvent(isDown, key, mods, event)
            return BigWorld.player().handleKey(isDown, key, mods)
        elif not self.__isStarted or self.__isDetached:
            return False
        for command in self.__commands:
            if command.handleKeyEvent(isDown, key, mods, event):
                return True

        if isDown and BigWorld.isKeyDown(Keys.KEY_CAPSLOCK):
            if self.__alwaysShowAimKey is not None and key == self.__alwaysShowAimKey:
                gui_event_dispatcher.toggleCrosshairVisibility()
                return True
            if self.__showMarkersKey is not None and key == self.__showMarkersKey and not self.__isGUIVisible:
                gui_event_dispatcher.toggleMarkers2DVisibility()
                return True
            if key == Keys.KEY_F5 and constants.HAS_DEV_RESOURCES:
                self.__vertScreenshotCamera.enable(not self.__vertScreenshotCamera.isEnabled)
                return True
        if key == Keys.KEY_SPACE and isDown and BigWorld.player().isObserver():
            BigWorld.player().cell.switchObserverFPV(not BigWorld.player().isObserverFPV)
            return True
        else:
            return True if not self.isObserverFPV and self.__curCtrl.handleKeyEvent(isDown, key, mods, event) else BigWorld.player().handleKey(isDown, key, mods)

    def handleMouseEvent(self, dx, dy, dz):
        return False if not self.__isStarted or self.__isDetached else self.__curCtrl.handleMouseEvent(dx, dy, dz)

    def setForcedGuiControlMode(self, flags):
        result = False
        detached = flags & GUI_CTRL_MODE_FLAG.CURSOR_ATTACHED > 0
        if detached ^ self.__isDetached:
            self.__isDetached = detached
            self.__targeting.detach(self.__isDetached)
            if detached:
                g_appLoader.attachCursor(settings.APP_NAME_SPACE.SF_BATTLE, flags=flags)
                result = True
                if flags & GUI_CTRL_MODE_FLAG.AIMING_ENABLED > 0:
                    self.setAimingMode(False, AIMING_MODE.USER_DISABLED)
            else:
                g_appLoader.detachCursor(settings.APP_NAME_SPACE.SF_BATTLE)
                result = True
            self.__curCtrl.setForcedGuiControlMode(detached)
        elif detached:
            g_appLoader.syncCursor(settings.APP_NAME_SPACE.SF_BATTLE, flags=flags)
        return result

    def updateShootingStatus(self, canShoot):
        return None if self.__isDetached else self.__curCtrl.updateShootingStatus(canShoot)

    def getDesiredShotPoint(self, ignoreAimingMode=False):
        return None if self.__isDetached else self.__curCtrl.getDesiredShotPoint(ignoreAimingMode)

    def getMarkerPoint(self):
        point = None
        if self.__ctrlModeName in (_CTRL_MODE.ARCADE, _CTRL_MODE.STRATEGIC, _CTRL_MODE.ARTY):
            AimingSystems.shootInSkyPoint.has_been_called = False
            point = self.getDesiredShotPoint(ignoreAimingMode=True)
            if AimingSystems.shootInSkyPoint.has_been_called:
                point = None
        return point

    def showGunMarker(self, isShown):
        self.__curCtrl.setGunMarkerFlag(isShown, _GUN_MARKER_FLAG.CLIENT_MODE_ENABLED)

    def showGunMarker2(self, isShown):
        if not BattleReplay.isPlaying():
            self.__curCtrl.setGunMarkerFlag(isShown, _GUN_MARKER_FLAG.SERVER_MODE_ENABLED)
            if gun_marker_ctrl.useDefaultGunMarkers():
                self.__curCtrl.setGunMarkerFlag(not isShown, _GUN_MARKER_FLAG.CLIENT_MODE_ENABLED)
            replayCtrl = BattleReplay.g_replayCtrl
            replayCtrl.setUseServerAim(isShown)

    def updateGunMarker(self, pos, direction, size, relaxTime, collData):
        self.__curCtrl.updateGunMarker(_GUN_MARKER_TYPE.CLIENT, pos, direction, size, relaxTime, collData)

    def updateGunMarker2(self, pos, direction, size, relaxTime, collData):
        self.__curCtrl.updateGunMarker(_GUN_MARKER_TYPE.SERVER, pos, direction, size, relaxTime, collData)

    def setAimingMode(self, enable, mode):
        self.__curCtrl.setAimingMode(enable, mode)

    def getAimingMode(self, mode):
        return self.__curCtrl.getAimingMode(mode)

    def setAutorotation(self, bValue):
        if not self.__curCtrl.enableSwitchAutorotationMode():
            return
        elif not BigWorld.player().isOnArena:
            return
        else:
            if self.__isAutorotation != bValue:
                self.__isAutorotation = bValue
                BigWorld.player().enableOwnVehicleAutorotation(self.__isAutorotation)
            self.__prevModeAutorotation = None
            return

    def getAutorotation(self):
        return self.__isAutorotation

    def switchAutorotation(self):
        self.setAutorotation(not self.__isAutorotation)

    def activatePostmortem(self, isRespawn):
        if self.siegeModeSoundNotifications is not None:
            self.siegeModeSoundNotifications = None
        BigWorld.player().autoAim(None)
        for ctlMode in self.__ctrls.itervalues():
            ctlMode.resetAimingMode()

        try:
            params = self.__curCtrl.postmortemCamParams
        except Exception:
            params = None

        onPostmortemActivation = getattr(self.__curCtrl, 'onPostmortemActivation', None)
        if onPostmortemActivation is not None:
            onPostmortemActivation(_CTRL_MODE.POSTMORTEM, postmortemParams=params, bPostmortemDelay=True, respawn=isRespawn)
        else:
            self.onControlModeChanged(_CTRL_MODE.POSTMORTEM, postmortemParams=params, bPostmortemDelay=True, respawn=isRespawn)
        return

    def deactivatePostmortem(self):
        self.onControlModeChanged('arcade')
        arcadeMode = self.__ctrls['arcade']
        arcadeMode.camera.setToVehicleDirection()
        self.__identifySPG()
        self.__constructComponents()

    def setKillerVehicleID(self, killerVehicleID):
        self.__killerVehicleID = killerVehicleID

    def getKillerVehicleID(self):
        return self.__killerVehicleID

    def start(self):
        g_guiResetters.add(self.__onRecreateDevice)
        self.steadyVehicleMatrixCalculator = SteadyVehicleMatrixCalculator()
        self.__identifySPG()
        self.__constructComponents()
        for control in self.__ctrls.itervalues():
            control.create()

        avatar = BigWorld.player()
        if not self.__curCtrl.isManualBind():
            avatar.positionControl.bindToVehicle(True)
        self.__curCtrl.enable()
        tmp = self.__curCtrl.getPreferredAutorotationMode()
        if tmp is not None:
            self.__isAutorotation = tmp
            self.__prevModeAutorotation = True
        else:
            self.__isAutorotation = True
            self.__prevModeAutorotation = None
        avatar.enableOwnVehicleAutorotation(self.__isAutorotation)
        self.__targeting.enable(True)
        self.__isStarted = True
        self.__isGUIVisible = True
        self.__killerVehicleID = None
        arena = avatar.arena
        arena.onPeriodChange += self.__onArenaStarted
        self.settingsCore.onSettingsChanged += self.__onSettingsChanged
        avatar.consistentMatrices.onVehicleMatrixBindingChanged += self.__onVehicleChanged
        self.__onArenaStarted(arena.period)
        if not avatar.isObserver() and arena.hasObservers:
            self.__remoteCameraSender = RemoteCameraSender(self)
        self.onCameraChanged('arcade')
        return

    def stop(self):
        self.__isStarted = False
        import SoundGroups
        SoundGroups.g_instance.changePlayMode(0)
        aih_global_binding.clear()
        for control in self.__ctrls.itervalues():
            control.destroy()

        replayCtrl = BattleReplay.g_replayCtrl
        if replayCtrl.isRecording:
            replayCtrl.setPlayerVehicleID(0)
        if self.__remoteCameraSender is not None:
            self.__remoteCameraSender.destroy()
            self.__remoteCameraSender = None
        self.onCameraChanged.clear()
        self.onCameraChanged = None
        self.onPostmortemVehicleChanged.clear()
        self.onPostmortemVehicleChanged = None
        self.onPostmortemKillerVisionEnter.clear()
        self.onPostmortemKillerVisionEnter = None
        self.onPostmortemKillerVisionExit.clear()
        self.onPostmortemKillerVisionExit = None
        self.__targeting.enable(False)
        self.__killerVehicleID = None
        if self.__onRecreateDevice in g_guiResetters:
            g_guiResetters.remove(self.__onRecreateDevice)
        BigWorld.player().arena.onPeriodChange -= self.__onArenaStarted
        self.settingsCore.onSettingsChanged -= self.__onSettingsChanged
        BigWorld.player().consistentMatrices.onVehicleMatrixBindingChanged -= self.__onVehicleChanged
        ComponentSystem.destroy(self)
        CallbackDelayer.destroy(self)
        return

    def __onVehicleChanged(self, isStatic):
        self.steadyVehicleMatrixCalculator.relinkSources()
        self.__identifySPG()
        if self.__waitObserverCallback is not None and self.__observerVehicle is not None:
            player = BigWorld.player()
            ownVehicle = BigWorld.entity(player.playerVehicleID)
            vehicle = player.getVehicleAttached()
            if vehicle != ownVehicle:
                self.__waitObserverCallback()
                self.__observerIsSwitching = False
                self.__observerVehicle = None
        return

    def setObservedVehicle(self, vehicleID):
        for control in self.__ctrls.itervalues():
            control.setObservedVehicle(vehicleID)

    def onControlModeChanged(self, eMode, **args):
        if self.steadyVehicleMatrixCalculator is not None:
            self.steadyVehicleMatrixCalculator.relinkSources()
        if not self.__isArenaStarted and eMode != _CTRL_MODE.POSTMORTEM:
            return
        else:
            player = BigWorld.player()
            isObserverMode = 'observer' in player.vehicleTypeDescriptor.type.tags if player is not None else True
            if self.__waitObserverCallback is not None:
                self.__waitObserverCallback = None
            if isObserverMode and eMode == _CTRL_MODE.POSTMORTEM:
                if self.__observerVehicle is not None and not self.__observerIsSwitching:
                    self.__waitObserverCallback = partial(self.onControlModeChanged, eMode, **args)
                    self.__observerIsSwitching = True
                    player.positionControl.followCamera(False)
                    player.positionControl.bindToVehicle(True, self.__observerVehicle)
                    return
            if isObserverMode and self.__ctrlModeName == _CTRL_MODE.POSTMORTEM:
                player = BigWorld.player()
                self.__observerVehicle = player.vehicle.id if player.vehicle else None
                self.__observerIsSwitching = False
            replayCtrl = BattleReplay.g_replayCtrl
            if replayCtrl.isRecording:
                replayCtrl.setControlMode(eMode)
            self.__curCtrl.disable()
            prevCtrl = self.__curCtrl
            self.__curCtrl = self.__ctrls[eMode]
            self.__ctrlModeName = eMode
            if player is not None:
                if not prevCtrl.isManualBind() and self.__curCtrl.isManualBind():
                    if isObserverMode:
                        player.positionControl.bindToVehicle(False, -1)
                    else:
                        player.positionControl.bindToVehicle(False)
                elif prevCtrl.isManualBind() and not self.__curCtrl.isManualBind():
                    if isObserverMode:
                        player.positionControl.followCamera(False)
                        player.positionControl.bindToVehicle(True, self.__observerVehicle)
                    else:
                        player.positionControl.bindToVehicle(True)
                elif not prevCtrl.isManualBind() and not self.__curCtrl.isManualBind():
                    if isObserverMode and not self.isObserverFPV:
                        player.positionControl.bindToVehicle(True)
                newAutoRotationMode = self.__curCtrl.getPreferredAutorotationMode()
                if newAutoRotationMode is not None:
                    if prevCtrl.getPreferredAutorotationMode() is None:
                        self.__prevModeAutorotation = self.__isAutorotation
                    if self.__isAutorotation != newAutoRotationMode:
                        self.__isAutorotation = newAutoRotationMode
                        BigWorld.player().enableOwnVehicleAutorotation(self.__isAutorotation)
                elif prevCtrl.getPreferredAutorotationMode() is not None:
                    if self.__prevModeAutorotation is None:
                        self.__prevModeAutorotation = True
                    if self.__isAutorotation != self.__prevModeAutorotation:
                        self.__isAutorotation = self.__prevModeAutorotation
                        BigWorld.player().enableOwnVehicleAutorotation(self.__isAutorotation)
                    self.__prevModeAutorotation = None
                if not isObserverMode and self.__ctrlModeName in (_CTRL_MODE.ARCADE, _CTRL_MODE.SNIPER):
                    lockEnabled = prevCtrl.getAimingMode(AIMING_MODE.TARGET_LOCK)
                    self.__curCtrl.setAimingMode(lockEnabled, AIMING_MODE.TARGET_LOCK)
            self.__targeting.onRecreateDevice()
            self.__curCtrl.setGUIVisible(self.__isGUIVisible)
            if isObserverMode:
                args.update(vehicleID=self.__observerVehicle)
                self.__curCtrl.enable(**args)
            else:
                self.__curCtrl.enable(**args)
            isReplayPlaying = replayCtrl.isPlaying
            vehicleID = None
            vehicle = player.getVehicleAttached()
            if isObserverMode:
                vehicleID = self.__observerVehicle
            elif vehicle is not None and isReplayPlaying:
                vehicleID = vehicle.id
            self.onCameraChanged(eMode, vehicleID)
            if not isReplayPlaying:
                self.__curCtrl.handleMouseEvent(0.0, 0.0, 0.0)
            return

    def onVehicleControlModeChanged(self, eMode):
        LOG_DEBUG('onVehicleControlModeChanged: ', eMode, self.isObserverFPV)
        if not self.isObserverFPV:
            self.onControlModeChanged(_CTRL_MODE.POSTMORTEM)
            return
        else:
            if eMode is None:
                eMode = _CTRL_MODES[BigWorld.player().observerFPVControlMode]
            targetPos = self.getDesiredShotPoint() or Math.Vector3(0, 0, 0)
            LOG_DEBUG('onVehicleControlModeChanged: ', eMode, targetPos)
            self.onControlModeChanged(eMode, preferredPos=targetPos, aimingMode=0, saveZoom=False, saveDist=True, equipmentID=None, curVehicleID=BigWorld.player().getVehicleAttached())
            return

    def getTargeting(self):
        return self.__targeting

    def setGUIVisible(self, isVisible):
        self.__isGUIVisible = isVisible
        self.__curCtrl.setGUIVisible(isVisible)

    def selectPlayer(self, vehId):
        self.__curCtrl.selectPlayer(vehId)

    def onMinimapClicked(self, worldPos):
        self.__curCtrl.onMinimapClicked(worldPos)

    def onVehicleShaken(self, vehicle, impulsePosition, impulseDir, caliber, shakeReason):
        if shakeReason == _ShakeReason.OWN_SHOT_DELAYED:
            shakeFuncBound = functools.partial(self.onVehicleShaken, vehicle, impulsePosition, impulseDir, caliber, _ShakeReason.OWN_SHOT)
            delayTime = self.__dynamicCameraSettings.settings['ownShotImpulseDelay']
            self.delayCallback(delayTime, shakeFuncBound)
            return
        else:
            camera = getattr(self.ctrl, 'camera', None)
            if camera is None:
                return
            impulseValue = self.__dynamicCameraSettings.getGunImpulse(caliber)
            vehicleSensitivity = 0.0
            avatarVehicle = BigWorld.player().getVehicleAttached()
            if avatarVehicle is None or not avatarVehicle.isAlive():
                return
            avatarVehicleTypeDesc = getattr(avatarVehicle, 'typeDescriptor', None)
            if avatarVehicleTypeDesc is not None:
                avatarVehWeightTons = avatarVehicleTypeDesc.physics['weight'] / 1000.0
                vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehWeightTons)
                vehicleSensitivity *= avatarVehicleTypeDesc.hull.swinging.sensitivityToImpulse
            impulseReason = None
            isDistant = False
            if shakeReason == _ShakeReason.OWN_SHOT:
                if vehicle is avatarVehicle:
                    impulseReason = cameras.ImpulseReason.MY_SHOT
                    isDistant = False
                else:
                    impulseReason = cameras.ImpulseReason.OTHER_SHOT
                    isDistant = True
            elif vehicle is avatarVehicle:
                if shakeReason == _ShakeReason.HIT or shakeReason == _ShakeReason.HIT_NO_DAMAGE:
                    impulseValue *= 1.0 if shakeReason == _ShakeReason.HIT else self.__dynamicCameraSettings.settings['zeroDamageHitSensitivity']
                    impulseReason = cameras.ImpulseReason.ME_HIT
                    isDistant = False
                else:
                    impulseReason = cameras.ImpulseReason.SPLASH
                    isDistant = True
            impulseDir, impulseValue = self.__adjustImpulse(impulseDir, impulseValue, camera, impulsePosition, vehicleSensitivity, impulseReason)
            if isDistant:
                camera.applyDistantImpulse(impulsePosition, impulseValue, impulseReason)
            else:
                camera.applyImpulse(impulsePosition, impulseDir * impulseValue, impulseReason)
            return

    def onVehicleCollision(self, vehicle, impactVelocity):
        if impactVelocity < self.__dynamicCameraSettings.settings['minCollisionSpeed']:
            return
        else:
            camera = getattr(self.ctrl, 'camera', None)
            if camera is None:
                return
            avatarVehicle = BigWorld.player().getVehicleAttached()
            if avatarVehicle is None or not avatarVehicle.isAlive():
                return
            if vehicle is avatarVehicle:
                impulse = Math.Vector3(0, impactVelocity * self.__dynamicCameraSettings.settings['collisionSpeedToImpulseRatio'], 0)
                camera.applyImpulse(vehicle.position, impulse, cameras.ImpulseReason.COLLISION)
            return

    def onVehicleDeath(self, vehicle, exploded):
        if not exploded:
            return
        else:
            camera = getattr(self.ctrl, 'camera', None)
            if camera is None:
                return
            avatarVehicle = BigWorld.player().getVehicleAttached()
            if avatarVehicle is None or avatarVehicle is vehicle:
                return
            caliber = vehicle.typeDescriptor.shot.shell.caliber
            impulseValue = self.__dynamicCameraSettings.getGunImpulse(caliber)
            avatarVehicleWeightInTons = avatarVehicle.typeDescriptor.physics['weight'] / 1000.0
            vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehicleWeightInTons)
            vehicleSensitivity *= avatarVehicle.typeDescriptor.hull.swinging.sensitivityToImpulse
            _, impulseValue = self.__adjustImpulse(Math.Vector3(0, 0, 0), impulseValue, camera, vehicle.position, vehicleSensitivity, cameras.ImpulseReason.VEHICLE_EXPLOSION)
            camera.applyDistantImpulse(vehicle.position, impulseValue, cameras.ImpulseReason.VEHICLE_EXPLOSION)
            return

    def onExplosionImpulse(self, position, impulseValue):
        camera = getattr(self.ctrl, 'camera', None)
        if camera is None:
            return
        else:
            avatarVehicle = BigWorld.player().getVehicleAttached()
            if avatarVehicle is None:
                return
            avatarVehicleWeightInTons = avatarVehicle.typeDescriptor.physics['weight'] / 1000.0
            vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehicleWeightInTons)
            vehicleSensitivity *= avatarVehicle.typeDescriptor.hull.swinging.sensitivityToImpulse
            _, impulseValue = self.__adjustImpulse(Math.Vector3(0, 0, 0), impulseValue, camera, position, vehicleSensitivity, cameras.ImpulseReason.HE_EXPLOSION)
            camera.applyDistantImpulse(position, impulseValue, cameras.ImpulseReason.HE_EXPLOSION)
            return

    def onProjectileHit(self, position, caliber, isOwnShot):
        if not isOwnShot:
            return
        else:
            camera = getattr(self.ctrl, 'camera', None)
            if camera is None:
                return
            impulseValue = self.__dynamicCameraSettings.getGunImpulse(caliber)
            vehicleSensitivity = 1.0
            avatarVehicle = BigWorld.player().getVehicleAttached()
            if avatarVehicle is not None:
                avatarVehicleWeightInTons = avatarVehicle.typeDescriptor.physics['weight'] / 1000.0
                vehicleSensitivity = self.__dynamicCameraSettings.getSensitivityToImpulse(avatarVehicleWeightInTons)
                vehicleSensitivity *= avatarVehicle.typeDescriptor.hull.swinging.sensitivityToImpulse
            _, impulseValue = self.__adjustImpulse(Math.Vector3(0, 0, 0), impulseValue, camera, position, vehicleSensitivity, cameras.ImpulseReason.VEHICLE_EXPLOSION)
            camera.applyDistantImpulse(position, impulseValue, cameras.ImpulseReason.PROJECTILE_HIT)
            return

    def onSpecificImpulse(self, position, impulse, specificCtrl=None):
        if specificCtrl is None:
            camera = getattr(self.ctrl, 'camera', None)
        else:
            camera = self.ctrls[specificCtrl].camera
        if camera is None:
            return
        else:
            camera.applyImpulse(position, impulse, cameras.ImpulseReason.MY_SHOT)
            return

    def __adjustImpulse(self, impulseDir, impulseValue, camera, impulsePosition, vehicleSensitivity, impulseReason):
        if impulseReason in camera.getReasonsAffectCameraDirectly():
            dirToCamera = camera.camera.position - impulsePosition
            dirToCamera.normalise()
            impulseDir = dirToCamera
        else:
            impulseValue *= vehicleSensitivity
        return (impulseDir, impulseValue)

    def __identifySPG(self):
        veh = BigWorld.entity(BigWorld.player().playerVehicleID)
        if veh is None:
            return
        else:
            vehTypeDesc = veh.typeDescriptor.type
            self.__isSPG = 'SPG' in vehTypeDesc.tags
            self.__isATSPG = 'AT-SPG' in vehTypeDesc.tags
            return

    def reloadDynamicSettings(self):
        if not constants.HAS_DEV_RESOURCES:
            return
        ResMgr.purge(INPUT_HANDLER_CFG)
        sec = ResMgr.openSection(INPUT_HANDLER_CFG)
        self.__dynamicCameraSettings = DynamicCameraSettings(sec['dynamicCameraCommon'])
        try:
            self.__ctrls['sniper'].camera.aimingSystem.reloadConfig(sec['sniperMode']['camera'])
        except Exception:
            pass

    def _readCfg(self):
        sec = ResMgr.openSection(INPUT_HANDLER_CFG)
        if sec is None:
            LOG_ERROR('can not open <%s>.' % INPUT_HANDLER_CFG)
            return
        else:
            self.__checkSections(sec)
            keySec = sec['keys']
            if keySec is not None:
                self.__showMarkersKey = getattr(Keys, keySec.readString('showMarkersKey', ''), None)
                self.__alwaysShowAimKey = getattr(Keys, keySec.readString('alwaysShowAimKey', ''), None)
            self.__dynamicCameraSettings = DynamicCameraSettings(sec['dynamicCameraCommon'])
            return sec

    def __setupCtrls(self, section):
        modules = (control_modes,
         MapCaseMode,
         RespawnDeathMode,
         epic_battle_death_mode)
        bonusType = BigWorld.player().arenaBonusType
        bonusTypeCtrlsMap = _OVERWRITE_CTRLS_DESC_MAP.get(bonusType, {})
        for name, desc in _CTRLS_DESC_MAP.items():
            if bonusTypeCtrlsMap.has_key(name):
                desc = bonusTypeCtrlsMap.get(name)
            try:
                if desc[2] != _CTRL_TYPE.DEVELOPMENT or desc[2] == _CTRL_TYPE.DEVELOPMENT and constants.HAS_DEV_RESOURCES:
                    if name not in self.__ctrls:
                        for module in modules:
                            classType = getattr(module, desc[0], None)
                            if classType is None:
                                pass
                            self.__ctrls[name] = classType(section[desc[1]] if desc[1] else None, self)
                            break

            except Exception:
                LOG_DEBUG('Error while setting ctrls', name, desc, constants.HAS_DEV_RESOURCES)
                LOG_CURRENT_EXCEPTION()

        return

    def __checkSections(self, section):
        for _, desc in _CTRLS_DESC_MAP.items():
            if desc[1] is None or desc[2] == _CTRL_TYPE.OPTIONAL or desc[2] == _CTRL_TYPE.DEVELOPMENT and not constants.HAS_DEV_RESOURCES:
                continue
            if not section.has_key(desc[1]):
                LOG_ERROR('Invalid section <%s> in <%s>.' % (desc[1], INPUT_HANDLER_CFG))

        return

    def __onArenaStarted(self, period, *args):
        self.__isArenaStarted = period == ARENA_PERIOD.BATTLE
        self.__curCtrl.setGunMarkerFlag(self.__isArenaStarted, _GUN_MARKER_FLAG.CONTROL_ENABLED)
        self.showGunMarker2(gun_marker_ctrl.useServerGunMarker())
        self.showGunMarker(gun_marker_ctrl.useClientGunMarker())

    def __onRecreateDevice(self):
        self.__curCtrl.onRecreateDevice()
        self.__targeting.onRecreateDevice()

    def __onSettingsChanged(self, diff):
        if 'dynamicCamera' in diff or 'horStabilizationSnp' in diff:
            dynamicCamera = self.settingsCore.getSetting('dynamicCamera')
            horStabilizationSnp = self.settingsCore.getSetting('horStabilizationSnp')
            self.enableDynamicCamera(dynamicCamera, horStabilizationSnp)

    def __onRequestFail(self):
        player = BigWorld.player()
        if player is not None:
            player.showVehicleError('cantSwitchEngineDestroyed')
        return
Пример #39
0
class CompanyBattleController(Notifiable):
    def __init__(self, eventsCache):
        self.__eventsCache = weakref.proxy(eventsCache)
        self.onCompanyStateChanged = Event()
        super(CompanyBattleController, self).__init__()
        self.__isLobbyLoaded = False
        self.__delayedCompanyState = []

    def start(self):
        g_eventBus.addListener(GUICommonEvent.LOBBY_VIEW_LOADED,
                               self.__onLobbyInited)
        g_playerEvents.onAvatarBecomePlayer += self.__onAvatarBecomePlayer
        g_connectionManager.onDisconnected += self.__onDisconnected
        self.setNotificators()

    def stop(self):
        self.onCompanyStateChanged.clear()
        self.clearNotification()
        g_eventBus.removeListener(GUICommonEvent.LOBBY_VIEW_LOADED,
                                  self.__onLobbyInited)
        g_playerEvents.onAvatarBecomePlayer -= self.__onAvatarBecomePlayer
        g_connectionManager.onDisconnected -= self.__onDisconnected

    def setNotificators(self):
        battle = self.__eventsCache.getCompanyBattles()
        self.clearNotification()
        if battle.isValid():
            destroyingTimeLeft = battle.getDestroyingTimeLeft()
            if destroyingTimeLeft is not None:
                if destroyingTimeLeft <= 0:
                    self.__onCompanyFinished()
                else:
                    self.addNotificators(
                        AcyclicNotifier(battle.getDestroyingTimeLeft,
                                        self.__onCompanyFinished))
            if battle.isCreationTimeCorrect():
                self.__onCompanyStarted()
            else:
                self.addNotificators(
                    AcyclicNotifier(battle.getCreationTimeLeft,
                                    self.__onCompanyStarted))
            self.startNotification()
        else:
            self.__onCompanyFinished()
        return

    def __onLobbyInited(self, *args):
        self.__isLobbyLoaded = True
        self.__handlePostponed()

    def __onAvatarBecomePlayer(self):
        self.__isLobbyLoaded = False

    def __onDisconnected(self):
        self.__isLobbyLoaded = False

    def __onCompanyStarted(self):
        if self.__isLobbyLoaded:
            self.onCompanyStateChanged(True)
        else:
            self.__delayedCompanyState.append(True)

    def __onCompanyFinished(self):
        if self.__isLobbyLoaded:
            self.onCompanyStateChanged(False)
        else:
            self.__delayedCompanyState.append(False)

    def __handlePostponed(self):
        for companyState in self.__delayedCompanyState:
            self.onCompanyStateChanged(companyState)

        self.__delayedCompanyState = []
Пример #40
0
class ContainerManager(ContainerManagerMeta):
    """
    Class of container manager.
    """
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {}
        for container in containers:
            raise isinstance(container,
                             AbstractViewContainer) or AssertionError
            self.__containers[container.getViewType()] = container(proxy)

        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name=None, *args, **kwargs):
        """
        Loads view to container.
        :param alias:
        :param name:
        :param args:
        :param kwargs:
        :return:
        """
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if result:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity
        return

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False
            return

    def addContainer(self, viewType, name, container=None):
        result = True
        if viewType not in self.__containers:
            if container is None:
                self.__containers[viewType] = DefaultContainer(
                    viewType, weakref.proxy(self))
                self.as_registerContainerS(viewType, name)
            elif isinstance(container, AbstractViewContainer):
                self.__containers[viewType] = container
                self.as_registerContainerS(viewType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer',
                          container)
                result = False
        else:
            LOG_ERROR('Container already registered', viewType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(
            ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]
        else:
            return None

    def isModalViewsIsExists(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria=None):
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria=None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False
            return

    def showContainers(self, *viewTypes):
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        return self.as_isContainerShownS(viewType)

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None:
                container.clear()

        return

    def removeLoadingView(self, alias, uniqueName):
        self._loadingViews.pop((alias, uniqueName), None)
        return

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: {}/{}'.format(container, viewType))
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()
        return

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop(
                (curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG(
                    '"%s" view cancelled to load, because its scope has been destroyed.'
                    % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' %
                      (viewType, pyView))
        return
Пример #41
0
class ContainerManager(ContainerManagerMeta):
    """
    Class of container manager.
    """

    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {}
        for container in containers:
            raise isinstance(container, AbstractViewContainer) or AssertionError
            self.__containers[container.getViewType()] = container(proxy)

        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name = None, *args, **kwargs):
        """
        Loads view to container.
        :param alias:
        :param name:
        :param args:
        :param kwargs:
        :return:
        """
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if result:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity
        return

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False
            return

    def addContainer(self, viewType, name, container = None):
        result = True
        if viewType not in self.__containers:
            if container is None:
                self.__containers[viewType] = DefaultContainer(viewType, weakref.proxy(self))
                self.as_registerContainerS(viewType, name)
            elif isinstance(container, AbstractViewContainer):
                self.__containers[viewType] = container
                self.as_registerContainerS(viewType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer', container)
                result = False
        else:
            LOG_ERROR('Container already registered', viewType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]
        else:
            return None

    def isModalViewsIsExists(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria = None):
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria = None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False
            return

    def showContainers(self, *viewTypes):
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        return self.as_isContainerShownS(viewType)

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None:
                container.clear()

        return

    def removeLoadingView(self, alias, uniqueName):
        self._loadingViews.pop((alias, uniqueName), None)
        return

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: {}/{}'.format(container, viewType))
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()
        return

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop((curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG('"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView))
        return
Пример #42
0
class ItemsCache(IItemsCache):
    def __init__(self):
        super(ItemsCache, self).__init__()
        goodies = GoodiesRequester()
        self.__items = ItemsRequester.ItemsRequester(
            InventoryRequester(), StatsRequester(), DossierRequester(),
            goodies, ShopRequester(goodies), RecycleBinRequester(),
            VehicleRotationRequester(), RankedRequester(), BadgesRequester())
        self.__waitForSync = False
        self.__syncFailed = False
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()
        self.onSyncFailed = Event()

    def init(self):
        g_playerEvents.onInventoryResync += self.__pe_onInventoryResync
        g_playerEvents.onDossiersResync += self.__pe_onDossiersResync
        g_playerEvents.onStatsResync += self.__pe_onStatsResync
        g_playerEvents.onCenterIsLongDisconnected += self._onCenterIsLongDisconnected

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        self.onSyncFailed.clear()
        g_playerEvents.onCenterIsLongDisconnected -= self._onCenterIsLongDisconnected
        g_playerEvents.onStatsResync -= self.__pe_onStatsResync
        g_playerEvents.onDossiersResync -= self.__pe_onDossiersResync
        g_playerEvents.onInventoryResync -= self.__pe_onInventoryResync

    @property
    def waitForSync(self):
        return self.__waitForSync

    @property
    def items(self):
        return self.__items

    @async
    def update(self, updateReason, diff=None, callback=None):
        if diff is None or self.__syncFailed:
            self.__invalidateFullData(updateReason, callback)
        else:
            self.__invalidateData(updateReason, diff, callback)
        return

    def clear(self):
        LOG_DEBUG('Clearing items cache.')
        return self.items.clear()

    def _onResync(self, reason):
        if not self.__waitForSync:
            self.__invalidateFullData(reason)

    def _onCenterIsLongDisconnected(self, isLongDisconnected):
        self.items.dossiers.onCenterIsLongDisconnected(isLongDisconnected)

    def __invalidateData(self,
                         updateReason,
                         diff,
                         callback=lambda *args: None):
        self.__waitForSync = True
        wasSyncFailed = self.__syncFailed
        self.__syncFailed = False
        self.onSyncStarted()
        if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed:
            invalidItems = self.__items.invalidateCache(diff)
        else:
            invalidItems = {}

        def cbWrapper(*args):
            self.__waitForSync = False
            if not self.isSynced():
                self.__syncFailed = True
                self.onSyncFailed(updateReason)
            else:
                self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def __invalidateFullData(self, updateReason, callback=lambda *args: None):
        self.__waitForSync = True
        wasSyncFailed = self.__syncFailed
        self.__syncFailed = False
        self.onSyncStarted()

        def cbWrapper(*args):
            self.__waitForSync = False
            if not self.isSynced():
                self.__syncFailed = True
                self.onSyncFailed(updateReason)
            else:
                if updateReason != CACHE_SYNC_REASON.DOSSIER_RESYNC or wasSyncFailed:
                    invalidItems = self.__items.invalidateCache()
                else:
                    invalidItems = {}
                self.onSyncCompleted(updateReason, invalidItems)
            callback(*args)

        self.__items.request()(cbWrapper)

    def isSynced(self):
        return self.items.isSynced()

    def __pe_onStatsResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.STATS_RESYNC)

    def __pe_onInventoryResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.INVENTORY_RESYNC)

    def __pe_onDossiersResync(self, *args):
        self._onResync(CACHE_SYNC_REASON.DOSSIER_RESYNC)
Пример #43
0
class _CurrentVehicle:
    def __init__(self):
        self.__vehInvID = 0
        self.__changeCallbackID = None
        self.onChanged = Event()
        self.onChangeStarted = Event()
        return

    def init(self):
        g_clientUpdateManager.addCallbacks({"inventory": self.onInventoryUpdate, "cache.vehsLock": self.onLocksUpdate})
        game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged
        game_control.g_instance.rentals.onRentChangeNotify += self.onRentChange
        game_control.getFalloutCtrl().onSettingsChanged += self.__onFalloutChanged
        prbVehicle = self.__checkPrebattleLockedVehicle()
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        self.selectVehicle(prbVehicle or storedVehInvID)

    def destroy(self):
        self.__vehInvID = 0
        self.__clearChangeCallback()
        self.onChanged.clear()
        self.onChangeStarted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)
        game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged
        game_control.g_instance.rentals.onRentChangeNotify -= self.onRentChange
        game_control.getFalloutCtrl().onSettingsChanged -= self.__onFalloutChanged
        _getHangarSpace().removeVehicle()
        self.selectNoVehicle()

    def onIgrTypeChanged(self, *args):
        if self.isPremiumIGR():
            self.onChanged()
        self.refreshModel()

    def onRentChange(self, vehicles):
        if self.isPresent():
            if self.item.intCD in vehicles:
                self.onChanged()

    def onInventoryUpdate(self, invDiff):
        vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {})
        isVehicleSold = False
        isVehicleDescrChanged = False
        if "compDescr" in vehsDiff and self.__vehInvID in vehsDiff["compDescr"]:
            isVehicleSold = vehsDiff["compDescr"][self.__vehInvID] is None
            isVehicleDescrChanged = not isVehicleSold
        if isVehicleSold or self.__vehInvID == 0:
            self.selectVehicle()
        else:
            isRepaired = "repair" in vehsDiff and self.__vehInvID in vehsDiff["repair"]
            isCustomizationChanged = (
                "igrCustomizationLayout" in vehsDiff and self.__vehInvID in vehsDiff["igrCustomizationLayout"]
            )
            isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff
            isVehicleChanged = (
                len(
                    filter(
                        lambda hive: self.__vehInvID in hive or (self.__vehInvID, "_r") in hive, vehsDiff.itervalues()
                    )
                )
                > 0
            )
            if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged:
                self.refreshModel()
            if isVehicleChanged or isRepaired:
                self.onChanged()
        return

    def onLocksUpdate(self, locksDiff):
        if self.__vehInvID in locksDiff:
            self.refreshModel()

    def refreshModel(self):
        if self.isPresent() and self.isInHangar() and self.item.modelState:
            if self.item.intCD not in g_tankActiveCamouflage:
                availableKinds = []
                currKind = 0
                for id, startTime, days in self.item.descriptor.camouflages:
                    if id is not None:
                        availableKinds.append(currKind)
                    currKind += 1

                if len(availableKinds) > 0:
                    g_tankActiveCamouflage[self.item.intCD] = random.choice(availableKinds)
            _getHangarSpace().updateVehicle(self.item)
        else:
            _getHangarSpace().removeVehicle()
        return

    @property
    def invID(self):
        return self.__vehInvID

    @property
    def item(self):
        if self.__vehInvID > 0:
            return g_itemsCache.items.getVehicle(self.__vehInvID)
        else:
            return None

    def isPresent(self):
        return self.item is not None

    def isBroken(self):
        return self.isPresent() and self.item.isBroken

    def isGroupReady(self):
        return self.isPresent() and self.item.isGroupReady()[0]

    def isDisabledInRoaming(self):
        return self.isPresent() and self.item.isDisabledInRoaming

    def isLocked(self):
        return self.isPresent() and self.item.isLocked

    def isClanLock(self):
        return self.isPresent() and self.item.clanLock > 0

    def isCrewFull(self):
        return self.isPresent() and self.item.isCrewFull

    def isDisabledInRent(self):
        return self.isPresent() and self.item.rentalIsOver

    def isDisabledInPremIGR(self):
        return self.isPresent() and self.item.isDisabledInPremIGR

    def isPremiumIGR(self):
        return self.isPresent() and self.item.isPremiumIGR

    def isInPrebattle(self):
        return self.isPresent() and self.item.isInPrebattle

    def isInBattle(self):
        return self.isPresent() and self.item.isInBattle

    def isInHangar(self):
        return self.isPresent() and not self.item.isInBattle

    def isAwaitingBattle(self):
        return self.isPresent() and self.item.isAwaitingBattle

    def isOnlyForEventBattles(self):
        return self.item.isOnlyForEventBattles

    def isAlive(self):
        return self.isPresent() and self.item.isAlive

    def isReadyToPrebattle(self):
        return self.isPresent() and self.item.isReadyToPrebattle()

    def isReadyToFight(self):
        return self.isPresent() and self.item.isReadyToFight

    def isAutoLoadFull(self):
        return not self.isPresent() or self.item.isAutoLoadFull()

    def isAutoEquipFull(self):
        return not self.isPresent() or self.item.isAutoEquipFull()

    def isFalloutOnly(self):
        return self.isPresent() and self.item.isFalloutOnly()

    def selectVehicle(self, vehInvID=0):
        vehicle = g_itemsCache.items.getVehicle(vehInvID)
        if vehicle is None:
            invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY)
            if len(invVehs):
                vehInvID = sorted(invVehs.itervalues())[0].invID
            else:
                vehInvID = 0
        self.__selectVehicle(vehInvID)
        return

    def selectNoVehicle(self):
        self.__selectVehicle(0)

    def getDossier(self):
        return g_itemsCache.items.getVehicleDossier(self.item.intCD)

    def getHangarMessage(self):
        if self.isPresent():
            state, stateLvl = self.item.getState()
            if state == Vehicle.VEHICLE_STATE.IN_PREMIUM_IGR_ONLY:
                rentLeftStr = getTimeLeftStr("#menu:vehicle/igrRentLeft/%s", self.item.rentInfo.timeLeft)
                icon = icons.premiumIgrBig()
                if self.item.isRented:
                    message = i18n.makeString("#menu:currentVehicleStatus/" + state, icon=icon, time=rentLeftStr)
                else:
                    message = i18n.makeString("#menu:tankCarousel/vehicleStates/inPremiumIgrOnly", icon=icon)
                return (state, message, stateLvl)
            return (state, "#menu:currentVehicleStatus/" + state, stateLvl)
        return (
            Vehicle.VEHICLE_STATE.NOT_PRESENT,
            MENU.CURRENTVEHICLESTATUS_NOTPRESENT,
            Vehicle.VEHICLE_STATE_LEVEL.CRITICAL,
        )

    def getViewState(self):
        return createState4CurrentVehicle(self)

    def __selectVehicle(self, vehInvID):
        if vehInvID == self.__vehInvID:
            return
        Waiting.show("updateCurrentVehicle", isSingle=True)
        self.onChangeStarted()
        self.__vehInvID = vehInvID
        AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID)
        self.refreshModel()
        if not self.__changeCallbackID:
            self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone)

    def __changeDone(self):
        self.__clearChangeCallback()
        if isPlayerAccount():
            self.onChanged()
        Waiting.hide("updateCurrentVehicle")

    def __clearChangeCallback(self):
        if self.__changeCallbackID is not None:
            BigWorld.cancelCallback(self.__changeCallbackID)
            self.__changeCallbackID = None
        return

    def __checkPrebattleLockedVehicle(self):
        clientPrb = prb_getters.getClientPrebattle()
        if clientPrb is not None:
            rosters = prb_getters.getPrebattleRosters(prebattle=clientPrb)
            for rId, roster in rosters.iteritems():
                if BigWorld.player().id in roster:
                    vehCompDescr = roster[BigWorld.player().id].get("vehCompDescr", "")
                    if len(vehCompDescr):
                        vehDescr = vehicles.VehicleDescr(vehCompDescr)
                        vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr)
                        if vehicle is not None:
                            return vehicle.invID

        return 0

    def __onFalloutChanged(self):
        if self.isPresent() and (self.item.isOnlyForEventBattles or self.item.isFalloutAvailable):
            self.onChanged()

    def __repr__(self):
        return "CurrentVehicle(%s)" % str(self.item)
Пример #44
0
class AnonymizerController(IAnonymizerController):
    __lobbyContext = dependency.descriptor(ILobbyContext)
    __itemsCache = dependency.descriptor(IItemsCache)
    __slots__ = ('__isEnabled', '__isRestricted', '__isAnonymized', '__isInBattle', '__uploader')

    def __init__(self):
        self.onStateChanged = Event()
        self.__isEnabled = False
        self.__isRestricted = False
        self.__isAnonymized = False
        self.__isInBattle = False
        self.__uploader = ContactsUploader()

    def onConnected(self):
        self.__uploader.init()

    def onDisconnected(self):
        self.__uploader.fini()
        self.__clear()

    def onLobbyInited(self, _):
        self.__isInBattle = False
        self.__addListeners()
        self.__update()

    def onAvatarBecomePlayer(self):
        self.__removeListeners()
        self.__isInBattle = True

    def onAccountBecomeNonPlayer(self):
        if self.__uploader.isProcessing:
            _logger.info('contacts uploader stopping because of onAccountBecomeNonPlayer.')
            self.__uploader.stop()

    @property
    def isInBattle(self):
        return self.__isInBattle

    @property
    def isEnabled(self):
        return self.__isEnabled

    @property
    def isRestricted(self):
        return self.__isRestricted

    @property
    def isAnonymized(self):
        return self.__isEnabled and self.__isAnonymized

    def setAnonymized(self, value):
        if self.isEnabled and not self.isRestricted:
            if value != self.__isAnonymized:
                self.__isAnonymized = value
                BigWorld.player().anonymizer.setAnonymized(self.__isAnonymized, self.__onSetAnonymizedResponse)
        else:
            self.__pushChangeUnavailableMessage()

    def __addListeners(self):
        g_clientUpdateManager.addCallbacks({'cache.SPA': self.__onCacheSPAChanged,
         'anonymizer.enabled': self.__onAnonymizedStateChanged,
         'anonymizer.contactsFeedback': self.__onContactsFeedback})
        self.__lobbyContext.getServerSettings().onServerSettingsChange += self.__onServerSettingsChanged

    def __removeListeners(self):
        self.__lobbyContext.getServerSettings().onServerSettingsChange -= self.__onServerSettingsChanged
        g_clientUpdateManager.removeObjectCallbacks(self)

    def __update(self):
        self.__isEnabled = self.__lobbyContext.getServerSettings().isAnonymizerEnabled()
        self.__isRestricted = self.__itemsCache.items.stats.isAnonymousRestricted
        self.__isAnonymized = self.__itemsCache.items.anonymizer.isPlayerAnonymized
        self.__processContacts()
        self.onStateChanged(enabled=self.isEnabled, restricted=self.isRestricted, anonymized=self.isAnonymized)

    def __clear(self):
        self.onStateChanged.clear()
        self.__removeListeners()
        self.__isEnabled = False
        self.__isRestricted = False
        self.__isAnonymized = False
        self.__isInBattle = False

    def __onServerSettingsChanged(self, *_):
        self.__isEnabled = self.__lobbyContext.getServerSettings().isAnonymizerEnabled()
        self.onStateChanged(enabled=self.isEnabled)

    def __onCacheSPAChanged(self, *_):
        self.__isRestricted = self.__itemsCache.items.stats.isAnonymousRestricted
        self.onStateChanged(restricted=self.isRestricted)

    def __onAnonymizedStateChanged(self, *_):
        self.__isAnonymized = self.__itemsCache.items.anonymizer.isPlayerAnonymized
        self.onStateChanged(anonymized=self.isAnonymized)

    def __onContactsFeedback(self, *_):
        self.__processContacts()

    def __processContacts(self):
        contactsFeedback = self.__itemsCache.items.anonymizer.contactsFeedback
        if contactsFeedback:
            arenaUniqueID, contactsBlob = self.__itemsCache.items.anonymizer.contactsFeedback[0]
            if self.__uploader.isProcessing:
                if self.__uploader.arenaUniqueID == arenaUniqueID:
                    _logger.info('contacts uploader continue upload arenaID %s', arenaUniqueID)
                    return
                self.__uploader.stop()
            self.__uploader.start(arenaUniqueID, contactsBlob)
        elif self.__uploader.isProcessing:
            self.__uploader.stop()

    def __onSetAnonymizedResponse(self, resultID, errorCode):
        if errorCode:
            self.__onAnonymizedStateChanged()
            self.__pushChangeUnavailableMessage()
        _logger.debug('setAnonymized response: %s', (resultID, errorCode))

    @staticmethod
    def __pushChangeUnavailableMessage():
        SystemMessages.pushMessage(backport.text(_RSettingsError.changeUnavailable.message()), SystemMessages.SM_TYPE.Warning)
Пример #45
0
class _CurrentVehicle():
    def __init__(self):
        self.__vehInvID = 0
        self.__changeCallbackID = None
        self.__historicalBattle = None
        self.onChanged = Event()
        self.onChangeStarted = Event()
        self.__crew = {}

    def init(self):
        g_clientUpdateManager.addCallbacks({
            'inventory': self.onInventoryUpdate,
            'cache.vehsLock': self.onLocksUpdate
        })
        game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged
        prbVehicle = self.__checkPrebattleLockedVehicle()
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        self.selectVehicle(prbVehicle or storedVehInvID)

    def destroy(self):
        self.__vehInvID = 0
        self.__clearChangeCallback()
        self.onChanged.clear()
        self.onChangeStarted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)
        game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged
        g_hangarSpace.removeVehicle()
        self.selectNoVehicle()

    def onIgrTypeChanged(self, *args):
        self.refreshModel()

    def onInventoryUpdate(self, invDiff):
        vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {})
        isVehicleSold = False
        isVehicleDescrChanged = False
        if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']:
            isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None
            isVehicleDescrChanged = not isVehicleSold
        if isVehicleSold or self.__vehInvID == 0:
            self.selectVehicle()
        else:
            isRepaired = 'repair' in vehsDiff and self.__vehInvID in vehsDiff[
                'repair']
            isCustomizationChanged = 'igrCustomizationsLayout' in vehsDiff and self.__vehInvID in vehsDiff[
                'igrCustomizationsLayout']
            isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff
            isVehicleChanged = len(
                filter(
                    lambda hive: self.__vehInvID in hive or
                    (self.__vehInvID, '_r') in hive,
                    vehsDiff.itervalues())) > 0

            if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged:
                self.refreshModel()
            if isVehicleChanged or isRepaired:
                self.onChanged()

        if self.isPresent():
            self.__updateViewRange()

    def onLocksUpdate(self, locksDiff):
        if self.__vehInvID in locksDiff:
            self.refreshModel()

    def refreshModel(self):
        if self.isPresent() and self.isInHangar() and self.item.modelState:
            if self.__historicalBattle is not None:
                historical = g_tankActiveCamouflage['historical']
                if self.__historicalBattle.canParticipateWith(
                        self.item.intCD) and self.item.intCD not in historical:
                    historical[self.item.
                               intCD] = self.__historicalBattle.getArenaType(
                               ).vehicleCamouflageKind
            if self.item.intCD not in g_tankActiveCamouflage:
                availableKinds = []
                currKind = 0
                for id, startTime, days in self.item.descriptor.camouflages:
                    if id is not None:
                        availableKinds.append(currKind)
                    currKind += 1

                if len(availableKinds) > 0:
                    g_tankActiveCamouflage[self.item.intCD] = random.choice(
                        availableKinds)
            g_hangarSpace.updateVehicle(self.item, self.__historicalBattle)
        else:
            g_hangarSpace.removeVehicle()
        return

    @property
    def invID(self):
        return self.__vehInvID

    @property
    def item(self):
        if self.__vehInvID > 0:
            return g_itemsCache.items.getVehicle(self.__vehInvID)
        else:
            return None

    def isPresent(self):
        return self.item is not None

    def isBroken(self):
        return self.isPresent() and self.item.isBroken

    def isDisabledInRoaming(self):
        return self.isPresent() and self.item.isDisabledInRoaming

    def isLocked(self):
        return self.isPresent() and self.item.isLocked

    def isClanLock(self):
        return self.isPresent() and self.item.clanLock > 0

    def isCrewFull(self):
        return self.isPresent() and self.item.isCrewFull

    def isInBattle(self):
        return self.isPresent() and self.item.isInBattle

    def isInHangar(self):
        return self.isPresent() and not self.item.isInBattle

    def isAwaitingBattle(self):
        return self.isPresent() and self.item.isAwaitingBattle

    def isAlive(self):
        return self.isPresent() and self.item.isAlive

    def isReadyToPrebattle(self):
        return self.isPresent() and self.item.isReadyToPrebattle

    def isReadyToFight(self):
        return self.isPresent() and self.item.isReadyToFight

    def isAutoLoadFull(self):
        if self.isPresent() and self.item.isAutoLoad:
            for shell in self.item.shells:
                if shell.count != shell.defaultCount:
                    return False

        return True

    def isAutoEquipFull(self):
        if self.isPresent() and self.item.isAutoEquip:
            for i, e in enumerate(self.item.eqsLayout):
                if e != self.item.eqs[i]:
                    return False

        return True

    def selectVehicle(self, vehInvID=0):
        vehicle = g_itemsCache.items.getVehicle(vehInvID)
        if vehicle is None:
            invVehs = g_itemsCache.items.getVehicles(
                criteria=REQ_CRITERIA.INVENTORY)
            if len(invVehs):
                vehInvID = sorted(invVehs.itervalues())[0].invID
            else:
                vehInvID = 0
        self.__selectVehicle(vehInvID)

    def selectNoVehicle(self):
        self.__selectVehicle(0)

    def getHangarMessage(self):
        if self.isPresent():
            state, stateLvl = self.item.getState()
            return ('#menu:currentVehicleStatus/' + state, stateLvl)
        return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT,
                Vehicle.VEHICLE_STATE_LEVEL.CRITICAL)

    def setHistoricalBattle(self, historicalBattle):
        g_tankActiveCamouflage['historical'] = {}
        self.__historicalBattle = historicalBattle
        self.refreshModel()
        self.onChanged()

    def __selectVehicle(self, vehInvID):
        if vehInvID == self.__vehInvID:
            return
        Waiting.show('updateCurrentVehicle', isSingle=True)
        self.onChangeStarted()
        self.__vehInvID = vehInvID
        AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID)
        self.refreshModel()
        if not self.__changeCallbackID:
            self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone)

        if self.isPresent():
            self.__updateViewRange()

    def __updateViewRange(self):
        # Set Defaults
        xvm_conf = {}
        saveConfig = False

        # Load configuration
        xvm_configuration_file = os.getcwd(
        ) + os.sep + 'res_mods' + os.sep + 'xvm' + os.sep + 'tankrange.xc'
        if not os.path.exists(xvm_configuration_file):
            SystemMessages.pushMessage("Configuration file missing (" +
                                       xvm_configuration_file + ")",
                                       type=SystemMessages.SM_TYPE.Error)
            return
        else:
            try:
                data = ""
                blockComment = False

                f = codecs.open(xvm_configuration_file, 'r', '"utf-8-sig"')
                for line in f.read().split('\n'):
                    line = line.strip()
                    if line != "":
                        # Start of block comment
                        comment = line.find("/*")
                        if comment != -1 and comment == 0:
                            blockComment = True
                            continue

                        # End of block comment
                        comment = line.find("*/")
                        if comment != -1:
                            blockComment = False
                            continue

                        # Block Comment
                        if blockComment == True:
                            continue

                        # Start of line comment
                        comment = line.find("//")
                        if comment != -1 and comment == 0:
                            continue

                        # Remove end of line comments
                        position = 0
                        for i in range(0, line.count("//")):
                            comment = line.find("//", position + 2)
                            if comment != -1:
                                colon = line.find(":")

                                startSpeach = line.find("\"", colon + 1)
                                if startSpeach > comment:
                                    line = line[:comment].strip()

                                endSpeach = line.find("\"", startSpeach + 1)
                                if comment > endSpeach:
                                    line = line[:comment].strip()

                            position += comment

                        if line != "":
                            data += line + '\n'
                f.close()

                xvm_conf = json.loads(data)
            except Exception as e:
                SystemMessages.pushMessage("Parsing configuration file: " +
                                           str(e),
                                           type=SystemMessages.SM_TYPE.Error)
                return

        # Code for migrating old configuration files (v1.5->v1.6)
        if not xvm_conf["tankrange"].has_key("spotting_limit"):
            xvm_conf["tankrange"]["spotting_limit"] = True
            saveConfig = True

        # Code for migrating old configuration files (v1.7->v1.8)
        if not xvm_conf["tankrange"].has_key("notify_changes"):
            xvm_conf["tankrange"]["notify_changes"] = True
            saveConfig = True

        # Get name
        tank_name = g_itemsCache.items.getVehicle(
            self.__vehInvID).descriptor.type.name.replace(":", "-")
        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Tank Name: ", tank_name)

        # Only update when we have a crew
        if not self.isCrewFull():
            if xvm_conf['tankrange']['logging']:
                LOG_NOTE('Crew is missing.')
            return

        # Remove current circles
        remaining = []
        oldCircles = {}
        for tank_data in xvm_conf["circles"]["special"]:
            if tank_data.keys()[0] != tank_name:
                remaining.append(tank_data)
            elif tank_data[tank_name].has_key(
                    'distance') and tank_data[tank_name].has_key(
                        '$ref') and tank_data[tank_name]['$ref'].has_key(
                            'path'):
                oldCircles[tank_data[tank_name]['$ref']
                           ['path']] = tank_data[tank_name]['distance']

        xvm_conf["circles"]["special"] = remaining

        # Get type
        if xvm_conf["tankrange"][
                "ignore_artillery"] and "SPG" in g_itemsCache.items.getVehicle(
                    self.__vehInvID).descriptor.type.tags:
            f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"')
            f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False,
                                       indent=2)))
            f.close()

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Ignoring " + vehicle_type + " tank.")
            return

        # Get view distance
        view_distance = g_itemsCache.items.getVehicle(
            self.__vehInvID).descriptor.turret["circularVisionRadius"]
        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Base View Range: ", view_distance)

        # Check for Ventilation
        ventilation = self.__isOptionalEquipped("improvedVentilation")
        if xvm_conf["tankrange"]["logging"] and ventilation:
            LOG_NOTE("Ventilation Found")

        # Check for Consumable
        consumable = False
        if self.__isConsumableEquipped("ration"):
            consumable = True
        if self.__isConsumableEquipped("chocolate"):
            consumable = True
        if self.__isConsumableEquipped("cocacola"):
            consumable = True
        if self.__isConsumableEquipped("hotCoffee"):
            consumable = True
        if xvm_conf["tankrange"]["logging"] and consumable:
            LOG_NOTE("Premium Consumable Found")

        # Update crew
        self.__updateCrew()

        # Check for Brothers In Arms
        brothers_in_arms = True
        if len(self.__crew) == 0:
            brothers_in_arms = False
        else:
            for name, data in self.__crew.iteritems():
                if "brotherhood" not in data["skill"]:
                    brothers_in_arms = False
                elif data["skill"]["brotherhood"] != 100:
                    brothers_in_arms = False

        if xvm_conf["tankrange"]["logging"] and brothers_in_arms:
            LOG_NOTE("BIA Found")

        # Calculate commander bonus
        commander_skill = 0.0
        if "commander" in self.__crew:
            commander_skill = self.__crew["commander"]["level"]

            if brothers_in_arms == True:
                commander_skill += 5.0
            if ventilation == True:
                commander_skill += 5.0
            if consumable == True:
                commander_skill += 10.0

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Commander Skill: ", commander_skill)

        # Calculate other bonuses
        other_bonus = 1.0
        for name, data in self.__crew.iteritems():
            # Calculate recon skills
            if "commander_eagleEye" in data["skill"]:
                other_bonus *= 1.0 + (0.0002 *
                                      data["skill"]["commander_eagleEye"])

                if xvm_conf["tankrange"]["logging"]:
                    LOG_NOTE(
                        "Recon Bonus: ",
                        1.0 + (0.0002 * data["skill"]["commander_eagleEye"]))

            # Calculate Situational Awareness Skill
            if "radioman_finder" in data["skill"]:
                other_bonus *= 1.0 + (0.0003 *
                                      data["skill"]["radioman_finder"])

                if xvm_conf["tankrange"]["logging"]:
                    LOG_NOTE("Situational Awareness Bonus: ",
                             1.0 + (0.0003 * data["skill"]["radioman_finder"]))

        # Check for Binoculars
        binoculars = self.__isOptionalEquipped("stereoscope")
        if xvm_conf["tankrange"]["logging"] and binoculars:
            LOG_NOTE("Binoculars Found")

        # Check for Coated Optics
        coated_optics = self.__isOptionalEquipped("coatedOptics")
        if xvm_conf["tankrange"]["logging"] and coated_optics:
            LOG_NOTE("Coated Optics Found")

        # Calculate final value
        view_distance = ((view_distance / 0.875) *
                         (0.00375 * commander_skill + 0.5)) * other_bonus

        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Other Bonus:", other_bonus)
            LOG_NOTE("Final View Range: ", view_distance)

        # Add binocular Circles
        binocular_distance = None
        if xvm_conf["tankrange"]["circle_binocular"]["enabled"] and binoculars:
            binocular_distance = view_distance * 1.25
            if xvm_conf["tankrange"]["spotting_limit"]:
                binocular_distance = min(445, binocular_distance)

            if not xvm_conf["tankrange"]["circle_binocular"]["filled"]:
                xvm_conf["circles"]["special"].append({
                    tank_name: {
                        "$ref": {
                            "path": "tankrange.circle_binocular"
                        },
                        "distance": binocular_distance
                    }
                })
            else:
                xvm_conf["circles"]["special"].append({
                    tank_name: {
                        "$ref": {
                            "path": "tankrange.circle_binocular"
                        },
                        "thickness": (binocular_distance * 0.25) - 14,
                        "distance": binocular_distance * 0.5
                    }
                })

            # store only when changes
            if not oldCircles.has_key("tankrange.circle_binocular") or float(
                    oldCircles["tankrange.circle_binocular"]
            ) != binocular_distance:
                saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_binocular"):
            saveConfig = True

        # Add standard Circles
        if coated_optics == True:
            view_distance = min(view_distance * 1.1, 500)

        if xvm_conf["tankrange"]["circle_view"]["enabled"]:
            if xvm_conf["tankrange"]["spotting_limit"]:
                view_distance = min(445, view_distance)

            if not xvm_conf["tankrange"]["circle_view"]["filled"]:
                xvm_conf["circles"]["special"].append({
                    tank_name: {
                        "$ref": {
                            "path": "tankrange.circle_view"
                        },
                        "distance": view_distance
                    }
                })
            else:
                xvm_conf["circles"]["special"].append({
                    tank_name: {
                        "$ref": {
                            "path": "tankrange.circle_view"
                        },
                        "thickness": (view_distance * 0.25) - 14,
                        "distance": view_distance * 0.5
                    }
                })

            # store only when changes
            if not oldCircles.has_key("tankrange.circle_view") or float(
                    oldCircles["tankrange.circle_view"]) != view_distance:
                saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_view"):
            saveConfig = True

        # Add Artillery Range
        artillery_range = 0
        if xvm_conf["tankrange"]["circle_artillery"][
                "enabled"] and "SPG" in g_itemsCache.items.getVehicle(
                    self.__vehInvID).descriptor.type.tags:
            for shell in g_itemsCache.items.getVehicle(
                    self.__vehInvID).descriptor.gun["shots"]:
                artillery_range = max(
                    artillery_range,
                    round(math.pow(shell["speed"], 2) / shell["gravity"]))

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Calculated Firing Range:", artillery_range)

            if not xvm_conf["tankrange"]["circle_artillery"]["filled"]:
                xvm_conf["circles"]["special"].append({
                    tank_name: {
                        "$ref": {
                            "path": "tankrange.circle_artillery"
                        },
                        "distance": artillery_range
                    }
                })
            else:
                xvm_conf["circles"]["special"].append({
                    tank_name: {
                        "$ref": {
                            "path": "tankrange.circle_artillery"
                        },
                        "thickness": (artillery_range * 0.25) - 14,
                        "distance": artillery_range * 0.5
                    }
                })

            # store only when changes
            if not oldCircles.has_key("tankrange.circle_artillery") or float(
                    oldCircles["tankrange.circle_artillery"]
            ) != artillery_range:
                saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_artillery"):
            saveConfig = True

        # Add Artillery Range
        shell_range = 0
        if xvm_conf["tankrange"]["circle_shell"]["enabled"]:
            for shell in g_itemsCache.items.getVehicle(
                    self.__vehInvID).descriptor.gun["shots"]:
                shell_range = max(shell_range, shell["maxDistance"])

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Calculated Shell Range:", shell_range)

            if shell_range < 445:
                if not xvm_conf["tankrange"]["circle_shell"]["filled"]:
                    xvm_conf["circles"]["special"].append({
                        tank_name: {
                            "$ref": {
                                "path": "tankrange.circle_shell"
                            },
                            "distance": shell_range
                        }
                    })
                else:
                    xvm_conf["circles"]["special"].append({
                        tank_name: {
                            "$ref": {
                                "path": "tankrange.circle_shell"
                            },
                            "thickness": (shell_range * 0.25) - 14,
                            "distance": shell_range * 0.5
                        }
                    })

                # store only when changes
                if not oldCircles.has_key("tankrange.circle_shell") or float(
                        oldCircles["tankrange.circle_shell"]) != shell_range:
                    saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_shell"):
            saveConfig = True

        # Write result
        if saveConfig:
            f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"')
            f.write(
                unicode(
                    json.dumps(xvm_conf,
                               ensure_ascii=False,
                               indent=2,
                               sort_keys=True)))
            f.close()

        # notify changes
        if saveConfig and xvm_conf["tankrange"]["notify_changes"]:
            msg = "{0}: View Distance: {1}m".format(
                g_itemsCache.items.getVehicle(self.__vehInvID).userName,
                round(view_distance, 1))
            if binocular_distance:
                msg += " + Binoculars: {0}m".format(
                    round(binocular_distance, 1))
            if artillery_range:
                msg += " Artillery Range: {0}m".format(
                    round(artillery_range, 1))
            if shell_range > 0 and shell_range < 445:
                msg += " Shell Range: {0}m".format(round(shell_range, 1))
            SystemMessages.pushMessage(msg,
                                       type=SystemMessages.SM_TYPE.Information)

    @process
    def __updateCrew(self):
        from gui.shared.utils.requesters import Requester
        self.__crew.clear()

        barracks = yield Requester('tankman').getFromInventory()
        for tankman in barracks:
            for crewman in self.item.crew:
                if crewman[1] is not None and crewman[
                        1].invID == tankman.inventoryId:
                    factor = tankman.descriptor.efficiencyOnVehicle(
                        g_itemsCache.items.getVehicle(
                            self.__vehInvID).descriptor)

                    crew_member = {
                        "level": tankman.descriptor.roleLevel * factor[0],
                        "skill": {}
                    }

                    skills = []
                    for skill_name in tankman.descriptor.skills:
                        skills.append({"name": skill_name, "level": 100})

                    if len(skills) != 0:
                        skills[-1]["level"] = tankman.descriptor.lastSkillLevel

                    for skill in skills:
                        crew_member["skill"][skill["name"]] = skill["level"]

                    self.__crew[tankman.descriptor.role] = crew_member

    def __isOptionalEquipped(self, optional_name):
        for item in self.item.descriptor.optionalDevices:
            if item is not None and optional_name in item.name:
                return True
        return False

    def __isConsumableEquipped(self, consumable_name):
        from gui.shared.utils.requesters import VehicleItemsRequester

        for item in self.item.eqsLayout:
            if item is not None and consumable_name in item.descriptor.name:
                return True
        return False

    def __changeDone(self):
        self.__clearChangeCallback()
        if isPlayerAccount():
            self.onChanged()
        Waiting.hide('updateCurrentVehicle')

    def __clearChangeCallback(self):
        if self.__changeCallbackID is not None:
            BigWorld.cancelCallback(self.__changeCallbackID)
            self.__changeCallbackID = None

    def __checkPrebattleLockedVehicle(self):
        clientPrb = prb_control.getClientPrebattle()
        if clientPrb is not None:
            rosters = prb_control.getPrebattleRosters(prebattle=clientPrb)
            for rId, roster in rosters.iteritems():
                if BigWorld.player().id in roster:
                    vehCompDescr = roster[BigWorld.player().id].get(
                        'vehCompDescr', '')
                    if len(vehCompDescr):
                        vehDescr = vehicles.VehicleDescr(vehCompDescr)
                        vehicle = g_itemsCache.items.getItemByCD(
                            vehDescr.type.compactDescr)
                        if vehicle is not None:
                            return vehicle.invID
        return 0

    def __repr__(self):
        return 'CurrentVehicle(%s)' % str(self.item)
Пример #46
0
class _ClanCache(object):
    def __init__(self):
        self.__waitForSync = False
        self.__fortProvider = None
        self.__clanMembersLen = None
        self.__clanMotto = ''
        self.__clanDescription = ''
        self.onSyncStarted = Event()
        self.onSyncCompleted = Event()
        return

    def init(self):
        self.__fortProvider = ClientFortProvider()

    def fini(self):
        self.onSyncStarted.clear()
        self.onSyncCompleted.clear()
        self.clear()

    def onAccountShowGUI(self):
        self.__startFortProvider()

    def onAvatarBecomePlayer(self):
        self.__stopFortProvider()

    def onDisconnected(self):
        self.__stopFortProvider()

    @property
    def waitForSync(self):
        return self.__waitForSync

    @async
    def update(self, diff=None, callback=None):
        self.__invalidateData(diff, callback)

    def clear(self):
        self.__fortProvider = None
        return

    @storage_getter('users')
    def usersStorage(self):
        return None

    @property
    def fortProvider(self):
        return self.__fortProvider

    @property
    def clanDBID(self):
        from gui.shared import g_itemsCache
        return g_itemsCache.items.stats.clanDBID

    @property
    def isInClan(self):
        """
        @return: is current player in clan
        """
        return self.clanDBID is not None and self.clanDBID != 0

    @property
    def clanMembers(self):
        members = set()
        if self.isInClan:
            members = set(self.usersStorage.getClanMembersIterator(False))
        return members

    @property
    def clanInfo(self):
        from gui.shared import g_itemsCache
        info = g_itemsCache.items.stats.clanInfo
        if info and len(info) > 1:
            return info
        else:
            return (None, None, -1, 0, 0)

    @property
    def clanName(self):
        return passCensor(html.escape(self.clanInfo[0]))

    @property
    def clanAbbrev(self):
        return self.clanInfo[1]

    @property
    def clanMotto(self):
        return self.__clanMotto

    @property
    def clanDescription(self):
        return self.__clanDescription

    @property
    def clanTag(self):
        result = self.clanAbbrev
        if result:
            return '[%s]' % result
        return result

    @property
    def clanCommanderName(self):
        for member in self.clanMembers:
            if member.getClanRole() == CLAN_MEMBER_FLAGS.LEADER:
                return member.getName()

        return None

    @property
    def clanRole(self):
        user = self.usersStorage.getUser(getAccountDatabaseID())
        if user:
            role = user.getClanRole()
        else:
            role = 0
        return role

    @property
    def isClanLeader(self):
        return self.clanRole == CLAN_MEMBER_FLAGS.LEADER

    @async
    @process
    def getClanEmblemID(self, callback):
        clanEmblem = None
        if self.isInClan:
            tID = 'clanInfo' + BigWorld.player().name
            clanEmblem = yield self.getClanEmblemTextureID(
                self.clanDBID, False, tID)
        callback(clanEmblem)
        return

    @async
    def getFileFromServer(self, clanId, fileType, callback):
        if not BigWorld.player().serverSettings['file_server'].has_key(
                fileType):
            LOG_ERROR("Invalid server's file type: %s" % fileType)
            self._valueResponse(0, (None, None), callback)
            return None
        else:
            clan_emblems = BigWorld.player(
            ).serverSettings['file_server'][fileType]
            BigWorld.player().customFilesCache.get(
                clan_emblems['url_template'] % clanId,
                lambda url, file: self._valueResponse(0,
                                                      (url, file), callback),
                True)
            return None

    @async
    @process
    def getClanEmblemTextureID(self, clanDBID, isBig, textureID, callback):
        import imghdr
        if clanDBID is not None and clanDBID != 0:
            _, clanEmblemFile = yield self.getFileFromServer(
                clanDBID,
                'clan_emblems_small' if not isBig else 'clan_emblems_big')
            if clanEmblemFile and imghdr.what(None,
                                              clanEmblemFile) is not None:
                BigWorld.wg_addTempScaleformTexture(textureID, clanEmblemFile)
                callback(textureID)
                return
        callback(None)
        return

    def getClanRoleUserString(self):
        position = self.clanInfo[3]
        return getClanRoleString(position)

    def onClanInfoReceived(self, clanDBID, clanName, clanAbbrev, clanMotto,
                           clanDescription):
        self.__clanMotto = passCensor(html.escape(clanMotto))
        self.__clanDescription = passCensor(html.escape(clanDescription))

    def _valueResponse(self, resID, value, callback):
        if resID < 0:
            LOG_ERROR(
                '[class %s] There is error while getting data from cache: %s[%d]'
                % (self.__class__.__name__, code2str(resID), resID))
            return callback(value)
        callback(value)

    def _onResync(self):
        if not self.__waitForSync:
            self.__invalidateData()

    def __invalidateData(self, diff=None, callback=lambda *args: None):
        if diff is not None:
            if 'stats' in diff and 'clanInfo' in diff['stats']:
                self.__fortProvider.resetState()
        callback(True)
        return

    def __startFortProvider(self):
        self.__clanMembersLen = len(self.clanMembers)
        g_messengerEvents.users.onClanMembersListChanged += self.__me_onClanMembersListChanged
        self.__fortProvider.start(self)

    def __stopFortProvider(self):
        self.__clanMembersLen = None
        g_messengerEvents.users.onClanMembersListChanged -= self.__me_onClanMembersListChanged
        self.__fortProvider.stop()
        return

    def __me_onClanMembersListChanged(self):
        clanMembersLen = len(self.clanMembers)
        if self.__clanMembersLen is not None and clanMembersLen != self.__clanMembersLen:
            self.__clanMembersLen = clanMembersLen
            self.__fortProvider.resetState()
        self.__fortProvider.notify('onClanMembersListChanged')
        return
Пример #47
0
class _CurrentVehicle():
    def __init__(self):
        self.__vehInvID = 0
        self.__changeCallbackID = None
        self.__historicalBattle = None
        self.onChanged = Event()
        self.onChangeStarted = Event()
        self.__crew = {}

    def init(self):
        g_clientUpdateManager.addCallbacks({
            'inventory': self.onInventoryUpdate,
            'cache.vehsLock': self.onLocksUpdate
        })
        game_control.g_instance.igr.onIgrTypeChanged += self.onIgrTypeChanged
        prbVehicle = self.__checkPrebattleLockedVehicle()
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        self.selectVehicle(prbVehicle or storedVehInvID)

    def destroy(self):
        self.__vehInvID = 0
        self.__clearChangeCallback()
        self.onChanged.clear()
        self.onChangeStarted.clear()
        g_clientUpdateManager.removeObjectCallbacks(self)
        game_control.g_instance.igr.onIgrTypeChanged -= self.onIgrTypeChanged
        g_hangarSpace.removeVehicle()
        self.selectNoVehicle()

    def onIgrTypeChanged(self, *args):
        self.refreshModel()

    def onInventoryUpdate(self, invDiff):
        vehsDiff = invDiff.get(GUI_ITEM_TYPE.VEHICLE, {})
        isVehicleSold = False
        isVehicleDescrChanged = False
        if 'compDescr' in vehsDiff and self.__vehInvID in vehsDiff['compDescr']:
            isVehicleSold = vehsDiff['compDescr'][self.__vehInvID] is None
            isVehicleDescrChanged = not isVehicleSold
        if isVehicleSold or self.__vehInvID == 0:
            self.selectVehicle()
        else:
            isRepaired = 'repair' in vehsDiff and self.__vehInvID in vehsDiff['repair']
            isCustomizationChanged = 'igrCustomizationsLayout' in vehsDiff and self.__vehInvID in vehsDiff['igrCustomizationsLayout']
            isComponentsChanged = GUI_ITEM_TYPE.TURRET in invDiff or GUI_ITEM_TYPE.GUN in invDiff
            isVehicleChanged = len(filter(lambda hive: self.__vehInvID in hive or (self.__vehInvID, '_r') in hive, vehsDiff.itervalues())) > 0

            if isComponentsChanged or isRepaired or isVehicleDescrChanged or isCustomizationChanged:
                self.refreshModel()
            if isVehicleChanged or isRepaired:
                self.onChanged()

        if self.isPresent():
            self.__updateViewRange()

    def onLocksUpdate(self, locksDiff):
        if self.__vehInvID in locksDiff:
            self.refreshModel()

    def refreshModel(self):
        if self.isPresent() and self.isInHangar() and self.item.modelState:
            if self.__historicalBattle is not None:
                historical = g_tankActiveCamouflage['historical']
                if self.__historicalBattle.canParticipateWith(self.item.intCD) and self.item.intCD not in historical:
                    historical[self.item.intCD] = self.__historicalBattle.getArenaType().vehicleCamouflageKind
            if self.item.intCD not in g_tankActiveCamouflage:
                availableKinds = []
                currKind = 0
                for id, startTime, days in self.item.descriptor.camouflages:
                    if id is not None:
                        availableKinds.append(currKind)
                    currKind += 1

                if len(availableKinds) > 0:
                    g_tankActiveCamouflage[self.item.intCD] = random.choice(availableKinds)
            g_hangarSpace.updateVehicle(self.item, self.__historicalBattle)
        else:
            g_hangarSpace.removeVehicle()
        return

    @property
    def invID(self):
        return self.__vehInvID

    @property
    def item(self):
        if self.__vehInvID > 0:
            return g_itemsCache.items.getVehicle(self.__vehInvID)
        else:
            return None

    def isPresent(self):
        return self.item is not None

    def isBroken(self):
        return self.isPresent() and self.item.isBroken

    def isDisabledInRoaming(self):
        return self.isPresent() and self.item.isDisabledInRoaming

    def isLocked(self):
        return self.isPresent() and self.item.isLocked

    def isClanLock(self):
        return self.isPresent() and self.item.clanLock > 0

    def isCrewFull(self):
        return self.isPresent() and self.item.isCrewFull

    def isInBattle(self):
        return self.isPresent() and self.item.isInBattle

    def isInHangar(self):
        return self.isPresent() and not self.item.isInBattle

    def isAwaitingBattle(self):
        return self.isPresent() and self.item.isAwaitingBattle

    def isAlive(self):
        return self.isPresent() and self.item.isAlive

    def isReadyToPrebattle(self):
        return self.isPresent() and self.item.isReadyToPrebattle

    def isReadyToFight(self):
        return self.isPresent() and self.item.isReadyToFight

    def isAutoLoadFull(self):
        if self.isPresent() and self.item.isAutoLoad:
            for shell in self.item.shells:
                if shell.count != shell.defaultCount:
                    return False

        return True

    def isAutoEquipFull(self):
        if self.isPresent() and self.item.isAutoEquip:
            for i, e in enumerate(self.item.eqsLayout):
                if e != self.item.eqs[i]:
                    return False

        return True

    def selectVehicle(self, vehInvID = 0):
        vehicle = g_itemsCache.items.getVehicle(vehInvID)
        if vehicle is None:
            invVehs = g_itemsCache.items.getVehicles(criteria=REQ_CRITERIA.INVENTORY)
            if len(invVehs):
                vehInvID = sorted(invVehs.itervalues())[0].invID
            else:
                vehInvID = 0
        self.__selectVehicle(vehInvID)

    def selectNoVehicle(self):
        self.__selectVehicle(0)

    def getHangarMessage(self):
        if self.isPresent():
            state, stateLvl = self.item.getState()
            return ('#menu:currentVehicleStatus/' + state, stateLvl)
        return (MENU.CURRENTVEHICLESTATUS_NOTPRESENT, Vehicle.VEHICLE_STATE_LEVEL.CRITICAL)

    def setHistoricalBattle(self, historicalBattle):
        g_tankActiveCamouflage['historical'] = {}
        self.__historicalBattle = historicalBattle
        self.refreshModel()
        self.onChanged()

    def __selectVehicle(self, vehInvID):
        if vehInvID == self.__vehInvID:
            return
        Waiting.show('updateCurrentVehicle', isSingle=True)
        self.onChangeStarted()
        self.__vehInvID = vehInvID
        AccountSettings.setFavorites(CURRENT_VEHICLE, vehInvID)
        self.refreshModel()
        if not self.__changeCallbackID:
            self.__changeCallbackID = BigWorld.callback(0.1, self.__changeDone)

        if self.isPresent():
            self.__updateViewRange()

    def __updateViewRange(self):
        # Set Defaults
        xvm_conf = {}
        saveConfig = False

        # Load configuration
        xvm_configuration_file = os.getcwd() + os.sep + 'res_mods' + os.sep + 'xvm' + os.sep + 'tankrange.xc'
        if not os.path.exists(xvm_configuration_file):
            SystemMessages.pushMessage("Configuration file missing (" + xvm_configuration_file + ")", type=SystemMessages.SM_TYPE.Error)
            return
        else:
            try:
                data = ""
                blockComment = False

                f = codecs.open(xvm_configuration_file, 'r', '"utf-8-sig"')
                for line in f.read().split('\n'):
                    line = line.strip()
                    if line != "":
                        # Start of block comment
                        comment = line.find("/*")
                        if comment != -1 and comment == 0:
                            blockComment = True
                            continue

                        # End of block comment
                        comment = line.find("*/")
                        if comment != -1:
                            blockComment = False
                            continue

                        # Block Comment
                        if blockComment == True:
                            continue

                        # Start of line comment
                        comment = line.find("//")
                        if comment != -1 and comment == 0:
                            continue

                        # Remove end of line comments
                        position = 0
                        for i in range(0,line.count("//")):
                            comment = line.find("//", position+2)
                            if comment != -1:
                                colon = line.find(":")

                                startSpeach = line.find("\"", colon+1)
                                if startSpeach > comment:
                                    line = line[:comment].strip()

                                endSpeach = line.find("\"", startSpeach+1)
                                if comment > endSpeach:
                                    line = line[:comment].strip()

                            position += comment

                        if line != "":
                            data += line + '\n'
                f.close()

                xvm_conf = json.loads(data)
            except Exception as e:
                SystemMessages.pushMessage("Parsing configuration file: " + str(e), type=SystemMessages.SM_TYPE.Error)
                return

        # Code for migrating old configuration files (v1.5->v1.6)
        if not xvm_conf["tankrange"].has_key("spotting_limit"):
            xvm_conf["tankrange"]["spotting_limit"] = True
            saveConfig = True

        # Code for migrating old configuration files (v1.7->v1.8)
        if not xvm_conf["tankrange"].has_key("notify_changes"):
            xvm_conf["tankrange"]["notify_changes"] = True
            saveConfig = True

        # Get name
        tank_name = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.name.replace(":","-")
        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Tank Name: ", tank_name)

        # Only update when we have a crew
        if not self.isCrewFull():
            if xvm_conf['tankrange']['logging']:
                LOG_NOTE('Crew is missing.')
            return

        # Remove current circles
        remaining = []
        oldCircles = {}
        for tank_data in xvm_conf["circles"]["special"]:
            if tank_data.keys()[0] != tank_name:
                remaining.append(tank_data)
            elif tank_data[tank_name].has_key('distance') and tank_data[tank_name].has_key('$ref') and tank_data[tank_name]['$ref'].has_key('path'):
                oldCircles[tank_data[tank_name]['$ref']['path']] = tank_data[tank_name]['distance']

        xvm_conf["circles"]["special"] = remaining

        # Get type
        if xvm_conf["tankrange"]["ignore_artillery"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags:
            f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"')
            f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2)))
            f.close()

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Ignoring " + vehicle_type + " tank.")
            return

        # Get view distance
        view_distance = g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.turret["circularVisionRadius"]
        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Base View Range: ", view_distance)

        # Check for Ventilation
        ventilation = self.__isOptionalEquipped("improvedVentilation")
        if xvm_conf["tankrange"]["logging"] and ventilation:
            LOG_NOTE("Ventilation Found")

        # Check for Consumable
        consumable = False
        if self.__isConsumableEquipped("ration"):
            consumable = True
        if self.__isConsumableEquipped("chocolate"):
            consumable = True
        if self.__isConsumableEquipped("cocacola"):
            consumable = True
        if self.__isConsumableEquipped("hotCoffee"):
            consumable = True
        if xvm_conf["tankrange"]["logging"] and consumable:
            LOG_NOTE("Premium Consumable Found")

        # Update crew
        self.__updateCrew()

        # Check for Brothers In Arms
        brothers_in_arms = True
        if len(self.__crew) == 0:
            brothers_in_arms = False
        else:
            for name, data in self.__crew.iteritems():
                if "brotherhood" not in data["skill"]:
                    brothers_in_arms = False
                elif data["skill"]["brotherhood"] != 100:
                    brothers_in_arms = False

        if xvm_conf["tankrange"]["logging"] and brothers_in_arms:
            LOG_NOTE("BIA Found")

        # Calculate commander bonus
        commander_skill = 0.0
        if "commander" in self.__crew:
            commander_skill = self.__crew["commander"]["level"]

            if brothers_in_arms == True:
                commander_skill += 5.0
            if ventilation == True:
                commander_skill += 5.0
            if consumable == True:
                commander_skill += 10.0

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Commander Skill: ", commander_skill)

        # Calculate other bonuses
        other_bonus = 1.0
        for name, data in self.__crew.iteritems():
            # Calculate recon skills
            if "commander_eagleEye" in data["skill"]:
                other_bonus *= 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] )

                if xvm_conf["tankrange"]["logging"]:
                    LOG_NOTE("Recon Bonus: ", 1.0 + ( 0.0002 * data["skill"]["commander_eagleEye"] ))

            # Calculate Situational Awareness Skill
            if "radioman_finder" in data["skill"]:
                other_bonus *= 1.0 + ( 0.0003 * data["skill"]["radioman_finder"] )

                if xvm_conf["tankrange"]["logging"]:
                    LOG_NOTE("Situational Awareness Bonus: ", 1.0 + ( 0.0003 * data["skill"]["radioman_finder"] ))

        # Check for Binoculars
        binoculars = self.__isOptionalEquipped("stereoscope")
        if xvm_conf["tankrange"]["logging"] and binoculars:
            LOG_NOTE("Binoculars Found")

        # Check for Coated Optics
        coated_optics = self.__isOptionalEquipped("coatedOptics")
        if xvm_conf["tankrange"]["logging"] and coated_optics:
            LOG_NOTE("Coated Optics Found")

        # Calculate final value
        view_distance = ((view_distance / 0.875) * (0.00375 * commander_skill + 0.5)) * other_bonus

        if xvm_conf["tankrange"]["logging"]:
            LOG_NOTE("Other Bonus:", other_bonus)
            LOG_NOTE("Final View Range: ", view_distance)

        # Add binocular Circles
        binocular_distance = None
        if xvm_conf["tankrange"]["circle_binocular"]["enabled"] and binoculars:
            binocular_distance = view_distance * 1.25
            if xvm_conf["tankrange"]["spotting_limit"]:
                binocular_distance = min(445, binocular_distance);

            if not xvm_conf["tankrange"]["circle_binocular"]["filled"]:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "distance": binocular_distance } })
            else:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_binocular" }, "thickness": (binocular_distance*0.25)-14, "distance": binocular_distance*0.5 } })

            # store only when changes
            if not oldCircles.has_key("tankrange.circle_binocular") or float(oldCircles["tankrange.circle_binocular"]) != binocular_distance:
                saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_binocular"):
            saveConfig = True

        # Add standard Circles
        if coated_optics == True:
            view_distance = min(view_distance * 1.1, 500)

        if xvm_conf["tankrange"]["circle_view"]["enabled"]:
            if xvm_conf["tankrange"]["spotting_limit"]:
                view_distance = min(445, view_distance);

            if not xvm_conf["tankrange"]["circle_view"]["filled"]:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "distance": view_distance } })
            else:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_view" }, "thickness": (view_distance*0.25)-14, "distance": view_distance*0.5 } })

            # store only when changes
            if not oldCircles.has_key("tankrange.circle_view") or float(oldCircles["tankrange.circle_view"]) != view_distance:
                saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_view"):
            saveConfig = True

        # Add Artillery Range
        artillery_range = 0
        if xvm_conf["tankrange"]["circle_artillery"]["enabled"] and "SPG" in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.type.tags:
            for shell in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.gun["shots"]:
                artillery_range = max(artillery_range, round(math.pow(shell["speed"],2) / shell["gravity"]))

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Calculated Firing Range:", artillery_range)

            if not xvm_conf["tankrange"]["circle_artillery"]["filled"]:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "distance": artillery_range } })
            else:
                xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_artillery" }, "thickness": (artillery_range*0.25)-14, "distance": artillery_range*0.5 } })

            # store only when changes
            if not oldCircles.has_key("tankrange.circle_artillery") or float(oldCircles["tankrange.circle_artillery"]) != artillery_range:
                saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_artillery"):
            saveConfig = True

        # Add Artillery Range
        shell_range = 0
        if xvm_conf["tankrange"]["circle_shell"]["enabled"]:
            for shell in g_itemsCache.items.getVehicle(self.__vehInvID).descriptor.gun["shots"]:
                shell_range = max(shell_range, shell["maxDistance"])

            if xvm_conf["tankrange"]["logging"]:
                LOG_NOTE("Calculated Shell Range:", shell_range)

            if shell_range < 445:
                if not xvm_conf["tankrange"]["circle_shell"]["filled"]:
                    xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_shell" }, "distance": shell_range } })
                else:
                    xvm_conf["circles"]["special"].append({ tank_name: { "$ref": { "path": "tankrange.circle_shell" }, "thickness": (shell_range*0.25)-14, "distance": shell_range*0.5 } })

                # store only when changes
                if not oldCircles.has_key("tankrange.circle_shell") or float(oldCircles["tankrange.circle_shell"]) != shell_range:
                    saveConfig = True

        # Remove old circles
        elif oldCircles.has_key("tankrange.circle_shell"):
            saveConfig = True

        # Write result
        if saveConfig:
            f = codecs.open(xvm_configuration_file, 'w', '"utf-8-sig"')
            f.write(unicode(json.dumps(xvm_conf, ensure_ascii=False, indent=2, sort_keys=True)))
            f.close()

        # notify changes
        if saveConfig and xvm_conf["tankrange"]["notify_changes"]:
            msg = "{0}: View Distance: {1}m".format(g_itemsCache.items.getVehicle(self.__vehInvID).userName, round(view_distance,1) )
            if binocular_distance:
                msg += " + Binoculars: {0}m".format( round(binocular_distance,1) )
            if artillery_range:
                msg += " Artillery Range: {0}m".format( round(artillery_range,1) )
            if shell_range > 0 and shell_range < 445:
                msg += " Shell Range: {0}m".format( round(shell_range,1) )
            SystemMessages.pushMessage(msg, type=SystemMessages.SM_TYPE.Information)

    @process
    def __updateCrew(self):
        from gui.shared.utils.requesters import Requester
        self.__crew.clear()

        barracks = yield Requester('tankman').getFromInventory()
        for tankman in barracks:
            for crewman in self.item.crew:
                if crewman[1] is not None and crewman[1].invID == tankman.inventoryId:
                    factor = tankman.descriptor.efficiencyOnVehicle(g_itemsCache.items.getVehicle(self.__vehInvID).descriptor)

                    crew_member = {
                        "level": tankman.descriptor.roleLevel * factor[0], 
                        "skill": {} 
                    }

                    skills = []
                    for skill_name in tankman.descriptor.skills:
                        skills.append({ "name": skill_name, "level": 100 })

                    if len(skills) != 0:
                        skills[-1]["level"] = tankman.descriptor.lastSkillLevel

                    for skill in skills:
                        crew_member["skill"][skill["name"]] = skill["level"]

                    self.__crew[tankman.descriptor.role] = crew_member

    def __isOptionalEquipped(self, optional_name):
        for item in self.item.descriptor.optionalDevices:
            if item is not None and optional_name in item.name:
                return True
        return False

    def __isConsumableEquipped(self, consumable_name):
        from gui.shared.utils.requesters import VehicleItemsRequester

        for item in self.item.eqsLayout:
            if item is not None and consumable_name in item.descriptor.name:
                return True
        return False

    def __changeDone(self):
        self.__clearChangeCallback()
        if isPlayerAccount():
            self.onChanged()
        Waiting.hide('updateCurrentVehicle')

    def __clearChangeCallback(self):
        if self.__changeCallbackID is not None:
            BigWorld.cancelCallback(self.__changeCallbackID)
            self.__changeCallbackID = None

    def __checkPrebattleLockedVehicle(self):
        clientPrb = prb_control.getClientPrebattle()
        if clientPrb is not None:
            rosters = prb_control.getPrebattleRosters(prebattle=clientPrb)
            for rId, roster in rosters.iteritems():
                if BigWorld.player().id in roster:
                    vehCompDescr = roster[BigWorld.player().id].get('vehCompDescr', '')
                    if len(vehCompDescr):
                        vehDescr = vehicles.VehicleDescr(vehCompDescr)
                        vehicle = g_itemsCache.items.getItemByCD(vehDescr.type.compactDescr)
                        if vehicle is not None:
                            return vehicle.invID
        return 0

    def __repr__(self):
        return 'CurrentVehicle(%s)' % str(self.item)