Exemplo n.º 1
0
 async def handle_permission_request(self, client: WvsLoginClient,
                                     packet: Packet):
     locale = packet.decode_byte()
     version = packet.decode_short()
     minor_version = packet.decode_string()
     if locale != server_constants.LOCALE or version != server_constants.SERVER_VERSION:
         client.close()
Exemplo n.º 2
0
    def create_new_char_result(success: LoginType, char: Character):
        send_packet = Packet(opcode=OutPacket.CREATE_NEW_CHARACTER_RESULT)

        send_packet.encode_byte(success.value)

        if success == LoginType.Success:
            char.cosmetic_info.encode_cosmetic(send_packet)

        return send_packet
Exemplo n.º 3
0
    def send_start_client():
        """Returns the client start packet

        :return: Packet
        """
        send_packet = Packet(opcode=OutPacket.CLIENT_START)

        send_packet.encode_byte(False)  # encode byte

        return send_packet
Exemplo n.º 4
0
    def send_auth_server(use_auth_server: bool):
        """
        :param use_auth_server: boolean
        :return: Packet
        """
        send_packet = Packet(opcode=OutPacket.AUTH_SERVER)

        send_packet.encode_byte(use_auth_server)

        return send_packet
Exemplo n.º 5
0
    def send_connect(siv, riv):

        send_packet = Packet(opcode=15)

        send_packet.encode_short(server_constants.SERVER_VERSION)
        send_packet.encode_string(server_constants.MINOR_VERSION)
        send_packet.encode_int(riv)
        send_packet.encode_int(siv)
        send_packet.encode_byte(server_constants.LOCALE)

        return send_packet
Exemplo n.º 6
0
    async def handle_select_world(self, client: WvsLoginClient,
                                  packet: Packet):
        unk1 = packet.decode_byte()
        world_id = packet.decode_byte()
        channel = packet.decode_byte(
        ) + 1  # We add one cause channels start at index 0 client-side
        success_code = 0
        user = client.user

        # Check if the instanced "user" object has accounts already instantiated
        if len(user.accounts) > 0:
            account = user.accounts[0]
            # We get the first one cause user should only have one account in this source
        else:
            account = user.get_account_from_db()

        world = global_states.worlds[
            0]  # This way only allows us to have one world will change in the future

        if user is not None and world is not None and world.get_channel_by_id(
                channel) is not None:
            if account is None:
                account = Account(user=user, world_id=world_id)
                account.account_id = await database_manager.get_next_available_acc_id(
                )
                account.init_characters()
                await database_manager.create_account(
                    account
                )  # create a new row in SQL if account doesn't exist
            user.add_account(account)
            client.account = account
            client.world_id = world_id
            client.channel = channel

            await client.send_packet(
                Login.select_world_result(user=client.user,
                                          account=client.account,
                                          success_code=success_code,
                                          special_server="normal",
                                          burning_event_block=False))
        else:
            await client.send_packet(
                Login.select_character_result(
                    login_type=LoginType.UnauthorizedUser,
                    error_code=0,
                    port=0,
                    character_id=0,
                ))
Exemplo n.º 7
0
def encode(out_packet: Packet):
    out_packet.encode_byte(ENABLE_JOBS)
    out_packet.encode_byte(JOB_ORDER)
    for job_info in LOGIN_JOB.values():
        job_type = job_info[0]
        job_flag = job_info[1]
        job_enum = job_info[2]
        out_packet.encode_byte(job_flag.value)
        out_packet.encode_short(job_flag.value)
Exemplo n.º 8
0
    def send_world_info_end():
        send_packet = Packet(opcode=OutPacket.WORLD_INFORMATION)
        send_packet.encode_int(255)

        # Possible Ads encoding
        # ads = 0
        #
        # advertisement = None if not ads else Advertisement()
        # send_packet.encode_byte(ads)
        #
        # for i in range(ads):
        #     advertisement.encode(out_packet=send_packet)
        #
        # send_packet.encode_byte(0)  # NotActiveAccountDlgFocus
        # send_packet.encode_int(49)  # lockAccount Connection count

        return send_packet
