コード例 #1
0
class RankedBattlesUnreachableView(LobbySubView,
                                   RankedBattlesUnreachableViewMeta):
    __rankedController = dependency.descriptor(IRankedBattlesController)
    _COMMON_SOUND_SPACE = RANKED_SUBVIEW_SOUND_SPACE
    __background_alpha__ = 0.5

    def __init__(self, _):
        super(RankedBattlesUnreachableView, self).__init__()
        self.__currentSeason = None
        self.__periodicNotifier = PeriodicNotifier(
            self.__timeTillCurrentSeasonEnd, self.__updateData)
        return

    def onEscapePress(self):
        self.__close()

    def onCloseBtnClick(self):
        self.__close()

    def _populate(self):
        super(RankedBattlesUnreachableView, self)._populate()
        self.__rankedController.onUpdated += self.__update
        self.__update()

    def _dispose(self):
        self.__periodicNotifier.stopNotification()
        self.__periodicNotifier.clear()
        self.__rankedController.onUpdated -= self.__update
        super(RankedBattlesUnreachableView, self)._dispose()

    def __close(self):
        self.fireEvent(events.LoadViewEvent(VIEW_ALIAS.LOBBY_HANGAR),
                       scope=EVENT_BUS_SCOPE.LOBBY)
        self.destroy()

    def __checkDestroy(self):
        if self.__currentSeason is None:
            self.__close()
        return

    def __timeTillCurrentSeasonEnd(self):
        if self.__currentSeason:
            seasonEnd = time_utils.makeLocalServerTime(
                self.__currentSeason.getEndDate())
            return time_utils.getTimeDeltaFromNowInLocal(seasonEnd)
        return time_utils.ONE_MINUTE

    def __update(self):
        self.__currentSeason = self.__rankedController.getCurrentSeason()
        self.__checkDestroy()
        self.__periodicNotifier.startNotification()
        self.__updateData()

    def __updateData(self):
        minLvl, maxLvl = self.__rankedController.getSuitableVehicleLevels()
        self.as_setDataS(getUnreachableVO(self.__currentSeason, minLvl,
                                          maxLvl))
コード例 #2
0
class RankedMainSeasonOnPage(RankedMainPage):
    _COMMON_SOUND_SPACE = RANKED_MAIN_PAGE_SOUND_SPACE
    __rankedController = dependency.descriptor(IRankedBattlesController)

    def __init__(self, ctx):
        super(RankedMainSeasonOnPage, self).__init__(ctx)
        self.__currentSeason = None
        self.__periodicNotifier = PeriodicNotifier(self.__getTimeTillCurrentSeasonEnd, self._updateHeader)
        return

    def _dispose(self):
        self.__periodicNotifier.stopNotification()
        self.__periodicNotifier.clear()
        super(RankedMainSeasonOnPage, self)._dispose()

    def _populate(self):
        super(RankedMainSeasonOnPage, self)._populate()
        self.__periodicNotifier.startNotification()

    def _onRegisterFlashComponent(self, viewPy, alias):
        if alias == RANKEDBATTLES_ALIASES.RANKED_BATTLES_REWARDS_UI and self.__selectedRewardsItemID is not None:
            viewPy.setActiveTab(self.__selectedRewardsItemID)
            self.__selectedRewardsItemID = None
        return

    def _update(self):
        self.__currentSeason = self.__rankedController.getCurrentSeason()
        self.__periodicNotifier.startNotification()
        super(RankedMainSeasonOnPage, self)._update()

    def _updateHeader(self):
        self.as_setHeaderDataS(main_page_vos.getRankedMainSeasonOnHeader(self.__currentSeason, self._selectedItemID))

    def _updateMenuItems(self, isRankedShopEnabled, isYearLBEnabled, yearLBSize):
        leagues = self.__rankedController.isAccountMastered()
        menuItems = main_page_vos.getRankedMainSeasonOnItems(isRankedShopEnabled, isYearLBEnabled, yearLBSize, leagues)
        self.as_setDataS({'menuItems': menuItems,
         'selectedIndex': self._getSelectedIdx(menuItems)})

    def _updateSounds(self, onClose=False):
        super(RankedMainSeasonOnPage, self)._updateSounds()
        soundManager = self.__rankedController.getSoundManager()
        if self.__rankedController.isAccountMastered():
            soundManager.setProgressSound()
        elif onClose:
            soundManager.setDefaultProgressSound()
        else:
            soundManager.setProgressSound(self.__rankedController.getCurrentDivision().getUserID())

    def _processContext(self, ctx):
        super(RankedMainSeasonOnPage, self)._processContext(ctx)
        self.__selectedRewardsItemID = ctx.get('rewardsSelectedTab', None)
        return

    def __getTimeTillCurrentSeasonEnd(self):
        return time_utils.getTimeDeltaFromNowInLocal(time_utils.makeLocalServerTime(self.__currentSeason.getEndDate())) if self.__currentSeason else time_utils.ONE_MINUTE
コード例 #3
0
class NyBroTokenTooltip(ViewImpl):
    __slots__ = ('__notifier',)
    __eventsCache = dependency.descriptor(IEventsCache)
    __itemsCache = dependency.descriptor(IItemsCache)
    __uiLogger = NyGiftSystemViewTooltipLogger(LogGroups.BRO_ICON.value)

    def __init__(self, layoutID=R.views.lobby.new_year.tooltips.NyBroTokenTooltip()):
        super(NyBroTokenTooltip, self).__init__(ViewSettings(layoutID, model=NyBroTokenTooltipModel()))
        self.__notifier = PeriodicNotifier(getTimerGameDayLeft, self.__updateClearingTimer, (ONE_MINUTE,))

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

    def _onLoading(self, *args, **kwargs):
        super(NyBroTokenTooltip, self)._onLoading()
        with self.viewModel.transaction() as model:
            self.__updateProgression(model=model)
            self.__updateClearingTimer()
        self.__notifier.startNotification()

    def _onLoaded(self, *args, **kwargs):
        super(NyBroTokenTooltip, self)._onLoaded(*args, **kwargs)
        self.__uiLogger.onTooltipOpened()

    def _initialize(self, *args, **kwargs):
        super(NyBroTokenTooltip, self)._initialize()
        self.__eventsCache.onSyncCompleted += self.__updateProgression

    def _finalize(self):
        super(NyBroTokenTooltip, self)._finalize()
        self.__eventsCache.onSyncCompleted -= self.__updateProgression
        self.__notifier.stopNotification()
        self.__notifier.clear()
        self.__uiLogger.onTooltipClosed()

    def __invalidateStages(self, requiredAmount):
        requiredAmount.clear()
        progressQuests = self.__eventsCache.getHiddenQuests(giftsPogressQuestFilter)
        for quest in sorted(progressQuests.itervalues(), key=lambda q: q.getID()):
            requiredAmount.addNumber(getGiftsTokensCountByID(quest.getID()))

        requiredAmount.invalidate()

    def __updateClearingTimer(self):
        self.viewModel.setRebootTimer(getDayTimeLeft())

    @replaceNoneKwargsModel
    def __updateProgression(self, model=None):
        subprogressQuests = self.__eventsCache.getHiddenQuests(giftsSubprogressQuestFilter)
        subprogressQuest = subprogressQuests.itervalues().next() if subprogressQuests else None
        model.setCurrentCount(self.__itemsCache.items.tokens.getTokenCount(NY_GIFT_SYSTEM_SUBPROGRESS_TOKEN))
        model.setTotalCount(getGiftsTokensCountByID(subprogressQuest.getID()) if subprogressQuest else 0)
        self.__invalidateStages(model.getAmountRequired())
        return
