Пример #1
0
 def init(self, clan, listeners, prevController=None):
     super(FortController, self).init(clan, listeners, prevController)
     self._sortiesCache = SortiesCache(self)
     self._sortiesCache.start()
     self._sortiesCurfewCtrl = SortiesCurfewController()
     self._sortiesCurfewCtrl.start()
     self._fortBattlesCache = FortBattlesCache(self)
     self._fortBattlesCache.start()
     self._finder = FortFinder()
     self._finder.init()
     self._publicInfoCache = PublicInfoCache(self)
     self._publicInfoCache.start()
Пример #2
0
 def init(self, clan, listeners, prevController = None):
     super(FortController, self).init(clan, listeners, prevController)
     self._sortiesCache = SortiesCache(self)
     self._sortiesCache.start()
     self._fortBattlesCache = FortBattlesCache(self)
     self._fortBattlesCache.start()
     self._finder = FortFinder()
     self._finder.init()
     self._publicInfoCache = PublicInfoCache(self)
     self._publicInfoCache.start()
Пример #3
0
class FortController(_FortController):

    def __init__(self):
        super(FortController, self).__init__({FORT_REQUEST_TYPE.OPEN_DIRECTION: self.openDirection,
         FORT_REQUEST_TYPE.CLOSE_DIRECTION: self.closeDirection,
         FORT_REQUEST_TYPE.ADD_BUILDING: self.addBuilding,
         FORT_REQUEST_TYPE.DELETE_BUILDING: self.deleteBuilding,
         FORT_REQUEST_TYPE.TRANSPORTATION: self.transport,
         FORT_REQUEST_TYPE.ADD_ORDER: self.addOrder,
         FORT_REQUEST_TYPE.ACTIVATE_ORDER: self.activateOrder,
         FORT_REQUEST_TYPE.ATTACH: self.attach,
         FORT_REQUEST_TYPE.UPGRADE: self.upgrade,
         FORT_REQUEST_TYPE.CREATE_SORTIE: self.createSortie,
         FORT_REQUEST_TYPE.REQUEST_SORTIE_UNIT: self.requestSortieUnit,
         FORT_REQUEST_TYPE.CHANGE_DEF_HOUR: self.changeDefHour,
         FORT_REQUEST_TYPE.CHANGE_OFF_DAY: self.changeOffDay,
         FORT_REQUEST_TYPE.CHANGE_PERIPHERY: self.changePeriphery,
         FORT_REQUEST_TYPE.CHANGE_VACATION: self.changeVacation,
         FORT_REQUEST_TYPE.CHANGE_SETTINGS: self.changeSettings,
         FORT_REQUEST_TYPE.SHUTDOWN_DEF_HOUR: self.shutDownDefHour,
         FORT_REQUEST_TYPE.CANCEL_SHUTDOWN_DEF_HOUR: self.cancelShutDownDefHour,
         FORT_REQUEST_TYPE.REQUEST_PUBLIC_INFO: self.requestFortPublicInfo,
         FORT_REQUEST_TYPE.REQUEST_CLAN_CARD: self.requestClanCard,
         FORT_REQUEST_TYPE.ADD_FAVORITE: self.addFavorite,
         FORT_REQUEST_TYPE.REMOVE_FAVORITE: self.removeFavorite,
         FORT_REQUEST_TYPE.PLAN_ATTACK: self.planAttack,
         FORT_REQUEST_TYPE.CREATE_OR_JOIN_FORT_BATTLE: self.createOrJoinFortBattle,
         FORT_REQUEST_TYPE.ACTIVATE_CONSUMABLE: self.activateConsumable,
         FORT_REQUEST_TYPE.RETURN_CONSUMABLE: self.returnConsumable})
        self.__cooldownCallback = None
        self.__cooldownBuildings = []
        self.__cooldownPassed = False
        self._upgradeVisitedBuildings = set()
        self._finder = None
        self.__defencePeriodCallback = None
        return

    @classmethod
    def isNext(cls, stateID, _):
        return stateID in (CLIENT_FORT_STATE.WIZARD, CLIENT_FORT_STATE.HAS_FORT)

    def init(self, clan, listeners, prevController = None):
        super(FortController, self).init(clan, listeners, prevController)
        self._sortiesCache = SortiesCache(self)
        self._sortiesCache.start()
        self._sortiesCurfewCtrl = SortiesCurfewController()
        self._sortiesCurfewCtrl.start()
        self._fortBattlesCache = FortBattlesCache(self)
        self._fortBattlesCache.start()
        self._finder = FortFinder()
        self._finder.init()
        self._publicInfoCache = PublicInfoCache(self)
        self._publicInfoCache.start()

    def fini(self, clearCache = True):
        if self._sortiesCache and clearCache:
            self._sortiesCache.stop()
            self._sortiesCache = None
        if self._sortiesCurfewCtrl:
            self._sortiesCurfewCtrl.stop()
            self._sortiesCurfewCtrl = None
        if self._fortBattlesCache:
            self._fortBattlesCache.stop()
            self._fortBattlesCache = None
        if self._publicInfoCache:
            self._publicInfoCache.stop()
            self._publicInfoCache = None
        super(FortController, self).fini()
        return

    def stopProcessing(self):
        if self._finder is not None:
            self._finder.stopProcessing()
        super(FortController, self).stopProcessing()
        return

    def openDirection(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        direction = ctx.getDirection()
        if fort.isDirectionOpened(direction):
            return self._failChecking('Direction already is opened', ctx, callback)
        if not perm.canOpenDirection():
            return self._failChecking('Player can not open direction', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.isDirectionValid(direction)
        if not valid:
            return self._failChecking('Direction is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'openDir', direction)

    def closeDirection(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        direction = ctx.getDirection()
        if not fort.isDirectionOpened(direction):
            return self._failChecking('Direction is not opened', ctx, callback)
        if not perm.canCloseDirection():
            return self._failChecking('Player can not open direction', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.isDirectionValid(direction, open=False)
        if not valid:
            return self._failChecking('Direction is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'closeDir', direction)

    def addBuilding(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        direction = ctx.getDirection()
        position = ctx.getPosition()
        if not fort.isPositionAvailable(direction, position):
            return self._failChecking('Positions is not available', ctx, callback)
        if fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is already built', ctx, callback)
        if not perm.canAddBuilding():
            return self._failChecking('Player can not build buildings', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.canBuild(buildingTypeID)
        if not valid:
            return self._failChecking('Building is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'addBuilding', buildingTypeID, direction, position)

    def deleteBuilding(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        if not fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is not built', ctx, callback)
        if not perm.canDeleteBuilding():
            return self._failChecking('Player can not build buildings', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'delBuilding', buildingTypeID)

    def transport(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        fromBuildingID = ctx.getFromBuildingTypeID()
        toBuildingID = ctx.getToBuildingTypeID()
        resCount = ctx.getResCount()
        if not fort.isBuildingBuilt(fromBuildingID):
            return self._failChecking('Exporting building is not built', ctx, callback)
        if not fort.isBuildingBuilt(toBuildingID):
            return self._failChecking('Importing building is not built', ctx, callback)
        fromBuilding = fort.getBuilding(fromBuildingID)
        if not fromBuilding.isReady() or not fromBuilding.isExportAvailable(resCount):
            return self._failChecking('Exporting from building is not available', ctx, callback)
        toBuilding = fort.getBuilding(toBuildingID)
        if not toBuilding.isImportAvailable(resCount):
            return self._failChecking('Importing into building is not available', ctx, callback)
        if not perm.canTransport():
            return self._failChecking('Player can not transport', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'transport', fromBuildingID, toBuildingID, resCount)

    def attach(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        if not fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is not built', ctx, callback)
        if not perm.canAttach():
            return self._failChecking('Player can not attach', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'attach', buildingTypeID)

    def upgrade(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        if not fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is not built', ctx, callback)
        building = fort.getBuilding(buildingTypeID)
        if not building.isReady():
            return self._failChecking('Building is not available', ctx, callback)
        if not perm.canUpgradeBuilding():
            return self._failChecking('Player can not upgrade building', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.canUpgrade(buildingTypeID)
        if not valid:
            return self._failChecking('Building is invalid: {0}'.format(reason), ctx, callback)
        self.removeUpgradeVisitedBuilding(buildingTypeID)
        return self._requester.doRequestEx(ctx, callback, 'upgrade', buildingTypeID)

    def addOrder(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        orderTypeID = ctx.getOrderTypeID()
        count = ctx.getCount()
        order = fort.getOrder(orderTypeID)
        if not order.hasBuilding:
            return self._failChecking('Order building is not built', ctx, callback)
        orderBuilding = fort.getBuilding(order.buildingID)
        if not orderBuilding.isReady() and not orderBuilding.orderInProduction:
            return self._failChecking('Building is not ready to add order', ctx, callback)
        if not perm.canAddOrder():
            return self._failChecking('Player can not add order', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.isOrderValid(orderTypeID, add=False)
        if not valid:
            return self._failChecking('Orded is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'addOrder', order.buildingID, count)

    def activateOrder(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        orderTypeID = ctx.getOrderTypeID()
        order = fort.getOrder(orderTypeID)
        if not order.hasBuilding:
            return self._failChecking('Order building is not built', ctx, callback)
        orderBuilding = fort.getBuilding(order.buildingID)
        if not orderBuilding.isReady():
            return self._failChecking('Building is not ready to add order', ctx, callback)
        if not perm.canActivateOrder():
            return self._failChecking('Player can not add order', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'activateOrder', orderTypeID)

    def createSortie(self, ctx, callback = None):
        level = ctx.getDivisionLevel()
        perm = self.getPermissions()
        if not perm.canCreateSortie():
            return self._failChecking('Player can not create sortie, no permission', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.isSortieCreationValid(level)
        if not valid:
            return self._failChecking('Player can not create sortie: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'createSortie', level)

    def requestSortieUnit(self, ctx, callback = None):
        unitMgrID = ctx.getUnitMgrID()
        peripheryID = ctx.getPeripheryID()
        fort = self.getFort()
        if not fort:
            return self._failChecking('Client fort is not found', ctx, callback)
        if (unitMgrID, peripheryID) not in fort.sorties:
            return self._failChecking('Sortie does not exists on client', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'getSortieData', unitMgrID, peripheryID)

    def getUpgradeVisitedBuildings(self):
        return self._upgradeVisitedBuildings

    def addUpgradeVisitedBuildings(self, buildingID):
        if buildingID not in self._upgradeVisitedBuildings:
            self._upgradeVisitedBuildings.add(buildingID)
            self._listeners.notify('onUpgradeVisitedBuildingChanged', buildingID)

    def removeUpgradeVisitedBuilding(self, buildingID):
        if buildingID in self._upgradeVisitedBuildings:
            self._upgradeVisitedBuildings.remove(buildingID)
            self._listeners.notify('onUpgradeVisitedBuildingChanged', buildingID)

    def changeDefHour(self, ctx, callback = None):
        perm = self.getPermissions()
        defHour = ctx.getDefenceHour()
        if not perm.canChangeDefHour():
            return self._failChecking('Player can not change defence hour', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'changeDefHour', defHour)

    def changeOffDay(self, ctx, callback = None):
        perm = self.getPermissions()
        offDay = ctx.getOffDay()
        if not perm.canChangeOffDay():
            return self._failChecking('Player can not change off day', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'changeOffDay', offDay)

    def changePeriphery(self, ctx, callback = None):
        perm = self.getPermissions()
        peripheryID = ctx.getPeripheryID()
        if not perm.canChangePeriphery():
            return self._failChecking('Player can not change periphery', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'changePeriphery', peripheryID)

    def changeVacation(self, ctx, callback = None):
        perm = self.getPermissions()
        timeVacationStart = ctx.getTimeVacationStart()
        timeVacationDuration = ctx.getTimeVacationDuration()
        if not perm.canChangeVacation():
            return self._failChecking('Player can not change vacation', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'changeVacation', timeVacationStart, timeVacationDuration)

    def changeSettings(self, ctx, callback = None):
        perm = self.getPermissions()
        fort = self.getFort()
        chain = []
        defHour = ctx.getDefenceHour()
        if defHour != fort.defenceHour:
            if not perm.canChangeDefHour():
                return self._failChecking('Player can not change defence hour', ctx, callback)
            chain.append(('changeDefHour', (defHour,), {}))
        offDay = ctx.getOffDay()
        if offDay != fort.offDay:
            if not perm.canChangeOffDay():
                return self._failChecking('Player can not change off day', ctx, callback)
            chain.append(('changeOffDay', (offDay,), {}))
        peripheryID = ctx.getPeripheryID()
        if peripheryID != fort.peripheryID:
            if not perm.canChangePeriphery():
                return self._failChecking('Player can not change periphery', ctx, callback)
            chain.append(('changePeriphery', (peripheryID,), {}))
        if not chain:
            return self._failChecking('No requests to process', ctx, callback)
        return self._requester.doRequestChainEx(ctx, callback, chain)

    def shutDownDefHour(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canShutDownDefHour():
            return self._failChecking('Player can not shut down def hour', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'shutdownDefHour')

    def cancelShutDownDefHour(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canCancelShutDownDefHour():
            return self._failChecking('Player can not cancel shut down def hour', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'cancelDefHourShutdown')

    def requestFortPublicInfo(self, ctx, callback = None):
        fort = self.getFort()
        perm = self.getPermissions()
        if not perm.canRequestPublicInfo():
            return self._failChecking('Player can not request public info', ctx, callback)
        filterType = ctx.getFilterType()
        abbrevPattern = ctx.getAbbrevPattern()
        homePeripheryID = fort.peripheryID
        limit = ctx.getLimit()
        lvlFrom = ctx.getLvlFrom()
        lvlTo = ctx.getLvlTo()
        ownStartDefHourFrom = fort.defenceHour
        nextOwnStartDefHourFrom, defHourChangeDay = fort.getNextDefenceHourData()
        extStartDefHourFrom = ctx.getStartDefHourFrom()
        extStartDefHourTo = ctx.getStartDefHourTo()
        attackDay = ctx.getAttackDay()
        ownFortLvl = fort.level
        battleStats = fort.getFortDossier().getBattlesStats()
        ownProfitFactor10 = int(battleStats.getProfitFactor() * 10)
        buildingLevels = map(attrgetter('level'), fort.getBuildings().itervalues())
        minLevel = fortified_regions.g_cache.defenceConditions.minRegionLevel
        validBuildingLevels = filter(lambda x: x >= minLevel, buildingLevels)
        avgBuildingLevel10 = 0
        if validBuildingLevels:
            avgBuildingLevel10 = int(float(sum(validBuildingLevels)) / len(validBuildingLevels) * 10)
        ownBattleCountForFort = battleStats.getBattlesCount()
        firstDefaultQuery = ctx.isFirstDefaultQuery()
        electedClanDBIDs = tuple(fort.favorites)
        val = self.getValidators()
        validationResult, validationReason = val.validate(ctx.getRequestType(), filterType, abbrevPattern)
        if not validationResult:
            self._listeners.notify('onFortPublicInfoValidationError', validationReason)
            return self._failChecking('Player input is invalid', ctx, callback)
        return self._finder.request(filterType, abbrevPattern, homePeripheryID, limit, lvlFrom, lvlTo, ownStartDefHourFrom, ownStartDefHourFrom + 1, nextOwnStartDefHourFrom, nextOwnStartDefHourFrom + 1, defHourChangeDay, extStartDefHourFrom, extStartDefHourTo, attackDay, ownFortLvl, ownProfitFactor10, avgBuildingLevel10, ownBattleCountForFort, firstDefaultQuery, electedClanDBIDs, callback)

    def requestClanCard(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canRequestClanCard():
            return self._failChecking('Player can not request clan card', ctx, callback)
        clanDBID = ctx.getClanDBID()
        return self._requester.doRequestEx(ctx, callback, 'getEnemyClanCard', clanDBID)

    def addFavorite(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canAddToFavorite():
            return self._failChecking('Player can not add favorite', ctx, callback)
        clanDBID = ctx.getClanDBID()
        return self._requester.doRequestEx(ctx, callback, 'addFavorite', clanDBID)

    def removeFavorite(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canRemoveFavorite():
            return self._failChecking('Player can not remove favorite', ctx, callback)
        clanDBID = ctx.getClanDBID()
        return self._requester.doRequestEx(ctx, callback, 'removeFavorite', clanDBID)

    def planAttack(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canPlanAttack():
            return self._failChecking('Player can not plan attack', ctx, callback)
        clanDBID = ctx.getClanDBID()
        timeAttack = ctx.getTimeAttack()
        dirFrom = ctx.getDirFrom()
        dirTo = ctx.getDirTo()
        return self._requester.doRequestEx(ctx, callback, 'planAttack', clanDBID, timeAttack, dirFrom, dirTo)

    def createOrJoinFortBattle(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canCreateFortBattle():
            return self._failChecking('Player can not plan attack', ctx, callback)
        battleID = ctx.getBattleID()
        slotIdx = ctx.getSlotIdx()
        return self._requester.doRequestEx(ctx, callback, 'createOrJoinFortBattle', battleID, slotIdx)

    def activateConsumable(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canActivateConsumable():
            return self._failChecking('Player can not activate consumable', ctx, callback)
        orderTypeID = ctx.getConsumableOrderTypeID()
        slotIdx = ctx.getSlotIdx()
        return self._requester.doRequestEx(ctx, callback, 'activateConsumable', orderTypeID, slotIdx)

    def returnConsumable(self, ctx, callback = None):
        perm = self.getPermissions()
        if not perm.canReturnConsumable():
            return self._failChecking('Player can not return consumable', ctx, callback)
        orderTypeID = ctx.getConsumableOrderTypeID()
        return self._requester.doRequestEx(ctx, callback, 'returnConsumable', orderTypeID)

    def _setLimits(self):
        self._limits = FortLimits()

    def _setValidators(self):
        self._validators = FortValidators()

    def _addFortListeners(self):
        super(FortController, self)._addFortListeners()
        fort = self.getFort()
        if not fort:
            LOG_ERROR('No fort to subscribe')
            return
        fort.onBuildingChanged += self.__fort_onBuildingChanged
        fort.onTransport += self.__fort_onTransport
        fort.onDirectionOpened += self.__fort_onDirectionOpened
        fort.onDirectionClosed += self.__fort_onDirectionClosed
        fort.onDirectionLockChanged += self.__fort_onDirectionLockChanged
        fort.onStateChanged += self.__fort_onStateChanged
        fort.onOrderChanged += self.__fort_onOrderChanged
        fort.onDossierChanged += self.__fort_onDossierChanged
        fort.onPlayerAttached += self.__fort_onPlayerAttached
        fort.onSettingCooldown += self.__fort_onSettingCooldown
        fort.onPeripheryChanged += self.__fort_onPeripheryChanged
        fort.onDefenceHourChanged += self.__fort_onDefenceHourChanged
        fort.onOffDayChanged += self.__fort_onOffDayChanged
        fort.onVacationChanged += self.__fort_onVacationChanged
        fort.onFavoritesChanged += self.__fort_onFavoritesChanged
        fort.onEnemyClanCardReceived += self.__fort_onEnemyClanCardReceived
        fort.onShutdownDowngrade += self.__fort_onShutdownDowngrade
        fort.onDefenceHourShutdown += self.__fort_onDefenceHourShutdown
        fort.onEmergencyRestore += self.__fort_onEmergencyRestore
        fort.onConsumablesChanged += self.__fort_onConsumablesChanged
        fort.onDefenceHourActivated += self.__fort_onDefenceHourActivated
        fortMgr = getClientFortMgr()
        if not fortMgr:
            LOG_ERROR('No fort manager to subscribe')
            return
        fortMgr.onFortUpdateReceived += self.__fortMgr_onFortUpdateReceived
        fortMgr.onFortPublicInfoReceived += self.__fortMgr_onFortPublicInfoReceived
        self.__refreshCooldowns(False)
        self.__processDefencePeriodCallback()

    def _removeFortListeners(self):
        self.__cancelCooldownCallback()
        self.__cancelDefencePeriodCallback()
        fort = self.getFort()
        if fort:
            fort.onBuildingChanged -= self.__fort_onBuildingChanged
            fort.onTransport -= self.__fort_onTransport
            fort.onDirectionOpened -= self.__fort_onDirectionOpened
            fort.onDirectionClosed -= self.__fort_onDirectionClosed
            fort.onDirectionLockChanged -= self.__fort_onDirectionLockChanged
            fort.onStateChanged -= self.__fort_onStateChanged
            fort.onOrderChanged -= self.__fort_onOrderChanged
            fort.onDossierChanged -= self.__fort_onDossierChanged
            fort.onPlayerAttached -= self.__fort_onPlayerAttached
            fort.onSettingCooldown -= self.__fort_onSettingCooldown
            fort.onPeripheryChanged -= self.__fort_onPeripheryChanged
            fort.onDefenceHourChanged -= self.__fort_onDefenceHourChanged
            fort.onOffDayChanged -= self.__fort_onOffDayChanged
            fort.onVacationChanged -= self.__fort_onVacationChanged
            fort.onFavoritesChanged -= self.__fort_onFavoritesChanged
            fort.onEnemyClanCardReceived -= self.__fort_onEnemyClanCardReceived
            fort.onShutdownDowngrade -= self.__fort_onShutdownDowngrade
            fort.onDefenceHourShutdown -= self.__fort_onDefenceHourShutdown
            fort.onEmergencyRestore -= self.__fort_onEmergencyRestore
            fort.onConsumablesChanged -= self.__fort_onConsumablesChanged
            fort.onDefenceHourActivated -= self.__fort_onDefenceHourActivated
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortUpdateReceived -= self.__fortMgr_onFortUpdateReceived
            fortMgr.onFortPublicInfoReceived -= self.__fortMgr_onFortPublicInfoReceived
        super(FortController, self)._removeFortListeners()

    def __refreshCooldowns(self, doNotify = True):
        self.__cancelCooldownCallback()
        if self.__cooldownBuildings and doNotify:
            self._listeners.notify('onBuildingsUpdated', self.__cooldownBuildings, self.__cooldownPassed)
        fort = self.getFort()
        self.__cooldownBuildings = fort.getBuildingsOnCooldown()
        if self.__cooldownBuildings:
            time = 30
            self.__cooldownPassed = False
            for buildingID in self.__cooldownBuildings:
                building = fort.getBuilding(buildingID)
                estimatedCooldown = building.getEstimatedCooldown()
                if 0 < estimatedCooldown <= time:
                    time = estimatedCooldown
                    self.__cooldownPassed = True
                productionCooldown = building.getProductionCooldown()
                if 0 < productionCooldown < time:
                    time = productionCooldown

            self.__cooldownCallback = BigWorld.callback(time, self.__refreshCooldowns)

    def __cancelCooldownCallback(self):
        if self.__cooldownCallback is not None:
            LOG_DEBUG('Cooldown callback cancelling: ', self.__cooldownCallback)
            BigWorld.cancelCallback(self.__cooldownCallback)
            self.__cooldownCallback = None
            self.__cooldownBuildings = []
            self.__cooldownPassed = False
        return

    def __processDefencePeriodCallback(self):
        self.__cancelDefencePeriodCallback()
        fort = self.getFort()
        self._listeners.notify('onDefenceHourStateChanged')
        start, finish = fort.getClosestDefencePeriod()
        if fort.isOnDefenceHour():
            timer = time_utils.getTimeDeltaFromNow(finish)
        else:
            timer = time_utils.getTimeDeltaFromNow(start)
        if timer > 0:
            self.__defencePeriodCallback = BigWorld.callback(timer, self.__processDefencePeriodCallback)

    def __cancelDefencePeriodCallback(self):
        if self.__defencePeriodCallback is not None:
            BigWorld.cancelCallback(self.__defencePeriodCallback)
            self.__defencePeriodCallback = None
        return

    def __fort_onBuildingChanged(self, buildingTypeID, reason, ctx = None):
        self._listeners.notify('onBuildingChanged', buildingTypeID, reason, ctx)

    def __fort_onBuildingRemoved(self, buildingTypeID):
        self._listeners.notify('onBuildingRemoved', buildingTypeID)

    def __fort_onTransport(self):
        self._listeners.notify('onTransport')

    def __fort_onDirectionOpened(self, dir):
        self._listeners.notify('onDirectionOpened', dir)

    def __fort_onDirectionClosed(self, dir):
        self._listeners.notify('onDirectionClosed', dir)

    def __fort_onDirectionLockChanged(self):
        self._listeners.notify('onDirectionLockChanged')

    def __fort_onStateChanged(self, state):
        self._listeners.notify('onStateChanged', state)

    def __fort_onOrderChanged(self, orderTypeID, reason):
        self._listeners.notify('onOrderChanged', orderTypeID, reason)

    def __fort_onDossierChanged(self, compDossierDescr):
        self._listeners.notify('onDossierChanged', compDossierDescr)

    def __fort_onPlayerAttached(self, buildingTypeID):
        self._listeners.notify('onPlayerAttached', buildingTypeID)

    def __fort_onSettingCooldown(self, eventTypeID):
        self._listeners.notify('onSettingCooldown', eventTypeID)

    def __fort_onPeripheryChanged(self, peripheryID):
        self._listeners.notify('onPeripheryChanged', peripheryID)

    def __fort_onDefenceHourChanged(self, hour):
        self._listeners.notify('onDefenceHourChanged', hour)
        self.__processDefencePeriodCallback()

    def __fort_onDefenceHourActivated(self, hour, initiatorDBID):
        self._listeners.notify('onDefenceHourActivated', hour, initiatorDBID)
        self.__processDefencePeriodCallback()

    def __fort_onOffDayChanged(self, offDay):
        self._listeners.notify('onOffDayChanged', offDay)
        self.__processDefencePeriodCallback()

    def __fort_onVacationChanged(self, vacationStart, vacationEnd):
        self._listeners.notify('onVacationChanged', vacationStart, vacationEnd)
        self.__processDefencePeriodCallback()

    def __fort_onFavoritesChanged(self, clanDBID):
        self._listeners.notify('onFavoritesChanged', clanDBID)

    def __fort_onEnemyClanCardReceived(self, card):
        if self._publicInfoCache is not None:
            self._publicInfoCache.storeSelectedClanCard(card)
        self._listeners.notify('onEnemyClanCardReceived', card)
        return

    def __fort_onShutdownDowngrade(self):
        self._listeners.notify('onShutdownDowngrade')

    def __fort_onDefenceHourShutdown(self):
        self._listeners.notify('onDefenceHourShutdown')

    def __fortMgr_onFortUpdateReceived(self, isFullUpdate = False):
        self.__refreshCooldowns(isFullUpdate)

    def __fortMgr_onFortPublicInfoReceived(self, requestID, errorID, resultSet):
        self._finder.response(requestID, errorID, resultSet)
        self._listeners.notify('onFortPublicInfoReceived', bool(resultSet))

    def __fort_onEmergencyRestore(self):
        self.stopProcessing()

    def __fort_onConsumablesChanged(self, unitMgrID):
        self._listeners.notify('onConsumablesChanged', unitMgrID)
Пример #4
0
 def removeFortBattlesCache(self):
     FortBattlesCache._removeStoredData()
Пример #5
0
class FortController(_FortController):
    def __init__(self):
        super(FortController, self).__init__({
            FORT_REQUEST_TYPE.OPEN_DIRECTION:
            self.openDirection,
            FORT_REQUEST_TYPE.CLOSE_DIRECTION:
            self.closeDirection,
            FORT_REQUEST_TYPE.ADD_BUILDING:
            self.addBuilding,
            FORT_REQUEST_TYPE.DELETE_BUILDING:
            self.deleteBuilding,
            FORT_REQUEST_TYPE.TRANSPORTATION:
            self.transport,
            FORT_REQUEST_TYPE.ADD_ORDER:
            self.addOrder,
            FORT_REQUEST_TYPE.ACTIVATE_ORDER:
            self.activateOrder,
            FORT_REQUEST_TYPE.ATTACH:
            self.attach,
            FORT_REQUEST_TYPE.UPGRADE:
            self.upgrade,
            FORT_REQUEST_TYPE.CREATE_SORTIE:
            self.createSortie,
            FORT_REQUEST_TYPE.REQUEST_SORTIE_UNIT:
            self.requestSortieUnit,
            FORT_REQUEST_TYPE.CHANGE_DEF_HOUR:
            self.changeDefHour,
            FORT_REQUEST_TYPE.CHANGE_OFF_DAY:
            self.changeOffDay,
            FORT_REQUEST_TYPE.CHANGE_PERIPHERY:
            self.changePeriphery,
            FORT_REQUEST_TYPE.CHANGE_VACATION:
            self.changeVacation,
            FORT_REQUEST_TYPE.CHANGE_SETTINGS:
            self.changeSettings,
            FORT_REQUEST_TYPE.SHUTDOWN_DEF_HOUR:
            self.shutDownDefHour,
            FORT_REQUEST_TYPE.CANCEL_SHUTDOWN_DEF_HOUR:
            self.cancelShutDownDefHour,
            FORT_REQUEST_TYPE.REQUEST_PUBLIC_INFO:
            self.requestFortPublicInfo,
            FORT_REQUEST_TYPE.REQUEST_CLAN_CARD:
            self.requestClanCard,
            FORT_REQUEST_TYPE.ADD_FAVORITE:
            self.addFavorite,
            FORT_REQUEST_TYPE.REMOVE_FAVORITE:
            self.removeFavorite,
            FORT_REQUEST_TYPE.PLAN_ATTACK:
            self.planAttack,
            FORT_REQUEST_TYPE.CREATE_OR_JOIN_FORT_BATTLE:
            self.createOrJoinFortBattle,
            FORT_REQUEST_TYPE.ACTIVATE_CONSUMABLE:
            self.activateConsumable,
            FORT_REQUEST_TYPE.RETURN_CONSUMABLE:
            self.returnConsumable
        })
        self.__cooldownCallback = None
        self.__cooldownBuildings = []
        self.__cooldownPassed = False
        self._upgradeVisitedBuildings = set()
        self._finder = None
        self.__defencePeriodCallback = None
        return

    @classmethod
    def isNext(cls, stateID, _):
        return stateID in (CLIENT_FORT_STATE.WIZARD,
                           CLIENT_FORT_STATE.HAS_FORT)

    def init(self, clan, listeners, prevController=None):
        super(FortController, self).init(clan, listeners, prevController)
        self._sortiesCache = SortiesCache(self)
        self._sortiesCache.start()
        self._sortiesCurfewCtrl = SortiesCurfewController()
        self._sortiesCurfewCtrl.start()
        self._fortBattlesCache = FortBattlesCache(self)
        self._fortBattlesCache.start()
        self._finder = FortFinder()
        self._finder.init()
        self._publicInfoCache = PublicInfoCache(self)
        self._publicInfoCache.start()

    def fini(self, clearCache=True):
        if self._sortiesCache and clearCache:
            self._sortiesCache.stop()
            self._sortiesCache = None
        if self._sortiesCurfewCtrl:
            self._sortiesCurfewCtrl.stop()
            self._sortiesCurfewCtrl = None
        if self._fortBattlesCache:
            self._fortBattlesCache.stop()
            self._fortBattlesCache = None
        if self._publicInfoCache:
            self._publicInfoCache.stop()
            self._publicInfoCache = None
        super(FortController, self).fini()
        return

    def stopProcessing(self):
        if self._finder is not None:
            self._finder.stopProcessing()
        super(FortController, self).stopProcessing()
        return

    def openDirection(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        direction = ctx.getDirection()
        if fort.isDirectionOpened(direction):
            return self._failChecking('Direction already is opened', ctx,
                                      callback)
        if not perm.canOpenDirection():
            return self._failChecking('Player can not open direction', ctx,
                                      callback)
        limits = self.getLimits()
        valid, reason = limits.isDirectionValid(direction)
        if not valid:
            return self._failChecking(
                'Direction is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'openDir', direction)

    def closeDirection(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        direction = ctx.getDirection()
        if not fort.isDirectionOpened(direction):
            return self._failChecking('Direction is not opened', ctx, callback)
        if not perm.canCloseDirection():
            return self._failChecking('Player can not open direction', ctx,
                                      callback)
        limits = self.getLimits()
        valid, reason = limits.isDirectionValid(direction, open=False)
        if not valid:
            return self._failChecking(
                'Direction is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'closeDir',
                                           direction)

    def addBuilding(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        direction = ctx.getDirection()
        position = ctx.getPosition()
        if not fort.isPositionAvailable(direction, position):
            return self._failChecking('Positions is not available', ctx,
                                      callback)
        if fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is already built', ctx,
                                      callback)
        if not perm.canAddBuilding():
            return self._failChecking('Player can not build buildings', ctx,
                                      callback)
        limits = self.getLimits()
        valid, reason = limits.canBuild(buildingTypeID)
        if not valid:
            return self._failChecking(
                'Building is invalid: {0}'.format(reason), ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'addBuilding',
                                           buildingTypeID, direction, position)

    def deleteBuilding(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        if not fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is not built', ctx, callback)
        if not perm.canDeleteBuilding():
            return self._failChecking('Player can not build buildings', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'delBuilding',
                                           buildingTypeID)

    def transport(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        fromBuildingID = ctx.getFromBuildingTypeID()
        toBuildingID = ctx.getToBuildingTypeID()
        resCount = ctx.getResCount()
        if not fort.isBuildingBuilt(fromBuildingID):
            return self._failChecking('Exporting building is not built', ctx,
                                      callback)
        if not fort.isBuildingBuilt(toBuildingID):
            return self._failChecking('Importing building is not built', ctx,
                                      callback)
        fromBuilding = fort.getBuilding(fromBuildingID)
        if not fromBuilding.isReady() or not fromBuilding.isExportAvailable(
                resCount):
            return self._failChecking(
                'Exporting from building is not available', ctx, callback)
        toBuilding = fort.getBuilding(toBuildingID)
        if not toBuilding.isImportAvailable(resCount):
            return self._failChecking(
                'Importing into building is not available', ctx, callback)
        if not perm.canTransport():
            return self._failChecking('Player can not transport', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'transport',
                                           fromBuildingID, toBuildingID,
                                           resCount)

    def attach(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        if not fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is not built', ctx, callback)
        if not perm.canAttach():
            return self._failChecking('Player can not attach', ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'attach',
                                           buildingTypeID)

    def upgrade(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        buildingTypeID = ctx.getBuildingTypeID()
        if not fort.isBuildingBuilt(buildingTypeID):
            return self._failChecking('Building is not built', ctx, callback)
        building = fort.getBuilding(buildingTypeID)
        if not building.isReady():
            return self._failChecking('Building is not available', ctx,
                                      callback)
        if not perm.canUpgradeBuilding():
            return self._failChecking('Player can not upgrade building', ctx,
                                      callback)
        limits = self.getLimits()
        valid, reason = limits.canUpgrade(buildingTypeID)
        if not valid:
            return self._failChecking(
                'Building is invalid: {0}'.format(reason), ctx, callback)
        self.removeUpgradeVisitedBuilding(buildingTypeID)
        return self._requester.doRequestEx(ctx, callback, 'upgrade',
                                           buildingTypeID)

    def addOrder(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        orderTypeID = ctx.getOrderTypeID()
        count = ctx.getCount()
        order = fort.getOrder(orderTypeID)
        if not order.hasBuilding:
            return self._failChecking('Order building is not built', ctx,
                                      callback)
        orderBuilding = fort.getBuilding(order.buildingID)
        if not orderBuilding.isReady() and not orderBuilding.orderInProduction:
            return self._failChecking('Building is not ready to add order',
                                      ctx, callback)
        if not perm.canAddOrder():
            return self._failChecking('Player can not add order', ctx,
                                      callback)
        limits = self.getLimits()
        valid, reason = limits.isOrderValid(orderTypeID, add=False)
        if not valid:
            return self._failChecking('Orded is invalid: {0}'.format(reason),
                                      ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'addOrder',
                                           order.buildingID, count)

    def activateOrder(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        orderTypeID = ctx.getOrderTypeID()
        order = fort.getOrder(orderTypeID)
        if not order.hasBuilding:
            return self._failChecking('Order building is not built', ctx,
                                      callback)
        orderBuilding = fort.getBuilding(order.buildingID)
        if not orderBuilding.isReady():
            return self._failChecking('Building is not ready to add order',
                                      ctx, callback)
        if not perm.canActivateOrder():
            return self._failChecking('Player can not add order', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'activateOrder',
                                           orderTypeID)

    def createSortie(self, ctx, callback=None):
        level = ctx.getDivisionLevel()
        perm = self.getPermissions()
        if not perm.canCreateSortie():
            return self._failChecking(
                'Player can not create sortie, no permission', ctx, callback)
        limits = self.getLimits()
        valid, reason = limits.isSortieCreationValid(level)
        if not valid:
            return self._failChecking(
                'Player can not create sortie: {0}'.format(reason), ctx,
                callback)
        return self._requester.doRequestEx(ctx, callback, 'createSortie',
                                           level)

    def requestSortieUnit(self, ctx, callback=None):
        unitMgrID = ctx.getUnitMgrID()
        peripheryID = ctx.getPeripheryID()
        fort = self.getFort()
        if not fort:
            return self._failChecking('Client fort is not found', ctx,
                                      callback)
        if (unitMgrID, peripheryID) not in fort.sorties:
            return self._failChecking('Sortie does not exists on client', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'getSortieData',
                                           unitMgrID, peripheryID)

    def getUpgradeVisitedBuildings(self):
        return self._upgradeVisitedBuildings

    def addUpgradeVisitedBuildings(self, buildingID):
        if buildingID not in self._upgradeVisitedBuildings:
            self._upgradeVisitedBuildings.add(buildingID)
            self._listeners.notify('onUpgradeVisitedBuildingChanged',
                                   buildingID)

    def removeUpgradeVisitedBuilding(self, buildingID):
        if buildingID in self._upgradeVisitedBuildings:
            self._upgradeVisitedBuildings.remove(buildingID)
            self._listeners.notify('onUpgradeVisitedBuildingChanged',
                                   buildingID)

    def changeDefHour(self, ctx, callback=None):
        perm = self.getPermissions()
        defHour = ctx.getDefenceHour()
        if not perm.canChangeDefHour():
            return self._failChecking('Player can not change defence hour',
                                      ctx, callback)
        return self._requester.doRequestEx(ctx, callback, 'changeDefHour',
                                           defHour)

    def changeOffDay(self, ctx, callback=None):
        perm = self.getPermissions()
        offDay = ctx.getOffDay()
        if not perm.canChangeOffDay():
            return self._failChecking('Player can not change off day', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'changeOffDay',
                                           offDay)

    def changePeriphery(self, ctx, callback=None):
        perm = self.getPermissions()
        peripheryID = ctx.getPeripheryID()
        if not perm.canChangePeriphery():
            return self._failChecking('Player can not change periphery', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'changePeriphery',
                                           peripheryID)

    def changeVacation(self, ctx, callback=None):
        perm = self.getPermissions()
        timeVacationStart = ctx.getTimeVacationStart()
        timeVacationDuration = ctx.getTimeVacationDuration()
        if not perm.canChangeVacation():
            return self._failChecking('Player can not change vacation', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'changeVacation',
                                           timeVacationStart,
                                           timeVacationDuration)

    def changeSettings(self, ctx, callback=None):
        perm = self.getPermissions()
        fort = self.getFort()
        chain = []
        defHour = ctx.getDefenceHour()
        if defHour != fort.defenceHour:
            if not perm.canChangeDefHour():
                return self._failChecking('Player can not change defence hour',
                                          ctx, callback)
            chain.append(('changeDefHour', (defHour, ), {}))
        offDay = ctx.getOffDay()
        if offDay != fort.offDay:
            if not perm.canChangeOffDay():
                return self._failChecking('Player can not change off day', ctx,
                                          callback)
            chain.append(('changeOffDay', (offDay, ), {}))
        peripheryID = ctx.getPeripheryID()
        if peripheryID != fort.peripheryID:
            if not perm.canChangePeriphery():
                return self._failChecking('Player can not change periphery',
                                          ctx, callback)
            chain.append(('changePeriphery', (peripheryID, ), {}))
        if not chain:
            return self._failChecking('No requests to process', ctx, callback)
        return self._requester.doRequestChainEx(ctx, callback, chain)

    def shutDownDefHour(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canShutDownDefHour():
            return self._failChecking('Player can not shut down def hour', ctx,
                                      callback)
        return self._requester.doRequestEx(ctx, callback, 'shutdownDefHour')

    def cancelShutDownDefHour(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canCancelShutDownDefHour():
            return self._failChecking(
                'Player can not cancel shut down def hour', ctx, callback)
        return self._requester.doRequestEx(ctx, callback,
                                           'cancelDefHourShutdown')

    def requestFortPublicInfo(self, ctx, callback=None):
        fort = self.getFort()
        perm = self.getPermissions()
        if not perm.canRequestPublicInfo():
            return self._failChecking('Player can not request public info',
                                      ctx, callback)
        filterType = ctx.getFilterType()
        abbrevPattern = ctx.getAbbrevPattern()
        homePeripheryID = fort.peripheryID
        limit = ctx.getLimit()
        lvlFrom = ctx.getLvlFrom()
        lvlTo = ctx.getLvlTo()
        ownStartDefHourFrom = fort.defenceHour
        nextOwnStartDefHourFrom, defHourChangeDay = fort.getNextDefenceHourData(
        )
        extStartDefHourFrom = ctx.getStartDefHourFrom()
        extStartDefHourTo = ctx.getStartDefHourTo()
        attackDay = ctx.getAttackDay()
        ownFortLvl = fort.level
        battleStats = fort.getFortDossier().getBattlesStats()
        ownProfitFactor10 = int(battleStats.getProfitFactor() * 10)
        buildingLevels = map(attrgetter('level'),
                             fort.getBuildings().itervalues())
        minLevel = fortified_regions.g_cache.defenceConditions.minRegionLevel
        validBuildingLevels = filter(lambda x: x >= minLevel, buildingLevels)
        avgBuildingLevel10 = 0
        if validBuildingLevels:
            avgBuildingLevel10 = int(
                float(sum(validBuildingLevels)) / len(validBuildingLevels) *
                10)
        ownBattleCountForFort = battleStats.getBattlesCount()
        firstDefaultQuery = ctx.isFirstDefaultQuery()
        electedClanDBIDs = tuple(fort.favorites)
        val = self.getValidators()
        validationResult, validationReason = val.validate(
            ctx.getRequestType(), filterType, abbrevPattern)
        if not validationResult:
            self._listeners.notify('onFortPublicInfoValidationError',
                                   validationReason)
            return self._failChecking('Player input is invalid', ctx, callback)
        return self._finder.request(
            filterType, abbrevPattern, homePeripheryID, limit, lvlFrom, lvlTo,
            ownStartDefHourFrom, ownStartDefHourFrom + 1,
            nextOwnStartDefHourFrom, nextOwnStartDefHourFrom + 1,
            defHourChangeDay, extStartDefHourFrom, extStartDefHourTo,
            attackDay, ownFortLvl, ownProfitFactor10, avgBuildingLevel10,
            ownBattleCountForFort, firstDefaultQuery, electedClanDBIDs,
            callback)

    def requestClanCard(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canRequestClanCard():
            return self._failChecking('Player can not request clan card', ctx,
                                      callback)
        clanDBID = ctx.getClanDBID()
        return self._requester.doRequestEx(ctx, callback, 'getEnemyClanCard',
                                           clanDBID)

    def addFavorite(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canAddToFavorite():
            return self._failChecking('Player can not add favorite', ctx,
                                      callback)
        clanDBID = ctx.getClanDBID()
        return self._requester.doRequestEx(ctx, callback, 'addFavorite',
                                           clanDBID)

    def removeFavorite(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canRemoveFavorite():
            return self._failChecking('Player can not remove favorite', ctx,
                                      callback)
        clanDBID = ctx.getClanDBID()
        return self._requester.doRequestEx(ctx, callback, 'removeFavorite',
                                           clanDBID)

    def planAttack(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canPlanAttack():
            return self._failChecking('Player can not plan attack', ctx,
                                      callback)
        clanDBID = ctx.getClanDBID()
        timeAttack = ctx.getTimeAttack()
        dirFrom = ctx.getDirFrom()
        dirTo = ctx.getDirTo()
        return self._requester.doRequestEx(ctx, callback, 'planAttack',
                                           clanDBID, timeAttack, dirFrom,
                                           dirTo)

    def createOrJoinFortBattle(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canCreateFortBattle():
            return self._failChecking('Player can not plan attack', ctx,
                                      callback)
        battleID = ctx.getBattleID()
        slotIdx = ctx.getSlotIdx()
        return self._requester.doRequestEx(ctx, callback,
                                           'createOrJoinFortBattle', battleID,
                                           slotIdx)

    def activateConsumable(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canActivateConsumable():
            return self._failChecking('Player can not activate consumable',
                                      ctx, callback)
        orderTypeID = ctx.getConsumableOrderTypeID()
        slotIdx = ctx.getSlotIdx()
        return self._requester.doRequestEx(ctx, callback, 'activateConsumable',
                                           orderTypeID, slotIdx)

    def returnConsumable(self, ctx, callback=None):
        perm = self.getPermissions()
        if not perm.canReturnConsumable():
            return self._failChecking('Player can not return consumable', ctx,
                                      callback)
        orderTypeID = ctx.getConsumableOrderTypeID()
        return self._requester.doRequestEx(ctx, callback, 'returnConsumable',
                                           orderTypeID)

    def _setLimits(self):
        self._limits = FortLimits()

    def _setValidators(self):
        self._validators = FortValidators()

    def _addFortListeners(self):
        super(FortController, self)._addFortListeners()
        fort = self.getFort()
        if not fort:
            LOG_ERROR('No fort to subscribe')
            return
        fort.onBuildingChanged += self.__fort_onBuildingChanged
        fort.onTransport += self.__fort_onTransport
        fort.onDirectionOpened += self.__fort_onDirectionOpened
        fort.onDirectionClosed += self.__fort_onDirectionClosed
        fort.onDirectionLockChanged += self.__fort_onDirectionLockChanged
        fort.onStateChanged += self.__fort_onStateChanged
        fort.onOrderChanged += self.__fort_onOrderChanged
        fort.onDossierChanged += self.__fort_onDossierChanged
        fort.onPlayerAttached += self.__fort_onPlayerAttached
        fort.onSettingCooldown += self.__fort_onSettingCooldown
        fort.onPeripheryChanged += self.__fort_onPeripheryChanged
        fort.onDefenceHourChanged += self.__fort_onDefenceHourChanged
        fort.onOffDayChanged += self.__fort_onOffDayChanged
        fort.onVacationChanged += self.__fort_onVacationChanged
        fort.onFavoritesChanged += self.__fort_onFavoritesChanged
        fort.onEnemyClanCardReceived += self.__fort_onEnemyClanCardReceived
        fort.onShutdownDowngrade += self.__fort_onShutdownDowngrade
        fort.onDefenceHourShutdown += self.__fort_onDefenceHourShutdown
        fort.onEmergencyRestore += self.__fort_onEmergencyRestore
        fort.onConsumablesChanged += self.__fort_onConsumablesChanged
        fort.onDefenceHourActivated += self.__fort_onDefenceHourActivated
        fortMgr = getClientFortMgr()
        if not fortMgr:
            LOG_ERROR('No fort manager to subscribe')
            return
        fortMgr.onFortUpdateReceived += self.__fortMgr_onFortUpdateReceived
        fortMgr.onFortPublicInfoReceived += self.__fortMgr_onFortPublicInfoReceived
        self.__refreshCooldowns(False)
        self.__processDefencePeriodCallback()

    def _removeFortListeners(self):
        self.__cancelCooldownCallback()
        self.__cancelDefencePeriodCallback()
        fort = self.getFort()
        if fort:
            fort.onBuildingChanged -= self.__fort_onBuildingChanged
            fort.onTransport -= self.__fort_onTransport
            fort.onDirectionOpened -= self.__fort_onDirectionOpened
            fort.onDirectionClosed -= self.__fort_onDirectionClosed
            fort.onDirectionLockChanged -= self.__fort_onDirectionLockChanged
            fort.onStateChanged -= self.__fort_onStateChanged
            fort.onOrderChanged -= self.__fort_onOrderChanged
            fort.onDossierChanged -= self.__fort_onDossierChanged
            fort.onPlayerAttached -= self.__fort_onPlayerAttached
            fort.onSettingCooldown -= self.__fort_onSettingCooldown
            fort.onPeripheryChanged -= self.__fort_onPeripheryChanged
            fort.onDefenceHourChanged -= self.__fort_onDefenceHourChanged
            fort.onOffDayChanged -= self.__fort_onOffDayChanged
            fort.onVacationChanged -= self.__fort_onVacationChanged
            fort.onFavoritesChanged -= self.__fort_onFavoritesChanged
            fort.onEnemyClanCardReceived -= self.__fort_onEnemyClanCardReceived
            fort.onShutdownDowngrade -= self.__fort_onShutdownDowngrade
            fort.onDefenceHourShutdown -= self.__fort_onDefenceHourShutdown
            fort.onEmergencyRestore -= self.__fort_onEmergencyRestore
            fort.onConsumablesChanged -= self.__fort_onConsumablesChanged
            fort.onDefenceHourActivated -= self.__fort_onDefenceHourActivated
        fortMgr = getClientFortMgr()
        if fortMgr:
            fortMgr.onFortUpdateReceived -= self.__fortMgr_onFortUpdateReceived
            fortMgr.onFortPublicInfoReceived -= self.__fortMgr_onFortPublicInfoReceived
        super(FortController, self)._removeFortListeners()

    def __refreshCooldowns(self, doNotify=True):
        self.__cancelCooldownCallback()
        if self.__cooldownBuildings and doNotify:
            self._listeners.notify('onBuildingsUpdated',
                                   self.__cooldownBuildings,
                                   self.__cooldownPassed)
        fort = self.getFort()
        self.__cooldownBuildings = fort.getBuildingsOnCooldown()
        if self.__cooldownBuildings:
            time = 30
            self.__cooldownPassed = False
            for buildingID in self.__cooldownBuildings:
                building = fort.getBuilding(buildingID)
                estimatedCooldown = building.getEstimatedCooldown()
                if 0 < estimatedCooldown <= time:
                    time = estimatedCooldown
                    self.__cooldownPassed = True
                productionCooldown = building.getProductionCooldown()
                if 0 < productionCooldown < time:
                    time = productionCooldown

            self.__cooldownCallback = BigWorld.callback(
                time, self.__refreshCooldowns)

    def __cancelCooldownCallback(self):
        if self.__cooldownCallback is not None:
            LOG_DEBUG('Cooldown callback cancelling: ',
                      self.__cooldownCallback)
            BigWorld.cancelCallback(self.__cooldownCallback)
            self.__cooldownCallback = None
            self.__cooldownBuildings = []
            self.__cooldownPassed = False
        return

    def __processDefencePeriodCallback(self):
        self.__cancelDefencePeriodCallback()
        fort = self.getFort()
        self._listeners.notify('onDefenceHourStateChanged')
        start, finish = fort.getClosestDefencePeriod()
        if fort.isOnDefenceHour():
            timer = time_utils.getTimeDeltaFromNow(finish)
        else:
            timer = time_utils.getTimeDeltaFromNow(start)
        if timer > 0:
            self.__defencePeriodCallback = BigWorld.callback(
                timer, self.__processDefencePeriodCallback)

    def __cancelDefencePeriodCallback(self):
        if self.__defencePeriodCallback is not None:
            BigWorld.cancelCallback(self.__defencePeriodCallback)
            self.__defencePeriodCallback = None
        return

    def __fort_onBuildingChanged(self, buildingTypeID, reason, ctx=None):
        self._listeners.notify('onBuildingChanged', buildingTypeID, reason,
                               ctx)

    def __fort_onBuildingRemoved(self, buildingTypeID):
        self._listeners.notify('onBuildingRemoved', buildingTypeID)

    def __fort_onTransport(self):
        self._listeners.notify('onTransport')

    def __fort_onDirectionOpened(self, dir):
        self._listeners.notify('onDirectionOpened', dir)

    def __fort_onDirectionClosed(self, dir):
        self._listeners.notify('onDirectionClosed', dir)

    def __fort_onDirectionLockChanged(self):
        self._listeners.notify('onDirectionLockChanged')

    def __fort_onStateChanged(self, state):
        self._listeners.notify('onStateChanged', state)

    def __fort_onOrderChanged(self, orderTypeID, reason):
        self._listeners.notify('onOrderChanged', orderTypeID, reason)

    def __fort_onDossierChanged(self, compDossierDescr):
        self._listeners.notify('onDossierChanged', compDossierDescr)

    def __fort_onPlayerAttached(self, buildingTypeID):
        self._listeners.notify('onPlayerAttached', buildingTypeID)

    def __fort_onSettingCooldown(self, eventTypeID):
        self._listeners.notify('onSettingCooldown', eventTypeID)

    def __fort_onPeripheryChanged(self, peripheryID):
        self._listeners.notify('onPeripheryChanged', peripheryID)

    def __fort_onDefenceHourChanged(self, hour):
        self._listeners.notify('onDefenceHourChanged', hour)
        self.__processDefencePeriodCallback()

    def __fort_onDefenceHourActivated(self, hour, initiatorDBID):
        self._listeners.notify('onDefenceHourActivated', hour, initiatorDBID)
        self.__processDefencePeriodCallback()

    def __fort_onOffDayChanged(self, offDay):
        self._listeners.notify('onOffDayChanged', offDay)
        self.__processDefencePeriodCallback()

    def __fort_onVacationChanged(self, vacationStart, vacationEnd):
        self._listeners.notify('onVacationChanged', vacationStart, vacationEnd)
        self.__processDefencePeriodCallback()

    def __fort_onFavoritesChanged(self, clanDBID):
        self._listeners.notify('onFavoritesChanged', clanDBID)

    def __fort_onEnemyClanCardReceived(self, card):
        if self._publicInfoCache is not None:
            self._publicInfoCache.storeSelectedClanCard(card)
        self._listeners.notify('onEnemyClanCardReceived', card)
        return

    def __fort_onShutdownDowngrade(self):
        self._listeners.notify('onShutdownDowngrade')

    def __fort_onDefenceHourShutdown(self):
        self._listeners.notify('onDefenceHourShutdown')

    def __fortMgr_onFortUpdateReceived(self, isFullUpdate=False):
        self.__refreshCooldowns(isFullUpdate)

    def __fortMgr_onFortPublicInfoReceived(self, requestID, errorID,
                                           resultSet):
        self._finder.response(requestID, errorID, resultSet)
        self._listeners.notify('onFortPublicInfoReceived', bool(resultSet))

    def __fort_onEmergencyRestore(self):
        self.stopProcessing()

    def __fort_onConsumablesChanged(self, unitMgrID):
        self._listeners.notify('onConsumablesChanged', unitMgrID)
Пример #6
0
 def removeFortBattlesCache(self):
     FortBattlesCache._removeStoredData()