Ejemplo n.º 1
0
 def __init__(self, settings = None):
     super(EventBattlesQueueFunctional, self).__init__(QUEUE_TYPE.EVENT_BATTLES, {QUEUE_EVENT_TYPE.ENQUEUED: g_playerEvents.onEnqueuedEventBattles,
      QUEUE_EVENT_TYPE.DEQUEUED: g_playerEvents.onDequeuedEventBattles,
      QUEUE_EVENT_TYPE.ENQUEUE_ERROR: g_playerEvents.onEnqueueEventBattlesFailure,
      QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE: g_playerEvents.onKickedFromEventBattles,
      QUEUE_EVENT_TYPE.KICKED_FROM_ARENA: g_playerEvents.onKickedFromArena}, settings=settings)
     self.__requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 2
0
 def start(self):
     g_eventDispatcher.init(self)
     result = self.__setFunctional(CreateFunctionalCtx())
     self.__requestCtx = PrbCtrlRequestCtx()
     self.__startListening()
     functional.initDevFunctional()
     if result & FUNCTIONAL_FLAG.LOAD_PAGE == 0:
         BigWorld.callback(0.001, lambda: g_eventDispatcher.loadHangar())
     g_eventDispatcher.updateUI()
     if GUI_SETTINGS.specPrebatlesVisible and not prb_getters.areSpecBattlesHidden(
     ):
         g_eventDispatcher.addSpecBattlesToCarousel()
Ejemplo n.º 3
0
 def __init__(self, settings=None):
     super(RandomQueueFunctional, self).__init__(QUEUE_TYPE.RANDOMS, {
         QUEUE_EVENT_TYPE.ENQUEUED:
         g_playerEvents.onEnqueuedRandom,
         QUEUE_EVENT_TYPE.DEQUEUED:
         g_playerEvents.onDequeuedRandom,
         QUEUE_EVENT_TYPE.ENQUEUE_ERROR:
         g_playerEvents.onEnqueueRandomFailure,
         QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE:
         g_playerEvents.onKickedFromRandomQueue,
         QUEUE_EVENT_TYPE.KICKED_FROM_ARENA:
         g_playerEvents.onKickedFromArena
     },
                                                 settings=settings)
     self.__requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 4
0
 def __init__(self, settings = None):
     super(RandomQueueFunctional, self).__init__(QUEUE_TYPE.RANDOMS, {QUEUE_EVENT_TYPE.ENQUEUED: g_playerEvents.onEnqueuedRandom,
      QUEUE_EVENT_TYPE.DEQUEUED: g_playerEvents.onDequeuedRandom,
      QUEUE_EVENT_TYPE.ENQUEUE_ERROR: g_playerEvents.onEnqueueRandomFailure,
      QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE: g_playerEvents.onKickedFromRandomQueue,
      QUEUE_EVENT_TYPE.KICKED_FROM_ARENA: g_playerEvents.onKickedFromArena}, settings=settings)
     self.__requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 5
0
 def __init__(self, settings = None):
     super(HistoricalQueueFunctional, self).__init__(QUEUE_TYPE.HISTORICAL, {QUEUE_EVENT_TYPE.ENQUEUED: g_playerEvents.onEnqueuedHistorical,
      QUEUE_EVENT_TYPE.DEQUEUED: g_playerEvents.onDequeuedHistorical,
      QUEUE_EVENT_TYPE.ENQUEUE_ERROR: g_playerEvents.onEnqueueHistoricalFailure,
      QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE: g_playerEvents.onKickedFromHistoricalQueue,
      QUEUE_EVENT_TYPE.KICKED_FROM_ARENA: g_playerEvents.onKickedFromArena}, settings=settings)
     self.__requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 6
0
 def __init__(self, settings=None):
     super(HistoricalQueueFunctional,
           self).__init__(QUEUE_TYPE.HISTORICAL, {
               QUEUE_EVENT_TYPE.ENQUEUED:
               g_playerEvents.onEnqueuedHistorical,
               QUEUE_EVENT_TYPE.DEQUEUED:
               g_playerEvents.onDequeuedHistorical,
               QUEUE_EVENT_TYPE.ENQUEUE_ERROR:
               g_playerEvents.onEnqueueHistoricalFailure,
               QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE:
               g_playerEvents.onKickedFromHistoricalQueue,
               QUEUE_EVENT_TYPE.KICKED_FROM_ARENA:
               g_playerEvents.onKickedFromArena
           },
                          settings=settings)
     self.__requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 7
0
 def start(self, ctx):
     g_eventDispatcher.init(self)
     self.__requestCtx = PrbCtrlRequestCtx()
     result = self.__factories.start(
         self,
         CreateFunctionalCtx(CTRL_ENTITY_TYPE.UNKNOWN,
                             create={
                                 'queueType': ctx.getQueueType(),
                                 'settings': ctx.prbSettings
                             }))
     self._startListening()
     functional.initDevFunctional()
     if result & FUNCTIONAL_INIT_RESULT.LOAD_PAGE == 0:
         BigWorld.callback(0.001, lambda: g_eventDispatcher.loadHangar())
     g_eventDispatcher.updateUI()
     if GUI_SETTINGS.specPrebatlesVisible and not areSpecBattlesHidden():
         g_eventDispatcher.addSpecBattlesToCarousel()
Ejemplo n.º 8
0
 def start(self):
     g_eventDispatcher.init(self)
     result = self.__setFunctional(CreateFunctionalCtx())
     self.__requestCtx = PrbCtrlRequestCtx()
     self.__startListening()
     functional.initDevFunctional()
     if result & FUNCTIONAL_FLAG.LOAD_PAGE == 0:
         BigWorld.callback(0.001, lambda: g_eventDispatcher.loadHangar())
     g_eventDispatcher.updateUI()
     if GUI_SETTINGS.specPrebatlesVisible and not prb_getters.areSpecBattlesHidden():
         g_eventDispatcher.addSpecBattlesToCarousel()
Ejemplo n.º 9
0
 def start(self, ctx):
     g_eventDispatcher.init(self)
     self.__requestCtx = PrbCtrlRequestCtx()
     result = self.__factories.start(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.UNKNOWN, create={'queueType': ctx.getQueueType(),
      'settings': ctx.prbSettings}))
     self._startListening()
     functional.initDevFunctional()
     if result & FUNCTIONAL_INIT_RESULT.LOAD_PAGE == 0:
         BigWorld.callback(0.001, lambda : g_eventDispatcher.loadHangar())
     g_eventDispatcher.updateUI()
     if GUI_SETTINGS.specPrebatlesVisible and not areSpecBattlesHidden():
         g_eventDispatcher.addSpecBattlesToCarousel()