class WotPlusPiggyBankCard(ViewImpl):
    _lobbyContext = dependency.descriptor(ILobbyContext)
    _itemsCache = dependency.descriptor(IItemsCache)
    _gameSession = dependency.descriptor(IGameSessionController)

    def __init__(self):
        settings = ViewSettings(R.views.lobby.premacc.dashboard.piggy_bank_cards.wot_plus_piggy_bank.WotPlusPiggyBankCard())
        settings.model = WotPlusPiggyBankCardModel()
        self._notifier = None
        self._premState = None
        self._wotPlusState = None
        self._wotPlusInfo = BigWorld.player().renewableSubscription
        super(WotPlusPiggyBankCard, self).__init__(settings)
        return

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

    def _onLoading(self, *args, **kwargs):
        super(WotPlusPiggyBankCard, self)._onLoading()
        self._addListeners()
        self._notifier = PeriodicNotifier(self._getDeltaTime, self._updateTimer, (time_utils.ONE_MINUTE,))
        self._isTimerEnabled = False
        self._premState = BankState.AVAILABLE
        self._wotPlusState = BankState.AVAILABLE
        with self.viewModel.transaction() as model:
            self._setMaxAmounts(model=model)
            self._setCurrentCredits(model=model)
            self._setCurrentGold(model=model)
            self._updatePremState(model=model)
            self._updateWotPlusState(model=model)
            self._updateTimer(model=model)

    def _finalize(self):
        self._notifier.stopNotification()
        self._notifier.clear()
        self._notifier = None
        self._removeListeners()
        super(WotPlusPiggyBankCard, self)._finalize()
        return

    @replaceNoneKwargsModel
    def _setMaxAmounts(self, model=None):
        serverSettings = self._lobbyContext.getServerSettings()
        maxAmount = serverSettings.getPiggyBankConfig().get('creditsThreshold', PiggyBankConstants.MAX_AMOUNT)
        maxAmountStr = self.gui.systemLocale.getNumberFormat(maxAmount)
        model.setCreditMaxAmount(maxAmountStr)
        maxAmount = serverSettings.getRenewableSubMaxGoldReserveCapacity()
        maxAmountStr = self.gui.systemLocale.getNumberFormat(maxAmount)
        model.setGoldMaxAmount(maxAmountStr)

    @replaceNoneKwargsModel
    def _setCurrentCredits(self, value=None, model=None):
        creditsValue = value or self._itemsCache.items.stats.piggyBank.get('credits', 0)
        creditsValueStr = self.gui.systemLocale.getNumberFormat(creditsValue)
        model.setCreditCurrentAmount(creditsValueStr)

    def _updateCredits(self, value=None):
        self._setCurrentCredits(value)

    @replaceNoneKwargsModel
    def _setCurrentGold(self, gold=None, model=None):
        goldValue = gold or self._itemsCache.items.stats.piggyBank.get('gold', 0)
        goldValueStr = self.gui.systemLocale.getNumberFormat(goldValue)
        model.setGoldCurrentAmount(goldValueStr)

    def _updateGold(self, gold=None):
        self._setCurrentGold(gold)

    @replaceNoneKwargsModel
    def _updatePremState(self, model=None):
        serverSettings = self._lobbyContext.getServerSettings()
        isEnabled = serverSettings.getPiggyBankConfig().get('enabled', False)
        hasPremium = self._itemsCache.items.stats.isActivePremium(PREMIUM_TYPE.PLUS)
        state = BankState.AVAILABLE
        if not isEnabled:
            state = BankState.DISABLE
        elif hasPremium:
            state = BankState.ACTIVE
        if self._premState != state:
            self._premState = state
            self._updateTimerStatus()
        model.setPremState(state.value)

    def _updatePrem(self, *args):
        self._updatePremState()

    @replaceNoneKwargsModel
    def _updateWotPlusState(self, model=None):
        serverSettings = self._lobbyContext.getServerSettings()
        isGoldEnabled = serverSettings.isRenewableSubGoldReserveEnabled()
        hasWotPlus = self._wotPlusInfo.isEnabled()
        state = BankState.AVAILABLE
        if not isGoldEnabled:
            state = BankState.DISABLE
        elif hasWotPlus:
            state = BankState.ACTIVE
        if self._wotPlusState != state:
            self._wotPlusState = state
            self._updateTimerStatus()
        model.setWotPlusState(state.value)

    @replaceNoneKwargsModel
    def _updateTimer(self, model=None):
        isTimerEnabled = self._getIsTimerEnabled()
        if not isTimerEnabled:
            return
        finishDeltatime = self._getDeltaTime()
        model.setTimeToOpen(finishDeltatime)

    def _getDeltaTime(self):
        serverSettings = self._lobbyContext.getServerSettings()
        config = serverSettings.getPiggyBankConfig()
        data = self._itemsCache.items.stats.piggyBank
        return getDeltaTimeHelper(config, data)

    def _getIsTimerEnabled(self):
        hasGold = self._itemsCache.items.stats.piggyBank.get('gold', 0)
        hasCredits = self._itemsCache.items.stats.piggyBank.get('credits', 0)
        return self._wotPlusState == BankState.ACTIVE or self._premState == BankState.ACTIVE or hasCredits or hasGold

    def _updateTimerStatus(self):
        isTimerEnabled = self._getIsTimerEnabled()
        if self._isTimerEnabled != isTimerEnabled:
            self._isTimerEnabled = isTimerEnabled
            if isTimerEnabled:
                self._notifier.startNotification()
                self._updateTimer()
            else:
                self._notifier.stopNotification()
        elif isTimerEnabled:
            self._notifier.startNotification()
            self._updateTimer()

    def _updateLastSmashTimestamp(self, *args):
        self._updateTimerStatus()

    def _onServerSettingsChange(self, diff):
        if self.viewStatus == ViewStatus.DESTROYED:
            return
        if PremiumConfigs.PIGGYBANK not in diff and RENEWABLE_SUBSCRIPTION_CONFIG not in diff:
            return
        diffConfigPiggy = diff.get(PremiumConfigs.PIGGYBANK)
        diffConfigGold = diff.get(RENEWABLE_SUBSCRIPTION_CONFIG)
        if 'creditsThreshold' in diffConfigPiggy or 'maxGoldReserveCapacity' in diffConfigGold:
            self._setMaxAmounts()
        if 'enabled' in diffConfigPiggy:
            self._updatePremState()
        if 'enableGoldReserve' in diffConfigGold:
            self._updateWotPlusState()
        if 'cycleLength' in diffConfigPiggy or 'cycleStartTime' in diffConfigPiggy:
            self._updateTimerStatus()

    def _onWotPlusDataChanged(self, diff):
        if 'isEnabled' in diff:
            self._updateWotPlusState()

    def __onCardClick(self):
        showPiggyBankView()

    def _addListeners(self):
        self.viewModel.onCardClick += self.__onCardClick
        g_clientUpdateManager.addCallbacks({PiggyBankConstants.PIGGY_BANK_CREDITS: self._updateCredits,
         PiggyBankConstants.PIGGY_BANK_GOLD: self._updateGold,
         PiggyBankConstants.PIGGY_BANK_SMASH_TIMESTAMP_CREDITS: self._updateLastSmashTimestamp,
         PiggyBankConstants.PIGGY_BANK_SMASH_TIMESTAMP_GOLD: self._updateLastSmashTimestamp})
        self._gameSession.onPremiumNotify += self._updatePrem
        self._wotPlusInfo.onRenewableSubscriptionDataChanged += self._onWotPlusDataChanged
        self._lobbyContext.getServerSettings().onServerSettingsChange += self._onServerSettingsChange

    def _removeListeners(self):
        self.viewModel.onCardClick -= self.__onCardClick
        g_clientUpdateManager.removeObjectCallbacks(self)
        self._gameSession.onPremiumNotify -= self._updatePrem
        self._wotPlusInfo.onRenewableSubscriptionDataChanged -= self._onWotPlusDataChanged
        self._lobbyContext.getServerSettings().onServerSettingsChange -= self._onServerSettingsChange