Exemplo n.º 9
0
    async def handle_check_login_auth_info(self, client: WvsLoginClient,
                                           packet: Packet):
        """Where logging in is handled, passwords/username etc"""
        sid = packet.decode_byte()
        password = packet.decode_string()
        username = packet.decode_string()
        machine_id = packet.decode_buffer(16)

        success = False
        result = None
        # db_user is a database object, setting anything would set it in the database: SwordieDB()
        db_user = await database_manager.get_user_from_db(username)
        # this user is the User object in the source
        user = None

        if db_user is None and AUTO_REGISTER:
            # if there is no user in the database we register one
            await database_manager.register_user(username, password)
            await client.send_packet(
                WvsContext.broadcast_msg(
                    BroadcastMsg.pop_up_message(
                        "Your account has now been registered.")))

        if db_user is not None:
            if password.lower() == "fixme":
                # TODO, implement a loggedin check
                await client.send_packet(
                    WvsContext.broadcast_msg(
                        BroadcastMsg.pop_up_message(
                            "Your account is now logged out.")))
            db_password = db_user.password
            success = db_password == password
            result = LoginType.Success if success else LoginType.IncorrectPassword
            if success:
                user = await User.get_user_from_name(username)
                client.user = user
        else:
            result = LoginType.NotRegistered

        await client.send_packet(
            Login.check_password_result(success, result, user))
Exemplo n.º 10
0
    def send_server_status(world_id: int):
        send_packet = Packet(opcode=OutPacket.SERVER_STATUS)
        world = None
        for world_created in worlds:
            if world_created.world_id == world_id:
                world = world_created
        if world is not None and not world.is_full():
            send_packet.encode_byte(ServerStatus.NORMAL.value)
        else:
            send_packet.encode_byte(ServerStatus.BUSY.value)

        send_packet.encode_byte(0)  # unknown

        return send_packet
Exemplo n.º 11
0
    async def handle_char_select_no_pic(self, client: WvsLoginClient,
                                        packet: Packet):
        """
        Pic Creation, if the user does not already have a Pic
        Parameters
        ----------
        client: WvsLoginClient
        packet: Packet

        -------

        """
        packet.decode_buffer(2)
        char_id = packet.decode_int()
        mac = packet.decode_string()
        unknown_string = packet.decode_string()
        pic = packet.decode_string()
        client.user.pic = pic  # TODO: Hash Pic here if you choose to do so.

        await client.user.save()

        if client.user.get_first_account().get_char_by_id(char_id) is None:
            await client.send_packet(
                Login.select_character_result(LoginType.UnauthorizedUser, 0, 0,
                                              0))
            return

        world_id = client.world_id
        channel_id = client.channel
        # Note: We get the first world in worlds list in global_states.py (Not the best solution).
        channel = global_states.worlds[0].get_channel_by_id(channel_id)
        await client.send_packet(
            Login.select_character_result(LoginType.Success, 0, channel.port,
                                          char_id))
Exemplo n.º 12
0
    def check_duplicated_id_result(name: str,
                                   char_name_result: CharNameResult):
        send_packet = Packet(opcode=OutPacket.CHECK_DUPLICATED_ID_RESULT)

        send_packet.encode_string(name)
        send_packet.encode_byte(char_name_result.value)

        return send_packet
Exemplo n.º 13
0
    async def handle_check_duplicate_id(self, client: WvsLoginClient,
                                        packet: Packet):
        """
        The Packet Handler for checking if a name is taken during character creation

        Parameters
        ----------
        client: WvsLoginClient
        packet: Packet

        -------

        """
        name = packet.decode_string()
        code = None
        if name.lower() in BLOCKED_NAMES:
            code = CharNameResult.Unavailable_Invalid
        else:
            name_taken = await database_manager.check_name_taken(name)
            code = CharNameResult.Unavailable_InUse if name_taken else CharNameResult.Available

        await client.send_packet(Login.check_duplicated_id_result(name, code))
