class BattleChatCommandHandler(bw2_provider.ResponseDictHandler,
                               IBattleCommandFactory):
    sessionProvider = dependency.descriptor(IBattleSessionProvider)

    def __init__(self, provider):
        super(BattleChatCommandHandler, self).__init__(provider)
        self.__factory = BattleCommandFactory()
        self.__targetIDs = []

    @property
    def factory(self):
        return self.__factory

    def clear(self):
        self.__factory = None
        self.__targetIDs = []
        super(BattleChatCommandHandler, self).clear()
        return

    def switch(self, scope):
        self.__targetIDs = []
        if scope != MESSENGER_SCOPE.BATTLE:
            return
        else:
            arena = self.sessionProvider.arenaVisitor.getArenaSubscription()
            if arena is not None:
                arena.onVehicleKilled += self.__onVehicleKilled
            return

    def send(self, decorator):
        command = decorator.getCommand()
        if command:
            provider = self.provider()
            success, reqID = provider.doAction(
                command.id, decorator.getProtoData(), True,
                not GUI_SETTINGS.isBattleCmdCoolDownVisible)
            if reqID:
                self.pushRq(reqID, command)
            if success:
                if decorator.isEnemyTarget():
                    self.__targetIDs.append(decorator.getTargetID())
                provider.setActionCoolDown(command.id, command.cooldownPeriod)
        else:
            LOG_ERROR('Battle command is not found', decorator)

    def registerHandlers(self):
        register = self.provider().registerHandler
        for command in BATTLE_CHAT_COMMANDS:
            register(command.id, self.__onCommandReceived)

        super(BattleChatCommandHandler, self).registerHandlers()

    def unregisterHandlers(self):
        unregister = self.provider().unregisterHandler
        for command in BATTLE_CHAT_COMMANDS:
            unregister(command.id, self.__onCommandReceived)

        super(BattleChatCommandHandler, self).unregisterHandlers()

    def createByName(self, name):
        return self.__factory.createByName(name)

    def createSPGAimAreaCommand(self, desiredShotPosition, cellIdx,
                                reloadTime):
        return self.__factory.createSPGAimAreaCommand(desiredShotPosition,
                                                      cellIdx, reloadTime)

    def createSPGAimTargetCommand(self, targetID, reloadTime):
        return self.__factory.createSPGAimTargetCommand(targetID, reloadTime)

    def createByNameTarget(self, name, targetID):
        return self.__factory.createByNameTarget(name, targetID)

    def createByCellIdx(self, cellIdx):
        return self.__factory.createByCellIdx(cellIdx)

    def createByPosition(self, position):
        return self.__factory.createByPosition(position)

    def createByObjectiveIndex(self, idx, isAtk):
        return self.__factory.createByObjectiveIndex(idx, isAtk)

    def createByBaseIndex(self, idx, name, isAtk):
        return self.__factory.createByBaseIndex(idx, name, isAtk)

    def createByGlobalMsgName(self, actionID, baseName=''):
        return self.__factory.createByGlobalMsgName(actionID, baseName)

    def create4Reload(self, isCassetteClip, timeLeft, quantity):
        return self.__factory.create4Reload(isCassetteClip, timeLeft, quantity)

    def _onResponseFailure(self, ids, args):
        command = super(BattleChatCommandHandler,
                        self)._onResponseFailure(ids, args)
        if command:
            error = errors.createBattleCommandError(args, command)
            if error:
                g_messengerEvents.onErrorReceived(error)
            else:
                LOG_WARNING('Error is not resolved on the client', command,
                            args)

    def __onCommandReceived(self, ids, args):
        actionID, _ = ids
        cmd = self.__factory.createByAction(actionID, args)
        if cmd.isIgnored():
            LOG_DEBUG('Chat command is ignored', cmd)
            return
        if cmd.isPrivate() and not (cmd.isReceiver() or cmd.isSender()):
            return
        g_messengerEvents.channels.onCommandReceived(cmd)

    def __onVehicleKilled(self, victimID, *args):
        provider = self.provider()
        if victimID in self.__targetIDs:
            self.__targetIDs.remove(victimID)
            for actionID in self.__factory.getEnemyTargetCommandsIDs():
                provider.clearActionCoolDown(actionID)