コード例 #5
0
class EpicBattlesWidget(EpicBattlesWidgetMeta):
    __epicController = dependency.descriptor(IEpicBattleMetaGameController)

    def __init__(self):
        super(EpicBattlesWidget, self).__init__()
        self.__periodicNotifier = None
        return

    def onWidgetClick(self):
        self.__epicController.openURL()

    def onSoundTrigger(self, triggerName):
        SoundGroups.g_instance.playSound2D(triggerName)

    def update(self):
        if not self.__epicController.isEnabled():
            return
        else:
            if self.__periodicNotifier is not None:
                self.__periodicNotifier.startNotification()
            self.as_setDataS(self.__buildVO()._asdict())
            return

    def _populate(self):
        super(EpicBattlesWidget, self)._populate()
        if not self.__epicController.isEnabled():
            return
        else:
            if self.__periodicNotifier is None:
                self.__periodicNotifier = PeriodicNotifier(
                    self.__epicController.getTimer, self.update)
            self.__periodicNotifier.startNotification()
            return

    def _dispose(self):
        if self.__periodicNotifier is not None:
            self.__periodicNotifier.stopNotification()
            self.__periodicNotifier.clear()
            self.__periodicNotifier = None
        super(EpicBattlesWidget, self)._dispose()
        self.__periodicNotifier = None
        return

    def __buildVO(self):
        season = self.__epicController.getCurrentSeason(
        ) or self.__epicController.getNextSeason()
        currentLevel, _ = self.__epicController.getPlayerLevelInfo()
        cycleNumber = 1
        if season is not None:
            cycleNumber = self.__epicController.getCurrentOrNextActiveCycleNumber(
                season)
        level = currentLevel if self.__epicController.isCurrentCycleActive(
        ) else None
        return EpicBattlesWidgetVO(
            epicMetaLevelIconData=getProgressionIconVODict(cycleNumber, level),
            points=str(self.__getSkillPoints()))

    def __getSkillPoints(self):
        season = self.__epicController.getCurrentSeason()
        if season is None:
            return ''
        else:
            noActiveCycles = not self.__epicController.isCurrentCycleActive()
            now = time_utils.getCurrentLocalServerTimestamp()
            allCyclesInFuture = True
            for cycle in season.getAllCycles().values():
                if cycle.startDate < now:
                    allCyclesInFuture = False
                    break

            if noActiveCycles and allCyclesInFuture:
                return ''
            noNextCycle = season.getNextByTimeCycle(now) is None
            return '' if noActiveCycles and noNextCycle else str(
                self.__epicController.getSkillPoints())
class TenYearsCountdownController(ITenYearsCountdownController):
    __eventsCache = dependency.descriptor(IEventsCache)

    def __init__(self):
        super(TenYearsCountdownController, self).__init__()
        self.onEventStateChanged = Event.Event()
        self.onEventBlockChanged = Event.Event()
        self.onEventMonthsChanged = Event.Event()
        self.onActivePhasesDatesChanged = Event.Event()
        self.onEventFinishChanged = Event.Event()
        self.onEventDataUpdated = Event.Event()
        self.onBlocksDataValidityChanged = Event.Event()
        self.__isEventActive = False
        self.__currentBlock = _CurrentBlock()
        self.__months = {}
        self.__activePhaseDates = {}
        self.__eventFinish = 0
        self.__blocksCount = 0
        self.__eventBaseURL = ''
        self.__isBlocksDataValid = False
        self.__periodicNotifier = None
        return

    def fini(self):
        self.__clear()
        self.__currentBlock = None
        self.onEventStateChanged.clear()
        self.onEventBlockChanged.clear()
        self.onActivePhasesDatesChanged.clear()
        self.onEventMonthsChanged.clear()
        self.onEventFinishChanged.clear()
        self.onEventDataUpdated.clear()
        self.onBlocksDataValidityChanged.clear()
        return

    def onLobbyInited(self, event):
        self.__eventsCache.onSyncCompleted += self.__update
        self.__update()

    def onAvatarBecomePlayer(self):
        self.__clear()

    def onDisconnected(self):
        self.__clear()

    def isEnabled(self):
        return self.__isEventActive

    def isCurrentBlockActive(self):
        return self.__isEventActive and self.__currentBlock.state == EventBlockStates.ACTIVE

    def getCurrentBlock(self):
        return self.__currentBlock

    def getCurrentBlockNumber(self):
        return self.__currentBlock.number if self.__currentBlock is not None else 0

    def getCurrentBlockState(self):
        return self.__currentBlock.state if self.__currentBlock is not None else None

    def getBlocksCount(self):
        return self.__blocksCount

    def getMonths(self):
        return self.__months

    def getMonth(self, blockNumber):
        return self.__months.get(blockNumber, 0)

    def getActivePhaseDates(self, blockNumber):
        return self.__activePhaseDates.get(blockNumber, ActivePhaseDates(0, 0))

    def getEventFinish(self):
        return self.__eventFinish

    def getEventBaseURL(self):
        return self.__eventBaseURL

    def isBlocksDataValid(self):
        return self.__isBlocksDataValid

    def isEventInProgress(self):
        return self.__isEventActive and self.__currentBlock.state != EventBlockStates.NOT_STARTED and self.__currentBlock.state != EventBlockStates.FINISHED

    def __clear(self):
        self.__isEventActive = False
        self.__currentBlock = _CurrentBlock()
        self.__months.clear()
        self.__activePhaseDates.clear()
        self.__eventFinish = 0
        self.__blocksCount = 0
        self.__eventBaseURL = ''
        self.__eventsCache.onSyncCompleted -= self.__update
        if self.__periodicNotifier is not None:
            self.__periodicNotifier.stopNotification()
            self.__periodicNotifier.clear()
            self.__periodicNotifier = None
        return

    def __update(self):
        actions = self.__eventsCache.getActions()
        eventState = self.__getEventState(actions, _EVENT_STATE_NAME)
        if eventState is None:
            if self.__isEventActive:
                self.__isEventActive = False
                self.onEventStateChanged()
            return
        else:
            isBlocksDataValid = False
            if eventState not in (_EVENT_STATE_IN_PROGRESS, _EVENT_STATE_END):
                _logger.error('Event state should be: "%s" or "%s"',
                              _EVENT_STATE_IN_PROGRESS, _EVENT_STATE_END)
                return
            self.__updateEvent(eventState)
            eventBaseURL = self.__getEventState(actions, _EVENT_URL_NAME)
            if not eventBaseURL:
                _logger.error(
                    'Event base url is not defined in step "EventBaseURL"')
            else:
                self.__updateBaseURL(eventBaseURL)
            datesState = self.__getEventState(actions, _EVENT_DATES_NAME)
            eventDates = self.__parseEventDates(datesState)
            if eventDates is not None:
                activePhaseDates, months, eventFinish = eventDates
                blocksCount = len(months)
                monthsByBlocks = {
                    block: months[block - 1]
                    for block in range(FIRST_BLOCK_NUMBER, blocksCount + 1)
                }
                activePhaseDatesByBlocks = {
                    block: activePhaseDates[block - 1]
                    for block in range(FIRST_BLOCK_NUMBER, blocksCount + 1)
                }
                block = self.__getCurrentBlock(activePhaseDatesByBlocks,
                                               eventFinish)
                if block is not None:
                    if block.state == EventBlockStates.FINISHED:
                        _logger.error('Event has finished.')
                    else:
                        self.__blocksCount = blocksCount
                        isBlocksDataValid = True
                        self.__updateMonths(monthsByBlocks)
                        self.__updateActivePhaseDates(activePhaseDatesByBlocks)
                        self.__updateEventFinish(eventFinish)
                        self.__updateCurrentBlock(block)
                        self.__startNotifier()
            self.__updateDataValidity(isBlocksDataValid)
            self.onEventDataUpdated()
            return

    def __updateEvent(self, eventState):
        isEventActive = eventState == _EVENT_STATE_IN_PROGRESS
        if self.__isEventActive != isEventActive:
            self.__isEventActive = isEventActive
            self.onEventStateChanged()

    def __updateCurrentBlock(self, block):
        if self.__currentBlock != block:
            self.__currentBlock = block
            self.onEventBlockChanged()

    def __updateMonths(self, months):
        if self.__months != months:
            self.__months = months
            self.onEventMonthsChanged()

    def __updateActivePhaseDates(self, dates):
        if self.__activePhaseDates != dates:
            self.__activePhaseDates = dates
            self.onActivePhasesDatesChanged()

    def __updateEventFinish(self, eventFinish):
        if self.__eventFinish != eventFinish:
            self.__eventFinish = eventFinish
            self.onEventFinishChanged()

    def __updateDataValidity(self, isBlocksDataValid):
        if self.__isBlocksDataValid != isBlocksDataValid:
            self.__isBlocksDataValid = isBlocksDataValid
            self.onBlocksDataValidityChanged()

    def __startNotifier(self):
        if self.__periodicNotifier is None and self.__currentBlock.state != EventBlockStates.FINISHED:
            self.__periodicNotifier = PeriodicNotifier(
                self.__getTimeLeft, self.__updateCurrentBlockOnTimeChanged,
                (time_utils.ONE_MINUTE, ))
            self.__periodicNotifier.startNotification()
        return

    def __updateCurrentBlockOnTimeChanged(self):
        timeLeft = self.__getTimeLeft()
        if timeLeft == 0:
            block = self.__getCurrentBlock(self.__activePhaseDates,
                                           self.__eventFinish)
            self.__updateCurrentBlock(block)
            if block.state == EventBlockStates.FINISHED and self.__periodicNotifier is not None:
                self.__periodicNotifier.stopNotification()
        return

    def __getTimeLeft(self):
        if self.__currentBlock.state == EventBlockStates.NOT_STARTED:
            event = self.__activePhaseDates[FIRST_BLOCK_NUMBER].start
        elif self.__currentBlock.state == EventBlockStates.ACTIVE:
            event = self.__activePhaseDates[self.__currentBlock.number].finish
        elif self.__currentBlock.number < self.__blocksCount:
            event = self.__activePhaseDates[self.__currentBlock.number +
                                            1].start
        elif self.__currentBlock.number == self.__blocksCount and self.__currentBlock.state == EventBlockStates.PASSIVE:
            event = self.__eventFinish
        else:
            return 0
        now = time_utils.getServerUTCTime()
        timeLeft = event - now
        return max(0, timeLeft)

    @process
    def __updateBaseURL(self, eventBaseURL):
        eventBaseURL = yield URLMacros().parse(eventBaseURL)
        if self.__eventBaseURL != eventBaseURL:
            self.__eventBaseURL = eventBaseURL

    @staticmethod
    def __getEventState(actions, eventName):
        for action in actions.itervalues():
            steps = action.getData()['steps']
            if steps is None:
                continue
            for step in steps:
                if step.get('name') != eventName:
                    continue
                return step.get('params').get('state')

        return

    @staticmethod
    def __getCurrentBlock(activePhases, eventFinish):
        if not activePhases:
            return
        else:
            now = time_utils.getServerUTCTime()
            if now < activePhases[FIRST_BLOCK_NUMBER].start:
                _logger.error("Event hasn't started yet.")
                return _CurrentBlock(FIRST_BLOCK_NUMBER,
                                     EventBlockStates.NOT_STARTED)
            if now >= eventFinish:
                return _CurrentBlock(5, EventBlockStates.FINISHED)
            nextBlockNumber = first(
                (block for block, date in activePhases.iteritems()
                 if date.start > now))
            if nextBlockNumber is None:
                blockNumber = activePhases.keys()[-1]
            else:
                blockNumber = nextBlockNumber - 1
            blockState = EventBlockStates.ACTIVE if now < activePhases[
                blockNumber].finish else EventBlockStates.PASSIVE
            currentBlock = _CurrentBlock(blockNumber, blockState)
            return currentBlock

    @staticmethod
    def __parseEventDates(eventDates):
        if eventDates is None:
            return
        else:
            activePhaseDates = []
            months = []
            try:
                active, finish = eventDates.split('||')
            except ValueError:
                _logger.error('Invalid format of event dates section: %s',
                              eventDates)
                return

            try:
                dates = active.split('|')
            except ValueError:
                dates = []
                _logger.error(
                    'Invalid format of active phase dates section: %s', dates)
                return

            for date in dates:
                month, activePhaseDate = TenYearsCountdownController.__parseActivePhaseDate(
                    date)
                if month is not None and activePhaseDate is not None:
                    if activePhaseDates and activePhaseDate.start < activePhaseDates[
                            -1].start:
                        _logger.error(
                            'Start of active phase should be later than start of previous active phase.'
                        )
                        return
                    if activePhaseDates and activePhaseDate.start < activePhaseDates[
                            -1].finish:
                        _logger.error(
                            'Start of active phase should be later than finish of previous active phase.'
                        )
                    else:
                        months.append(month)
                        activePhaseDates.append(activePhaseDate)

            if len(activePhaseDates) != EVENT_BLOCKS_COUNT:
                _logger.error(
                    'Number of dates should be equal to the number of event blocks: %s',
                    EVENT_BLOCKS_COUNT)
                return
            if finish:
                eventFinish = TenYearsCountdownController.__parseEventFinishDate(
                    finish)
                if activePhaseDates and eventFinish < activePhaseDates[
                        -1].finish:
                    _logger.error(
                        'Finish of event should be later than finish of last active phase.'
                    )
                    return
            else:
                eventFinish = 0
            return (activePhaseDates, months, eventFinish)

    @staticmethod
    def __parseActivePhaseDate(date):
        try:
            start, finish = date.split()
            start = time.strptime(start, '%d.%m.%Y-%H:%M:%S')
            finish = time.strptime(finish, '%d.%m.%Y-%H:%M:%S')
            month = start.tm_mon
            start = calendar.timegm(start)
            finish = calendar.timegm(finish)
            if finish < start:
                _logger.error(
                    'Start of active phase should be earlier than its end.')
                month, activePhaseDate = (None, None)
            else:
                activePhaseDate = ActivePhaseDates(start, finish)
        except ValueError:
            _logger.error(
                'Invalid format: %s, dates should be in format DD.MM.YYYY-HH:MM:SS',
                date)
            month, activePhaseDate = (None, None)

        return (month, activePhaseDate)

    @staticmethod
    def __parseEventFinishDate(finish):
        try:
            eventFinish = time.strptime(finish.strip(), '%d.%m.%Y-%H:%M:%S')
            eventFinish = calendar.timegm(eventFinish)
        except ValueError:
            eventFinish = 0
            _logger.error(
                'Invalid format: %s, date should be in format DD.MM.YYYY-HH:MM:SS',
                eventFinish)

        return eventFinish