Exemplo n.º 14
0
    async def receive(self, client):
        self._is_online = True
        while self._is_online:
            if not self._overflow:
                recv_buffer = await self._loop.sock_recv(
                    self._socket, self.receive_size)

                if not recv_buffer:
                    client._parent.on_client_disconnect(client)
                    return

            else:
                recv_buffer = self._overflow
                self._overflow = None

            if self.riv:
                async with self._lock:
                    length = MapleAes.get_length(recv_buffer)
                    if length != len(recv_buffer) - 4:
                        self._overflow = recv_buffer[length + 4:]
                        recv_buffer = recv_buffer[:length + 4]
                    recv_buffer = self.manipulate_buffer(recv_buffer)

            client.dispatch(Packet(recv_buffer))
Exemplo n.º 15
0
    async def handle_client_error(self, client: WvsLoginClient,
                                  packet: Packet):
        client.close()
        if packet.get_length() < 8:
            debug.error(f"Error: {packet.to_string()}")
            return
        error_str_type = packet.decode_short()
        type_str = ""

        if error_str_type == 0x01:
            type_str = "SendBackupPacket"
        elif error_str_type == 0x02:
            type_str = "CrashReport"
        elif error_str_type == 0x03:
            type_str = "Exception"

        error_type = packet.decode_int()
        data_length = packet.decode_short()
        unk1 = packet.decode_int()

        opcode = packet.decode_short()
        debug.error(f"Error {error_type} at Opcode: {opcode}")
Exemplo n.º 16
0
 def encode(self, out_packet: Packet):
     out_packet.encode_string(self.striking_image)
     out_packet.encode_string(self.address_to_move)
     out_packet.encode_int(self.duration)
     out_packet.encode_int(self.width)
     out_packet.encode_int(self.height)
     out_packet.encode_int(self.x_pos)
     out_packet.encode_int(self.y_pos)
Exemplo n.º 17
0
    def send_auth_response(response: bool):
        send_packet = Packet(opcode=OutPacket.PRIVATE_SERVER_PACKET)

        send_packet.encode_int(response)

        return send_packet
Exemplo n.º 18
0
 def send_recommended_world_msg(world_id: int, msg: str):
     send_packet = Packet(opcode=OutPacket.RECOMMENDED_WORLD_MESSAGE)
     send_packet.encode_byte(1)
     send_packet.encode_int(world_id)
     send_packet.encode_string(msg)
     return send_packet
Exemplo n.º 19
0
    def send_world_information(world: World, string_infos: List[Tuple]):
        send_packet = Packet(opcode=OutPacket.WORLD_INFORMATION)

        send_packet.encode_byte(world.world_id)
        send_packet.encode_string(world.name)
        send_packet.encode_byte(world.world_state)
        send_packet.encode_string(world.world_event_description)
        send_packet.encode_short(world.world_event_exp_wse)
        send_packet.encode_short(world.world_event_drop_wse)
        send_packet.encode_byte(world.char_create_block)
        send_packet.encode_byte(world.get_channel_size())

        for channel in world.channels:
            send_packet.encode_string(channel.name)
            send_packet.encode_int(channel.get_gauge_percent())
            send_packet.encode_byte(channel.world_id)
            send_packet.encode_byte(channel.channel_id)
            send_packet.encode_byte(channel.adult_channel)

        if string_infos is None:
            send_packet.encode_short(0)
        else:
            send_packet.encode_short(len(string_infos))
            for string_info in string_infos:
                send_packet.encode_position(string_info[0])
                send_packet.encode_string(string_info[1])

        send_packet.encode_int(0)  # some Offset
        send_packet.encode_byte(world.star_planet)

        return send_packet
