def init(self):
     super(BattleRoyaleController, self).init()
     self.__voControl = BRVoiceOverController()
     self.__voControl.init()
     self.__urlMacros = URLMacros()
     self.addNotificator(SimpleNotifier(self.getTimer, self.__timerUpdate))
     self.addNotificator(PeriodicNotifier(self.getTimer, self.__timerTick))
 def __init__(self):
     super(PromoController, self).__init__()
     self.__urlMacros = URLMacros()
     self.__externalCloseCallback = None
     self.__isLobbyInited = False
     self.__pendingPromo = None
     self.__promoCount = 0
     self.__lastUpdateTimeMark = 0
     self.__promoData = None
     self.__waitingForWebBridgeData = False
     self.__battlesFromLastTeaser = 0
     self.__wasInBattle = False
     self.__hasPendingTeaser = False
     self.__isPromoOpen = False
     self.__browserCreationCallbacks = {}
     self.__browserWatchers = {}
     self.__isInHangar = False
     self.__isTeaserOpen = False
     self.__checkIntervalInBattles = GUI_SETTINGS.checkPromoFrequencyInBattles
     self.__em = EventManager()
     self.onNewTeaserReceived = Event(self.__em)
     self.onPromoCountChanged = Event(self.__em)
     self.onTeaserShown = Event(self.__em)
     self.onTeaserClosed = Event(self.__em)
     return
Example #3
0
 def __init__(self):
     self.__urlMacros = URLMacros()
     self.__isEnabled = False
     self.__isFrontLine = False
     self.__isSteelHunter = False
     self.__url = ''
     self.__actualRewardPoints = 0
     self.__seasonRewardPoints = 0
     self.__maxRewardPoints = 0
     self.__rewardPointsTokenID = ''
     self.__seasonPointsTokenID = ''
     self.__rewardVehicles = []
     self.__currentMode = None
     self.__questCardLevelTxtId = 0
     self.__progressionNameCycleTxtId = 0
     self.__progressionIconId = 0
     self.__selectorLabelTxtId = 0
     self.__selectorRibbonResId = 0
     self.__allCyclesWasEndedResId = 0
     self.__selectorData = 0
     self.__selectorType = 0
     self.__selectorQueueType = 0
     self.__questPrefix = ''
     self.__activeQuestIDs = []
     self.__primeTimeTitle = ''
     self.__primeTimeBg = ''
     return
Example #4
0
 def __init__(self, skipConfirm=False):
     super(VehiclePreviewBuyingPanel, self).__init__()
     heroTankCD = self._heroTanks.getCurrentTankCD()
     self._vehicleCD = g_currentPreviewVehicle.item.intCD
     self._vehicleLevel = g_currentPreviewVehicle.item.level
     self._actionType = None
     self._skipConfirm = skipConfirm
     self._disableBuyButton = False
     self._marathonEvent = None
     self.__previewDP = DefaultVehPreviewDataProvider()
     self.__isHeroTank = heroTankCD and heroTankCD == self._vehicleCD
     self.__price = None
     self.__title = None
     self.__description = None
     self.__items = None
     self.__offers = None
     self.__currentOffer = None
     self.__styleByGroup = {}
     self.__vehicleByGroup = {}
     self.__endTime = None
     self.__oldPrice = MONEY_UNDEFINED
     self.__buyParams = None
     self.__backAlias = None
     self.__backCallback = None
     self.__timeCallbackID = None
     self.__timeLeftIcon = icons.makeImageTag(
         RES_ICONS.MAPS_ICONS_LIBRARY_TIME_ICON, 16, 16)
     self.__cachedVehiclesVOs = None
     self.__cachedItemsVOs = None
     self.__cachedCollapsedItemsVOs = None
     self.__couponInfo = None
     self.__hasSSEDiscount = False
     self.__urlMacros = URLMacros()
     g_techTreeDP.load()
     return
 def init(self):
     super(EpicBattleMetaGameController, self).init()
     self.__urlMacros = URLMacros()
     self.addNotificator(SimpleNotifier(self.getTimer, self.__timerUpdate))
     self.addNotificator(PeriodicNotifier(self.getTimer, self.__timerTick))
     self.__eventEndedNotifier = SimpleNotifier(self.getEventTimeLeft,
                                                self.__onEventEnded)
     self.addNotificator(self.__eventEndedNotifier)
def showBuyItemWebView(url, itemId, source=None, origin=None, alias=VIEW_ALIAS.OVERLAY_WEB_STORE):
    url = yield URLMacros().parse(url)
    params = {}
    if source:
        params['source'] = source
    if origin:
        params['origin'] = origin
    url = yield URLMacros().parse(url=_makeBuyItemUrl(url, itemId), params=params)
    g_eventBus.handleEvent(events.LoadViewEvent(alias, ctx={'url': url}), EVENT_BUS_SCOPE.LOBBY)
 def __init__(self):
     super(MarathonEvent, self).__init__()
     self.__isEnabled = False
     self.__isAvailable = False
     self.__rewardObtained = False
     self.__state = ''
     self.__suspendFlag = False
     self.__quest = None
     self.__group = None
     self.__urlMacros = URLMacros()
     return
Example #8
0
 def __init__(self):
     super(BrowserController, self).__init__()
     self.__browsers = {}
     self.__browsersCallbacks = {}
     self.__browserCreationCallbacks = {}
     self.__browserIDGenerator = SequenceIDGenerator()
     self.__eventMgr = Event.EventManager()
     self.onBrowserAdded = Event.Event(self.__eventMgr)
     self.onBrowserDeleted = Event.Event(self.__eventMgr)
     self.__urlMacros = URLMacros()
     self.__pendingBrowsers = {}
     self.__creatingBrowserID = None
     self.__filters = _getGlobalFilters()
     return
Example #9
0
    def init(self):
        self.__urlMacros = URLMacros()
        addListener = g_eventBus.addListener
        for eventType, handlerName in _LISTENERS.iteritems():
            handler = getattr(self, handlerName, None)
            if not handler:
                _logger.error('Handler is not found %s %s', eventType, handlerName)
                continue
            if not callable(handler):
                _logger.error('Handler is invalid %s %s %r', eventType, handlerName, handler)
                continue
            addListener(eventType, handler)

        return
def getShopProductInfo(productID, callback=None, webCtrl=None):
    productInfo = None
    accessTokenData = yield webCtrl.getAccessTokenData(force=False)
    loginUrl = yield URLMacros().parse(url=getLoginUrl())
    productUrl = yield URLMacros().parse(url=getProductsUrl(productID))
    reqTimeoutSeconds = 10.0
    if accessTokenData is not None and loginUrl and productUrl:
        authHeader = ('Authorization: Basic {}'.format(str(accessTokenData.accessToken)),)
        authResponse = yield _fetchUrl(loginUrl, authHeader, reqTimeoutSeconds, 'POST')
        if 200 <= authResponse.responseCode < 300:
            getProductHeader = authHeader + ('Cookie: {}'.format(authResponse.headers().get('Set-Cookie')), 'Accept-Language: {}'.format(getClientLanguage()))
            productResponse = yield _fetchUrl(productUrl, getProductHeader, reqTimeoutSeconds, 'GET')
            productInfo = _tryParseProductInfo(productResponse.body)
    if callback:
        callback(productInfo)
    return
Example #11
0
def showBuyGoldWebOverlay(params=None, parent=None):
    url = helpers.getBuyMoreGoldUrl()
    if url:
        url = yield URLMacros().parse(url, params=params)
        g_eventBus.handleEvent(
            events.LoadViewEvent(SFViewLoadParams(VIEW_ALIAS.OVERLAY_WEB_STORE,
                                                  parent=parent),
                                 ctx={'url': url}), EVENT_BUS_SCOPE.LOBBY)
Example #12
0
 def __init__(self, layoutID, c11nView, *args, **kwargs):
     settings = ViewSettings(layoutID)
     settings.args = args
     settings.kwargs = kwargs
     settings.flags = ViewFlags.LOBBY_TOP_SUB_VIEW
     settings.model = ProgressiveItemsViewModel()
     super(ProgressiveItemsView, self).__init__(settings)
     self._itemsProgressData = None
     self._possibleItems = None
     self._vehicle = None
     self.__blur = CachedBlur()
     self.__layoutID = layoutID
     self.__c11nView = c11nView
     self.__urlMacros = URLMacros()
     self.__guiSettings = GUI_SETTINGS.progressiveItems.get(
         'tutorialVideo', {})
     return
Example #13
0
 def __init__(self, _=None):
     LobbySelectableView.__init__(self, 0)
     self.__currentCarouselAlias = None
     self.__isSpaceReadyForC11n = False
     self.__isVehicleReadyForC11n = False
     self.__isVehicleCameraReadyForC11n = False
     self.__urlMacros = URLMacros()
     self.__teaser = None
     self.__seniorityAwardsIsActive = False
     return
def showGetVehiclePage(vehicle, params=None):
    if vehicle.isInInventory and not vehicle.isRented:
        showInventoryMsg('already_exists',
                         vehicle,
                         msgType=SystemMessages.SM_TYPE.Warning)
        event_dispatcher.selectVehicleInHangar(vehicle.intCD)
        return
    url = helpers.getObtainVehicleURL()
    if url:
        url = yield URLMacros().parse(url, params=params)
        showReferralProgramWindow(url)
Example #15
0
def _showBlurredWebOverlay(url,
                           params=None,
                           parent=None,
                           isClientCloseControl=False):
    url = yield URLMacros().parse(url, params)
    ctx = {'url': url, 'allowRightClick': False}
    if isClientCloseControl:
        ctx.update(helpers.getClientControlledCloseCtx())
    g_eventBus.handleEvent(
        events.LoadViewEvent(SFViewLoadParams(VIEW_ALIAS.WEB_VIEW_TRANSPARENT,
                                              parent=parent),
                             ctx=ctx), EVENT_BUS_SCOPE.LOBBY)
Example #16
0
def _showOverlayWebStoreDefault(url, params=None):
    if url:
        url = yield URLMacros().parse(url, params=params)
        g_eventBus.handleEvent(
            events.LoadViewEvent(
                SFViewLoadParams(VIEW_ALIAS.OVERLAY_WEB_STORE),
                ctx={
                    'url':
                    url,
                    'browserParams':
                    makeBrowserParams(R.strings.waiting.updating(), True, True,
                                      0.5)
                }), EVENT_BUS_SCOPE.LOBBY)
Example #17
0
def showRentVehicleOverlay(params=None):
    url = helpers.getVehicleUrl()
    if url:
        url = yield URLMacros().parse(url, params=params)
        g_eventBus.handleEvent(
            events.LoadViewEvent(
                SFViewLoadParams(VIEW_ALIAS.OVERLAY_WEB_STORE),
                ctx={
                    'url':
                    url,
                    'browserParams':
                    makeBrowserParams(R.strings.waiting.updating(), True, True,
                                      0.5)
                }), EVENT_BUS_SCOPE.LOBBY)
 def __init__(self, _=None):
     LobbySelectableView.__init__(self, 0)
     self.__currentCarouselAlias = None
     self.__isSpaceReadyForC11n = False
     self.__isVehicleReadyForC11n = False
     self.__isVehicleCameraReadyForC11n = False
     self.__isUnitJoiningInProgress = False
     self.__urlMacros = URLMacros()
     self.__teaser = None
     self.__timer = None
     self.__wotPlusInfo = BigWorld.player().renewableSubscription
     self.__updateDogTagsState()
     self.__updateWotPlusState()
     return
Example #19
0
class OpenBrowserOnClickComponent(CGFComponent):
    urlProvider = ComponentProperty(type=CGFMetaTypes.STRING,
                                    editorName='url provider',
                                    value='MARATHON_VIDEO_URL_PROVIDER')

    def __init__(self):
        super(OpenBrowserOnClickComponent, self).__init__()
        self.__urlParser = URLMacros()

    def doAction(self):
        self.__openBrowser()

    @process
    def __openBrowser(self):
        getterFunc = URL_PROVIDERS[self.urlProvider]
        unparsedUrl = getterFunc()
        url = yield self.__urlParser.parse(unparsedUrl)
        showBrowserOverlayView(url, alias=VIEW_ALIAS.BROWSER_OVERLAY)