コード例 #7
0
class NyGiftSystemView(HistorySubModelPresenter, GiftEventHubWatcher):
    __slots__ = ('_tooltips', '_eventHub', '__notifier', '__forcedSending', '__messageID', '__targetSpaID')
    _GIFT_EVENT_ID = GiftEventID.NY_HOLIDAYS
    __eventsCache = dependency.descriptor(IEventsCache)
    __giftsController = dependency.descriptor(IGiftSystemController)
    __itemsCache = dependency.descriptor(IItemsCache)
    __settingsCore = dependency.descriptor(ISettingsCore)
    __introLogger = NyGiftSystemIntroLogger()
    __sendButtonLogger = NyGiftSystemSendButtonLogger()

    def __init__(self, viewModel, parentView, soundConfig=None):
        super(NyGiftSystemView, self).__init__(viewModel, parentView, soundConfig)
        self._tooltips = {}
        self.__forcedSending = False
        self.__messageID = getGiftSystemRandomCongratulationID()
        self.__targetSpaID = _NOT_SELECTED_SPA_ID
        self.__notifier = PeriodicNotifier(getTimerGameDayLeft, self.__updateProgressionTimer, (ONE_MINUTE,))

    @property
    def viewModel(self):
        return self.getViewModel()

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

    def initialize(self, targetSpaID=_NOT_SELECTED_SPA_ID, forceShowIntro=False, *args, **kwargs):
        super(NyGiftSystemView, self).initialize(*args, **kwargs)
        self.__addListeners()
        self.__checkTargetConsistency(targetSpaID or self.__targetSpaID)
        with self.viewModel.transaction() as model:
            self.__updateIntro(model=model, force=forceShowIntro)
            self.__updateFriends(model=model)
            self.__updateProgression(model=model)
        self.__notifier.startNotification()
        self.__giftsController.requestWebState(GiftEventID.NY_HOLIDAYS)

    def finalize(self):
        self._tooltips.clear()
        self.__removeListeners()
        self.__forcedSending = False
        self.__notifier.stopNotification()
        self.__introLogger.onViewClosed()
        self.__sendButtonLogger.resetMessageChanged()
        super(NyGiftSystemView, self).finalize()

    def clear(self):
        self.__notifier.clear()
        super(NyGiftSystemView, self).clear()

    @backportTooltipDecorator()
    def createToolTip(self, event):
        return super(NyGiftSystemView, self).createToolTip(event)

    def createToolTipContent(self, event, contentID):
        if event.contentID == R.views.lobby.new_year.tooltips.NyPostStampTooltip():
            return NyPostStampTooltip()
        return NyBroTokenTooltip() if event.contentID == R.views.lobby.new_year.tooltips.NyBroTokenTooltip() else super(NyGiftSystemView, self).createToolTipContent(event, contentID)

    def _getInfoForHistory(self):
        return {}

    def _goToCelebrityView(self, *args, **kwargs):
        super(NyGiftSystemView, self)._goToCelebrityView(*args, **kwargs)
        NyCelebrityButtonLogger().logClickInGiftSystem()
        NyGiftSystemFlowLogger().logCelebrityClick()

    def _onGiftHubUpdate(self, reason, extraInfo=None):
        if reason == HubUpdateReason.OUTCOME_GIFT:
            self.__checkSendingComplete(extraInfo)
        elif reason == HubUpdateReason.INCOME_GIFT:
            self.__updateSubmission()
        elif reason == HubUpdateReason.STAMPER_UPDATE:
            self.__updateState()
            self.viewModel.submissionForm.setState(self.__getSubmissionState())
        elif reason == HubUpdateReason.KEEPER_CLEAR:
            self.__updateSubmission()
        elif reason == HubUpdateReason.HISTORY:
            self.__giftsController.requestWebState(GiftEventID.NY_HOLIDAYS)
        elif reason == HubUpdateReason.WEB_STATE:
            self.__checkTargetConsistency(self.__targetSpaID)
            self.__updateSubmission()

    def __addListeners(self):
        self.catchGiftEventHub()
        viewModel = self.viewModel
        viewModel.onIntroClose += self.__onCloseIntro
        viewModel.onQuestsBtnClick += _showDailyQuestsTab
        viewModel.onCelebrityBtnClick += self._goToCelebrityView
        viewModel.giftsProgression.onStylePreviewShow += self.__onPreviewStyleShow
        submission = viewModel.submissionForm
        submission.onRollCongrats += self.__onRollCongratsText
        submission.onSelectFriend += self.__onSelectFriend
        submission.onSendAnimationEnd += self.__onSendAnimationEnd
        submission.onSendGift += self.__onSendGift
        NewYearNavigation.onUpdateCurrentView += self.__onUpdateView
        g_messengerEvents.users.onUserActionReceived += self.__onUserActionReceived
        g_messengerEvents.users.onUsersListReceived += self.__onUsersListReceived
        self.__eventsCache.onSyncCompleted += self.__updateProgression

    def __removeListeners(self):
        self.releaseGiftEventHub()
        viewModel = self.viewModel
        viewModel.onIntroClose -= self.__onCloseIntro
        viewModel.onQuestsBtnClick -= _showDailyQuestsTab
        viewModel.onCelebrityBtnClick -= self._goToCelebrityView
        viewModel.giftsProgression.onStylePreviewShow -= self.__onPreviewStyleShow
        submission = viewModel.submissionForm
        submission.onRollCongrats -= self.__onRollCongratsText
        submission.onSelectFriend -= self.__onSelectFriend
        submission.onSendAnimationEnd -= self.__onSendAnimationEnd
        submission.onSendGift -= self.__onSendGift
        NewYearNavigation.onUpdateCurrentView -= self.__onUpdateView
        g_messengerEvents.users.onUserActionReceived -= self.__onUserActionReceived
        g_messengerEvents.users.onUsersListReceived -= self.__onUsersListReceived
        self.__eventsCache.onSyncCompleted -= self.__updateProgression

    def __getFriendsList(self):
        return self.usersStorage.getList(AnySubFindCriteria())

    def __getSubmissionState(self):
        resultState = SubmissionState.NONE
        if self.__forcedSending:
            resultState = SubmissionState.GIFT_SENDING
        elif self._eventHub.getGifter().getActiveRequest() is not None:
            resultState = SubmissionState.PREV_GIFT_SENDING
        elif not self._eventHub.isWebStateReceived():
            resultState = SubmissionState.LIMITS_LOADING
        elif not self._eventHub.getStamper().isBalanceAvailable():
            resultState = SubmissionState.BALANCE_UNAVAILABLE
        elif self.__targetSpaID != _NOT_SELECTED_SPA_ID:
            user = self.usersStorage.getUser(self.__targetSpaID) or _DEFAULT_SELECTED_USER
            resultState = SubmissionState.NO_LONGER_FRIEND if not user.isAnySub() else resultState
        return resultState

    def __onCloseIntro(self):
        self.__settingsCore.serverSettings.saveInNewYearStorage({NewYearStorageKeys.GIFT_SYSTEM_INTRO_VISITED: True})
        self.viewModel.setIsIntroOpened(False)
        self.__introLogger.onViewClosed()

    def __onPreviewStyleShow(self, args):
        backCallback = _ShowGiftSystemCallback()
        NewYearNavigation.switchTo(None, True)
        styleItem = self.__itemsCache.items.getItemByCD(int(args['styleID']))
        showStylePreview(getVehiclePreviewID(styleItem), styleItem, styleItem.getDescription(), backCallback=backCallback, backBtnDescrLabel=backport.text(R.strings.ny.giftSystem.backLabel()))
        return

    def __onRollCongratsText(self):
        self.__messageID = getGiftSystemRandomCongratulationID(self.__messageID)
        self.__invalidateSelectedCongrats(self.viewModel.submissionForm)
        self.__sendButtonLogger.onMessageChanged()

    @hasGiftEventHub
    @replaceNoneKwargsModel
    def __onSelectFriend(self, args, model=None):
        self.__checkTargetConsistency(int(args['spaID']))
        submissionState = self.__getSubmissionState()
        model.submissionForm.setState(submissionState)
        self.__invalidateSelectedFriend(model.submissionForm.selectedFriend, submissionState)

    @hasGiftEventHub
    def __onSendAnimationEnd(self):
        self.__forcedSending = False
        self.__checkSendingComplete()

    @hasGiftEventHub
    def __onSendGift(self):
        submissionState = self.__getSubmissionState()
        if submissionState in _LOCKED_STATES:
            return
        else:
            gifter = self._eventHub.getGifter()
            restriction = gifter.getRequestRestriction()
            if restriction is not None:
                defaultErrorRes = R.strings.ny.giftSystem.notification.error.defaultSending
                restrictErrorRes = R.strings.ny.giftSystem.notification.error.dyn(restriction.value, defaultErrorRes)
                SystemMessages.pushMessage(backport.text(restrictErrorRes()), type=SystemMessages.SM_TYPE.GiftSystemError)
                return
            self.__forcedSending = True
            self.__sendButtonLogger.logClick()
            self.__sendButtonLogger.resetMessageChanged()
            self.viewModel.submissionForm.setState(SubmissionState.GIFT_SENDING)
            gifter.sendGift(NY_STAMP_CODE, self.__targetSpaID, {'message_id': self.__messageID})(None)
            return

    def __onUpdateView(self, *_, **kwargs):
        spaID = kwargs.get('targetSpaID')
        if spaID is not None:
            self.__onSelectFriend({'spaID': spaID})
        return

    def __onUserActionReceived(self, actionID, *_):
        if actionID in (_ACTION_ID.FRIEND_ADDED, _ACTION_ID.FRIEND_REMOVED, _ACTION_ID.SUBSCRIPTION_CHANGED):
            self.__updateFriends()

    def __onUsersListReceived(self, tags):
        if USER_TAG.FRIEND in tags:
            self.__updateFriends()

    def __buildFriend(self, friend, friendModel=None):
        friendModel = friendModel or FriendModel()
        friendModel.setSpaID(friend.getID())
        friendModel.setName(friend.getName())
        friendModel.setClanAbbrev(friend.getClanAbbrev())
        return friendModel

    def __buildProgressionStage(self, packer, progressQuest, progressTokensRemains, prevStageTokensRequiered):
        maxCoinsCount = getGiftsTokensCountByID(progressQuest.getID()) - prevStageTokensRequiered
        currentCoinsCount = math_utils.clamp(0, maxCoinsCount, progressTokensRemains)
        stage = ProgressionStageModel()
        stage.setMaxCoinsCount(maxCoinsCount)
        stage.setCurrentCoinsCount(currentCoinsCount)
        stageBonuses, stageRewardsModels = progressQuest.getBonuses(), stage.getRewards()
        packBonusModelAndTooltipData(stageBonuses, stageRewardsModels, packer, self._tooltips)
        stageRewardsModels.invalidate()
        self.__invalidateStylesModel(stageRewardsModels, stage.getStyleIDs())
        return stage

    def __checkSendingComplete(self, webResponse=None):
        if webResponse is not None:
            self.__processSendResponse(webResponse)
        submissionState = self.__getSubmissionState()
        if submissionState in (SubmissionState.GIFT_SENDING, SubmissionState.PREV_GIFT_SENDING):
            return
        else:
            self.__updateFriends()
            return

    @hasGiftEventHub
    def __checkTargetConsistency(self, targetSpaID):
        user = self.usersStorage.getUser(targetSpaID)
        eventHub = self.getGiftEventHub()
        ifConsistentTarget = user and user.isAnySub() and not eventHub.getKeeper().isFullfilled(user.getID())
        self.__targetSpaID = user.getID() if ifConsistentTarget else _NOT_SELECTED_SPA_ID

    @hasGiftEventHub
    def __invalidateFriends(self, waiting, fullfilled, friends):
        waiting.clear()
        fullfilled.clear()
        income = self._eventHub.getKeeper().getIncomeRelations()
        outcome = self._eventHub.getKeeper().getOutcomeRelations()
        for friend in sorted(friends, key=lambda f: f.getName()):
            friendID = friend.getID()
            friendModel = self.__buildFriend(friend, FriendModel())
            friendModel.setIsGiftReceived(friendID in income and income[friendID])
            (fullfilled if friendID in outcome and outcome[friendID] else waiting).addViewModel(friendModel)

        fullfilled.invalidate()
        waiting.invalidate()

    def __invalidateProgressionStages(self, stages, progressQuests, progressTokensCount):
        stages.clear()
        prevStageRequiredAmount = 0
        packer = getNewYearBonusPacker()
        for quest in sorted(progressQuests.itervalues(), key=lambda q: q.getID()):
            stageModel = self.__buildProgressionStage(packer, quest, progressTokensCount, prevStageRequiredAmount)
            prevStageRequiredAmount = getGiftsTokensCountByID(quest.getID())
            progressTokensCount -= stageModel.getCurrentCoinsCount()
            stages.addViewModel(stageModel)

        stages.invalidate()

    @hasGiftEventHub
    def __invalidateSelectedCongrats(self, submission, submissionState=None):
        gifterCtx = self._eventHub.getGifter().getActiveRequest()
        submissionState = submissionState or self.__getSubmissionState()
        if submissionState in _LOCKED_STATES and gifterCtx is None:
            return
        else:
            messageID = gifterCtx.getMetaInfo()['message_id'] if gifterCtx else self.__messageID
            submission.setCongratsText(getGiftSystemCongratulationResource(messageID)())
            return

    @hasGiftEventHub
    def __invalidateSelectedFriend(self, selectedFriend, submissionState=None):
        gifterCtx = self._eventHub.getGifter().getActiveRequest()
        submissionState = submissionState or self.__getSubmissionState()
        if submissionState in _LOCKED_STATES and gifterCtx is None:
            return
        else:
            selectedUser = self.usersStorage.getUser(gifterCtx.getReceiverID() if gifterCtx else self.__targetSpaID)
            selectedUser, income = selectedUser or _DEFAULT_SELECTED_USER, self._eventHub.getKeeper().getIncomeRelations()
            selectedFriend.setIsGiftReceived(selectedUser.getID() in income and income[selectedUser.getID()])
            self.__buildFriend(selectedUser, selectedFriend)
            return

    def __invalidateStylesModel(self, stageRewardsModels, styleIDs):
        for rewardModel in stageRewardsModels:
            tooltipData = self._tooltips.get(rewardModel.getTooltipId())
            if tooltipData is None or not tooltipData.specialArgs:
                styleIDs.addNumber(0)
                continue
            possibleStyle = self.__itemsCache.items.getItemByCD(tooltipData.specialArgs[0])
            if possibleStyle is None or possibleStyle.itemTypeID != GUI_ITEM_TYPE.STYLE:
                styleIDs.addNumber(0)
                continue
            styleIDs.addNumber(possibleStyle.intCD)

        styleIDs.invalidate()
        return

    def __processSendResponse(self, webResponse):
        isSuccess = webResponse.state == GifterResponseState.WEB_SUCCESS
        receiverID, messageID = webResponse.receiverID, webResponse.meta['message_id']
        currentTarget = _NOT_SELECTED_SPA_ID if self.__targetSpaID == receiverID else self.__targetSpaID
        self.__messageID = getGiftSystemRandomCongratulationID(messageID) if isSuccess else messageID
        self.__targetSpaID = currentTarget if isSuccess else receiverID

    @replaceNoneKwargsModel
    def __updateIntro(self, model=None, force=False):
        isIntroVisited = self.__settingsCore.serverSettings.getNewYearStorage().get(NewYearStorageKeys.GIFT_SYSTEM_INTRO_VISITED, False)
        showIntro = not isIntroVisited or force
        model.setIsIntroOpened(showIntro)
        if showIntro:
            self.__introLogger.onViewOpened()

    @replaceNoneKwargsModel
    def __updateProgression(self, model=None):
        tokens = self.__itemsCache.items.tokens
        progressQuests = self.__eventsCache.getHiddenQuests(giftsPogressQuestFilter)
        progressTokensCount = tokens.getTokenCount(NY_GIFT_SYSTEM_PROGRESSION_TOKEN)
        subprogressTokensCount = tokens.getTokenCount(NY_GIFT_SYSTEM_SUBPROGRESS_TOKEN)
        subprogressQuests = self.__eventsCache.getHiddenQuests(giftsSubprogressQuestFilter)
        subprogressQuest = subprogressQuests.itervalues().next() if subprogressQuests else None
        self._tooltips.clear()
        progression = model.giftsProgression
        progression.setCurrentGiftsCount(subprogressTokensCount)
        progression.setMaxGiftsCount(getGiftsTokensCountByID(subprogressQuest.getID()) if subprogressQuest else 0)
        self.__invalidateProgressionStages(progression.getStages(), progressQuests, progressTokensCount)
        self.__updateProgressionTimer(model=model)
        return

    @replaceNoneKwargsModel
    def __updateProgressionTimer(self, model=None):
        model.giftsProgression.setResetDelta(getDayTimeLeft())

    @hasGiftEventHub
    @replaceNoneKwargsModel
    def __updateState(self, model=None, friends=None):
        stamper = self._eventHub.getStamper()
        stampsCount = stamper.getStampCount(NY_STAMP_CODE)
        friends = friends if friends is not None else self.__getFriendsList()
        state = State.NORMAL
        if not stamper.wasBalanceAvailable():
            state = State.NO_BALANCE
        elif stampsCount == 0:
            state = State.NO_POST_STAMPS
        elif not friends:
            state = State.NO_FRIENDS
        model.setState(State.NORMAL if self.__forcedSending else state)
        model.setPostStampsCount(stampsCount)
        return

    @hasGiftEventHub
    @replaceNoneKwargsModel
    def __updateSubmission(self, model=None, friends=None, submissionState=None):
        submissionState = submissionState or self.__getSubmissionState()
        submission = model.submissionForm
        submission.setState(submissionState)
        friends = friends if friends is not None else self.__getFriendsList()
        self.__invalidateFriends(submission.getWaitingFriends(), submission.getFullfilledFriends(), friends)
        self.__invalidateSelectedFriend(submission.selectedFriend, submissionState)
        self.__invalidateSelectedCongrats(submission, submissionState)
        return

    @replaceNoneKwargsModel
    def __updateFriends(self, model=None):
        friends = self.__getFriendsList()
        self.__updateState(model=model, friends=friends)
        self.__updateSubmission(model=model, friends=friends)
