summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context.h147
-rw-r--r--include/pso/TMenuList.h6
-rw-r--r--include/pso/TProtocol.h25
-rw-r--r--include/pso/packet_classes.h122
-rw-r--r--src/pso/TProtocol.cpp93
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 <typename T, int num_entries>
class TMenuList<T, num_entries, 0> {
public:
@@ -464,7 +464,7 @@ public:
};
public:
packet_header header;
- TMenuListEntry<T> entries[num_entries];
+ T entries[num_entries];
} __packed__;
template <typename T, int num_pad_entries>
@@ -478,7 +478,7 @@ public:
};
public:
packet_header header;
- TMenuListEntry<T> 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 <typename T, int num_entries>
class TMenuList<T, num_entries, 0> {
public:
@@ -52,7 +52,7 @@ public:
};
public:
packet_header header;
- TMenuListEntry<T> entries[num_entries];
+ T entries[num_entries];
} __packed__;
template <typename T, int num_pad_entries>
@@ -66,7 +66,7 @@ public:
};
public:
packet_header header;
- TMenuListEntry<T> 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 <pso/TTcpSocket.h>
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<LobbyListEntry, 16, 0> 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;