def generate_loot(self, action: str, json_data: Any) -> None:
        """
        Method to generate loot after passing the dungeon
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """

        if self.connected_users[self.user_key]['authorized']:
            if self.connected_users[self.user_key]['main'][
                    'dungeon']:  # fixme check if dungeon complete
                available_loot = self.cursor.get_loot()
                self.connected_users[
                    self.user_key]['main']['dungeon']['passed'] = True
                result = LootModule.LootModule(dungeon=self.connected_users[
                    self.user_key]['main']['dungeon']['skeleton'],
                                               player=self.player,
                                               loot=available_loot).get_loot()
                result['level'] = self.player.level_up(
                    received_experience=result['level'])
                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=204, data=result))
                del result
                del available_loot
            else:
                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=410))
        else:
            self.send_one(response=UtilityModule.generate_response(
                action=action, code=406))
    def lineReceived(self, line: bytes):
        """
        Receive line and parse it to json_data.
        Call method depending on action stored in json_data
        :param line:
        :return:
        """

        try:
            json_data = json.loads(line.decode("utf8"))
            action = json_data['action']

            try:
                self.log_to_debug(line=f"Received line: {json_data}")
                if action in self.actions:
                    self.actions.get(action)(action, json_data)
                else:
                    self.send_one(
                        response=self.actions.get("default")(action, 403))

            except Exception as exception:
                self.log_file.log_all(priority=2, string=str(exception))
                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=400))

        except json.decoder.JSONDecodeError as json_decode_error:
            self.log_file.log_all(priority=2, string=str(json_decode_error))
            self.send_one(response=UtilityModule.generate_response(action=None,
                                                                   code=401))
    def get_dungeon_skeleton(self, action: str, json_data: Any) -> None:
        """
        Generate and send dungeon skeleton for the player
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """

        try:
            if self.connected_users[self.user_key].get('authorized'):
                skeleton = self.dungeon_generator.final_dungeon_skeleton(
                    player_data=self.player)
                self.connected_users[self.user_key]['main']['dungeon'] = {
                    'skeleton': skeleton,
                    'passed': False
                }
                self.send_one(response=UtilityModule.generate_response(
                    action=action,
                    code=201,
                    data={"dungeonSkeleton": skeleton}))
            else:
                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=406))

        except Exception as exception:
            self.log_file.log_all(priority=2, string=str(exception))
            self.send_one(response=UtilityModule.generate_response(
                action=action, code=400))
    def send_private_message(self, action: str, json_data: Any) -> None:
        """
        Sending message to the another specified user from a specified player
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """

        data = {
            'from': self.player.player_name,
            'to': json_data['data']['to'],
            'message': json_data['data']['message']
        }
        try:
            self.send_to_spec_user(to_player=json_data['data']['to'],
                                   message=UtilityModule.generate_response(
                                       action=action, code=200, data=data))
        except ChatExceptions.ChatException:
            self.send_one(response=UtilityModule.generate_response(
                action=action, code=407))
    def start_battle(self, action: str, json_data: Any) -> None:
        """
        Method for invoking battle between a player and given enemy
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """

        battle = BattleModule.BattleModule(
            player=self.player, battle_data=json_data['data']).battle_result()
        self.send_one(response=UtilityModule.generate_response(
            action=action, code=205, data=battle))
    def __init__(self, player_data: dict):
        super().__init__()
        self.player_id = player_data.get('main')[0]['player_id']
        self.player_name = player_data.get('main')[0]['player_name']
        self.level = player_data.get('main')[0]['lvl']
        self.experience = player_data.get('main')[0]['experience']
        self.class_id = player_data.get('main')[0]['class_id']
        self.class_name = player_data.get('main')[0]['class_name']
        self.race_id = player_data.get('main')[0]['race_id']
        self.race = player_data.get('main')[0]['race']

        self.armor_class = player_data.get('main')[0]['armor_class']
        self.hits = player_data.get('main')[0]['hits']
        self.speed = player_data.get('main')[0]['speed']
        self.strength = player_data.get('main')[0]['strength']
        self.dexterity = player_data.get('main')[0]['dexterity']
        self.intelligence = player_data.get('main')[0]['intelligence']
        self.wisdom = player_data.get('main')[0]['wisdom']
        self.chance = player_data.get('main')[0]['chance']
        self.constitution = player_data.get('main')[0]['constitution']

        self.food = UtilityModule.serialize_data(player_data, 'food')
        self.armor = UtilityModule.serialize_data(player_data, 'armor')
        self.weapons = UtilityModule.serialize_data(player_data, 'weapons')
        self.animals = UtilityModule.serialize_data(player_data, 'animals')
        self.vulnerabilities = UtilityModule.serialize_data(
            player_data, 'vulnerabilities')
        self.attacks = UtilityModule.serialize_data(player_data, 'attacks')

        self.base_exp_for_level = 300
        self.exp_multiplier = 2.35
    def player_registration(self, action: str, json_data: Any) -> None:
        """
        Registration of specified player
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """

        try:
            if self.cursor.check_player_name(
                    name=json_data['data']['player_name']) == 1:
                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=405))

            elif self.cursor.add_player(
                    name=json_data['data']['player_name'],
                    password=UtilityModule.encrypt_password(
                        player_password=json_data['data']['player_password']),
                    class_id=json_data['data']['class_id'],
                    race_id=json_data['data']['race_id']) == 1:

                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=202))

                self.log_account_info(
                    username=json_data['data']['player_name'],
                    password=json_data['data']['player_password'])

                self.log_file.log_all(
                    priority=3,
                    string=
                    f"Player < {json_data['data']['player_name']} > successfully registered"
                )

        except DBExceptions.QueryExecuteError as query_exec_error:
            self.send_one(response=UtilityModule.generate_response(
                action=action, code=400))
            self.log_file.log_all(priority=2, string=str(query_exec_error))
    def send_chat_message(self, action: str, json_data: Any) -> None:
        """
        Sending message to the cat from a specified player
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """

        data = {
            'from': self.player.player_name,
            'message': json_data['data']['message']
        }
        self.send_all(message=UtilityModule.generate_response(
            action=action, code=200, data=data))
    def connectionMade(self):
        """
        Sending response that connection made and adding to connections list
        :return:
        """

        self.connected_users[self.user_key] = {
            "host": self.addr.host,
            "type": self.addr.type,
            "authorized": False,
            "main": {
                "player_name": None,
                "base": None,
                "dungeon": None
            },
        }
        self.log_to_debug(
            line=f"{self.addr.host}:{self.addr.port} Connected...")
        self.log_file.log_all(
            priority=3,
            string=f"{self.addr.host}:{self.addr.port} Connected to server")
        self.send_one(response=UtilityModule.generate_response(
            action="connectToServer", code=100))
    def player_authorization(self, action: str, json_data: Any) -> None:
        """
        Authorization of specified player
        :param action: String used to generate response
        :param json_data: Received data from the client
        :return:
        """
        def check_for_user_not_in_system(player_name: str) -> bool:
            """
            Checking if user with given username already logged
            :param player_name:
            :return:
            """

            for uid, user in self.connected_users.items():
                if user['authorized'] and user['main'][
                        'player_name'] == player_name:
                    return False
            return True

        try:
            if self.cursor.check_player_name(
                    name=json_data['data']['player_name']) == 1:
                if check_for_user_not_in_system(json_data['data']['player_name']) \
                        or len(self.connected_users) == 1:
                    if self.cursor.check_player(
                            name=json_data['data']['player_name'],
                            password=UtilityModule.encrypt_password(
                                player_password=json_data['data']
                                ['player_password'])) == 1:
                        self.player = UserModule(
                            player_data=self.cursor.get_player(
                                player_name=json_data['data']['player_name']))

                        self.connected_users[self.user_key]['main'][
                            'player_name'] = self.player.player_name
                        self.connected_users[
                            self.user_key]['main']['base'] = self
                        self.connected_users[
                            self.user_key]['authorized'] = True

                        self.send_one(response=UtilityModule.generate_response(
                            action=action,
                            code=203,
                            data=self.player.get_player()))
                        self.log_file.log_all(
                            priority=3,
                            string=
                            f"Player < {json_data['data']['player_name']} > successfully authorized"
                        )
                    else:
                        self.send_one(response=UtilityModule.generate_response(
                            action=action, code=408))
                else:
                    self.send_one(response=UtilityModule.generate_response(
                        action=action, code=409))
            else:
                self.send_one(response=UtilityModule.generate_response(
                    action=action, code=408))
        except DBExceptions.QueryExecuteError as query_exec_error:
            self.send_one(response=UtilityModule.generate_response(
                action=action, code=400))
            self.log_file.log_all(priority=2, string=str(query_exec_error))