class SocialWebApi(object):
    lobbyContext = dependency.descriptor(ILobbyContext)

    def __init__(self):
        super(SocialWebApi, self).__init__()
        self.__usersInfoHelper = UsersInfoHelper()

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

    @w2c(W2CSchema, name='friends_status')
    def friendsStatus(self, cmd):
        storage = self.usersStorage
        friends = storage.getList(MutualFriendsFindCriteria())
        return {
            'action': 'friends_status',
            'friends_status': getStatuses(friends)
        }

    @w2c(_PlayerStatusSchema, name='player_status')
    def isPlayerOnline(self, cmd, ctx):
        callback = ctx.get('callback')
        playerId = cmd.player_id

        def isAvailable():
            player = self.__usersInfoHelper.getContact(playerId)
            return {
                'is_online': player.isOnline() if player is not None else False
            }

        def onNamesReceivedCallback():
            callback(isAvailable())
            self.__usersInfoHelper.onNamesReceived -= onNamesReceivedCallback

        if not bool(self.__usersInfoHelper.getUserName(playerId)):
            self.__usersInfoHelper.onNamesReceived += onNamesReceivedCallback
            self.__usersInfoHelper.syncUsersInfo()
        else:
            return isAvailable()

    @w2c(W2CSchema, name='get_player_info')
    def getPlayerInfo(self, _):
        if not isPlayerAccount():
            return {}
        name = BigWorld.player().name
        clanInfo = g_clanCache.clanInfo
        if clanInfo and len(clanInfo) > 1:
            clanAbbrev = clanInfo[1]
        else:
            clanAbbrev = ''
        return {
            'fullName':
            self.lobbyContext.getPlayerFullName(name, clanInfo=clanInfo),
            'userName':
            name,
            'clanAbbrev':
            clanAbbrev
        }
Exemplo n.º 2
0
 def __init__(self):
     super(PostmortemPanel, self).__init__()
     self.__playerInfo = None
     self._isPlayerVehicle = False
     self.__maxHealth = 0
     self.__healthPercent = 0
     self.__isInPostmortem = False
     self._deathAlreadySet = False
     self.__isColorBlind = self.settingsCore.getSetting('isColorBlind')
     self.__userInfoHelper = UsersInfoHelper()
     return
class SocialWebApi(object):
    def __init__(self):
        super(SocialWebApi, self).__init__()
        self.__usersInfoHelper = UsersInfoHelper()

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

    @w2c(W2CSchema, name='friends_status')
    def friendsStatus(self, cmd):
        storage = self.usersStorage
        friends = storage.getList(MutualFriendsFindCriteria())
        return {
            'action': 'friends_status',
            'friends_status': getStatuses(friends)
        }

    @w2c(_PlayerStatusSchema, name='player_status')
    def isPlayerOnline(self, cmd, ctx):
        callback = ctx.get('callback')
        playerId = cmd.player_id

        def isAvailable():
            player = self.__usersInfoHelper.getContact(playerId)
            return {
                'is_online': player.isOnline() if player is not None else False
            }

        def onNamesReceivedCallback():
            callback(isAvailable())
            self.__usersInfoHelper.onNamesReceived -= onNamesReceivedCallback

        if not bool(self.__usersInfoHelper.getUserName(playerId)):
            self.__usersInfoHelper.onNamesReceived += onNamesReceivedCallback
            self.__usersInfoHelper.syncUsersInfo()
        else:
            return isAvailable()
 def __init__(self):
     super(SocialWebApi, self).__init__()
     self.__usersInfoHelper = UsersInfoHelper()
