def __init__(self): super(_PrebattleDispatcher, self).__init__() self.__requestCtx = None self.__collection = FunctionalCollection() self.__factories = ControlFactoryDecorator() self.__nextPrbFunctional = None self._globalListeners = set()
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()
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)
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()
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)