Example #20
0
 def __init__(self):
     self.prefix = 'event_marathon'
     self.tokenPrefix = 'event_marathon'
     self.styleTokenPostfix = ''
     self.urlName = 'marathonUrl'
     self.marathonCompleteUrlAdd = 'overlay/'
     self.vehicleName = ''
     self.suspendPrefix = ':suspend'
     self.completedTokenPostfix = '_PASS'
     self.hangarFlagName = 'flag_italy'
     self.questsInChain = 10
     self.minVehicleLevel = 6
     self.awardTokensPostfix = ('complete', 'ps_stop')
     self.awardPostTokensPostfix = ('post_complete', )
     self.showFlagTooltipBottom = True
     self.flagTooltip = TOOLTIPS_CONSTANTS.MARATHON_QUESTS_PREVIEW
     self.disabledFlagTooltip = TOOLTIPS.MARATHON_OFF
     self.marathonTooltipHeader = 'marathonTooltipHeader'
     self.bodyAddInfo = R_TITLE_TOOLTIP.body.addInfo
     self.doesShowRewardScreen = False
     self.doesShowRewardVideo = False
     self.doesShowInPostBattle = True
     self.questsPerStep = 2
     self.isEnabled = False
     self.isAvailable = False
     self.rewardObtained = False
     self.postRewardObtained = False
     self.state = MarathonState.UNKNOWN
     self.suspendFlag = False
     self.quest = None
     self.group = None
     self.vehicleID = 0
     self.awardTokens = None
     self.postAwardTokens = None
     self.tabTooltip = None
     self.infoBody = None
     self.label = ''
     self.backBtnLabel = ''
     self.tooltips = None
     self.icons = None
     self.urlMacros = URLMacros()
     self._override()
     self._initialize()
     return
 def invoke(self, notID, actor=None):
     processedUrl = yield URLMacros().parse(self._url)
     try:
         BigWorld.wg_openWebBrowser(processedUrl)
     except (AttributeError, TypeError):
         LOG_CURRENT_EXCEPTION()