Exemplo n.º 5
0
class PostmortemPanel(_SummaryPostmortemPanel):
    __slots__ = ('__playerInfo', '_isPlayerVehicle', '__maxHealth',
                 '__healthPercent', '__isInPostmortem', '_deathAlreadySet',
                 '__isColorBlind')

    def __init__(self):
        super(PostmortemPanel, self).__init__()
        self.__playerInfo = None
        self._isPlayerVehicle = False
        self.__maxHealth = 0
        self.__healthPercent = 0
        self.__isInPostmortem = False
        self._deathAlreadySet = False
        self.__isColorBlind = self.settingsCore.getSetting('isColorBlind')
        self.__userInfoHelper = UsersInfoHelper()
        self.__arenaInfo = BigWorld.player().arena.arenaInfo
        return

    def _populate(self):
        super(PostmortemPanel, self)._populate()
        if self._hasBonusCap(
                ARENA_BONUS_TYPE_CAPS.DOG_TAG) and self.__arenaInfo:
            defaultComponents = [
                pack_component(comp.componentId, 0) for comp in
                componentConfigAdapter.getDefaultDogTag().components
            ]
            self._preloadDTImages(defaultComponents, False)
            self._preloadDTImages(
                self.__arenaInfo.dogTagsInfo.usedDogTagsComponents)

    def _addGameListeners(self):
        super(PostmortemPanel, self)._addGameListeners()
        ctrl = self.sessionProvider.shared.vehicleState
        if ctrl is not None:
            ctrl.onVehicleStateUpdated += self.__onVehicleStateUpdated
            ctrl.onVehicleControlling += self.__onVehicleControlling
            ctrl.onPostMortemSwitched += self.__onPostMortemSwitched
            ctrl.onRespawnBaseMoving += self.__onRespawnBaseMoving
            self.__isInPostmortem = ctrl.isInPostmortem
            vehicle = ctrl.getControllingVehicle()
            if vehicle is not None:
                self.__setPlayerInfo(vehicle.id)
                self.__onVehicleControlling(vehicle)
        self.settingsCore.onSettingsChanged += self.__onSettingsChanged
        dogTagsCtrl = self.sessionProvider.dynamic.dogTags
        if dogTagsCtrl is not None:
            dogTagsCtrl.onKillerDogTagSet += self.__onKillerDogTagSet
            dogTagsCtrl.onVictimDogTagSet += self.__onVictimDogTagSet
            dogTagsCtrl.onKillerDogTagCheat += self.__onKillerDogCheat
        if self.__arenaInfo and self._hasBonusCap(
                ARENA_BONUS_TYPE_CAPS.DOG_TAG):
            self.__arenaInfo.dogTagsInfo.onUsedComponentsUpdated += self.__onUsedComponentsUpdated
        return

    def _removeGameListeners(self):
        ctrl = self.sessionProvider.shared.vehicleState
        if ctrl is not None:
            ctrl.onVehicleStateUpdated -= self.__onVehicleStateUpdated
            ctrl.onVehicleControlling -= self.__onVehicleControlling
            ctrl.onPostMortemSwitched -= self.__onPostMortemSwitched
            ctrl.onRespawnBaseMoving -= self.__onRespawnBaseMoving
        self.settingsCore.onSettingsChanged -= self.__onSettingsChanged
        super(PostmortemPanel, self)._removeGameListeners()
        dogTagsCtrl = self.sessionProvider.dynamic.dogTags
        if dogTagsCtrl is not None:
            dogTagsCtrl.onKillerDogTagSet -= self.__onKillerDogTagSet
            dogTagsCtrl.onVictimDogTagSet -= self.__onVictimDogTagSet
            dogTagsCtrl.onKillerDogTagCheat -= self.__onKillerDogCheat
        return

    def _deathInfoReceived(self):
        self._updateVehicleInfo()

    def _preloadDTImages(self, usedDogTagsComponents, skipSameTeam=True):
        componentImages = set()
        for componentPacked in usedDogTagsComponents:
            compId, grade, teamId = unpack_component(componentPacked)
            if skipSameTeam and teamId == BigWorld.player().team:
                continue
            viewType = componentConfigAdapter.getComponentById(compId).viewType
            componentImages.add('{}_{}_{}'.format(viewType.value.lower(),
                                                  compId, grade))

        if componentImages:
            _logger.debug('PostmortemPanel preloading %s',
                          str(componentImages))
            self.as_preloadComponentsS(list(componentImages))

    @staticmethod
    def _hasBonusCap(cap):
        return ARENA_BONUS_TYPE_CAPS.checkAny(BigWorld.player().arenaBonusType,
                                              cap)

    def __setHealthPercent(self, health):
        self.__healthPercent = normalizeHealthPercent(health, self.__maxHealth)

    def __setPlayerInfo(self, vehicleID):
        self.__playerInfo = self.sessionProvider.getCtx(
        ).getPlayerFullNameParts(vID=vehicleID, showVehShortName=True)

    def __onVehicleControlling(self, vehicle):
        self.__maxHealth = vehicle.maxHealth
        self._isPlayerVehicle = vehicle.isPlayerVehicle
        self.__setHealthPercent(vehicle.health)
        self._updateVehicleInfo()

    def __onVehicleStateUpdated(self, state, value):
        if state == VEHICLE_VIEW_STATE.HEALTH:
            if self.__maxHealth != 0 and self.__maxHealth > value:
                self.__setHealthPercent(value)
                self._updateVehicleInfo()
        elif state == VEHICLE_VIEW_STATE.PLAYER_INFO:
            self.__setPlayerInfo(value)
        elif state == VEHICLE_VIEW_STATE.SWITCHING:
            self.__maxHealth = 0
            self.__healthPercent = 0

    def __onPostMortemSwitched(self, noRespawnPossible, respawnAvailable):
        self.__isInPostmortem = True
        self._updateVehicleInfo()

    def __onRespawnBaseMoving(self):
        self.__isInPostmortem = False
        self.__deathAlreadySet = False
        self.resetDeathInfo()

    def _updateVehicleInfo(self):
        if not self.__isInPostmortem:
            return
        if self._isPlayerVehicle:
            self._showOwnDeathInfo()
        else:
            self._showPlayerInfo()

    def _showOwnDeathInfo(self):
        if self._deathAlreadySet:
            self.as_showDeadReasonS()
        else:
            deathInfo = self.getDeathInfo()
            if deathInfo:
                killerVehID = deathInfo['killerVehicle']
                battleCtx = self.sessionProvider.getCtx()
                if killerVehID and not battleCtx.isCurrentPlayer(
                        killerVehID) and battleCtx.getArenaDP().getVehicleInfo(
                            killerVehID).vehicleType.compactDescr:
                    showVehicle = True
                    vInfoVO = battleCtx.getArenaDP().getVehicleInfo(
                        killerVehID)
                    vTypeInfoVO = vInfoVO.vehicleType
                    vehImg = _VEHICLE_SMALL_ICON_RES_PATH.format(
                        vTypeInfoVO.iconName)
                    if not vTypeInfoVO.isOnlyForBattleRoyaleBattles:
                        vehLvl = int2roman(vTypeInfoVO.level)
                        vehClass = Vehicle.getTypeVPanelIconPath(
                            vTypeInfoVO.classTag)
                    else:
                        vehLvl = None
                        vehClass = None
                    vehName = vTypeInfoVO.shortNameWithPrefix
                    killerUserVO = self.__makeKillerVO(vInfoVO)
                else:
                    showVehicle = False
                    vehLvl = vehImg = vehClass = vehName = None
                    killerUserVO = {}
                reason = self.__makeReasonInfo(deathInfo)
                self.as_setDeadReasonInfoS(reason, showVehicle, vehLvl, vehImg,
                                           vehClass, vehName, killerUserVO)
                self._deathAlreadySet = True
            else:
                self.as_setDeadReasonInfoS('', False, None, None, None, None,
                                           None)
        return

    def __makeKillerVO(self, vInfoVO):
        fullName = self.sessionProvider.getCtx().getPlayerFullNameParts(
            vInfoVO.vehicleID, showVehShortName=False)
        playerVO = vInfoVO.player
        userVO = {
            'userName':
            fullName.playerName,
            'fakeName':
            fullName.playerFakeName,
            'clanAbbrev':
            playerVO.clanAbbrev,
            'region':
            fullName.regionCode,
            'igrType':
            playerVO.igrType,
            'tags':
            self.__userInfoHelper.getUserTags(playerVO.avatarSessionID,
                                              playerVO.igrType)
        }
        badgeID = vInfoVO.selectedBadge
        badge = buildBadge(badgeID, vInfoVO.getBadgeExtraInfo())
        if badge is not None:
            userVO['badgeVisualVO'] = badge.getBadgeVO(ICONS_SIZES.X24,
                                                       {'isAtlasSource': True},
                                                       shortIconName=True)
        return userVO

    def __makeReasonInfo(self, deathInfo):
        colors = deathInfo['colors']
        if self.__isColorBlind:
            color = colors[1]
        else:
            color = colors[0]
        names = {'device': '', 'entity': '', 'killer': '', 'color': color}
        device = deathInfo['device']
        if device:
            names['device'] = device
        reason = ''
        try:
            reason = deathInfo['text'] % names
        except TypeError:
            LOG_CURRENT_EXCEPTION()

        return reason

    def _showPlayerInfo(self):
        ctx = {
            'name': self.__playerInfo.playerFullName,
            'health': self.__healthPercent
        }
        template = 'other'
        msg = makeHtmlString('html_templates:battle/postmortemMessages',
                             template,
                             ctx=ctx)
        self.as_setPlayerInfoS(msg)

    def __onSettingsChanged(self, diff):
        if GRAPHICS.COLOR_BLIND in diff:
            self.__isColorBlind = diff[GRAPHICS.COLOR_BLIND]
            self._deathAlreadySet = False
            self._updateVehicleInfo()

    def onDogTagKillerInPlaySound(self):
        if not BattleReplay.isPlaying():
            WWISE.WW_eventGlobal(backport.sound(R.sounds.dt_pc_destroyed()))

    def onDogTagKillerOutPlaySound(self):
        if not BattleReplay.isPlaying():
            WWISE.WW_eventGlobal(
                backport.sound(R.sounds.dt_pc_destroyed_slide_out()))

    def onVictimDogTagInPlaySound(self):
        WWISE.WW_eventGlobal(backport.sound(R.sounds.dt_enemy()))

    @staticmethod
    def _buildDogTag(dogTag):
        return DisplayableDogTag(PlayerDogTag.fromDict(dogTag),
                                 dogTag['playerName'], dogTag['clanTag'])

    def __onKillerDogTagSet(self, dogTagInfo):
        dogTagModel = layoutComposer.getModel(
            self._buildDogTag(dogTagInfo['dogTag']))
        _logger.info(
            'PostmortemPanel.__onKillerDogTagSet: dogTagInfo %s, dogTagModel %s',
            str(dogTagInfo), str(dogTagModel))
        self.as_showKillerDogTagS(dogTagModel)

    def __onVictimDogTagSet(self, dogTagInfo):
        dogTagModel = layoutComposer.getModel(
            self._buildDogTag(dogTagInfo['dogTag']))
        _logger.info(
            'PostmortemPanel.__onVictimDogTagSet: dogTagInfo %s, dogTagModel %s',
            str(dogTagInfo), str(dogTagModel))
        self.as_showVictimDogTagS(dogTagModel)

    def __onKillerDogCheat(self, deadReasonInfo):
        self.as_setDeadReasonInfoS(*deadReasonInfo)

    def __onUsedComponentsUpdated(self, usedComponents):
        self._preloadDTImages(usedComponents)