コード例 #8
0
class RankedBattlesSeasonGapView(RankedBattlesSeasonGapViewMeta,
                                 IResetablePage):
    __eventsCache = dependency.descriptor(IEventsCache)
    __itemsCache = dependency.descriptor(IItemsCache)
    __rankedController = dependency.descriptor(IRankedBattlesController)
    __TOKENS_ORDER = (SeasonResultTokenPatterns.RANKED_OFF_BANNED,
                      SeasonResultTokenPatterns.RANKED_OFF_ROLLED,
                      SeasonResultTokenPatterns.RANKED_OFF_BRONZE_LEAGUE_TOKEN,
                      SeasonResultTokenPatterns.RANKED_OFF_SILVER_LEAGUE_TOKEN,
                      SeasonResultTokenPatterns.RANKED_OFF_GOLD_LEAGUE_TOKEN)
    __slots__ = ()

    def __init__(self):
        super(RankedBattlesSeasonGapView, self).__init__()
        self.__periodicNotifier = None
        self.__prevSeason = None
        self.__dossier = None
        self.__resultState = None
        self.__resultLeague = UNDEFINED_LEAGUE_ID
        self.__isSprinter = False
        return

    def reset(self):
        self.__update()

    def onBtnClick(self):
        self.__rankedController.showRankedBattlePage(
            ctx={
                'selectedItemID': RANKEDBATTLES_CONSTS.RANKED_BATTLES_RATING_ID
            })

    def _populate(self):
        super(RankedBattlesSeasonGapView, self)._populate()
        self.__rankedController.onUpdated += self.__update
        g_clientUpdateManager.addCallbacks({'tokens': self.__onTokensUpdate})
        self.__prevSeason = self.__rankedController.getPreviousSeason()
        self.__dossier = self.__itemsCache.items.getAccountDossier(
        ).getSeasonRankedStats(
            RankedDossierKeys.SEASON % self.__prevSeason.getNumber(),
            self.__prevSeason.getSeasonID())
        self.__periodicNotifier = PeriodicNotifier(self.__getTillUpdateTime,
                                                   self.__update)
        self.__update()
        self.__periodicNotifier.startNotification()

    def _dispose(self):
        self.__rankedController.onUpdated -= self.__update
        g_clientUpdateManager.removeObjectCallbacks(self)
        self.__periodicNotifier.stopNotification()
        self.__periodicNotifier.clear()
        super(RankedBattlesSeasonGapView, self)._dispose()

    def __getResultTokenPattern(self):
        prevSeasonID = self.__prevSeason.getSeasonID()
        for tokenPattern in self.__TOKENS_ORDER:
            tokenName = tokenPattern.format(prevSeasonID)
            token = self.__itemsCache.items.tokens.getTokens().get(tokenName)
            if token:
                _, count = token
                if count > 0:
                    return tokenPattern

        return None

    def __getNotLeagueQuest(self):
        return self.__eventsCache.getHiddenQuests().get(
            NOT_IN_LEAGUES_QUEST.format(self.__prevSeason.getSeasonID()))

    def __getTillUpdateTime(self):
        notLeagueQuest = self.__getNotLeagueQuest()
        return notLeagueQuest.getStartTimeLeft(
        ) if notLeagueQuest is not None else time_utils.ONE_MINUTE

    def __hasSprinterToken(self):
        prevSeasonID = self.__prevSeason.getSeasonID()
        sprinterToken = SeasonResultTokenPatterns.RANKED_OFF_SPRINTER.format(
            prevSeasonID)
        token = self.__itemsCache.items.tokens.getTokens().get(sprinterToken)
        if token:
            _, count = token
            if count > 0:
                return True
        return False

    def __onTokensUpdate(self, _):
        self.__update()

    def __update(self):
        self.__updateStateByDossier()
        self.__updateStateByTokens()
        self.__updateEfficiency()
        self.__updateRating()
        self.__updateData()

    def __updateData(self):
        achievedRankID = self.__dossier.getAchievedRank()
        achievedDivision = self.__rankedController.getDivision(achievedRankID)
        self.as_setDataS(
            season_gap_vos.getDataVO(
                season_gap_vos.StateBlock(
                    self.__resultState, achievedRankID, achievedDivision,
                    self.__resultLeague, self.__isSprinter,
                    self.__rankedController.isYearRewardEnabled())))

    def __updateEfficiency(self):
        self.as_setEfficiencyDataS(
            season_gap_vos.getEfficiencyVO(
                self.__dossier.getStepsEfficiency()))

    def __updateRating(self):
        isMastered = self.__resultState in (SeasonGapStates.IN_LEAGUES,
                                            SeasonGapStates.WAITING_IN_LEAGUES)
        webSeasonInfo = self.__rankedController.getWebSeasonProvider(
        ).seasonInfo
        if webSeasonInfo.league != self.__resultLeague:
            webSeasonInfo = self.__rankedController.getClientSeasonInfo()
        position = webSeasonInfo.position if webSeasonInfo.league == self.__resultLeague else None
        self.as_setRatingDataS(season_gap_vos.getRatingVO(
            position, isMastered))
        return

    def __updateStateByDossier(self):
        achievedRank = self.__dossier.getAchievedRank()
        self.__resultState = SeasonGapStates.WAITING_IN_LEAGUES
        if achievedRank == ZERO_RANK_ID:
            self.__resultState = SeasonGapStates.WAITING_NOT_IN_SEASON
        elif achievedRank == ZERO_RANK_ID + 1:
            self.__resultState = SeasonGapStates.WAITING_NOT_IN_DIVISIONS
        elif achievedRank < self.__rankedController.getMaxPossibleRank():
            self.__resultState = SeasonGapStates.WAITING_IN_DIVISIONS

    def __updateStateByTokens(self):
        self.__resultLeague = UNDEFINED_LEAGUE_ID
        self.__isSprinter = self.__hasSprinterToken()
        resultTokenPattern = self.__getResultTokenPattern()
        if resultTokenPattern == SeasonResultTokenPatterns.RANKED_OFF_BANNED:
            self.__resultState = _STATE_TO_BANNED_GAP_STATE.get(
                self.__resultState, self.__resultState)
        elif resultTokenPattern == SeasonResultTokenPatterns.RANKED_OFF_ROLLED:
            self.__resultState = _STATE_TO_ROLLED_GAP_STATE.get(
                self.__resultState, self.__resultState)
        elif resultTokenPattern is not None:
            self.__resultState = SeasonGapStates.IN_LEAGUES
            self.__resultLeague = int(resultTokenPattern.split('_')[-1])
        else:
            notLeagueQuest = self.__getNotLeagueQuest()
            if notLeagueQuest is not None and notLeagueQuest.getStartTime(
            ) < time.time():
                self.__resultState = _STATE_TO_READY_GAP_STATE.get(
                    self.__resultState, self.__resultState)
        return
