From ad1179e6cfeb07ff865e0086627761b0a04bfd79 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Tue, 14 Mar 2023 16:41:22 -0300 Subject: TProtocol: Add (and match) even more command handlers Slowly starting to get fleshed out. --- context.h | 147 +++++++++++++++++++++++++++++++++++++++++-- include/pso/TMenuList.h | 6 +- include/pso/TProtocol.h | 25 +++++++- include/pso/packet_classes.h | 122 +++++++++++++++++++++++++++++++++++ src/pso/TProtocol.cpp | 93 +++++++++++++++++++++++---- 5 files changed, 369 insertions(+), 24 deletions(-) diff --git a/context.h b/context.h index e82c1da..04c2593 100644 --- a/context.h +++ b/context.h @@ -182,7 +182,7 @@ typedef long ptrdiff_t; o(handle_64_recv_start_game3, TPlyJoinGame &join_data) \ o(unused8, void) \ o(handle_67_recv_start_lobby2, TPlyJoinLobbyEntry *entries, u8 entry_count, int client_id, int leader_id, int lobby_number, int block_number, int smth, int event) \ - o(handle_80_unused_ignored_packet, void) \ + o(handle_80_recv_generate_id, TRecvGenerateID gen_id) \ o(unused9, void) \ o(handle_65_add_player_to_game_packet, void) \ o(handle_66_player_left_game_packet, void) \ @@ -192,8 +192,8 @@ typedef long ptrdiff_t; o(handle_92_9C_register_response_packet, void) \ o(unused10, void) \ o(handle_95_request_character_data_packet, void) \ - o(handle_81_simple_mail_packet, void) \ - o(handle_41_guild_card_search_reply_packet, void) \ + o(handle_81_recv_chat_message, TChatMessage &chat_message) \ + o(handle_41_recv_user_ans, TUserAns &user_ans) \ o(send_96_unused, void) \ o(handle_97_checksum_reply_packet, void) \ o(handle_B1_current_time_packet, void) \ @@ -452,7 +452,7 @@ public: T entries[num_entries]; } __packed__; -#ifdef __MWCC__ +#ifdef __MWERKS__ template class TMenuList { public: @@ -464,7 +464,7 @@ public: }; public: packet_header header; - TMenuListEntry entries[num_entries]; + T entries[num_entries]; } __packed__; template @@ -478,7 +478,7 @@ public: }; public: packet_header header; - TMenuListEntry pad_entries[num_pad_entries]; + T pad_entries[num_pad_entries]; } __packed__; #endif @@ -489,6 +489,44 @@ struct TPlyText { char text[size]; }; +struct game_command_header { + u8 command; + u8 size; + u16 id; + + void bswap() { + bswap_16(&id); + }; +}; + +struct extended_game_command_header { + game_command_header header; + u32 size; + + void bswap() { + bswap_16(&header.id); + bswap_32(&size); + }; +}; + +struct game_command { + game_command_header header; + u8 data[1024-sizeof(game_command_header)]; + + void bswap() { + header.bswap(); + }; +}; + +struct extended_game_command { + extended_game_command_header header; + u8 data[1024-sizeof(extended_game_command_header)]; + + void bswap() { + header.bswap(); + }; +}; + TMenuListEntry(GameListEntry, u8 difficulty_tag; u8 num_players; @@ -517,6 +555,7 @@ extern TTcpSocket *tcp_socket_table[16]; // pso/TProtocol.h EXTERN_OBJECT_NAME(TProtocol); +extern int maybe_release_flag; extern u32 new_ip_addr; extern u16 new_port; extern TPlyMeetUserExtension meet_user_settings; @@ -739,6 +778,10 @@ struct packet { } pkt; u8 bytes[0x7c00]; }; + + void bswap() { + pkt.header.bswap(); + }; }; struct recv_packet_handlers { @@ -1200,6 +1243,84 @@ public: }; }; +class TChatMessage { +public: + packet_header header; + TPlyGuildCardTag tag; + char name[16]; + u32 to_guildcard_number; + char text[512]; +public: + void bswap() { + header.bswap(); + tag.bswap(); + bswap_32(&to_guildcard_number); + }; +}; + +class TUserAns { +public: + packet_header header; + TPlyGuildCardTag tag; + u32 found_guildcard; + TRecvPort recv_port; + char location[68]; + TPlyMeetUserExtension extension; +public: + void bswap() { + header.bswap(); + tag.bswap(); + bswap_32(&found_guildcard); + recv_port.bswap(); + extension.bswap(); + }; +}; + +class TGenGuildCardTag { +public: + u8 tag0; + u8 tag1; + u16 tag2; + u32 guildcard_number; +public: + TGenGuildCardTag() {}; + + void bswap() { + bswap_32(&guildcard_number); + bswap_16(&tag2); + }; +}; + +class TRecvGenerateID { +public: + packet_header header; + u32 client_id; + TGenGuildCardTag tag; +public: + void bswap() { + header.bswap(); + bswap_32(&client_id); + tag.bswap(); + }; +}; + +class TPsoData { +public: + union game_command_union pkt; +public: + void recv_pso_data_buf(size_t size) {}; +}; + +class TRecvPsoData { +public: + packet_header header; + TPsoData data; +public: + void bswap() { + header.bswap(); + }; +}; + class TPlyJoinLobbyData { public: TPlyGuildCardTag tag; @@ -1458,6 +1579,20 @@ public: void recv_battle_data(packet &pkt); // 0x1C void recv_system_file(packet &pkt); + // 0x60/0x62 + void recv_pso_data(packet &pkt); + // 0x6C/0x6D + void recv_pso_data_long(packet &pkt); + // 0x80 + void recv_generate_id(packet &pkt); + // 0x83 + void recv_room_info(packet &pkt); + // 0x41 + void recv_user_ans(packet &pkt); + // 0x1D + void recv_ping(packet &pkt); + // 0x81 + void recv_chat_message(packet &pkt); // Send command handlers. int send_login3(); diff --git a/include/pso/TMenuList.h b/include/pso/TMenuList.h index 90a7423..c752341 100644 --- a/include/pso/TMenuList.h +++ b/include/pso/TMenuList.h @@ -40,7 +40,7 @@ public: T entries[num_entries]; } __packed__; -#ifdef __MWCC__ +#ifdef __MWERKS__ template class TMenuList { public: @@ -52,7 +52,7 @@ public: }; public: packet_header header; - TMenuListEntry entries[num_entries]; + T entries[num_entries]; } __packed__; template @@ -66,7 +66,7 @@ public: }; public: packet_header header; - TMenuListEntry pad_entries[num_pad_entries]; + T pad_entries[num_pad_entries]; } __packed__; #endif diff --git a/include/pso/TProtocol.h b/include/pso/TProtocol.h index bc0f27f..fa9f6da 100644 --- a/include/pso/TProtocol.h +++ b/include/pso/TProtocol.h @@ -19,6 +19,7 @@ #include EXTERN_OBJECT_NAME(TProtocol); +extern int maybe_release_flag; extern u32 new_ip_addr; extern u16 new_port; extern TPlyMeetUserExtension meet_user_settings; @@ -33,6 +34,10 @@ struct packet { } pkt; u8 bytes[0x7c00]; }; + + void bswap() { + pkt.header.bswap(); + }; }; #define RECV_PACKET_HANDLERS \ @@ -51,7 +56,7 @@ struct packet { o(handle_64_recv_start_game3, TPlyJoinGame &join_data) \ o(unused8, void) \ o(handle_67_recv_start_lobby2, TPlyJoinLobbyEntry *entries, u8 entry_count, int client_id, int leader_id, int lobby_number, int block_number, int smth, int event) \ - o(handle_80_unused_ignored_packet, void) \ + o(handle_80_recv_generate_id, TRecvGenerateID gen_id) \ o(unused9, void) \ o(handle_65_add_player_to_game_packet, void) \ o(handle_66_player_left_game_packet, void) \ @@ -61,8 +66,8 @@ struct packet { o(handle_92_9C_register_response_packet, void) \ o(unused10, void) \ o(handle_95_request_character_data_packet, void) \ - o(handle_81_simple_mail_packet, void) \ - o(handle_41_guild_card_search_reply_packet, void) \ + o(handle_81_recv_chat_message, TChatMessage &chat_message) \ + o(handle_41_recv_user_ans, TUserAns &user_ans) \ o(send_96_unused, void) \ o(handle_97_checksum_reply_packet, void) \ o(handle_B1_current_time_packet, void) \ @@ -205,6 +210,20 @@ public: void recv_battle_data(packet &pkt); // 0x1C void recv_system_file(packet &pkt); + // 0x60/0x62 + void recv_pso_data(packet &pkt); + // 0x6C/0x6D + void recv_pso_data_long(packet &pkt); + // 0x80 + void recv_generate_id(packet &pkt); + // 0x83 + void recv_room_info(packet &pkt); + // 0x41 + void recv_user_ans(packet &pkt); + // 0x1D + void recv_ping(packet &pkt); + // 0x81 + void recv_chat_message(packet &pkt); // Send command handlers. int send_login3(); diff --git a/include/pso/packet_classes.h b/include/pso/packet_classes.h index 0764388..b6217ca 100644 --- a/include/pso/packet_classes.h +++ b/include/pso/packet_classes.h @@ -18,6 +18,44 @@ struct TPlyText { char text[size]; }; +struct game_command_header { + u8 command; + u8 size; + u16 id; + + void bswap() { + bswap_16(&id); + }; +}; + +struct extended_game_command_header { + game_command_header header; + u32 size; + + void bswap() { + bswap_16(&header.id); + bswap_32(&size); + }; +}; + +struct game_command { + game_command_header header; + u8 data[1024-sizeof(game_command_header)]; + + void bswap() { + header.bswap(); + }; +}; + +struct extended_game_command { + extended_game_command_header header; + u8 data[1024-sizeof(extended_game_command_header)]; + + void bswap() { + header.bswap(); + }; +}; + TMenuListEntry(GameListEntry, u8 difficulty_tag; u8 num_players; @@ -35,6 +73,12 @@ TMenuListEntry(QuestListEntry, char short_description[112]; ); +union game_command_union { + struct game_command game_cmd; + struct extended_game_command ext_game_cmd; + u8 bytes[1024]; +}; + class TRecvPort { public: packet_header header; @@ -63,6 +107,84 @@ public: }; }; +class TChatMessage { +public: + packet_header header; + TPlyGuildCardTag tag; + char name[16]; + u32 to_guildcard_number; + char text[512]; +public: + void bswap() { + header.bswap(); + tag.bswap(); + bswap_32(&to_guildcard_number); + }; +}; + +class TUserAns { +public: + packet_header header; + TPlyGuildCardTag tag; + u32 found_guildcard; + TRecvPort recv_port; + char location[68]; + TPlyMeetUserExtension extension; +public: + void bswap() { + header.bswap(); + tag.bswap(); + bswap_32(&found_guildcard); + recv_port.bswap(); + extension.bswap(); + }; +}; + +class TGenGuildCardTag { +public: + u8 tag0; + u8 tag1; + u16 tag2; + u32 guildcard_number; +public: + TGenGuildCardTag() {}; + + void bswap() { + bswap_32(&guildcard_number); + bswap_16(&tag2); + }; +}; + +class TRecvGenerateID { +public: + packet_header header; + u32 client_id; + TGenGuildCardTag tag; +public: + void bswap() { + header.bswap(); + bswap_32(&client_id); + tag.bswap(); + }; +}; + +class TPsoData { +public: + union game_command_union pkt; +public: + void recv_pso_data_buf(size_t size) {}; +}; + +class TRecvPsoData { +public: + packet_header header; + TPsoData data; +public: + void bswap() { + header.bswap(); + }; +}; + class TPlyJoinLobbyData { public: TPlyGuildCardTag tag; diff --git a/src/pso/TProtocol.cpp b/src/pso/TProtocol.cpp index 35d8a54..895a09a 100644 --- a/src/pso/TProtocol.cpp +++ b/src/pso/TProtocol.cpp @@ -14,6 +14,8 @@ OBJECT_NAME(TProtocol); packet *server_packet = nullptr; +// Seems like this is 1 if it's the full release, and 0 if it's the trial edition. +int maybe_release_flag = 1; u32 new_ip_addr; u16 new_port; TPlyMeetUserExtension meet_user_settings; @@ -40,6 +42,73 @@ int TProtocol::send_login3() { return ret; } +void TProtocol::recv_chat_message(packet &pkt) { + TChatMessage tmp = as(TChatMessage &, pkt); + tmp.bswap(); + + if (m_recv_handlers.handle_81_recv_chat_message != nullptr) { + m_recv_handlers.handle_81_recv_chat_message(tmp); + } +}; + +void TProtocol::recv_ping(packet &pkt) { + packet_header tmp; + tmp.command = 0x1D; + tmp.flags = 0; + tmp.size = sizeof(tmp); + tmp.bswap(); + + send(as(u8 *, &tmp), sizeof(tmp)); +}; + +void TProtocol::recv_user_ans(packet &pkt) { + TUserAns tmp = as(TUserAns &, pkt); + tmp.bswap(); + + if (m_recv_handlers.handle_41_recv_user_ans != nullptr) { + m_recv_handlers.handle_41_recv_user_ans(tmp); + } +}; + +void TProtocol::recv_room_info(packet &pkt) { + typedef TMenuList lobby_list; + lobby_list tmp = as(lobby_list &, pkt); + tmp.bswap(); + + m_lobby_list_count = tmp.header.flags; + + if (maybe_release_flag) { + for (int i = 0; i < m_lobby_list_count; ++i) { + m_lobby_entries[i] = tmp.entries[i]; + } + } else { + for (int i = 0; i < 10; ++i) { + m_lobby_entries[i] = tmp.entries[i]; + } + } +}; + +void TProtocol::recv_generate_id(packet &pkt) { + TRecvGenerateID tmp = as(TRecvGenerateID &, pkt); + tmp.bswap(); + + if (m_recv_handlers.handle_80_recv_generate_id != nullptr) { + m_recv_handlers.handle_80_recv_generate_id(tmp); + } +}; + +void TProtocol::recv_pso_data_long(packet &pkt) { + TRecvPsoData &tmp = as(TRecvPsoData &, pkt); + pkt.bswap(); + tmp.data.recv_pso_data_buf(tmp.header.size - 4); +}; + +void TProtocol::recv_pso_data(packet &pkt) { + TRecvPsoData tmp = as(TRecvPsoData &, pkt); + tmp.bswap(); + tmp.data.recv_pso_data_buf(tmp.header.size - 4); +}; + void TProtocol::recv_system_file(packet &pkt) {}; void TProtocol::recv_battle_data(packet &pkt) { @@ -333,18 +402,18 @@ int TProtocol::handle_command(struct packet *pkt) { { 0x1A, &recv_text }, { 0x1B, &recv_battle_data }, { 0x1C, &recv_system_file }, - // 0x60 - // 0x62 - // 0x6C - // 0x6D - // 0x81 - // 0x41 + { 0x60, &recv_pso_data }, + { 0x62, &recv_pso_data }, + { 0x6C, &recv_pso_data_long }, + { 0x6D, &recv_pso_data_long }, + { 0x81, &recv_chat_message }, + { 0x41, &recv_user_ans }, // 0x88 // 0x8A - // 0x80 + { 0x80, &recv_generate_id }, { 0x67, &recv_start_lobby2 }, - // 0x83 - // 0x1D + { 0x83, &recv_room_info }, + { 0x1D, &recv_ping }, // 0x65 // 0x66 // 0x68 @@ -528,7 +597,7 @@ TProtocol::TProtocol(TObject *parent, u16 sub_version, int language, char *seria m_recv_handlers.unused8 = nullptr; m_recv_handlers.handle_67_recv_start_lobby2 = nullptr; m_recv_handlers.handle_13_recv_download = nullptr; - m_recv_handlers.handle_80_unused_ignored_packet = nullptr; + m_recv_handlers.handle_80_recv_generate_id = nullptr; m_recv_handlers.unused9 = nullptr; m_recv_handlers.handle_65_add_player_to_game_packet = nullptr; m_recv_handlers.handle_66_player_left_game_packet = nullptr; @@ -536,8 +605,8 @@ TProtocol::TProtocol(TObject *parent, u16 sub_version, int language, char *seria m_recv_handlers.handle_69_player_left_lobby_packet = nullptr; m_recv_handlers.handle_92_9C_register_response_packet = nullptr; m_recv_handlers.unused10 = nullptr; - m_recv_handlers.handle_81_simple_mail_packet = nullptr; - m_recv_handlers.handle_41_guild_card_search_reply_packet = nullptr; + m_recv_handlers.handle_81_recv_chat_message = nullptr; + m_recv_handlers.handle_41_recv_user_ans = nullptr; m_recv_handlers.handle_A2_quest_list_packet = nullptr; m_recv_handlers.handle_A3_quest_info_packet = nullptr; m_recv_handlers.handle_44_recv_download_head = nullptr; -- cgit v1.2.3-13-gbd6f