Exemplo n.º 6
0
class PostmortemPanel(_SummaryPostmortemPanel):
    __slots__ = ('__playerInfo', '_isPlayerVehicle', '__maxHealth',
                 '__healthPercent', '__isInPostmortem', '_deathAlreadySet',
                 '__isColorBlind')

    def __init__(self):
        super(PostmortemPanel, self).__init__()
        self.__playerInfo = None
        self._isPlayerVehicle = False
        self.__maxHealth = 0
        self.__healthPercent = 0
        self.__isInPostmortem = False
        self._deathAlreadySet = False
        self.__isColorBlind = self.settingsCore.getSetting('isColorBlind')
        self.__userInfoHelper = UsersInfoHelper()
        return

    def _addGameListeners(self):
        super(PostmortemPanel, self)._addGameListeners()
        ctrl = self.sessionProvider.shared.vehicleState
        if ctrl is not None:
            ctrl.onVehicleStateUpdated += self.__onVehicleStateUpdated
            ctrl.onVehicleControlling += self.__onVehicleControlling
            ctrl.onPostMortemSwitched += self.__onPostMortemSwitched
            ctrl.onRespawnBaseMoving += self.__onRespawnBaseMoving
            self.__isInPostmortem = ctrl.isInPostmortem
            vehicle = ctrl.getControllingVehicle()
            if vehicle is not None:
                self.__setPlayerInfo(vehicle.id)
                self.__onVehicleControlling(vehicle)
        self.settingsCore.onSettingsChanged += self.__onSettingsChanged
        return

    def _removeGameListeners(self):
        ctrl = self.sessionProvider.shared.vehicleState
        if ctrl is not None:
            ctrl.onVehicleStateUpdated -= self.__onVehicleStateUpdated
            ctrl.onVehicleControlling -= self.__onVehicleControlling
            ctrl.onPostMortemSwitched -= self.__onPostMortemSwitched
            ctrl.onRespawnBaseMoving -= self.__onRespawnBaseMoving
        self.settingsCore.onSettingsChanged -= self.__onSettingsChanged
        super(PostmortemPanel, self)._removeGameListeners()
        return

    def _deathInfoReceived(self):
        self._updateVehicleInfo()

    def __setHealthPercent(self, health):
        self.__healthPercent = normalizeHealthPercent(health, self.__maxHealth)

    def __setPlayerInfo(self, vehicleID):
        self.__playerInfo = self.sessionProvider.getCtx(
        ).getPlayerFullNameParts(vID=vehicleID, showVehShortName=True)

    def __onVehicleControlling(self, vehicle):
        self.__maxHealth = vehicle.maxHealth
        self._isPlayerVehicle = vehicle.isPlayerVehicle
        self.__setHealthPercent(vehicle.health)
        self._updateVehicleInfo()

    def __onVehicleStateUpdated(self, state, value):
        if state == VEHICLE_VIEW_STATE.HEALTH:
            if self.__maxHealth != 0 and self.__maxHealth > value:
                self.__setHealthPercent(value)
                self._updateVehicleInfo()
        elif state == VEHICLE_VIEW_STATE.PLAYER_INFO:
            self.__setPlayerInfo(value)
        elif state == VEHICLE_VIEW_STATE.SWITCHING:
            self.__maxHealth = 0
            self.__healthPercent = 0

    def __onPostMortemSwitched(self, noRespawnPossible, respawnAvailable):
        self.__isInPostmortem = True
        self._updateVehicleInfo()

    def __onRespawnBaseMoving(self):
        self.__isInPostmortem = False
        self.__deathAlreadySet = False
        self.resetDeathInfo()

    def _updateVehicleInfo(self):
        if not self.__isInPostmortem:
            return
        if self._isPlayerVehicle:
            self._showOwnDeathInfo()
        else:
            self._showPlayerInfo()

    def _showOwnDeathInfo(self):
        if self._deathAlreadySet:
            self.as_showDeadReasonS()
        else:
            deathInfo = self.getDeathInfo()
            if deathInfo:
                killerVehID = deathInfo['killerVehicle']
                battleCtx = self.sessionProvider.getCtx()
                if killerVehID and not battleCtx.isCurrentPlayer(
                        killerVehID) and battleCtx.getArenaDP().getVehicleInfo(
                            killerVehID).vehicleType.compactDescr:
                    showVehicle = True
                    vInfoVO = battleCtx.getArenaDP().getVehicleInfo(
                        killerVehID)
                    vTypeInfoVO = vInfoVO.vehicleType
                    vehImg = _VEHICLE_SMALL_ICON_RES_PATH.format(
                        vTypeInfoVO.iconName)
                    if not vTypeInfoVO.isOnlyForBattleRoyaleBattles:
                        vehLvl = int2roman(vTypeInfoVO.level)
                        vehClass = Vehicle.getTypeBigIconPath(
                            vTypeInfoVO.classTag)
                    else:
                        vehLvl = None
                        vehClass = None
                    vehName = vTypeInfoVO.shortNameWithPrefix
                    killerUserVO = self.__makeKillerVO(vInfoVO)
                else:
                    showVehicle = False
                    vehLvl = vehImg = vehClass = vehName = None
                    killerUserVO = {}
                reason = self.__makeReasonInfo(deathInfo)
                self.as_setDeadReasonInfoS(reason, showVehicle, vehLvl, vehImg,
                                           vehClass, vehName, killerUserVO)
                self._deathAlreadySet = True
            else:
                self.as_setDeadReasonInfoS('', False, None, None, None, None,
                                           None)
        return

    def __makeKillerVO(self, vInfoVO):
        fullName = self.sessionProvider.getCtx().getPlayerFullNameParts(
            vInfoVO.vehicleID, showVehShortName=False)
        playerVO = vInfoVO.player
        userVO = {
            'userName':
            fullName.playerName,
            'fakeName':
            fullName.playerFakeName,
            'clanAbbrev':
            playerVO.clanAbbrev,
            'region':
            fullName.regionCode,
            'igrType':
            playerVO.igrType,
            'tags':
            self.__userInfoHelper.getUserTags(playerVO.avatarSessionID,
                                              playerVO.igrType)
        }
        badgeID = vInfoVO.selectedBadge
        badge = buildBadge(badgeID, vInfoVO.getBadgeExtraInfo())
        if badge is not None:
            userVO['badgeVisualVO'] = badge.getBadgeVO(ICONS_SIZES.X24,
                                                       {'isAtlasSource': True},
                                                       shortIconName=True)
        return userVO

    def __makeReasonInfo(self, deathInfo):
        colors = deathInfo['colors']
        if self.__isColorBlind:
            color = colors[1]
        else:
            color = colors[0]
        names = {'device': '', 'entity': '', 'killer': '', 'color': color}
        device = deathInfo['device']
        if device:
            names['device'] = device
        reason = ''
        try:
            reason = deathInfo['text'] % names
        except TypeError:
            LOG_CURRENT_EXCEPTION()

        return reason

    def _showPlayerInfo(self):
        ctx = {
            'name': self.__playerInfo.playerFullName,
            'health': self.__healthPercent
        }
        template = 'other'
        msg = makeHtmlString('html_templates:battle/postmortemMessages',
                             template,
                             ctx=ctx)
        self.as_setPlayerInfoS(msg)

    def __onSettingsChanged(self, diff):
        if GRAPHICS.COLOR_BLIND in diff:
            self.__isColorBlind = diff[GRAPHICS.COLOR_BLIND]
            self._deathAlreadySet = False
            self._updateVehicleInfo()