Example #2
0
class BattleChatCommandHandler(bw2_provider.ResponseDictHandler, IBattleCommandFactory):
    __sessionProvider = dependency.descriptor(IBattleSessionProvider)
    __settingsCore = dependency.descriptor(ISettingsCore)

    def __init__(self, provider):
        super(BattleChatCommandHandler, self).__init__(provider)
        self.__factory = BattleCommandFactory()
        self.__targetIDs = []
        self.__receivedChatCommands = {}
        self.__isEnabled = True

    @property
    def factory(self):
        return self.__factory

    def clear(self):
        self.__factory = None
        self.__targetIDs = []
        self.__receivedChatCommands = None
        super(BattleChatCommandHandler, self).clear()
        return

    def switch(self, scope):
        self.__targetIDs = []
        if scope != MESSENGER_SCOPE.BATTLE:
            return
        else:
            arena = self.__sessionProvider.arenaVisitor.getArenaSubscription()
            if arena is not None:
                arena.onVehicleKilled += self.__onVehicleKilled
                self.__isEnabled = self.__settingsCore.getSetting(BattleCommStorageKeys.ENABLE_BATTLE_COMMUNICATION)
            return

    def send(self, decorator):
        command = decorator.getCommand()
        if command:
            provider = self.provider()
            success, reqID = provider.doAction(command.id, decorator.getProtoData(), True, not GUI_SETTINGS.isBattleCmdCoolDownVisible)
            if reqID:
                self.pushRq(reqID, command)
            if success:
                if decorator.isEnemyTarget():
                    self.__targetIDs.append(decorator.getTargetID())
                provider.setActionCoolDown(command.id, command.cooldownPeriod, decorator.getTargetID())
        else:
            LOG_ERROR('Battle command is not found', decorator)

    def registerHandlers(self):
        register = self.provider().registerHandler
        for command in BATTLE_CHAT_COMMANDS:
            register(command.id, self.__onCommandReceived)

        self.__settingsCore.onSettingsChanged += self.__onSettingsChanged
        super(BattleChatCommandHandler, self).registerHandlers()

    def unregisterHandlers(self):
        unregister = self.provider().unregisterHandler
        for command in BATTLE_CHAT_COMMANDS:
            unregister(command.id, self.__onCommandReceived)

        self.__settingsCore.onSettingsChanged -= self.__onSettingsChanged
        super(BattleChatCommandHandler, self).unregisterHandlers()

    def createByName(self, name):
        return self.__factory.createByName(name)

    def createSPGAimTargetCommand(self, targetID, reloadTime):
        return self.__factory.createSPGAimTargetCommand(targetID, reloadTime)

    def createByNameTarget(self, name, targetID):
        return self.__factory.createByNameTarget(name, targetID)

    def createByPosition(self, position, name, reloadTime=0.0):
        return self.__factory.createByPosition(position, name, reloadTime)

    def createByObjectiveIndex(self, idx, isAtk):
        return self.__factory.createByObjectiveIndex(idx, isAtk)

    def createByBaseIndexAndName(self, pointId, commandName, baseName):
        return self.__factory.createByBaseIndexAndName(pointId, commandName, baseName)

    def createByGlobalMsgName(self, actionID, baseName=''):
        return self.__factory.createByGlobalMsgName(actionID, baseName)

    def create4Reload(self, isCassetteClip, timeLeft, quantity):
        return self.__factory.create4Reload(isCassetteClip, timeLeft, quantity)

    def createReplyByName(self, replyID, replyType, replierID):
        return self.__factory.createReplyByName(replyID, replyType, replierID)

    def createCancelReplyByName(self, replyID, replyType, replierID):
        return self.__factory.createCancelReplyByName(replyID, replyType, replierID)

    def createClearChatCommandsFromTarget(self, targetID, targetMarkerType):
        return self.__factory.createClearChatCommandsFromTarget(targetID, targetMarkerType)

    def _onResponseFailure(self, ids, args):
        command = super(BattleChatCommandHandler, self)._onResponseFailure(ids, args)
        if command:
            self.provider().clearActionCoolDown(command.id)
            error = errors.createBattleCommandError(args, command)
            if error:
                g_messengerEvents.onErrorReceived(error)
            else:
                LOG_WARNING('Error is not resolved on the client', command, args)

    def __isSilentMode(self, cmd):
        arenaDP = self.__sessionProvider.getArenaDP()
        if not cmd.isMuteTypeMessage() or cmd.getSenderID() == '' or arenaDP is None:
            return False
        elif arenaDP.getVehIDBySessionID(cmd.getSenderID()) == arenaDP.getPlayerVehicleID():
            return False
        else:
            silentMode = False
            currTime = BigWorld.time()
            cmdID = cmd.getID()
            key = (cmd.getSenderID(), cmdID)
            if key not in self.__receivedChatCommands:
                self.__receivedChatCommands[key] = currTime + _MUTE_CHAT_COMMAND_AND_SENDER_DURATION
            elif currTime < self.__receivedChatCommands[key]:
                silentMode = True
            else:
                self.__receivedChatCommands[key] = currTime + _MUTE_CHAT_COMMAND_AND_SENDER_DURATION
            return silentMode

    def __onSettingsChanged(self, diff):
        battleCommunicationEnabled = diff.get(BattleCommStorageKeys.ENABLE_BATTLE_COMMUNICATION)
        if not battleCommunicationEnabled:
            return
        self.__isEnabled = bool(battleCommunicationEnabled)

    def __onCommandReceived(self, ids, args):
        actionID, _ = ids
        cmd = self.__factory.createByAction(actionID, args)
        if self.__isEnabled is False:
            return
        silentMode = self.__isSilentMode(cmd)
        if silentMode:
            cmd.setSilentMode(silentMode)
        if cmd.isIgnored():
            g_mutedMessages[cmd.getFirstTargetID()] = cmd
            LOG_DEBUG('Chat command is ignored', cmd)
            return
        if cmd.isPrivate() and not (cmd.isReceiver() or cmd.isSender()):
            return
        g_messengerEvents.channels.onCommandReceived(cmd)

    def __onVehicleKilled(self, victimID, *args):
        provider = self.provider()
        if victimID in self.__targetIDs:
            self.__targetIDs.remove(victimID)
            for actionID in self.__factory.getEnemyTargetCommandsIDs():
                provider.clearActionCoolDown(actionID)
