diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2023-03-06 16:19:36 -0400 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2023-03-06 16:19:36 -0400 |
commit | 06d75ece6452a33f11afd7e5ec3dd1f916c8583f (patch) | |
tree | 6a3b5d45eee8d64630a647d04a43638ebef91605 | |
parent | 306a76cb444102bc207ee16e8a65aa9e90bbd37a (diff) |
TProtocol: Match both `parse_packet()`, and `run_task()`
-rw-r--r-- | context.h | 55 | ||||
-rw-r--r-- | include/pso/TProtocol.h | 28 | ||||
-rw-r--r-- | include/pso/TSocket.h | 23 | ||||
-rw-r--r-- | include/pso/TTcpSocket.h | 2 | ||||
-rw-r--r-- | src/pso/TProtocol.cpp | 76 | ||||
-rw-r--r-- | src/pso/TSocket.cpp | 13 | ||||
-rw-r--r-- | src/pso/TTcpSocket.cpp | 4 |
7 files changed, 152 insertions, 49 deletions
@@ -538,6 +538,10 @@ extern short tcp_receive(short nh, void (*notify)(short size, short sock_fd), sh extern int get_link_status(); extern char *get_sock_status_name(short code); +// pso/TSocket.h +extern u16 to_be_uint16_t(u16 val); +extern u16 to_le_uint16_t(u16 val); + // THeap.cpp extern void heap_xfree(void *ptr); extern void *heap_xmalloc(size_t size); @@ -560,6 +564,9 @@ extern void func_803e11f0(); extern void func_803369b4(); +// pso/TProtocol.h +extern void copy_packet(struct packet *pkt); + // pso/protocol.h extern void bswap_16(u16 *val); extern void bswap_32(u32 *val); @@ -693,13 +700,23 @@ struct send_buffs { // pso/TProtocol.h struct packet { - packet_header header; - TArray<u8, 0x7c00-sizeof(packet_header)> data; + union { + struct { + packet_header header; + TArray<u8, 0x7c00-sizeof(packet_header)> data; + } packet; + u8 bytes[0x7c00]; + }; template<typename T> T &as() { return reinterpret_cast<T>(*this); }; + + template<typename T> + T *as_ptr() { + return reinterpret_cast<T *>(this); + }; }; struct GameListEntry { @@ -1082,15 +1099,15 @@ public: }; // pso/TSocket.h -class TSocket : private TObject { -private: +class TSocket : public TObject { +public: ipv4_addr m_dst_addr; u16 m_dst_port; u16 m_src_port; ipv4_addr m_src_addr; s16 m_sock_fd; - u8 m_sock_flags; - bool m_buffer_cleared; + char m_is_invalid_packet; + char m_buffer_cleared; s16 m_size; s16 m_buffer_offset; u32 m_unused; @@ -1118,19 +1135,19 @@ public: int is_empty(); void set_flags(u8 flags) { - m_sock_flags |= flags; + m_is_invalid_packet |= flags; }; void clear_flags(u8 flags) { - m_sock_flags &= ~flags; + m_is_invalid_packet &= ~flags; }; void toggle_flags(u8 flags) { - m_sock_flags ^= flags; + m_is_invalid_packet ^= flags; }; u8 get_flags(u8 flags) { - return m_sock_flags & flags; + return m_is_invalid_packet & flags; }; PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr); @@ -1138,8 +1155,8 @@ public: PRIVATE_MEMBER_ACCESSORS(u16, src_port); PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr); PRIVATE_MEMBER_ACCESSORS(s16, sock_fd); - PRIVATE_MEMBER_ACCESSORS(u8, sock_flags); - PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared); + PRIVATE_MEMBER_ACCESSORS(char, is_invalid_packet); + PRIVATE_MEMBER_ACCESSORS(char, buffer_cleared); PRIVATE_MEMBER_ACCESSORS(s16, size); PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset); PRIVATE_MEMBER_ACCESSORS(u32, unused); @@ -1154,7 +1171,7 @@ public: // pso/TTcpSocket.h class TTcpSocket : public TSocket { -private: +public: PSOV3EncryptionTCP m_send_crypt; PSOV3EncryptionTCP m_recv_crypt; int m_is_encrypted; @@ -1259,7 +1276,7 @@ private: // pso/TProtocol.h class TProtocol : public TTcpSocket { -private: +public: TPlySmth m_smth; TPlyGuildCardTag m_guildcard_tag; u16 m_sub_version; @@ -1267,7 +1284,7 @@ private: int m_connected; int m_joined_game; int m_has_meet_user_settings; - int m_buffer_ready; + int m_handle_pings_only; int m_entry_count; int m_unused; int m_lobby_list_count; @@ -1300,9 +1317,11 @@ public: virtual ~TProtocol(); virtual void run_task(); - virtual int send(u8 *data, size_t size); + virtual short send(u8 *data, size_t size); - int handle_command(packet *pkt); + void some_stub(); + int handle_command(struct packet *pkt); + void parse_packet(); PRIVATE_MEMBER_ACCESSORS(TPlySmth, smth); PRIVATE_MEMBER_ACCESSORS(TPlyGuildCardTag, guildcard_tag); @@ -1311,7 +1330,7 @@ public: PRIVATE_MEMBER_ACCESSORS(int, connected); PRIVATE_MEMBER_ACCESSORS(int, joined_game); PRIVATE_MEMBER_ACCESSORS(int, has_meet_user_settings); - PRIVATE_MEMBER_ACCESSORS(int, buffer_ready); + PRIVATE_MEMBER_ACCESSORS(int, handle_pings_only); PRIVATE_MEMBER_ACCESSORS(int, entry_count); PRIVATE_MEMBER_ACCESSORS(int, unused); PRIVATE_MEMBER_ACCESSORS(int, lobby_list_count); diff --git a/include/pso/TProtocol.h b/include/pso/TProtocol.h index ed80d04..6cd2a9e 100644 --- a/include/pso/TProtocol.h +++ b/include/pso/TProtocol.h @@ -18,17 +18,27 @@ #include <pso/TSocket.h> #include <pso/TTcpSocket.h> - EXTERN_OBJECT_NAME(TProtocol); +extern void copy_packet(struct packet *pkt); struct packet { - packet_header header; - TArray<u8, 0x7c00-sizeof(packet_header)> data; + union { + struct { + packet_header header; + TArray<u8, 0x7c00-sizeof(packet_header)> data; + } packet; + u8 bytes[0x7c00]; + }; template<typename T> T &as() { return reinterpret_cast<T>(*this); }; + + template<typename T> + T *as_ptr() { + return reinterpret_cast<T *>(this); + }; }; struct GameListEntry { @@ -51,7 +61,7 @@ struct QuestListEntry { typedef void (*recv_packet_handler)(packet &pkt); class TProtocol : public TTcpSocket { -private: +public: TPlySmth m_smth; TPlyGuildCardTag m_guildcard_tag; u16 m_sub_version; @@ -59,7 +69,7 @@ private: int m_connected; int m_joined_game; int m_has_meet_user_settings; - int m_buffer_ready; + int m_handle_pings_only; int m_entry_count; int m_unused; int m_lobby_list_count; @@ -92,9 +102,11 @@ public: virtual ~TProtocol(); virtual void run_task(); - virtual int send(u8 *data, size_t size); + virtual short send(u8 *data, size_t size); - int handle_command(packet *pkt); + void some_stub(); + int handle_command(struct packet *pkt); + void parse_packet(); PRIVATE_MEMBER_ACCESSORS(TPlySmth, smth); PRIVATE_MEMBER_ACCESSORS(TPlyGuildCardTag, guildcard_tag); @@ -103,7 +115,7 @@ public: PRIVATE_MEMBER_ACCESSORS(int, connected); PRIVATE_MEMBER_ACCESSORS(int, joined_game); PRIVATE_MEMBER_ACCESSORS(int, has_meet_user_settings); - PRIVATE_MEMBER_ACCESSORS(int, buffer_ready); + PRIVATE_MEMBER_ACCESSORS(int, handle_pings_only); PRIVATE_MEMBER_ACCESSORS(int, entry_count); PRIVATE_MEMBER_ACCESSORS(int, unused); PRIVATE_MEMBER_ACCESSORS(int, lobby_list_count); diff --git a/include/pso/TSocket.h b/include/pso/TSocket.h index c55dd08..6f79e13 100644 --- a/include/pso/TSocket.h +++ b/include/pso/TSocket.h @@ -13,15 +13,18 @@ union ipv4_addr { TArray<u8, 4> addr_bytes; }; -class TSocket : private TObject { -private: +extern u16 to_be_uint16_t(u16 val); +extern u16 to_le_uint16_t(u16 val); + +class TSocket : public TObject { +public: ipv4_addr m_dst_addr; u16 m_dst_port; u16 m_src_port; ipv4_addr m_src_addr; s16 m_sock_fd; - u8 m_sock_flags; - bool m_buffer_cleared; + char m_is_invalid_packet; + char m_buffer_cleared; s16 m_size; s16 m_buffer_offset; u32 m_unused; @@ -49,19 +52,19 @@ public: int is_empty(); void set_flags(u8 flags) { - m_sock_flags |= flags; + m_is_invalid_packet |= flags; }; void clear_flags(u8 flags) { - m_sock_flags &= ~flags; + m_is_invalid_packet &= ~flags; }; void toggle_flags(u8 flags) { - m_sock_flags ^= flags; + m_is_invalid_packet ^= flags; }; u8 get_flags(u8 flags) { - return m_sock_flags & flags; + return m_is_invalid_packet & flags; }; PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr); @@ -69,8 +72,8 @@ public: PRIVATE_MEMBER_ACCESSORS(u16, src_port); PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr); PRIVATE_MEMBER_ACCESSORS(s16, sock_fd); - PRIVATE_MEMBER_ACCESSORS(u8, sock_flags); - PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared); + PRIVATE_MEMBER_ACCESSORS(char, is_invalid_packet); + PRIVATE_MEMBER_ACCESSORS(char, buffer_cleared); PRIVATE_MEMBER_ACCESSORS(s16, size); PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset); PRIVATE_MEMBER_ACCESSORS(u32, unused); diff --git a/include/pso/TTcpSocket.h b/include/pso/TTcpSocket.h index b2c8cfb..8e90558 100644 --- a/include/pso/TTcpSocket.h +++ b/include/pso/TTcpSocket.h @@ -14,7 +14,7 @@ EXTERN_OBJECT_NAME(TTcpSocket); extern TTcpSocket *tcp_socket_table[16]; class TTcpSocket : public TSocket { -private: +public: PSOV3EncryptionTCP m_send_crypt; PSOV3EncryptionTCP m_recv_crypt; int m_is_encrypted; diff --git a/src/pso/TProtocol.cpp b/src/pso/TProtocol.cpp index b0be8ee..d30df7d 100644 --- a/src/pso/TProtocol.cpp +++ b/src/pso/TProtocol.cpp @@ -14,18 +14,84 @@ OBJECT_NAME(TProtocol); -void TProtocol::run_task() { +packet *server_packet = nullptr; + +void copy_packet(struct packet *pkt) { } -int TProtocol::send(u8 *data, size_t size) { - return TTcpSocket::send(data, size); +int TProtocol::handle_command(struct packet *pkt) { + } -int handle_command(packet *pkt) { +void TProtocol::parse_packet() { + // This is needed to match, either that or cast the sizeof to an int. + const int max_packet_size = sizeof(struct packet); + while (!is_empty()) { + m_packet.bytes[m_packet_offset++] = next(); + if (m_packet_offset == sizeof(packet_header)) { + if (m_is_encrypted) { + m_recv_crypt.encrypt(&m_packet.packet.header, sizeof(packet_header)); + } + } + // NOTE: The `const int &` is required here to match. + // Convert packet size to native endian. + const int &packet_size = m_packet_size = to_be_uint16_t(m_packet.packet.header.size); + // Is the packet size invalid? + if (packet_size > max_packet_size || !packet_size) { + m_packet_size = 0; + m_packet_offset = 0; + m_is_invalid_packet = true; + break; + // Do we have the rest of the packet yet? + } else if (m_packet_size > 0 && m_packet_offset >= m_packet_size) { + // Decrypt it if necessary. + if (m_is_encrypted) { + m_recv_crypt.encrypt(&m_packet.packet.data, m_packet_size-sizeof(packet_header)); + } + struct packet *pkt = &m_packet; + m_packet_size = 0; + m_packet_offset = 0; + if (m_handle_pings_only) { + if (pkt->packet.header.command == 0x1d) { + if (!handle_command(pkt)) { + continue; + } else { + break; + } + } else { + copy_packet(pkt); + } + } else if (handle_command(pkt)) { + break; + } + } + } } +short TProtocol::send(u8 *data, size_t size) { + return TTcpSocket::send(data, size); +} + +void TProtocol::run_task() { + TTcpSocket::some_stub(); + some_stub(); + if (m_is_invalid_packet) { + close(); + m_is_encrypted = 0; + m_connected = 0; + m_packet_offset = 0; + m_packet_size = 0; + } else if (!m_buffer_cleared) { + server_packet = &m_packet; + parse_packet(); + recv(); + } +} + +void TProtocol::some_stub() {}; + TProtocol::~TProtocol() { } @@ -56,7 +122,7 @@ TProtocol::TProtocol(TObject *parent, u16 sub_version, int language, char *seria m_connected = 0; m_joined_game = 0; m_has_meet_user_settings = 0; - m_buffer_ready = 0; + m_handle_pings_only = false; m_entry_count = 0; m_unused = 0; m_lobby_list_count = 0; diff --git a/src/pso/TSocket.cpp b/src/pso/TSocket.cpp index 0a0166e..3c5576f 100644 --- a/src/pso/TSocket.cpp +++ b/src/pso/TSocket.cpp @@ -5,8 +5,6 @@ #include "pso/TObject.h" #include "pso/TSocket.h" -u16 bswap_word(u16 val); - int TSocket::is_empty() { if (all_parents_unqueued_for_destruction()) { return !m_size; @@ -25,7 +23,7 @@ const u8 TSocket::next() { } void TSocket::set_port(u32 port) { - m_dst_port = bswap_word(port); + m_dst_port = to_le_uint16_t(port); } void TSocket::set_ip_address(u32 addr) { @@ -42,14 +40,19 @@ TSocket::TSocket(TObject *parent) : TObject(parent) { m_dst_port = 0; m_src_port = 0; m_sock_fd = -1; - m_sock_flags = 0; + m_is_invalid_packet = false; m_size = 0; m_buffer_offset = 0; m_buffer_cleared = true; m_callback = nullptr; } -u16 bswap_word(u16 val) { +u16 to_be_uint16_t(u16 val) { + u8 *ptr = reinterpret_cast<u8 *>(&val); + return ptr[0] + (ptr[1] << 8); +} + +u16 to_le_uint16_t(u16 val) { u8 *ptr = reinterpret_cast<u8 *>(&val); return ptr[1] + (ptr[0] << 8); } diff --git a/src/pso/TTcpSocket.cpp b/src/pso/TTcpSocket.cpp index f105298..e923abb 100644 --- a/src/pso/TTcpSocket.cpp +++ b/src/pso/TTcpSocket.cpp @@ -99,7 +99,7 @@ int TTcpSocket::send(u8 *data, size_t size) { m_send_crypt.encrypt(data, size); } - const s8 flags = sock_flags(); + const s8 flags = is_invalid_packet(); if (flags || !get_link_status()) { return -1; } else { @@ -138,7 +138,7 @@ int TTcpSocket::send(u8 *data, size_t size) { short TTcpSocket::send(u8 *data) { if (sock_fd() != -1) { - const s8 flags = sock_flags(); + const s8 flags = is_invalid_packet(); if (flags || !get_link_status()) { return -1; } else { |