class EpicBattleMetaGameController(Notifiable, SeasonProvider,
                                   IEpicBattleMetaGameController,
                                   IGlobalListener):
    bootcampController = dependency.descriptor(IBootcampController)
    __itemsCache = dependency.descriptor(IItemsCache)
    __eventsCache = dependency.descriptor(IEventsCache)
    __settingsCore = dependency.descriptor(ISettingsCore)
    __lobbyContext = dependency.descriptor(ILobbyContext)
    __battleResultsService = dependency.descriptor(IBattleResultsService)
    __offersProvider = dependency.descriptor(IOffersDataProvider)
    MAX_STORED_ARENAS_RESULTS = 20
    DAILY_QUEST_ID = 'front_line'
    FINAL_BADGE_QUEST_ID = 'epicmetagame:progression_finish'

    def __init__(self):
        super(EpicBattleMetaGameController, self).__init__()
        self.onUpdated = Event.Event()
        self.onPrimeTimeStatusUpdated = Event.Event()
        self.onEventEnded = Event.Event()
        self.onGameModeStatusTick = Event.Event()
        self.__skillData = {}
        self.__playerMaxLevel = 0
        self.__levelProgress = tuple()
        self.__abilityPointsForLevel = list()
        self.__performanceGroup = None
        self.__isEpicSoundMode = False
        self.__rankSettings = {}
        self.__showedResultsForArenas = []
        self.__eventEndedNotifier = None
        self.__urlMacros = None
        return

    def init(self):
        super(EpicBattleMetaGameController, self).init()
        self.__urlMacros = URLMacros()
        self.addNotificator(SimpleNotifier(self.getTimer, self.__timerUpdate))
        self.addNotificator(PeriodicNotifier(self.getTimer, self.__timerTick))
        self.__eventEndedNotifier = SimpleNotifier(self.getEventTimeLeft,
                                                   self.__onEventEnded)
        self.addNotificator(self.__eventEndedNotifier)

    def fini(self):
        del self.__showedResultsForArenas[:]
        self.onUpdated.clear()
        self.onPrimeTimeStatusUpdated.clear()
        self.onGameModeStatusTick.clear()
        self.onEventEnded.clear()
        self.clearNotification()
        self.stopGlobalListening()
        self.__urlMacros = None
        super(EpicBattleMetaGameController, self).fini()
        return

    def onLobbyInited(self, ctx):
        self.__lobbyContext.getServerSettings(
        ).onServerSettingsChange += self.__updateEpicMetaGameSettings
        g_currentVehicle.onChanged += self.__invalidateBattleAbilities
        self.__itemsCache.onSyncCompleted += self.__invalidateBattleAbilities
        g_clientUpdateManager.addCallbacks({
            'epicMetaGame': self.__updateEpic,
            'inventory': self.__onInventoryUpdate,
            'tokens': self.__onTokensUpdate
        })
        self.startGlobalListening()
        self.__setData()
        self.__invalidateBattleAbilities()
        self.startNotification()
        if self.getPerformanceGroup() == EPIC_PERF_GROUP.HIGH_RISK:
            self.__lobbyContext.addFightButtonConfirmator(
                self.__confirmFightButtonPressEnabled)
        self.__isEpicSoundMode = False
        if self.prbEntity is not None:
            enableSound = bool(self.prbEntity.getModeFlags()
                               & FUNCTIONAL_FLAG.EPIC)
            self.__updateSounds(enableSound)
        return

    def onDisconnected(self):
        self.__clear()

    def onPrbEntitySwitching(self):
        if self.prbEntity is None:
            return
        else:
            switchedFromEpic = bool(self.prbEntity.getModeFlags()
                                    & FUNCTIONAL_FLAG.EPIC)
            if switchedFromEpic:
                self.__updateSounds(False)
            return

    def onPrbEntitySwitched(self):
        self.__invalidateBattleAbilities()
        if self.prbEntity is None:
            return
        else:
            isEpicSoundMode = bool(self.prbEntity.getModeFlags()
                                   & FUNCTIONAL_FLAG.EPIC)
            if isEpicSoundMode:
                self.__updateSounds(True)
            return

    def onAccountBecomePlayer(self):
        self.__battleResultsService.onResultPosted += self.__showBattleResults

    def onAvatarBecomePlayer(self):
        self.__clear()
        self.__battleResultsService.onResultPosted -= self.__showBattleResults

    def getModeSettings(self):
        return self.__lobbyContext.getServerSettings().epicBattles

    def isEnabled(self):
        return self.getModeSettings().isEnabled

    def isEpicPrbActive(self):
        return False if self.prbEntity is None else bool(
            self.prbEntity.getModeFlags() & FUNCTIONAL_FLAG.EPIC)

    def isCurrentCycleActive(self):
        season = self.getCurrentSeason()
        return season.hasActiveCycle(time_utils.getCurrentLocalServerTimestamp(
        )) if season is not None else False

    def isUnlockVehiclesInBattleEnabled(self):
        return any(self.getUnlockableInBattleVehLevels())

    def isDailyQuestsUnlocked(self):
        currrentLevel, _ = self.getPlayerLevelInfo()
        return currrentLevel >= self.getMaxPlayerLevel()

    def isDailyQuestsRefreshAvailable(self):
        if self.hasPrimeTimesLeftForCurrentCycle():
            return True
        primeTimePeriodsForDay = self.getPrimeTimesForDay(
            time_utils.getCurrentLocalServerTimestamp())
        if primeTimePeriodsForDay:
            _, periodTimeEnd = max(primeTimePeriodsForDay.values(),
                                   key=itemgetter(1))
            periodTimeLeft = periodTimeEnd - time_utils.getCurrentLocalServerTimestamp(
            )
            return periodTimeLeft > time_utils.getDayTimeLeft()
        return False

    def getPerformanceGroup(self):
        if not self.__performanceGroup:
            self.__analyzeClientSystem()
            _logger.debug('Current performance group %s',
                          self.__performanceGroup)
        return self.__performanceGroup

    def getMaxPlayerLevel(self):
        return self.__playerMaxLevel

    def getStageLimit(self):
        return self.__stageLimit

    def getAbilityPointsForLevel(self):
        return self.__abilityPointsForLevel

    def getValidVehicleLevels(self):
        return self.getModeSettings().validVehicleLevels

    def getUnlockableInBattleVehLevels(self):
        return self.getModeSettings().unlockableInBattleVehLevels

    def getSuitableForQueueVehicleLevels(self):
        return set(self.getValidVehicleLevels()) - set(
            self.getUnlockableInBattleVehLevels())

    def getPointsProgressForLevel(self, level):
        return self.__levelProgress[level]

    def getPointsForLevel(self, level):
        return sum(
            (self.__levelProgress[level] for level in xrange(level - 1)))

    def getLevelProgress(self):
        return self.__levelProgress

    def getLevelForPoints(self, points):
        lvl = 0
        while points >= 0 and lvl <= self.__playerMaxLevel:
            points -= self.__levelProgress[lvl]
            lvl += 1

        return lvl - 1

    def getAllSkillsInformation(self):
        return self.__skillData

    def getPlayerLevelInfo(self):
        return self.__itemsCache.items.epicMetaGame.playerLevelInfo

    def getPlayerRanksInfo(self):
        if not self.__rankSettings:
            famePtsByRank = self.__metaSettings.metaLevel.get(
                'famePtsByRank', {})
            rankSettings = getRankSettings()
            self.__rankSettings = {
                rankLvl:
                (extraFamePts, rankSettings.bonus.factor100ByRank[rankLvl])
                for rankLvl, extraFamePts in famePtsByRank.iteritems()
            }
        return self.__rankSettings

    def getSeasonData(self):
        return self.__itemsCache.items.epicMetaGame.seasonData

    def getSkillPoints(self):
        return self.__itemsCache.items.epicMetaGame.skillPoints

    def getSkillLevels(self):
        return self.__itemsCache.items.epicMetaGame.skillLevels

    def getSelectedSkills(self, vehicleCD):
        selected = self.__itemsCache.items.epicMetaGame.selectedSkills(
            vehicleCD)
        numSlots = self.getNumAbilitySlots(vehicles.getVehicleType(vehicleCD))
        while len(selected) < numSlots:
            selected.append(-1)

        return selected

    def hasSuitableVehicles(self):
        requiredLevel = self.getModeSettings().validVehicleLevels
        v = self.__itemsCache.items.getVehicles(
            REQ_CRITERIA.INVENTORY
            | REQ_CRITERIA.VEHICLE.LEVELS(requiredLevel))
        return len(v) > 0

    def increaseSkillLevel(self, skillID):
        BigWorld.player().epicMetaGame.increaseAbility(skillID)

    def changeEquippedSkills(self,
                             skillIDArray,
                             vehicleCD,
                             callback=None,
                             classVehs=False):
        if classVehs:
            if callback is None:
                BigWorld.player().epicMetaGame.setSelectedAbilitiesVehsClass(
                    skillIDArray, vehicleCD)
            else:
                BigWorld.player().epicMetaGame.setSelectedAbilitiesVehsClass(
                    skillIDArray, vehicleCD, callback)
        elif callback is None:
            BigWorld.player().epicMetaGame.setSelectedAbilities(
                skillIDArray, vehicleCD)
        else:
            BigWorld.player().epicMetaGame.setSelectedAbilities(
                skillIDArray, vehicleCD, callback)
        return

    def getCycleInfo(self, cycleID=None):
        season = self.getCurrentSeason()
        if season is not None:
            return season.getCycleInfo(cycleID)
        else:
            _logger.warning('No current season')
            return

    def getCycleOrdinalNumber(self, cycleID):
        cycleInfo = self.getCycleInfo(cycleID)
        return cycleInfo.ordinalNumber if cycleInfo else None

    def getSeasonTimeRange(self):
        season = self.getCurrentSeason() or self.getNextSeason()
        if season is not None:
            cycles = season.getAllCycles()
            if cycles:
                cycles = list(
                    sorted(cycles.values(), key=lambda c: c.ordinalNumber))
                return (cycles[0].startDate, cycles[-1].endDate)
        return (0, 0)

    def getAllUnlockedSkillInfoBySkillId(self):
        return {
            skillID: skill.getSkillInfo()
            for skillID, skill in self.__skillData.iteritems()
            if skill.isActivated
        }

    def getUnlockedAbilityIds(self):
        return (skill.getSkillInfo().eqID
                for skill in self.getAllSkillsInformation().itervalues()
                if skill.isActivated and skill.getSkillInfo() is not None)

    def getStoredEpicDiscount(self):
        return BigWorld.player().epicMetaGame.getStoredDiscount()

    def getEventTimeLeft(self):
        timeLeft = self.getSeasonTimeRange(
        )[1] - time_utils.getCurrentLocalServerTimestamp()
        return timeLeft + 1 if timeLeft > 0 else time_utils.ONE_MINUTE

    def getStats(self):
        return self.__itemsCache.items.epicMetaGame

    @process
    def openURL(self, url=None):
        requestUrl = url or self.getModeSettings().url
        if requestUrl:
            parsedUrl = yield self.__urlMacros.parse(requestUrl)
            if parsedUrl:
                self.__showBrowserView(parsedUrl)

    def showCustomScreen(self, screen):
        if self.getModeSettings().url and EpicBattleScreens.hasValue(screen):
            self.openURL('/'.join((self.getModeSettings().url.strip('/'),
                                   screen.value.strip('/'))))

    def getNumAbilitySlots(self, vehicleType):
        vehClass = getVehicleClassFromVehicleType(vehicleType)
        return self.__metaSettings.defaultSlots.get(vehClass, 0)

    def getAbilitySlotsOrder(self, vehicleType):
        vehClass = getVehicleClassFromVehicleType(vehicleType)
        return self.__metaSettings.slots.get(vehClass, (0, 0, 0))

    def getAbilitySlotsUnlockOrder(self, vehicleType):
        vehClass = getVehicleClassFromVehicleType(vehicleType)
        return self.__metaSettings.inBattleReservesByRank.get(
            'slotActions').get(vehClass, [[0], [0], [0]])

    def getAllLevelRewards(self):
        rewardsData = dict()
        allQuests = self.__eventsCache.getAllQuests()
        for questKey, questData in allQuests.iteritems():
            if LEVELUP_TOKEN_TEMPLATE in questKey:
                _, _, questNum = questKey.partition(LEVELUP_TOKEN_TEMPLATE)
                if questNum:
                    questLvl = int(questNum)
                    rewardsData[questLvl] = questData

        return rewardsData

    def isNeedToTakeReward(self):
        currentLevel, _ = self.getPlayerLevelInfo()
        rewardsData = self.getAllLevelRewards()
        for bonuses in (rewards.getBonuses()
                        for level, rewards in rewardsData.iteritems()
                        if level <= currentLevel):
            for bonus in bonuses:
                if bonus.getName() == EPIC_SELECT_BONUS_NAME:
                    for tokenID in bonus.getTokens().iterkeys():
                        if self.__itemsCache.items.tokens.getToken(tokenID):
                            return True

        return False

    def getNotChosenRewardCount(self):
        count = 0
        for token in self.__itemsCache.items.tokens.getTokens().iterkeys():
            if not token.startswith(EPIC_CHOICE_REWARD_OFFER_GIFT_TOKENS):
                continue
            if not self.__offersProvider.getOfferByToken(
                    token.replace('_gift', '')):
                continue
            if self.__itemsCache.items.tokens.isTokenAvailable(token):
                count += self.__itemsCache.items.tokens.getTokenCount(token)

        return count

    def hasAnyOfferGiftToken(self):
        return any((token.startswith(EPIC_CHOICE_REWARD_OFFER_GIFT_TOKENS)
                    for token in
                    self.__itemsCache.items.tokens.getTokens().iterkeys()))

    def replaceOfferByGift(self, bonuses):
        result = []
        for bonus in bonuses:
            gift = self.__getReceivedGift(bonus)
            if gift:
                result.extend(gift.bonuses)
            result.append(bonus)

        return result

    def replaceOfferByReward(self, bonuses):
        result = []
        for bonus in bonuses:
            if bool(self.__getReceivedGift(bonus)):
                bonus.updateContext({'isReceived': True})
            result.append(bonus)

        return result

    def __getReceivedGift(self, bonus):
        if bonus.getName() == EPIC_SELECT_BONUS_NAME:
            bonus.updateContext({'isReceived': False})
            for tokenID in bonus.getTokens().iterkeys():
                offer = self.__offersProvider.getOfferByToken(
                    tokenID.replace('_gift', ''))
                if offer:
                    receivedGifts = self.__offersProvider.getReceivedGifts(
                        offer.id)
                    if receivedGifts:
                        for giftId, count in receivedGifts.iteritems():
                            if count > 0:
                                return offer.getGift(giftId)

        return None

    def __invalidateBattleAbilities(self, *_):
        if not self.__itemsCache.isSynced():
            return
        self.__invalidateBattleAbilityItems()
        self.__invalidateBattleAbilitiesForVehicle()

    def __setData(self):
        self.__skillData = {}
        skills = self.__metaSettings.rewards.get('combatReserves', {})
        maxSkillLvl = self.__metaSettings.maxCombatReserveLevel
        eqs = vehicles.g_cache.equipments()
        if skills != {}:
            for key, value in skills.iteritems():
                self.__skillData[key] = EpicMetaGameSkill(
                    key, maxSkillLvl, value.get('tags'), value.get('price', 0))
                lvls = value['levels']
                lvlAmount = len(lvls)
                found = 0
                for eq in eqs.values():
                    if eq.name in lvls:
                        lvl = lvls.index(eq.name) + 1
                        self.__skillData[key].levels[
                            lvl] = EpicMetaGameSkillLevel(
                                lvl, eq.id[1], i18n.makeString(eq.userString),
                                i18n.makeString(eq.shortDescription),
                                i18n.makeString(eq.longDescription),
                                i18n.makeString(eq.shortFilterAlert),
                                i18n.makeString(eq.longFilterAlert),
                                eq.icon[0])
                        found += 1
                        if found == lvlAmount:
                            break

        metaLevel = self.__metaSettings.metaLevel
        self.__playerMaxLevel = metaLevel.get('maxLevel', 0)
        self.__stageLimit = metaLevel.get('stageLimit', -1)
        self.__abilityPointsForLevel = metaLevel.get('abilityPointsForLevel',
                                                     [])
        levelProgress = metaLevel.get('famePtsToProgress', [])[:]
        levelProgress.insert(0, 0)
        self.__levelProgress = tuple(levelProgress)

    def __clear(self):
        self.stopNotification()
        self.stopGlobalListening()
        self.__lobbyContext.getServerSettings(
        ).onServerSettingsChange -= self.__updateEpicMetaGameSettings
        g_currentVehicle.onChanged -= self.__invalidateBattleAbilities
        self.__itemsCache.onSyncCompleted -= self.__invalidateBattleAbilities
        g_clientUpdateManager.removeObjectCallbacks(self)
        if self.getPerformanceGroup() == EPIC_PERF_GROUP.HIGH_RISK:
            self.__lobbyContext.deleteFightButtonConfirmator(
                self.__confirmFightButtonPressEnabled)

    def __updateEpic(self, diff):
        changes = set(diff.keys())
        self.__invalidateBattleAbilities()
        if changes:
            self.onUpdated(diff)

    def __updateEpicMetaGameSettings(self, diff):
        if 'epic_config' in diff:
            self.__setData()
            self.onUpdated(diff['epic_config'])
            self.__resetTimer()

    def __resetTimer(self):
        self.startNotification()
        self.__timerUpdate()
        self.__timerTick()

    def __timerUpdate(self):
        status, _, _ = self.getPrimeTimeStatus()
        self.onPrimeTimeStatusUpdated(status)

    def __timerTick(self):
        self.onGameModeStatusTick()

    def __onEventEnded(self):
        self.onEventEnded()
        self.__eventEndedNotifier.stopNotification()
        self.__eventEndedNotifier.clear()

    def __showBattleResults(self, reusableInfo, _, resultsWindow):
        if reusableInfo.common.arenaBonusType == ARENA_BONUS_TYPE.EPIC_BATTLE:
            arenaUniqueID = reusableInfo.arenaUniqueID
            if arenaUniqueID not in self.__showedResultsForArenas:
                self.__showedResultsForArenas.append(arenaUniqueID)
                self.__showedResultsForArenas = self.__showedResultsForArenas[
                    -self.MAX_STORED_ARENAS_RESULTS:]
                extensionInfo = reusableInfo.personal.avatar.extensionInfo
                levelUpInfo = {
                    'metaLevel': extensionInfo.get('metaLevel'),
                    'prevMetaLevel': extensionInfo.get('prevMetaLevel'),
                    'playerRank': extensionInfo.get('playerRank'),
                    'originalFlXP': extensionInfo.get('originalFlXP'),
                    'boosterFlXP': extensionInfo.get('boosterFlXP')
                }
                event_dispatcher.showEpicBattlesAfterBattleWindow(
                    levelUpInfo, resultsWindow)

    def __isInValidPrebattle(self):
        if g_prbLoader and g_prbLoader.getDispatcher(
        ) and g_prbLoader.getDispatcher().getEntity():
            currentPrbEntity = g_prbLoader.getDispatcher().getEntity(
            ).getEntityType()
            return currentPrbEntity in (QUEUE_TYPE.EPIC, PREBATTLE_TYPE.EPIC,
                                        PREBATTLE_TYPE.EPIC_TRAINING)
        else:
            return None

    def __invalidateBattleAbilityItems(self):
        data = self.__itemsCache.items.getItems(GUI_ITEM_TYPE.BATTLE_ABILITY,
                                                REQ_CRITERIA.EMPTY)
        vehicle = g_currentVehicle.item
        for item in data.values():
            if self.__isInValidPrebattle():
                item.isUnlocked = item.innationID in self.getUnlockedAbilityIds(
                )
                if vehicle is not None:
                    mayInstall, _ = item.mayInstall(vehicle)
                    if not mayInstall:
                        item.isUnlocked = False
            item.isUnlocked = False

        return

    def __invalidateBattleAbilitiesForVehicle(self):
        vehicle = g_currentVehicle.item
        if vehicle is None or vehicle.descriptor.type.level not in self.__lobbyContext.getServerSettings(
        ).epicBattles.validVehicleLevels or not self.__isInValidPrebattle():
            return
        else:
            amountOfSlots = self.getNumAbilitySlots(vehicle.descriptor.type)
            selectedItems = [None] * amountOfSlots
            skillInfo = self.getAllSkillsInformation()
            selectedSkills = self.getSelectedSkills(vehicle.intCD)
            battleAbilities = self.__itemsCache.items.getItems(
                GUI_ITEM_TYPE.BATTLE_ABILITY, REQ_CRITERIA.EMPTY)
            for item in battleAbilities.values():
                for index, skillID in enumerate(selectedSkills):
                    if skillID is not None and skillID >= 0:
                        if skillInfo[skillID].getSkillInfo(
                        ) and item.innationID == skillInfo[
                                skillID].getSkillInfo().eqID:
                            selectedItems[index] = item

            vehicle.battleAbilities.setLayout(*selectedItems)
            vehicle.battleAbilities.setInstalled(*selectedItems)
            return

    def __analyzeClientSystem(self):
        stats = BigWorld.wg_getClientStatistics()
        stats['graphicsEngine'] = self.__settingsCore.getSetting(
            GRAPHICS.RENDER_PIPELINE)
        self.__performanceGroup = EPIC_PERF_GROUP.LOW_RISK
        for groupName, conditions in PERFORMANCE_GROUP_LIMITS.iteritems():
            for currentLimit in conditions:
                condValid = True
                systemStats = currentLimit.get(
                    EPIC_META_GAME_LIMIT_TYPE.SYSTEM_DATA, {})
                for key, limit in systemStats.iteritems():
                    currValue = stats.get(key, None)
                    if currValue is None or currValue != limit:
                        condValid = False

                hardwareParams = currentLimit.get(
                    EPIC_META_GAME_LIMIT_TYPE.HARDWARE_PARAMS, {})
                for key, limit in hardwareParams.iteritems():
                    currValue = BigWorld.getAutoDetectGraphicsSettingsScore(
                        key)
                    if currValue >= limit:
                        condValid = False

                if condValid:
                    self.__performanceGroup = groupName
                    return

        return

    def __onInventoryUpdate(self, invDiff):
        items = {
            GUI_ITEM_TYPE.VEHICLE, GUI_ITEM_TYPE.BATTLE_ABILITY,
            GUI_ITEM_TYPE.CUSTOMIZATION
        }
        if items.intersection(invDiff):
            self.__invalidateBattleAbilities()

    def __updateSounds(self, isEpicSoundMode):
        if isEpicSoundMode != self.__isEpicSoundMode:
            _FrontLineSounds.onChange(isEpicSoundMode)
            self.__isEpicSoundMode = isEpicSoundMode

    @async
    @process
    def __confirmFightButtonPressEnabled(self, callback):
        if not self.__isInValidPrebattle():
            callback(True)
            return
        defaults = AccountSettings.getFilterDefault(GUI_START_BEHAVIOR)
        filters = self.__settingsCore.serverSettings.getSection(
            GUI_START_BEHAVIOR, defaults)
        isEpicPerformanceWarningEnabled = not AccountSettings.getSettings(
            'isEpicPerformanceWarningClicked')
        if isEpicPerformanceWarningEnabled:
            result, checkboxChecked = yield DialogsInterface.showI18nCheckBoxDialog(
                'epicBattleConfirmDialog')
            filters['isEpicPerformanceWarningClicked'] = checkboxChecked
            AccountSettings.setSettings('isEpicPerformanceWarningClicked',
                                        checkboxChecked)
        else:
            result = True
        callback(result)

    def __showBrowserView(self, url):
        from gui.Scaleform.daapi.view.lobby.epicBattle.web_handlers import createFrontlineWebHandlers
        webHandlers = createFrontlineWebHandlers()
        alias = VIEW_ALIAS.BROWSER_VIEW
        g_eventBus.handleEvent(
            events.LoadViewEvent(SFViewLoadParams(alias,
                                                  getUniqueViewName(alias)),
                                 ctx={
                                     'url':
                                     url,
                                     'webHandlers':
                                     webHandlers,
                                     'returnAlias':
                                     VIEW_ALIAS.LOBBY_HANGAR,
                                     'onServerSettingsChange':
                                     self.__serverSettingsChangeBrowserHandler
                                 }), EVENT_BUS_SCOPE.LOBBY)

    def __serverSettingsChangeBrowserHandler(self, browser, diff):
        if not diff.get(Configs.EPIC_CONFIG.value, {}).get('isEnabled'):
            browser.onCloseView()

    @property
    def __metaSettings(self):
        return self.__lobbyContext.getServerSettings().epicMetaGame

    def __onTokensUpdate(self, diff):
        if any((key.startswith(EPIC_CHOICE_REWARD_OFFER_GIFT_TOKENS)
                for key in diff.keys())):
            pass