Example #3
0
class BattleChatCommandHandler(bw2_provider.ResponseDictHandler, IBattleCommandFactory):
    __sessionProvider = dependency.descriptor(IBattleSessionProvider)
    __settingsCore = dependency.descriptor(ISettingsCore)

    def __init__(self, provider):
        super(BattleChatCommandHandler, self).__init__(provider)
        self.__factory = BattleCommandFactory()
        self.__targetIDs = []
        self.__receivedChatCommands = {}
        self.__isEnabled = True

    @property
    def factory(self):
        return self.__factory

    def clear(self):
        self.__factory = None
        self.__targetIDs = []
        self.__receivedChatCommands = None
        super(BattleChatCommandHandler, self).clear()
        return

    @loggerEntry
    def switch(self, scope):
        self.__targetIDs = []
        if scope != MESSENGER_SCOPE.BATTLE:
            return
        else:
            arena = self.__sessionProvider.arenaVisitor.getArenaSubscription()
            if arena is not None:
                arena.onVehicleKilled += self.__onVehicleKilled
                self.__isEnabled = self.__settingsCore.getSetting(BattleCommStorageKeys.ENABLE_BATTLE_COMMUNICATION)
            return

    @simpleLog(argsIndex=0, preProcessAction=lambda x: x.getCommand().name, resetTime=False)
    def send(self, decorator):
        command = decorator.getCommand()
        if command:
            provider = self.provider()
            success, reqID = provider.doAction(command.id, decorator.getProtoData(), True, not GUI_SETTINGS.isBattleCmdCoolDownVisible)
            if reqID:
                self.pushRq(reqID, command)
            if success:
                if decorator.isEnemyTarget():
                    self.__targetIDs.append(decorator.getTargetID())
                if _ACTIONS.isBattleChatAction(command.id):
                    cooldownConfig = getCooldownGameModeDataForGameMode(self.__sessionProvider.arenaVisitor.getArenaBonusType())
                    provider.setBattleActionCoolDown(reqID, command.id, decorator.getTargetID(), cooldownConfig)
                else:
                    provider.setActionCoolDown(command.id, command.cooldownPeriod)
        else:
            _logger.error('Battle command is not found %r', decorator)

    def registerHandlers(self):
        register = self.provider().registerHandler
        for command in BATTLE_CHAT_COMMANDS:
            register(command.id, self.__onCommandReceived)

        self.__settingsCore.onSettingsChanged += self.__onSettingsChanged
        super(BattleChatCommandHandler, self).registerHandlers()

    def unregisterHandlers(self):
        unregister = self.provider().unregisterHandler
        for command in BATTLE_CHAT_COMMANDS:
            unregister(command.id, self.__onCommandReceived)

        self.__settingsCore.onSettingsChanged -= self.__onSettingsChanged
        super(BattleChatCommandHandler, self).unregisterHandlers()

    def createByName(self, name):
        return self.__factory.createByName(name)

    def createSPGAimTargetCommand(self, targetID, reloadTime):
        return self.__factory.createSPGAimTargetCommand(targetID, reloadTime)

    def createByNameTarget(self, name, targetID):
        return self.__factory.createByNameTarget(name, targetID)

    def createByPosition(self, position, name, reloadTime=0.0):
        return self.__factory.createByPosition(position, name, reloadTime)

    def createByObjectiveIndex(self, idx, isAtk, actionName):
        return self.__factory.createByObjectiveIndex(idx, isAtk, actionName)

    def createByBaseIndexAndName(self, pointId, commandName, baseName):
        return self.__factory.createByBaseIndexAndName(pointId, commandName, baseName)

    def createByGlobalMsgName(self, actionID, baseName=''):
        return self.__factory.createByGlobalMsgName(actionID, baseName)

    def create4Reload(self, isCassetteClip, timeLeft, quantity):
        return self.__factory.create4Reload(isCassetteClip, timeLeft, quantity)

    def createReplyByName(self, replyID, replyType, replierID):
        return self.__factory.createReplyByName(replyID, replyType, replierID)

    def createCancelReplyByName(self, replyID, replyType, replierID):
        return self.__factory.createCancelReplyByName(replyID, replyType, replierID)

    def createClearChatCommandsFromTarget(self, targetID, targetMarkerType):
        return self.__factory.createClearChatCommandsFromTarget(targetID, targetMarkerType)

    def _onResponseFailure(self, ids, args):
        command = super(BattleChatCommandHandler, self)._onResponseFailure(ids, args)
        if command:
            if _ACTIONS.isBattleChatAction(command.id):
                self.provider().clearBattleActionCoolDown(ids, command.id)
            else:
                self.provider().clearActionCoolDown(command.id)
            error = errors.createBattleCommandError(args, command)
            if error:
                g_messengerEvents.onErrorReceived(error)
            else:
                _logger.warning('Error is not resolved on the client %d, %r', command.getID(), args)

    def __isSilentModeForEpicBattleMode(self, cmd):
        mapsCtrl = self.__sessionProvider.dynamic.maps
        if mapsCtrl.overviewMapScreenVisible:
            return False
        respawnCtrl = self.__sessionProvider.dynamic.respawn
        if respawnCtrl and respawnCtrl.isRespawnVisible():
            return False
        senderSessionID = cmd.getSenderID()
        senderVID = self.__sessionProvider.getArenaDP().getVehIDBySessionID(senderSessionID)

        def isPositionOnMinimap(position):
            if position == INVALID_VEHICLE_POSITION:
                return False
            minimapCenter = mapsCtrl.getMinimapCenterPosition()
            halfMinimapWidth = mapsCtrl.getMinimapZoomMode() * _EPIC_MINIMAP_ZOOM_MODE_SCALE
            return False if not minimapCenter.x - halfMinimapWidth <= position.x <= minimapCenter.x + halfMinimapWidth or not minimapCenter.z - halfMinimapWidth <= position.z <= minimapCenter.z + halfMinimapWidth else True

        shouldBeSilent = False
        if senderVID != BigWorld.player().playerVehicleID:
            senderPos = mapsCtrl.getVehiclePosition(senderVID)
            senderInRange = isPositionOnMinimap(senderPos)
        else:
            senderInRange = True
        if cmd.isVehicleRelatedCommand():
            targetInRange = senderInRange
            if cmd.hasTarget():
                targetPos = mapsCtrl.getVehiclePosition(cmd.getFirstTargetID())
                targetInRange = isPositionOnMinimap(targetPos)
            shouldBeSilent = not (senderInRange or targetInRange)
        elif cmd.isLocationRelatedCommand():
            markingPos = cmd.getMarkedPosition()
            shouldBeSilent = not (senderInRange or isPositionOnMinimap(markingPos))
        elif cmd.isBaseRelatedCommand() or cmd.isMarkedObjective():
            shouldBeSilent = False
        if cmd.isEpicGlobalMessage():
            shouldBeSilent = False
        return shouldBeSilent

    def __isSilentMode(self, cmd):
        arenaDP = self.__sessionProvider.getArenaDP()
        if not cmd.isMuteTypeMessage() or cmd.getSenderID() == '' or arenaDP is None:
            return False
        elif arenaDP.getVehIDBySessionID(cmd.getSenderID()) == arenaDP.getPlayerVehicleID():
            return False
        else:
            silentMode = False
            currTime = BigWorld.time()
            cmdID = cmd.getID()
            key = (cmd.getSenderID(), cmdID)
            if key not in self.__receivedChatCommands:
                self.__receivedChatCommands[key] = currTime + _MUTE_CHAT_COMMAND_AND_SENDER_DURATION
            elif currTime < self.__receivedChatCommands[key]:
                silentMode = True
            else:
                self.__receivedChatCommands[key] = currTime + _MUTE_CHAT_COMMAND_AND_SENDER_DURATION
            return silentMode

    def __onSettingsChanged(self, diff):
        battleCommunicationEnabled = diff.get(BattleCommStorageKeys.ENABLE_BATTLE_COMMUNICATION)
        if not battleCommunicationEnabled:
            return
        self.__isEnabled = bool(battleCommunicationEnabled)

    def __onCommandReceived(self, ids, args):
        actionID, _ = ids
        cmd = self.__factory.createByAction(actionID, args)
        if self.__isEnabled is False:
            return
        else:
            silentMode = self.__isSilentMode(cmd)
            if not silentMode and self.__sessionProvider.arenaVisitor.getArenaBonusType() == ARENA_BONUS_TYPE.EPIC_BATTLE:
                silentMode = self.__isSilentModeForEpicBattleMode(cmd)
            if silentMode:
                cmd.setSilentMode(silentMode)
            if cmd.isIgnored():
                g_mutedMessages[cmd.getFirstTargetID()] = cmd
                _logger.debug("Chat command '%s' is ignored", cmd.getCommandText())
                return
            if cmd.isPrivate() and not (cmd.isReceiver() or cmd.isSender()):
                return
            arenaDP = self.__sessionProvider.getArenaDP()
            if arenaDP is not None:
                if arenaDP.isObserver(arenaDP.getPlayerVehicleID()) and (cmd.isReply() or cmd.isCancelReply() or cmd.isAutoCommit()):
                    return
            g_messengerEvents.channels.onCommandReceived(cmd)
            return

    def __onVehicleKilled(self, victimID, *args):
        provider = self.provider()
        if victimID in self.__targetIDs:
            self.__targetIDs.remove(victimID)
            for actionID in self.__factory.getEnemyTargetCommandsIDs():
                provider.clearActionCoolDown(actionID)