Ejemplo n.º 10
0
class AccountQueueFunctional(PreQueueFunctional):

    def __init__(self, queueType, subscriber, flags = FUNCTIONAL_FLAG.UNDEFINED):
        super(AccountQueueFunctional, self).__init__(queueType, subscriber, flags)
        self._requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx = None):
        return super(AccountQueueFunctional, self).init(ctx)

    def fini(self, woEvents = False):
        self._requestCtx.clear()
        super(AccountQueueFunctional, self).fini(woEvents)

    def doAction(self, action = None):
        if not self.isInQueue():
            self.queue(self._makeQueueCtxByAction(action))
        else:
            self.dequeue(pre_queue_ctx.DequeueCtx(waitingID='prebattle/leave'))
        return True

    def queue(self, ctx, callback = None):
        if ctx is None:
            ctx = self._makeQueueCtxByAction()
        if self._requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self._requestCtx)
            if callback is not None:
                callback(False)
            return
        elif self.isInQueue():
            LOG_ERROR('Player already is in the queue', self._requestCtx)
            if callback is not None:
                callback(False)
            return
        elif self._validateParentControl():
            if callback is not None:
                callback(False)
            return
        else:
            self._requestCtx = ctx
            self._requestCtx.startProcessing(callback)
            try:
                self._doQueue(ctx)
            except (AttributeError, TypeError, NotImplementedError):
                LOG_CURRENT_EXCEPTION()
                self._requestCtx.stopProcessing(False)

            return

    def dequeue(self, ctx, callback = None):
        if self._requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self._requestCtx)
            if callback:
                callback(False)
            return
        elif not self.isInQueue():
            LOG_ERROR('Player is not in the queue', ctx)
            if callback is not None:
                callback(False)
            return
        else:
            self._requestCtx = ctx
            self._requestCtx.startProcessing(callback)
            try:
                self._doDequeue(ctx)
            except (AttributeError, TypeError, NotImplementedError):
                LOG_CURRENT_EXCEPTION()
                self._requestCtx.stopProcessing(False)

            return

    def onEnqueued(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onEnqueued(*args)

    def onDequeued(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onDequeued(*args)

    def onEnqueueError(self, *args):
        self._requestCtx.stopProcessing(False)
        super(AccountQueueFunctional, self).onEnqueueError(*args)

    def onKickedFromQueue(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onKickedFromQueue(*args)

    def onKickedFromArena(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onKickedFromArena(*args)

    def _doQueue(self, ctx):
        raise NotImplementedError('Routine _doQueue must be overridden')

    def _doDequeue(self, ctx):
        raise NotImplementedError('Routine _doDequeue must be overridden')

    def _makeQueueCtxByAction(self, action = None):
        raise NotImplementedError('Routine _makeDefQueueCtx must be overridden')

    def _validateParentControl(self):
        result = prb_getters.isParentControlActivated()
        if result:
            g_eventDispatcher.showParentControlNotification()
        return result
Ejemplo n.º 11
0
class _PrebattleDispatcher(ListenersCollection):
    def __init__(self):
        super(_PrebattleDispatcher, self).__init__()
        self.__requestCtx = None
        self.__collection = FunctionalCollection()
        self.__factories = ControlFactoryDecorator()
        self.__nextPrbFunctional = None
        self._setListenerClass(IGlobalListener)
        return

    def __del__(self):
        LOG_DEBUG('_PrebattleDispatcher deleted')

    def start(self):
        g_eventDispatcher.init(self)
        result = self.__setFunctional(CreateFunctionalCtx())
        self.__requestCtx = PrbCtrlRequestCtx()
        self.__startListening()
        functional.initDevFunctional()
        if result & FUNCTIONAL_FLAG.LOAD_PAGE == 0:
            BigWorld.callback(0.001, lambda: g_eventDispatcher.loadHangar())
        g_eventDispatcher.updateUI()
        if GUI_SETTINGS.specPrebatlesVisible and not prb_getters.areSpecBattlesHidden(
        ):
            g_eventDispatcher.addSpecBattlesToCarousel()

    def stop(self):
        self.__nextPrbFunctional = None
        self.__stopListening()
        functional.finiDevFunctional()
        self.__clear(woEvents=True)
        g_eventDispatcher.fini()
        return

    def getPrbFunctional(self):
        return self.__collection.getItem(_CTRL_TYPE.PREBATTLE)

    def getUnitFunctional(self):
        return self.__collection.getItem(_CTRL_TYPE.UNIT)

    def getPreQueueFunctional(self):
        return self.__collection.getItem(_CTRL_TYPE.PREQUEUE)

    def getFunctional(self, ctrlType):
        return self.__collection.getItem(ctrlType)

    def getFunctionalCollection(self):
        return self.__collection

    def getControlFactories(self):
        return self.__factories

    def hasModalEntity(self):
        return self.__collection.hasModalEntity()

    def getFunctionalState(self):
        return self.__collection.getState(self.__factories)

    @async
    @process
    def create(self, ctx, callback=None):
        if ctx.getRequestType() == _RQ_TYPE.CREATE:
            if not self.__requestCtx.isProcessing():
                result = yield self.unlock(ctx)
                if result:
                    entry = self.__factories.createEntry(ctx)
                    if entry:
                        LOG_DEBUG('Request to create', ctx)
                        self.__requestCtx = ctx
                        entry.create(ctx, callback=callback)
                    else:
                        LOG_ERROR('Entry not found', ctx)
                        if callback is not None:
                            callback(False)
                elif callback is not None:
                    callback(False)
            else:
                LOG_ERROR('Request is processing', self.__requestCtx)
                if callback is not None:
                    callback(False)
                yield lambda callback=None: callback
        else:
            LOG_ERROR('Invalid context to create', ctx)
            if callback is not None:
                callback(False)
            yield lambda callback=None: callback
        return

    @async
    @process
    def join(self, ctx, callback=None):
        if self.__validateJoinOp(ctx):
            result = yield self.unlock(ctx)
            ctx.setForced(result)
            if result:
                entry = self.__factories.createEntry(ctx)
                if entry:
                    LOG_DEBUG('Request to join', ctx)
                    self.__requestCtx = ctx
                    entry.join(ctx, callback=callback)
                else:
                    LOG_ERROR('Entry not found', ctx)
                    if callback is not None:
                        callback(False)
        else:
            if callback is not None:
                callback(False)
            yield lambda callback=None: callback
        return

    @async
    def leave(self, ctx, callback=None):
        if ctx.getRequestType() != _RQ_TYPE.LEAVE:
            LOG_ERROR('Invalid context to leave prebattle/unit', ctx)
            if callback is not None:
                callback(False)
            return
        elif self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback is not None:
                callback(False)
            return
        else:
            ctrlType = ctx.getCtrlType()
            formation = self.__collection.getItem(ctx.getCtrlType())
            if formation is not None:
                if formation.hasLockedState():
                    entityType = formation.getEntityType()
                    SystemMessages.pushI18nMessage(
                        messages.getLeaveDisabledMessage(ctrlType, entityType),
                        type=SystemMessages.SM_TYPE.Warning)
                    if callback is not None:
                        callback(False)
                    return
                LOG_DEBUG('Request to leave formation', ctx)
                self.__requestCtx = ctx
                formation.leave(ctx, callback=callback)
            else:
                LOG_ERROR('Functional not found', ctx)
                if callback is not None:
                    callback(False)
            return

    @async
    @process
    def unlock(self, unlockCtx, callback=None):
        state = self.getFunctionalState()
        result = True
        if not state.isIntroMode:
            canDoLeave = True
        elif unlockCtx.hasFlags(FUNCTIONAL_FLAG.SWITCH):
            if state.ctrlTypeID == unlockCtx.getCtrlType(
            ) and state.entityTypeID != unlockCtx.getEntityType():
                canDoLeave = True
                unlockCtx.removeFlags(FUNCTIONAL_FLAG.SWITCH)
            else:
                canDoLeave = False
        else:
            canDoLeave = True
        if canDoLeave:
            factory = self.__factories.get(state.ctrlTypeID)
            result = False
            if factory:
                ctx = factory.createLeaveCtx(unlockCtx.getFlags())
                if ctx:
                    meta = self.__collection.getConfirmDialogMeta(
                        state.ctrlTypeID, unlockCtx)
                    if meta:
                        result = yield DialogsInterface.showDialog(meta)
                    else:
                        result = True
                    if result:
                        result = yield self.leave(ctx)
                else:
                    LOG_ERROR('Can not create leave ctx', state)
            else:
                LOG_ERROR('Factory is not found', state)
        if callback is not None:
            callback(result)
        yield lambda callback=None: callback
        return

    @async
    @process
    def select(self, entry, callback=None):
        ctx = entry.makeDefCtx()
        if ctx and self.__validateJoinOp(ctx):
            result = yield self.unlock(ctx)
            ctx.setForced(result)
            if result:
                LOG_DEBUG('Request to select', ctx)
                self.__requestCtx = ctx
                entry.select(ctx, callback=callback)
            elif callback is not None:
                callback(False)
        else:
            if callback is not None:
                callback(False)
            yield lambda callback=None: callback
        return

    @async
    def sendPrbRequest(self, ctx, callback=None):
        prbFunctional = self.getFunctional(_CTRL_TYPE.PREBATTLE)
        if prbFunctional:
            prbFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('prbFunctional is not found', ctx)
            if callback is not None:
                callback(False)
        return

    @async
    def sendUnitRequest(self, ctx, callback=None):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        if unitFunctional:
            unitFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('unitFunctional is not found', ctx)
            if callback is not None:
                callback(False)
        return

    @async
    def sendPreQueueRequest(self, ctx, callback=None):
        preQueueFunctional = self.getFunctional(_CTRL_TYPE.PREQUEUE)
        if preQueueFunctional is not None:
            preQueueFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('preQueueFunctional is not found', ctx)
            if callback is not None:
                callback(False)
        return

    def exitFromQueue(self):
        self.__collection.exitFromQueue()

    def canPlayerDoAction(self):
        canDo, restriction = self.__collection.canPlayerDoAction(False)
        if canDo:
            if g_currentPreviewVehicle.isPresent():
                canDo = False
                restriction = PREBATTLE_RESTRICTION.PREVIEW_VEHICLE_IS_PRESENT
            elif not g_currentVehicle.isReadyToFight():
                if not g_currentVehicle.isPresent():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT
                elif g_currentVehicle.isInBattle():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_BATTLE
                elif not g_currentVehicle.isCrewFull():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.CREW_NOT_FULL
                elif g_currentVehicle.isBroken():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_BROKEN
                elif g_currentVehicle.isFalloutOnly(
                ) and not game_control.getFalloutCtrl().isSelected():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_FALLOUT_ONLY
                elif g_currentVehicle.isDisabledInRoaming():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_ROAMING
                elif g_currentVehicle.isDisabledInPremIGR():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_PREMIUM_IGR_ONLY
                elif g_currentVehicle.isDisabledInRent():
                    unit = self.getUnitFunctional()
                    if unit is not None and unit.getFlags().isInPreArena():
                        canDo = True
                    else:
                        canDo = False
                        if g_currentVehicle.isPremiumIGR():
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_IGR_RENTALS_IS_OVER
                        else:
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_RENTALS_IS_OVER
            if canDo:
                canDo, restriction = self.__collection.canPlayerDoAction(True)
        return (canDo, restriction)

    def getPlayerInfo(self):
        return self.__collection.getPlayerInfo(self.__factories)

    def doAction(self, action=None):
        if not g_currentVehicle.isPresent():
            SystemMessages.pushMessage(messages.getInvalidVehicleMessage(
                PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT),
                                       type=SystemMessages.SM_TYPE.Error)
            return False
        LOG_DEBUG('Do GUI action', action)
        return self.__collection.doAction(self.__factories, action)

    def doSelectAction(self, action):
        result = self.__collection.doSelectAction(action)
        if result.isProcessed:
            if result.newEntry is not None:
                self.__doSelect(result.newEntry)
            return True
        else:
            entry = self.__factories.createEntryByAction(action)
            if entry is not None:
                self.__doSelect(entry)
                return True
            return False

    @process
    def doLeaveAction(self, ctx):
        meta = self.__collection.getConfirmDialogMeta(ctx.getCtrlType(), ctx)
        if meta is not None:
            isConfirmed = yield DialogsInterface.showDialog(meta)
        else:
            isConfirmed = yield lambda callback: callback(True)
        if isConfirmed:
            yield self.leave(ctx)
        return

    def getGUIPermissions(self):
        return self.__collection.getGUIPermissions()

    def onCompanyStateChanged(self, _):
        if not self.getPrbFunctional().hasLockedState():
            g_eventDispatcher.updateUI()

    def setRequestCtx(self, ctx):
        result = True
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            result = False
        else:
            self.__requestCtx = ctx
        return result

    def pe_onArenaJoinFailure(self, errorCode, _):
        self.__collection.reset()
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode),
                                   type=SystemMessages.SM_TYPE.Error)

    def pe_onKickedFromArena(self, reasonCode):
        self.__collection.reset()
        SystemMessages.pushMessage(messages.getKickReasonMessage(reasonCode),
                                   type=SystemMessages.SM_TYPE.Error)

    def pe_onPrebattleAutoInvitesChanged(self):
        if GUI_SETTINGS.specPrebatlesVisible:
            isHidden = prb_getters.areSpecBattlesHidden()
            if isHidden:
                g_eventDispatcher.removeSpecBattlesFromCarousel()
            else:
                g_eventDispatcher.addSpecBattlesToCarousel()
        g_eventDispatcher.updateUI()

    def pe_onPrebattleJoined(self):
        if prb_getters.getClientPrebattle() is not None:
            flags = self.__requestCtx.getFlags()
            self.__setFunctional(
                CreateFunctionalCtx(_CTRL_TYPE.PREBATTLE, flags=flags))
        else:
            LOG_ERROR('ClientPrebattle is not defined')
            self.__requestCtx.stopProcessing(result=False)
        return

    def pe_onPrebattleJoinFailure(self, errorCode):
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode),
                                   type=SystemMessages.SM_TYPE.Error)
        self.__requestCtx.stopProcessing(result=False)
        self.__requestCtx.clearFlags()
        g_eventDispatcher.updateUI()

    def pe_onPrebattleLeft(self):
        if self.__nextPrbFunctional is not None:
            self.__nextPrbFunctional()
            self.__nextPrbFunctional = None
            return
        else:
            flags = self.__requestCtx.getFlags()
            flags |= FUNCTIONAL_FLAG.LEAVE_ENTITY
            prbType = 0
            if flags & FUNCTIONAL_FLAG.SWITCH > 0:
                prbFunctional = self.getFunctional(_CTRL_TYPE.PREBATTLE)
                if prbFunctional is not None:
                    prbType = prbFunctional.getEntityType()
            self.__changePrbFunctional(flags=flags,
                                       prbType=prbType,
                                       stop=False)
            return

    def pe_onKickedFromPrebattle(self, _):
        self.__changePrbFunctional(stop=True)

    def gs_onTillBanNotification(self, isPlayTimeBan, timeTillBlock):
        if prb_getters.isParentControlActivated():
            self.__collection.reset()
            key = '#system_messages:gameSessionControl/korea/{0:>s}'
            if isPlayTimeBan:
                SystemMessages.g_instance.pushI18nMessage(
                    key.format('playTimeNotification'),
                    timeTillBlock,
                    type=SystemMessages.SM_TYPE.Warning)
            else:
                gameSession = game_control.g_instance.gameSession
                notifyStartTime, blockTime = gameSession.getCurfewBlockTime()
                formatter = lambda t: time.strftime('%H:%M', time.localtime(t))
                SystemMessages.g_instance.pushI18nMessage(
                    key.format('midnightNotification'),
                    type=SystemMessages.SM_TYPE.Warning,
                    preBlockTime=formatter(notifyStartTime),
                    blockTime=formatter(blockTime))

    def rc_onRentChange(self, vehicles):
        if g_currentVehicle.isPresent(
        ) and g_currentVehicle.item.intCD in vehicles and g_currentVehicle.isDisabledInRent(
        ) and g_currentVehicle.isInPrebattle():
            self.__collection.reset()

    def igr_onRoomChange(self, roomType, _):
        if roomType != IGR_TYPE.PREMIUM:
            if g_currentVehicle.isPremiumIGR(
            ) and g_currentVehicle.isInPrebattle():
                self.__collection.reset()

    def ctrl_onPrebattleIntroModeJoined(self, prbType, isLeaving):
        flags = self.__requestCtx.getFlags()
        if not isLeaving:
            self.__changePrbFunctional(flags=flags, prbType=prbType)
        else:
            self.__nextPrbFunctional = partial(self.__changePrbFunctional,
                                               flags=flags,
                                               prbType=prbType)

    def ctrl_onPrebattleIntroModeLeft(self):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_INTRO
        self.__changePrbFunctional(flags=flags)

    def ctrl_onPrebattleInited(self):
        self.__requestCtx.stopProcessing(result=True)
        self.__setFunctional(
            CreateFunctionalCtx(_CTRL_TYPE.PREBATTLE,
                                flags=self.__requestCtx.getFlags(),
                                initCtx=self.__requestCtx))
        g_eventDispatcher.updateUI()

    def ctrl_onUnitIntroModeJoined(self, prbType, flags):
        self.__changeUnitFunctional(flags=flags, prbType=prbType)

    def ctrl_onUnitIntroModeLeft(self):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_INTRO
        self.__changeUnitFunctional(flags=flags)

    def ctrl_onPreQueueFunctionalCreated(self, queueType):
        self.__changePreQueueFunctional(flags=self.__requestCtx.getFlags(),
                                        queueType=queueType)
        g_eventDispatcher.updateUI()

    def ctrl_onPreQueueFunctionalDestroyed(self):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_PRE_QUEUE
        self.__changePreQueueFunctional(flags=flags)

    def unitMgr_onUnitJoined(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        if unitFunctional is not None and unitFunctional.getID(
        ) == unitMgrID and unitFunctional.getUnitIdx() == unitIdx:
            unitFunctional.rejoin()
        else:
            if unitFunctional is not None:
                prbType = unitFunctional.getEntityType()
            else:
                prbType = 0
            self.__changeUnitFunctional(flags=self.__requestCtx.getFlags(),
                                        prbType=prbType)
        return

    def unitMgr_onUnitLeft(self, unitMgrID, unitIdx):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_ENTITY
        prbType = 0
        if flags & FUNCTIONAL_FLAG.SWITCH > 0:
            unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
            if unitFunctional is not None:
                prbType = unitFunctional.getEntityType()
        self.__changeUnitFunctional(flags=flags, prbType=prbType)
        g_eventDispatcher.updateUI()
        return

    def unitMgr_onUnitRestored(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        flags = unitFunctional.getFlags()
        pInfo = unitFunctional.getPlayerInfo()
        if flags.isInPreArena() and pInfo.isInSlot:
            g_eventDispatcher.loadHangar()

    def unitMgr_onUnitErrorReceived(self, requestID, unitMgrID, unitIdx,
                                    errorCode, errorString):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        if unitFunctional is not None:
            unitFunctional.setLastError(errorCode)
            if errorCode in RETURN_INTRO_UNIT_MGR_ERRORS and unitFunctional.canSwitchToIntro(
            ):
                self.__requestCtx.addFlags(FUNCTIONAL_FLAG.SWITCH)
            if errorCode == UNIT_ERROR.CANT_PICK_LEADER:
                self.__requestCtx.removeFlags(FUNCTIONAL_FLAG.SWITCH)
            elif errorCode == UNIT_ERROR.REMOVED_PLAYER:
                if self.__requestCtx.getCtrlType(
                ) == _CTRL_TYPE.UNIT and unitFunctional.getEntityType(
                ) != self.__requestCtx.getEntityType():
                    self.__requestCtx.removeFlags(FUNCTIONAL_FLAG.SWITCH)
        else:
            LOG_ERROR('Unit functional is not found')
        if errorCode not in IGNORED_UNIT_MGR_ERRORS:
            msgType, msgBody = messages.getUnitMessage(errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)
            self.__requestCtx.stopProcessing(result=False)
            g_eventDispatcher.updateUI()
        return

    def unitBrowser_onErrorReceived(self, errorCode, errorString):
        if errorCode not in IGNORED_UNIT_BROWSER_ERRORS:
            msgType, msgBody = messages.getUnitBrowserMessage(
                errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)

    def forMgr_onFortStateChanged(self):
        g_eventDispatcher.updateUI()

    def fortMgr_onFortResponseReceived(self, requestID, resultCode, _):
        self.__requestCtx.stopProcessing(
            result=resultCode in (FORT_ERROR.OK, ))
        g_eventDispatcher.updateUI()

    def __startListening(self):
        """
        Subscribes to player events.
        """
        g_playerEvents.onPrebattleJoined += self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure += self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft += self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle += self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure += self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena += self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged += self.pe_onPrebattleAutoInvitesChanged
        gameSession = game_control.g_instance.gameSession
        rentCtr = game_control.g_instance.rentals
        igrCtr = game_control.g_instance.igr
        if gameSession.lastBanMsg is not None:
            self.gs_onTillBanNotification(*gameSession.lastBanMsg)
        gameSession.onTimeTillBan += self.gs_onTillBanNotification
        rentCtr.onRentChangeNotify += self.rc_onRentChange
        igrCtr.onIgrTypeChanged += self.igr_onRoomChange
        unitMgr = prb_getters.getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined += self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft += self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored += self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived += self.unitMgr_onUnitErrorReceived
        else:
            LOG_ERROR('Unit manager is not defined')
        unitBrowser = prb_getters.getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived += self.unitBrowser_onErrorReceived
        else:
            LOG_ERROR('Unit browser is not defined')
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortStateChanged += self.forMgr_onFortStateChanged
            fortMgr.onFortResponseReceived += self.fortMgr_onFortResponseReceived
        else:
            LOG_ERROR('Fort manager is not defined')
        g_prbCtrlEvents.onPrebattleIntroModeJoined += self.ctrl_onPrebattleIntroModeJoined
        g_prbCtrlEvents.onPrebattleIntroModeLeft += self.ctrl_onPrebattleIntroModeLeft
        g_prbCtrlEvents.onPrebattleInited += self.ctrl_onPrebattleInited
        g_prbCtrlEvents.onUnitIntroModeJoined += self.ctrl_onUnitIntroModeJoined
        g_prbCtrlEvents.onUnitIntroModeLeft += self.ctrl_onUnitIntroModeLeft
        g_prbCtrlEvents.onPreQueueFunctionalCreated += self.ctrl_onPreQueueFunctionalCreated
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed += self.ctrl_onPreQueueFunctionalDestroyed
        g_eventsCache.companies.onCompanyStateChanged += self.onCompanyStateChanged
        return

    def __stopListening(self):
        """
        Unsubscribe from player events.
        """
        g_eventsCache.companies.onCompanyStateChanged -= self.onCompanyStateChanged
        g_playerEvents.onPrebattleJoined -= self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure -= self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft -= self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle -= self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure -= self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena -= self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged -= self.pe_onPrebattleAutoInvitesChanged
        game_control.g_instance.gameSession.onTimeTillBan -= self.gs_onTillBanNotification
        game_control.g_instance.rentals.onRentChangeNotify -= self.rc_onRentChange
        game_control.g_instance.igr.onIgrTypeChanged -= self.igr_onRoomChange
        unitMgr = prb_getters.getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined -= self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft -= self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored -= self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived -= self.unitMgr_onUnitErrorReceived
        unitBrowser = prb_getters.getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived -= self.unitBrowser_onErrorReceived
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortResponseReceived -= self.fortMgr_onFortResponseReceived
            fortMgr.onFortStateChanged -= self.forMgr_onFortStateChanged
        g_prbCtrlEvents.clear()

    def __clear(self, woEvents=False):
        if self.__requestCtx:
            self.__requestCtx.clear()
            self.__requestCtx = None
        if self.__collection is not None:
            self.__collection.clear(woEvents=woEvents)
            self.__collection = None
        if self.__factories is not None:
            self.__factories.clear()
            self.__factories = None
        g_eventDispatcher.removeSpecBattlesFromCarousel()
        self.clear()
        return

    def __changePrbFunctional(self,
                              flags=FUNCTIONAL_FLAG.UNDEFINED,
                              prbType=0,
                              stop=True):
        self.__setFunctional(
            CreateFunctionalCtx(_CTRL_TYPE.PREBATTLE, prbType, flags=flags))
        if stop:
            self.__requestCtx.stopProcessing(result=True)

    def __changeUnitFunctional(self,
                               flags=FUNCTIONAL_FLAG.UNDEFINED,
                               prbType=0):
        self.__setFunctional(
            CreateFunctionalCtx(_CTRL_TYPE.UNIT,
                                prbType,
                                flags=flags,
                                initCtx=self.__requestCtx))
        self.__requestCtx.stopProcessing(result=True)

    def __changePreQueueFunctional(self,
                                   flags=FUNCTIONAL_FLAG.UNDEFINED,
                                   queueType=0):
        self.__setFunctional(
            CreateFunctionalCtx(_CTRL_TYPE.PREQUEUE, queueType, flags=flags))
        self.__requestCtx.stopProcessing(result=True)

    def __validateJoinOp(self, ctx):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            return False
        for func in self.__collection.getIterator():
            if func.isPlayerJoined(ctx):
                LOG_DEBUG('Player already joined', ctx)
                func.showGUI(ctx)
                return False
            if func.hasLockedState():
                SystemMessages.pushI18nMessage(
                    '#system_messages:prebattle/hasLockedState',
                    type=SystemMessages.SM_TYPE.Warning)
                return False

        return True

    @process
    def __doSelect(self, entry):
        yield self.select(entry)

    def __setFunctional(self, ctx):
        ctx.addFlags(self.__collection.getFunctionalFlags())
        items = []
        for created in self.__factories.createFunctional(ctx):
            if ctx.hasFlags(FUNCTIONAL_FLAG.SET_GLOBAL_LISTENERS):
                created.addMutualListeners(self)
            items.append(created)

        for item in items:
            ctrlType = item.getCtrlType()
            self.__collection.setFunctionalFlags(ctrlType, ctx.getFlags())
            flag = self.__collection.setItem(item.getCtrlType(), item,
                                             ctx.getInitCtx())
            ctx.addFlags(flag)

        LOG_DEBUG('Functionals have been updated', ctx.getFlagsToStrings())
        ctx.clear()
        return ctx.getFlags()
Ejemplo n.º 12
0
class _PrebattleDispatcher(object):

    def __init__(self):
        super(_PrebattleDispatcher, self).__init__()
        self.__requestCtx = None
        self.__collection = FunctionalCollection()
        self.__factories = ControlFactoryDecorator()
        self.__nextPrbFunctional = None
        self._globalListeners = set()
        return

    def __del__(self):
        LOG_DEBUG('_PrebattleDispatcher deleted')

    def start(self, ctx):
        g_eventDispatcher.init(self)
        self.__requestCtx = PrbCtrlRequestCtx()
        result = self.__factories.start(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.UNKNOWN, create={'queueType': ctx.getQueueType(),
         'settings': ctx.prbSettings}))
        self._startListening()
        functional.initDevFunctional()
        if result & FUNCTIONAL_INIT_RESULT.LOAD_PAGE == 0:
            BigWorld.callback(0.001, lambda : g_eventDispatcher.loadHangar())
        g_eventDispatcher.updateUI()
        if GUI_SETTINGS.specPrebatlesVisible and not areSpecBattlesHidden():
            g_eventDispatcher.addSpecBattlesToCarousel()

    def stop(self):
        self.__nextPrbFunctional = None
        self._stopListening()
        functional.finiDevFunctional()
        self._clear(woEvents=True)
        g_eventDispatcher.fini()
        return

    def getPrbFunctional(self):
        return self.__collection.getItem(CTRL_ENTITY_TYPE.PREBATTLE)

    def getUnitFunctional(self):
        return self.__collection.getItem(CTRL_ENTITY_TYPE.UNIT)

    def getPreQueueFunctional(self):
        return self.__collection.getItem(CTRL_ENTITY_TYPE.PREQUEUE)

    def getFunctional(self, ctrlType):
        return self.__collection.getItem(ctrlType)

    def getFunctionalCollection(self):
        return self.__collection

    def getControlFactories(self):
        return self.__factories

    def hasModalEntity(self):
        return self.__collection.hasModalEntity()

    def getFunctionalState(self):
        return self.__collection.getState(self.__factories)

    @async
    @process
    def create(self, ctx, callback = None):
        if ctx.getRequestType() == REQUEST_TYPE.CREATE:
            if not self.__requestCtx.isProcessing():
                result = yield self.unlock(ctx.getFuncExit(), True)
                if result:
                    entry = self.__factories.createEntry(ctx)
                    if entry:
                        LOG_DEBUG('Request to create', ctx)
                        self.__requestCtx = ctx
                        entry.create(ctx, callback=callback)
                    else:
                        LOG_ERROR('Entry not found', ctx)
                        if callback:
                            callback(False)
                elif callback:
                    callback(False)
            else:
                LOG_ERROR('Request is processing', self.__requestCtx)
                if callback:
                    callback(False)
                yield lambda callback = None: callback
        else:
            LOG_ERROR('Invalid context to create', ctx)
            if callback:
                callback(False)
            yield lambda callback = None: callback
        return

    @async
    @process
    def join(self, ctx, callback = None):
        if self._validateJoinOp(ctx):
            result = yield self.unlock(ctx.getFuncExit(), ctx.isForced())
            ctx.setForced(result)
            if result:
                entry = self.__factories.createEntry(ctx)
                if entry:
                    LOG_DEBUG('Request to join', ctx)
                    self.__requestCtx = ctx
                    entry.join(ctx, callback=callback)
                else:
                    LOG_ERROR('Entry not found', ctx)
                    if callback:
                        callback(False)
        else:
            if callback:
                callback(False)
            yield lambda callback = None: callback
        return

    @async
    def leave(self, ctx, callback = None):
        if ctx.getRequestType() is not REQUEST_TYPE.LEAVE:
            LOG_ERROR('Invalid context to leave prebattle/unit', ctx)
            if callback:
                callback(False)
            return
        elif self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        else:
            ctrlType = ctx.getCtrlType()
            formation = self.__collection.getItem(ctx.getCtrlType())
            if formation is not None:
                if formation.hasLockedState():
                    if ctrlType == CTRL_ENTITY_TYPE.PREQUEUE:
                        entityType = formation.getQueueType()
                    else:
                        entityType = formation.getPrbType()
                    SystemMessages.pushI18nMessage('#system_messages:{0}'.format(rally_dialog_meta.makeI18nKey(ctrlType, entityType, 'leaveDisabled')), type=SystemMessages.SM_TYPE.Warning)
                    if callback:
                        callback(False)
                    return
                LOG_DEBUG('Request to leave formation', ctx)
                self.__requestCtx = ctx
                formation.leave(ctx, callback=callback)
            else:
                LOG_ERROR('Functional not found', ctx)
                if callback:
                    callback(False)
            return

    @async
    @process
    def unlock(self, funcExit, forced, callback = None):
        state = self.getFunctionalState()
        result = True
        if state.hasModalEntity and (not state.isIntroMode or forced) and not (funcExit == FUNCTIONAL_EXIT.FALLOUT and state.isInFallout()):
            factory = self.__factories.get(state.ctrlTypeID)
            result = False
            if factory:
                ctx = factory.createLeaveCtx(funcExit)
                if ctx:
                    meta = self.__collection.getItem(state.ctrlTypeID).getConfirmDialogMeta(funcExit)
                    if meta:
                        result = yield DialogsInterface.showDialog(meta)
                    else:
                        result = True
                    if result:
                        result = yield self.leave(ctx)
                else:
                    LOG_ERROR('Can not create leave ctx', state)
            else:
                LOG_ERROR('Factory is not found', state)
        if getFalloutCtrl().isEnabled() and not funcExit == FUNCTIONAL_EXIT.SQUAD:
            g_eventDispatcher.unloadFallout()
        if callback:
            callback(result)
        yield lambda callback = None: callback
        return

    @async
    @process
    def select(self, entry, callback = None):
        ctx = entry.makeDefCtx()
        if ctx and self._validateJoinOp(ctx):
            result = yield self.unlock(ctx.getFuncExit(), True)
            ctx.setForced(result)
            if result:
                LOG_DEBUG('Request to select', ctx)
                self.__requestCtx = ctx
                entry.select(ctx, callback=callback)
            elif callback:
                callback(False)
        else:
            if callback:
                callback(False)
            yield lambda callback = None: callback
        return

    @async
    def sendPrbRequest(self, ctx, callback = None):
        prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
        if prbFunctional:
            prbFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('prbFunctional is not found', ctx)
            if callback:
                callback(False)

    @async
    def sendUnitRequest(self, ctx, callback = None):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if unitFunctional:
            unitFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('unitFunctional is not found', ctx)
            if callback:
                callback(False)

    def exitFromQueue(self):
        self.__collection.exitFromQueue()

    def canPlayerDoAction(self):
        canDo, restriction = self.__collection.canPlayerDoAction(False)
        falloutCtrl = getFalloutCtrl()
        if canDo:
            if falloutCtrl.isEnabled():
                if falloutCtrl.getBattleType() == FALLOUT_BATTLE_TYPE.UNDEFINED:
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.FALLOUT_NOT_SELECTED
                elif not g_currentVehicle.isGroupReady():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_GROUP_IS_NOT_READY
            elif not g_currentVehicle.isReadyToFight():
                if not g_currentVehicle.isPresent():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT
                elif g_currentVehicle.isInBattle():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_BATTLE
                elif not g_currentVehicle.isCrewFull():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.CREW_NOT_FULL
                elif g_currentVehicle.isBroken():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_BROKEN
                elif g_currentVehicle.isFalloutOnly():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_FALLOUT_ONLY
                elif g_currentVehicle.isDisabledInRoaming():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_ROAMING
                elif g_currentVehicle.isDisabledInPremIGR():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_PREMIUM_IGR_ONLY
                elif g_currentVehicle.isDisabledInRent():
                    unit = self.getUnitFunctional()
                    if unit is not None and unit.getFlags().isInPreArena():
                        canDo = True
                    else:
                        canDo = False
                        if g_currentVehicle.isPremiumIGR():
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_IGR_RENTALS_IS_OVER
                        else:
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_RENTALS_IS_OVER
            if canDo:
                canDo, restriction = self.__collection.canPlayerDoAction(True)
        return (canDo, restriction)

    def getPlayerInfo(self):
        return self.__collection.getPlayerInfo(self.__factories)

    def doAction(self, action):
        if not g_currentVehicle.isPresent():
            SystemMessages.pushMessage(messages.getInvalidVehicleMessage(PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT), type=SystemMessages.SM_TYPE.Error)
            return False
        LOG_DEBUG('Do GUI action', action)
        return self.__collection.doAction(self, action, self.__factories)

    def doSelectAction(self, action):
        result = self.__collection.doSelectAction(action)
        if result:
            return True
        if action.actionName == PREBATTLE_ACTION_NAME.JOIN_RANDOM_QUEUE:
            self._doUnlock()
            return True
        entry = self.__factories.createEntryByAction(action.actionName)
        if entry:
            self._doSelect(entry)
            result = True
        return result

    def doLeaveAction(self, ctx):
        formation = self.__collection.getItem(ctx.getCtrlType())
        if formation:
            LOG_DEBUG('Request to leave', ctx)
            formation.doLeaveAction(self, ctx=ctx)
        else:
            LOG_ERROR('Functional is not found.', ctx)

    def addGlobalListener(self, listener):
        if isinstance(listener, IGlobalListener):
            listenerRef = weakref.ref(listener)
            if listenerRef not in self._globalListeners:
                self._globalListeners.add(listenerRef)
                self.__collection.addListener(listener)
            else:
                LOG_ERROR('Listener already added', listener)
        else:
            LOG_ERROR('Object is not extend IPrbListener', listener)

    def removeGlobalListener(self, listener):
        listenerRef = weakref.ref(listener)
        if listenerRef in self._globalListeners:
            self._globalListeners.remove(listenerRef)
        else:
            LOG_ERROR('Listener not found', listener)
        self.__collection.removeListener(listener)

    def getGUIPermissions(self):
        return self.__collection.getGUIPermissions()

    def _startListening(self):
        """
        Subscribes to player events.
        """
        g_playerEvents.onPrebattleJoined += self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure += self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft += self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle += self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure += self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena += self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged += self.pe_onPrebattleAutoInvitesChanged
        gameSession = game_control.g_instance.gameSession
        captchaCtrl = game_control.g_instance.captcha
        rentCtr = game_control.g_instance.rentals
        igrCtr = game_control.g_instance.igr
        if gameSession.lastBanMsg is not None:
            self.gs_onTillBanNotification(*gameSession.lastBanMsg)
        gameSession.onTimeTillBan += self.gs_onTillBanNotification
        rentCtr.onRentChangeNotify += self.rc_onRentChange
        captchaCtrl.onCaptchaInputCanceled += self.captcha_onCaptchaInputCanceled
        igrCtr.onIgrTypeChanged += self.igr_onRoomChange
        unitMgr = getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined += self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft += self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored += self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived += self.unitMgr_onUnitErrorReceived
        else:
            LOG_ERROR('Unit manager is not defined')
        unitBrowser = getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived += self.unitBrowser_onErrorReceived
        else:
            LOG_ERROR('Unit browser is not defined')
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortStateChanged += self.forMgr_onFortStateChanged
            fortMgr.onFortResponseReceived += self.fortMgr_onFortResponseReceived
        else:
            LOG_ERROR('Fort manager is not defined')
        g_prbCtrlEvents.onPrebattleIntroModeJoined += self.ctrl_onPrebattleIntroModeJoined
        g_prbCtrlEvents.onPrebattleIntroModeLeft += self.ctrl_onPrebattleIntroModeLeft
        g_prbCtrlEvents.onPrebattleInited += self.ctrl_onPrebattleInited
        g_prbCtrlEvents.onUnitIntroModeJoined += self.ctrl_onUnitIntroModeJoined
        g_prbCtrlEvents.onUnitIntroModeLeft += self.ctrl_onUnitIntroModeLeft
        g_prbCtrlEvents.onPreQueueFunctionalCreated += self.ctrl_onPreQueueFunctionalCreated
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed += self.ctrl_onPreQueueFunctionalDestroyed
        g_eventsCache.companies.onCompanyStateChanged += self.onCompanyStateChanged
        return

    def _stopListening(self):
        """
        Unsubscribe from player events.
        """
        g_eventsCache.companies.onCompanyStateChanged -= self.onCompanyStateChanged
        g_playerEvents.onPrebattleJoined -= self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure -= self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft -= self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle -= self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure -= self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena -= self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged -= self.pe_onPrebattleAutoInvitesChanged
        game_control.g_instance.captcha.onCaptchaInputCanceled -= self.captcha_onCaptchaInputCanceled
        game_control.g_instance.gameSession.onTimeTillBan -= self.gs_onTillBanNotification
        game_control.g_instance.rentals.onRentChangeNotify -= self.rc_onRentChange
        game_control.g_instance.igr.onIgrTypeChanged -= self.igr_onRoomChange
        unitMgr = getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined -= self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft -= self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored -= self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived -= self.unitMgr_onUnitErrorReceived
        unitBrowser = getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived -= self.unitBrowser_onErrorReceived
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortResponseReceived -= self.fortMgr_onFortResponseReceived
            fortMgr.onFortStateChanged -= self.forMgr_onFortStateChanged
        g_prbCtrlEvents.clear()

    def onCompanyStateChanged(self, _):
        if not g_prbLoader.getDispatcher().getPrbFunctional().hasLockedState():
            g_eventDispatcher.updateUI()

    def _setRequestCtx(self, ctx):
        result = True
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            result = False
        else:
            self.__requestCtx = ctx
        return result

    def _clear(self, woEvents = False):
        if self.__requestCtx:
            self.__requestCtx.clear()
            self.__requestCtx = None
        if self.__collection is not None:
            self.__collection.clear(woEvents=woEvents)
            self.__collection = None
        if self.__factories is not None:
            self.__factories.clear()
            self.__factories = None
        g_eventDispatcher.removeSpecBattlesFromCarousel()
        self._globalListeners.clear()
        return

    def pe_onArenaJoinFailure(self, errorCode, _):
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)

    def pe_onKickedFromArena(self, reasonCode):
        self.__collection.reset()
        SystemMessages.pushMessage(messages.getKickReasonMessage(reasonCode), type=SystemMessages.SM_TYPE.Error)

    def pe_onPrebattleAutoInvitesChanged(self):
        if GUI_SETTINGS.specPrebatlesVisible:
            isHidden = areSpecBattlesHidden()
            if isHidden:
                g_eventDispatcher.removeSpecBattlesFromCarousel()
            else:
                g_eventDispatcher.addSpecBattlesToCarousel()
        g_eventDispatcher.updateUI()

    def pe_onPrebattleJoined(self):
        clientPrb = getClientPrebattle()
        if clientPrb:
            prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
            if prbFunctional:
                if self.__requestCtx and self.__requestCtx.getPrbType() == prbFunctional.getPrbType():
                    exit = FUNCTIONAL_EXIT.PREBATTLE
                else:
                    exit = FUNCTIONAL_EXIT.NO_FUNC
                prbFunctional.setExit(exit)
            else:
                LOG_ERROR('Prebattle functional is not found')
            self.__factories.createFunctional(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREBATTLE))
        else:
            LOG_ERROR('ClientPrebattle is not defined')
            self.__requestCtx.stopProcessing(result=False)

    def pe_onPrebattleJoinFailure(self, errorCode):
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)
        self.__requestCtx.stopProcessing(result=False)
        g_eventDispatcher.updateUI()

    def pe_onPrebattleLeft(self):
        if self.__nextPrbFunctional:
            self.__nextPrbFunctional()
            self.__nextPrbFunctional = None
            return
        else:
            prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
            prbType = 0
            if prbFunctional and prbFunctional.getExit() not in (FUNCTIONAL_EXIT.NO_FUNC,
             FUNCTIONAL_EXIT.BATTLE_TUTORIAL,
             FUNCTIONAL_EXIT.RANDOM,
             FUNCTIONAL_EXIT.SWITCH,
             FUNCTIONAL_EXIT.SQUAD,
             FUNCTIONAL_EXIT.FALLOUT):
                prbType = prbFunctional.getPrbType()
            self._changePrbFunctional(prbType=prbType, stop=False)
            return

    def pe_onKickedFromPrebattle(self, _):
        self._changePrbFunctional(funcExit=FUNCTIONAL_EXIT.NO_FUNC, stop=False)

    def gs_onTillBanNotification(self, isPlayTimeBan, timeTillBlock):
        if isParentControlActivated():
            self.__collection.reset()
            key = '#system_messages:gameSessionControl/korea/{0:>s}'
            if isPlayTimeBan:
                SystemMessages.g_instance.pushI18nMessage(key.format('playTimeNotification'), timeTillBlock, type=SystemMessages.SM_TYPE.Warning)
            else:
                gameSession = game_control.g_instance.gameSession
                notifyStartTime, blockTime = gameSession.getCurfewBlockTime()
                formatter = lambda t: time.strftime('%H:%M', time.localtime(t))
                SystemMessages.g_instance.pushI18nMessage(key.format('midnightNotification'), type=SystemMessages.SM_TYPE.Warning, preBlockTime=formatter(notifyStartTime), blockTime=formatter(blockTime))

    def rc_onRentChange(self, vehicles):
        if g_currentVehicle.isPresent() and g_currentVehicle.item.intCD in vehicles and g_currentVehicle.isDisabledInRent() and g_currentVehicle.isInPrebattle():
            self.__collection.reset()

    def igr_onRoomChange(self, roomType, _):
        if roomType != IGR_TYPE.PREMIUM:
            if g_currentVehicle.isPremiumIGR() and g_currentVehicle.isInPrebattle():
                self.__collection.reset()

    def captcha_onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(False)

    def ctrl_onPrebattleIntroModeJoined(self, prbType, isLeaving):
        if not isLeaving:
            self._changePrbFunctional(funcExit=FUNCTIONAL_EXIT.INTRO_PREBATTLE, prbType=prbType)
        else:
            self.__nextPrbFunctional = partial(self._changePrbFunctional, prbType=prbType)

    def ctrl_onPrebattleIntroModeLeft(self):
        self._changePrbFunctional()

    def ctrl_onPrebattleInited(self):
        self.__requestCtx.stopProcessing(result=True)
        self.__factories.createFunctional(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREBATTLE, init={'ctx': self.__requestCtx}))
        g_eventDispatcher.updateUI()

    def ctrl_onUnitIntroModeJoined(self, prbType, modeFlags):
        self._changeUnitFunctional(funcExit=FUNCTIONAL_EXIT.INTRO_UNIT, prbType=prbType, modeFlags=modeFlags)

    def ctrl_onUnitIntroModeLeft(self):
        self._changeUnitFunctional()

    def ctrl_onPreQueueFunctionalCreated(self, queueType, doAction = False, action = None):
        self.__factories.createFunctional(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREQUEUE, create={'queueType': queueType}))
        g_prbCtrlEvents.onPreQueueFunctionalChanged()
        if action and doAction:
            preQueueFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREQUEUE)
            if preQueueFunctional:
                preQueueFunctional.doAction(action, dispatcher=self)
            else:
                LOG_ERROR('PreQueue functional is not found')
        g_eventDispatcher.updateUI()

    def ctrl_onPreQueueFunctionalDestroyed(self):
        self.ctrl_onPreQueueFunctionalCreated(None)
        return

    def unitMgr_onUnitJoined(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if unitFunctional and unitFunctional.getID() == unitMgrID and unitFunctional.getUnitIdx() == unitIdx:
            unitFunctional.rejoin()
        else:
            self._changeUnitFunctional(funcExit=FUNCTIONAL_EXIT.UNIT)

    def unitMgr_onUnitLeft(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        prbType = 0
        update = True
        if unitFunctional and unitFunctional.getExit() == FUNCTIONAL_EXIT.INTRO_UNIT:
            prbType = unitFunctional.getPrbType()
            update = False
        self._changeUnitFunctional(prbType=prbType)
        if update:
            g_eventDispatcher.updateUI()

    def unitMgr_onUnitRestored(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        flags = unitFunctional.getFlags()
        pInfo = unitFunctional.getPlayerInfo()
        if flags.isInPreArena() and pInfo.isInSlot:
            g_eventDispatcher.loadHangar()

    def unitMgr_onUnitErrorReceived(self, requestID, unitMgrID, unitIdx, errorCode, errorString):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if unitFunctional:
            unitFunctional.setLastError(errorCode)
        else:
            LOG_ERROR('Unit functional is not found')
        if errorCode not in IGNORED_UNIT_MGR_ERRORS:
            msgType, msgBody = messages.getUnitMessage(errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)
            if errorCode in RETURN_INTRO_UNIT_MGR_ERRORS and unitFunctional:
                unitFunctional.setExit(FUNCTIONAL_EXIT.INTRO_UNIT)
            self.__requestCtx.stopProcessing(result=False)
            g_eventDispatcher.updateUI()

    def unitBrowser_onErrorReceived(self, errorCode, errorString):
        if errorCode not in IGNORED_UNIT_BROWSER_ERRORS:
            msgType, msgBody = messages.getUnitBrowserMessage(errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)

    def forMgr_onFortStateChanged(self):
        g_eventDispatcher.updateUI()

    def fortMgr_onFortResponseReceived(self, requestID, resultCode, _):
        self.__requestCtx.stopProcessing(result=resultCode in (FORT_ERROR.OK,))
        g_eventDispatcher.updateUI()

    def _changePrbFunctional(self, funcExit = None, prbType = 0, stop = True):
        if funcExit is not None:
            prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
            if prbFunctional:
                prbFunctional.setExit(funcExit)
            else:
                LOG_ERROR('Prebattle functional is not found')
        self.__factories.createFunctional(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREBATTLE, prbType))
        if stop:
            self.__requestCtx.stopProcessing(result=True)
        return

    def _changeUnitFunctional(self, funcExit = None, prbType = 0, modeFlags = UNIT_MODE_FLAGS.UNDEFINED):
        if funcExit is not None:
            unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
            if unitFunctional:
                unitFunctional.setExit(funcExit)
            else:
                LOG_ERROR('Unit functional is not found')
        self.__factories.createFunctional(self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.UNIT, prbType, create={'modeFlags': modeFlags}, init={'ctx': self.__requestCtx}))
        self.__requestCtx.stopProcessing(result=True)
        return

    def _validateJoinOp(self, ctx):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            return False
        for func in self.__collection.getIterator():
            if func.isPlayerJoined(ctx):
                LOG_DEBUG('Player already joined', ctx)
                func.showGUI()
                return False
            if func.hasLockedState():
                SystemMessages.pushI18nMessage('#system_messages:prebattle/hasLockedState', type=SystemMessages.SM_TYPE.Warning)
                return False

        return True

    @process
    def _doUnlock(self):
        yield self.unlock(FUNCTIONAL_EXIT.RANDOM, True)

    @process
    def _doSelect(self, entry):
        yield self.select(entry)
Ejemplo n.º 13
0
class HistoricalQueueFunctional(PreQueueFunctional, IStatefulFunctional):

    def __init__(self, settings = None):
        super(HistoricalQueueFunctional, self).__init__(QUEUE_TYPE.HISTORICAL, {QUEUE_EVENT_TYPE.ENQUEUED: g_playerEvents.onEnqueuedHistorical,
         QUEUE_EVENT_TYPE.DEQUEUED: g_playerEvents.onDequeuedHistorical,
         QUEUE_EVENT_TYPE.ENQUEUE_ERROR: g_playerEvents.onEnqueueHistoricalFailure,
         QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE: g_playerEvents.onKickedFromHistoricalQueue,
         QUEUE_EVENT_TYPE.KICKED_FROM_ARENA: g_playerEvents.onKickedFromArena}, settings=settings)
        self.__requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx = None):
        result = super(HistoricalQueueFunctional, self).init(ctx=ctx)
        g_eventDispatcher.loadHistoryBattles()
        g_eventsCache.onSyncCompleted += self.onEventsCacheResync
        g_eventBus.addListener(events.ChannelCarouselEvent.CAROUSEL_INITED, self.__handleCarouselInited, scope=EVENT_BUS_SCOPE.LOBBY)
        g_gameCtrl.captcha.onCaptchaInputCanceled += self.onCaptchaInputCanceled
        result = FUNCTIONAL_INIT_RESULT.addIfNot(result, FUNCTIONAL_INIT_RESULT.LOAD_WINDOW)
        return result

    def fini(self, woEvents = False):
        self.__requestCtx = None
        if not woEvents:
            g_eventDispatcher.unloadHistoryBattles()
        else:
            g_eventDispatcher.removeHistoryBattlesFromCarousel()
        g_gameCtrl.captcha.onCaptchaInputCanceled -= self.onCaptchaInputCanceled
        g_eventBus.removeListener(events.ChannelCarouselEvent.CAROUSEL_INITED, self.__handleCarouselInited, scope=EVENT_BUS_SCOPE.LOBBY)
        g_eventDispatcher.unloadHistoryBattles()
        g_eventsCache.onSyncCompleted -= self.onEventsCacheResync
        g_currentVehicle.setHistoricalBattle(None)
        super(HistoricalQueueFunctional, self).fini(woEvents=woEvents)
        return

    def getStates(self):
        return ({'isInHistoricalQueue': True}, dict(self._settings))

    def isInQueue(self):
        return isInHistoricalQueue()

    def showGUI(self):
        g_eventDispatcher.loadHistoryBattles()

    @process
    def doLeaveAction(self, dispatcher, ctx = None, showConfirmation = True):
        meta = self.getConfirmDialogMeta()
        if meta is not None:
            isConfirmed = yield DialogsInterface.showDialog(meta)
        else:
            isConfirmed = yield lambda callback: callback(True)
        if isConfirmed:
            super(HistoricalQueueFunctional, self).doLeaveAction(dispatcher, ctx=None)
        return

    def join(self, ctx, callback = None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if isParentControlActivated():
            g_eventDispatcher.showParentControlNotification()
            if callback:
                callback(False)
            return
        if not hasattr(BigWorld.player(), 'enqueueHistorical'):
            if callback:
                callback(False)
            LOG_ERROR('Player can not join to history queue')
            return
        self.__requestCtx = ctx
        self.__requestCtx.startProcessing(callback)
        invID = ctx.getVehicleInventoryID()
        histBattleID = ctx.getHistBattleID()
        isCreditsAmmo = ctx.getIsCreditsAmmo()
        BigWorld.player().enqueueHistorical(invID, histBattleID=histBattleID, isCreditsAmmo=isCreditsAmmo)
        LOG_DEBUG('Player is joining to historical queue', ctx)

    def leave(self, ctx, callback = None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if hasattr(BigWorld.player(), 'dequeueHistorical'):
            if self.isInQueue():
                self.__requestCtx = ctx
                self.__requestCtx.startProcessing(callback)
                BigWorld.player().dequeueHistorical()
            else:
                super(HistoricalQueueFunctional, self).leave(ctx, callback)
        else:
            if callback:
                callback(False)
            LOG_ERROR('Player can not exit from random queue')

    def getItemData(self):
        battleID = self.getSetting(PREQUEUE_SETTING_NAME.BATTLE_ID)
        return g_eventsCache.getHistoricalBattles().get(battleID)

    def canPlayerDoAction(self):
        histBattleID = self.getSetting(PREQUEUE_SETTING_NAME.BATTLE_ID)
        vehicleID = g_currentVehicle.item.intCD if g_currentVehicle.isPresent() else None
        historicalBattle = g_eventsCache.getHistoricalBattles().get(histBattleID)
        priceIndex, _ = self.getSelectedPrice(histBattleID, vehicleID)
        if historicalBattle is not None and vehicleID is not None:
            if historicalBattle.isFuture():
                return (False, '')
            if not historicalBattle.canParticipateWith(vehicleID):
                return (False, '')
            prices = historicalBattle.getShellsLayoutPrice(vehicleID)
            selected = priceIndex if priceIndex is not None else len(prices) - 1
            enoughGold, enoughCredits = historicalBattle.getShellsLayoutPriceStatus(vehicleID)[selected]
            if not enoughGold or not enoughCredits:
                return (False, '')
            return super(HistoricalQueueFunctional, self).canPlayerDoAction()
        else:
            return (False, '')

    def doAction(self, action = None, dispatcher = None):
        result = False
        if not self.isInQueue():
            histBattleID = self.getSetting(PREQUEUE_SETTING_NAME.BATTLE_ID)
            selectedVehicleID = self.getSetting(PREQUEUE_SETTING_NAME.SELECTED_VEHICLE_ID)
            _, isCreditsAmmo = self.getSelectedPrice(histBattleID, selectedVehicleID)
            self.join(pre_queue_ctx.JoinHistoricalQueueCtx(histBattleID, isCreditsAmmo, waitingID='prebattle/join'))
        else:
            self.leave(pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))
        return result

    def doSelectAction(self, action):
        result = False
        if action.actionName == PREBATTLE_ACTION_NAME.HISTORICAL:
            g_eventDispatcher.showHistoryBattlesWindow()
            result = True
        return result

    def onEnqueued(self, *args):
        super(HistoricalQueueFunctional, self).onEnqueued(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadBattleQueue()
        g_eventDispatcher.updateUI()

    def onDequeued(self, *args):
        super(HistoricalQueueFunctional, self).onDequeued(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        self.showGUI()
        self.__checkAvailability()

    def onEnqueueError(self, errorCode, _):
        super(HistoricalQueueFunctional, self).onEnqueueError(errorCode, _)
        self.__requestCtx.stopProcessing(False)
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)

    def onKickedFromQueue(self, *args):
        super(HistoricalQueueFunctional, self).onKickedFromQueue(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        SystemMessages.pushMessage(messages.getKickReasonMessage('timeout'), type=SystemMessages.SM_TYPE.Warning)
        self.__checkAvailability()

    def onKickedFromArena(self, *args):
        super(HistoricalQueueFunctional, self).onKickedFromQueue(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        SystemMessages.pushMessage(messages.getKickReasonMessage('timeout'), type=SystemMessages.SM_TYPE.Warning)
        self.__checkAvailability()

    def onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(True)

    def getSelectedPrice(self, histBattleID, selectedVehicleID):
        return self.getSetting(PREQUEUE_SETTING_NAME.PRICE_INDEX, {}).get(histBattleID, {}).get(selectedVehicleID, (None, True))

    def onEventsCacheResync(self):
        if isInHistoricalQueue():
            return
        self.__checkAvailability()

    def _applySettings(self, settings):
        if PREQUEUE_SETTING_NAME.BATTLE_ID in settings:
            historicalBattle = g_eventsCache.getHistoricalBattles().get(settings[PREQUEUE_SETTING_NAME.BATTLE_ID])
            g_currentVehicle.setHistoricalBattle(historicalBattle)

    def __handleCarouselInited(self, _):
        g_eventDispatcher.addHistoryBattlesToCarousel()

    def __checkAvailability(self):
        if not g_eventsCache.getHistoricalBattles():
            LOG_DEBUG('No historical battles available.')
            self.leave(pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))
            return
        else:
            historicalBattle = g_eventsCache.getHistoricalBattles().get(self._settings[PREQUEUE_SETTING_NAME.BATTLE_ID])
            if historicalBattle is None:
                LOG_DEBUG('Currently selected historical battle is no longer available.')
                self.leave(pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))
            else:
                g_currentVehicle.setHistoricalBattle(historicalBattle)
            return
Ejemplo n.º 14
0
class _PrebattleDispatcher(object):
    def __init__(self):
        super(_PrebattleDispatcher, self).__init__()
        self.__requestCtx = None
        self.__collection = FunctionalCollection()
        self.__factories = ControlFactoryDecorator()
        self.__nextPrbFunctional = None
        self._globalListeners = set()

    def __del__(self):
        LOG_DEBUG('_PrebattleDispatcher deleted')

    def start(self, ctx):
        g_eventDispatcher.init(self)
        self.__requestCtx = PrbCtrlRequestCtx()
        result = self.__factories.start(
            self,
            CreateFunctionalCtx(CTRL_ENTITY_TYPE.UNKNOWN,
                                create={
                                    'queueType': ctx.getQueueType(),
                                    'settings': ctx.prbSettings
                                }))
        self._startListening()
        functional.initDevFunctional()
        if result & FUNCTIONAL_INIT_RESULT.LOAD_PAGE == 0:
            BigWorld.callback(0.001, lambda: g_eventDispatcher.loadHangar())
        g_eventDispatcher.updateUI()
        if GUI_SETTINGS.specPrebatlesVisible and not areSpecBattlesHidden():
            g_eventDispatcher.addSpecBattlesToCarousel()

    def stop(self):
        self.__nextPrbFunctional = None
        self._stopListening()
        functional.finiDevFunctional()
        self._clear(woEvents=True)
        g_eventDispatcher.fini()

    def getPrbFunctional(self):
        return self.__collection.getItem(CTRL_ENTITY_TYPE.PREBATTLE)

    def getUnitFunctional(self):
        return self.__collection.getItem(CTRL_ENTITY_TYPE.UNIT)

    def getPreQueueFunctional(self):
        return self.__collection.getItem(CTRL_ENTITY_TYPE.PREQUEUE)

    def getFunctional(self, ctrlType):
        return self.__collection.getItem(ctrlType)

    def getFunctionalCollection(self):
        return self.__collection

    def getControlFactories(self):
        return self.__factories

    def hasModalEntity(self):
        return self.__collection.hasModalEntity()

    def getFunctionalState(self):
        return self.__collection.getState(self.__factories)

    @async
    @process
    def create(self, ctx, callback=None):
        if ctx.getRequestType() == REQUEST_TYPE.CREATE:
            if not self.__requestCtx.isProcessing():
                result = yield self.unlock(ctx.getFuncExit(), True)
                if result:
                    entry = self.__factories.createEntry(ctx)
                    if entry:
                        LOG_DEBUG('Request to create', ctx)
                        self.__requestCtx = ctx
                        entry.create(ctx, callback=callback)
                    else:
                        LOG_ERROR('Entry not found', ctx)
                        if callback:
                            callback(False)
                elif callback:
                    callback(False)
            else:
                LOG_ERROR('Request is processing', self.__requestCtx)
                if callback:
                    callback(False)
                yield lambda callback=None: callback
        else:
            LOG_ERROR('Invalid context to create', ctx)
            if callback:
                callback(False)
            yield lambda callback=None: callback

    @async
    @process
    def join(self, ctx, callback=None):
        if self._validateJoinOp(ctx):
            result = yield self.unlock(ctx.getFuncExit(), ctx.isForced())
            ctx.setForced(result)
            if result:
                entry = self.__factories.createEntry(ctx)
                if entry:
                    LOG_DEBUG('Request to join', ctx)
                    self.__requestCtx = ctx
                    entry.join(ctx, callback=callback)
                else:
                    LOG_ERROR('Entry not found', ctx)
                    if callback:
                        callback(False)
        else:
            if callback:
                callback(False)
            yield lambda callback=None: callback

    @async
    def leave(self, ctx, callback=None):
        if ctx.getRequestType() is not REQUEST_TYPE.LEAVE:
            LOG_ERROR('Invalid context to leave prebattle/unit', ctx)
            if callback:
                callback(False)
            return
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        ctrlType = ctx.getCtrlType()
        formation = self.__collection.getItem(ctx.getCtrlType())
        if formation is not None:
            if formation.hasLockedState():
                if ctrlType == CTRL_ENTITY_TYPE.PREQUEUE:
                    entityType = formation.getQueueType()
                else:
                    entityType = formation.getPrbType()
                SystemMessages.pushI18nMessage(
                    '#system_messages:{0}'.format(
                        rally_dialog_meta.makeI18nKey(ctrlType, entityType,
                                                      'leaveDisabled')),
                    type=SystemMessages.SM_TYPE.Warning)
                if callback:
                    callback(False)
                return
            LOG_DEBUG('Request to leave formation', ctx)
            self.__requestCtx = ctx
            formation.leave(ctx, callback=callback)
        else:
            LOG_ERROR('Functional not found', ctx)
            if callback:
                callback(False)

    @async
    @process
    def unlock(self, funcExit, forced, callback=None):
        state = self.getFunctionalState()
        result = True
        if state.hasModalEntity and (not state.isIntroMode or forced) and not (
                funcExit == FUNCTIONAL_EXIT.FALLOUT and state.isInFallout()):
            factory = self.__factories.get(state.ctrlTypeID)
            result = False
            if factory:
                ctx = factory.createLeaveCtx(funcExit)
                if ctx:
                    meta = self.__collection.getItem(
                        state.ctrlTypeID).getConfirmDialogMeta(funcExit)
                    if meta:
                        result = yield DialogsInterface.showDialog(meta)
                    else:
                        result = True
                    if result:
                        result = yield self.leave(ctx)
                else:
                    LOG_ERROR('Can not create leave ctx', state)
            else:
                LOG_ERROR('Factory is not found', state)
        if getFalloutCtrl().isEnabled(
        ) and not funcExit == FUNCTIONAL_EXIT.SQUAD:
            g_eventDispatcher.unloadFallout()
        if callback:
            callback(result)
        yield lambda callback=None: callback

    @async
    @process
    def select(self, entry, callback=None):
        ctx = entry.makeDefCtx()
        if ctx and self._validateJoinOp(ctx):
            result = yield self.unlock(ctx.getFuncExit(), True)
            ctx.setForced(result)
            if result:
                LOG_DEBUG('Request to select', ctx)
                self.__requestCtx = ctx
                entry.select(ctx, callback=callback)
            elif callback:
                callback(False)
        else:
            if callback:
                callback(False)
            yield lambda callback=None: callback

    @async
    def sendPrbRequest(self, ctx, callback=None):
        prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
        if prbFunctional:
            prbFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('prbFunctional is not found', ctx)
            if callback:
                callback(False)

    @async
    def sendUnitRequest(self, ctx, callback=None):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if unitFunctional:
            unitFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR('unitFunctional is not found', ctx)
            if callback:
                callback(False)

    def exitFromQueue(self):
        self.__collection.exitFromQueue()

    def canPlayerDoAction(self):
        canDo, restriction = self.__collection.canPlayerDoAction(False)
        falloutCtrl = getFalloutCtrl()
        if canDo:
            if falloutCtrl.isEnabled():
                if falloutCtrl.getBattleType(
                ) == FALLOUT_BATTLE_TYPE.UNDEFINED:
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.FALLOUT_NOT_SELECTED
                elif not g_currentVehicle.isGroupReady():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_GROUP_IS_NOT_READY
            elif not g_currentVehicle.isReadyToFight():
                if not g_currentVehicle.isPresent():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT
                elif g_currentVehicle.isInBattle():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_BATTLE
                elif not g_currentVehicle.isCrewFull():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.CREW_NOT_FULL
                elif g_currentVehicle.isBroken():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_BROKEN
                elif g_currentVehicle.isFalloutOnly():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_FALLOUT_ONLY
                elif g_currentVehicle.isDisabledInRoaming():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_ROAMING
                elif g_currentVehicle.isDisabledInPremIGR():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_PREMIUM_IGR_ONLY
                elif g_currentVehicle.isDisabledInRent():
                    unit = self.getUnitFunctional()
                    if unit is not None and unit.getFlags().isInPreArena():
                        canDo = True
                    else:
                        canDo = False
                        if g_currentVehicle.isPremiumIGR():
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_IGR_RENTALS_IS_OVER
                        else:
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_RENTALS_IS_OVER
            if canDo:
                canDo, restriction = self.__collection.canPlayerDoAction(True)
        return (canDo, restriction)

    def getPlayerInfo(self):
        return self.__collection.getPlayerInfo(self.__factories)

    def doAction(self, action):
        if not g_currentVehicle.isPresent():
            SystemMessages.pushMessage(messages.getInvalidVehicleMessage(
                PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT),
                                       type=SystemMessages.SM_TYPE.Error)
            return False
        LOG_DEBUG('Do GUI action', action)
        return self.__collection.doAction(self, action, self.__factories)

    def doSelectAction(self, action):
        result = self.__collection.doSelectAction(action)
        if result:
            return True
        if action.actionName == PREBATTLE_ACTION_NAME.JOIN_RANDOM_QUEUE:
            self._doUnlock()
            return True
        entry = self.__factories.createEntryByAction(action.actionName)
        if entry:
            self._doSelect(entry)
            result = True
        return result

    def doLeaveAction(self, ctx):
        formation = self.__collection.getItem(ctx.getCtrlType())
        if formation:
            LOG_DEBUG('Request to leave', ctx)
            formation.doLeaveAction(self, ctx=ctx)
        else:
            LOG_ERROR('Functional is not found.', ctx)

    def addGlobalListener(self, listener):
        if isinstance(listener, IGlobalListener):
            listenerRef = weakref.ref(listener)
            if listenerRef not in self._globalListeners:
                self._globalListeners.add(listenerRef)
                self.__collection.addListener(listener)
            else:
                LOG_ERROR('Listener already added', listener)
        else:
            LOG_ERROR('Object is not extend IPrbListener', listener)

    def removeGlobalListener(self, listener):
        listenerRef = weakref.ref(listener)
        if listenerRef in self._globalListeners:
            self._globalListeners.remove(listenerRef)
        else:
            LOG_ERROR('Listener not found', listener)
        self.__collection.removeListener(listener)

    def getGUIPermissions(self):
        return self.__collection.getGUIPermissions()

    def _startListening(self):
        """
        Subscribes to player events.
        """
        g_playerEvents.onPrebattleJoined += self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure += self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft += self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle += self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure += self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena += self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged += self.pe_onPrebattleAutoInvitesChanged
        gameSession = game_control.g_instance.gameSession
        captchaCtrl = game_control.g_instance.captcha
        rentCtr = game_control.g_instance.rentals
        igrCtr = game_control.g_instance.igr
        if gameSession.lastBanMsg is not None:
            self.gs_onTillBanNotification(*gameSession.lastBanMsg)
        gameSession.onTimeTillBan += self.gs_onTillBanNotification
        rentCtr.onRentChangeNotify += self.rc_onRentChange
        captchaCtrl.onCaptchaInputCanceled += self.captcha_onCaptchaInputCanceled
        igrCtr.onIgrTypeChanged += self.igr_onRoomChange
        unitMgr = getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined += self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft += self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored += self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived += self.unitMgr_onUnitErrorReceived
        else:
            LOG_ERROR('Unit manager is not defined')
        unitBrowser = getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived += self.unitBrowser_onErrorReceived
        else:
            LOG_ERROR('Unit browser is not defined')
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortStateChanged += self.forMgr_onFortStateChanged
            fortMgr.onFortResponseReceived += self.fortMgr_onFortResponseReceived
        else:
            LOG_ERROR('Fort manager is not defined')
        g_prbCtrlEvents.onPrebattleIntroModeJoined += self.ctrl_onPrebattleIntroModeJoined
        g_prbCtrlEvents.onPrebattleIntroModeLeft += self.ctrl_onPrebattleIntroModeLeft
        g_prbCtrlEvents.onPrebattleInited += self.ctrl_onPrebattleInited
        g_prbCtrlEvents.onUnitIntroModeJoined += self.ctrl_onUnitIntroModeJoined
        g_prbCtrlEvents.onUnitIntroModeLeft += self.ctrl_onUnitIntroModeLeft
        g_prbCtrlEvents.onPreQueueFunctionalCreated += self.ctrl_onPreQueueFunctionalCreated
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed += self.ctrl_onPreQueueFunctionalDestroyed
        g_eventsCache.companies.onCompanyStateChanged += self.onCompanyStateChanged

    def _stopListening(self):
        """
        Unsubscribe from player events.
        """
        g_eventsCache.companies.onCompanyStateChanged -= self.onCompanyStateChanged
        g_playerEvents.onPrebattleJoined -= self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure -= self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft -= self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle -= self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure -= self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena -= self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged -= self.pe_onPrebattleAutoInvitesChanged
        game_control.g_instance.captcha.onCaptchaInputCanceled -= self.captcha_onCaptchaInputCanceled
        game_control.g_instance.gameSession.onTimeTillBan -= self.gs_onTillBanNotification
        game_control.g_instance.rentals.onRentChangeNotify -= self.rc_onRentChange
        game_control.g_instance.igr.onIgrTypeChanged -= self.igr_onRoomChange
        unitMgr = getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined -= self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft -= self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored -= self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived -= self.unitMgr_onUnitErrorReceived
        unitBrowser = getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived -= self.unitBrowser_onErrorReceived
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortResponseReceived -= self.fortMgr_onFortResponseReceived
            fortMgr.onFortStateChanged -= self.forMgr_onFortStateChanged
        g_prbCtrlEvents.clear()

    def onCompanyStateChanged(self, _):
        if not g_prbLoader.getDispatcher().getPrbFunctional().hasLockedState():
            g_eventDispatcher.updateUI()

    def _setRequestCtx(self, ctx):
        result = True
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            result = False
        else:
            self.__requestCtx = ctx
        return result

    def _clear(self, woEvents=False):
        if self.__requestCtx:
            self.__requestCtx.clear()
            self.__requestCtx = None
        if self.__collection is not None:
            self.__collection.clear(woEvents=woEvents)
            self.__collection = None
        if self.__factories is not None:
            self.__factories.clear()
            self.__factories = None
        g_eventDispatcher.removeSpecBattlesFromCarousel()
        self._globalListeners.clear()

    def pe_onArenaJoinFailure(self, errorCode, _):
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode),
                                   type=SystemMessages.SM_TYPE.Error)

    def pe_onKickedFromArena(self, reasonCode):
        self.__collection.reset()
        SystemMessages.pushMessage(messages.getKickReasonMessage(reasonCode),
                                   type=SystemMessages.SM_TYPE.Error)

    def pe_onPrebattleAutoInvitesChanged(self):
        if GUI_SETTINGS.specPrebatlesVisible:
            isHidden = areSpecBattlesHidden()
            if isHidden:
                g_eventDispatcher.removeSpecBattlesFromCarousel()
            else:
                g_eventDispatcher.addSpecBattlesToCarousel()
        g_eventDispatcher.updateUI()

    def pe_onPrebattleJoined(self):
        clientPrb = getClientPrebattle()
        if clientPrb:
            prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
            if prbFunctional:
                if self.__requestCtx and self.__requestCtx.getPrbType(
                ) == prbFunctional.getPrbType():
                    exit = FUNCTIONAL_EXIT.PREBATTLE
                else:
                    exit = FUNCTIONAL_EXIT.NO_FUNC
                prbFunctional.setExit(exit)
            else:
                LOG_ERROR('Prebattle functional is not found')
            self.__factories.createFunctional(
                self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREBATTLE))
        else:
            LOG_ERROR('ClientPrebattle is not defined')
            self.__requestCtx.stopProcessing(result=False)

    def pe_onPrebattleJoinFailure(self, errorCode):
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode),
                                   type=SystemMessages.SM_TYPE.Error)
        self.__requestCtx.stopProcessing(result=False)
        g_eventDispatcher.updateUI()

    def pe_onPrebattleLeft(self):
        if self.__nextPrbFunctional:
            self.__nextPrbFunctional()
            self.__nextPrbFunctional = None
            return
        prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
        prbType = 0
        if prbFunctional and prbFunctional.getExit() not in (
                FUNCTIONAL_EXIT.NO_FUNC, FUNCTIONAL_EXIT.BATTLE_TUTORIAL,
                FUNCTIONAL_EXIT.RANDOM, FUNCTIONAL_EXIT.SWITCH,
                FUNCTIONAL_EXIT.SQUAD, FUNCTIONAL_EXIT.FALLOUT):
            prbType = prbFunctional.getPrbType()
        self._changePrbFunctional(prbType=prbType, stop=False)

    def pe_onKickedFromPrebattle(self, _):
        self._changePrbFunctional(funcExit=FUNCTIONAL_EXIT.NO_FUNC, stop=False)

    def gs_onTillBanNotification(self, isPlayTimeBan, timeTillBlock):
        if isParentControlActivated():
            self.__collection.reset()
            key = '#system_messages:gameSessionControl/korea/{0:>s}'
            if isPlayTimeBan:
                SystemMessages.g_instance.pushI18nMessage(
                    key.format('playTimeNotification'),
                    timeTillBlock,
                    type=SystemMessages.SM_TYPE.Warning)
            else:
                gameSession = game_control.g_instance.gameSession
                notifyStartTime, blockTime = gameSession.getCurfewBlockTime()
                formatter = lambda t: time.strftime('%H:%M', time.localtime(t))
                SystemMessages.g_instance.pushI18nMessage(
                    key.format('midnightNotification'),
                    type=SystemMessages.SM_TYPE.Warning,
                    preBlockTime=formatter(notifyStartTime),
                    blockTime=formatter(blockTime))

    def rc_onRentChange(self, vehicles):
        if g_currentVehicle.isPresent(
        ) and g_currentVehicle.item.intCD in vehicles and g_currentVehicle.isDisabledInRent(
        ) and g_currentVehicle.isInPrebattle():
            self.__collection.reset()

    def igr_onRoomChange(self, roomType, _):
        if roomType != IGR_TYPE.PREMIUM:
            if g_currentVehicle.isPremiumIGR(
            ) and g_currentVehicle.isInPrebattle():
                self.__collection.reset()

    def captcha_onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(False)

    def ctrl_onPrebattleIntroModeJoined(self, prbType, isLeaving):
        if not isLeaving:
            self._changePrbFunctional(funcExit=FUNCTIONAL_EXIT.INTRO_PREBATTLE,
                                      prbType=prbType)
        else:
            self.__nextPrbFunctional = partial(self._changePrbFunctional,
                                               prbType=prbType)

    def ctrl_onPrebattleIntroModeLeft(self):
        self._changePrbFunctional()

    def ctrl_onPrebattleInited(self):
        self.__requestCtx.stopProcessing(result=True)
        self.__factories.createFunctional(
            self,
            CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREBATTLE,
                                init={'ctx': self.__requestCtx}))
        g_eventDispatcher.updateUI()

    def ctrl_onUnitIntroModeJoined(self, prbType, modeFlags):
        self._changeUnitFunctional(funcExit=FUNCTIONAL_EXIT.INTRO_UNIT,
                                   prbType=prbType,
                                   modeFlags=modeFlags)

    def ctrl_onUnitIntroModeLeft(self):
        self._changeUnitFunctional()

    def ctrl_onPreQueueFunctionalCreated(self,
                                         queueType,
                                         doAction=False,
                                         action=None):
        self.__factories.createFunctional(
            self,
            CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREQUEUE,
                                create={'queueType': queueType}))
        g_prbCtrlEvents.onPreQueueFunctionalChanged()
        if action and doAction:
            preQueueFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREQUEUE)
            if preQueueFunctional:
                preQueueFunctional.doAction(action, dispatcher=self)
            else:
                LOG_ERROR('PreQueue functional is not found')
        g_eventDispatcher.updateUI()

    def ctrl_onPreQueueFunctionalDestroyed(self):
        self.ctrl_onPreQueueFunctionalCreated(None)

    def unitMgr_onUnitJoined(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if unitFunctional and unitFunctional.getID(
        ) == unitMgrID and unitFunctional.getUnitIdx() == unitIdx:
            unitFunctional.rejoin()
        else:
            self._changeUnitFunctional(funcExit=FUNCTIONAL_EXIT.UNIT)

    def unitMgr_onUnitLeft(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        prbType = 0
        update = True
        if unitFunctional and unitFunctional.getExit(
        ) == FUNCTIONAL_EXIT.INTRO_UNIT:
            prbType = unitFunctional.getPrbType()
            update = False
        self._changeUnitFunctional(prbType=prbType)
        if update:
            g_eventDispatcher.updateUI()

    def unitMgr_onUnitRestored(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        flags = unitFunctional.getFlags()
        pInfo = unitFunctional.getPlayerInfo()
        if flags.isInPreArena() and pInfo.isInSlot:
            g_eventDispatcher.loadHangar()

    def unitMgr_onUnitErrorReceived(self, requestID, unitMgrID, unitIdx,
                                    errorCode, errorString):
        unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
        if unitFunctional:
            unitFunctional.setLastError(errorCode)
        else:
            LOG_ERROR('Unit functional is not found')
        if errorCode not in IGNORED_UNIT_MGR_ERRORS:
            msgType, msgBody = messages.getUnitMessage(errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)
            if errorCode in RETURN_INTRO_UNIT_MGR_ERRORS and unitFunctional:
                unitFunctional.setExit(FUNCTIONAL_EXIT.INTRO_UNIT)
            self.__requestCtx.stopProcessing(result=False)
            g_eventDispatcher.updateUI()

    def unitBrowser_onErrorReceived(self, errorCode, errorString):
        if errorCode not in IGNORED_UNIT_BROWSER_ERRORS:
            msgType, msgBody = messages.getUnitBrowserMessage(
                errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)

    def forMgr_onFortStateChanged(self):
        g_eventDispatcher.updateUI()

    def fortMgr_onFortResponseReceived(self, requestID, resultCode, _):
        self.__requestCtx.stopProcessing(
            result=resultCode in (FORT_ERROR.OK, ))
        g_eventDispatcher.updateUI()

    def _changePrbFunctional(self, funcExit=None, prbType=0, stop=True):
        if funcExit is not None:
            prbFunctional = self.getFunctional(CTRL_ENTITY_TYPE.PREBATTLE)
            if prbFunctional:
                prbFunctional.setExit(funcExit)
            else:
                LOG_ERROR('Prebattle functional is not found')
        self.__factories.createFunctional(
            self, CreateFunctionalCtx(CTRL_ENTITY_TYPE.PREBATTLE, prbType))
        if stop:
            self.__requestCtx.stopProcessing(result=True)

    def _changeUnitFunctional(self,
                              funcExit=None,
                              prbType=0,
                              modeFlags=UNIT_MODE_FLAGS.UNDEFINED):
        if funcExit is not None:
            unitFunctional = self.getFunctional(CTRL_ENTITY_TYPE.UNIT)
            if unitFunctional:
                unitFunctional.setExit(funcExit)
            else:
                LOG_ERROR('Unit functional is not found')
        self.__factories.createFunctional(
            self,
            CreateFunctionalCtx(CTRL_ENTITY_TYPE.UNIT,
                                prbType,
                                create={'modeFlags': modeFlags},
                                init={'ctx': self.__requestCtx}))
        self.__requestCtx.stopProcessing(result=True)

    def _validateJoinOp(self, ctx):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            return False
        for func in self.__collection.getIterator():
            if func.isPlayerJoined(ctx):
                LOG_DEBUG('Player already joined', ctx)
                func.showGUI()
                return False
            if func.hasLockedState():
                SystemMessages.pushI18nMessage(
                    '#system_messages:prebattle/hasLockedState',
                    type=SystemMessages.SM_TYPE.Warning)
                return False

        return True

    @process
    def _doUnlock(self):
        yield self.unlock(FUNCTIONAL_EXIT.RANDOM, True)

    @process
    def _doSelect(self, entry):
        yield self.select(entry)
Ejemplo n.º 15
0
class EventBattlesQueueFunctional(PreQueueFunctional):

    def __init__(self, settings = None):
        super(EventBattlesQueueFunctional, self).__init__(QUEUE_TYPE.EVENT_BATTLES, {QUEUE_EVENT_TYPE.ENQUEUED: g_playerEvents.onEnqueuedEventBattles,
         QUEUE_EVENT_TYPE.DEQUEUED: g_playerEvents.onDequeuedEventBattles,
         QUEUE_EVENT_TYPE.ENQUEUE_ERROR: g_playerEvents.onEnqueueEventBattlesFailure,
         QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE: g_playerEvents.onKickedFromEventBattles,
         QUEUE_EVENT_TYPE.KICKED_FROM_ARENA: g_playerEvents.onKickedFromArena}, settings=settings)
        self.__requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx = None):
        result = super(EventBattlesQueueFunctional, self).init(ctx)
        g_gameCtrl.captcha.onCaptchaInputCanceled += self.onCaptchaInputCanceled
        if self.isInQueue():
            g_eventDispatcher.loadBattleQueue()
            result = FUNCTIONAL_INIT_RESULT.addIfNot(result, FUNCTIONAL_INIT_RESULT.LOAD_PAGE)
        return result

    def fini(self, woEvents = False):
        self.__requestCtx = None
        g_gameCtrl.captcha.onCaptchaInputCanceled -= self.onCaptchaInputCanceled
        super(EventBattlesQueueFunctional, self).fini(woEvents)

    @groupAmmoCheck
    def join(self, ctx, callback = None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if isParentControlActivated():
            g_eventDispatcher.showParentControlNotification()
            if callback:
                callback(False)
            return
        if not hasattr(BigWorld.player(), 'enqueueEventBattles'):
            if callback:
                callback(False)
            LOG_ERROR('Player can not join to event battles queue')
            return
        self.__requestCtx = ctx
        self.__requestCtx.startProcessing(callback)
        BigWorld.player().enqueueEventBattles(ctx.getVehicleInventoryIDs(), ctx.getBattleType())
        LOG_DEBUG('Player is joining to event battles queue', ctx)

    def leave(self, ctx, callback = None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if hasattr(BigWorld.player(), 'dequeueEventBattles'):
            if self.isInQueue():
                self.__requestCtx = ctx
                self.__requestCtx.startProcessing(callback)
                BigWorld.player().dequeueEventBattles()
            else:
                super(EventBattlesQueueFunctional, self).leave(ctx, callback)
        else:
            if callback:
                callback(False)
            LOG_ERROR('Player can not exit from event battles queue')

    def isInQueue(self):
        return isInEventBattlesQueue()

    def hasGUIPage(self):
        return True

    def doAction(self, action = None, dispatcher = None):
        result = False

        def _leavePreQueue():
            self.leave(pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))

        if not self.isInQueue():

            def _joinResponse(success):
                if not success:
                    _leavePreQueue()

            falloutCtrl = getFalloutCtrl()
            self.join(pre_queue_ctx.JoinEventBattlesQueueCtx(map(lambda v: v.invID, falloutCtrl.getSelectedVehicles()), falloutCtrl.getBattleType(), waitingID='prebattle/join'), callback=_joinResponse)
        else:
            _leavePreQueue()
        return result

    def onEnqueued(self):
        super(EventBattlesQueueFunctional, self).onEnqueued()
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadBattleQueue()
        g_eventDispatcher.updateUI()

    def onDequeued(self):
        super(EventBattlesQueueFunctional, self).onDequeued()
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()

    def onEnqueueError(self, errorCode, _):
        super(EventBattlesQueueFunctional, self).onEnqueueError(errorCode, _)
        self.__requestCtx.stopProcessing(False)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)

    def onKickedFromQueue(self):
        super(EventBattlesQueueFunctional, self).onKickedFromQueue()
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        SystemMessages.pushMessage(messages.getKickReasonMessage('timeout'), type=SystemMessages.SM_TYPE.Warning)

    def onKickedFromArena(self, errorCode):
        super(EventBattlesQueueFunctional, self).onKickedFromArena(errorCode)
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()

    def onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
Ejemplo n.º 16
0
 def __init__(self, queueType, subscriber, flags=FUNCTIONAL_FLAG.UNDEFINED):
     super(AccountQueueFunctional, self).__init__(queueType, subscriber,
                                                  flags)
     self._requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 17
0
class RandomQueueFunctional(PreQueueFunctional):

    def __init__(self, settings = None):
        super(RandomQueueFunctional, self).__init__(QUEUE_TYPE.RANDOMS, {QUEUE_EVENT_TYPE.ENQUEUED: g_playerEvents.onEnqueuedRandom,
         QUEUE_EVENT_TYPE.DEQUEUED: g_playerEvents.onDequeuedRandom,
         QUEUE_EVENT_TYPE.ENQUEUE_ERROR: g_playerEvents.onEnqueueRandomFailure,
         QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE: g_playerEvents.onKickedFromRandomQueue,
         QUEUE_EVENT_TYPE.KICKED_FROM_ARENA: g_playerEvents.onKickedFromArena}, settings=settings)
        self.__requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx = None):
        result = super(RandomQueueFunctional, self).init(ctx)
        g_gameCtrl.captcha.onCaptchaInputCanceled += self.onCaptchaInputCanceled
        if self.isInQueue():
            g_eventDispatcher.loadBattleQueue()
            result = FUNCTIONAL_INIT_RESULT.addIfNot(result, FUNCTIONAL_INIT_RESULT.LOAD_PAGE)
        return result

    def fini(self, woEvents = False):
        self.__requestCtx = None
        g_gameCtrl.captcha.onCaptchaInputCanceled -= self.onCaptchaInputCanceled
        super(RandomQueueFunctional, self).fini(woEvents)

    @vehicleAmmoCheck
    def join(self, ctx, callback = None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if isParentControlActivated():
            g_eventDispatcher.showParentControlNotification()
            if callback:
                callback(False)
            return
        if not hasattr(BigWorld.player(), 'enqueueRandom'):
            if callback:
                callback(False)
            LOG_ERROR('Player can not join to random queue')
            return
        mapID = ctx.getDemoArenaTypeID()
        if mapID:
            LOG_DEBUG('Demonstrator mapID:', ArenaType.g_cache[mapID].geometryName)
        self.__requestCtx = ctx
        self.__requestCtx.startProcessing(callback)
        BigWorld.player().enqueueRandom(ctx.getVehicleInventoryID(), gameplaysMask=ctx.getGamePlayMask(), arenaTypeID=mapID)
        LOG_DEBUG('Player is joining to random queue', ctx)

    def leave(self, ctx, callback = None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if hasattr(BigWorld.player(), 'dequeueRandom'):
            if self.isInQueue():
                self.__requestCtx = ctx
                self.__requestCtx.startProcessing(callback)
                BigWorld.player().dequeueRandom()
            else:
                super(RandomQueueFunctional, self).leave(ctx, callback)
        else:
            if callback:
                callback(False)
            LOG_ERROR('Player can not exit from random queue')

    def isInQueue(self):
        return isInRandomQueue()

    def hasGUIPage(self):
        return True

    def doAction(self, action = None, dispatcher = None):
        result = False

        def _leavePreQueue():
            self.leave(pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))

        if not self.isInQueue():

            def _joinResponse(success):
                if not success:
                    _leavePreQueue()

            self.join(pre_queue_ctx.JoinRandomQueueCtx(action.mapID if action else 0, waitingID='prebattle/join'), callback=_joinResponse)
        else:
            _leavePreQueue()
        return result

    def onEnqueued(self):
        super(RandomQueueFunctional, self).onEnqueued()
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadBattleQueue()
        g_eventDispatcher.updateUI()

    def onDequeued(self):
        super(RandomQueueFunctional, self).onDequeued()
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()

    def onEnqueueError(self, errorCode, _):
        super(RandomQueueFunctional, self).onEnqueueError(errorCode, _)
        self.__requestCtx.stopProcessing(False)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)

    def onKickedFromQueue(self):
        super(RandomQueueFunctional, self).onKickedFromQueue()
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        SystemMessages.pushMessage(messages.getKickReasonMessage('timeout'), type=SystemMessages.SM_TYPE.Warning)

    def onKickedFromArena(self, errorCode):
        super(RandomQueueFunctional, self).onKickedFromArena(errorCode)
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()

    def onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
Ejemplo n.º 18
0
class _PrebattleDispatcher(ListenersCollection):
    def __init__(self):
        super(_PrebattleDispatcher, self).__init__()
        self.__requestCtx = None
        self.__collection = FunctionalCollection()
        self.__factories = ControlFactoryDecorator()
        self.__nextPrbFunctional = None
        self._setListenerClass(IGlobalListener)
        return

    def __del__(self):
        LOG_DEBUG("_PrebattleDispatcher deleted")

    def start(self):
        g_eventDispatcher.init(self)
        result = self.__setFunctional(CreateFunctionalCtx())
        self.__requestCtx = PrbCtrlRequestCtx()
        self.__startListening()
        functional.initDevFunctional()
        if result & FUNCTIONAL_FLAG.LOAD_PAGE == 0:
            BigWorld.callback(0.001, lambda: g_eventDispatcher.loadHangar())
        g_eventDispatcher.updateUI()
        if GUI_SETTINGS.specPrebatlesVisible and not prb_getters.areSpecBattlesHidden():
            g_eventDispatcher.addSpecBattlesToCarousel()

    def stop(self):
        self.__nextPrbFunctional = None
        self.__stopListening()
        functional.finiDevFunctional()
        self.__clear(woEvents=True)
        g_eventDispatcher.fini()
        return

    def getPrbFunctional(self):
        return self.__collection.getItem(_CTRL_TYPE.PREBATTLE)

    def getUnitFunctional(self):
        return self.__collection.getItem(_CTRL_TYPE.UNIT)

    def getPreQueueFunctional(self):
        return self.__collection.getItem(_CTRL_TYPE.PREQUEUE)

    def getFunctional(self, ctrlType):
        return self.__collection.getItem(ctrlType)

    def getFunctionalCollection(self):
        return self.__collection

    def getControlFactories(self):
        return self.__factories

    def hasModalEntity(self):
        return self.__collection.hasModalEntity()

    def getFunctionalState(self):
        return self.__collection.getState(self.__factories)

    @async
    @process
    def create(self, ctx, callback=None):
        if ctx.getRequestType() == _RQ_TYPE.CREATE:
            if not self.__requestCtx.isProcessing():
                result = yield self.unlock(ctx)
                if result:
                    entry = self.__factories.createEntry(ctx)
                    if entry:
                        LOG_DEBUG("Request to create", ctx)
                        self.__requestCtx = ctx
                        entry.create(ctx, callback=callback)
                    else:
                        LOG_ERROR("Entry not found", ctx)
                        if callback is not None:
                            callback(False)
                elif callback is not None:
                    callback(False)
            else:
                LOG_ERROR("Request is processing", self.__requestCtx)
                if callback is not None:
                    callback(False)
                yield lambda callback=None: callback
        else:
            LOG_ERROR("Invalid context to create", ctx)
            if callback is not None:
                callback(False)
            yield lambda callback=None: callback
        return

    @async
    @process
    def join(self, ctx, callback=None):
        if self.__validateJoinOp(ctx):
            result = yield self.unlock(ctx)
            ctx.setForced(result)
            if result:
                entry = self.__factories.createEntry(ctx)
                if entry:
                    LOG_DEBUG("Request to join", ctx)
                    self.__requestCtx = ctx
                    entry.join(ctx, callback=callback)
                else:
                    LOG_ERROR("Entry not found", ctx)
                    if callback is not None:
                        callback(False)
        else:
            if callback is not None:
                callback(False)
            yield lambda callback=None: callback
        return

    @async
    def leave(self, ctx, callback=None):
        if ctx.getRequestType() != _RQ_TYPE.LEAVE:
            LOG_ERROR("Invalid context to leave prebattle/unit", ctx)
            if callback is not None:
                callback(False)
            return
        elif self.__requestCtx.isProcessing():
            LOG_ERROR("Request is processing", self.__requestCtx)
            if callback is not None:
                callback(False)
            return
        else:
            ctrlType = ctx.getCtrlType()
            formation = self.__collection.getItem(ctx.getCtrlType())
            if formation is not None:
                if formation.hasLockedState():
                    entityType = formation.getEntityType()
                    SystemMessages.pushI18nMessage(
                        messages.getLeaveDisabledMessage(ctrlType, entityType), type=SystemMessages.SM_TYPE.Warning
                    )
                    if callback is not None:
                        callback(False)
                    return
                LOG_DEBUG("Request to leave formation", ctx)
                self.__requestCtx = ctx
                formation.leave(ctx, callback=callback)
            else:
                LOG_ERROR("Functional not found", ctx)
                if callback is not None:
                    callback(False)
            return

    @async
    @process
    def unlock(self, unlockCtx, callback=None):
        state = self.getFunctionalState()
        result = True
        if not state.isIntroMode:
            canDoLeave = True
        elif unlockCtx.hasFlags(FUNCTIONAL_FLAG.SWITCH):
            if state.ctrlTypeID == unlockCtx.getCtrlType() and state.entityTypeID != unlockCtx.getEntityType():
                canDoLeave = True
                unlockCtx.removeFlags(FUNCTIONAL_FLAG.SWITCH)
            else:
                canDoLeave = False
        else:
            canDoLeave = True
        if canDoLeave:
            factory = self.__factories.get(state.ctrlTypeID)
            result = False
            if factory:
                ctx = factory.createLeaveCtx(unlockCtx.getFlags())
                if ctx:
                    meta = self.__collection.getConfirmDialogMeta(state.ctrlTypeID, unlockCtx)
                    if meta:
                        result = yield DialogsInterface.showDialog(meta)
                    else:
                        result = True
                    if result:
                        result = yield self.leave(ctx)
                else:
                    LOG_ERROR("Can not create leave ctx", state)
            else:
                LOG_ERROR("Factory is not found", state)
        if callback is not None:
            callback(result)
        yield lambda callback=None: callback
        return

    @async
    @process
    def select(self, entry, callback=None):
        ctx = entry.makeDefCtx()
        if ctx and self.__validateJoinOp(ctx):
            result = yield self.unlock(ctx)
            ctx.setForced(result)
            if result:
                LOG_DEBUG("Request to select", ctx)
                self.__requestCtx = ctx
                entry.select(ctx, callback=callback)
            elif callback is not None:
                callback(False)
        else:
            if callback is not None:
                callback(False)
            yield lambda callback=None: callback
        return

    @async
    def sendPrbRequest(self, ctx, callback=None):
        prbFunctional = self.getFunctional(_CTRL_TYPE.PREBATTLE)
        if prbFunctional:
            prbFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR("prbFunctional is not found", ctx)
            if callback is not None:
                callback(False)
        return

    @async
    def sendUnitRequest(self, ctx, callback=None):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        if unitFunctional:
            unitFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR("unitFunctional is not found", ctx)
            if callback is not None:
                callback(False)
        return

    @async
    def sendPreQueueRequest(self, ctx, callback=None):
        preQueueFunctional = self.getFunctional(_CTRL_TYPE.PREQUEUE)
        if preQueueFunctional is not None:
            preQueueFunctional.request(ctx, callback=callback)
        else:
            LOG_ERROR("preQueueFunctional is not found", ctx)
            if callback is not None:
                callback(False)
        return

    def exitFromQueue(self):
        self.__collection.exitFromQueue()

    def canPlayerDoAction(self):
        canDo, restriction = self.__collection.canPlayerDoAction(False)
        if canDo:
            if g_currentPreviewVehicle.isPresent():
                canDo = False
                restriction = PREBATTLE_RESTRICTION.PREVIEW_VEHICLE_IS_PRESENT
            elif not g_currentVehicle.isReadyToFight():
                if not g_currentVehicle.isPresent():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT
                elif g_currentVehicle.isInBattle():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_BATTLE
                elif not g_currentVehicle.isCrewFull():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.CREW_NOT_FULL
                elif g_currentVehicle.isBroken():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_BROKEN
                elif g_currentVehicle.isFalloutOnly() and not game_control.getFalloutCtrl().isSelected():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_FALLOUT_ONLY
                elif g_currentVehicle.isDisabledInRoaming():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_ROAMING
                elif g_currentVehicle.isDisabledInPremIGR():
                    canDo = False
                    restriction = PREBATTLE_RESTRICTION.VEHICLE_IN_PREMIUM_IGR_ONLY
                elif g_currentVehicle.isDisabledInRent():
                    unit = self.getUnitFunctional()
                    if unit is not None and unit.getFlags().isInPreArena():
                        canDo = True
                    else:
                        canDo = False
                        if g_currentVehicle.isPremiumIGR():
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_IGR_RENTALS_IS_OVER
                        else:
                            restriction = PREBATTLE_RESTRICTION.VEHICLE_RENTALS_IS_OVER
            if canDo:
                canDo, restriction = self.__collection.canPlayerDoAction(True)
        return (canDo, restriction)

    def getPlayerInfo(self):
        return self.__collection.getPlayerInfo(self.__factories)

    def doAction(self, action=None):
        if not g_currentVehicle.isPresent():
            SystemMessages.pushMessage(
                messages.getInvalidVehicleMessage(PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT),
                type=SystemMessages.SM_TYPE.Error,
            )
            return False
        LOG_DEBUG("Do GUI action", action)
        return self.__collection.doAction(self.__factories, action)

    def doSelectAction(self, action):
        result = self.__collection.doSelectAction(action)
        if result.isProcessed:
            if result.newEntry is not None:
                self.__doSelect(result.newEntry)
            return True
        else:
            entry = self.__factories.createEntryByAction(action)
            if entry is not None:
                self.__doSelect(entry)
                return True
            return False

    @process
    def doLeaveAction(self, ctx):
        meta = self.__collection.getConfirmDialogMeta(ctx.getCtrlType(), ctx)
        if meta is not None:
            isConfirmed = yield DialogsInterface.showDialog(meta)
        else:
            isConfirmed = yield lambda callback: callback(True)
        if isConfirmed:
            yield self.leave(ctx)
        return

    def getGUIPermissions(self):
        return self.__collection.getGUIPermissions()

    def onCompanyStateChanged(self, _):
        if not self.getPrbFunctional().hasLockedState():
            g_eventDispatcher.updateUI()

    def setRequestCtx(self, ctx):
        result = True
        if self.__requestCtx.isProcessing():
            LOG_ERROR("Request is processing", self.__requestCtx)
            result = False
        else:
            self.__requestCtx = ctx
        return result

    def pe_onArenaJoinFailure(self, errorCode, _):
        self.__collection.reset()
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)

    def pe_onKickedFromArena(self, reasonCode):
        self.__collection.reset()
        SystemMessages.pushMessage(messages.getKickReasonMessage(reasonCode), type=SystemMessages.SM_TYPE.Error)

    def pe_onPrebattleAutoInvitesChanged(self):
        if GUI_SETTINGS.specPrebatlesVisible:
            isHidden = prb_getters.areSpecBattlesHidden()
            if isHidden:
                g_eventDispatcher.removeSpecBattlesFromCarousel()
            else:
                g_eventDispatcher.addSpecBattlesToCarousel()
        g_eventDispatcher.updateUI()

    def pe_onPrebattleJoined(self):
        if prb_getters.getClientPrebattle() is not None:
            flags = self.__requestCtx.getFlags()
            self.__setFunctional(CreateFunctionalCtx(_CTRL_TYPE.PREBATTLE, flags=flags))
        else:
            LOG_ERROR("ClientPrebattle is not defined")
            self.__requestCtx.stopProcessing(result=False)
        return

    def pe_onPrebattleJoinFailure(self, errorCode):
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error)
        self.__requestCtx.stopProcessing(result=False)
        self.__requestCtx.clearFlags()
        g_eventDispatcher.updateUI()

    def pe_onPrebattleLeft(self):
        if self.__nextPrbFunctional is not None:
            self.__nextPrbFunctional()
            self.__nextPrbFunctional = None
            return
        else:
            flags = self.__requestCtx.getFlags()
            flags |= FUNCTIONAL_FLAG.LEAVE_ENTITY
            prbType = 0
            if flags & FUNCTIONAL_FLAG.SWITCH > 0:
                prbFunctional = self.getFunctional(_CTRL_TYPE.PREBATTLE)
                if prbFunctional is not None:
                    prbType = prbFunctional.getEntityType()
            self.__changePrbFunctional(flags=flags, prbType=prbType, stop=False)
            return

    def pe_onKickedFromPrebattle(self, _):
        self.__changePrbFunctional(stop=True)

    def gs_onTillBanNotification(self, isPlayTimeBan, timeTillBlock):
        if prb_getters.isParentControlActivated():
            self.__collection.reset()
            key = "#system_messages:gameSessionControl/korea/{0:>s}"
            if isPlayTimeBan:
                SystemMessages.g_instance.pushI18nMessage(
                    key.format("playTimeNotification"), timeTillBlock, type=SystemMessages.SM_TYPE.Warning
                )
            else:
                gameSession = game_control.g_instance.gameSession
                notifyStartTime, blockTime = gameSession.getCurfewBlockTime()
                formatter = lambda t: time.strftime("%H:%M", time.localtime(t))
                SystemMessages.g_instance.pushI18nMessage(
                    key.format("midnightNotification"),
                    type=SystemMessages.SM_TYPE.Warning,
                    preBlockTime=formatter(notifyStartTime),
                    blockTime=formatter(blockTime),
                )

    def rc_onRentChange(self, vehicles):
        if (
            g_currentVehicle.isPresent()
            and g_currentVehicle.item.intCD in vehicles
            and g_currentVehicle.isDisabledInRent()
            and g_currentVehicle.isInPrebattle()
        ):
            self.__collection.reset()

    def igr_onRoomChange(self, roomType, _):
        if roomType != IGR_TYPE.PREMIUM:
            if g_currentVehicle.isPremiumIGR() and g_currentVehicle.isInPrebattle():
                self.__collection.reset()

    def ctrl_onPrebattleIntroModeJoined(self, prbType, isLeaving):
        flags = self.__requestCtx.getFlags()
        if not isLeaving:
            self.__changePrbFunctional(flags=flags, prbType=prbType)
        else:
            self.__nextPrbFunctional = partial(self.__changePrbFunctional, flags=flags, prbType=prbType)

    def ctrl_onPrebattleIntroModeLeft(self):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_INTRO
        self.__changePrbFunctional(flags=flags)

    def ctrl_onPrebattleInited(self):
        self.__requestCtx.stopProcessing(result=True)
        self.__setFunctional(
            CreateFunctionalCtx(_CTRL_TYPE.PREBATTLE, flags=self.__requestCtx.getFlags(), initCtx=self.__requestCtx)
        )
        g_eventDispatcher.updateUI()

    def ctrl_onUnitIntroModeJoined(self, prbType, flags):
        self.__changeUnitFunctional(flags=flags, prbType=prbType)

    def ctrl_onUnitIntroModeLeft(self):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_INTRO
        self.__changeUnitFunctional(flags=flags)

    def ctrl_onPreQueueFunctionalCreated(self, queueType):
        self.__changePreQueueFunctional(flags=self.__requestCtx.getFlags(), queueType=queueType)
        g_eventDispatcher.updateUI()

    def ctrl_onPreQueueFunctionalDestroyed(self):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_PRE_QUEUE
        self.__changePreQueueFunctional(flags=flags)

    def unitMgr_onUnitJoined(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        if (
            unitFunctional is not None
            and unitFunctional.getID() == unitMgrID
            and unitFunctional.getUnitIdx() == unitIdx
        ):
            unitFunctional.rejoin()
        else:
            if unitFunctional is not None:
                prbType = unitFunctional.getEntityType()
            else:
                prbType = 0
            self.__changeUnitFunctional(flags=self.__requestCtx.getFlags(), prbType=prbType)
        return

    def unitMgr_onUnitLeft(self, unitMgrID, unitIdx):
        flags = self.__requestCtx.getFlags()
        flags |= FUNCTIONAL_FLAG.LEAVE_ENTITY
        prbType = 0
        if flags & FUNCTIONAL_FLAG.SWITCH > 0:
            unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
            if unitFunctional is not None:
                prbType = unitFunctional.getEntityType()
        self.__changeUnitFunctional(flags=flags, prbType=prbType)
        g_eventDispatcher.updateUI()
        return

    def unitMgr_onUnitRestored(self, unitMgrID, unitIdx):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        flags = unitFunctional.getFlags()
        pInfo = unitFunctional.getPlayerInfo()
        if flags.isInPreArena() and pInfo.isInSlot:
            g_eventDispatcher.loadHangar()

    def unitMgr_onUnitErrorReceived(self, requestID, unitMgrID, unitIdx, errorCode, errorString):
        unitFunctional = self.getFunctional(_CTRL_TYPE.UNIT)
        if unitFunctional is not None:
            unitFunctional.setLastError(errorCode)
            if errorCode in RETURN_INTRO_UNIT_MGR_ERRORS and unitFunctional.canSwitchToIntro():
                self.__requestCtx.addFlags(FUNCTIONAL_FLAG.SWITCH)
            if errorCode == UNIT_ERROR.CANT_PICK_LEADER:
                self.__requestCtx.removeFlags(FUNCTIONAL_FLAG.SWITCH)
            elif errorCode == UNIT_ERROR.REMOVED_PLAYER:
                if (
                    self.__requestCtx.getCtrlType() == _CTRL_TYPE.UNIT
                    and unitFunctional.getEntityType() != self.__requestCtx.getEntityType()
                ):
                    self.__requestCtx.removeFlags(FUNCTIONAL_FLAG.SWITCH)
        else:
            LOG_ERROR("Unit functional is not found")
        if errorCode not in IGNORED_UNIT_MGR_ERRORS:
            msgType, msgBody = messages.getUnitMessage(errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)
            self.__requestCtx.stopProcessing(result=False)
            g_eventDispatcher.updateUI()
        return

    def unitBrowser_onErrorReceived(self, errorCode, errorString):
        if errorCode not in IGNORED_UNIT_BROWSER_ERRORS:
            msgType, msgBody = messages.getUnitBrowserMessage(errorCode, errorString)
            SystemMessages.pushMessage(msgBody, type=msgType)

    def forMgr_onFortStateChanged(self):
        g_eventDispatcher.updateUI()

    def fortMgr_onFortResponseReceived(self, requestID, resultCode, _):
        self.__requestCtx.stopProcessing(result=resultCode in (FORT_ERROR.OK,))
        g_eventDispatcher.updateUI()

    def __startListening(self):
        """
        Subscribes to player events.
        """
        g_playerEvents.onPrebattleJoined += self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure += self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft += self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle += self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure += self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena += self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged += self.pe_onPrebattleAutoInvitesChanged
        gameSession = game_control.g_instance.gameSession
        rentCtr = game_control.g_instance.rentals
        igrCtr = game_control.g_instance.igr
        if gameSession.lastBanMsg is not None:
            self.gs_onTillBanNotification(*gameSession.lastBanMsg)
        gameSession.onTimeTillBan += self.gs_onTillBanNotification
        rentCtr.onRentChangeNotify += self.rc_onRentChange
        igrCtr.onIgrTypeChanged += self.igr_onRoomChange
        unitMgr = prb_getters.getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined += self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft += self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored += self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived += self.unitMgr_onUnitErrorReceived
        else:
            LOG_ERROR("Unit manager is not defined")
        unitBrowser = prb_getters.getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived += self.unitBrowser_onErrorReceived
        else:
            LOG_ERROR("Unit browser is not defined")
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortStateChanged += self.forMgr_onFortStateChanged
            fortMgr.onFortResponseReceived += self.fortMgr_onFortResponseReceived
        else:
            LOG_ERROR("Fort manager is not defined")
        g_prbCtrlEvents.onPrebattleIntroModeJoined += self.ctrl_onPrebattleIntroModeJoined
        g_prbCtrlEvents.onPrebattleIntroModeLeft += self.ctrl_onPrebattleIntroModeLeft
        g_prbCtrlEvents.onPrebattleInited += self.ctrl_onPrebattleInited
        g_prbCtrlEvents.onUnitIntroModeJoined += self.ctrl_onUnitIntroModeJoined
        g_prbCtrlEvents.onUnitIntroModeLeft += self.ctrl_onUnitIntroModeLeft
        g_prbCtrlEvents.onPreQueueFunctionalCreated += self.ctrl_onPreQueueFunctionalCreated
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed += self.ctrl_onPreQueueFunctionalDestroyed
        g_eventsCache.companies.onCompanyStateChanged += self.onCompanyStateChanged
        return

    def __stopListening(self):
        """
        Unsubscribe from player events.
        """
        g_eventsCache.companies.onCompanyStateChanged -= self.onCompanyStateChanged
        g_playerEvents.onPrebattleJoined -= self.pe_onPrebattleJoined
        g_playerEvents.onPrebattleJoinFailure -= self.pe_onPrebattleJoinFailure
        g_playerEvents.onPrebattleLeft -= self.pe_onPrebattleLeft
        g_playerEvents.onKickedFromPrebattle -= self.pe_onKickedFromPrebattle
        g_playerEvents.onArenaJoinFailure -= self.pe_onArenaJoinFailure
        g_playerEvents.onKickedFromArena -= self.pe_onKickedFromArena
        g_playerEvents.onPrebattleAutoInvitesChanged -= self.pe_onPrebattleAutoInvitesChanged
        game_control.g_instance.gameSession.onTimeTillBan -= self.gs_onTillBanNotification
        game_control.g_instance.rentals.onRentChangeNotify -= self.rc_onRentChange
        game_control.g_instance.igr.onIgrTypeChanged -= self.igr_onRoomChange
        unitMgr = prb_getters.getClientUnitMgr()
        if unitMgr:
            unitMgr.onUnitJoined -= self.unitMgr_onUnitJoined
            unitMgr.onUnitLeft -= self.unitMgr_onUnitLeft
            unitMgr.onUnitRestored -= self.unitMgr_onUnitRestored
            unitMgr.onUnitErrorReceived -= self.unitMgr_onUnitErrorReceived
        unitBrowser = prb_getters.getClientUnitBrowser()
        if unitBrowser:
            unitBrowser.onErrorReceived -= self.unitBrowser_onErrorReceived
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortResponseReceived -= self.fortMgr_onFortResponseReceived
            fortMgr.onFortStateChanged -= self.forMgr_onFortStateChanged
        g_prbCtrlEvents.clear()

    def __clear(self, woEvents=False):
        if self.__requestCtx:
            self.__requestCtx.clear()
            self.__requestCtx = None
        if self.__collection is not None:
            self.__collection.clear(woEvents=woEvents)
            self.__collection = None
        if self.__factories is not None:
            self.__factories.clear()
            self.__factories = None
        g_eventDispatcher.removeSpecBattlesFromCarousel()
        self.clear()
        return

    def __changePrbFunctional(self, flags=FUNCTIONAL_FLAG.UNDEFINED, prbType=0, stop=True):
        self.__setFunctional(CreateFunctionalCtx(_CTRL_TYPE.PREBATTLE, prbType, flags=flags))
        if stop:
            self.__requestCtx.stopProcessing(result=True)

    def __changeUnitFunctional(self, flags=FUNCTIONAL_FLAG.UNDEFINED, prbType=0):
        self.__setFunctional(CreateFunctionalCtx(_CTRL_TYPE.UNIT, prbType, flags=flags, initCtx=self.__requestCtx))
        self.__requestCtx.stopProcessing(result=True)

    def __changePreQueueFunctional(self, flags=FUNCTIONAL_FLAG.UNDEFINED, queueType=0):
        self.__setFunctional(CreateFunctionalCtx(_CTRL_TYPE.PREQUEUE, queueType, flags=flags))
        self.__requestCtx.stopProcessing(result=True)

    def __validateJoinOp(self, ctx):
        if self.__requestCtx.isProcessing():
            LOG_ERROR("Request is processing", self.__requestCtx)
            return False
        for func in self.__collection.getIterator():
            if func.isPlayerJoined(ctx):
                LOG_DEBUG("Player already joined", ctx)
                func.showGUI(ctx)
                return False
            if func.hasLockedState():
                SystemMessages.pushI18nMessage(
                    "#system_messages:prebattle/hasLockedState", type=SystemMessages.SM_TYPE.Warning
                )
                return False

        return True

    @process
    def __doSelect(self, entry):
        yield self.select(entry)

    def __setFunctional(self, ctx):
        ctx.addFlags(self.__collection.getFunctionalFlags())
        items = []
        for created in self.__factories.createFunctional(ctx):
            if ctx.hasFlags(FUNCTIONAL_FLAG.SET_GLOBAL_LISTENERS):
                created.addMutualListeners(self)
            items.append(created)

        for item in items:
            ctrlType = item.getCtrlType()
            self.__collection.setFunctionalFlags(ctrlType, ctx.getFlags())
            flag = self.__collection.setItem(item.getCtrlType(), item, ctx.getInitCtx())
            ctx.addFlags(flag)

        LOG_DEBUG("Functionals have been updated", ctx.getFlagsToStrings())
        ctx.clear()
        return ctx.getFlags()
Ejemplo n.º 19
0
class HistoricalQueueFunctional(PreQueueFunctional, IStatefulFunctional):
    def __init__(self, settings=None):
        super(HistoricalQueueFunctional,
              self).__init__(QUEUE_TYPE.HISTORICAL, {
                  QUEUE_EVENT_TYPE.ENQUEUED:
                  g_playerEvents.onEnqueuedHistorical,
                  QUEUE_EVENT_TYPE.DEQUEUED:
                  g_playerEvents.onDequeuedHistorical,
                  QUEUE_EVENT_TYPE.ENQUEUE_ERROR:
                  g_playerEvents.onEnqueueHistoricalFailure,
                  QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE:
                  g_playerEvents.onKickedFromHistoricalQueue,
                  QUEUE_EVENT_TYPE.KICKED_FROM_ARENA:
                  g_playerEvents.onKickedFromArena
              },
                             settings=settings)
        self.__requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx=None):
        result = super(HistoricalQueueFunctional, self).init(ctx=ctx)
        g_eventDispatcher.loadHistoryBattles()
        g_eventsCache.onSyncCompleted += self.onEventsCacheResync
        g_eventBus.addListener(events.ChannelCarouselEvent.CAROUSEL_INITED,
                               self.__handleCarouselInited,
                               scope=EVENT_BUS_SCOPE.LOBBY)
        g_gameCtrl.captcha.onCaptchaInputCanceled += self.onCaptchaInputCanceled
        result = FUNCTIONAL_INIT_RESULT.addIfNot(
            result, FUNCTIONAL_INIT_RESULT.LOAD_WINDOW)
        return result

    def fini(self, woEvents=False):
        self.__requestCtx = None
        if not woEvents:
            g_eventDispatcher.unloadHistoryBattles()
        else:
            g_eventDispatcher.removeHistoryBattlesFromCarousel()
        g_gameCtrl.captcha.onCaptchaInputCanceled -= self.onCaptchaInputCanceled
        g_eventBus.removeListener(events.ChannelCarouselEvent.CAROUSEL_INITED,
                                  self.__handleCarouselInited,
                                  scope=EVENT_BUS_SCOPE.LOBBY)
        g_eventDispatcher.unloadHistoryBattles()
        g_eventsCache.onSyncCompleted -= self.onEventsCacheResync
        g_currentVehicle.setHistoricalBattle(None)
        super(HistoricalQueueFunctional, self).fini(woEvents=woEvents)

    def getStates(self):
        return ({'isInHistoricalQueue': True}, dict(self._settings))

    def isInQueue(self):
        return isInHistoricalQueue()

    def showGUI(self):
        g_eventDispatcher.loadHistoryBattles()

    @process
    def doLeaveAction(self, dispatcher, ctx=None, showConfirmation=True):
        meta = self.getConfirmDialogMeta()
        if meta is not None:
            isConfirmed = yield DialogsInterface.showDialog(meta)
        else:
            isConfirmed = yield lambda callback: callback(True)
        if isConfirmed:
            super(HistoricalQueueFunctional, self).doLeaveAction(dispatcher,
                                                                 ctx=None)

    def join(self, ctx, callback=None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if isParentControlActivated():
            g_eventDispatcher.showParentControlNotification()
            if callback:
                callback(False)
            return
        if not hasattr(BigWorld.player(), 'enqueueHistorical'):
            if callback:
                callback(False)
            LOG_ERROR('Player can not join to history queue')
            return
        self.__requestCtx = ctx
        self.__requestCtx.startProcessing(callback)
        invID = ctx.getVehicleInventoryID()
        histBattleID = ctx.getHistBattleID()
        isCreditsAmmo = ctx.getIsCreditsAmmo()
        BigWorld.player().enqueueHistorical(invID,
                                            histBattleID=histBattleID,
                                            isCreditsAmmo=isCreditsAmmo)
        LOG_DEBUG('Player is joining to historical queue', ctx)

    def leave(self, ctx, callback=None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if hasattr(BigWorld.player(), 'dequeueHistorical'):
            if self.isInQueue():
                self.__requestCtx = ctx
                self.__requestCtx.startProcessing(callback)
                BigWorld.player().dequeueHistorical()
            else:
                super(HistoricalQueueFunctional, self).leave(ctx, callback)
        else:
            if callback:
                callback(False)
            LOG_ERROR('Player can not exit from random queue')

    def getItemData(self):
        battleID = self.getSetting(PREQUEUE_SETTING_NAME.BATTLE_ID)
        return g_eventsCache.getHistoricalBattles().get(battleID)

    def canPlayerDoAction(self):
        histBattleID = self.getSetting(PREQUEUE_SETTING_NAME.BATTLE_ID)
        vehicleID = g_currentVehicle.item.intCD if g_currentVehicle.isPresent(
        ) else None
        historicalBattle = g_eventsCache.getHistoricalBattles().get(
            histBattleID)
        priceIndex, _ = self.getSelectedPrice(histBattleID, vehicleID)
        if historicalBattle is not None and vehicleID is not None:
            if historicalBattle.isFuture():
                return (False, '')
            if not historicalBattle.canParticipateWith(vehicleID):
                return (False, '')
            prices = historicalBattle.getShellsLayoutPrice(vehicleID)
            selected = priceIndex if priceIndex is not None else len(
                prices) - 1
            enoughGold, enoughCredits = historicalBattle.getShellsLayoutPriceStatus(
                vehicleID)[selected]
            if not enoughGold or not enoughCredits:
                return (False, '')
            return super(HistoricalQueueFunctional, self).canPlayerDoAction()
        return (False, '')

    def doAction(self, action=None, dispatcher=None):
        result = False
        if not self.isInQueue():
            histBattleID = self.getSetting(PREQUEUE_SETTING_NAME.BATTLE_ID)
            selectedVehicleID = self.getSetting(
                PREQUEUE_SETTING_NAME.SELECTED_VEHICLE_ID)
            _, isCreditsAmmo = self.getSelectedPrice(histBattleID,
                                                     selectedVehicleID)
            self.join(
                pre_queue_ctx.JoinHistoricalQueueCtx(
                    histBattleID, isCreditsAmmo, waitingID='prebattle/join'))
        else:
            self.leave(
                pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))
        return result

    def doSelectAction(self, action):
        result = False
        if action.actionName == PREBATTLE_ACTION_NAME.HISTORICAL:
            g_eventDispatcher.showHistoryBattlesWindow()
            result = True
        return result

    def onEnqueued(self, *args):
        super(HistoricalQueueFunctional, self).onEnqueued(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadBattleQueue()
        g_eventDispatcher.updateUI()

    def onDequeued(self, *args):
        super(HistoricalQueueFunctional, self).onDequeued(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        self.showGUI()
        self.__checkAvailability()

    def onEnqueueError(self, errorCode, _):
        super(HistoricalQueueFunctional, self).onEnqueueError(errorCode, _)
        self.__requestCtx.stopProcessing(False)
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode),
                                   type=SystemMessages.SM_TYPE.Error)

    def onKickedFromQueue(self, *args):
        super(HistoricalQueueFunctional, self).onKickedFromQueue(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        SystemMessages.pushMessage(messages.getKickReasonMessage('timeout'),
                                   type=SystemMessages.SM_TYPE.Warning)
        self.__checkAvailability()

    def onKickedFromArena(self, *args):
        super(HistoricalQueueFunctional, self).onKickedFromQueue(*args)
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        self.__checkAvailability()

    def onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(True)

    def getSelectedPrice(self, histBattleID, selectedVehicleID):
        return self.getSetting(PREQUEUE_SETTING_NAME.PRICE_INDEX,
                               {}).get(histBattleID,
                                       {}).get(selectedVehicleID, (None, True))

    def onEventsCacheResync(self):
        if isInHistoricalQueue():
            return
        self.__checkAvailability()

    def _applySettings(self, settings):
        if PREQUEUE_SETTING_NAME.BATTLE_ID in settings:
            historicalBattle = g_eventsCache.getHistoricalBattles().get(
                settings[PREQUEUE_SETTING_NAME.BATTLE_ID])
            g_currentVehicle.setHistoricalBattle(historicalBattle)

    def __handleCarouselInited(self, _):
        g_eventDispatcher.addHistoryBattlesToCarousel()

    def __checkAvailability(self):
        if not g_eventsCache.getHistoricalBattles():
            LOG_DEBUG('No historical battles available.')
            self.leave(
                pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))
            return
        historicalBattle = g_eventsCache.getHistoricalBattles().get(
            self._settings[PREQUEUE_SETTING_NAME.BATTLE_ID])
        if historicalBattle is None:
            LOG_DEBUG(
                'Currently selected historical battle is no longer available.')
            self.leave(
                pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))
        else:
            g_currentVehicle.setHistoricalBattle(historicalBattle)