Exemplo n.º 20
0
    def select_world_result(user: User, account: Account, success_code: int,
                            special_server: str,
                            burning_event_block: bool) -> Packet:
        """
        The packet that is sent to client when they Select a World (scania, etc)
        Parameters
        ----------
        user: User
        account: Account
        success_code: int
        special_server: string
        burning_event_block: bool

        Returns: Packet
        -------

        """
        send_packet = Packet(opcode=OutPacket.SELECT_WORLD_RESULT)

        send_packet.encode_byte(success_code)
        send_packet.encode_string(special_server)
        send_packet.encode_int(14)  # trunk/storage slot count
        send_packet.encode_byte(burning_event_block)

        reserved = 0
        send_packet.encode_int(reserved)  # Reserved size
        send_packet.encode_ft(FileTime(FileTimeType.ZERO_TIME))

        for i in range(reserved):
            # FileTime
            send_packet.encode_int(0)
            # ft.encode()

        is_edited = False
        send_packet.encode_byte(is_edited)

        chars = account.characters
        chars.sort(key=lambda x: x.chr_id)  # Sort by character ID
        char_size = len(chars)

        send_packet.encode_int(char_size)

        for char in chars:
            send_packet.encode_int(char.chr_id)

        send_packet.encode_byte(char_size)

        for char in chars:
            char.cosmetic_info.encode_cosmetic(send_packet)
            send_packet.encode_byte(False)  # Family Stuff
            has_ranking = char.ranking is not None and not job_constants.is_gm_job(
                char.job_id)
            send_packet.encode_byte(False)
            if has_ranking:
                char.ranking.encode(send_packet)  # TODO: Rankings encode

        send_packet.encode_byte(user.get_pic_status().value)  # bLoginOpt
        send_packet.encode_byte(False)  # bQuerySSNOnCreateNewCharacter
        send_packet.encode_int(user.character_slots)
        send_packet.encode_int(0)
        send_packet.encode_int(-1)  # nEventNewCharJob
        send_packet.encode_ft(FileTime(FileTimeType.ZERO_TIME))

        send_packet.encode_byte(0)  # RenameCount
        send_packet.encode_byte(0)

        return send_packet
Exemplo n.º 21
0
    async def handle_create_new_char(self, client: WvsLoginClient,
                                     packet: Packet):
        """
        This is where character creation entry begins.
        Parameters
        ----------
        client: WvsLoginClient
        packet: Packet

        -------

        """
        account = client.account
        name = packet.decode_string()
        key_setting_type = packet.decode_int()
        event_new_char_sale_job = packet.decode_int()
        cur_selected_race = packet.decode_int()
        job = job_constants.get_login_job_by_id(cur_selected_race)[2]
        cur_selected_sub_job = packet.decode_short()
        gender = packet.decode_byte()
        skin = packet.decode_byte()

        item_length = packet.decode_byte()
        items = [packet.decode_int() for i in range(item_length)]

        face = items[0]
        hair = items[1]

        name_result_code = None
        # Add a check if starting items are valid
        if skin > 13 or skin < 0 or face < 20000 or face > 29999 or hair < 30000 or hair > 49999:
            print(
                f"{name} tried to add items unavailable on character creation")
            name_result_code = CharNameResult.Unavailable_CashItem

        name_taken = await database_manager.check_name_taken(name)

        if name in BLOCKED_NAMES:
            name_result_code = CharNameResult.Unavailable_Invalid
        elif name_taken:
            name_result_code = CharNameResult.Unavailable_InUse

        if name_result_code is not None:
            await client.send_packet(
                Login.check_duplicated_id_result(name, name_result_code))
            return
        char_id = await database_manager.get_next_available_chr_id()
        char = Character(
            chr_id=char_id,
            acc_id=account.account_id,
            key_setting_type=key_setting_type,
            name=name,
            job_id=job.value[0],
            cur_selected_sub_job=cur_selected_sub_job,
            gender=gender,
            skin=skin,
            face=face,
            hair=hair,
            items=items,
        )

        # TODO: Add Job Manager to Char
        char = await char.init_in_db()
        char_stat = char.cosmetic_info.character_stat

        if cur_selected_race == job_constants.LOGIN_JOB['DUAL_BLADE'][0]:
            char_stat.sub_job = 1

        char_stat.world_id_for_log = account.world_id

        for hair_id in char.cosmetic_info.cosmetic_look.hair_equips:
            # TODO: Add item to inventory
            pass

        # TODO: Codex
        account.characters.append(char)
        await char.save()
        await account.save()
        await client.send_packet(
            Login.create_new_char_result(LoginType.Success, char))