コード例 #9
0
class EpicBattlesWidget(EpicBattlesWidgetMeta):
    __epicController = dependency.descriptor(IEpicBattleMetaGameController)

    def __init__(self):
        super(EpicBattlesWidget, self).__init__()
        self.__periodicNotifier = None
        return

    def onWidgetClick(self):
        self.__epicController.openURL()

    def onSoundTrigger(self, triggerName):
        SoundGroups.g_instance.playSound2D(triggerName)

    def update(self):
        if not self.__epicController.isEnabled():
            return
        else:
            if self.__periodicNotifier is not None:
                self.__periodicNotifier.startNotification()
            self.as_setDataS(self.__buildVO()._asdict())
            return

    def _populate(self):
        super(EpicBattlesWidget, self)._populate()
        if not self.__epicController.isEnabled():
            return
        else:
            if self.__periodicNotifier is None:
                self.__periodicNotifier = PeriodicNotifier(
                    self.__epicController.getTimer, self.update)
            self.__periodicNotifier.startNotification()
            g_clientUpdateManager.addCallbacks(
                {'tokens': self.__onTokensUpdate})
            return

    def _dispose(self):
        g_clientUpdateManager.removeObjectCallbacks(self)
        if self.__periodicNotifier is not None:
            self.__periodicNotifier.stopNotification()
            self.__periodicNotifier.clear()
            self.__periodicNotifier = None
        super(EpicBattlesWidget, self)._dispose()
        self.__periodicNotifier = None
        return

    def __buildVO(self):
        season = self.__epicController.getCurrentSeason(
        ) or self.__epicController.getNextSeason()
        currentLevel, _ = self.__epicController.getPlayerLevelInfo()
        cycleNumber = 1
        if season is not None:
            cycleNumber = self.__epicController.getCurrentOrNextActiveCycleNumber(
                season)
        level = currentLevel if self.__epicController.isCurrentCycleActive(
        ) else None
        return EpicBattlesWidgetVO(
            epicMetaLevelIconData=getProgressionIconVODict(cycleNumber, level),
            points=str(self.__getSkillPoints()),
            counterValue=self.__epicController.getNotChosenRewardCount())

    def __getSkillPoints(self):
        season = self.__epicController.getCurrentSeason()
        if season is None:
            return ''
        else:
            noActiveCycles = not self.__epicController.isCurrentCycleActive()
            now = time_utils.getCurrentLocalServerTimestamp()
            allCyclesInFuture = True
            for cycle in season.getAllCycles().values():
                if cycle.startDate < now:
                    allCyclesInFuture = False
                    break

            if noActiveCycles and allCyclesInFuture:
                return ''
            noNextCycle = season.getNextByTimeCycle(now) is None
            return '' if noActiveCycles and noNextCycle else str(
                self.__epicController.getSkillPoints())

    def __onTokensUpdate(self, diff):
        if any((key.startswith(EPIC_CHOICE_REWARD_OFFER_GIFT_TOKENS)
                for key in diff.keys())):
            self.update()
