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))
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
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
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 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)
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
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()
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)