Exemplo n.º 22
0
 async def handle_world_status_request(self, client: WvsLoginClient,
                                       packet: Packet):
     world_id = packet.decode_byte()
     await client.send_packet(Login.send_server_status(world_id))
Exemplo n.º 23
0
    def select_character_result(login_type: LoginType, error_code, port,
                                character_id):
        send_packet = Packet(opcode=OutPacket.SELECT_CHARACTER_RESULT)
        send_packet.encode_byte(login_type.value)
        send_packet.encode_byte(error_code)
        if login_type == LoginType.Success:
            server = [8, 31, 99, 141]
            send_packet.encode_arr(server)
            send_packet.encode_short(port)

            chat_server = [8, 31, 99, 141]
            send_packet.encode_arr(chat_server)
            send_packet.encode_short(CHAT_PORT)

            send_packet.encode_int(character_id)
            send_packet.encode_byte(0)
            send_packet.encode_int(0)  # ulArgument
            send_packet.encode_byte(0)
            send_packet.encode_int(0)
            send_packet.encode_int(0)
            send_packet.encode_byte(0)

        return send_packet
Exemplo n.º 24
0
    async def initialize(self):
        # Handshake packet
        send_packet = Packet(opcode=15)

        send_packet.encode_short(server_constants.SERVER_VERSION)
        send_packet.encode_string(server_constants.MINOR_VERSION)
        send_packet.encode_unsigned_int(self.socket.riv.value)
        send_packet.encode_unsigned_int(self.socket.siv.value)
        send_packet.encode_byte(server_constants.LOCALE)
        send_packet.encode_byte(False)

        await self.send_packet_raw(send_packet)

        await self.receive()
Exemplo n.º 25
0
 def encode(self, out_packet: Packet):
     out_packet.encode_short(self._charisma)
     out_packet.encode_short(self._insight)
     out_packet.encode_short(self._will)
     out_packet.encode_short(self._craft)
     out_packet.encode_short(self._sense)
     out_packet.encode_short(self._charm)
     out_packet.encode_byte(self._charm_by_cash_pr)
     out_packet.encode_ft(self._last_update_charm_by_cash_pr)
Exemplo n.º 26
0
 def encode(self, out_packet: Packet):
     for i in range(9):
         out_packet.encode_int(self.char_id)
         out_packet.encode_byte(self.level)
         out_packet.encode_int(self.job)
Exemplo n.º 27
0
 def encode(self, out_packet: Packet):
     out_packet.encode_byte(self.get_sp_set_size())
     for sps in self.sp_set:
         out_packet.encode_byte(sps.job_level)
         out_packet.encode_int(sps.sp)