class ExternalLinksHandler(IExternalLinksController):
    def __init__(self):
        super(ExternalLinksHandler, self).__init__()
        self.__urlMacros = None
        return

    def init(self):
        self.__urlMacros = URLMacros()
        addListener = g_eventBus.addListener
        for eventType, handlerName in _LISTENERS.iteritems():
            handler = getattr(self, handlerName, None)
            if not handler:
                LOG_ERROR('Handler is not found', eventType, handlerName)
                continue
            if not callable(handler):
                LOG_ERROR('Handler is invalid', eventType, handlerName,
                          handler)
                continue
            addListener(eventType, handler)

        return

    def fini(self):
        if self.__urlMacros is not None:
            self.__urlMacros.clear()
            self.__urlMacros = None
        removeListener = g_eventBus.removeListener
        for eventType, handlerName in _LISTENERS.iteritems():
            handler = getattr(self, handlerName, None)
            if handler:
                removeListener(eventType, handler)

        super(ExternalLinksHandler, self).fini()
        return

    def open(self, url):
        if not url:
            LOG_ERROR('URL is empty', url)
            return
        try:
            BigWorld.wg_openWebBrowser(url)
        except Exception:
            LOG_ERROR('There is error while opening web browser at page:', url)
            LOG_CURRENT_EXCEPTION()

    @async
    @process
    def getURL(self, name, params=None, callback=lambda *args: None):
        urlSettings = GUI_SETTINGS.lookup(name)
        if urlSettings:
            url = yield self.__urlMacros.parse(str(urlSettings), params)
        else:
            url = yield lambda callback: callback('')
        callback(url)

    def _handleSpecifiedURL(self, event):
        self.open(event.url)

    @process
    def __openParsedUrl(self, urlName, params=None):
        parsedUrl = yield self.getURL(urlName, params)
        self.open(parsedUrl)

    def _handleParsedURL(self, event):
        self.__openParsedUrl(event.url)

    def _handleOpenRegistrationURL(self, _):
        self.__openParsedUrl('registrationURL')

    def _handleOpenRecoveryPasswordURL(self, _):
        self.__openParsedUrl('recoveryPswdURL')

    def _handleOpenPaymentURL(self, _):
        self.__openParsedUrl('paymentURL')

    def _handleSecuritySettingsURL(self, _):
        self.__openParsedUrl('securitySettingsURL')

    def _handleSupportURL(self, _):
        self.__openParsedUrl('supportURL')

    def _handleMigrationURL(self):
        self.__openParsedUrl('migrationURL')

    def _handleFortDescription(self, _):
        self.__openParsedUrl('fortDescription')

    def _handleClanSearch(self, _):
        self.__openParsedUrl('clanSearch')

    def _handleClanCreate(self, _):
        self.__openParsedUrl('clanCreate')

    def _handleInvitesManagementURL(self, _):
        self.__openParsedUrl('invitesManagementURL')

    def _handleGmSummaryURL(self, _):
        self.__openParsedUrl('globalMapSummary')

    def _handleGmPromoSummaryURL(self, _):
        self.__openParsedUrl('globalMapPromoSummary')

    def _handleGmCapURL(self, _):
        self.__openParsedUrl('globalMapCap')

    def _handleGmPromoURL(self, _):
        self.__openParsedUrl('globalMapPromo')

    def _handleOpenPremShopURL(self, _):
        self.__openParsedUrl('premShopURL')

    def _handleFrontlineChangesURL(self, _):
        self.__openParsedUrl('frontlineChangesURL')

    def _handleTokenShopURL(self, event):
        self.__openParsedUrl('tokenShopURL', event.params)

    def _handleTechTreeNewsURL(self, event):
        self.__openParsedUrl('techTreeUpdateNewsURL', event.params)