Ejemplo n.º 20
0
class RandomQueueFunctional(PreQueueFunctional):
    def __init__(self, settings=None):
        super(RandomQueueFunctional, self).__init__(QUEUE_TYPE.RANDOMS, {
            QUEUE_EVENT_TYPE.ENQUEUED:
            g_playerEvents.onEnqueuedRandom,
            QUEUE_EVENT_TYPE.DEQUEUED:
            g_playerEvents.onDequeuedRandom,
            QUEUE_EVENT_TYPE.ENQUEUE_ERROR:
            g_playerEvents.onEnqueueRandomFailure,
            QUEUE_EVENT_TYPE.KICKED_FROM_QUEUE:
            g_playerEvents.onKickedFromRandomQueue,
            QUEUE_EVENT_TYPE.KICKED_FROM_ARENA:
            g_playerEvents.onKickedFromArena
        },
                                                    settings=settings)
        self.__requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx=None):
        result = super(RandomQueueFunctional, self).init(ctx)
        g_gameCtrl.captcha.onCaptchaInputCanceled += self.onCaptchaInputCanceled
        if self.isInQueue():
            g_eventDispatcher.loadBattleQueue()
            result = FUNCTIONAL_INIT_RESULT.addIfNot(
                result, FUNCTIONAL_INIT_RESULT.LOAD_PAGE)
        return result

    def fini(self, woEvents=False):
        self.__requestCtx = None
        g_gameCtrl.captcha.onCaptchaInputCanceled -= self.onCaptchaInputCanceled
        super(RandomQueueFunctional, self).fini(woEvents)

    @vehicleAmmoCheck
    def join(self, ctx, callback=None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if isParentControlActivated():
            g_eventDispatcher.showParentControlNotification()
            if callback:
                callback(False)
            return
        if not hasattr(BigWorld.player(), 'enqueueRandom'):
            if callback:
                callback(False)
            LOG_ERROR('Player can not join to random queue')
            return
        mapID = ctx.getDemoArenaTypeID()
        if mapID:
            LOG_DEBUG('Demonstrator mapID:',
                      ArenaType.g_cache[mapID].geometryName)
        self.__requestCtx = ctx
        self.__requestCtx.startProcessing(callback)
        BigWorld.player().enqueueRandom(ctx.getVehicleInventoryID(),
                                        gameplaysMask=ctx.getGamePlayMask(),
                                        arenaTypeID=mapID)
        LOG_DEBUG('Player is joining to random queue', ctx)

    def leave(self, ctx, callback=None):
        if self.__requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self.__requestCtx)
            if callback:
                callback(False)
            return
        if hasattr(BigWorld.player(), 'dequeueRandom'):
            if self.isInQueue():
                self.__requestCtx = ctx
                self.__requestCtx.startProcessing(callback)
                BigWorld.player().dequeueRandom()
            else:
                super(RandomQueueFunctional, self).leave(ctx, callback)
        else:
            if callback:
                callback(False)
            LOG_ERROR('Player can not exit from random queue')

    def isInQueue(self):
        return isInRandomQueue()

    def hasGUIPage(self):
        return True

    def doAction(self, action=None, dispatcher=None):
        result = False

        def _leavePreQueue():
            self.leave(
                pre_queue_ctx.LeavePreQueueCtx(waitingID='prebattle/leave'))

        if not self.isInQueue():

            def _joinResponse(success):
                if not success:
                    _leavePreQueue()

            self.join(pre_queue_ctx.JoinRandomQueueCtx(
                action.mapID if action else 0, waitingID='prebattle/join'),
                      callback=_joinResponse)
        else:
            _leavePreQueue()
        return result

    def onEnqueued(self):
        super(RandomQueueFunctional, self).onEnqueued()
        self.__requestCtx.stopProcessing(True)
        g_eventDispatcher.loadBattleQueue()
        g_eventDispatcher.updateUI()

    def onDequeued(self):
        super(RandomQueueFunctional, self).onDequeued()
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()

    def onEnqueueError(self, errorCode, _):
        super(RandomQueueFunctional, self).onEnqueueError(errorCode, _)
        self.__requestCtx.stopProcessing(False)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode),
                                   type=SystemMessages.SM_TYPE.Error)

    def onKickedFromQueue(self):
        super(RandomQueueFunctional, self).onKickedFromQueue()
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()
        SystemMessages.pushMessage(messages.getKickReasonMessage('timeout'),
                                   type=SystemMessages.SM_TYPE.Warning)

    def onKickedFromArena(self, errorCode):
        super(RandomQueueFunctional, self).onKickedFromArena(errorCode)
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
        g_eventDispatcher.loadHangar()
        g_eventDispatcher.updateUI()

    def onCaptchaInputCanceled(self):
        self.__requestCtx.stopProcessing(True)
        g_prbCtrlEvents.onPreQueueFunctionalDestroyed()