Exemplo n.º 7
0
 def __init__(self):
     super(UtilWebApiMixin, self).__init__()
     self.__usersInfoHelper = UsersInfoHelper()
Exemplo n.º 8
0
class UtilWebApiMixin(object):
    itemsCache = dependency.descriptor(IItemsCache)
    goodiesCache = dependency.descriptor(IGoodiesCache)
    _webCtrl = dependency.descriptor(IWebController)
    _lnkCtrl = dependency.descriptor(IExternalLinksController)

    def __init__(self):
        super(UtilWebApiMixin, self).__init__()
        self.__usersInfoHelper = UsersInfoHelper()

    @w2c(_SetCounterSchema, 'set_counter')
    def setCounterState(self, cmd):
        alias = _COUNTER_IDS_MAP.get(cmd.id)
        if alias is not None:
            g_eventBus.handleEvent(HasCtxEvent(eventType=HEADER_BUTTONS_COUNTERS_CHANGED_EVENT, ctx={'alias': alias,
             'value': cmd.value or ''}))
        return

    @w2c(_GetCountersSchema, 'get_counters')
    def getCountersInfo(self, cmd):
        ids = cmd.id_list or _COUNTER_IDS_MAP.keys()
        counters = AccountSettings.getCounters(NEW_LOBBY_TAB_COUNTER)
        return {id:counters.get(_COUNTER_IDS_MAP[id]) for id in ids if id in _COUNTER_IDS_MAP}

    @w2c(W2CSchema, 'blink_taskbar')
    def blinkTaskbar(self, _):
        showInvitationInWindowsBar()

    @w2c(_RunTriggerChainSchema, 'run_trigger_chain')
    def runTriggerChain(self, cmd):
        chainID = cmd.trigger_chain_id
        runSalesChain(chainID, reloadIfRun=True, isStopForced=True)

    @w2c(_ShowToolTipSchema, 'show_tooltip')
    def showTooltip(self, cmd):
        tooltipType = cmd.tooltipType
        itemId = cmd.itemId
        args = []
        withLongIntArgs = (TC.AWARD_SHELL,)
        withLongOnlyArgs = (TC.AWARD_VEHICLE,
         TC.AWARD_MODULE,
         TC.INVENTORY_BATTLE_BOOSTER,
         TC.BOOSTERS_BOOSTER_INFO,
         TC.BADGE,
         TC.TECH_CUSTOMIZATION_ITEM)
        if tooltipType in withLongIntArgs:
            args = [itemId, 0]
        elif tooltipType in withLongOnlyArgs:
            args = [itemId]
        elif tooltipType == TC.ACHIEVEMENT:
            dossier = self.itemsCache.items.getAccountDossier()
            dossierCompDescr = dumpDossier(self.itemsCache.items.getAccountDossier())
            achievement = dossier.getTotalStats().getAchievement((cmd.blockId, itemId))
            args = [dossier.getDossierType(),
             dossierCompDescr,
             achievement.getBlock(),
             cmd.itemId,
             isRareAchievement(achievement)]
        self.__getTooltipMgr().onCreateTypedTooltip(tooltipType, args, 'INFO')

    @w2c(_ShowItemTooltipSchema, 'show_item_tooltip')
    def showItemTooltip(self, cmd):
        itemType = cmd.type
        if itemType == ItemPackType.CREW_BOOK:
            itemId = makeIntCompactDescrByID('crewBook', CrewBookCacheType.CREW_BOOK, cmd.id)
        else:
            itemId = getCDFromId(itemType=cmd.type, itemId=cmd.id)
        rawItem = ItemPackEntry(type=itemType, id=itemId, count=cmd.count or 1, extra=cmd.extra or {})
        item = lookupItem(rawItem, self.itemsCache, self.goodiesCache)
        showItemTooltip(self.__getTooltipMgr(), rawItem, item)

    @w2c(_ShowAwardsTooltipSchema, 'show_awards_tooltip')
    def showAwardsTooltip(self, cmd):
        showAwardsTooltip(self.__getTooltipMgr(), cmd.type, cmd.data)

    @w2c(_ShowCustomTooltipSchema, 'show_custom_tooltip')
    def showCustomTooltip(self, cmd):
        self.__getTooltipMgr().onCreateComplexTooltip(makeTooltip(header=cmd.header, body=cmd.body), 'INFO')

    @w2c(_ShowSimpleTooltipSchema, 'show_simple_tooltip')
    def showSimpleTooltip(self, cmd):
        self.__getTooltipMgr().onCreateComplexTooltip(makeTooltip(body=cmd.body), 'INFO')

    @w2c(W2CSchema, 'hide_tooltip')
    def hideToolTip(self, _):
        self.__getTooltipMgr().hide()

    @w2c(W2CSchema, 'hide_window_tooltip')
    def hideWulfToolTip(self, _):
        self.__getTooltipMgr().onHideTooltip('')

    @w2c(_ShowAdditionalRewardsTooltipSchema, 'show_additional_rewards_tooltip')
    def showAdditionalRewardsTooltip(self, cmd):
        bonuses = []
        for key, value in cmd.rewards.iteritems():
            bonuses.extend(getNonQuestBonuses(key, value))

        self.__getTooltipMgr().onCreateWulfTooltip(TC.ADDITIONAL_REWARDS, [bonuses], cmd.x, cmd.y)

    @w2c(W2CSchema, 'server_timestamp')
    def getCurrentLocalServerTimestamp(self, _):
        return time_utils.getCurrentLocalServerTimestamp()

    @w2c(_PlatformProductListSchema, name='fetch_product_list')
    def handleFetchProductList(self, cmd):
        ctx = PlatformFetchProductListCtx(cmd)
        response = yield self._webCtrl.sendRequest(ctx=ctx)
        if response.isSuccess():
            yield {'result': response.getData()}
        else:
            yield {'error': self.__getErrorResponse(response.data, 'Unable to fetch product list.')}

    @w2c(_AccountAttribute, name='get_account_attribute_by_prefix')
    def handleGetAccountAttributeByPrefix(self, cmd):
        ctx = SPAAccountAttributeCtx(cmd)
        response = yield self._webCtrl.sendRequest(ctx=ctx)
        if response.isSuccess():
            yield {'result': response.getData()}
        else:
            yield {'error': self.__getErrorResponse(response.data, 'Unable to obtain account attrs.')}

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

    @w2c(_ChatAvailabilitySchema, 'check_if_chat_available')
    def checkIfChatAvailable(self, cmd, ctx):
        callback = ctx.get('callback')
        receiverId = cmd.receiver_id

        def isAvailable():
            receiver = self.__usersInfoHelper.getContact(receiverId)
            return receiver.hasValidName() and not receiver.isIgnored()

        def onNamesReceivedCallback():
            callback(isAvailable())

        if not bool(self.__usersInfoHelper.getUserName(receiverId)):
            self.__usersInfoHelper.onNamesReceived += onNamesReceivedCallback
            self.__usersInfoHelper.syncUsersInfo()
        else:
            return isAvailable()

    @w2c(_VehicleCustomizationPreviewSchema, 'can_install_style')
    def canStyleBeInstalled(self, cmd):
        result = canInstallStyle(cmd.style_id)
        return {'can_install': result.canInstall}

    def __getTooltipMgr(self):
        appLoader = dependency.instance(IAppLoader)
        return appLoader.getApp().getToolTipMgr()

    @staticmethod
    def __getErrorResponse(data, defaultError=''):
        return data if data else {'description': defaultError}

    @w2c(_SelectBattleTypeSchema, 'select_battle_type')
    def selectBattleType(self, cmd):
        battle_selector_items.getItems().select(cmd.battle_type, onlyActive=True)

    @w2c(_UrlInfoSchema, 'get_url_info')
    def getUrlInfo(self, cmd):
        external = self._lnkCtrl.externalAllowed(cmd.url)
        return {'external_allowed': external}