class PromoController(IPromoController):
    __browserCtrl = dependency.descriptor(IBrowserController)
    __notificationsCtrl = dependency.descriptor(IEventsNotificationsController)
    __webController = dependency.descriptor(IWebController)
    __settingsCore = dependency.descriptor(ISettingsCore)
    __lobbyContext = dependency.descriptor(ILobbyContext)
    __logger = dependency.descriptor(IPromoLogger)
    __bootcamp = dependency.descriptor(IBootcampController)

    def __init__(self):
        super(PromoController, self).__init__()
        self.__urlMacros = URLMacros()
        self.__externalCloseCallback = None
        self.__isLobbyInited = False
        self.__pendingPromo = None
        self.__promoCount = 0
        self.__lastUpdateTimeMark = 0
        self.__promoData = None
        self.__waitingForWebBridgeData = False
        self.__battlesFromLastTeaser = 0
        self.__wasInBattle = False
        self.__hasPendingTeaser = False
        self.__isPromoOpen = False
        self.__browserCreationCallbacks = {}
        self.__browserWatchers = {}
        self.__isInHangar = False
        self.__isTeaserOpen = False
        self.__checkIntervalInBattles = GUI_SETTINGS.checkPromoFrequencyInBattles
        self.__em = EventManager()
        self.onNewTeaserReceived = Event(self.__em)
        self.onPromoCountChanged = Event(self.__em)
        self.onTeaserShown = Event(self.__em)
        self.onTeaserClosed = Event(self.__em)
        return

    @sf_lobby
    def app(self):
        pass

    def fini(self):
        self.__stop()
        self.__pendingPromo = None
        self.__urlMacros.clear()
        self.__urlMacros = None
        self.__externalCloseCallback = None
        self.__em.clear()
        g_eventBus.removeListener(BrowserEvent.BROWSER_CREATED,
                                  self.__handleBrowserCreated)
        self.__browserCreationCallbacks = {}
        self.__browserWatchers = {}
        super(PromoController, self).fini()
        return

    def onLobbyInited(self, event):
        if not isPlayerAccount():
            return
        g_eventBus.addListener(BrowserEvent.BROWSER_CREATED,
                               self.__handleBrowserCreated)
        self.__isLobbyInited = True
        if self.__needToGetTeasersInfo():
            self.__updateWebBrgData()
        elif self.__hasPendingTeaser:
            self.__tryToShowTeaser()
        self.__notificationsCtrl.onEventNotificationsChanged += self.__onEventNotification
        if not isPopupsWindowsOpenDisabled():
            self.__processPromo(
                self.__notificationsCtrl.getEventsNotifications())
        self.app.loaderManager.onViewLoaded += self.__onViewLoaded

    @property
    def checkIntervalInBattles(self):
        return self.__checkIntervalInBattles

    def setNewTeaserData(self, teaserData):
        timestamp = teaserData['timestamp']
        if self.__lastUpdateTimeMark < timestamp and not self.__isPromoOpen and not self.__isTeaserOpen:
            self.__updateTeaserData(teaserData)

    def showFieldPost(self):
        url = GUI_SETTINGS.promoscreens
        loadingCallback = self.__logger.getLoggingFuture(
            action=PromoLogActions.OPEN_FROM_MENU,
            type=PromoLogSubjectType.INDEX,
            url=url)
        self.__showBrowserView(url, loadingCallback, soundSpaceID='field_post')

    @process
    def showLastTeaserPromo(self):
        rowUrl = self.__promoData.get('url', '')
        loadingCallback = self.__logger.getLoggingFuture(
            self.__promoData,
            action=PromoLogActions.OPEN_FROM_TEASER,
            type=PromoLogSubjectType.PROMO_SCREEN,
            url=rowUrl)
        url = yield self.__addAuthParams(rowUrl)
        self.__showBrowserView(url, loadingCallback)

    def setUnreadPromoCount(self, count):
        self.__updatePromoCount(count)

    def isTeaserOpen(self):
        return self.__isTeaserOpen

    def onAvatarBecomePlayer(self):
        if self.__isLobbyInited:
            self.__battlesFromLastTeaser += 1
        self.__stop()

    def onDisconnected(self):
        self.__stop()

    def isActive(self):
        return self.__lobbyContext.getServerSettings().isFieldPostEnabled(
        ) and not self.__bootcamp.isInBootcamp()

    def getPromoCount(self):
        return self.__promoCount

    def showPromo(self, url, closeCallback=None, source=None):
        if self.__isLobbyInited:
            if not self.__isPromoOpen and not self.__waitingForWebBridgeData:
                self.__registerAndShowPromoBrowser(
                    url, closeCallback,
                    self.__logger.getLoggingFuture(
                        action=PromoLogActions.OPEN_IN_OLD,
                        type=PromoLogSubjectType.PROMO_SCREEN,
                        source=source,
                        url=url))
        else:
            self.__pendingPromo = _PromoData(url, closeCallback, source)

    def __needToGetTeasersInfo(self):
        return True if self.__battlesFromLastTeaser == 0 else self.__checkIntervalInBattles > 0 and self.__battlesFromLastTeaser % self.__checkIntervalInBattles == 0

    def __onTeaserClosed(self, byUser=False):
        self.__isTeaserOpen = False
        self.onTeaserClosed()
        if byUser:
            self.__showBubbleTooltip()

    def __showBubbleTooltip(self):
        storageData = self.__settingsCore.serverSettings.getUIStorage()
        if not storageData.get(UI_STORAGE_KEYS.FIELD_POST_HINT_IS_SHOWN):
            showBubbleTooltip(i18n.makeString(TOOLTIPS.HEADER_VERSIONINFOHINT))
            self.__settingsCore.serverSettings.saveInUIStorage(
                {UI_STORAGE_KEYS.FIELD_POST_HINT_IS_SHOWN: True})

    @process
    def __updateWebBrgData(self):
        ctx = PromoGetTeaserRequestCtx()
        if self.__battlesFromLastTeaser == 0:
            sourceType = PromoLogSourceType.FIRST_LOGIN
        else:
            sourceType = PromoLogSourceType.AFTER_BATTLE
        answerCallback = self.__logger.getLoggingFuture(
            action=PromoLogActions.GET_MOST_IMPORTANT, source=sourceType)
        self.__waitingForWebBridgeData = True
        response = yield self.__webController.sendRequest(ctx=ctx)
        self.__waitingForWebBridgeData = False
        if response.isSuccess():
            self.__updateTeaserData(ctx.getDataObj(response.getData()))
        elif self.__hasPendingTeaser:
            self.__tryToShowTeaser()
        if answerCallback:
            answerCallback(success=response.extraCode)

    def __onPromoClosed(self, **kwargs):
        self.__isPromoOpen = False
        self.__showBubbleTooltip()
        if self.__externalCloseCallback:
            self.__externalCloseCallback()
        self.__requestPromoCount()
        actionType = PromoLogActions.CLOSED_BY_USER if kwargs.get(
            'byUser') else PromoLogActions.KILLED_BY_SYSTEM
        self.__logger.logAction(action=actionType,
                                type=PromoLogSubjectType.PROMO_SCREEN_OR_INDEX,
                                url=kwargs.get('url'))

    @process
    def __requestPromoCount(self):
        if not self.isActive():
            _logger.warning(
                'Trying to request unread promos count when promo functionality is disabled'
            )
            return
        ctx = PromoGetUnreadCountRequestCtx()
        response = yield self.__webController.sendRequest(ctx=ctx)
        if response.isSuccess():
            self.__updatePromoCount(ctx.getCount(response))

    def __updatePromoCount(self, count):
        countChanged = count != self.__promoCount
        self.__promoCount = count
        if countChanged:
            self.onPromoCountChanged()

    def __updateTeaserData(self, teaserData):
        self.__lastUpdateTimeMark = teaserData['timestamp']
        self.__promoData = teaserData['lastPromo']
        self.__updatePromoCount(teaserData['count'])
        if self.__promoData.get('url'):
            self.__tryToShowTeaser()

    def __showTeaser(self):
        if self.isActive():
            self.__battlesFromLastTeaser = 0
            self.__hasPendingTeaser = False
            self.onNewTeaserReceived(self.__promoData, self.__onTeaserShown,
                                     self.__onTeaserClosed)
        else:
            _logger.warning(
                'Impossible to show teaser, functionality is disabled')

    @process
    def __onTeaserShown(self, promoID):
        self.__isTeaserOpen = True
        self.onTeaserShown()
        yield self.__webController.sendRequest(
            PromoSendTeaserShownRequestCtx(promoID))

    def __tryToShowTeaser(self):
        if self.__isLobbyInited and self.__isInHangar and not self.__waitingForWebBridgeData:
            self.__showTeaser()
        else:
            self.__hasPendingTeaser = True

    def __stop(self):
        if self.app and self.app.loaderManager:
            self.app.loaderManager.onViewLoaded -= self.__onViewLoaded
        self.__isLobbyInited = False
        self.__isInHangar = False
        self.__isPromoOpen = False
        self.__externalCloseCallback = None
        self.__isTeaserOpen = False
        self.__notificationsCtrl.onEventNotificationsChanged -= self.__onEventNotification
        g_eventBus.removeListener(BrowserEvent.BROWSER_CREATED,
                                  self.__handleBrowserCreated)
        self.__browserCreationCallbacks = {}
        watcherKeys = self.__browserWatchers.keys()
        for browserID in watcherKeys:
            self.__clearWatcher(browserID)

        return

    def __processPromo(self, promos):
        if not self.__isPromoOpen and not self.__waitingForWebBridgeData:
            logData = {
                'action': PromoLogActions.OPEN_IN_OLD,
                'type': PromoLogSubjectType.PROMO_SCREEN
            }
            if self.__pendingPromo is not None:
                promoData = self.__pendingPromo
                logData.update({
                    'source': promoData.source,
                    'url': promoData.url
                })
                loadingCallback = self.__logger.getLoggingFuture(**logData)
                self.__registerAndShowPromoBrowser(promoData.url,
                                                   promoData.closeCallback,
                                                   loadingCallback)
                self.__pendingPromo = None
                return
            promo = findFirst(
                lambda item: item.eventType.startswith(
                    gc_constants.PROMO.TEMPLATE.ACTION), promos)
            if promo:
                logData.update({
                    'source': PromoLogSourceType.SSE,
                    'url': promo.data
                })
                self.__showBrowserView(
                    promo.data, self.__logger.getLoggingFuture(**logData))
        return

    def __onEventNotification(self, added, _):
        self.__processPromo(added)

    def __registerAndShowPromoBrowser(self, url, closeCallback,
                                      loadingCallback):
        self.__externalCloseCallback = closeCallback
        self.__showBrowserView(url, loadingCallback)

    @process
    def __showBrowserView(self, url, loadingCallback=None, soundSpaceID=None):
        promoUrl = yield self.__urlMacros.parse(url)
        self.__registerLoadingCallback(promoUrl, loadingCallback)
        _showBrowserView(promoUrl,
                         self.__onPromoClosed,
                         soundSpaceID=soundSpaceID)
        self.__isPromoOpen = True

    def __registerLoadingCallback(self, url, callback):
        if callback is not None:
            self.__browserCreationCallbacks[url] = callback
        return

    def __handleBrowserCreated(self, event):
        url = event.ctx.get('url')
        if url in self.__browserCreationCallbacks:
            callback = self.__browserCreationCallbacks.pop(url)
            browserID = event.ctx.get('browserID')
            browser = self.__browserCtrl.getBrowser(browserID)
            if browser is None:
                return

            def callbackWrapper(clbUrl, _, statusCode):
                if clbUrl == url:
                    callback(url=url, success=statusCode)
                    self.__clearWatcher(browserID)

            browser.onLoadEnd += callbackWrapper
            self.__browserWatchers[browserID] = callbackWrapper
        return

    def __clearWatcher(self, browserID):
        if browserID in self.__browserWatchers:
            watcher = self.__browserWatchers.pop(browserID)
            browser = self.__browserCtrl.getBrowser(browserID)
            if browser is not None:
                browser.onLoadEnd -= watcher
        return

    @async
    @process
    def __addAuthParams(self, url, callback):
        if not url or not self.__webController:
            callback(url)
        accessTokenData = yield self.__webController.getAccessTokenData(
            force=True)
        params = {
            'access_token': str(accessTokenData.accessToken),
            'spa_id': BigWorld.player().databaseID
        }
        callback(url_formatters.addParamsToUrlQuery(url, params))

    def __onViewLoaded(self, pyView, _):
        if self.__isLobbyInited:
            if pyView.alias == VIEW_ALIAS.LOBBY_HANGAR:
                self.__isInHangar = True
                if self.__hasPendingTeaser:
                    self.__tryToShowTeaser()
            elif pyView.viewType == ViewTypes.LOBBY_SUB:
                self.__isInHangar = False
class ExternalLinksHandler(IExternalLinksController):
    __loginManager = dependency.descriptor(ILoginManager)

    def __init__(self):
        super(ExternalLinksHandler, self).__init__()
        self.__urlMacros = None
        self.__linksHandlers = None
        return

    def init(self):
        self.__urlMacros = URLMacros()
        addListener = g_eventBus.addListener
        for eventType, handlerName in _LISTENERS.iteritems():
            handler = getattr(self, handlerName, None)
            if not handler:
                _logger.error('Handler is not found %s %s', eventType,
                              handlerName)
                continue
            if not callable(handler):
                _logger.error('Handler is invalid %s %s %r', eventType,
                              handlerName, handler)
                continue
            addListener(eventType, handler)

        return

    def fini(self):
        if self.__urlMacros is not None:
            self.__urlMacros.clear()
            self.__urlMacros = None
        removeListener = g_eventBus.removeListener
        for eventType, handlerName in _LISTENERS.iteritems():
            handler = getattr(self, handlerName, None)
            if handler:
                removeListener(eventType, handler)

        super(ExternalLinksHandler, self).fini()
        return

    def open(self, url):
        if not url:
            _logger.error('URL is empty %r', url)
            return
        handled = False
        for handler in self._getHandlers():
            handled = handler.handle(url)
            if handled:
                break

        if not handled:
            _logger.error('Cant handle external link: %s', url)

    @async
    @process
    def getURL(self, name, params=None, callback=lambda *args: None):
        urlSettings = GUI_SETTINGS.lookup(name)
        if urlSettings:
            url = yield self.__urlMacros.parse(str(urlSettings), params)
        else:
            url = yield lambda callback: callback('')
        callback(url)

    def externalAllowed(self, url):
        for handler in self._getHandlers():
            result = handler.checkHandle(url)
            if result.handled:
                return result.externalAllowed

        return False

    def _handleSpecifiedURL(self, event):
        self.open(event.url)

    @process
    def __openParsedUrl(self, urlName, params=None):
        parsedUrl = yield self.getURL(urlName, params)
        self.open(parsedUrl)

    def _handleParsedURL(self, event):
        self.__openParsedUrl(event.url)

    def _handleOpenRegistrationURL(self, _):
        self.__openParsedUrl('registrationURL')

    def _handleOpenRecoveryPasswordURL(self, _):
        self.__openParsedUrl('recoveryPswdURL')

    def _handleOpenPaymentURL(self, _):
        self.__openParsedUrl('paymentURL')

    def _handleSecuritySettingsURL(self, _):
        self.__openParsedUrl('securitySettingsURL')

    def _handleClanRulesURL(self, _):
        self.__openParsedUrl('clanRulesURL')

    def _handleSupportURL(self, _):
        self.__openParsedUrl('supportURL')

    def _handleMigrationURL(self):
        self.__openParsedUrl('migrationURL')

    def _handleFortDescription(self, _):
        self.__openParsedUrl('fortDescription')

    def _handleClanSearch(self, _):
        self.__openParsedUrl('clanSearch')

    def _handleClanCreate(self, _):
        self.__openParsedUrl('clanCreate')

    def _handleInvitesManagementURL(self, _):
        self.__openParsedUrl('invitesManagementURL')

    def _handleGmSummaryURL(self, _):
        self.__openParsedUrl('globalMapSummary')

    def _handleGmPromoSummaryURL(self, _):
        self.__openParsedUrl('globalMapPromoSummary')

    def _handleGmCapURL(self, _):
        self.__openParsedUrl('globalMapCap')

    def _handleGmPromoURL(self, _):
        self.__openParsedUrl('globalMapPromo')

    def _handleOpenPremShopURL(self, _):
        self.__openParsedUrl('premShopURL')

    def _handleFrontlineChangesURL(self, _):
        self.__openParsedUrl('frontlineChangesURL')

    def _handleTokenShopURL(self, event):
        self.__openParsedUrl('tokenShopURL', event.params)

    def _getHandlers(self):
        if not self.__linksHandlers:
            self.__linksHandlers = []
            if self.__loginManager.isWgcSteam:
                self.__linksHandlers.append(external.PremShopLinksHandler())
                self.__linksHandlers.append(
                    external.AddPlatformTagLinksHandler())
                self.__linksHandlers.append(
                    external.PremShopLinksForArgsUrlHandler())
                self.__linksHandlers.append(
                    external.AddPlatformTagLinksToArgsUrlHandler())
            self.__linksHandlers.append(external.OpenBrowserHandler())
        return self.__linksHandlers
 def __init__(self, ctx):
     super(PersonalMissionFirstEntryView, self).__init__(ctx)
     self.__urlMacros = URLMacros()
     self.__settings = GUI_SETTINGS.personalMissions.get('welcomeVideo', {})
     self.__cardsLen = len(self.__CARDS)