コード例 #10
0
class EpicBattlesWidget(EpicBattlesWidgetMeta):
    __connectionMgr = dependency.descriptor(IConnectionManager)
    __eventProgression = dependency.descriptor(IEventProgressionController)

    def __init__(self):
        super(EpicBattlesWidget, self).__init__()
        self.__periodicNotifier = None
        return

    def onWidgetClick(self):
        self.__eventProgression.openURL()

    def onQuestBtnClick(self, questType, questID):
        if questType == HANGAR_HEADER_QUESTS.QUEST_TYPE_COMMON:
            missions_page.setHideDoneFilter()
            showMissionsCategories()

    def onSoundTrigger(self, triggerName):
        SoundGroups.g_instance.playSound2D(triggerName)

    def onChangeServerClick(self):
        event_dispatcher.showEpicBattlesPrimeTimeWindow()

    def update(self):
        if not self.__eventProgression.isAvailable():
            return
        else:
            if self.__periodicNotifier is not None:
                self.__periodicNotifier.startNotification()
            self.as_setDataS(self._buildVO()._asdict())
            return

    def _populate(self):
        super(EpicBattlesWidget, self)._populate()
        if not self.__eventProgression.isAvailable():
            return
        else:
            if self.__periodicNotifier is None:
                self.__periodicNotifier = PeriodicNotifier(self.__eventProgression.getTimer, self.update)
            self.__periodicNotifier.startNotification()
            return

    def _dispose(self):
        if self.__periodicNotifier is not None:
            self.__periodicNotifier.stopNotification()
            self.__periodicNotifier.clear()
            self.__periodicNotifier = None
        super(EpicBattlesWidget, self)._dispose()
        self.__periodicNotifier = None
        return

    def _buildVO(self):
        showAlert = not self.__eventProgression.isInPrimeTime() and self.__eventProgression.modeIsEnabled()
        season = self.__eventProgression.getCurrentSeason() or self.__eventProgression.getNextSeason()
        levelInfo = self.__eventProgression.getPlayerLevelInfo()
        cycleNumber = 1
        if season is not None:
            cycleNumber = self.__eventProgression.getCurrentOrNextActiveCycleNumber(season)
        eventMode = EVENTPROGRESSION_CONSTS.STEEL_HUNTER_MODE if self.__eventProgression.isSteelHunter else EVENTPROGRESSION_CONSTS.FRONT_LINE_MODE
        level = levelInfo.currentLevel if self.__eventProgression.isActive() else None
        return EpicBattlesWidgetVO(calendarStatus=self.__getStatusBlock()._asdict(), showAlert=showAlert, epicMetaLevelIconData=getProgressionIconVODict(cycleNumber, level), quests=self.__getQuestsVO(), eventMode=eventMode)

    def __getQuestsVO(self):
        if not self.__eventProgression.modeIsAvailable():
            return []
        quests = self.__eventProgression.getQuestForVehicle(g_currentVehicle.item)
        totalCount = len(quests)
        completedQuests = len([ q for q in quests if q.isCompleted() ])
        libraryIcons = R.images.gui.maps.icons.library
        commonQuestsIcon = libraryIcons.outline.quests_available()
        if not totalCount:
            commonQuestsIcon = libraryIcons.outline.quests_disabled()
            label = ''
        elif self.__eventProgression.isNeedAchieveMaxLevelForDailyQuest():
            label = icons.makeImageTag(backport.image(libraryIcons.CancelIcon_1()))
        elif completedQuests != totalCount:
            label = backport.text(R.strings.menu.hangar_header.battle_quests_label.dyn(LABEL_STATE.ACTIVE)(), total=totalCount - completedQuests)
        else:
            currentCycleEndTime, _ = self.__eventProgression.getCurrentCycleInfo()
            cycleTimeLeft = currentCycleEndTime - time_utils.getCurrentLocalServerTimestamp()
            if cycleTimeLeft < ONE_DAY or not self.__eventProgression.isDailyQuestsRefreshAvailable():
                label = icons.makeImageTag(backport.image(libraryIcons.ConfirmIcon_1()))
            else:
                label = icons.makeImageTag(backport.image(libraryIcons.time_icon()))
        quests = [self._headerQuestFormatterVo(totalCount > 0, backport.image(commonQuestsIcon), label, HANGAR_HEADER_QUESTS.QUEST_TYPE_COMMON, flag=backport.image(self.__eventProgression.flagIconId), tooltip=TOOLTIPS_CONSTANTS.EPIC_QUESTS_PREVIEW, isTooltipSpecial=True)]
        return [self.__wrapQuestGroup(HANGAR_HEADER_QUESTS.QUEST_GROUP_COMMON, '', quests)]

    def __wrapQuestGroup(self, groupID, icon, quests):
        return {'groupID': groupID,
         'groupIcon': icon,
         'quests': quests}

    def _headerQuestFormatterVo(self, enable, icon, label, questType, flag=None, stateIcon=None, questID=None, isReward=False, tooltip='', isTooltipSpecial=False):
        return {'enable': enable,
         'flag': flag,
         'icon': icon,
         'stateIcon': stateIcon,
         'label': label,
         'questType': questType,
         'questID': str(questID),
         'isReward': isReward,
         'tooltip': tooltip,
         'isTooltipSpecial': isTooltipSpecial}

    def __getStatusBlock(self):
        status, timeLeft, _ = self.__eventProgression.getPrimeTimeStatus()
        showPrimeTimeAlert = status != PrimeTimeStatus.AVAILABLE
        hasAvailableServers = self.__eventProgression.hasAvailablePrimeTimeServers()
        return CalendarStatusVO(alertIcon=backport.image(R.images.gui.maps.icons.library.alertBigIcon()) if showPrimeTimeAlert else None, buttonIcon='', buttonLabel=backport.text(R.strings.epic_battle.widgetAlertMessageBlock.button()), buttonVisible=showPrimeTimeAlert and hasAvailableServers, buttonTooltip=None, statusText=self.__getAlertStatusText(timeLeft, hasAvailableServers), popoverAlias=None, bgVisible=True, shadowFilterVisible=showPrimeTimeAlert, tooltip=None)

    def __getAlertStatusText(self, timeLeft, hasAvailableServers):
        rAlertMsgBlock = R.strings.epic_battle.widgetAlertMessageBlock
        alertStr = ''
        if hasAvailableServers:
            alertStr = backport.text(rAlertMsgBlock.somePeripheriesHalt(), serverName=self.__connectionMgr.serverUserNameShort)
        else:
            currSeason = self.__eventProgression.getCurrentSeason()
            currTime = time_utils.getCurrentLocalServerTimestamp()
            primeTime = self.__eventProgression.getPrimeTimes().get(self.__connectionMgr.peripheryID)
            isCycleNow = currSeason and currSeason.hasActiveCycle(currTime) and primeTime and primeTime.getPeriodsBetween(currTime, currSeason.getCycleEndDate())
            if isCycleNow:
                if self.__connectionMgr.isStandalone():
                    key = rAlertMsgBlock.singleModeHalt
                else:
                    key = rAlertMsgBlock.allPeripheriesHalt
                timeLeftStr = time_utils.getTillTimeString(timeLeft, EPIC_BATTLE.STATUS_TIMELEFT, removeLeadingZeros=True)
                alertStr = backport.text(key(), time=timeLeftStr)
            else:
                nextSeason = currSeason or self.__eventProgression.getNextSeason()
                if nextSeason is not None:
                    nextCycle = nextSeason.getNextByTimeCycle(currTime)
                    if nextCycle is not None:
                        cycleNumber = nextCycle.getEpicCycleNumber()
                        timeLeftStr = time_utils.getTillTimeString(nextCycle.startDate - currTime, EPIC_BATTLE.STATUS_TIMELEFT, removeLeadingZeros=True)
                        alertStr = backport.text(rAlertMsgBlock.startIn(), cycle=int2roman(cycleNumber), time=timeLeftStr)
                if not alertStr:
                    prevSeason = currSeason or self.__eventProgression.getPreviousSeason()
                    if prevSeason is not None:
                        prevCycle = prevSeason.getLastActiveCycleInfo(currTime)
                        if prevCycle is not None:
                            cycleNumber = prevCycle.getEpicCycleNumber()
                            alertStr = backport.text(rAlertMsgBlock.noCycleMessage(), cycle=int2roman(cycleNumber))
        return text_styles.vehicleStatusCriticalText(alertStr)