Exemplo n.º 28
0
    def encode(self, out_packet: Packet):
        out_packet.encode_int(self.chr_id)
        out_packet.encode_int(self.chr_id_for_log)
        out_packet.encode_int(self.world_id_for_log)
        out_packet.encode_fixed_string(self.name, 13)
        out_packet.encode_byte(self.gender)
        out_packet.encode_byte(self.skin)
        out_packet.encode_int(self.face)
        out_packet.encode_int(self.hair)
        out_packet.encode_byte(self.mix_base_hair_color)
        out_packet.encode_byte(self.mix_add_hair_color)
        out_packet.encode_byte(self.mix_hair_base_prob)
        out_packet.encode_byte(self.level)
        out_packet.encode_short(self.job)
        out_packet.encode_short(self.strength)
        out_packet.encode_short(self.dex)
        out_packet.encode_short(self.inte)
        out_packet.encode_short(self.luk)
        out_packet.encode_int(self.hp)
        out_packet.encode_int(self.max_hp)
        out_packet.encode_int(self.mp)
        out_packet.encode_int(self.max_hp)
        out_packet.encode_short(self.ap)

        if is_extend_sp_job(self.job):
            self.extend_sp.encode(out_packet)
        else:
            out_packet.encode_short(self.sp)

        out_packet.encode_long(int(self.exp))
        out_packet.encode_int(self.pop)
        out_packet.encode_int(self.wp)
        out_packet.encode_int(int(self.pos_map))
        out_packet.encode_int(self.gach_exp)
        out_packet.encode_byte(self.portal)
        out_packet.encode_int(0)  # TODO: Figure out
        out_packet.encode_short(self.sub_job)

        job_id = self.job

        if is_demon(job_id) or is_xenon(job_id) or is_beast_tamer(job_id):
            out_packet.encode_int(self.def_face_acc)

        out_packet.encode_byte(self.fatigue)
        out_packet.encode_int(self.last_fatigue_update_time)
        out_packet.encode_int(self.charisma_exp)
        out_packet.encode_int(self.insight_exp)
        out_packet.encode_int(self.will_exp)
        out_packet.encode_int(self.craft_exp)
        out_packet.encode_int(self.sense_exp)
        out_packet.encode_int(self.charm_exp)

        self.non_combat_stat_day_limit.encode(out_packet)

        out_packet.encode_int(self.pvp_exp)
        out_packet.encode_byte(self.pvp_grade)
        out_packet.encode_int(self.pvp_point)
        out_packet.encode_byte(2)

        out_packet.encode_byte(self.pvp_mode_type)
        out_packet.encode_int(self.event_point)
        out_packet.encode_byte(self.alba_activity_id)
        out_packet.encode_ft(FileTime(
            FileTimeType.ZERO_TIME))  # self.alba_start_time
        out_packet.encode_int(self.alba_duration)
        out_packet.encode_byte(self.alba_special_reward)

        self.character_card.encode(out_packet)

        out_packet.encode_ft(FileTime(
            FileTimeType.ZERO_TIME))  # self.last_logout
        out_packet.encode_byte(self.burning)
Exemplo n.º 29
0
    def check_password_result(success: bool, login_type: LoginType,
                              user: User) -> Packet:

        send_packet = Packet(opcode=OutPacket.CHECK_PASSWORD_RESULT)

        if success:
            send_packet.encode_byte(LoginType.Success.value)
            send_packet.encode_byte(0)
            send_packet.encode_int(0)
            send_packet.encode_string(user.name)
            send_packet.encode_int(user.user_id)
            send_packet.encode_byte(user.gender)
            send_packet.encode_byte(user.msg2)
            send_packet.encode_int(user.acc_type.value)
            send_packet.encode_int(user.age)

            has_censored = user.has_censored_nx_login_id

            send_packet.encode_byte(not has_censored)
            if has_censored:
                send_packet.encode_string(user.censored_nx_login_id)

            send_packet.encode_string(user.name)
            send_packet.encode_byte(user.p_block_reason)
            send_packet.encode_byte(0)  # unknown
            send_packet.encode_long(user.chat_unblock_date)
            send_packet.encode_long(user.chat_unblock_date)
            send_packet.encode_int(user.character_slots + 3)
            job_constants.encode(send_packet)
            send_packet.encode_byte(user.grade_code)
            send_packet.encode_int(-1)  # Enable Star Planet
            send_packet.encode_byte(0)  # Unknown
            send_packet.encode_byte(0)  # Unknown
            send_packet.encode_ft(user.creation_date)
        elif login_type == LoginType.Blocked:
            send_packet.encode_byte(login_type.value)
            send_packet.encode_byte(0)
            send_packet.encode_int(0)
            send_packet.encode_byte(0)
            send_packet.encode_ft(None)  # FileTime is not handled atm
        else:
            send_packet.encode_byte(login_type.value)
            send_packet.encode_byte(0)
            send_packet.encode_int(0)

        return send_packet
Exemplo n.º 30
0
    def broadcast_msg(broadcast_msg):
        send_packet = Packet(opcode=OutPacket.BROADCAST_MSG)

        broadcast_msg.encode(send_packet)

        return send_packet