class PersonalMissionFirstEntryView(LobbySubView,
                                    PersonalMissionFirstEntryViewMeta):
    _COMMON_SOUND_SPACE = PERSONAL_MISSIONS_SOUND_SPACE
    __settingsCore = dependency.descriptor(ISettingsCore)
    __CARDS = (3, 3, 4, 4)
    __R_PERSONAL_MISSION_FIRST_ENTRY_VIEW = R.strings.personal_missions.PersonalMissionFirstEntryView

    def __init__(self, ctx):
        super(PersonalMissionFirstEntryView, self).__init__(ctx)
        self.__urlMacros = URLMacros()
        self.__settings = GUI_SETTINGS.personalMissions.get('welcomeVideo', {})
        self.__cardsLen = len(self.__CARDS)

    def playVideo(self):
        if self.__settings.get('isEnabled', False):
            self.__showVideo()

    def backBtnClicked(self):
        self.fireEvent(events.LoadViewEvent(
            SFViewLoadParams(VIEW_ALIAS.LOBBY_PERSONAL_MISSIONS)),
                       scope=EVENT_BUS_SCOPE.LOBBY)

    def onViewClose(self, isAcceptBtnClick=False):
        if isAcceptBtnClick:
            self.__settingsCore.serverSettings.saveInUIStorage(
                {PM_TUTOR_FIELDS.GREETING_SCREEN_SHOWN: True})
            self.fireEvent(events.LoadViewEvent(
                SFViewLoadParams(VIEW_ALIAS.LOBBY_PERSONAL_MISSIONS)),
                           scope=EVENT_BUS_SCOPE.LOBBY)
        else:
            self.fireEvent(events.LoadViewEvent(
                SFViewLoadParams(VIEW_ALIAS.LOBBY_HANGAR)),
                           scope=EVENT_BUS_SCOPE.LOBBY)

    def onCardClick(self, cardIndex):
        self.__updateDetailedData(cardIndex)

    def onNextCardClick(self, cardIndex):
        self.__updateDetailedData(cardIndex + 1)

    def onPrevCardClick(self, cardIndex):
        self.__updateDetailedData(cardIndex - 1)

    def _populate(self):
        super(PersonalMissionFirstEntryView, self)._populate()
        infoBlocks = [
            self.__makeTileData(cardIndex)
            for cardIndex in xrange(0, self.__cardsLen)
        ]
        firstEntry = not self.__settingsCore.serverSettings.getUIStorage().get(
            PM_TUTOR_FIELDS.GREETING_SCREEN_SHOWN)
        self.as_setInitDataS({
            'titleLabel':
            PERSONAL_MISSIONS.PERSONALMISSIONFIRSTENTRYVIEW_TITLE,
            'bigBtnLabel':
            PERSONAL_MISSIONS.PERSONALMISSIONFIRSTENTRYVIEW_ACKNOWLEDGEBTN,
            'playVideoBtnLabel':
            text_styles.concatStylesToSingleLine(
                icons.makeImageTag(
                    RES_ICONS.MAPS_ICONS_PERSONALMISSIONS_PLAYICON,
                    width=14,
                    height=15,
                    vSpace=-2),
                i18n.makeString(PERSONAL_MISSIONS.
                                PERSONALMISSIONFIRSTENTRYVIEW_VIDEOBTNLABEL)),
            'playVideoBtnVisible':
            self.__settings.get('isEnabled', False),
            'bgSource':
            RES_ICONS.MAPS_ICONS_PERSONALMISSIONS_INFOSCREENBG,
            'infoBlocks':
            infoBlocks,
            'backBtnLabel':
            PERSONAL_MISSIONS.HEADER_BACKBTN_LABEL,
            'isFirstEntry':
            firstEntry
        })
        self.soundManager.setRTPC(SOUNDS.RTCP_OVERLAY,
                                  SOUNDS.MAX_MISSIONS_ZOOM)

    def _dispose(self):
        self.soundManager.setRTPC(SOUNDS.RTCP_OVERLAY,
                                  SOUNDS.MIN_MISSIONS_ZOOM)
        super(PersonalMissionFirstEntryView, self)._dispose()

    def __updateDetailedData(self, cardIndex):
        cardIndex = self.__normalizeSlotIndex(cardIndex)
        blocksLen = self.__CARDS[cardIndex]
        blocks = []
        for blockIndex in xrange(0, blocksLen):
            blocks.append({
                'title':
                PERSONAL_MISSIONS.getBlockTitle(cardIndex, blockIndex),
                'description':
                PERSONAL_MISSIONS.getBlockDescription(cardIndex, blockIndex),
                'image':
                RES_ICONS.getBlockImageByStep(cardIndex, blockIndex)
            })

        item = self.__R_PERSONAL_MISSION_FIRST_ENTRY_VIEW.dyn(
            'item{}'.format(cardIndex))
        data = {
            'index':
            cardIndex,
            'icon':
            RES_ICONS.getInfoIcon(cardIndex),
            'title':
            PERSONAL_MISSIONS.getCardHeader(cardIndex),
            'description':
            PERSONAL_MISSIONS.getCardInnerDescription(cardIndex),
            'blocks':
            blocks,
            'notificationIcon':
            RES_ICONS.MAPS_ICONS_LIBRARY_WARNINGICON_1,
            'notificationLabel':
            backport.text(item.warning())
            if item and 'warning' in item.keys() else ''
        }
        self.as_setDetailedCardDataS(data)

    @process
    def __showVideo(self):
        url = yield self.__urlMacros.parse(self.__settings.get('url'))
        webHandlers = webApiCollection(ui_web_api.CloseViewWebApi,
                                       sound_web_api.SoundWebApi,
                                       sound_web_api.HangarSoundWebApi)
        ctx = {
            'url': url,
            'webHandlers': webHandlers,
            'returnAlias': self.alias
        }
        showPersonalMissionBrowserView(ctx)

    @staticmethod
    def __makeTileData(cardIndex):
        return {
            'index': cardIndex,
            'iconSource': RES_ICONS.getInfoIcon(cardIndex),
            'titleLabel': PERSONAL_MISSIONS.getCardHeader(cardIndex),
            'descriptionLabel': PERSONAL_MISSIONS.getCardDescription(cardIndex)
        }

    def __normalizeSlotIndex(self, slotIndex):
        if slotIndex >= self.__cardsLen:
            return 0
        return self.__cardsLen - 1 if slotIndex < 0 else slotIndex
Example #28
0
 def __init__(self):
     super(OpenBrowserOnClickComponent, self).__init__()
     self.__urlParser = URLMacros()