Ejemplo n.º 21
0
 def __init__(self, queueType, subscriber, flags = FUNCTIONAL_FLAG.UNDEFINED):
     super(AccountQueueFunctional, self).__init__(queueType, subscriber, flags)
     self._requestCtx = PrbCtrlRequestCtx()
Ejemplo n.º 22
0
class AccountQueueFunctional(PreQueueFunctional):
    __metaclass__ = EventVehicleMeta

    def __init__(self, queueType, subscriber, flags=FUNCTIONAL_FLAG.UNDEFINED):
        super(AccountQueueFunctional, self).__init__(queueType, subscriber,
                                                     flags)
        self._requestCtx = PrbCtrlRequestCtx()

    def init(self, ctx=None):
        return super(AccountQueueFunctional, self).init(ctx)

    def fini(self, woEvents=False):
        self._requestCtx.clear()
        super(AccountQueueFunctional, self).fini(woEvents)

    def doAction(self, action=None):
        if not self.isInQueue():
            self.queue(self._makeQueueCtxByAction(action))
        else:
            self.dequeue(pre_queue_ctx.DequeueCtx(waitingID='prebattle/leave'))
        return True

    def queue(self, ctx, callback=None):
        if ctx is None:
            ctx = self._makeQueueCtxByAction()
        if self._requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self._requestCtx)
            if callback is not None:
                callback(False)
            return
        elif self.isInQueue():
            LOG_ERROR('Player already is in the queue', self._requestCtx)
            if callback is not None:
                callback(False)
            return
        elif self._validateParentControl():
            if callback is not None:
                callback(False)
            return
        else:
            self._requestCtx = ctx
            self._requestCtx.startProcessing(callback)
            try:
                self._doQueue(ctx)
            except (AttributeError, TypeError, NotImplementedError):
                LOG_CURRENT_EXCEPTION()
                self._requestCtx.stopProcessing(False)

            return

    def dequeue(self, ctx, callback=None):
        if self._requestCtx.isProcessing():
            LOG_ERROR('Request is processing', self._requestCtx)
            if callback:
                callback(False)
            return
        elif not self.isInQueue():
            LOG_ERROR('Player is not in the queue', ctx)
            if callback is not None:
                callback(False)
            return
        else:
            self._requestCtx = ctx
            self._requestCtx.startProcessing(callback)
            try:
                self._doDequeue(ctx)
            except (AttributeError, TypeError, NotImplementedError):
                LOG_CURRENT_EXCEPTION()
                self._requestCtx.stopProcessing(False)

            return

    def onEnqueued(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onEnqueued(*args)

    def onDequeued(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onDequeued(*args)

    def onEnqueueError(self, *args):
        self._requestCtx.stopProcessing(False)
        super(AccountQueueFunctional, self).onEnqueueError(*args)

    def onKickedFromQueue(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onKickedFromQueue(*args)

    def onKickedFromArena(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onKickedFromArena(*args)

    def onArenaJoinFailure(self, *args):
        self._requestCtx.stopProcessing(True)
        super(AccountQueueFunctional, self).onArenaJoinFailure(*args)

    def _doQueue(self, ctx):
        raise NotImplementedError('Routine _doQueue must be overridden')

    def _doDequeue(self, ctx):
        raise NotImplementedError('Routine _doDequeue must be overridden')

    def _makeQueueCtxByAction(self, action=None):
        raise NotImplementedError(
            'Routine _makeDefQueueCtx must be overridden')

    def _validateParentControl(self):
        result = prb_getters.isParentControlActivated()
        if result:
            g_eventDispatcher.showParentControlNotification()
        return result