summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context.h108
-rw-r--r--include/pso/TProtocol.h14
-rw-r--r--include/pso/packet_classes.h94
-rw-r--r--src/pso/TProtocol.cpp151
4 files changed, 355 insertions, 12 deletions
diff --git a/context.h b/context.h
index cfc430d..fff939a 100644
--- a/context.h
+++ b/context.h
@@ -899,8 +899,8 @@ struct send_buffs {
// pso/packet_classes.h
struct game_command_header {
- u8 command;
- u8 size;
+ char command;
+ char size;
u16 id;
void bswap() {
@@ -918,6 +918,24 @@ struct extended_game_command_header {
};
};
+struct long_game_command {
+ game_command_header header;
+ u8 data[1460-sizeof(game_command_header)];
+
+ void bswap() {
+ header.bswap();
+ };
+};
+
+struct extended_long_game_command {
+ extended_game_command_header header;
+ u8 data[1460-sizeof(extended_game_command_header)];
+
+ void bswap() {
+ header.bswap();
+ };
+};
+
struct game_command {
game_command_header header;
u8 data[1024-sizeof(game_command_header)];
@@ -973,6 +991,12 @@ union game_command_union {
u8 bytes[1024];
};
+union long_game_command_union {
+ struct long_game_command game_cmd;
+ struct extended_long_game_command ext_game_cmd;
+ u8 bytes[1460];
+};
+
// pso/TObject.h
// Enum defs.
enum object_flags {
@@ -1402,6 +1426,47 @@ public:
};
// pso/packet_classes.h
+class TCreateGame {
+public:
+ packet_header header;
+ TPlyGuildCardTag tag;
+ char name[16];
+ char password[16];
+ u8 difficulty;
+ u8 battle_mode;
+ u8 challenge_mode;
+ u8 episode;
+public:
+ void bswap() {
+ header.bswap();
+ tag.bswap();
+ };
+};
+
+class TFindUser {
+public:
+ packet_header header;
+ TPlyGuildCardTag tag;
+ u32 target_gc;
+public:
+ void bswap() {
+ header.bswap();
+ tag.bswap();
+ bswap_32(&target_gc);
+ };
+};
+
+class TRoomChange {
+public:
+ packet_header header;
+ TPlyGuildCardTag tag;
+public:
+ void bswap() {
+ header.bswap();
+ tag.bswap();
+ };
+};
+
class TRegister {
public:
packet_header header;
@@ -1509,11 +1574,32 @@ public:
};
};
-class TPsoData {
+class TPsoDataBuf {
+public:
+ void recv_pso_data_buf(size_t size) {};
+};
+
+class TPsoDataLong : public TPsoDataBuf {
+public:
+ union {
+ union long_game_command_union pkt;
+ u8 bytes[0x8000];
+ };
+};
+
+class TPsoData : public TPsoDataBuf {
public:
union game_command_union pkt;
+};
+
+class TRecvPsoDataLong {
public:
- void recv_pso_data_buf(size_t size) {};
+ packet_header header;
+ TPsoDataLong data;
+public:
+ void bswap() {
+ header.bswap();
+ };
};
class TRecvPsoData {
@@ -1833,4 +1919,18 @@ public:
void send_text_list();
// 0x61
void send_chara_data_v2(TPlyCharData &char_data, TPlyChallenge &challenge, TPlyChoiceSearchConfig &choice_search_config, TBlockedSenders &blocked_senders, TPlyText<512> &auto_reply, char *info_board);
+ // 0x98
+ void send_update_chara_data_v2(TPlyCharData &char_data, TPlyChallenge &challenge, TPlyChoiceSearchConfig &choice_search_config, TBlockedSenders &blocked_senders, TPlyText<512> &auto_reply, char *info_board);
+ // 0x60
+ void send_pso_data(game_command &packet, u32 size);
+ // 0x62
+ void send_pso_data2(u32 flags, game_command &packet, u32 size);
+ // 0x6D
+ void send_pso_data_long2(char flags, long_game_command &packet, size_t size);
+ // 0x84
+ void send_room_change(int idx);
+ // 0x40
+ void send_find_user(TPlyGuildCardTag &tag, u32 gc_num);
+ // 0xC1
+ void send_create_game(char *name, char *password, u8 difficulty, u8 battle_mode, u8 challenge_mode, u8 episode);
};
diff --git a/include/pso/TProtocol.h b/include/pso/TProtocol.h
index 98976b7..ca80ffe 100644
--- a/include/pso/TProtocol.h
+++ b/include/pso/TProtocol.h
@@ -266,6 +266,20 @@ public:
void send_text_list();
// 0x61
void send_chara_data_v2(TPlyCharData &char_data, TPlyChallenge &challenge, TPlyChoiceSearchConfig &choice_search_config, TBlockedSenders &blocked_senders, TPlyText<512> &auto_reply, char *info_board);
+ // 0x98
+ void send_update_chara_data_v2(TPlyCharData &char_data, TPlyChallenge &challenge, TPlyChoiceSearchConfig &choice_search_config, TBlockedSenders &blocked_senders, TPlyText<512> &auto_reply, char *info_board);
+ // 0x60
+ void send_pso_data(game_command &packet, u32 size);
+ // 0x62
+ void send_pso_data2(u32 flags, game_command &packet, u32 size);
+ // 0x6D
+ void send_pso_data_long2(char flags, long_game_command &packet, size_t size);
+ // 0x84
+ void send_room_change(int idx);
+ // 0x40
+ void send_find_user(TPlyGuildCardTag &tag, u32 gc_num);
+ // 0xC1
+ void send_create_game(char *name, char *password, u8 difficulty, u8 battle_mode, u8 challenge_mode, u8 episode);
};
#endif
diff --git a/include/pso/packet_classes.h b/include/pso/packet_classes.h
index e0a78bd..d49c49a 100644
--- a/include/pso/packet_classes.h
+++ b/include/pso/packet_classes.h
@@ -25,8 +25,8 @@ struct TPlyText {
};
struct game_command_header {
- u8 command;
- u8 size;
+ char command;
+ char size;
u16 id;
void bswap() {
@@ -44,6 +44,24 @@ struct extended_game_command_header {
};
};
+struct long_game_command {
+ game_command_header header;
+ u8 data[1460-sizeof(game_command_header)];
+
+ void bswap() {
+ header.bswap();
+ };
+};
+
+struct extended_long_game_command {
+ extended_game_command_header header;
+ u8 data[1460-sizeof(extended_game_command_header)];
+
+ void bswap() {
+ header.bswap();
+ };
+};
+
struct game_command {
game_command_header header;
u8 data[1024-sizeof(game_command_header)];
@@ -85,6 +103,53 @@ union game_command_union {
u8 bytes[1024];
};
+union long_game_command_union {
+ struct long_game_command game_cmd;
+ struct extended_long_game_command ext_game_cmd;
+ u8 bytes[1460];
+};
+
+class TCreateGame {
+public:
+ packet_header header;
+ TPlyGuildCardTag tag;
+ char name[16];
+ char password[16];
+ u8 difficulty;
+ u8 battle_mode;
+ u8 challenge_mode;
+ u8 episode;
+public:
+ void bswap() {
+ header.bswap();
+ tag.bswap();
+ };
+};
+
+class TFindUser {
+public:
+ packet_header header;
+ TPlyGuildCardTag tag;
+ u32 target_gc;
+public:
+ void bswap() {
+ header.bswap();
+ tag.bswap();
+ bswap_32(&target_gc);
+ };
+};
+
+class TRoomChange {
+public:
+ packet_header header;
+ TPlyGuildCardTag tag;
+public:
+ void bswap() {
+ header.bswap();
+ tag.bswap();
+ };
+};
+
class TBlockedSenders {
public:
packet_header header;
@@ -275,11 +340,32 @@ public:
};
};
-class TPsoData {
+class TPsoDataBuf {
+public:
+ void recv_pso_data_buf(size_t size) {};
+};
+
+class TPsoDataLong : public TPsoDataBuf {
+public:
+ union {
+ union long_game_command_union pkt;
+ u8 bytes[0x8000];
+ };
+};
+
+class TPsoData : public TPsoDataBuf {
public:
union game_command_union pkt;
+};
+
+class TRecvPsoDataLong {
public:
- void recv_pso_data_buf(size_t size) {};
+ packet_header header;
+ TPsoDataLong data;
+public:
+ void bswap() {
+ header.bswap();
+ };
};
class TRecvPsoData {
diff --git a/src/pso/TProtocol.cpp b/src/pso/TProtocol.cpp
index 3b7cbd3..3c410aa 100644
--- a/src/pso/TProtocol.cpp
+++ b/src/pso/TProtocol.cpp
@@ -24,6 +24,149 @@ void copy_packet(struct packet *pkt) {
}
+void TProtocol::send_create_game(char *name, char *password, u8 difficulty, u8 battle_mode, u8 challenge_mode, u8 episode) {
+ if (m_connected) {
+ TCreateGame tmp;
+ tmp.header.command = 0xC1;
+ tmp.header.flags = 3;
+ tmp.header.size = sizeof(tmp);
+ tmp.tag = TPlyGuildCardTag(0, 0);
+ tmp.difficulty = difficulty;
+ tmp.battle_mode = battle_mode;
+ tmp.challenge_mode = challenge_mode;
+ tmp.episode = episode;
+ strncpy(tmp.name, name, sizeof(tmp.name));
+ strncpy(tmp.password, password, sizeof(tmp.password));
+ tmp.bswap();
+ send(as(u8 *, &tmp), sizeof(tmp));
+ }
+}
+
+void TProtocol::send_find_user(TPlyGuildCardTag &tag, u32 gc_num) {
+ if (m_connected) {
+ TFindUser tmp;
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.header.command = 0x40;
+ tmp.header.size = sizeof(tmp);
+ tmp.tag = tag;
+ tmp.target_gc = gc_num;
+ tmp.bswap();
+ send(as(u8 *, &tmp), sizeof(tmp));
+ }
+}
+
+void TProtocol::send_room_change(int idx) {
+ if (m_connected) {
+ TRoomChange tmp;
+ tmp.header.command = 0x84;
+ tmp.header.flags = 0;
+ tmp.header.size = sizeof(tmp);
+ tmp.tag = m_lobby_entries[idx].tag;
+ tmp.bswap();
+ send(as(u8 *, &tmp), sizeof(tmp));
+ }
+}
+
+void TProtocol::send_pso_data_long2(char flags, long_game_command &packet, size_t size) {
+ const int header_size = sizeof(packet_header);
+ const int command_size = sizeof(long_game_command);
+ if (m_connected) {
+ TRecvPsoDataLong *tmp = new TRecvPsoDataLong;
+ u8 *pkt = as(u8 *, tmp);
+ int packet_size;
+ int cmd_count;
+ int leftover;
+ int offset;
+
+ memcpy(tmp->data.bytes, &packet, size);
+ tmp->header.command = 0x6d;
+ tmp->header.flags = flags;
+ tmp->header.size = size + header_size;
+ tmp->bswap();
+
+ packet_size = (int)size + header_size;
+ cmd_count = packet_size/command_size;
+ leftover = packet_size - (cmd_count * command_size);
+
+ for (offset = 0; cmd_count > 0; --cmd_count, offset += command_size) {
+ if (test_connection()) {
+ goto end;
+ } else {
+ send(&pkt[offset], command_size);
+ }
+ }
+
+ if (!test_connection() && leftover > 0) {
+ send(&pkt[offset], leftover);
+ }
+
+ end:
+ delete tmp;
+ }
+}
+
+void TProtocol::send_pso_data2(u32 flags, game_command &packet, u32 size) {
+ char tmp_str[128];
+ sprintf(tmp_str, "SndPsoData2 %d %d %d", packet.header.command, size, flags);
+ if (m_connected) {
+ TRecvPsoData tmp;
+ int packet_size;
+ packet_size = (u16)(size + sizeof(packet_header));
+ tmp.header.command = 0x62;
+ tmp.header.flags = flags;
+ packet_size = (u16)(size + sizeof(packet_header));
+ tmp.header.size = packet_size;
+ memcpy(&tmp.data, &packet, size);
+ tmp.bswap();
+ send(as(u8 *, &tmp), packet_size);
+ }
+}
+
+void TProtocol::send_pso_data(game_command &packet, u32 size) {
+ char tmp_str[128];
+ sprintf(tmp_str, "SndPsoData %d %d", packet.header.command, size);
+ if (m_connected) {
+ TRecvPsoData tmp;
+ int packet_size;
+ tmp.header.command = 0x60;
+ tmp.header.flags = 0;
+ packet_size = (u16)(size + sizeof(packet_header));
+ tmp.header.size = packet_size;
+ memcpy(&tmp.data, &packet, (u32)size);
+ tmp.bswap();
+ send(as(u8 *, &tmp), packet_size);
+ }
+}
+
+void TProtocol::send_update_chara_data_v2(TPlyCharData &char_data, TPlyChallenge &challenge, TPlyChoiceSearchConfig &choice_search_config, TBlockedSenders &blocked_senders, TPlyText<512> &auto_reply, char *info_board) {
+ if (m_connected) {
+ char_data.m_disp_data.m_disp_part2.is_valid();
+ m_character_data = char_data;
+ TPlyJoinData tmp;
+ memset(&tmp, 0, sizeof(tmp));
+
+
+ tmp.header.command = 0x98;
+ tmp.header.flags = 3;
+ tmp.header.size = sizeof(tmp);
+ tmp.char_data = m_character_data;
+ tmp.challenge = challenge;
+ tmp.choice_search_config = choice_search_config;
+ strncpy(tmp.info_board, info_board, sizeof(tmp.info_board));
+ for (int i = 0; i < blocked_senders.header.flags; ++i) {
+ tmp.blocked_senders[i] = blocked_senders.blocked_senders[i];
+ }
+ tmp.auto_reply_enabled = auto_reply.header.flags;
+ strncpy(tmp.auto_reply, auto_reply.text, sizeof(tmp.auto_reply)-1);
+ const int packet_size = strlen(tmp.auto_reply) + offsetof(TPlyJoinData, auto_reply) + sizeof(packet_header);
+
+ tmp.header.size = packet_size & ~3;
+ tmp.char_data.some_stub();
+ tmp.bswap();
+ send(as(u8 *, &tmp), packet_size & ~3);
+ }
+}
+
void TProtocol::send_chara_data_v2(TPlyCharData &char_data, TPlyChallenge &challenge, TPlyChoiceSearchConfig &choice_search_config, TBlockedSenders &blocked_senders, TPlyText<512> &auto_reply, char *info_board) {
if (m_connected) {
char_data.m_disp_data.m_disp_part2.is_valid();
@@ -399,15 +542,15 @@ void TProtocol::recv_generate_id(packet &pkt) {
};
void TProtocol::recv_pso_data_long(packet &pkt) {
- TRecvPsoData &tmp = as(TRecvPsoData &, pkt);
- pkt.pkt.bswap();
- tmp.data.recv_pso_data_buf(tmp.header.size - 4);
+ TRecvPsoDataLong &tmp = as(TRecvPsoDataLong &, pkt);
+ tmp.bswap();
+ tmp.data.recv_pso_data_buf(tmp.header.size - sizeof(packet_header));
};
void TProtocol::recv_pso_data(packet &pkt) {
TRecvPsoData tmp = as(TRecvPsoData &, pkt);
tmp.bswap();
- tmp.data.recv_pso_data_buf(tmp.header.size - 4);
+ tmp.data.recv_pso_data_buf(tmp.header.size - sizeof(packet_header));
};
void TProtocol::recv_system_file(packet &pkt) {};