Example #29
0
class BattleRoyaleController(Notifiable, SeasonProvider,
                             IBattleRoyaleController, IGlobalListener):
    __lobbyContext = dependency.descriptor(ILobbyContext)
    __eventsCache = dependency.descriptor(IEventsCache)
    __itemsCache = dependency.descriptor(IItemsCache)
    __hangarsSpace = dependency.descriptor(IHangarSpace)
    __settingsCore = dependency.descriptor(ISettingsCore)
    __hangarSpacesSwitcher = dependency.descriptor(IHangarSpacesSwitcher)
    __hangarSpaceReloader = dependency.descriptor(IHangarSpaceReloader)
    __notificationsCtrl = dependency.descriptor(IEventsNotificationsController)
    __sessionProvider = dependency.descriptor(IBattleSessionProvider)
    __c11nService = dependency.descriptor(ICustomizationService)
    __connectionMgr = dependency.descriptor(IConnectionManager)
    __battleRoyaleTournamentController = dependency.descriptor(
        IBattleRoyaleTournamentController)
    __bootcamp = dependency.descriptor(IBootcampController)
    TOKEN_QUEST_ID = 'token:br:title:'
    MAX_STORED_ARENAS_RESULTS = 20

    def __init__(self):
        super(BattleRoyaleController, self).__init__()
        self.onUpdated = Event.Event()
        self.onPrimeTimeStatusUpdated = Event.Event()
        self.onSpaceUpdated = Event.Event()
        self.__clientValuesInited = False
        self.__clientShields = {}
        self.__performanceGroup = None
        self.__serverSettings = None
        self.__battleRoyaleSettings = None
        self.__wasInLobby = False
        self.__equipmentCount = {}
        self.__equipmentSlots = tuple()
        self.__voControl = None
        self.__defaultHangars = {}
        self.__c11nVisible = False
        self.__urlMacros = None
        self.__isNeedToUpdateHeroTank = False
        return

    def init(self):
        super(BattleRoyaleController, self).init()
        self.__voControl = BRVoiceOverController()
        self.__voControl.init()
        self.__urlMacros = URLMacros()
        self.addNotificator(SimpleNotifier(self.getTimer, self.__timerUpdate))

    def fini(self):
        self.__voControl.fini()
        self.__voControl = None
        self.__equipmentCount = None
        self.__defaultHangars = None
        self.__urlMacros = None
        self.onUpdated.clear()
        self.onPrimeTimeStatusUpdated.clear()
        self.clearNotification()
        super(BattleRoyaleController, self).fini()
        return

    def wasInLobby(self):
        return self.__wasInLobby

    def onLobbyInited(self, event):
        super(BattleRoyaleController, self).onLobbyInited(event)
        if not self.__clientValuesInited:
            self.__clientValuesInited = True
        g_clientUpdateManager.addCallbacks(
            {'battleRoyale': self.__updateRoyale})
        self.startNotification()
        self.startGlobalListening()
        self.__hangarsSpace.onSpaceChangedByAction += self.__onSpaceChanged
        self.__hangarsSpace.onSpaceChanged += self.__onSpaceChanged
        self.__hangarsSpace.onVehicleChanged += self.__onVehicleChanged
        self.__c11nService.onVisibilityChanged += self.__onC11nVisibilityChanged
        self.__notificationsCtrl.onEventNotificationsChanged += self.__onEventNotification
        self.__onEventNotification(
            self.__notificationsCtrl.getEventsNotifications())
        self.__battleRoyaleTournamentController.onSelectBattleRoyaleTournament += self.__selectBattleRoyaleTournament
        self.__updateMode()
        self.__wasInLobby = True
        if not self.__hangarsSpace.spaceInited or self.__hangarsSpace.spaceLoading(
        ):
            self.__hangarsSpace.onSpaceCreate += self.__onSpaceCreate
        else:
            self.__updateSpace()
        nextTick(self.__eventAvailabilityUpdate)()

    def __onEventNotification(self, added, removed=()):
        for evNotification in removed:
            if evNotification.eventType in (SERVER_CMD_CHANGE_HANGAR,
                                            SERVER_CMD_CHANGE_HANGAR_PREM):
                self.__defaultHangars[evNotification.eventType ==
                                      SERVER_CMD_CHANGE_HANGAR_PREM] = None

        for evNotification in added:
            if evNotification.eventType in (SERVER_CMD_CHANGE_HANGAR,
                                            SERVER_CMD_CHANGE_HANGAR_PREM):
                try:
                    data = json.loads(evNotification.data)
                    path = data['hangar']
                except Exception:
                    path = evNotification.data

                self.__defaultHangars[evNotification.eventType ==
                                      SERVER_CMD_CHANGE_HANGAR_PREM] = path

        return

    def onDisconnected(self):
        self.__wasInLobby = False
        self.__clearClientValues()
        self.__clear()
        super(BattleRoyaleController, self).onDisconnected()

    def onAccountBecomePlayer(self):
        self.__onServerSettingsChanged(self.__lobbyContext.getServerSettings())
        super(BattleRoyaleController, self).onAccountBecomePlayer()

    def onAvatarBecomePlayer(self):
        self.__clear()
        if self.__sessionProvider.arenaVisitor.getArenaBonusType(
        ) in ARENA_BONUS_TYPE.BATTLE_ROYALE_RANGE:
            self.__voControl.activate()
        else:
            self.__voControl.deactivate()
        self.__voControl.onAvatarBecomePlayer()
        super(BattleRoyaleController, self).onAvatarBecomePlayer()

    def getModeSettings(self):
        return self.__lobbyContext.getServerSettings().battleRoyale

    def isEnabled(self):
        return self.getModeSettings().isEnabled

    def getEndTime(self):
        return self.getCurrentSeason().getCycleEndDate()

    def getPerformanceGroup(self):
        if not self.__performanceGroup:
            self.__analyzeClientSystem()
            _logger.debug('Current performance group %s',
                          self.__performanceGroup)
        return self.__performanceGroup

    def getDefaultAmmoCount(self, itemKey, intCD=None, vehicleName=None):
        if itemKey in AmmoTypes.SHELLS or itemKey in AmmoTypes.CHARGES:
            return self.__equipmentCount.get(itemKey, 0)
        else:
            if itemKey == AmmoTypes.ITEM:
                if intCD is None:
                    _logger.error(
                        'Cannot get count of equipment. Equipment id not specified'
                    )
                    return 0
                if vehicleName is None:
                    _logger.error(
                        "Cannot get count of '%r' equipment. Vehicle not specified",
                        intCD)
                    return 0
                vehiclesSlotsConfig = self.getModeSettings(
                ).vehiclesSlotsConfig
                if vehicleName not in vehiclesSlotsConfig:
                    _logger.error(
                        "Cannot get count of '%r' equipment. Vehicle '%r' not found",
                        intCD, vehicleName)
                    return 0
                for chargeId, equipmentId in vehiclesSlotsConfig[
                        vehicleName].iteritems():
                    if equipmentId == intCD:
                        return self.getDefaultAmmoCount(chargeId)

            else:
                _logger.warning(
                    "Can't get default ammo count. Unknown item key: '%r'.",
                    itemKey)
            return 0

    def getVehicleSlots(self):
        return self.__equipmentSlots

    def getBrVehicleEquipmentIds(self, vehicleName):
        vehiclesSlotsConfig = self.getModeSettings().vehiclesSlotsConfig
        if vehicleName not in vehiclesSlotsConfig:
            _logger.error(
                "Get equipment for vehicle '%r' failed. Vehicle not found. Slots config %s",
                vehicleName, vehiclesSlotsConfig)
            return None
        else:
            vehiclesSlots = vehiclesSlotsConfig[vehicleName]
            result = []
            for chargeName in sorted(vehiclesSlots.keys()):
                result.append(vehiclesSlots[chargeName])

            return result

    @staticmethod
    def getBrCommanderSkills():
        result = []
        if g_currentVehicle.isPresent():
            vehicle = g_currentVehicle.item
            for _, tankman in vehicle.crew:
                if tankman is not None:
                    for skill in tankman.skills:
                        result.append(skill)

        return result

    def isActive(self):
        _, isCycleActive = self.getCurrentCycleInfo()
        return self.isEnabled() and self.getCurrentSeason(
        ) is not None and isCycleActive

    def isBattleRoyaleMode(self):
        if self.prbDispatcher is None:
            return False
        else:
            state = self.prbDispatcher.getFunctionalState()
            return self.__isBattleRoyaleMode(
                state) or self.__isBattleRoyaleTournamentMode(state)

    def __isBattleRoyaleMode(self, state):
        return state.isInPreQueue(
            queueType=QUEUE_TYPE.BATTLE_ROYALE) or state.isInUnit(
                PREBATTLE_TYPE.BATTLE_ROYALE)

    def __isBattleRoyaleTournamentMode(self, state):
        return state.isInPreQueue(
            queueType=QUEUE_TYPE.BATTLE_ROYALE_TOURNAMENT) or state.isInUnit(
                PREBATTLE_TYPE.BATTLE_ROYALE_TOURNAMENT)

    def isBattlePassAvailable(self, bonusType):
        battlePassConfig = self.__lobbyContext.getServerSettings(
        ).getBattlePassConfig()
        return battlePassConfig.isEnabled(
        ) and battlePassConfig.isGameModeEnabled(bonusType)

    def isInBattleRoyaleSquad(self):
        dispatcher = self.prbDispatcher
        if dispatcher is not None:
            state = dispatcher.getFunctionalState()
            return state.isInUnit(PREBATTLE_TYPE.BATTLE_ROYALE)
        else:
            return False

    def onPrbEntitySwitched(self):
        self.__updateMode()
        self.__updateSpace()

    def selectRoyaleBattle(self):
        if not self.isEnabled():
            return
        self.__selectRoyaleBattle()

    def setDefaultHangarEntryPoint(self):
        if self.__battleRoyaleTournamentController.isSelected():
            self.__battleRoyaleTournamentController.leaveBattleRoyaleTournament(
                isChangingToBattleRoyaleHangar=True)

    def isGeneralHangarEntryPoint(self):
        return not self.__battleRoyaleTournamentController.isSelected()

    def selectRandomBattle(self):
        dispatcher = g_prbLoader.getDispatcher()
        if dispatcher is None:
            _logger.error('Prebattle dispatcher is not defined')
            return
        else:
            self.__doSelectRandomPrb(dispatcher)
            return

    def getPlayerLevelInfo(self):
        return self.__itemsCache.items.battleRoyale.accTitle

    def getStats(self):
        return self.__itemsCache.items.battleRoyale

    @process
    def openURL(self, url=None):
        requestUrl = url or self.__battleRoyaleSettings.url
        if requestUrl:
            parsedUrl = yield self.__urlMacros.parse(requestUrl)
            if parsedUrl:
                self.__showBrowserView(parsedUrl)

    def getQuests(self):
        _, isCycleActive = self.getCurrentCycleInfo()
        return {
            k: v
            for k, v in self.__eventsCache.getQuests().items()
            if v.getGroupID() == BATTLE_ROYALE_GROUPS_ID
            and self.__tokenIsValid(v)
        } if self.isGeneralHangarEntryPoint() and isCycleActive else {}

    def isDailyQuestsRefreshAvailable(self):
        if self.hasPrimeTimesLeftForCurrentCycle():
            return True
        serversPeriodsMapping = self.getPrimeTimesForDay(
            time_utils.getCurrentLocalServerTimestamp())
        periods = []
        for _, dayPeriods in serversPeriodsMapping.items():
            periods.append(max([periodEnd for _, periodEnd in dayPeriods]))

        if periods:
            periodTimeLeft = max(
                periods) - time_utils.getCurrentLocalServerTimestamp()
            return periodTimeLeft > time_utils.getDayTimeLeft()
        return False

    def __selectRoyaleBattle(self):
        dispatcher = g_prbLoader.getDispatcher()
        if dispatcher is None:
            _logger.error('Prebattle dispatcher is not defined')
            return
        else:
            self.__doSelectBattleRoyalePrb(dispatcher)
            return

    def __selectBattleRoyaleTournament(self):
        dispatcher = g_prbLoader.getDispatcher()
        if dispatcher is None:
            _logger.error('Prebattle dispatcher is not defined')
            return
        else:
            self.__doSelectBattleRoyaleTournamentPrb(dispatcher)
            return

    def __showBrowserView(self, url):
        webHandlers = createBattleRoyaleWebHanlders()
        alias = VIEW_ALIAS.BROWSER_VIEW
        g_eventBus.handleEvent(
            events.LoadViewEvent(SFViewLoadParams(alias,
                                                  getUniqueViewName(alias)),
                                 ctx={
                                     'url':
                                     url,
                                     'webHandlers':
                                     webHandlers,
                                     'returnAlias':
                                     VIEW_ALIAS.LOBBY_HANGAR,
                                     'onServerSettingsChange':
                                     self.__serverSettingsChangeBrowserHandler
                                 }), EVENT_BUS_SCOPE.LOBBY)

    def __serverSettingsChangeBrowserHandler(self, browser, diff):
        if not diff.get(Configs.BATTLE_ROYALE_CONFIG.value,
                        {}).get('isEnabled'):
            browser.onCloseView()

    def _createSeason(self, cycleInfo, seasonData):
        return BattleRoyaleSeason(cycleInfo, seasonData)

    def __onSpaceChanged(self):
        switchItems = self.__hangarSpacesSwitcher.itemsToSwitch
        if self.isBattleRoyaleMode(
        ) and self.__hangarSpacesSwitcher.currentItem != switchItems.BATTLE_ROYALE:
            self.selectRandomBattle()

    def __eventAvailabilityUpdate(self, *_):
        if g_prbLoader.getDispatcher() is None:
            return
        elif self.__battleRoyaleTournamentController.isSelected():
            return
        else:
            battleRoyaleEnabled = self.isEnabled() and self.getCurrentSeason(
            ) is not None
            isSelectRandom = not battleRoyaleEnabled and self.isBattleRoyaleMode(
            )
            if battleRoyaleEnabled and not self.isActive():
                currTime = time_utils.getCurrentLocalServerTimestamp()
                cycle = self.getCurrentSeason().getNextByTimeCycle(currTime)
                isSelectRandom = cycle is None
            if isSelectRandom:
                self.selectRandomBattle()
            return

    def __onSpaceCreate(self):
        nextTick(self.__updateSpace)()

    def __updateSpace(self):
        if not self.__c11nVisible and self.__hangarsSpace.spaceInited and not self.__hangarsSpace.spaceLoading(
        ):
            switchItems = self.__hangarSpacesSwitcher.itemsToSwitch
            isBrSpace = self.__hangarSpacesSwitcher.currentItem == switchItems.BATTLE_ROYALE
            isBrMode = self.isBattleRoyaleMode()
            if isBrMode and not isBrSpace:
                g_eventBus.handleEvent(events.HangarSpacesSwitcherEvent(
                    events.HangarSpacesSwitcherEvent.SWITCH_TO_HANGAR_SPACE,
                    ctx={'switchItemName': switchItems.BATTLE_ROYALE}),
                                       scope=EVENT_BUS_SCOPE.LOBBY)
                self.__isNeedToUpdateHeroTank = True
            elif not isBrMode and isBrSpace:
                defaultHangarPath = self.__defaultHangars.get(
                    self.__hangarsSpace.isPremium)
                if defaultHangarPath is not None:
                    self.__hangarSpaceReloader.changeHangarSpace(
                        defaultHangarPath)
                else:
                    g_eventBus.handleEvent(events.HangarSpacesSwitcherEvent(
                        events.HangarSpacesSwitcherEvent.
                        SWITCH_TO_HANGAR_SPACE,
                        ctx={'switchItemName': switchItems.DEFAULT}),
                                           scope=EVENT_BUS_SCOPE.LOBBY)
            self.onSpaceUpdated()
        return

    def __updateMode(self):
        if self.isBattleRoyaleMode():
            self.__enableRoyaleMode()
        elif not self.__bootcamp.isInBootcamp():
            self.__disableRoyaleMode()

    def __enableRoyaleMode(self):
        royaleVehicleID = AccountSettings.getFavorites(ROYALE_VEHICLE)
        if not royaleVehicleID or self.__itemsCache.items.getVehicle(
                royaleVehicleID) is None:
            criteria = REQ_CRITERIA.VEHICLE.HAS_TAGS(
                [VEHICLE_TAGS.BATTLE_ROYALE]) | REQ_CRITERIA.INVENTORY
            vehicles = self.__itemsCache.items.getVehicles
            royaleVehicle = first(
                sorted(vehicles(criteria=criteria).values(),
                       key=lambda item: item.intCD))
            if royaleVehicle:
                royaleVehicleID = royaleVehicle.invID
        if self.__c11nVisible:
            pass
        elif royaleVehicleID:
            g_currentVehicle.selectVehicle(royaleVehicleID)
        else:
            g_currentVehicle.selectNoVehicle()
        self.__voControl.activate()
        return

    def __disableRoyaleMode(self):
        storedVehInvID = AccountSettings.getFavorites(CURRENT_VEHICLE)
        if not storedVehInvID:
            criteria = REQ_CRITERIA.INVENTORY | ~REQ_CRITERIA.VEHICLE.HAS_TAGS(
                [VEHICLE_TAGS.BATTLE_ROYALE])
            vehicle = first(
                self.__itemsCache.items.getVehicles(
                    criteria=criteria).values())
            if vehicle:
                storedVehInvID = vehicle.invID
        if storedVehInvID:
            g_currentVehicle.selectVehicle(storedVehInvID)
        else:
            g_currentVehicle.selectNoVehicle()
        self.__voControl.deactivate()

    @process
    def __doSelectBattleRoyaleTournamentPrb(self, dispatcher):
        yield dispatcher.doSelectAction(
            PrbAction(PREBATTLE_ACTION_NAME.BATTLE_ROYALE_TOURNAMENT))

    @process
    def __doSelectBattleRoyalePrb(self, dispatcher):
        yield dispatcher.doSelectAction(
            PrbAction(PREBATTLE_ACTION_NAME.BATTLE_ROYALE))

    @process
    def __doSelectRandomPrb(self, dispatcher):
        yield dispatcher.doSelectAction(PrbAction(
            PREBATTLE_ACTION_NAME.RANDOM))

    @process
    def fightClick(self):
        dispatcher = g_prbLoader.getDispatcher()
        if not dispatcher:
            return
        lobbyContext = dependency.instance(ILobbyContext)
        navigationPossible = yield lobbyContext.isHeaderNavigationPossible()
        fightButtonPressPossible = yield lobbyContext.isFightButtonPressPossible(
        )
        if navigationPossible and fightButtonPressPossible:
            if dispatcher:
                dispatcher.doAction(
                    PrbAction(PREBATTLE_ACTION_NAME.BATTLE_ROYALE))
            else:
                _logger.error('Prebattle dispatcher is not defined')

    @process
    def _doLeaveBattleRoyalePrb(self, dispatcher):
        if dispatcher is None:
            return
        else:
            yield dispatcher.doLeaveAction(LeavePrbAction())
            return

    def __getBattleRoyaleSettings(self):
        generalSettings = self.__serverSettings.battleRoyale
        cycleID = None
        now = time_utils.getCurrentLocalServerTimestamp()
        _, cycleInfo = season_common.getSeason(generalSettings.asDict(), now)
        if cycleInfo:
            _, _, _, cycleID = cycleInfo
        for season in generalSettings.seasons.values():
            if cycleID in season.get('cycles', {}):
                return generalSettings.replace(season).replace(
                    season['cycles'][cycleID])

        return generalSettings

    def __getCachedSettings(self):
        return self.__battleRoyaleSettings

    def __timerUpdate(self):
        status, _, _ = self.getPrimeTimeStatus()
        self.onPrimeTimeStatusUpdated(status)
        self.__eventAvailabilityUpdate()

    def __resetTimer(self):
        self.startNotification()
        self.__timerUpdate()

    def __onServerSettingsChanged(self, serverSettings):
        if self.__serverSettings is not None:
            self.__serverSettings.onServerSettingsChange -= self.__updateRoyaleSettings
        self.__serverSettings = serverSettings
        self.__battleRoyaleSettings = self.__getBattleRoyaleSettings()
        self.__updateEquipmentCount()
        self.__serverSettings.onServerSettingsChange += self.__updateRoyaleSettings
        return

    def __updateRoyaleSettings(self, diff):
        if Configs.BATTLE_ROYALE_CONFIG.value not in diff:
            return
        else:
            self.__eventAvailabilityUpdate()
            self.__battleRoyaleSettings = self.__getBattleRoyaleSettings()
            self.__updateEquipmentCount()
            self.__divisions = None
            self.onUpdated()
            self.__resetTimer()
            return

    def __clear(self):
        self.stopNotification()
        self.stopGlobalListening()
        self.__hangarsSpace.onSpaceChangedByAction -= self.__onSpaceChanged
        self.__hangarsSpace.onSpaceChanged -= self.__onSpaceChanged
        self.__hangarsSpace.onSpaceCreate -= self.__onSpaceCreate
        self.__hangarsSpace.onVehicleChanged -= self.__onVehicleChanged
        self.__notificationsCtrl.onEventNotificationsChanged -= self.__onEventNotification
        self.__c11nService.onVisibilityChanged -= self.__onC11nVisibilityChanged
        self.__battleRoyaleTournamentController.onSelectBattleRoyaleTournament -= self.__selectBattleRoyaleTournament
        self.__defaultHangars = {}
        g_clientUpdateManager.removeObjectCallbacks(self)

    def __clearClientValues(self):
        if self.__serverSettings is not None:
            self.__serverSettings.onServerSettingsChange -= self.__updateRoyaleSettings
        self.__serverSettings = None
        self.__clientValuesInited = False
        return

    def __updateRoyale(self, _):
        self.onUpdated()
        self.__resetTimer()

    def __analyzeClientSystem(self):
        stats = BigWorld.wg_getClientStatistics()
        stats['graphicsEngine'] = self.__settingsCore.getSetting(
            GRAPHICS.RENDER_PIPELINE)
        self.__performanceGroup = BattleRoyalePerfProblems.LOW_RISK
        for groupName, conditions in PERFORMANCE_GROUP_LIMITS.iteritems():
            for currentLimit in conditions:
                condValid = True
                systemStats = currentLimit.get(
                    BATTLE_ROYALE_GAME_LIMIT_TYPE.SYSTEM_DATA, {})
                for key, limit in systemStats.iteritems():
                    currValue = stats.get(key, None)
                    if currValue is None or currValue != limit:
                        condValid = False

                hardwareParams = currentLimit.get(
                    BATTLE_ROYALE_GAME_LIMIT_TYPE.HARDWARE_PARAMS, {})
                for key, limit in hardwareParams.iteritems():
                    currValue = BigWorld.getAutoDetectGraphicsSettingsScore(
                        key)
                    if currValue >= limit:
                        condValid = False

                if condValid:
                    self.__performanceGroup = groupName
                    return

        return

    def __updateEquipmentCount(self):
        if self.__equipmentCount:
            self.__equipmentCount = None
        self.__equipmentCount = {}
        items = self.__battleRoyaleSettings.defaultAmmo
        for itemGroup in items:
            groupKey, groupItems = itemGroup
            self.__equipmentCount[groupKey] = groupItems[0]

        return

    def __onC11nVisibilityChanged(self, isVisible):
        self.__c11nVisible = isVisible
        self.__updateSpace()

    def __onVehicleChanged(self):
        if self.__isNeedToUpdateHeroTank:
            self.__hangarsSpace.onHeroTankReady()
            self.__isNeedToUpdateHeroTank = False

    def __tokenIsValid(self, quest):
        tokens = quest.accountReqs.getTokens()
        return False if tokens and not tokens[0].isAvailable() else True
Example #30
0
class ProgressiveItemsView(ViewImpl):
    __slots__ = ('__c11nView', '_itemsProgressData', '_possibleItems',
                 '_vehicle', '__blur', '__layoutID', '__urlMacros',
                 '__guiSettings')
    __lobbyContext = dependency.descriptor(ILobbyContext)
    __itemsCache = dependency.descriptor(IItemsCache)
    __customizationService = dependency.descriptor(ICustomizationService)
    __appLoader = dependency.descriptor(IAppLoader)
    __settingsCore = dependency.descriptor(ISettingsCore)

    def __init__(self, layoutID, c11nView, *args, **kwargs):
        settings = ViewSettings(layoutID)
        settings.args = args
        settings.kwargs = kwargs
        settings.flags = ViewFlags.LOBBY_TOP_SUB_VIEW
        settings.model = ProgressiveItemsViewModel()
        super(ProgressiveItemsView, self).__init__(settings)
        self._itemsProgressData = None
        self._possibleItems = None
        self._vehicle = None
        self.__blur = CachedBlur()
        self.__layoutID = layoutID
        self.__c11nView = c11nView
        self.__urlMacros = URLMacros()
        self.__guiSettings = GUI_SETTINGS.progressiveItems.get(
            'tutorialVideo', {})
        return

    def createToolTip(self, event):
        if event.contentID == R.views.common.tooltip_window.backport_tooltip_content.BackportTooltipContent(
        ):
            intCD = int(event.getArgument('id'))
            level = int(event.getArgument('level'))
            window = BackportTooltipWindow(
                self.__getTooltipData(intCD, event.getArgument('tooltip'),
                                      level), self.getParentWindow())
            window.load()
            return window
        return super(ProgressiveItemsView, self).createToolTip(event)

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

    def _initialize(self, *args, **kwargs):
        super(ProgressiveItemsView, self)._initialize(*args, **kwargs)
        if self.__c11nView is not None:
            self.__c11nView.changeVisible(False)
        self.viewModel.onSelectItem += self._onSelectItem
        self.viewModel.tutorial.showVideo += self._showVideoPage
        return

    def _finalize(self):
        super(ProgressiveItemsView, self)._finalize()
        if self.__c11nView is not None:
            self.__c11nView.changeVisible(True)
            self.__c11nView = None
        self.__blur.fini()
        self.viewModel.onSelectItem -= self._onSelectItem
        self.viewModel.tutorial.showVideo -= self._showVideoPage
        return

    def _onLoading(self, *args, **kwargs):
        self._vehicle = g_currentVehicle.item
        self._possibleItems = self._getPossibleItemsForVehicle()
        self._itemsProgressData = self.__itemsCache.items.inventory.getC11nProgressionDataForVehicle(
            self._vehicle.intCD)
        itemIntCD = kwargs.get('itemIntCD')
        with self.getViewModel().transaction() as model:
            model.setTankName(self._vehicle.userName)
            model.setTankLevel(int2roman(self._vehicle.level))
            model.setTankType(self._vehicle.typeBigIconResource())
            self.__setItems(model)
            model.setIsRendererPipelineDeferred(isRendererPipelineDeferred())
            model.setItemToScroll(0 if itemIntCD is None else itemIntCD)
        return

    def _onLoaded(self, *args, **kwargs):
        self.__blur.enable()
        self.__settingsCore.serverSettings.setOnceOnlyHintsSettings(
            {OnceOnlyHints.C11N_PROGRESSION_VIEW_HINT: HINT_SHOWN_STATUS})

    def _onSelectItem(self, args=None):
        if args is not None:
            intCD = int(args['intCD'])
            level = int(args['level'])
            item = self.__customizationService.getItemByCD(intCD)
            ctx = self.__customizationService.getCtx()

            def changeTabAndGetItemToHand():
                ctx.changeModeWithProgressionDecal(intCD)
                ctx.events.onGetItemBackToHand(item, level, scrollToItem=True)
                noveltyCount = self._vehicle.getC11nItemNoveltyCounter(
                    proxy=self.__itemsCache.items, item=item)
                if noveltyCount:
                    BigWorld.callback(
                        0.0, lambda: ctx.resetItemsNovelty([item.intCD]))

            BigWorld.callback(0.0, changeTabAndGetItemToHand)
        self.destroyWindow()
        return

    def _showVideoPage(self, args=None):
        self.__showVideo()

    @process
    def __showVideo(self):
        url = yield self.__urlMacros.parse(self.__guiSettings.get('url'))
        webHandlers = webApiCollection(ui_web_api.CloseViewWebApi,
                                       sound_web_api.SoundWebApi,
                                       sound_web_api.HangarSoundWebApi)
        ctx = {'url': url, 'webHandlers': webHandlers}
        showProgressiveItemsBrowserView(ctx)

    def _getPossibleItemsForVehicle(self):
        customizationCache = vehicles.g_cache.customization20()
        vehicleType = self._vehicle.descriptor.type
        sortedItems = sorted(
            customizationCache.customizationWithProgression.itervalues(),
            key=lambda i: i.id)
        return [
            item.compactDescr for item in sortedItems
            if item.filter.matchVehicleType(vehicleType)
        ]

    def __setItems(self, model):
        for intCD in self._possibleItems:
            itemModel = ItemModel()
            item = self.__customizationService.getItemByCD(intCD)
            itemModel.setItemId(intCD)
            itemModel.setItemUserString(item.userName)
            itemModel.setMaxLevel(item.getMaxProgressionLevel())
            itemModel.setScaleFactor(item.formfactor)
            latestOpenedLevel = item.getLatestOpenedProgressionLevel(
                self._vehicle)
            itemModel.setCurrentLevel(1 if latestOpenedLevel ==
                                      -1 else latestOpenedLevel + 1)
            self.__setEachLevelInfo(itemModel, item)
            model.progressiveItems.addViewModel(itemModel)

    def __setEachLevelInfo(self, model, item):
        for level in xrange(1, model.getMaxLevel() + 1):
            levelInfo = ItemLevelInfoModel()
            levelInfo.setLevel(level)
            levelInfo.setLevelText(getProgressionItemStatusText(level))
            levelInfo.setUnlocked(level < model.getCurrentLevel())
            icon = item.iconUrlByProgressionLevel(
                level, _PREVIEW_ICON_SIZE,
                _PREVIEW_ICON_INNER_SIZE.get(item.formfactor))
            levelInfo.setIcon(icon)
            if level == model.getCurrentLevel():
                levelInfo.setInProgress(True)
                levelInfo.progressBlock.setUnlockCondition(
                    _ms(
                        item.progressionConditions.get(level, {})[0].get(
                            'description', '')))
                currProgress = int(
                    item.getCurrentProgressOnCurrentLevel(self._vehicle))
                currProgress = currProgress if currProgress > 0 else 0
                maxProgress = int(
                    item.progressionConditions.get(level,
                                                   {})[0].get('value', '1'))
                if maxProgress > 1:
                    levelInfo.progressBlock.setProgressionVal(currProgress)
                    levelInfo.progressBlock.setMaxProgressionVal(maxProgress)
                else:
                    levelInfo.progressBlock.setHideProgressBarAndString(True)
            model.eachLevelInfo.addViewModel(levelInfo)

    @staticmethod
    def __getTooltipData(intCD, tooltip, level):
        return createTooltipData(isSpecial=True,
                                 specialAlias=tooltip,
                                 specialArgs=CustomizationTooltipContext(
                                     itemCD=intCD,
                                     level=level,
                                     showOnlyProgressBlock=True))