diff options
40 files changed, 7412 insertions, 1218 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp index 790eeda..d36eb80 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -54,9 +54,15 @@ #include "../io/tty.hpp" #include "../io/write.hpp" +#include "../net/packets.hpp" #include "../net/socket.hpp" #include "../net/timer.hpp" -#include "../net/vomit.hpp" + +#include "../proto2/any-user.hpp" +#include "../proto2/login-admin.hpp" +#include "../proto2/login-char.hpp" +#include "../proto2/char-map.hpp" +#include "../proto2/char-user.hpp" #include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" @@ -194,6 +200,14 @@ TimeT update_online; // to update online files when we receiving infor static pid_t pid = 0; // For forked DB writes + +auto iter_map_sessions() -> decltype(filter_iterator<Session *>(std::declval<Array<Session *, MAX_MAP_SERVERS> *>())) +{ + return filter_iterator<Session *>(&server_session); +} + + + static void create_online_files(void); @@ -621,7 +635,7 @@ void mmo_char_sync_timer(TimerData *, tick_t) // Function to create a new character //----------------------------------- static -CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], uint8_t slot, uint16_t hair_color, uint16_t hair_style) +CharPair *make_new_char(Session *s, CharName name, const Stats6& stats, uint8_t slot, uint16_t hair_color, uint16_t hair_style) { // ugh char_session_data *sd = static_cast<char_session_data *>(s->session_data.get()); @@ -674,16 +688,17 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui } } // else, all letters/symbols are authorised (except control char removed before) + // TODO this comment is obsolete // this is why it needs to be unsigned - if (stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5] != 5 * 6 || // stats + if (stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk != 5 * 6 || // stats slot >= 9 || hair_style >= 20 || hair_color >= 12) { CHAR_LOG("Make new char error (invalid values): (connection #%d, account: %d) slot %d, name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d\n"_fmt, s, sd->account_id, slot, name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, hair_style, hair_color); return nullptr; } @@ -691,12 +706,13 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui // check individual stat value for (int i = 0; i < 6; i++) { - if (stats[i] < 1 || stats[i] > 9) + uint8_t statsi = reinterpret_cast<const uint8_t *>(&stats)[i]; + if (statsi < 1 || statsi > 9) { CHAR_LOG("Make new char error (invalid stat value: not between 1 to 9): (connection #%d, account: %d) slot %d, name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d\n"_fmt, s, sd->account_id, slot, name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, hair_style, hair_color); return nullptr; } @@ -708,8 +724,8 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui { CHAR_LOG("Make new char error (name already exists): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n"_fmt, s, sd->account_id, slot, name, cd.key.name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, hair_style, hair_color); return nullptr; } @@ -718,8 +734,8 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui { CHAR_LOG("Make new char error (slot already used): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n"_fmt, s, sd->account_id, slot, name, cd.key.name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, hair_style, hair_color); return nullptr; } @@ -729,8 +745,8 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui { CHAR_LOG("Make new char error (name used is wisp name for server): (connection #%d, account: %d) slot %d, name: %s (actual name whisper server: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n"_fmt, s, sd->account_id, slot, name, wisp_server_name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, hair_style, hair_color); return nullptr; } @@ -739,8 +755,8 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui CHAR_LOG("Creation of New Character: (connection #%d, account: %d) slot %d, character Name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d. [%s]\n"_fmt, s, sd->account_id, slot, name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, hair_style, hair_color, ip); CharPair cp; @@ -757,12 +773,12 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui cd.base_exp = 0; cd.job_exp = 0; cd.zeny = 0; - cd.attrs[ATTR::STR] = stats[0]; - cd.attrs[ATTR::AGI] = stats[1]; - cd.attrs[ATTR::VIT] = stats[2]; - cd.attrs[ATTR::INT] = stats[3]; - cd.attrs[ATTR::DEX] = stats[4]; - cd.attrs[ATTR::LUK] = stats[5]; + cd.attrs[ATTR::STR] = stats.str; + cd.attrs[ATTR::AGI] = stats.agi; + cd.attrs[ATTR::VIT] = stats.vit; + cd.attrs[ATTR::INT] = stats.int_; + cd.attrs[ATTR::DEX] = stats.dex; + cd.attrs[ATTR::LUK] = stats.luk; cd.max_hp = 40 * (100 + cd.attrs[ATTR::VIT]) / 100; cd.max_sp = 11 * (100 + cd.attrs[ATTR::INT]) / 100; cd.hp = cd.max_hp; @@ -963,66 +979,69 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd) } } - const int offset = 24; - WFIFO_ZERO(s, 0, offset + found_num * 106); - WFIFOW(s, 0) = 0x6b; - WFIFOW(s, 2) = offset + found_num * 106; + Packet_Head<0x006b> head_6b; + std::vector<Packet_Repeat<0x006b>> repeat_6b; + + head_6b.unused = {}; for (int i = 0; i < found_num; i++) { const CharPair *cp = found_char[i]; - int j = offset + (i * 106); const CharKey *k = &cp->key; const CharData *p = cp->data.get(); - WFIFOL(s, j) = unwrap<CharId>(k->char_id); - WFIFOL(s, j + 4) = p->base_exp; - WFIFOL(s, j + 8) = p->zeny; - WFIFOL(s, j + 12) = p->job_exp; - WFIFOL(s, j + 16) = p->job_level; - - WFIFOW(s, j + 20) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::SHOES)); - WFIFOW(s, j + 22) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::GLOVES)); - WFIFOW(s, j + 24) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::CAPE)); - WFIFOW(s, j + 26) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::MISC1)); - WFIFOL(s, j + 28) = static_cast<uint16_t>(p->option); - - WFIFOL(s, j + 32) = p->karma; - WFIFOL(s, j + 36) = p->manner; - - WFIFOW(s, j + 40) = p->status_point; - WFIFOW(s, j + 42) = std::min(p->hp, 0x7fff); - WFIFOW(s, j + 44) = std::min(p->max_hp, 0x7fff); - WFIFOW(s, j + 46) = std::min(p->sp, 0x7fff); - WFIFOW(s, j + 48) = std::min(p->max_sp, 0x7fff); - WFIFOW(s, j + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed; - WFIFOW(s, j + 52) = unwrap<Species>(p->species); - WFIFOW(s, j + 54) = p->hair; -// WFIFOW(s,j+56) = p->weapon; // dont send weapon since TMW does not support it - WFIFOW(s, j + 56) = 0; - WFIFOW(s, j + 58) = p->base_level; - WFIFOW(s, j + 60) = p->skill_point; - WFIFOW(s, j + 62) = unwrap<ItemNameId>(p->head_bottom); - WFIFOW(s, j + 64) = unwrap<ItemNameId>(p->shield); - WFIFOW(s, j + 66) = unwrap<ItemNameId>(p->head_top); - WFIFOW(s, j + 68) = unwrap<ItemNameId>(p->head_mid); - WFIFOW(s, j + 70) = p->hair_color; - WFIFOW(s, j + 72) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::MISC2)); -// WFIFOW(s,j+72) = p->clothes_color; - - WFIFO_STRING(s, j + 74, k->name.to__actual(), 24); - - WFIFOB(s, j + 98) = saturate<uint8_t>(p->attrs[ATTR::STR]); - WFIFOB(s, j + 99) = saturate<uint8_t>(p->attrs[ATTR::AGI]); - WFIFOB(s, j + 100) = saturate<uint8_t>(p->attrs[ATTR::VIT]); - WFIFOB(s, j + 101) = saturate<uint8_t>(p->attrs[ATTR::INT]); - WFIFOB(s, j + 102) = saturate<uint8_t>(p->attrs[ATTR::DEX]); - WFIFOB(s, j + 103) = saturate<uint8_t>(p->attrs[ATTR::LUK]); - WFIFOB(s, j + 104) = k->char_num; + Packet_Repeat<0x006b> info; + CharSelect& sel = info.char_select; + + sel.char_id = k->char_id; + sel.base_exp = p->base_exp; + sel.zeny = p->zeny; + sel.job_exp = p->job_exp; + sel.job_level = p->job_level; + + sel.shoes = find_equip_view(cp, EPOS::SHOES); + sel.gloves = find_equip_view(cp, EPOS::GLOVES); + sel.cape = find_equip_view(cp, EPOS::CAPE); + sel.misc1 = find_equip_view(cp, EPOS::MISC1); + sel.option = p->option; + + sel.karma = p->karma; + sel.manner = p->manner; + + sel.status_point = p->status_point; + sel.hp = std::min(p->hp, 0x7fff); + sel.max_hp = std::min(p->max_hp, 0x7fff); + sel.sp = std::min(p->sp, 0x7fff); + sel.max_sp = std::min(p->max_sp, 0x7fff); + sel.speed = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed; + sel.species = p->species; + sel.hair_style = p->hair; + sel.weapon = 0; // p->weapon; // dont send weapon since TMW does not support it + sel.base_level = p->base_level; + sel.skill_point = p->skill_point; + sel.head_bottom = p->head_bottom; + sel.shield = p->shield; + sel.head_top = p->head_top; + sel.head_mid = p->head_mid; + sel.hair_color = p->hair_color; + sel.misc2 = find_equip_view(cp, EPOS::MISC2); // = p->clothes_color; + + sel.char_name = k->name; + + sel.stats.str = saturate<uint8_t>(p->attrs[ATTR::STR]); + sel.stats.agi = saturate<uint8_t>(p->attrs[ATTR::AGI]); + sel.stats.vit = saturate<uint8_t>(p->attrs[ATTR::VIT]); + sel.stats.int_ = saturate<uint8_t>(p->attrs[ATTR::INT]); + sel.stats.dex = saturate<uint8_t>(p->attrs[ATTR::DEX]); + sel.stats.luk = saturate<uint8_t>(p->attrs[ATTR::LUK]); + sel.char_num = k->char_num; + sel.unused = 0; + + repeat_6b.push_back(info); } - WFIFOSET(s, WFIFOW(s, 2)); + send_vpacket<0x006b, 24, 106>(s, head_6b, repeat_6b); return 0; } @@ -1052,8 +1071,6 @@ int set_account_reg2(AccountId acc, Slice<global_reg> reg) static int char_divorce(CharPair *cp) { - uint8_t buf[10]; - if (cp == NULL) return 0; @@ -1062,24 +1079,31 @@ int char_divorce(CharPair *cp) if (!cs->partner_id) { - WBUFW(buf, 0) = 0x2b12; - WBUFL(buf, 2) = unwrap<CharId>(ck->char_id); + Packet_Fixed<0x2b12> fixed_12; + fixed_12.char_id = ck->char_id; // partner id 0 means failure - WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); - mapif_sendall(buf, 10); + fixed_12.partner_id = cs->partner_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } return 0; } - WBUFW(buf, 0) = 0x2b12; - WBUFL(buf, 2) = unwrap<CharId>(ck->char_id); + Packet_Fixed<0x2b12> fixed_12; + fixed_12.char_id = ck->char_id; for (CharPair& cd : char_keys) { if (cd.key.char_id == cs->partner_id && cd.data->partner_id == ck->char_id) { - WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); - mapif_sendall(buf, 10); + fixed_12.partner_id = cs->partner_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } + cs->partner_id = CharId(); cd.data->partner_id = CharId(); return 0; @@ -1088,17 +1112,24 @@ int char_divorce(CharPair *cp) // Don't worry about this, as the map server should verify itself that the other doesn't have us as a partner, and so won't mess with their marriage else if (cd.key.char_id == cs->partner_id) { - WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); - mapif_sendall(buf, 10); + fixed_12.partner_id = cs->partner_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } + cs->partner_id = CharId(); return 0; } } // Our partner wasn't found, so just clear our marriage - WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); + fixed_12.partner_id = cs->partner_id; cs->partner_id = CharId(); - mapif_sendall(buf, 10); + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } return 0; } @@ -1143,10 +1174,12 @@ int char_delete(CharPair *cp) // Force the character (and all on the same account) to leave all map servers { - unsigned char buf[6]; - WBUFW(buf, 0) = 0x2afe; - WBUFL(buf, 2) = unwrap<AccountId>(ck->account_id); - mapif_sendall(buf, 6); + Packet_Fixed<0x2afe> fixed_fe; + fixed_fe.account_id = ck->account_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2afe, 6>(ss, fixed_fe); + } } return 0; @@ -1165,14 +1198,20 @@ void parse_tologin(Session *ls) char_session_data *sd = static_cast<char_session_data *>(ls->session_data.get()); - while (RFIFOREST(ls) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(ls, &packet_id)) { - switch (RFIFOW(ls, 0)) + switch (packet_id) { case 0x2711: - if (RFIFOREST(ls) < 3) - return; - if (RFIFOB(ls, 2)) + { + Packet_Fixed<0x2711> fixed; + rv = recv_fpacket<0x2711, 3>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + if (fixed.code) { PRINTF("Can not connect to login-server.\n"_fmt); PRINTF("The server communication passwords (default s1/p1) is probably invalid.\n"_fmt); @@ -1187,62 +1226,72 @@ void parse_tologin(Session *ls) // if no map-server already connected, display a message... int i; for (i = 0; i < MAX_MAP_SERVERS; i++) + { if (server_session[i] && server[i].maps[0]) // if map-server online and at least 1 map break; + } if (i == MAX_MAP_SERVERS) PRINTF("Awaiting maps from map-server.\n"_fmt); } - RFIFOSKIP(ls, 3); break; + } case 0x2713: - if (RFIFOREST(ls) < 51) - return; + { + Packet_Fixed<0x2713> fixed; + rv = recv_fpacket<0x2713, 51>(ls, fixed); + if (rv != RecvResult::Complete) + break; + for (io::FD i : iter_fds()) { - AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); + AccountId acc = fixed.account_id; Session *s2 = get_session(i); if (!s2) continue; sd = static_cast<char_session_data *>(s2->session_data.get()); if (sd && sd->account_id == acc) { - if (RFIFOB(ls, 6) != 0) + if (fixed.invalid != 0) { - WFIFOW(s2, 0) = 0x6c; - WFIFOB(s2, 2) = 0x42; - WFIFOSET(s2, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0x42; + send_fpacket<0x006c, 3>(s2, fixed_6c); } else if (max_connect_user == 0 || count_users() < max_connect_user) { - sd->email = stringish<AccountEmail>(RFIFO_STRING<40>(ls, 7)); + sd->email = stringish<AccountEmail>(fixed.email); if (!e_mail_check(sd->email)) sd->email = DEFAULT_EMAIL; - sd->connect_until_time = static_cast<time_t>(RFIFOL(ls, 47)); + sd->connect_until_time = fixed.connect_until; // send characters to player mmo_char_send006b(s2, sd); } else { // refuse connection: too much online players - WFIFOW(s2, 0) = 0x6c; - WFIFOB(s2, 2) = 0; - WFIFOSET(s2, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0; + send_fpacket<0x006c, 3>(s2, fixed_6c); } break; } } - RFIFOSKIP(ls, 51); break; + } // Receiving of an e-mail/time limit from the login-server (answer of a request because a player comes back from map-server to char-server) by [Yor] case 0x2717: - if (RFIFOREST(ls) < 50) - return; + { + Packet_Fixed<0x2717> fixed; + rv = recv_fpacket<0x2717, 50>(ls, fixed); + if (rv != RecvResult::Complete) + break; + for (io::FD i : iter_fds()) { - AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); + AccountId acc = fixed.account_id; Session *s2 = get_session(i); if (!s2) continue; @@ -1251,40 +1300,49 @@ void parse_tologin(Session *ls) { if (sd->account_id == acc) { - sd->email = stringish<AccountEmail>(RFIFO_STRING<40>(ls, 6)); + sd->email = fixed.email; if (!e_mail_check(sd->email)) sd->email = DEFAULT_EMAIL; - sd->connect_until_time = static_cast<time_t>(RFIFOL(ls, 46)); + sd->connect_until_time = fixed.connect_until; break; } } } - RFIFOSKIP(ls, 50); break; + } case 0x2721: // gm reply - if (RFIFOREST(ls) < 10) - return; + { + Packet_Fixed<0x2721> fixed; + rv = recv_fpacket<0x2721, 10>(ls, fixed); + if (rv != RecvResult::Complete) + break; + { - AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); - GmLevel gml = GmLevel::from(RFIFOL(ls, 2)); - unsigned char buf[10]; - WBUFW(buf, 0) = 0x2b0b; - WBUFL(buf, 2) = unwrap<AccountId>(acc); - WBUFL(buf, 6) = gml.get_all_bits(); - mapif_sendall(buf, 10); + AccountId acc = fixed.account_id; + GmLevel gml = fixed.gm_level; + + Packet_Fixed<0x2b0b> fixed_2b; + fixed_2b.account_id = acc; + fixed_2b.gm_level = gml; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b0b, 10>(ss, fixed_2b); + } } - RFIFOSKIP(ls, 10); break; + } case 0x2723: // changesex reply (modified by [Yor]) - if (RFIFOREST(ls) < 7) - return; + { + Packet_Fixed<0x2723> fixed; + rv = recv_fpacket<0x2723, 7>(ls, fixed); + if (rv != RecvResult::Complete) + break; + { - unsigned char buf[7]; - AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); - SEX sex = static_cast<SEX>(RFIFOB(ls, 6)); - RFIFOSKIP(ls, 7); + AccountId acc = fixed.account_id; + SEX sex = fixed.sex; if (acc) { for (CharPair& cp : char_keys) @@ -1312,18 +1370,26 @@ void parse_tologin(Session *ls) // disconnect player if online on char-server disconnect_player(acc); } - WBUFW(buf, 0) = 0x2b0d; - WBUFL(buf, 2) = unwrap<AccountId>(acc); - WBUFB(buf, 6) = static_cast<uint8_t>(sex); - mapif_sendall(buf, 7); + Packet_Fixed<0x2b0d> fixed_0d; + fixed_0d.account_id = acc; + fixed_0d.sex = sex; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b0d, 7>(ss, fixed_0d); + } } break; + } case 0x2726: // Request to send a broadcast message (no answer) - if (RFIFOREST(ls) < 8 - || RFIFOREST(ls) < (8 + RFIFOL(ls, 4))) - return; - if (RFIFOL(ls, 4) < 1) + { + Packet_Head<0x2726> head; + AString repeat; + rv = recv_vpacket<0x2726, 8, 1>(ls, head, repeat); + if (rv != RecvResult::Complete) + break; + + if (!repeat) CHAR_LOG("Receiving a message for broadcast, but message is void.\n"_fmt); else { @@ -1336,8 +1402,7 @@ void parse_tologin(Session *ls) CHAR_LOG("'ladmin': Receiving a message for broadcast, but no map-server is online.\n"_fmt); else { - size_t len = RFIFOL(ls, 4); - AString message = RFIFO_STRING(ls, 8, len).to_print().lstrip(); + AString message = repeat.to_print().lstrip(); // if message is only composed of spaces if (!message) CHAR_LOG("Receiving a message for broadcast, but message is only a lot of spaces.\n"_fmt); @@ -1347,62 +1412,81 @@ void parse_tologin(Session *ls) CHAR_LOG("'ladmin': Receiving a message for broadcast (message (in yellow): %s)\n"_fmt, message); // send broadcast to all map-servers - uint8_t buf[4 + len]; - WBUFW(buf, 0) = 0x3800; - WBUFW(buf, 2) = 4 + len; - WBUF_STRING(buf, 4, message, len); - mapif_sendall(buf, WBUFW(buf, 2)); + for (Session *ss : iter_map_sessions()) + { + send_packet_repeatonly<0x3800, 4, 1>(ss, message); + } } } } - RFIFOSKIP(ls, 8 + RFIFOL(ls, 4)); break; + } // account_reg2変更通知 case 0x2729: - if (RFIFOREST(ls) < 4 || RFIFOREST(ls) < RFIFOW(ls, 2)) - return; + { + Packet_Head<0x2729> head; + std::vector<Packet_Repeat<0x2729>> repeat; + rv = recv_vpacket<0x2729, 8, 36>(ls, head, repeat); + if (rv != RecvResult::Complete) + break; + { Array<struct global_reg, ACCOUNT_REG2_NUM> reg; - int j, p; - AccountId acc = wrap<AccountId>(RFIFOL(ls, 4)); - for (p = 8, j = 0; - p < RFIFOW(ls, 2) && j < ACCOUNT_REG2_NUM; - p += 36, j++) + int j = 0; + AccountId acc = head.account_id; + for (const auto& info : repeat) { - reg[j].str = stringish<VarName>(RFIFO_STRING<32>(ls, p)); - reg[j].value = RFIFOL(ls, p + 32); + reg[j].str = info.name; + reg[j].value = info.value; + ++j; + if (j == ACCOUNT_REG2_NUM) + break; } set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), j)); - size_t len = RFIFOW(ls, 2); - uint8_t buf[len]; - RFIFO_BUF_CLONE(ls, buf, len); - WBUFW(buf, 0) = 0x2b11; - mapif_sendall(buf, len); + Packet_Head<0x2b11> head_11; + head_11.account_id = head.account_id; + std::vector<Packet_Repeat<0x2b11>> repeat_11(repeat.size()); + for (size_t k = 0; k < repeat.size(); ++k) + { + repeat_11[k].name = repeat[k].name; + repeat_11[k].value = repeat[k].value; + } + for (Session *ss : iter_map_sessions()) + { + send_vpacket<0x2b11, 8, 36>(ss, head_11, repeat_11); + } } - RFIFOSKIP(ls, RFIFOW(ls, 2)); break; + } case 0x7924: { // [Fate] Itemfrob package: forwarded from login-server - if (RFIFOREST(ls) < 10) - return; - ItemNameId source_id = wrap<ItemNameId>(RFIFOL(ls, 2)); - ItemNameId dest_id = wrap<ItemNameId>(RFIFOL(ls, 6)); - unsigned char buf[10]; + Packet_Fixed<0x7924> fixed; + rv = recv_fpacket<0x7924, 10>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + ItemNameId source_id = fixed.source_item_id; + ItemNameId dest_id = fixed.dest_item_id; - WBUFW(buf, 0) = 0x2afa; - WBUFL(buf, 2) = unwrap<ItemNameId>(source_id); - WBUFL(buf, 6) = unwrap<ItemNameId>(dest_id); + Packet_Fixed<0x2afa> fixed_fa; + fixed_fa.source_item_id = source_id; + fixed_fa.dest_item_id = dest_id; + + // forward package to map servers + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2afa, 10>(ss, fixed_fa); + } - mapif_sendall(buf, 10); // forward package to map servers for (CharPair& cp : char_keys) { CharKey *k = &cp.key; CharData& cd = *cp.data.get(); CharData *c = &cd; - struct storage *s = account2storage(k->account_id); + Storage *s = account2storage(k->account_id); int changes = 0; int j; #define FIX(v) if (v == source_id) {v = dest_id; ++changes; } @@ -1428,16 +1512,18 @@ void parse_tologin(Session *ls) mmo_char_sync(); inter_storage_save(); - RFIFOSKIP(ls, 10); break; } // Account deletion notification (from login-server) case 0x2730: - if (RFIFOREST(ls) < 6) - return; { - AccountId aid = wrap<AccountId>(RFIFOL(ls, 2)); + Packet_Fixed<0x2730> fixed; + rv = recv_fpacket<0x2730, 6>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId aid = fixed.account_id; // Deletion of all characters of the account //#warning "This comment is a lie, but it's still true." @@ -1468,50 +1554,57 @@ void parse_tologin(Session *ls) inter_storage_delete(aid); // send to all map-servers to disconnect the player { - unsigned char buf[6]; - WBUFW(buf, 0) = 0x2b13; - WBUFL(buf, 2) = unwrap<AccountId>(aid); - mapif_sendall(buf, 6); + Packet_Fixed<0x2b13> fixed_13; + fixed_13.account_id = aid; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b13, 6>(ss, fixed_13); + } } // disconnect player if online on char-server disconnect_player(aid); - } - RFIFOSKIP(ls, 6); break; + } // State change of account/ban notification (from login-server) by [Yor] case 0x2731: - if (RFIFOREST(ls) < 11) - return; { - AccountId aid = wrap<AccountId>(RFIFOL(ls, 2)); + Packet_Fixed<0x2731> fixed; + rv = recv_fpacket<0x2731, 11>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId aid = fixed.account_id; // send to all map-servers to disconnect the player { - unsigned char buf[11]; - WBUFW(buf, 0) = 0x2b14; - WBUFL(buf, 2) = unwrap<AccountId>(aid); - WBUFB(buf, 6) = RFIFOB(ls, 6); // 0: change of statut, 1: ban - WBUFL(buf, 7) = RFIFOL(ls, 7); // status or final date of a banishment - mapif_sendall(buf, 11); + Packet_Fixed<0x2b14> fixed_14; + fixed_14.account_id = aid; + fixed_14.ban_not_status = fixed.ban_not_status; // 0: change of statut, 1: ban + fixed_14.status_or_ban_until = fixed.status_or_ban_until; // status or final date of a banishment + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b14, 11>(ss, fixed_14); + } } // disconnect player if online on char-server disconnect_player(aid); - } - RFIFOSKIP(ls, 11); break; + } // Receiving GM acounts info from login-server (by [Yor]) case 0x2732: - if (RFIFOREST(ls) < 4 || RFIFOREST(ls) < RFIFOW(ls, 2)) - return; + { + std::vector<Packet_Repeat<0x2732>> repeat; + rv = recv_packet_repeatonly<0x2732, 4, 5>(ls, repeat); + if (rv != RecvResult::Complete) + break; + { - size_t len = RFIFOW(ls, 2); - uint8_t buf[len]; - gm_accounts.clear(); - gm_accounts.reserve((len - 4) / 5); - for (int i = 4; i < len; i += 5) + gm_accounts.resize(repeat.size()); + for (size_t k = 0; k < repeat.size(); ++k) { - gm_accounts.push_back({wrap<AccountId>(RFIFOL(ls, i)), GmLevel::from(static_cast<uint32_t>(RFIFOB(ls, i + 4)))}); + gm_accounts[k].account_id = repeat[k].account_id; + gm_accounts[k].level = repeat[k].gm_level; } PRINTF("From login-server: receiving of %zu GM accounts information.\n"_fmt, gm_accounts.size()); @@ -1519,19 +1612,30 @@ void parse_tologin(Session *ls) gm_accounts.size()); create_online_files(); // update online players files (perhaps some online players change of GM level) // send new gm acccounts level to map-servers - RFIFO_BUF_CLONE(ls, buf, len); - WBUFW(buf, 0) = 0x2b15; - mapif_sendall(buf, len); + std::vector<Packet_Repeat<0x2b15>> repeat_15(repeat.size()); + for (size_t k = 0; k < repeat.size(); ++k) + { + repeat_15[k].account_id = repeat[k].account_id; + repeat_15[k].gm_level = repeat[k].gm_level; + } + for (Session *ss : iter_map_sessions()) + { + send_packet_repeatonly<0x2b15, 4, 5>(ss, repeat_15); + } } - RFIFOSKIP(ls, RFIFOW(ls, 2)); break; + } case 0x2741: // change password reply - if (RFIFOREST(ls) < 7) - return; + { + Packet_Fixed<0x2741> fixed; + rv = recv_fpacket<0x2741, 7>(ls, fixed); + if (rv != RecvResult::Complete) + break; + { - AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); - int status = RFIFOB(ls, 6); + AccountId acc = fixed.account_id; + int status = fixed.status; for (io::FD i : iter_fds()) { @@ -1543,20 +1647,22 @@ void parse_tologin(Session *ls) { if (sd->account_id == acc) { - WFIFOW(s2, 0) = 0x62; - WFIFOB(s2, 2) = status; - WFIFOSET(s2, 3); + Packet_Fixed<0x0062> fixed_62; + fixed_62.status = status; + send_fpacket<0x0062, 3>(s2, fixed_62); break; } } } } - RFIFOSKIP(ls, 7); break; + } default: + { ls->set_eof(); return; + } } } } @@ -1598,47 +1704,60 @@ void parse_frommap(Session *ms) return; } - while (RFIFOREST(ms) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(ms, &packet_id)) { - switch (RFIFOW(ms, 0)) + switch (packet_id) { // request from map-server to reload GM accounts. Transmission to login-server (by Yor) case 0x2af7: + { + Packet_Fixed<0x2af7> fixed; + rv = recv_fpacket<0x2af7, 2>(ms, fixed); + if (rv != RecvResult::Complete) + break; + if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2709; - WFIFOSET(login_session, 2); + Packet_Fixed<0x2709> fixed_09; + send_fpacket<0x2709, 2>(login_session, fixed_09); } - RFIFOSKIP(ms, 2); break; + } // Receiving map names list from the map-server case 0x2afa: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; { + std::vector<Packet_Repeat<0x2afa>> repeat; + rv = recv_packet_repeatonly<0x2afa, 4, 16>(ms, repeat); + if (rv != RecvResult::Complete) + break; + for (MapName &foo : server[id].maps) foo = MapName(); - int j = 0; - for (int i = 4; i < RFIFOW(ms, 2); i += 16) + + for (size_t j = 0; j < repeat.size(); ++j) { - server[id].maps[j] = RFIFO_STRING<16>(ms, i); - j++; + server[id].maps[j] = repeat[j].map_name; } + const size_t j = repeat.size(); + { - PRINTF("Map-Server %d connected: %d maps, from IP %s port %d.\n"_fmt, + PRINTF("Map-Server %d connected: %zu maps, from IP %s port %d.\n"_fmt, id, j, server[id].ip, server[id].port); PRINTF("Map-server %d loading complete.\n"_fmt, id); - CHAR_LOG("Map-Server %d connected: %d maps, from IP %s port %d. Map-server %d loading complete.\n"_fmt, + CHAR_LOG("Map-Server %d connected: %zu maps, from IP %s port %d. Map-server %d loading complete.\n"_fmt, id, j, server[id].ip, server[id].port, id); } - WFIFOW(ms, 0) = 0x2afb; - WFIFOB(ms, 2) = 0; - WFIFO_STRING(ms, 3, wisp_server_name.to__actual(), 24); - WFIFOSET(ms, 27); + + Packet_Fixed<0x2afb> fixed_fb; + fixed_fb.unknown = 0; + fixed_fb.whisper_name = wisp_server_name; + send_fpacket<0x2afb, 27>(ms, fixed_fb); + { - unsigned char buf[16384]; if (j == 0) { PRINTF("WARNING: Map-Server %d have NO map.\n"_fmt, id); @@ -1648,49 +1767,62 @@ void parse_frommap(Session *ms) } else { - WBUFW(buf, 0) = 0x2b04; - WBUFW(buf, 2) = j * 16 + 10; - WBUFIP(buf, 4) = server[id].ip; - WBUFW(buf, 8) = server[id].port; - // server[id].maps[i] = RFIFO_STRING(fd, 4 + i * 16) + Packet_Head<0x2b04> head_04; + head_04.ip = server[id].ip; + head_04.port = server[id].port; + std::vector<Packet_Repeat<0x2b04>> repeat_04(j); for (int i = 0; i < j; ++i) - WBUF_STRING(buf, 10, server[id].maps[i], 16); - mapif_sendallwos(ms, buf, WBUFW(buf, 2)); + { + repeat_04[i].map_name = server[id].maps[i]; + } + for (Session *ss : iter_map_sessions()) + { + if (ss == ms) + continue; + send_vpacket<0x2b04, 10, 16>(ss, head_04, repeat_04); + } } // Transmitting the maps of the other map-servers to the new map-server for (int x = 0; x < MAX_MAP_SERVERS; x++) { if (server_session[x] && x != id) { - WFIFOW(ms, 0) = 0x2b04; - WFIFOIP(ms, 4) = server[x].ip; - WFIFOW(ms, 8) = server[x].port; - j = 0; + Packet_Head<0x2b04> head_04; + head_04.ip = server[x].ip; + head_04.port = server[x].port; + std::vector<Packet_Repeat<0x2b04>> repeat_04; for (int i = 0; i < MAX_MAP_PER_SERVER; i++) + { if (server[x].maps[i]) - WFIFO_STRING(ms, 10 + (j++) * 16, server[x].maps[i], 16); - if (j > 0) + { + Packet_Repeat<0x2b04> info; + info.map_name = server[x].maps[i]; + repeat_04.push_back(info); + } + } + if (repeat.size()) { - WFIFOW(ms, 2) = j * 16 + 10; - WFIFOSET(ms, WFIFOW(ms, 2)); + send_vpacket<0x2b04, 10, 16>(ms, head_04, repeat_04); } } } } - } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // 認証要求 case 0x2afc: - if (RFIFOREST(ms) < 22) - return; { - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 2)); - CharId char_id = wrap<CharId>(RFIFOL(ms, 6)); - int login_id1 = RFIFOL(ms, 10); - int login_id2 = RFIFOL(ms, 14); - IP4Address ip = RFIFOIP(ms, 18); + Packet_Fixed<0x2afc> fixed; + rv = recv_fpacket<0x2afc, 22>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + CharId char_id = fixed.char_id; + int login_id1 = fixed.login_id1; + int login_id2 = fixed.login_id2; + IP4Address ip = fixed.ip; for (AuthFifoEntry& afi : auth_fifo) { if (afi.account_id == account_id && @@ -1716,39 +1848,43 @@ void parse_frommap(Session *ms) CharData *cd = cp->data.get(); afi.delflag = 1; - WFIFOW(ms, 0) = 0x2afd; - WFIFOW(ms, 2) = 18 + sizeof(*ck) + sizeof(*cd); - WFIFOL(ms, 4) = unwrap<AccountId>(account_id); - WFIFOL(ms, 8) = afi.login_id2; - WFIFOL(ms, 12) = static_cast<time_t>(afi.connect_until_time); + Packet_Payload<0x2afd> payload_fd; // not file descriptor + payload_fd.account_id = account_id; + payload_fd.login_id2 = afi.login_id2; + payload_fd.connect_until = afi.connect_until_time; cd->sex = afi.sex; - WFIFOW(ms, 16) = afi.packet_tmw_version; + payload_fd.packet_tmw_version = afi.packet_tmw_version; FPRINTF(stderr, "From queue index %zd: recalling packet version %d\n"_fmt, (&afi - &auth_fifo.front()), afi.packet_tmw_version); - WFIFO_STRUCT(ms, 18, *ck); - WFIFO_STRUCT(ms, 18 + sizeof(*ck), *cd); - WFIFOSET(ms, WFIFOW(ms, 2)); + payload_fd.char_key = *ck; + payload_fd.char_data = *cd; + send_ppacket<0x2afd>(ms, payload_fd); goto x2afc_out; } } { - WFIFOW(ms, 0) = 0x2afe; - WFIFOL(ms, 2) = unwrap<AccountId>(account_id); - WFIFOSET(ms, 6); + Packet_Fixed<0x2afe> fixed_fe; + fixed_fe.account_id = account_id; + send_fpacket<0x2afe, 6>(ms, fixed_fe); PRINTF("auth_fifo search error! account %d not authentified.\n"_fmt, account_id); } - } x2afc_out: - RFIFOSKIP(ms, 22); break; + } // MAPサーバー上のユーザー数受信 case 0x2aff: - if (RFIFOREST(ms) < 6 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; - server[id].users = RFIFOW(ms, 4); + { + Packet_Head<0x2aff> head; + std::vector<Packet_Repeat<0x2aff>> repeat; + rv = recv_vpacket<0x2aff, 6, 4>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + + server[id].users = head.users; + assert (head.users == repeat.size()); if (anti_freeze_enable) server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed // remove all previously online players of the server @@ -1761,7 +1897,7 @@ void parse_frommap(Session *ms) // add online players in the list by [Yor] for (int i = 0; i < server[id].users; i++) { - CharId char_id = wrap<CharId>(RFIFOL(ms, 6 + i * 4)); + CharId char_id = repeat[i].char_id; for (const CharPair& cd : char_keys) { if (cd.key.char_id == char_id) @@ -1779,313 +1915,370 @@ void parse_frommap(Session *ms) // only every 8 sec. (normally, 1 server send users every 5 sec.) Don't update every time, because that takes time, but only every 2 connection. // it set to 8 sec because is more than 5 (sec) and if we have more than 1 map-server, informations can be received in shifted. } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // キャラデータ保存 case 0x2b01: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; { - AccountId aid = wrap<AccountId>(RFIFOL(ms, 4)); - CharId cid = wrap<CharId>(RFIFOL(ms, 8)); + Packet_Payload<0x2b01> payload; + rv = recv_ppacket<0x2b01>(ms, payload); + if (rv != RecvResult::Complete) + break; + + AccountId aid = payload.account_id; + CharId cid = payload.char_id; for (CharPair& cd : char_keys) { if (cd.key.account_id == aid && cd.key.char_id == cid) { - RFIFO_STRUCT(ms, 12, cd.key); - RFIFO_STRUCT(ms, 12 + sizeof(cd.key), *cd.data); + cd.key = payload.char_key; + *cd.data = payload.char_data; break; } } - } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // キャラセレ要求 case 0x2b02: - if (RFIFOREST(ms) < 18) - return; { - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 2)); + Packet_Fixed<0x2b02> fixed; + rv = recv_fpacket<0x2b02, 18>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); auth_fifo_iter->account_id = account_id; auth_fifo_iter->char_id = CharId(); - auth_fifo_iter->login_id1 = RFIFOL(ms, 6); - auth_fifo_iter->login_id2 = RFIFOL(ms, 10); + auth_fifo_iter->login_id1 = fixed.login_id1; + auth_fifo_iter->login_id2 = fixed.login_id2; auth_fifo_iter->delflag = 2; auth_fifo_iter->connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server) - auth_fifo_iter->ip = RFIFOIP(ms, 14); + auth_fifo_iter->ip = fixed.ip; auth_fifo_iter++; - WFIFOW(ms, 0) = 0x2b03; - WFIFOL(ms, 2) = unwrap<AccountId>(account_id); - WFIFOB(ms, 6) = 0; - WFIFOSET(ms, 7); - } - RFIFOSKIP(ms, 18); + + Packet_Fixed<0x2b03> fixed_03; + fixed_03.account_id = account_id; + fixed_03.unknown = 0; + send_fpacket<0x2b03, 7>(ms, fixed_03); break; + } // マップサーバー間移動要求 case 0x2b05: - if (RFIFOREST(ms) < 49) - return; + { + Packet_Fixed<0x2b05> fixed; + rv = recv_fpacket<0x2b05, 49>(ms, fixed); + if (rv != RecvResult::Complete) + break; + if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); - RFIFO_WFIFO_CLONE(ms, ms, 44); - // overwrite - WFIFOW(ms, 0) = 0x2b06; - auth_fifo_iter->account_id = wrap<AccountId>(RFIFOL(ms, 2)); - auth_fifo_iter->char_id = wrap<CharId>(RFIFOL(ms, 14)); - auth_fifo_iter->login_id1 = RFIFOL(ms, 6); - auth_fifo_iter->login_id2 = RFIFOL(ms, 10); + Packet_Fixed<0x2b06> fixed_06; + fixed_06.account_id = fixed.account_id; + //fixed_06.error = fixed.login_id1; + //fixed_06.unknown = fixed.login_id2; + fixed_06.char_id = fixed.char_id; + fixed_06.map_name = fixed.map_name; + fixed_06.x = fixed.x; + fixed_06.y = fixed.y; + fixed_06.map_ip = fixed.map_ip; + fixed_06.map_port = fixed.map_port; + + auth_fifo_iter->account_id = fixed.account_id; + auth_fifo_iter->login_id1 = fixed.login_id1; + auth_fifo_iter->login_id2 = fixed.login_id2; + auth_fifo_iter->char_id = fixed.char_id; auth_fifo_iter->delflag = 0; - auth_fifo_iter->sex = static_cast<SEX>(RFIFOB(ms, 44)); + auth_fifo_iter->sex = fixed.sex; auth_fifo_iter->connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server) - auth_fifo_iter->ip = RFIFOIP(ms, 45); + auth_fifo_iter->ip = fixed.client_ip; // default, if not found in the loop - WFIFOW(ms, 6) = 1; + fixed_06.error = 1; for (const CharPair& cd : char_keys) { - AccountId aid = wrap<AccountId>(RFIFOL(ms, 2)); - CharId cid = wrap<CharId>(RFIFOL(ms, 14)); + AccountId aid = fixed.account_id; + CharId cid = fixed.char_id; if (cd.key.account_id == aid && cd.key.char_id == cid) { auth_fifo_iter++; - WFIFOL(ms, 6) = 0; + fixed_06.error = 0; break; } } - WFIFOSET(ms, 44); - RFIFOSKIP(ms, 49); + send_fpacket<0x2b06, 44>(ms, fixed_06); break; + } // it is a request to become GM case 0x2b0a: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; { - int account_id = RFIFOL(ms, 4); + Packet_Head<0x2b0a> head; + AString repeat; + rv = recv_vpacket<0x2b0a, 8, 1>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = head.account_id; if (login_session) { // don't send request if no login-server - size_t len = RFIFOW(ms, 2); - RFIFO_WFIFO_CLONE(ms, login_session, len); - WFIFOW(login_session, 0) = 0x2720; - WFIFOSET(login_session, len); + Packet_Head<0x2720> head_20; + head_20.account_id = account_id; + AString& repeat_20 = repeat; + send_vpacket<0x2720, 8, 1>(ms, head_20, repeat_20); } else { - WFIFOW(ms, 0) = 0x2b0b; - WFIFOL(ms, 2) = account_id; - WFIFOL(ms, 6) = 0; - WFIFOSET(ms, 10); + Packet_Fixed<0x2b0b> fixed_0b; + fixed_0b.account_id = account_id; + fixed_0b.gm_level = GmLevel(); + send_fpacket<0x2b0b, 10>(ms, fixed_0b); } - } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // Map server send information to change an email of an account -> login-server case 0x2b0c: - if (RFIFOREST(ms) < 86) - return; + { + Packet_Fixed<0x2b0c> fixed; + rv = recv_fpacket<0x2b0c, 86>(ms, fixed); + if (rv != RecvResult::Complete) + break; + if (login_session) { // don't send request if no login-server - RFIFO_WFIFO_CLONE(ms, login_session, 86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B - WFIFOW(login_session, 0) = 0x2722; - WFIFOSET(login_session, 86); + Packet_Fixed<0x2722> fixed_22; + fixed_22.account_id = fixed.account_id; + fixed_22.old_email = fixed.old_email; + fixed_22.new_email = fixed.new_email; + send_fpacket<0x2722, 86>(login_session, fixed_22); } - RFIFOSKIP(ms, 86); break; + } // Map server ask char-server about a character name to do some operations (all operations are transmitted to login-server) case 0x2b0e: - if (RFIFOREST(ms) < 44) - return; + { + Packet_Fixed<0x2b0e> fixed; + rv = recv_fpacket<0x2b0e, 44>(ms, fixed); + if (rv != RecvResult::Complete) + break; + { - AccountId acc = wrap<AccountId>(RFIFOL(ms, 2)); // account_id of who ask (-1 if nobody) - CharName character_name = stringish<CharName>(RFIFO_STRING<24>(ms, 6)); - int operation = RFIFOW(ms, 30); + AccountId acc = fixed.account_id; + CharName character_name = fixed.char_name; + int operation = fixed.operation; // prepare answer - WFIFOW(ms, 0) = 0x2b0f; // answer - WFIFOL(ms, 2) = unwrap<AccountId>(acc); // who want do operation - WFIFOW(ms, 30) = operation; // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5-changesex + Packet_Fixed<0x2b0f> fixed_0f; + fixed_0f.account_id = acc; + fixed_0f.operation = operation; // search character const CharPair *cd = search_character(character_name); + // TODO invert the below logic to shrink this code + // Current logic: + // 1. if no character, return error 1 + // 2. else if gm level too low, return error 2 + // 3. else if login server offline, return error 3 + // 4. else return error 0 and maybe do other stuff if (cd) { const CharKey *ck = &cd->key; - WFIFO_STRING(ms, 6, ck->name.to__actual(), 24); // put correct name if found - WFIFOW(ms, 32) = 0; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline - switch (RFIFOW(ms, 30)) + fixed_0f.char_name = ck->name; + fixed_0f.error = 0; + switch (operation) { case 1: // block + { if (!acc || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2724; - WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value - WFIFOL(login_session, 6) = 5; // status of the account - WFIFOSET(login_session, 10); + Packet_Fixed<0x2724> fixed_24; + fixed_24.account_id = ck->account_id; + fixed_24.status = 5; + send_fpacket<0x2724, 10>(login_session, fixed_24); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 2: // ban + { if (!acc || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2725; - WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value - HumanTimeDiff ban_change; - RFIFO_STRUCT(ms, 32, ban_change); - WFIFO_STRUCT(login_session, 6, ban_change); - WFIFOSET(login_session, 18); + Packet_Fixed<0x2725> fixed_25; + fixed_25.account_id = ck->account_id; + HumanTimeDiff ban_change = fixed.ban_add; + fixed_25.ban_add = ban_change; + send_fpacket<0x2725, 18>(login_session, fixed_25); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 3: // unblock + { if (!acc || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2724; - WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value - WFIFOL(login_session, 6) = 0; // status of the account - WFIFOSET(login_session, 10); + Packet_Fixed<0x2724> fixed_24; + fixed_24.account_id = ck->account_id; + fixed_24.status = 0; + send_fpacket<0x2724, 10>(login_session, fixed_24); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 4: // unban + { if (!acc || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x272a; - WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value - WFIFOSET(login_session, 6); + Packet_Fixed<0x272a> fixed_2a; + fixed_2a.account_id = ck->account_id; + send_fpacket<0x272a, 6>(login_session, fixed_2a); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 5: // changesex + { if (!acc || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2727; - WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value - WFIFOSET(login_session, 6); + Packet_Fixed<0x2727> fixed_27; + fixed_27.account_id = ck->account_id; + send_fpacket<0x2727, 6>(login_session, fixed_27); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } } } else { // character name not found - WFIFO_STRING(ms, 6, character_name.to__actual(), 24); - WFIFOW(ms, 32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.char_name = character_name; + fixed_0f.error = 1; } // send answer if a player ask, not if the server ask if (acc) { - WFIFOSET(ms, 34); + send_fpacket<0x2b0f, 34>(ms, fixed_0f); } - RFIFOSKIP(ms, 44); break; } - -// case 0x2b0f: not more used (available for futur usage) + } // account_reg保存要求 case 0x2b10: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; + { + Packet_Head<0x2b10> head; + std::vector<Packet_Repeat<0x2b10>> repeat; + rv = recv_vpacket<0x2b10, 8, 36>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + { Array<struct global_reg, ACCOUNT_REG2_NUM> reg; - int p, j; - AccountId acc = wrap<AccountId>(RFIFOL(ms, 4)); - for (p = 8, j = 0; - p < RFIFOW(ms, 2) && j < ACCOUNT_REG2_NUM; - p += 36, j++) + AccountId acc = head.account_id; + auto jlim = std::min(repeat.size(), ACCOUNT_REG2_NUM); + for (size_t j = 0; j < jlim; ++j) { - reg[j].str = stringish<VarName>(RFIFO_STRING<32>(ms, p)); - reg[j].value = RFIFOL(ms, p + 32); + reg[j].str = repeat[j].name; + reg[j].value = repeat[j].value; } - set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), j)); + set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), jlim)); // loginサーバーへ送る if (login_session) { // don't send request if no login-server - RFIFO_WFIFO_CLONE(ms, login_session, RFIFOW(ms, 2)); - WFIFOW(login_session, 0) = 0x2728; - WFIFOSET(login_session, WFIFOW(login_session, 2)); + Packet_Head<0x2728> head_28; + std::vector<Packet_Repeat<0x2728>> repeat_28(repeat.size()); + for (size_t j = 0; j < repeat.size(); ++j) + { + repeat_28[j].name = repeat[j].name; + repeat_28[j].value = repeat[j].value; + } + send_vpacket<0x2728, 8, 36>(login_session, head_28, repeat_28); } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; } + } // Map server is requesting a divorce case 0x2b16: - if (RFIFOREST(ms) < 4) - return; + { + Packet_Fixed<0x2b16> fixed; + rv = recv_fpacket<0x2b16, 6>(ms, fixed); + if (rv != RecvResult::Complete) + break; + { - CharId cid = wrap<CharId>(RFIFOL(ms, 2)); + CharId cid = fixed.char_id; for (CharPair& cd : char_keys) + { if (cd.key.char_id == cid) { char_divorce(&cd); break; } + } - RFIFOSKIP(ms, 6); break; } + } default: // inter server処理に渡す { - int r = inter_parse_frommap(ms); - if (r == 1) // 処理できた + RecvResult r = inter_parse_frommap(ms, packet_id); + if (r == RecvResult::Complete) break; - if (r == 2) // パケット長が足りない + if (r == RecvResult::Incomplete) return; - } // inter server処理でもない場合は切断 PRINTF("char: unknown packet 0x%04x (%zu bytes to read in buffer)! (from map).\n"_fmt, - RFIFOW(ms, 0), RFIFOREST(ms)); + packet_id, packet_avail(ms)); ms->set_eof(); return; + } } } } @@ -2164,25 +2357,27 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP // if no map-server is connected, we send: server closed if (j == MAX_MAP_SERVERS) { - WFIFOW(s, 0) = 0x81; - WFIFOB(s, 2) = 1; // 01 = Server closed - WFIFOSET(s, 3); + Packet_Fixed<0x0081> fixed_81; + fixed_81.error_code = 1; + send_fpacket<0x0081, 3>(s, fixed_81); return; } } - WFIFOW(s, 0) = 0x71; - WFIFOL(s, 2) = unwrap<CharId>(ck->char_id); - WFIFO_STRING(s, 6, cd->last_point.map_, 16); + + Packet_Fixed<0x0071> fixed_71; + fixed_71.char_id = ck->char_id; + fixed_71.map_name = cd->last_point.map_; PRINTF("Character selection '%s' (account: %d, slot: %d) [%s]\n"_fmt, ck->name, sd->account_id, ck->char_num, ip); PRINTF("--Send IP of map-server. "_fmt); if (lan_ip_check(ip)) - WFIFOIP(s, 22) = lan_map_ip; + fixed_71.ip = lan_map_ip; else - WFIFOIP(s, 22) = server[i].ip; - WFIFOW(s, 26) = server[i].port; - WFIFOSET(s, 28); + fixed_71.ip = server[i].ip; + fixed_71.port = server[i].port; + send_fpacket<0x0071, 28>(s, fixed_71); + if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); auth_fifo_iter->account_id = sd->account_id; @@ -2216,36 +2411,40 @@ void parse_char(Session *s) char_session_data *sd = static_cast<char_session_data *>(s->session_data.get()); - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { - switch (RFIFOW(s, 0)) + switch (packet_id) { - case 0x20b: //20040622暗号化ragexe対応 - if (RFIFOREST(s) < 19) - return; - RFIFOSKIP(s, 19); - break; - case 0x61: // change password request - if (RFIFOREST(s) < 50) - return; + { + Packet_Fixed<0x0061> fixed; + rv = recv_fpacket<0x0061, 50>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - WFIFOW(login_session, 0) = 0x2740; - WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id); - AccountPass old_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 2)); - WFIFO_STRING(login_session, 6, old_pass, 24); - AccountPass new_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); - WFIFO_STRING(login_session, 30, new_pass, 24); - WFIFOSET(login_session, 54); + Packet_Fixed<0x2740> fixed_40; + fixed_40.account_id = sd->account_id; + AccountPass old_pass = fixed.old_pass; + fixed_40.old_pass = old_pass; + AccountPass new_pass = fixed.new_pass; + fixed_40.new_pass = new_pass; + send_fpacket<0x2740, 54>(login_session, fixed_40); } - RFIFOSKIP(s, 50); break; + } case 0x65: // 接続要求 - if (RFIFOREST(s) < 17) - return; + { + Packet_Fixed<0x0065> fixed; + rv = recv_fpacket<0x0065, 17>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - AccountId account_id = wrap<AccountId>(RFIFOL(s, 2)); + AccountId account_id = fixed.account_id; GmLevel GM_value = isGM(account_id); if (GM_value) PRINTF("Account Logged On; Account ID: %d (GM level %d).\n"_fmt, @@ -2261,13 +2460,19 @@ void parse_char(Session *s) sd->connect_until_time = TimeT(); // unknow or illimited (not displaying on map-server) } sd->account_id = account_id; - sd->login_id1 = RFIFOL(s, 6); - sd->login_id2 = RFIFOL(s, 10); - sd->packet_tmw_version = RFIFOW(s, 14); - sd->sex = static_cast<SEX>(RFIFOB(s, 16)); + sd->login_id1 = fixed.login_id1; + sd->login_id2 = fixed.login_id2; + sd->packet_tmw_version = fixed.packet_tmw_version; + sd->sex = fixed.sex; // send back account_id - WFIFOL(s, 0) = unwrap<AccountId>(account_id); - WFIFOSET(s, 4); + // TODO put this into a proper packet + Little32 account_id_net; + if (!native_to_network(&account_id_net, account_id) + || !packet_send(s, reinterpret_cast<const Byte *>(&account_id_net), 4)) + { + s->set_eof(); + return; + } // search authentification for (AuthFifoEntry& afi : auth_fifo) { @@ -2285,9 +2490,9 @@ void parse_char(Session *s) if (login_session) { // don't send request if no login-server // request to login-server to obtain e-mail/time limit - WFIFOW(login_session, 0) = 0x2716; - WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id); - WFIFOSET(login_session, 6); + Packet_Fixed<0x2716> fixed_16; + fixed_16.account_id = sd->account_id; + send_fpacket<0x2716, 6>(login_session, fixed_16); } // Record client version afi.packet_tmw_version = @@ -2298,9 +2503,9 @@ void parse_char(Session *s) else { // refuse connection (over populated) - WFIFOW(s, 0) = 0x6c; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0; + send_fpacket<0x006c, 3>(s, fixed_6c); } goto x65_out; } @@ -2310,111 +2515,144 @@ void parse_char(Session *s) if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2712; // ask login-server to authentify an account - WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id); - WFIFOL(login_session, 6) = sd->login_id1; - WFIFOL(login_session, 10) = sd->login_id2; // relate to the versions higher than 18 - WFIFOB(login_session, 14) = static_cast<uint8_t>(sd->sex); - WFIFOIP(login_session, 15) = s->client_ip; - WFIFOSET(login_session, 19); + Packet_Fixed<0x2712> fixed_12; + fixed_12.account_id = sd->account_id; + fixed_12.login_id1 = sd->login_id1; + fixed_12.login_id2 = sd->login_id2; // relate to the versions higher than 18 + fixed_12.sex = sd->sex; + fixed_12.ip = s->client_ip; + send_fpacket<0x2712, 19>(login_session, fixed_12); } else { // if no login-server, we must refuse connection - WFIFOW(s, 0) = 0x6c; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0; + send_fpacket<0x006c, 3>(s, fixed_6c); } } } x65_out: - RFIFOSKIP(s, 17); break; + } case 0x66: // キャラ選択 - if (!sd || RFIFOREST(s) < 3) + { + Packet_Fixed<0x0066> fixed; + rv = recv_fpacket<0x0066, 3>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (!sd) + { + s->set_eof(); return; - handle_x0066(s, sd, RFIFOB(s, 2), ip); - RFIFOSKIP(s, 3); + } + handle_x0066(s, sd, fixed.code, ip); break; + } case 0x67: // 作成 - if (!sd || RFIFOREST(s) < 37) - return; { - CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 2)); - uint8_t stats[6]; - for (int i = 0; i < 6; ++i) - stats[i] = RFIFOB(s, 26 + i); - uint8_t slot = RFIFOB(s, 32); - uint16_t hair_color = RFIFOW(s, 33); - uint16_t hair_style = RFIFOW(s, 35); + Packet_Fixed<0x0067> fixed; + rv = recv_fpacket<0x0067, 37>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (!sd) + { + s->set_eof(); + return; + } + CharName name = fixed.char_name; + Stats6 stats = fixed.stats; + uint8_t slot = fixed.slot; + uint16_t hair_color = fixed.hair_color; + uint16_t hair_style = fixed.hair_style; const CharPair *cp = make_new_char(s, name, stats, slot, hair_color, hair_style); if (!cp) { - WFIFOW(s, 0) = 0x6e; - WFIFOB(s, 2) = 0x00; - WFIFOSET(s, 3); - RFIFOSKIP(s, 37); + Packet_Fixed<0x006e> fixed_6e; + fixed_6e.code = 0x00; + send_fpacket<0x006e, 3>(s, fixed_6e); break; } const CharKey *ck = &cp->key; const CharData *cd = cp->data.get(); - WFIFOW(s, 0) = 0x6d; - WFIFO_ZERO(s, 2, 106); - - WFIFOL(s, 2) = unwrap<CharId>(ck->char_id); - WFIFOL(s, 2 + 4) = cd->base_exp; - WFIFOL(s, 2 + 8) = cd->zeny; - WFIFOL(s, 2 + 12) = cd->job_exp; - WFIFOL(s, 2 + 16) = cd->job_level; - - WFIFOL(s, 2 + 28) = cd->karma; - WFIFOL(s, 2 + 32) = cd->manner; - - WFIFOW(s, 2 + 40) = 0x30; - WFIFOW(s, 2 + 42) = saturate<int16_t>(cd->hp); - WFIFOW(s, 2 + 44) = saturate<int16_t>(cd->max_hp); - WFIFOW(s, 2 + 46) = saturate<int16_t>(cd->sp); - WFIFOW(s, 2 + 48) = saturate<int16_t>(cd->max_sp); - WFIFOW(s, 2 + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // cd->speed; - WFIFOW(s, 2 + 52) = unwrap<Species>(cd->species); - WFIFOW(s, 2 + 54) = cd->hair; - - WFIFOW(s, 2 + 58) = cd->base_level; - WFIFOW(s, 2 + 60) = cd->skill_point; - - WFIFOW(s, 2 + 64) = unwrap<ItemNameId>(cd->shield); - WFIFOW(s, 2 + 66) = unwrap<ItemNameId>(cd->head_top); - WFIFOW(s, 2 + 68) = unwrap<ItemNameId>(cd->head_mid); - WFIFOW(s, 2 + 70) = cd->hair_color; - - WFIFO_STRING(s, 2 + 74, ck->name.to__actual(), 24); - - WFIFOB(s, 2 + 98) = saturate<uint8_t>(cd->attrs[ATTR::STR]); - WFIFOB(s, 2 + 99) = saturate<uint8_t>(cd->attrs[ATTR::AGI]); - WFIFOB(s, 2 + 100) = saturate<uint8_t>(cd->attrs[ATTR::VIT]); - WFIFOB(s, 2 + 101) = saturate<uint8_t>(cd->attrs[ATTR::INT]); - WFIFOB(s, 2 + 102) = saturate<uint8_t>(cd->attrs[ATTR::DEX]); - WFIFOB(s, 2 + 103) = saturate<uint8_t>(cd->attrs[ATTR::LUK]); - WFIFOB(s, 2 + 104) = ck->char_num; - - WFIFOSET(s, 108); - } - RFIFOSKIP(s, 37); + Packet_Fixed<0x006d> fixed_6d; + + fixed_6d.char_select.char_id = ck->char_id; + fixed_6d.char_select.base_exp = cd->base_exp; + fixed_6d.char_select.zeny = cd->zeny; + fixed_6d.char_select.job_exp = cd->job_exp; + fixed_6d.char_select.job_level = cd->job_level; + + fixed_6d.char_select.shoes = ItemNameId(); + fixed_6d.char_select.gloves = ItemNameId(); + fixed_6d.char_select.cape = ItemNameId(); + fixed_6d.char_select.misc1 = ItemNameId(); + fixed_6d.char_select.option = Option(); + fixed_6d.char_select.unused = 0; + + // this was buggy until the protocol became generated + // but the client ignores it anyway + fixed_6d.char_select.karma = cd->karma; + fixed_6d.char_select.manner = cd->manner; + + fixed_6d.char_select.status_point = 0x30; + fixed_6d.char_select.hp = saturate<int16_t>(cd->hp); + fixed_6d.char_select.max_hp = saturate<int16_t>(cd->max_hp); + fixed_6d.char_select.sp = saturate<int16_t>(cd->sp); + fixed_6d.char_select.max_sp = saturate<int16_t>(cd->max_sp); + fixed_6d.char_select.speed = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // cd->speed; + fixed_6d.char_select.species = cd->species; + fixed_6d.char_select.hair_style = cd->hair; + fixed_6d.char_select.weapon = 0; + + fixed_6d.char_select.base_level = cd->base_level; + fixed_6d.char_select.skill_point = cd->skill_point; + + fixed_6d.char_select.head_bottom = ItemNameId(); + fixed_6d.char_select.shield = cd->shield; + fixed_6d.char_select.head_top = cd->head_top; + fixed_6d.char_select.head_mid = cd->head_mid; + fixed_6d.char_select.hair_color = cd->hair_color; + fixed_6d.char_select.misc2 = ItemNameId(); + + fixed_6d.char_select.char_name = ck->name; + + fixed_6d.char_select.stats.str = saturate<uint8_t>(cd->attrs[ATTR::STR]); + fixed_6d.char_select.stats.agi = saturate<uint8_t>(cd->attrs[ATTR::AGI]); + fixed_6d.char_select.stats.vit = saturate<uint8_t>(cd->attrs[ATTR::VIT]); + fixed_6d.char_select.stats.int_ = saturate<uint8_t>(cd->attrs[ATTR::INT]); + fixed_6d.char_select.stats.dex = saturate<uint8_t>(cd->attrs[ATTR::DEX]); + fixed_6d.char_select.stats.luk = saturate<uint8_t>(cd->attrs[ATTR::LUK]); + fixed_6d.char_select.char_num = ck->char_num; + fixed_6d.char_select.unused2 = 0; + + send_fpacket<0x006d, 108>(s, fixed_6d); break; + } case 0x68: // delete char //Yor's Fix - if (!sd || RFIFOREST(s) < 46) - return; { - AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 6)); + Packet_Fixed<0x0068> fixed; + rv = recv_fpacket<0x0068, 46>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (!sd) + { + s->set_eof(); + return; + } + AccountEmail email = fixed.email; if (!e_mail_check(email)) email = DEFAULT_EMAIL; { { - CharId cid = wrap<CharId>(RFIFOL(s, 2)); + CharId cid = fixed.char_id; CharPair *cs = nullptr; for (CharPair& cd : char_keys) { @@ -2435,93 +2673,100 @@ void parse_char(Session *s) } char_keys.pop_back(); - WFIFOW(s, 0) = 0x6f; - WFIFOSET(s, 2); + Packet_Fixed<0x006f> fixed_6f; + send_fpacket<0x006f, 2>(s, fixed_6f); goto x68_out; } } { - WFIFOW(s, 0) = 0x70; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); + Packet_Fixed<0x0070> fixed_70; + fixed_70.code = 0; + send_fpacket<0x0070, 3>(s, fixed_70); } } - } x68_out: - RFIFOSKIP(s, 46); break; + } case 0x2af8: // マップサーバーログイン - if (RFIFOREST(s) < 60) - return; { + Packet_Fixed<0x2af8> fixed; + rv = recv_fpacket<0x2af8, 60>(s, fixed); + if (rv != RecvResult::Complete) + break; + int i; - WFIFOW(s, 0) = 0x2af9; + Packet_Fixed<0x2af9> fixed_f9; for (i = 0; i < MAX_MAP_SERVERS; i++) { if (!server_session[i]) break; } - AccountName userid_ = stringish<AccountName>(RFIFO_STRING<24>(s, 2)); - AccountPass passwd_ = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); + AccountName userid_ = fixed.account_name; + AccountPass passwd_ = fixed.account_pass; if (i == MAX_MAP_SERVERS || userid_ != userid || passwd_ != passwd) { - WFIFOB(s, 2) = 3; - WFIFOSET(s, 3); - RFIFOSKIP(s, 60); + fixed_f9.code = 3; + send_fpacket<0x2af9, 3>(s, fixed_f9); } else { - int len; - WFIFOB(s, 2) = 0; + fixed_f9.code = 0; s->set_parsers(SessionParsers{.func_parse= parse_frommap, .func_delete= delete_frommap}); server_session[i] = s; if (anti_freeze_enable) server_freezeflag[i] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed - // ignore RFIFOL(fd, 50) - server[i].ip = RFIFOIP(s, 54); - server[i].port = RFIFOW(s, 58); + // ignore fixed.unknown + server[i].ip = fixed.ip; + server[i].port = fixed.port; server[i].users = 0; for (MapName& mapi : server[i].maps) mapi = MapName(); - WFIFOSET(s, 3); - RFIFOSKIP(s, 60); + send_fpacket<0x2af9, 3>(s, fixed_f9); realloc_fifo(s, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); // send gm acccounts level to map-servers - len = 4; - WFIFOW(s, 0) = 0x2b15; + std::vector<Packet_Repeat<0x2b15>> repeat_15(gm_accounts.size()); + auto it = repeat_15.begin(); for (const GM_Account& gma : gm_accounts) { - WFIFOL(s, len) = unwrap<AccountId>(gma.account_id); - WFIFOB(s, len + 4) = gma.level.get_all_bits(); - len += 5; + it->account_id = gma.account_id; + it->gm_level = gma.level; + ++it; } - WFIFOW(s, 2) = len; - WFIFOSET(s, len); + send_packet_repeatonly<0x2b15, 4, 5>(s, repeat_15); + // justification: we switched the session parsers + parse_frommap(s); return; } - } - break; - - case 0x187: // Alive信号? - if (RFIFOREST(s) < 6) - return; - RFIFOSKIP(s, 6); break; + } case 0x7530: // Athena情報所得 - WFIFOW(s, 0) = 0x7531; - WFIFO_STRUCT(s, 2, CURRENT_CHAR_SERVER_VERSION); - WFIFOSET(s, 10); - RFIFOSKIP(s, 2); - return; + { + Packet_Fixed<0x7530> fixed; + rv = recv_fpacket<0x7530, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7531> fixed_31; + fixed_31.version = CURRENT_CHAR_SERVER_VERSION; + send_fpacket<0x7531, 10>(s, fixed_31); + break; + } case 0x7532: // 接続の切断(defaultと処理は一緒だが明示的にするため) + { + Packet_Fixed<0x7532> fixed; + rv = recv_fpacket<0x7532, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + s->set_eof(); return; + } default: s->set_eof(); @@ -2530,81 +2775,25 @@ void parse_char(Session *s) } } -// 全てのMAPサーバーにデータ送信(送信したmap鯖の数を返す) -int mapif_sendall(const uint8_t *buf, unsigned int len) -{ - int i, c; - - c = 0; - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - Session *s = server_session[i]; - if (s) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - c++; - } - } - return c; -} - -// 自分以外の全てのMAPサーバーにデータ送信(送信したmap鯖の数を返す) -int mapif_sendallwos(Session *ss, const uint8_t *buf, unsigned int len) -{ - int i, c; - - c = 0; - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - Session *s = server_session[i]; - if (s && s != ss) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - c++; - } - } - return c; -} - -// MAPサーバーにデータ送信(map鯖生存確認有り) -int mapif_send(Session *s, const uint8_t *buf, unsigned int len) -{ - int i; - - if (s) - { - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - if (s == server_session[i]) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - return 1; - } - } - } - return 0; -} - static void send_users_tologin(TimerData *, tick_t) { int users = count_users(); - uint8_t buf[16]; if (login_session) { // send number of user to login server - WFIFOW(login_session, 0) = 0x2714; - WFIFOL(login_session, 2) = users; - WFIFOSET(login_session, 6); + Packet_Fixed<0x2714> fixed_14; + fixed_14.users = users; + send_fpacket<0x2714, 6>(login_session, fixed_14); } // send number of players to all map-servers - WBUFW(buf, 0) = 0x2b00; - WBUFL(buf, 2) = users; - mapif_sendall(buf, 6); + Packet_Fixed<0x2b00> fixed_00; + fixed_00.users = users; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b00, 6>(ss, fixed_00); + } } static @@ -2618,18 +2807,18 @@ void check_connect_login_server(TimerData *, tick_t) if (!login_session) return; realloc_fifo(login_session, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); - WFIFOW(login_session, 0) = 0x2710; - WFIFO_ZERO(login_session, 2, 24); - WFIFO_STRING(login_session, 2, userid, 24); - WFIFO_STRING(login_session, 26, passwd, 24); - WFIFOL(login_session, 50) = 0; - WFIFOIP(login_session, 54) = char_ip; - WFIFOL(login_session, 58) = char_port; - WFIFO_STRING(login_session, 60, server_name, 20); - WFIFOW(login_session, 80) = 0; - WFIFOW(login_session, 82) = 0; //char_maintenance; - WFIFOW(login_session, 84) = 0; //char_new; - WFIFOSET(login_session, 86); + + Packet_Fixed<0x2710> fixed_10; + fixed_10.account_name = userid; + fixed_10.account_pass = passwd; + fixed_10.unknown = 0; + fixed_10.ip = char_ip; + fixed_10.port = char_port; + fixed_10.server_name = server_name; + fixed_10.unknown2 = 0; + fixed_10.maintenance = 0; + fixed_10.is_new = 0; + send_fpacket<0x2710, 86>(login_session, fixed_10); } } diff --git a/src/char/char.hpp b/src/char/char.hpp index 3ba455f..f8adeb9 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -45,9 +45,7 @@ const CharPair *search_character(CharName character_name); const CharPair *search_character_id(CharId char_id); Session *server_for(const CharPair *mcs); -int mapif_sendall(const uint8_t *buf, unsigned int len); -int mapif_sendallwos(Session *s, const uint8_t *buf, unsigned int len); -int mapif_send(Session *s, const uint8_t *buf, unsigned int len); +auto iter_map_sessions() -> decltype(filter_iterator<Session *>(std::declval<Array<Session *, MAX_MAP_SERVERS> *>())); void char_log(XString line); diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 056e11d..64e3158 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -33,7 +33,9 @@ #include "../io/read.hpp" #include "../io/write.hpp" -#include "../net/vomit.hpp" +#include "../net/packets.hpp" + +#include "../proto2/char-map.hpp" #include "../mmo/extract.hpp" #include "../mmo/ids.hpp" @@ -47,27 +49,27 @@ AString party_txt = "save/party.txt"_s; static -Map<PartyId, struct party> party_db; +Map<PartyId, PartyMost> party_db; static PartyId party_newid = wrap<PartyId>(100_u32); static void mapif_party_broken(PartyId party_id, int flag); static -int party_check_empty(struct party *p); +int party_check_empty(PartyPair p); static void mapif_parse_PartyLeave(Session *s, PartyId party_id, AccountId account_id); // パーティデータの文字列への変換 static -AString inter_party_tostr(struct party *p) +AString inter_party_tostr(PartyPair p) { MString str; str += STRPRINTF( "%d\t" "%s\t" "%d,%d\t"_fmt, - p->party_id, + p.party_id, p->name, p->exp, p->item); for (int i = 0; i < MAX_PARTY; i++) @@ -86,9 +88,9 @@ AString inter_party_tostr(struct party *p) } static -bool extract(XString str, party *p) +bool extract(XString str, PartyPair *pp) { - *p = party(); + PartyPair& p = *pp; // not compatible with the normal extract()ors since it has // a variable-size element that uses the same separator @@ -97,7 +99,7 @@ bool extract(XString str, party *p) return false; auto begin = bits.begin(); auto end = bits.end(); - if (begin == end || !extract(*begin, &p->party_id)) + if (begin == end || !extract(*begin, &p.party_id)) return false; ++begin; if (begin == end || !extract(*begin, &p->name)) @@ -125,7 +127,7 @@ bool extract(XString str, party *p) } static -void party_check_deleted_init(struct party *p) +void party_check_deleted_init(PartyPair p) { for (int i = 0; i < MAX_PARTY; i++) { @@ -136,10 +138,10 @@ void party_check_deleted_init(struct party *p) { CHAR_LOG("WARNING: deleting obsolete party member %d %s of %d %s\n"_fmt, p->member[i].account_id, p->member[i].name, - p->party_id, p->name); + p.party_id, p->name); PRINTF("WARNING: deleting obsolete party member %d %s of %d %s\n"_fmt, p->member[i].account_id, p->member[i].name, - p->party_id, p->name); + p.party_id, p->name); p->member[i] = party_member{}; } } @@ -165,14 +167,16 @@ void inter_party_init(void) continue; } - struct party p {}; - if (extract(line, &p) && p.party_id) + PartyMost pm; + PartyPair pp; + pp.party_most = ± + if (extract(line, &pp) && pp.party_id) { - if (party_newid < next(p.party_id)) - party_newid = next(p.party_id); - party_check_deleted_init(&p); - party_db.insert(p.party_id, p); - party_check_empty(&p); + if (party_newid < next(pp.party_id)) + party_newid = next(pp.party_id); + party_check_deleted_init(pp); + party_db.insert(pp.party_id, pm); + party_check_empty(pp); } else { @@ -185,7 +189,7 @@ void inter_party_init(void) // パーティーデータのセーブ用 static -void inter_party_save_sub(struct party *data, io::WriteFile& fp) +void inter_party_save_sub(PartyPair data, io::WriteFile& fp) { AString line = inter_party_tostr(data); fp.put_line(line); @@ -202,14 +206,19 @@ int inter_party_save(void) return 1; } for (auto& pair : party_db) - inter_party_save_sub(&pair.second, fp); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + inter_party_save_sub(tmp, fp); + } return 0; } // パーティ名検索用 static -void search_partyname_sub(struct party *p, PartyName str, struct party **dst) +void search_partyname_sub(PartyPair p, PartyName str, PartyPair *dst) { if (p->name == str) *dst = p; @@ -217,18 +226,23 @@ void search_partyname_sub(struct party *p, PartyName str, struct party **dst) // パーティ名検索 static -struct party *search_partyname(PartyName str) +PartyPair search_partyname(PartyName str) { - struct party *p = NULL; + PartyPair p; for (auto& pair : party_db) - search_partyname_sub(&pair.second, str, &p); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + search_partyname_sub(tmp, str, &p); + } return p; } // EXP公平分配できるかチェック static -int party_check_exp_share(struct party *p) +int party_check_exp_share(PartyPair p) { int i; int maxlv = 0, minlv = 0x7fffffff; @@ -249,7 +263,7 @@ int party_check_exp_share(struct party *p) } // パーティが空かどうかチェック -int party_check_empty(struct party *p) +int party_check_empty(PartyPair p) { int i; @@ -261,20 +275,20 @@ int party_check_empty(struct party *p) } } // 誰もいないので解散 - mapif_party_broken(p->party_id, 0); - party_db.erase(p->party_id); + mapif_party_broken(p.party_id, 0); + party_db.erase(p.party_id); return 1; } // キャラの競合がないかチェック用 static -void party_check_conflict_sub(struct party *p, +void party_check_conflict_sub(PartyPair p, PartyId party_id, AccountId account_id, CharName nick) { int i; - if (p->party_id == party_id) // 本来の所属なので問題なし + if (p.party_id == party_id) // 本来の所属なので問題なし return; for (i = 0; i < MAX_PARTY; i++) @@ -284,8 +298,8 @@ void party_check_conflict_sub(struct party *p, { // 別のパーティに偽の所属データがあるので脱退 PRINTF("int_party: party conflict! %d %d %d\n"_fmt, account_id, - party_id, p->party_id); - mapif_parse_PartyLeave(nullptr, p->party_id, account_id); + party_id, p.party_id); + mapif_parse_PartyLeave(nullptr, p.party_id, account_id); } } } @@ -295,8 +309,13 @@ static void party_check_conflict(PartyId party_id, AccountId account_id, CharName nick) { for (auto& pair : party_db) - party_check_conflict_sub(&pair.second, + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + party_check_conflict_sub(tmp, party_id, account_id, nick); + } } //------------------------------------------------------------------- @@ -304,81 +323,92 @@ void party_check_conflict(PartyId party_id, AccountId account_id, CharName nick) // パーティ作成可否 static -void mapif_party_created(Session *s, AccountId account_id, struct party *p) +void mapif_party_created(Session *s, AccountId account_id, PartyPair p) { - WFIFOW(s, 0) = 0x3820; - WFIFOL(s, 2) = unwrap<AccountId>(account_id); - if (p != NULL) + Packet_Fixed<0x3820> fixed_20; + fixed_20.account_id = account_id; + if (p) { - WFIFOB(s, 6) = 0; - WFIFOL(s, 7) = unwrap<PartyId>(p->party_id); - WFIFO_STRING(s, 11, p->name, 24); - PRINTF("int_party: created! %d %s\n"_fmt, p->party_id, p->name); + fixed_20.error = 0; + fixed_20.party_id = p.party_id; + fixed_20.party_name = p->name; + PRINTF("int_party: created! %d %s\n"_fmt, p.party_id, p->name); } else { - WFIFOB(s, 6) = 1; - WFIFOL(s, 7) = 0; - WFIFO_STRING(s, 11, "error"_s, 24); + fixed_20.error = 1; + fixed_20.party_id = PartyId(); + fixed_20.party_name = stringish<PartyName>("error"_s); } - WFIFOSET(s, 35); + send_fpacket<0x3820, 35>(s, fixed_20); } // パーティ情報見つからず static void mapif_party_noinfo(Session *s, PartyId party_id) { - WFIFOW(s, 0) = 0x3821; - WFIFOW(s, 2) = 8; - WFIFOL(s, 4) = unwrap<PartyId>(party_id); - WFIFOSET(s, 8); + Packet_Head<0x3821> head_21; + Packet_Option<0x3821> option_21; + head_21.party_id = party_id; + send_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head_21, false, option_21); PRINTF("int_party: info not found %d\n"_fmt, party_id); } // パーティ情報まとめ送り static -void mapif_party_info(Session *s, struct party *p) +void mapif_party_info(Session *s, PartyPair p) { - unsigned char buf[4 + sizeof(struct party)]; - - WBUFW(buf, 0) = 0x3821; - WBUF_STRUCT(buf, 4, *p); - WBUFW(buf, 2) = 4 + sizeof(struct party); + Packet_Head<0x3821> head_21; + head_21.party_id = p.party_id; + Packet_Option<0x3821> option_21; + option_21.party_most = *p.party_most; if (!s) - mapif_sendall(buf, WBUFW(buf, 2)); + { + for (Session *ss : iter_map_sessions()) + { + send_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(ss, head_21, true, option_21); + } + } else - mapif_send(s, buf, WBUFW(buf, 2)); + { + send_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head_21, true, option_21); + } } // パーティメンバ追加可否 static void mapif_party_memberadded(Session *s, PartyId party_id, AccountId account_id, int flag) { - WFIFOW(s, 0) = 0x3822; - WFIFOL(s, 2) = unwrap<PartyId>(party_id); - WFIFOL(s, 6) = unwrap<AccountId>(account_id); - WFIFOB(s, 10) = flag; - WFIFOSET(s, 11); + Packet_Fixed<0x3822> fixed_22; + fixed_22.party_id = party_id; + fixed_22.account_id = account_id; + fixed_22.flag = flag; + send_fpacket<0x3822, 11>(s, fixed_22); } // パーティ設定変更通知 static -void mapif_party_optionchanged(Session *s, struct party *p, AccountId account_id, +void mapif_party_optionchanged(Session *s, PartyPair p, AccountId account_id, int flag) { - unsigned char buf[15]; - - WBUFW(buf, 0) = 0x3823; - WBUFL(buf, 2) = unwrap<PartyId>(p->party_id); - WBUFL(buf, 6) = unwrap<AccountId>(account_id); - WBUFW(buf, 10) = p->exp; - WBUFW(buf, 12) = p->item; - WBUFB(buf, 14) = flag; + Packet_Fixed<0x3823> fixed_23; + fixed_23.party_id = p.party_id; + fixed_23.account_id = account_id; + fixed_23.exp = p->exp; + fixed_23.item = p->item; + fixed_23.flag = flag; if (flag == 0) - mapif_sendall(buf, 15); + { + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3823, 15>(ss, fixed_23); + } + } else - mapif_send(s, buf, 15); - PRINTF("int_party: option changed %d %d %d %d %d\n"_fmt, p->party_id, + { + send_fpacket<0x3823, 15>(s, fixed_23); + } + PRINTF("int_party: option changed %d %d %d %d %d\n"_fmt, p.party_id, account_id, p->exp, p->item, flag); } @@ -386,40 +416,47 @@ void mapif_party_optionchanged(Session *s, struct party *p, AccountId account_id static void mapif_party_leaved(PartyId party_id, AccountId account_id, CharName name) { - unsigned char buf[34]; + Packet_Fixed<0x3824> fixed_24; + fixed_24.party_id = party_id; + fixed_24.account_id = account_id; + fixed_24.char_name = name; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3824, 34>(ss, fixed_24); + } - WBUFW(buf, 0) = 0x3824; - WBUFL(buf, 2) = unwrap<PartyId>(party_id); - WBUFL(buf, 6) = unwrap<AccountId>(account_id); - WBUF_STRING(buf, 10, name.to__actual(), 24); - mapif_sendall(buf, 34); PRINTF("int_party: party leaved %d %d %s\n"_fmt, party_id, account_id, name); } // パーティマップ更新通知 static -void mapif_party_membermoved(struct party *p, int idx) +void mapif_party_membermoved(PartyPair p, int idx) { assert (idx < MAX_PARTY); - unsigned char buf[29]; - WBUFW(buf, 0) = 0x3825; - WBUFL(buf, 2) = unwrap<PartyId>(p->party_id); - WBUFL(buf, 6) = unwrap<AccountId>(p->member[idx].account_id); - WBUF_STRING(buf, 10, p->member[idx].map, 16); - WBUFB(buf, 26) = p->member[idx].online; - WBUFW(buf, 27) = p->member[idx].lv; - mapif_sendall(buf, 29); + Packet_Fixed<0x3825> fixed_25; + fixed_25.party_id = p.party_id; + fixed_25.account_id = p->member[idx].account_id; + fixed_25.map_name = p->member[idx].map; + fixed_25.online = p->member[idx].online; + fixed_25.level = p->member[idx].lv; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3825, 29>(ss, fixed_25); + } } // パーティ解散通知 void mapif_party_broken(PartyId party_id, int flag) { - unsigned char buf[7]; - WBUFW(buf, 0) = 0x3826; - WBUFL(buf, 2) = unwrap<PartyId>(party_id); - WBUFB(buf, 6) = flag; - mapif_sendall(buf, 7); + Packet_Fixed<0x3826> fixed_26; + fixed_26.party_id = party_id; + fixed_26.flag = flag; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3826, 7>(ss, fixed_26); + } + PRINTF("int_party: broken %d\n"_fmt, party_id); CHAR_LOG("int_party: broken %d\n"_fmt, party_id); } @@ -428,15 +465,14 @@ void mapif_party_broken(PartyId party_id, int flag) static void mapif_party_message(PartyId party_id, AccountId account_id, XString mes) { - size_t len = mes.size() + 1; - unsigned char buf[len + 12]; - - WBUFW(buf, 0) = 0x3827; - WBUFW(buf, 2) = len + 12; - WBUFL(buf, 4) = unwrap<PartyId>(party_id); - WBUFL(buf, 8) = unwrap<AccountId>(account_id); - WBUF_STRING(buf, 12, mes, len); - mapif_sendall(buf, len + 12); + Packet_Head<0x3827> head_27; + XString repeat_27 = mes; + head_27.party_id = party_id; + head_27.account_id = account_id; + for (Session *ss : iter_map_sessions()) + { + send_vpacket<0x3827, 12, 1>(ss, head_27, repeat_27); + } } //------------------------------------------------------------------- @@ -451,20 +487,22 @@ void mapif_parse_CreateParty(Session *s, AccountId account_id, PartyName name, C if (!name.is_print()) { PRINTF("int_party: illegal party name [%s]\n"_fmt, name); - mapif_party_created(s, account_id, NULL); + mapif_party_created(s, account_id, PartyPair()); return; } } - if (search_partyname(name) != NULL) + if (search_partyname(name)) { PRINTF("int_party: same name party exists [%s]\n"_fmt, name); - mapif_party_created(s, account_id, NULL); + mapif_party_created(s, account_id, PartyPair()); return; } - struct party p {}; + PartyMost p {}; + PartyPair pp; + pp.party_most = &p; party_newid = next(party_newid); - p.party_id = party_newid; + pp.party_id = party_newid; p.name = name; p.exp = 0; p.item = 0; @@ -475,18 +513,19 @@ void mapif_parse_CreateParty(Session *s, AccountId account_id, PartyName name, C p.member[0].online = 1; p.member[0].lv = lv; - party_db.insert(p.party_id, p); + party_db.insert(pp.party_id, p); - mapif_party_created(s, account_id, &p); - mapif_party_info(s, &p); + mapif_party_created(s, account_id, pp); + mapif_party_info(s, pp); } // パーティ情報要求 static void mapif_parse_PartyInfo(Session *s, PartyId party_id) { - struct party *p = party_db.search(party_id); - if (p != NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (p) mapif_party_info(s, p); else mapif_party_noinfo(s, party_id); @@ -497,8 +536,9 @@ static void mapif_parse_PartyAddMember(Session *s, PartyId party_id, AccountId account_id, CharName nick, MapName map, int lv) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) { mapif_party_memberadded(s, party_id, account_id, 1); return; @@ -537,8 +577,9 @@ static void mapif_parse_PartyChangeOption(Session *s, PartyId party_id, AccountId account_id, int exp, int item) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) return; p->exp = exp; @@ -557,7 +598,8 @@ void mapif_parse_PartyChangeOption(Session *s, PartyId party_id, AccountId accou // パーティ脱退要求 void mapif_parse_PartyLeave(Session *, PartyId party_id, AccountId account_id) { - struct party *p = party_db.search(party_id); + PartyPair p; + p.party_most = party_db.search(party_id); if (!p) return; for (int i = 0; i < MAX_PARTY; i++) @@ -578,8 +620,9 @@ static void mapif_parse_PartyChangeMap(Session *s, PartyId party_id, AccountId account_id, MapName map, int online, int lv) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) return; for (int i = 0; i < MAX_PARTY; i++) @@ -608,8 +651,9 @@ void mapif_parse_PartyChangeMap(Session *s, PartyId party_id, AccountId account_ static void mapif_parse_BreakParty(Session *, PartyId party_id) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) return; party_db.erase(party_id); @@ -635,117 +679,163 @@ void mapif_parse_PartyCheck(Session *, PartyId party_id, AccountId account_id, C // ・パケット長データはinter.cにセットしておくこと // ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない -int inter_party_parse_frommap(Session *ms) +RecvResult inter_party_parse_frommap(Session *ms, uint16_t packet_id) { - switch (RFIFOW(ms, 0)) + RecvResult rv = RecvResult::Error; + switch (packet_id) { case 0x3020: { - AccountId account = wrap<AccountId>(RFIFOL(ms, 2)); - PartyName name = stringish<PartyName>(RFIFO_STRING<24>(ms, 6)); - CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 30)); - MapName map = RFIFO_STRING<16>(ms, 54); - uint16_t lv = RFIFOW(ms, 70); + Packet_Fixed<0x3020> fixed; + rv = recv_fpacket<0x3020, 72>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account = fixed.account_id; + PartyName name = fixed.party_name; + CharName nick = fixed.char_name; + MapName map = fixed.map_name; + uint16_t lv = fixed.level; mapif_parse_CreateParty(ms, account, name, nick, map, lv); - } break; + } case 0x3021: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); + Packet_Fixed<0x3021> fixed; + rv = recv_fpacket<0x3021, 6>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; mapif_parse_PartyInfo(ms, party_id); - } break; + } case 0x3022: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6)); - CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 10)); - MapName map = RFIFO_STRING<16>(ms, 34); - uint16_t lv = RFIFOW(ms, 50); + Packet_Fixed<0x3022> fixed; + rv = recv_fpacket<0x3022, 52>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + CharName nick = fixed.char_name; + MapName map = fixed.map_name; + uint16_t lv = fixed.level; mapif_parse_PartyAddMember(ms, party_id, account_id, nick, map, lv); - } break; + } case 0x3023: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6)); - uint16_t exp = RFIFOW(ms, 10); - uint16_t item = RFIFOW(ms, 12); + Packet_Fixed<0x3023> fixed; + rv = recv_fpacket<0x3023, 14>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + uint16_t exp = fixed.exp; + uint16_t item = fixed.item; mapif_parse_PartyChangeOption(ms, party_id, account_id, exp, item); - } break; + } case 0x3024: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6)); + Packet_Fixed<0x3024> fixed; + rv = recv_fpacket<0x3024, 10>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; mapif_parse_PartyLeave(ms, party_id, account_id); - } break; + } case 0x3025: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6)); - MapName map = RFIFO_STRING<16>(ms, 10); - uint8_t online = RFIFOB(ms, 26); - uint16_t lv = RFIFOW(ms, 27); + Packet_Fixed<0x3025> fixed; + rv = recv_fpacket<0x3025, 29>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + MapName map = fixed.map_name; + uint8_t online = fixed.online; + uint16_t lv = fixed.level; mapif_parse_PartyChangeMap(ms, party_id, account_id, map, online, lv); - } break; + } case 0x3026: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); + Packet_Fixed<0x3026> fixed; + rv = recv_fpacket<0x3026, 6>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; mapif_parse_BreakParty(ms, party_id); - } break; + } case 0x3027: { - size_t len = RFIFOW(ms, 2) - 12; - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 4)); - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 8)); - AString mes = RFIFO_STRING(ms, 12, len); + Packet_Head<0x3027> head; + AString repeat; + rv = recv_vpacket<0x3027, 12, 1>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = head.party_id; + AccountId account_id = head.account_id; + AString& mes = repeat; mapif_parse_PartyMessage(ms, party_id, account_id, mes); - } break; + } case 0x3028: { - PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2)); - AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6)); - CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 10)); + Packet_Fixed<0x3028> fixed; + rv = recv_fpacket<0x3028, 34>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + CharName nick = fixed.char_name; mapif_parse_PartyCheck(ms, party_id, account_id, nick); - } break; + } default: - return 0; + return RecvResult::Error; } - return 1; + return rv; } // サーバーから脱退要求(キャラ削除用) diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index ab42501..1d8cadc 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -32,7 +32,7 @@ void inter_party_init(void); int inter_party_save(void); -int inter_party_parse_frommap(Session *ms); +RecvResult inter_party_parse_frommap(Session *ms, uint16_t); void inter_party_leave(PartyId party_id, AccountId account_id); diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index 5cbc2a1..6ff6e2e 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -32,7 +32,9 @@ #include "../io/read.hpp" #include "../io/write.hpp" -#include "../net/vomit.hpp" +#include "../net/packets.hpp" + +#include "../proto2/char-map.hpp" #include "../mmo/extract.hpp" #include "../mmo/mmo.hpp" @@ -44,11 +46,11 @@ AString storage_txt = "save/storage.txt"_s; static -Map<AccountId, struct storage> storage_db; +Map<AccountId, Storage> storage_db; // 倉庫データを文字列に変換 static -AString storage_tostr(struct storage *p) +AString storage_tostr(Storage *p) { MString str; str += STRPRINTF( @@ -85,7 +87,7 @@ AString storage_tostr(struct storage *p) // 文字列を倉庫データに変換 static -bool extract(XString str, struct storage *p) +bool extract(XString str, Storage *p) { std::vector<struct item> storage_items; if (!extract(str, @@ -109,9 +111,9 @@ bool extract(XString str, struct storage *p) } // アカウントから倉庫データインデックスを得る(新規倉庫追加可能) -struct storage *account2storage(AccountId account_id) +Storage *account2storage(AccountId account_id) { - struct storage *s = storage_db.search(account_id); + Storage *s = storage_db.search(account_id); if (s == NULL) { s = storage_db.init(account_id); @@ -136,7 +138,7 @@ void inter_storage_init(void) AString line; while (in.getline(line)) { - struct storage s {}; + Storage s {}; if (extract(line, &s)) { storage_db.insert(s.account_id, s); @@ -151,7 +153,7 @@ void inter_storage_init(void) } static -void inter_storage_save_sub(struct storage *data, io::WriteFile& fp) +void inter_storage_save_sub(Storage *data, io::WriteFile& fp) { AString line = storage_tostr(data); if (line) @@ -188,53 +190,60 @@ void inter_storage_delete(AccountId account_id) static void mapif_load_storage(Session *ss, AccountId account_id) { - struct storage *st = account2storage(account_id); - WFIFOW(ss, 0) = 0x3810; - WFIFOW(ss, 2) = sizeof(struct storage) + 8; - WFIFOL(ss, 4) = unwrap<AccountId>(account_id); - WFIFO_STRUCT(ss, 8, *st); - WFIFOSET(ss, WFIFOW(ss, 2)); + Storage *st = account2storage(account_id); + Packet_Payload<0x3810> payload_10; + payload_10.account_id = account_id; + payload_10.storage = *st; + send_ppacket<0x3810>(ss, payload_10); } // 倉庫データ保存完了送信 static void mapif_save_storage_ack(Session *ss, AccountId account_id) { - WFIFOW(ss, 0) = 0x3811; - WFIFOL(ss, 2) = unwrap<AccountId>(account_id); - WFIFOB(ss, 6) = 0; - WFIFOSET(ss, 7); + Packet_Fixed<0x3811> fixed_11; + fixed_11.account_id = account_id; + fixed_11.unknown = 0; + send_fpacket<0x3811, 7>(ss, fixed_11); } //--------------------------------------------------------- // map serverからの通信 // 倉庫データ要求受信 -static -void mapif_parse_LoadStorage(Session *ss) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_LoadStorage(Session *ss) { - AccountId account_id = wrap<AccountId>(RFIFOL(ss, 2)); + Packet_Fixed<0x3010> fixed; + RecvResult rv = recv_fpacket<0x3010, 6>(ss, fixed); + if (rv != RecvResult::Complete) + return rv; + + AccountId account_id = fixed.account_id; mapif_load_storage(ss, account_id); + + return rv; } // 倉庫データ受信&保存 -static -void mapif_parse_SaveStorage(Session *ss) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_SaveStorage(Session *ss) { - struct storage *st; - AccountId account_id = wrap<AccountId>(RFIFOL(ss, 4)); - int len = RFIFOW(ss, 2); - if (sizeof(struct storage) != len - 8) - { - PRINTF("inter storage: data size error %zu %d\n"_fmt, - sizeof(struct storage), len - 8); - } - else + Packet_Payload<0x3011> payload; + RecvResult rv = recv_ppacket<0x3011>(ss, payload); + if (rv != RecvResult::Complete) + return rv; + + Storage *st; + AccountId account_id = payload.account_id; + { st = account2storage(account_id); - RFIFO_STRUCT(ss, 8, *st); + *st = payload.storage; mapif_save_storage_ack(ss, account_id); } + + return rv; } // map server からの通信 @@ -242,18 +251,19 @@ void mapif_parse_SaveStorage(Session *ss) // ・パケット長データはinter.cにセットしておくこと // ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない -int inter_storage_parse_frommap(Session *ms) +RecvResult inter_storage_parse_frommap(Session *ms, uint16_t packet_id) { - switch (RFIFOW(ms, 0)) + RecvResult rv; + switch (packet_id) { case 0x3010: - mapif_parse_LoadStorage(ms); + rv = mapif_parse_LoadStorage(ms); break; case 0x3011: - mapif_parse_SaveStorage(ms); + rv = mapif_parse_SaveStorage(ms); break; default: - return 0; + return RecvResult::Error; } - return 1; + return rv; } diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index 83981b6..6bf3e1f 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -32,9 +32,9 @@ void inter_storage_init(void); int inter_storage_save(void); void inter_storage_delete(AccountId account_id); -struct storage *account2storage(AccountId account_id); +Storage *account2storage(AccountId account_id); -int inter_storage_parse_frommap(Session *ms); +RecvResult inter_storage_parse_frommap(Session *ms, uint16_t); extern AString storage_txt; diff --git a/src/char/inter.cpp b/src/char/inter.cpp index a4af7e5..9eb43cf 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -38,7 +38,9 @@ #include "../io/read.hpp" #include "../io/write.hpp" -#include "../net/vomit.hpp" +#include "../net/packets.hpp" + +#include "../proto2/char-map.hpp" #include "../mmo/extract.hpp" #include "../mmo/mmo.hpp" @@ -54,29 +56,15 @@ AString accreg_txt = "save/accreg.txt"_s; struct accreg { - int account_id, reg_num; + AccountId account_id; + int reg_num; Array<struct global_reg, ACCOUNT_REG_NUM> reg; }; static -Map<int, struct accreg> accreg_db; +Map<AccountId, struct accreg> accreg_db; int party_share_level = 10; -// 受信パケット長リスト -static -int inter_recv_packet_length[] = -{ - -1, -1, 7, -1, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, -1, 0, 0, 0, 0, 0, 0, 10, -1, 0, 0, 0, 0, 0, 0, - 72, 6, 52, 14, 10, 29, 6, -1, 34, 0, 0, 0, 0, 0, 0, 0, - -1, 6, -1, 0, 55, 19, 6, -1, 14, -1, -1, -1, 14, 19, 186, -1, - 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 14, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - //-------------------------------------------------------- // アカウント変数を文字列へ変換 @@ -101,7 +89,7 @@ bool extract(XString str, struct accreg *reg) ®->account_id, vrec<' '>(&vars)))) return false; - if (reg->account_id <= 0) + if (!reg->account_id) return false; if (vars.size() > ACCOUNT_REG_NUM) @@ -218,14 +206,10 @@ void inter_init2() static void mapif_GMmessage(XString mes) { - size_t str_len = mes.size() + 1; - size_t msg_len = str_len + 4; - uint8_t buf[msg_len]; - - WBUFW(buf, 0) = 0x3800; - WBUFW(buf, 2) = msg_len; - WBUF_STRING(buf, 4, mes, str_len); - mapif_sendall(buf, msg_len); + for (Session *ss : iter_map_sessions()) + { + send_packet_repeatonly<0x3800, 4, 1>(ss, mes); + } } // Wisp/page transmission to correct map-server @@ -235,103 +219,105 @@ void mapif_wis_message(Session *tms, CharName src, CharName dst, XString msg) const CharPair *mcs = search_character(src); assert (mcs); - size_t str_size = msg.size() + 1; - uint8_t buf[56 + str_size]; - - WBUFW(buf, 0) = 0x3801; - WBUFW(buf, 2) = 56 + str_size; - WBUFL(buf, 4) = unwrap<CharId>(mcs->key.char_id); // formerly, whisper ID - WBUF_STRING(buf, 8, src.to__actual(), 24); - WBUF_STRING(buf, 32, dst.to__actual(), 24); - WBUF_STRING(buf, 56, msg, str_size); - mapif_send(tms, buf, WBUFW(buf, 2)); + Packet_Head<0x3801> head_01; + head_01.whisper_id = mcs->key.char_id; + head_01.src_char_name = src; + head_01.dst_char_name = dst; + send_vpacket<0x3801, 56, 1>(tms, head_01, msg); } // Wisp/page transmission result to map-server static void mapif_wis_end(Session *sms, CharName sender, int flag) { - uint8_t buf[27]; - - WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, sender.to__actual(), 24); - WBUFB(buf, 26) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - mapif_send(sms, buf, 27); + Packet_Fixed<0x3802> fixed_02; + fixed_02.sender_char_name = sender; + fixed_02.flag = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3802, 27>(sms, fixed_02); } // アカウント変数送信 static -void mapif_account_reg(Session *s) +void mapif_account_reg(Session *s, AccountId account_id, const std::vector<Packet_Repeat<0x3004>>& repeat) { - size_t len = RFIFOW(s, 2); - uint8_t buf[len]; - RFIFO_BUF_CLONE(s, buf, len); - WBUFW(buf, 0) = 0x3804; - mapif_sendallwos(s, buf, WBUFW(buf, 2)); + Packet_Head<0x3804> head_04; + head_04.account_id = account_id; + std::vector<Packet_Repeat<0x3804>> repeat_04(repeat.size()); + for (size_t i = 0; i < repeat.size(); ++i) + { + repeat_04[i].name = repeat[i].name; + repeat_04[i].value = repeat[i].value; + } + + for (Session *ss : iter_map_sessions()) + { + if (ss == s) + continue; + send_vpacket<0x3804, 8, 36>(ss, head_04, repeat_04); + } } // アカウント変数要求返信 static -void mapif_account_reg_reply(Session *s, int account_id) +void mapif_account_reg_reply(Session *s, AccountId account_id) { struct accreg *reg = accreg_db.search(account_id); - WFIFOW(s, 0) = 0x3804; - WFIFOL(s, 4) = account_id; - if (reg == NULL) - { - WFIFOW(s, 2) = 8; - } - else + Packet_Head<0x3804> head_04; + head_04.account_id = account_id; + std::vector<Packet_Repeat<0x3804>> repeat_04; + if (reg) { + repeat_04.resize(reg->reg_num); assert (reg->reg_num < ACCOUNT_REG_NUM); - int j, p; - for (j = 0, p = 8; j < reg->reg_num; j++, p += 36) + for (size_t j = 0; j < reg->reg_num; ++j) { - WFIFO_STRING(s, p, reg->reg[j].str, 32); - WFIFOL(s, p + 32) = reg->reg[j].value; + repeat_04[j].name = reg->reg[j].str; + repeat_04[j].value = reg->reg[j].value; } - WFIFOW(s, 2) = p; } - WFIFOSET(s, WFIFOW(s, 2)); + send_vpacket<0x3804, 8, 36>(s, head_04, repeat_04); } //-------------------------------------------------------- // received packets from map-server // GMメッセージ送信 -static -void mapif_parse_GMmessage(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_GMmessage(Session *s) { - size_t msg_len = RFIFOW(s, 2); - size_t str_len = msg_len - 4; - AString buf = RFIFO_STRING(s, 4, str_len); + AString repeat; + RecvResult rv = recv_packet_repeatonly<0x3000, 4, 1>(s, repeat); + if (rv != RecvResult::Complete) + return rv; + AString& buf = repeat; mapif_GMmessage(buf); + + return rv; } // Wisp/page request to send -static -void mapif_parse_WisRequest(Session *sms) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_WisRequest(Session *sms) { - if (RFIFOW(sms, 2) - 52 <= 0) - { // normaly, impossible, but who knows... - PRINTF("inter: Wis message doesn't exist.\n"_fmt); - return; - } + Packet_Head<0x3001> head; + AString repeat; + RecvResult rv = recv_vpacket<0x3001, 52, 1>(sms, head, repeat); + if (rv != RecvResult::Complete) + return rv; - CharName from = stringish<CharName>(RFIFO_STRING<24>(sms, 4)); - CharName to = stringish<CharName>(RFIFO_STRING<24>(sms, 28)); + CharName from = head.from_char_name; + CharName to = head.to_char_name; // search if character exists before to ask all map-servers const CharPair *mcs = search_character(to); if (!mcs) { - uint8_t buf[27]; - WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, from.to__actual(), 24); - WBUFB(buf, 26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - mapif_send(sms, buf, 27); + Packet_Fixed<0x3802> fixed_02; + fixed_02.sender_char_name = from; + fixed_02.flag = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3802, 27>(sms, fixed_02); // Character exists. So, ask all map-servers } else @@ -341,17 +327,15 @@ void mapif_parse_WisRequest(Session *sms) // if source is destination, don't ask other servers. if (from == to) { - uint8_t buf[27]; - WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, from.to__actual(), 24); - WBUFB(buf, 26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - mapif_send(sms, buf, 27); + Packet_Fixed<0x3802> fixed_02; + fixed_02.sender_char_name = from; + fixed_02.flag = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3802, 27>(sms, fixed_02); } else { - size_t len = RFIFOW(sms, 2) - 52; Session *tms = server_for(mcs); // for to - AString msg = RFIFO_STRING(sms, 52, len); + AString& msg = repeat; if (tms) { mapif_wis_message(tms, from, to, msg); @@ -362,69 +346,99 @@ void mapif_parse_WisRequest(Session *sms) } } } + + return rv; } // Wisp/page transmission result -static -int mapif_parse_WisReply(Session *tms) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_WisReply(Session *tms) { - CharId id = wrap<CharId>(RFIFOL(tms, 2)); - uint8_t flag = RFIFOB(tms, 6); + Packet_Fixed<0x3002> fixed; + RecvResult rv = recv_fpacket<0x3002, 7>(tms, fixed); + if (rv != RecvResult::Complete) + return rv; + + CharId id = fixed.char_id; + uint8_t flag = fixed.flag; const CharPair *smcs = search_character_id(id); CharName from = smcs->key.name; Session *sms = server_for(smcs); + { mapif_wis_end(sms, from, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target } - return 0; + return rv; } // Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers) -static -void mapif_parse_WisToGM(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_WisToGM(Session *s) { - size_t len = RFIFOW(s, 2); - uint8_t buf[len]; - // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B + Packet_Head<0x3003> head; + AString repeat; + RecvResult rv = recv_vpacket<0x3003, 30, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + Packet_Head<0x3803> head_03; + head_03.char_name = head.char_name; + head_03.min_gm_level = head.min_gm_level; + for (Session *ss : iter_map_sessions()) + { + send_vpacket<0x3803, 30, 1>(ss, head_03, repeat); + } - RFIFO_BUF_CLONE(s, buf, len); - WBUFW(buf, 0) = 0x3803; - mapif_sendall(buf, len); + return rv; } // アカウント変数保存要求 -static -void mapif_parse_AccReg(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_AccReg(Session *s) { - int j, p; - struct accreg *reg = accreg_db.search(RFIFOL(s, 4)); + Packet_Head<0x3004> head; + std::vector<Packet_Repeat<0x3004>> repeat; + RecvResult rv = recv_vpacket<0x3004, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + struct accreg *reg = accreg_db.search(head.account_id); if (reg == NULL) { - int account_id = RFIFOL(s, 4); + AccountId account_id = head.account_id; reg = accreg_db.init(account_id); reg->account_id = account_id; } - for (j = 0, p = 8; j < ACCOUNT_REG_NUM && p < RFIFOW(s, 2); - j++, p += 36) + size_t jlim = std::min(repeat.size(), ACCOUNT_REG_NUM); + for (size_t j = 0; j < jlim; ++j) { - reg->reg[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p)); - reg->reg[j].value = RFIFOL(s, p + 32); + reg->reg[j].str = repeat[j].name; + reg->reg[j].value = repeat[j].value; } - reg->reg_num = j; + reg->reg_num = jlim; // 他のMAPサーバーに送信 - mapif_account_reg(s); + mapif_account_reg(s, head.account_id, repeat); + + return rv; } // アカウント変数送信要求 -static -void mapif_parse_AccRegRequest(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_AccRegRequest(Session *s) { - mapif_account_reg_reply(s, RFIFOL(s, 2)); + Packet_Fixed<0x3005> fixed; + RecvResult rv = recv_fpacket<0x3005, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + mapif_account_reg_reply(s, fixed.account_id); + + return rv; } //-------------------------------------------------------- @@ -432,70 +446,41 @@ void mapif_parse_AccRegRequest(Session *s) // map server からの通信(1パケットのみ解析すること) // エラーなら0(false)、処理できたなら1、 // パケット長が足りなければ2をかえさなければならない -int inter_parse_frommap(Session *ms) +RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id) { - int cmd = RFIFOW(ms, 0); - int len = 0; - - // inter鯖管轄かを調べる - if (cmd < 0x3000 - || cmd >= - 0x3000 + - (sizeof(inter_recv_packet_length) / - sizeof(inter_recv_packet_length[0]))) - return 0; - - // パケット長を調べる - if ((len = - inter_check_length(ms, - inter_recv_packet_length[cmd - 0x3000])) == 0) - return 2; + int cmd = packet_id; + + RecvResult rv; switch (cmd) { case 0x3000: - mapif_parse_GMmessage(ms); + rv = mapif_parse_GMmessage(ms); break; case 0x3001: - mapif_parse_WisRequest(ms); + rv = mapif_parse_WisRequest(ms); break; case 0x3002: - mapif_parse_WisReply(ms); + rv = mapif_parse_WisReply(ms); break; case 0x3003: - mapif_parse_WisToGM(ms); + rv = mapif_parse_WisToGM(ms); break; case 0x3004: - mapif_parse_AccReg(ms); + rv = mapif_parse_AccReg(ms); break; case 0x3005: - mapif_parse_AccRegRequest(ms); + rv = mapif_parse_AccRegRequest(ms); break; default: - if (inter_party_parse_frommap(ms)) - break; - if (inter_storage_parse_frommap(ms)) - break; - return 0; + rv = inter_party_parse_frommap(ms, packet_id); + if (rv != RecvResult::Error) + return rv; + rv = inter_storage_parse_frommap(ms, packet_id); + if (rv != RecvResult::Error) + return rv; + return RecvResult::Error; } - RFIFOSKIP(ms, len); - - return 1; -} - -// RFIFOのパケット長確認 -// 必要パケット長があればパケット長、まだ足りなければ0 -int inter_check_length(Session *s, int length) -{ - if (length == -1) - { // 可変パケット長 - if (RFIFOREST(s) < 4) // パケット長が未着 - return 0; - length = RFIFOW(s, 2); - } - - if (RFIFOREST(s) < length) // パケットが未着 - return 0; - return length; + return rv; } diff --git a/src/char/inter.hpp b/src/char/inter.hpp index bb3c9da..9269017 100644 --- a/src/char/inter.hpp +++ b/src/char/inter.hpp @@ -30,9 +30,7 @@ bool inter_config(XString key, ZString value); void inter_init2(); void inter_save(void); -int inter_parse_frommap(Session *ms); - -int inter_check_length(Session *ms, int length); +RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id); extern int party_share_level; diff --git a/src/login/login.cpp b/src/login/login.cpp index 98f0c1e..8d893f9 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -1372,7 +1372,7 @@ void parse_fromchar(Session *s) else timestamp = ad.ban_until_time; struct tm tmtime = timestamp; - HumanTimeDiff ban_diff = fixed.deltas; + HumanTimeDiff ban_diff = fixed.ban_add; tmtime.tm_year += ban_diff.year; tmtime.tm_mon += ban_diff.month; tmtime.tm_mday += ban_diff.day; diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index bc026be..a6c89e5 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -808,7 +808,7 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - struct party *p; + PartyPair p; VString<23> match_text = message; match_text = match_text.to_lower(); @@ -925,7 +925,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - struct party *p; + PartyPair p; map_local *map_id; { @@ -990,7 +990,7 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - struct party *p; + PartyPair p; VString<23> match_text = message; match_text = match_text.to_lower(); @@ -1144,7 +1144,7 @@ static ATCE atcommand_storage(Session *s, dumb_ptr<map_session_data> sd, ZString) { - struct storage *stor; + Storage *stor; if (sd->state.storage_open) { @@ -3393,7 +3393,7 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, ZString message) { PartyName party_name; - struct party *p; + PartyPair p; int count; if (!extract(message, &party_name) || !party_name) @@ -3407,9 +3407,9 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, return ATCE::PERM; } - if ((p = party_searchname(party_name)) != NULL || + if ((p = party_searchname(party_name)) || // name first to avoid error when name begin with a number - (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str()))))) != NULL) + (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))))) { count = 0; for (io::FD i : iter_fds()) @@ -3420,7 +3420,7 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth && sd->status_key.account_id != pl_sd->status_key.account_id - && pl_sd->status.party_id == p->party_id) + && pl_sd->status.party_id == p.party_id) { if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP) && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) @@ -3589,12 +3589,12 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd, if (!extract(message, &party_name)) return ATCE::USAGE; - struct party *p; - if ((p = party_searchname(party_name)) != NULL || + PartyPair p; + if ((p = party_searchname(party_name)) || // name first to avoid error when name begin with a number - (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str()))))) != NULL) + (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))))) { - if (sd->partyspy == p->party_id) + if (sd->partyspy == p.party_id) { sd->partyspy = PartyId(); AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); @@ -3602,7 +3602,7 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd, } else { - sd->partyspy = p->party_id; + sd->partyspy = p.party_id; AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); clif_displaymessage(s, output); } @@ -3963,7 +3963,7 @@ static ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd, ZString message) { - struct storage *stor; + Storage *stor; struct item_data *item_data = NULL; int i, count, counter; CharName character; diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index 9e69521..a6c11b9 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -268,6 +268,7 @@ int chrif_changemapserverack(Session *s) if (sd == NULL || sd->status_key.char_id != wrap<CharId>(RFIFOL(s, 14))) return -1; + // I am fairly certain that this is not possible if (RFIFOL(s, 6) == 1) { if (battle_config.error_log) @@ -956,7 +957,7 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameI case BL::PC: { dumb_ptr<map_session_data> pc = bl->is_player(); - struct storage *stor = account2storage2(pc->status_key.account_id); + Storage *stor = account2storage2(pc->status_key.account_id); int j; for (j = 0; j < MAX_INVENTORY; j++) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 10aeb0c..218c00b 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -322,7 +322,7 @@ void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len, static int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type) { - struct party *p = NULL; + PartyPair p; int x0 = 0, x1 = 0, y0 = 0, y1 = 0; if (type != SendWho::ALL_CLIENT) @@ -463,7 +463,7 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())); if (sd && sd->state.auth) { - if (sd->partyspy == p->party_id) + if (sd->partyspy == p.party_id) { if (clif_parse_func_table[RBUFW(buf, 0)].len) { @@ -1526,7 +1526,7 @@ void clif_equiplist(dumb_ptr<map_session_data> sd) * カプラさんに預けてある消耗品&収集品リスト *------------------------------------------ */ -int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor) +int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor) { nullpo_ret(sd); nullpo_ret(stor); @@ -1569,7 +1569,7 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor) * カプラさんに預けてある装備リスト *------------------------------------------ */ -int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor) +int clif_storageequiplist(dumb_ptr<map_session_data> sd, Storage *stor) { nullpo_ret(sd); nullpo_ret(stor); @@ -2235,7 +2235,7 @@ int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail) *------------------------------------------ */ int clif_updatestorageamount(dumb_ptr<map_session_data> sd, - struct storage *stor) + Storage *stor) { nullpo_ret(sd); nullpo_ret(stor); @@ -2253,7 +2253,7 @@ int clif_updatestorageamount(dumb_ptr<map_session_data> sd, * カプラ倉庫にアイテムを追加する *------------------------------------------ */ -int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor, +int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor, int index, int amount) { nullpo_ret(sd); @@ -2969,7 +2969,7 @@ int clif_party_created(dumb_ptr<map_session_data> sd, int flag) * パーティ情報送信 *------------------------------------------ */ -int clif_party_info(struct party *p, Session *s) +int clif_party_info(PartyPair p, Session *s) { unsigned char buf[1024]; int i, c; @@ -3019,7 +3019,7 @@ int clif_party_info(struct party *p, Session *s) void clif_party_invite(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd) { - struct party *p; + PartyPair p; nullpo_retv(sd); nullpo_retv(tsd); @@ -3067,7 +3067,7 @@ void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag * 0x100=一人にのみ送信 *------------------------------------------ */ -void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag) +void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag) { unsigned char buf[16]; @@ -3098,7 +3098,7 @@ void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag) * パーティ脱退(脱退前に呼ぶこと) *------------------------------------------ */ -void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, +void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd, AccountId account_id, CharName name, int flag) { unsigned char buf[64]; @@ -3134,7 +3134,7 @@ void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, * パーティメッセージ送信 *------------------------------------------ */ -void clif_party_message(struct party *p, AccountId account_id, XString mes) +void clif_party_message(PartyPair p, AccountId account_id, XString mes) { // always set, but clang is not smart enough dumb_ptr<map_session_data> sd = nullptr; @@ -3164,7 +3164,7 @@ void clif_party_message(struct party *p, AccountId account_id, XString mes) * パーティ座標通知 *------------------------------------------ */ -int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd) +int clif_party_xy(PartyPair , dumb_ptr<map_session_data> sd) { unsigned char buf[16]; @@ -3182,7 +3182,7 @@ int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd) * パーティHP通知 *------------------------------------------ */ -int clif_party_hp(struct party *, dumb_ptr<map_session_data> sd) +int clif_party_hp(PartyPair , dumb_ptr<map_session_data> sd) { unsigned char buf[16]; @@ -3625,13 +3625,13 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) WFIFO_STRING(s, 6, ssd->status_key.name.to__actual(), 24); WFIFOSET(s, clif_parse_func_table[0x95].len); - struct party *p = NULL; + PartyPair p; PartyName party_name; int send = 0; - if (ssd->status.party_id && (p = party_search(ssd->status.party_id)) != NULL) + if (ssd->status.party_id && (p = party_search(ssd->status.party_id))) { party_name = p->name; send = 1; diff --git a/src/map/clif.hpp b/src/map/clif.hpp index b2a5747..3bed955 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -117,12 +117,12 @@ int clif_tradecancelled(dumb_ptr<map_session_data> sd); int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail); // storage -int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor); +int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor); int clif_storageequiplist(dumb_ptr<map_session_data> sd, - struct storage *stor); + Storage *stor); int clif_updatestorageamount(dumb_ptr<map_session_data> sd, - struct storage *stor); -int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor, + Storage *stor); +int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor, int index, int amount); int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index, int amount); @@ -161,17 +161,17 @@ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl); // party int clif_party_created(dumb_ptr<map_session_data> sd, int flag); -int clif_party_info(struct party *p, Session *s); +int clif_party_info(PartyPair p, Session *s); void clif_party_invite(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd); void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag); -void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, +void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag); -void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, +void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd, AccountId account_id, CharName name, int flag); -void clif_party_message(struct party *p, AccountId account_id, XString mes); -int clif_party_xy(struct party *p, dumb_ptr<map_session_data> sd); -int clif_party_hp(struct party *p, dumb_ptr<map_session_data> sd); +void clif_party_message(PartyPair p, AccountId account_id, XString mes); +int clif_party_xy(PartyPair p, dumb_ptr<map_session_data> sd); +int clif_party_hp(PartyPair p, dumb_ptr<map_session_data> sd); // atcommand void clif_displaymessage(Session *s, XString mes); diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 5d8bfd6..bb4b893 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -157,11 +157,11 @@ void intif_request_storage(AccountId account_id) } // 倉庫データ送信 -void intif_send_storage(struct storage *stor) +void intif_send_storage(Storage *stor) { nullpo_retv(stor); WFIFOW(char_session, 0) = 0x3011; - WFIFOW(char_session, 2) = sizeof(struct storage) + 8; + WFIFOW(char_session, 2) = sizeof(Storage) + 8; WFIFOL(char_session, 4) = unwrap<AccountId>(stor->account_id); WFIFO_STRUCT(char_session, 8, *stor); WFIFOSET(char_session, WFIFOW(char_session, 2)); @@ -373,7 +373,7 @@ int intif_parse_AccountReg(Session *s) static int intif_parse_LoadStorage(Session *s) { - struct storage *stor; + Storage *stor; dumb_ptr<map_session_data> sd; sd = map_id2sd(account_to_block(wrap<AccountId>(RFIFOL(s, 4)))); @@ -400,11 +400,11 @@ int intif_parse_LoadStorage(Session *s) return 1; } - if (RFIFOW(s, 2) - 8 != sizeof(struct storage)) + if (RFIFOW(s, 2) - 8 != sizeof(Storage)) { if (battle_config.error_log) PRINTF("intif_parse_LoadStorage: data size error %d %zu\n"_fmt, - RFIFOW(s, 2) - 8, sizeof(struct storage)); + RFIFOW(s, 2) - 8, sizeof(Storage)); return 1; } if (battle_config.save_log) @@ -455,16 +455,21 @@ void intif_parse_PartyInfo(Session *s) return; } - if (RFIFOW(s, 2) != sizeof(struct party) + 4) + if (RFIFOW(s, 2) != sizeof(PartyMost) + 8) { if (battle_config.error_log) PRINTF("intif: party info : data size error %d %d %zu\n"_fmt, RFIFOL(s, 4), RFIFOW(s, 2), - sizeof(struct party) + 4); + sizeof(PartyMost) + 8); } - party p {}; - RFIFO_STRUCT(s, 4, p); - party_recv_info(&p); + PartyId pi; + PartyMost pm; + RFIFO_STRUCT(s, 4, pi); + RFIFO_STRUCT(s, 8, pm); + PartyPair pp; + pp.party_id = pi; + pp.party_most = ± + party_recv_info(pp); } // パーティ追加通知 diff --git a/src/map/intif.hpp b/src/map/intif.hpp index c60e3c1..2e3d3fe 100644 --- a/src/map/intif.hpp +++ b/src/map/intif.hpp @@ -42,7 +42,7 @@ void intif_saveaccountreg(dumb_ptr<map_session_data> sd); void intif_request_accountreg(dumb_ptr<map_session_data> sd); void intif_request_storage(AccountId account_id); -void intif_send_storage(struct storage *stor); +void intif_send_storage(Storage *stor); void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name); void intif_request_partyinfo(PartyId party_id); diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 2dd7ea4..74e00be 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -2491,7 +2491,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, { struct DmgLogParty { - struct party *p; + PartyPair p; int base_exp, job_exp; }; std::vector<DmgLogParty> ptv; @@ -2532,7 +2532,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, int base_exp, job_exp, flag = 1; double per; - struct party *p; + PartyPair p; // [Fate] The above is the old formula. We do a more involved computation below. // [o11c] Look in git history for old code, you idiot! @@ -2578,13 +2578,13 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, std::vector<DmgLogParty>::iterator it = std::find_if(ptv.begin(), ptv.end(), [pid](const DmgLogParty& dlp) { - return dlp.p->party_id == pid; + return dlp.p.party_id == pid; } ); if (it == ptv.end()) { p = party_search(pid); - if (p != NULL && p->exp != 0) + if (p && p->exp != 0) { DmgLogParty pn {}; pn.p = p; diff --git a/src/map/party.cpp b/src/map/party.cpp index f40b991..5f69de5 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -46,7 +46,7 @@ constexpr interval_t PARTY_SEND_XYHP_INVERVAL = std::chrono::seconds(1); static -Map<PartyId, struct party> party_db; +Map<PartyId, PartyMost> party_db; static void party_check_conflict(dumb_ptr<map_session_data> sd); @@ -63,24 +63,33 @@ void do_init_party(void) } // 検索 -struct party *party_search(PartyId party_id) +PartyPair party_search(PartyId party_id) { - return party_db.search(party_id); + PartyPair p; + p.party_most = party_db.search(party_id); + if (p) + p.party_id = party_id; + return p; } static -void party_searchname_sub(struct party *p, PartyName str, struct party **dst) +void party_searchname_sub(PartyPair p, PartyName str, PartyPair *dst) { if (p->name == str) *dst = p; } // パーティ名検索 -struct party *party_searchname(PartyName str) +PartyPair party_searchname(PartyName str) { - struct party *p = NULL; + PartyPair p; for (auto& pair : party_db) - party_searchname_sub(&pair.second, str, &p); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + party_searchname_sub(tmp, str, &p); + } return p; } @@ -117,15 +126,15 @@ void party_created(AccountId account_id, int fail, PartyId party_id, PartyName n { sd->status.party_id = party_id; - struct party *p = party_db.search(party_id); - if (p != NULL) + PartyPair p = party_search(party_id); + if (p) { PRINTF("party_created(): ID already exists!\n"_fmt); exit(1); } - p = party_db.init(party_id); - p->party_id = party_id; + p.party_most = party_db.init(party_id); + p.party_id = party_id; p->name = name; /* The party was created successfully. */ @@ -144,7 +153,7 @@ void party_request_info(PartyId party_id) // 所属キャラの確認 static -int party_check_member(struct party *p) +int party_check_member(PartyPair p) { nullpo_ret(p); @@ -156,7 +165,7 @@ int party_check_member(struct party *p) map_session_data *sd = static_cast<map_session_data *>(s->session_data.get()); if (sd && sd->state.auth) { - if (sd->status.party_id == p->party_id) + if (sd->status.party_id == p.party_id) { int j, f = 1; for (j = 0; j < MAX_PARTY; j++) @@ -204,29 +213,29 @@ int party_recv_noinfo(PartyId party_id) } // 情報所得 -int party_recv_info(const struct party *sp) +int party_recv_info(const PartyPair sp) { int i; nullpo_ret(sp); - struct party *p = party_db.search(sp->party_id); - if (p == NULL) + PartyPair p = party_search(sp.party_id); + if (!p) { - p = party_db.init(sp->party_id); + p.party_most = party_db.init(sp.party_id); // 最初のロードなのでユーザーのチェックを行う - *p = *sp; + *p.party_most = *sp.party_most; party_check_member(p); } else - *p = *sp; + *p.party_most = *sp.party_most; for (i = 0; i < MAX_PARTY; i++) { // sdの設定 dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id)); p->member[i].sd = (sd != NULL - && sd->status.party_id == p->party_id) ? sd.operator->() : NULL; + && sd->status.party_id == p.party_id) ? sd.operator->() : NULL; } clif_party_info(p, nullptr); @@ -249,7 +258,7 @@ int party_recv_info(const struct party *sp) int party_invite(dumb_ptr<map_session_data> sd, AccountId account_id) { dumb_ptr<map_session_data> tsd = map_id2sd(account_to_block(account_id)); - struct party *p = party_search(sd->status.party_id); + PartyPair p = party_search(sd->status.party_id); int i; int full = 1; /* Indicates whether or not there's room for one more. */ @@ -347,7 +356,7 @@ int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id, int int party_member_added(PartyId party_id, AccountId account_id, int flag) { dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)), sd2; - struct party *p = party_search(party_id); + PartyPair p = party_search(party_id); if (sd == NULL) { @@ -364,7 +373,7 @@ int party_member_added(PartyId party_id, AccountId account_id, int flag) sd->party_invite = PartyId(); sd->party_invite_account = AccountId(); - if (p == NULL) + if (!p) { PRINTF("party_member_added: party %d not found.\n"_fmt, party_id); intif_party_leave(party_id, account_id); @@ -396,26 +405,28 @@ int party_member_added(PartyId party_id, AccountId account_id, int flag) // パーティ除名要求 int party_removemember(dumb_ptr<map_session_data> sd, AccountId account_id) { - struct party *p; + PartyPair p; int i; nullpo_ret(sd); - if ((p = party_search(sd->status.party_id)) == NULL) + if (!(p = party_search(sd->status.party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) { // リーダーかどうかチェック if (p->member[i].account_id == sd->status_key.account_id) + { if (p->member[i].leader == 0) return 0; + } } for (i = 0; i < MAX_PARTY; i++) { // 所属しているか調べる if (p->member[i].account_id == account_id) { - intif_party_leave(p->party_id, account_id); + intif_party_leave(p.party_id, account_id); return 0; } } @@ -425,19 +436,19 @@ int party_removemember(dumb_ptr<map_session_data> sd, AccountId account_id) // パーティ脱退要求 int party_leave(dumb_ptr<map_session_data> sd) { - struct party *p; + PartyPair p; int i; nullpo_ret(sd); - if ((p = party_search(sd->status.party_id)) == NULL) + if (!(p = party_search(sd->status.party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) { // 所属しているか if (p->member[i].account_id == sd->status_key.account_id) { - intif_party_leave(p->party_id, sd->status_key.account_id); + intif_party_leave(p.party_id, sd->status_key.account_id); return 0; } } @@ -448,8 +459,8 @@ int party_leave(dumb_ptr<map_session_data> sd) int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) { dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)); - struct party *p = party_search(party_id); - if (p != NULL) + PartyPair p = party_search(party_id); + if (p) { int i; for (i = 0; i < MAX_PARTY; i++) @@ -471,9 +482,9 @@ int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) // パーティ解散通知 int party_broken(PartyId party_id) { - struct party *p; + PartyPair p; int i; - if ((p = party_search(party_id)) == NULL) + if (!(p = party_search(party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) @@ -494,12 +505,12 @@ int party_broken(PartyId party_id) // パーティの設定変更要求 int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item) { - struct party *p; + PartyPair p; nullpo_ret(sd); if (!sd->status.party_id - || (p = party_search(sd->status.party_id)) == NULL) + || !(p = party_search(sd->status.party_id))) return 0; intif_party_changeoption(sd->status.party_id, sd->status_key.account_id, exp, item); @@ -510,9 +521,9 @@ int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item) int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int item, int flag) { - struct party *p; + PartyPair p; dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)); - if ((p = party_search(party_id)) == NULL) + if (!(p = party_search(party_id))) return 0; if (!(flag & 0x01)) @@ -527,9 +538,9 @@ int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int ite void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname, int online, int lv) { - struct party *p; + PartyPair p; int i; - if ((p = party_search(party_id)) == NULL) + if (!(p = party_search(party_id))) return; for (i = 0; i < MAX_PARTY; i++) { @@ -559,7 +570,7 @@ void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname, { // sd再設定 dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id)); p->member[i].sd = (sd != NULL - && sd->status.party_id == p->party_id) ? sd.operator->() : NULL; + && sd->status.party_id == p.party_id) ? sd.operator->() : NULL; } party_send_xy_clear(p); // 座標再通知要請 @@ -570,7 +581,7 @@ void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname, // パーティメンバの移動 int party_send_movemap(dumb_ptr<map_session_data> sd) { - struct party *p; + PartyPair p; nullpo_ret(sd); @@ -585,10 +596,10 @@ int party_send_movemap(dumb_ptr<map_session_data> sd) party_check_conflict(sd); // あるならパーティ情報送信 - if ((p = party_search(sd->status.party_id)) != NULL) + if ((p = party_search(sd->status.party_id))) { party_check_member(p); // 所属を確認する - if (sd->status.party_id == p->party_id) + if (sd->status.party_id == p.party_id) { clif_party_info(p, sd->sess); clif_party_option(p, sd, 0x100); @@ -602,7 +613,7 @@ int party_send_movemap(dumb_ptr<map_session_data> sd) // パーティメンバのログアウト int party_send_logout(dumb_ptr<map_session_data> sd) { - struct party *p; + PartyPair p; nullpo_ret(sd); @@ -610,7 +621,7 @@ int party_send_logout(dumb_ptr<map_session_data> sd) intif_party_changemap(sd, 0); // sdが無効になるのでパーティ情報から削除 - if ((p = party_search(sd->status.party_id)) != NULL) + if ((p = party_search(sd->status.party_id))) { int i; for (i = 0; i < MAX_PARTY; i++) @@ -632,8 +643,8 @@ void party_send_message(dumb_ptr<map_session_data> sd, XString mes) // パーティメッセージ受信 void party_recv_message(PartyId party_id, AccountId account_id, XString mes) { - struct party *p; - if ((p = party_search(party_id)) == NULL) + PartyPair p; + if (!(p = party_search(party_id))) return; clif_party_message(p, account_id, mes); } @@ -649,7 +660,7 @@ void party_check_conflict(dumb_ptr<map_session_data> sd) // 位置やHP通知用 static -void party_send_xyhp_timer_sub(struct party *p) +void party_send_xyhp_timer_sub(PartyPair p) { int i; @@ -682,11 +693,16 @@ void party_send_xyhp_timer_sub(struct party *p) void party_send_xyhp_timer(TimerData *, tick_t) { for (auto& pair : party_db) - party_send_xyhp_timer_sub(&pair.second); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + party_send_xyhp_timer_sub(tmp); + } } // 位置通知クリア -void party_send_xy_clear(struct party *p) +void party_send_xy_clear(PartyPair p) { int i; @@ -720,7 +736,7 @@ void party_send_hp_check(dumb_ptr<block_list> bl, PartyId party_id, int *flag) } // 経験値公平分配 -int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp) +int party_exp_share(PartyPair p, map_local *mapid, int base_exp, int job_exp) { dumb_ptr<map_session_data> sd; int i, c; @@ -751,7 +767,7 @@ int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, dumb_ptr<map_session_data> sd, int type) { - struct party *p; + PartyPair p; int i; int x0, y0, x1, y1; dumb_ptr<map_session_data> list[MAX_PARTY]; @@ -759,7 +775,7 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, nullpo_retv(sd); - if ((p = party_search(sd->status.party_id)) == NULL) + if (!(p = party_search(sd->status.party_id))) return; x0 = sd->bl_x - AREA_SIZE; diff --git a/src/map/party.hpp b/src/map/party.hpp index 4670aee..d4000f7 100644 --- a/src/map/party.hpp +++ b/src/map/party.hpp @@ -32,8 +32,8 @@ # include "../mmo/fwd.hpp" void do_init_party(void); -struct party *party_search(PartyId party_id); -struct party *party_searchname(PartyName str); +PartyPair party_search(PartyId party_id); +PartyPair party_searchname(PartyName str); int party_create(dumb_ptr<map_session_data> sd, PartyName name); void party_created(AccountId account_id, int fail, PartyId party_id, PartyName name); @@ -46,7 +46,7 @@ int party_member_leaved(PartyId party_id, AccountId account_id, CharName name); int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id, int flag); int party_recv_noinfo(PartyId party_id); -int party_recv_info(const struct party *sp); +int party_recv_info(const PartyPair sp); void party_recv_movemap(PartyId party_id, AccountId account_id, MapName map, int online, int lv); int party_broken(PartyId party_id); @@ -60,10 +60,10 @@ int party_send_logout(dumb_ptr<map_session_data> sd); void party_send_message(dumb_ptr<map_session_data> sd, XString mes); void party_recv_message(PartyId party_id, AccountId account_id, XString mes); -void party_send_xy_clear(struct party *p); +void party_send_xy_clear(PartyPair p); void party_send_hp_check(dumb_ptr<block_list> bl, PartyId party_id, int *flag); -int party_exp_share(struct party *p, map_local *map, int base_exp, int job_exp); +int party_exp_share(PartyPair p, map_local *map, int base_exp, int job_exp); void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, dumb_ptr<map_session_data> sd, int type); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 8aeebdf..ac8af28 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -648,7 +648,7 @@ int pc_authok(AccountId id, int login_id2, TimeT connect_until_time, { dumb_ptr<map_session_data> sd = NULL; - struct party *p; + PartyPair p; tick_t tick = gettick(); sd = map_id2sd(account_to_block(id)); @@ -754,7 +754,7 @@ int pc_authok(AccountId id, int login_id2, TimeT connect_until_time, // パーティ、ギルドデータの要求 if (sd->status.party_id - && (p = party_search(sd->status.party_id)) == NULL) + && !(p = party_search(sd->status.party_id))) party_request_info(sd->status.party_id); // pvpの設定 @@ -2096,7 +2096,7 @@ int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount) static int can_pick_item_up_from(dumb_ptr<map_session_data> self, BlockId other_id) { - struct party *p = party_search(self->status.party_id); + PartyPair p = party_search(self->status.party_id); /* From ourselves or from no-one? */ if (!self || self->bl_id == other_id || !other_id) @@ -2503,8 +2503,8 @@ void pc_walk(TimerData *, tick_t tick, BlockId id, unsigned char data) if (sd->status.party_id) { // パーティのHP情報通知検査 - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) { int p_flag = 0; map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &p_flag), @@ -2677,8 +2677,8 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y) if (sd->status.party_id) { // パーティのHP情報通知検査 - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) { int flag = 0; map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &flag), @@ -3432,8 +3432,8 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) clif_party_hp(p, sd); } // end addition [Valaris] @@ -3799,8 +3799,8 @@ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp) if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) clif_party_hp(p, sd); } // end addition [Valaris] @@ -4244,7 +4244,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, VarName reg, int val) return 0; } if (battle_config.error_log) - PRINTF("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %d)\n"_fmt, + PRINTF("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %zu)\n"_fmt, reg, ACCOUNT_REG_NUM); return 1; diff --git a/src/map/script.cpp b/src/map/script.cpp index 499e155..6cac082 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -2224,7 +2224,7 @@ void builtin_getcharid(ScriptState *st) static dumb_string builtin_getpartyname_sub(PartyId party_id) { - struct party *p = party_search(party_id); + PartyPair p = party_search(party_id); if (p) return dumb_string::copys(p->name); diff --git a/src/map/storage.cpp b/src/map/storage.cpp index b88c1ea..f8dbd0f 100644 --- a/src/map/storage.cpp +++ b/src/map/storage.cpp @@ -37,16 +37,16 @@ #include "../poison.hpp" static -Map<AccountId, struct storage> storage_db; +Map<AccountId, Storage> storage_db; void do_final_storage(void) { storage_db.clear(); } -struct storage *account2storage(AccountId account_id) +Storage *account2storage(AccountId account_id) { - struct storage *stor = storage_db.search(account_id); + Storage *stor = storage_db.search(account_id); if (stor == NULL) { stor = storage_db.init(account_id); @@ -56,7 +56,7 @@ struct storage *account2storage(AccountId account_id) } // Just to ask storage, without creation -struct storage *account2storage2(AccountId account_id) +Storage *account2storage2(AccountId account_id) { return storage_db.search(account_id); } @@ -78,7 +78,7 @@ int storage_storageopen(dumb_ptr<map_session_data> sd) if (sd->state.storage_open) return 1; //Already open? - struct storage *stor = storage_db.search(sd->status_key.account_id); + Storage *stor = storage_db.search(sd->status_key.account_id); if (stor == NULL) { //Request storage. intif_request_storage(sd->status_key.account_id); @@ -101,7 +101,7 @@ int storage_storageopen(dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor, +int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor, struct item *item_data, int amount) { struct item_data *data; @@ -147,7 +147,7 @@ int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor, *------------------------------------------ */ static -int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor, +int storage_delitem(dumb_ptr<map_session_data> sd, Storage *stor, int n, int amount) { @@ -173,7 +173,7 @@ int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor, */ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount) { - struct storage *stor; + Storage *stor; nullpo_ret(sd); stor = account2storage2(sd->status_key.account_id); @@ -208,7 +208,7 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount) */ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount) { - struct storage *stor; + Storage *stor; PickupFail flag; nullpo_ret(sd); @@ -238,7 +238,7 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount) */ int storage_storageclose(dumb_ptr<map_session_data> sd) { - struct storage *stor; + Storage *stor; nullpo_ret(sd); stor = account2storage2(sd->status_key.account_id); @@ -270,7 +270,7 @@ int storage_storageclose(dumb_ptr<map_session_data> sd) */ int storage_storage_quit(dumb_ptr<map_session_data> sd) { - struct storage *stor; + Storage *stor; nullpo_ret(sd); @@ -287,7 +287,7 @@ int storage_storage_quit(dumb_ptr<map_session_data> sd) int storage_storage_save(AccountId account_id, int final) { - struct storage *stor; + Storage *stor; stor = account2storage2(account_id); if (!stor) @@ -315,7 +315,7 @@ int storage_storage_save(AccountId account_id, int final) //Ack from Char-server indicating the storage was saved. [Skotlex] int storage_storage_saved(AccountId account_id) { - struct storage *stor = account2storage2(account_id); + Storage *stor = account2storage2(account_id); if (stor) { diff --git a/src/map/storage.hpp b/src/map/storage.hpp index 4de931f..3eab087 100644 --- a/src/map/storage.hpp +++ b/src/map/storage.hpp @@ -32,8 +32,8 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount); int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount); int storage_storageclose(dumb_ptr<map_session_data> sd); void do_final_storage(void); -struct storage *account2storage(AccountId account_id); -struct storage *account2storage2(AccountId account_id); +Storage *account2storage(AccountId account_id); +Storage *account2storage2(AccountId account_id); int storage_storage_quit(dumb_ptr<map_session_data> sd); int storage_storage_save(AccountId account_id, int final); int storage_storage_saved(AccountId account_id); diff --git a/src/mmo/fwd.hpp b/src/mmo/fwd.hpp index eb8bc05..3217fc1 100644 --- a/src/mmo/fwd.hpp +++ b/src/mmo/fwd.hpp @@ -45,4 +45,21 @@ class VarName; class MapName; class CharName; +# if 0 +class item; +class point; +class skill_value; +class global_reg; +class CharKey; +class CharData; +class CharPair; +# endif +class Storage; +# if 0 +class GM_Account; +class party_member; +# endif +class PartyMost; +class PartyPair; + #endif // TMWA_MMO_FWD_HPP diff --git a/src/mmo/ids.hpp b/src/mmo/ids.hpp index ed5ab58..bfd7de9 100644 --- a/src/mmo/ids.hpp +++ b/src/mmo/ids.hpp @@ -115,6 +115,22 @@ public: return true; // LIES. But this code is going away soon anyway } + // TODO kill this code too + friend + bool native_to_network(Little16 *network, GmLevel native) + { + uint16_t tmp = native.bits; + return native_to_network(network, tmp); + } + friend + bool network_to_native(GmLevel *native, Little16 network) + { + uint16_t tmp; + bool rv = network_to_native(&tmp, network); + native->bits = tmp; + return rv; + } + friend bool native_to_network(Little32 *network, GmLevel native) { diff --git a/src/mmo/mmo.hpp b/src/mmo/mmo.hpp index d96e619..89aef6d 100644 --- a/src/mmo/mmo.hpp +++ b/src/mmo/mmo.hpp @@ -44,7 +44,7 @@ constexpr int MAX_ZENY = 1000000000; // 1G zeny constexpr int TRADE_MAX = 10; constexpr int GLOBAL_REG_NUM = 96; -constexpr int ACCOUNT_REG_NUM = 16; +constexpr size_t ACCOUNT_REG_NUM = 16; constexpr size_t ACCOUNT_REG2_NUM = 16; constexpr interval_t DEFAULT_WALK_SPEED = std::chrono::milliseconds(150); constexpr interval_t MIN_WALK_SPEED = interval_t::zero(); @@ -147,7 +147,7 @@ struct CharPair {} }; -struct storage +struct Storage { bool dirty; AccountId account_id; @@ -171,13 +171,23 @@ struct party_member struct map_session_data *sd; }; -struct party +struct PartyMost { - PartyId party_id; PartyName name; int exp; int item; Array<struct party_member, MAX_PARTY> member; }; +struct PartyPair +{ + PartyId party_id = {}; + PartyMost *party_most = {}; + + explicit + operator bool() const { return party_most; } + bool operator !() const { return !party_most; } + PartyMost *operator->() const { return party_most; } +}; + #endif // TMWA_MMO_MMO_HPP diff --git a/src/net/fwd.hpp b/src/net/fwd.hpp index ca54e8d..109aeed 100644 --- a/src/net/fwd.hpp +++ b/src/net/fwd.hpp @@ -27,4 +27,6 @@ class IP4Address; class TimerData; +enum class RecvResult; + #endif // TMWA_NET_FWD_HPP diff --git a/src/net/packets.hpp b/src/net/packets.hpp index 6146b90..293aed8 100644 --- a/src/net/packets.hpp +++ b/src/net/packets.hpp @@ -79,6 +79,14 @@ SendResult net_send_fpacket(Session *s, const NetPacket_Fixed<id>& fixed) template<uint16_t id> __attribute__((warn_unused_result)) +SendResult net_send_ppacket(Session *s, const NetPacket_Payload<id>& payload) +{ + bool ok = packet_send(s, reinterpret_cast<const Byte *>(&payload), sizeof(NetPacket_Payload<id>)); + return ok ? SendResult::Success : SendResult::Fail; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) SendResult net_send_vpacket(Session *s, const NetPacket_Head<id>& head, const std::vector<NetPacket_Repeat<id>>& repeat) { bool ok = packet_send(s, reinterpret_cast<const Byte *>(&head), sizeof(NetPacket_Head<id>)); @@ -88,6 +96,18 @@ SendResult net_send_vpacket(Session *s, const NetPacket_Head<id>& head, const st template<uint16_t id> __attribute__((warn_unused_result)) +SendResult net_send_opacket(Session *s, const NetPacket_Head<id>& head, bool has_opt, const NetPacket_Option<id>& opt) +{ + bool ok = packet_send(s, reinterpret_cast<const Byte *>(&head), sizeof(NetPacket_Head<id>)); + if (has_opt) + { + ok &= packet_send(s, reinterpret_cast<const Byte *>(&opt), sizeof(NetPacket_Option<id>)); + } + return ok ? SendResult::Success : SendResult::Fail; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed<id>& fixed) { bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&fixed), sizeof(NetPacket_Fixed<id>)); @@ -101,6 +121,19 @@ RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed<id>& fixed) template<uint16_t id> __attribute__((warn_unused_result)) +RecvResult net_recv_ppacket(Session *s, NetPacket_Payload<id>& payload) +{ + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&payload), sizeof(NetPacket_Payload<id>)); + if (ok) + { + packet_discard(s, sizeof(NetPacket_Payload<id>)); + return RecvResult::Complete; + } + return RecvResult::Incomplete; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) RecvResult net_recv_vpacket(Session *s, NetPacket_Head<id>& head, std::vector<NetPacket_Repeat<id>>& repeat) { bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>)); @@ -127,6 +160,37 @@ RecvResult net_recv_vpacket(Session *s, NetPacket_Head<id>& head, std::vector<Ne return RecvResult::Incomplete; } +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult net_recv_opacket(Session *s, NetPacket_Head<id>& head, bool *has_opt, NetPacket_Option<id>& opt) +{ + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>)); + if (ok) + { + Packet_Head<id> nat; + if (!network_to_native(&nat, head)) + return RecvResult::Error; + if (packet_avail(s) < nat.magic_packet_length) + return RecvResult::Incomplete; + if (nat.magic_packet_length < sizeof(NetPacket_Head<id>)) + return RecvResult::Error; + size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head<id>); + if (bytes_repeat % sizeof(NetPacket_Repeat<id>)) + return RecvResult::Error; + size_t has_opt_pls = bytes_repeat / sizeof(NetPacket_Option<id>); + if (has_opt_pls > 1) + return RecvResult::Error; + *has_opt = has_opt_pls; + if (!*has_opt || packet_fetch(s, sizeof(NetPacket_Head<id>), reinterpret_cast<Byte *>(&opt), sizeof(NetPacket_Option<id>))) + { + packet_discard(s, nat.magic_packet_length); + return RecvResult::Complete; + } + return RecvResult::Incomplete; + } + return RecvResult::Incomplete; +} + template<uint16_t id, uint16_t size> void send_fpacket(Session *s, const Packet_Fixed<id>& fixed) @@ -145,6 +209,23 @@ void send_fpacket(Session *s, const Packet_Fixed<id>& fixed) s->set_eof(); } +template<uint16_t id> +void send_ppacket(Session *s, Packet_Payload<id>& payload) +{ + static_assert(id == Packet_Payload<id>::PACKET_ID, "Packet_Payload<id>::PACKET_ID"); + + NetPacket_Payload<id> net_payload; + payload.magic_packet_length = sizeof(NetPacket_Payload<id>); + if (!native_to_network(&net_payload, payload)) + { + s->set_eof(); + return; + } + SendResult rv = net_send_ppacket(s, net_payload); + if (rv != SendResult::Success) + s->set_eof(); +} + template<uint16_t id, uint16_t headsize, uint16_t repeatsize> void send_vpacket(Session *s, Packet_Head<id>& head, const std::vector<Packet_Repeat<id>>& repeat) { @@ -183,6 +264,43 @@ void send_vpacket(Session *s, Packet_Head<id>& head, const std::vector<Packet_Re s->set_eof(); } +template<uint16_t id, uint16_t headsize, uint16_t optsize> +void send_opacket(Session *s, Packet_Head<id>& head, bool has_opt, const Packet_Option<id>& opt) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "sizeof(NetPacket_Head<id>)"); + static_assert(id == Packet_Option<id>::PACKET_ID, "Packet_Option<id>::PACKET_ID"); + static_assert(optsize == sizeof(NetPacket_Option<id>), "sizeof(NetPacket_Option<id>)"); + + NetPacket_Head<id> net_head; + // since these are already allocated, can't overflow address space + size_t total_size = sizeof(NetPacket_Head<id>) + has_opt * sizeof(NetPacket_Option<id>); + // truncates + head.magic_packet_length = total_size; + if (head.magic_packet_length != total_size) + { + s->set_eof(); + return; + } + NetPacket_Option<id> net_opt; + if (!native_to_network(&net_head, head)) + { + s->set_eof(); + return; + } + if (has_opt) + { + if (!native_to_network(&net_opt, opt)) + { + s->set_eof(); + return; + } + } + SendResult rv = net_send_opacket(s, net_head, has_opt, net_opt); + if (rv != SendResult::Success) + s->set_eof(); +} + template<uint16_t id, uint16_t size> __attribute__((warn_unused_result)) RecvResult recv_fpacket(Session *s, Packet_Fixed<id>& fixed) @@ -192,11 +310,30 @@ RecvResult recv_fpacket(Session *s, Packet_Fixed<id>& fixed) NetPacket_Fixed<id> net_fixed; RecvResult rv = net_recv_fpacket(s, net_fixed); - assert (fixed.magic_packet_id == Packet_Fixed<id>::PACKET_ID); if (rv == RecvResult::Complete) { if (!network_to_native(&fixed, net_fixed)) return RecvResult::Error; + assert (fixed.magic_packet_id == Packet_Fixed<id>::PACKET_ID); + } + return rv; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult recv_ppacket(Session *s, Packet_Payload<id>& payload) +{ + static_assert(id == Packet_Payload<id>::PACKET_ID, "Packet_Payload<id>::PACKET_ID"); + + NetPacket_Payload<id> net_payload; + RecvResult rv = net_recv_ppacket(s, net_payload); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&payload, net_payload)) + return RecvResult::Error; + assert (payload.magic_packet_id == Packet_Payload<id>::PACKET_ID); + if (payload.magic_packet_length != sizeof(net_payload)) + return RecvResult::Error; } return rv; } @@ -213,11 +350,12 @@ RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, std::vector<Packet_Re NetPacket_Head<id> net_head; std::vector<NetPacket_Repeat<id>> net_repeat; RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); - assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); if (rv == RecvResult::Complete) { if (!network_to_native(&head, net_head)) return RecvResult::Error; + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); + repeat.resize(net_repeat.size()); for (size_t i = 0; i < net_repeat.size(); ++i) { @@ -228,6 +366,33 @@ RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, std::vector<Packet_Re return rv; } +template<uint16_t id, uint16_t headsize, uint16_t optsize> +__attribute__((warn_unused_result)) +RecvResult recv_opacket(Session *s, Packet_Head<id>& head, bool *has_opt, Packet_Option<id>& opt) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Option<id>::PACKET_ID, "Packet_Option<id>::PACKET_ID"); + static_assert(optsize == sizeof(NetPacket_Option<id>), "NetPacket_Option<id>"); + + NetPacket_Head<id> net_head; + NetPacket_Option<id> net_opt; + RecvResult rv = net_recv_opacket(s, net_head, has_opt, net_opt); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&head, net_head)) + return RecvResult::Error; + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); + + if (*has_opt) + { + if (!network_to_native(&opt, net_opt)) + return RecvResult::Error; + } + } + return rv; +} + // convenience for trailing strings diff --git a/src/proto2/any-user.hpp b/src/proto2/any-user.hpp index d704233..da9b1bc 100644 --- a/src/proto2/any-user.hpp +++ b/src/proto2/any-user.hpp @@ -27,6 +27,19 @@ // This is a public protocol, and changes require client cooperation +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) + +template<> +struct Packet_Fixed<0x0081> +{ + static const uint16_t PACKET_ID = 0x0081; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t error_code = {}; +}; + template<> struct Packet_Fixed<0x7530> { @@ -57,6 +70,16 @@ struct Packet_Fixed<0x7532> template<> +struct NetPacket_Fixed<0x0081> +{ + Little16 magic_packet_id; + Byte error_code; +}; +static_assert(offsetof(NetPacket_Fixed<0x0081>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0081>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0081>, error_code) == 2, "offsetof(NetPacket_Fixed<0x0081>, error_code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0081>) == 3, "sizeof(NetPacket_Fixed<0x0081>) == 3"); + +template<> struct NetPacket_Fixed<0x7530> { Little16 magic_packet_id; @@ -84,6 +107,23 @@ static_assert(sizeof(NetPacket_Fixed<0x7532>) == 2, "sizeof(NetPacket_Fixed<0x75 inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0081> *network, Packet_Fixed<0x0081> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->error_code, native.error_code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0081> *native, NetPacket_Fixed<0x0081> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->error_code, network.error_code); + return rv; +} + +inline __attribute__((warn_unused_result)) bool native_to_network(NetPacket_Fixed<0x7530> *network, Packet_Fixed<0x7530> native) { bool rv = true; @@ -131,4 +171,6 @@ bool network_to_native(Packet_Fixed<0x7532> *native, NetPacket_Fixed<0x7532> net } +#pragma pack(pop) + #endif // TMWA_PROTO2_ANY_USER_HPP diff --git a/src/proto2/char-map.hpp b/src/proto2/char-map.hpp index 83f13a7..333c948 100644 --- a/src/proto2/char-map.hpp +++ b/src/proto2/char-map.hpp @@ -27,7 +27,3435 @@ // This is an internal protocol, and can be changed without notice +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) +template<> +struct Packet_Fixed<0x2af7> +{ + static const uint16_t PACKET_ID = 0x2af7; + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x2af8> +{ + static const uint16_t PACKET_ID = 0x2af8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountPass account_pass = {}; + uint32_t unused = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; + +template<> +struct Packet_Fixed<0x2af9> +{ + static const uint16_t PACKET_ID = 0x2af9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Head<0x2afa> +{ + static const uint16_t PACKET_ID = 0x2afa; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x2afa> +{ + static const uint16_t PACKET_ID = 0x2afa; + + MapName map_name = {}; +}; + +template<> +struct Packet_Fixed<0x2afa> +{ + static const uint16_t PACKET_ID = 0x2afa; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + ItemNameId source_item_id = {}; + ItemNameId dest_item_id = {}; +}; + +template<> +struct Packet_Fixed<0x2afb> +{ + static const uint16_t PACKET_ID = 0x2afb; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t unknown = {}; + CharName whisper_name = {}; +}; + +template<> +struct Packet_Fixed<0x2afc> +{ + static const uint16_t PACKET_ID = 0x2afc; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharId char_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + IP4Address ip = {}; +}; + +template<> +struct Packet_Payload<0x2afd> +{ + static const uint16_t PACKET_ID = 0x2afd; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + uint32_t login_id2 = {}; + TimeT connect_until = {}; + uint16_t packet_tmw_version = {}; + CharKey char_key = {}; + CharData char_data = {}; +}; + +template<> +struct Packet_Fixed<0x2afe> +{ + static const uint16_t PACKET_ID = 0x2afe; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Head<0x2aff> +{ + static const uint16_t PACKET_ID = 0x2aff; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + uint16_t users = {}; +}; +template<> +struct Packet_Repeat<0x2aff> +{ + static const uint16_t PACKET_ID = 0x2aff; + + CharId char_id = {}; +}; + +template<> +struct Packet_Fixed<0x2b00> +{ + static const uint16_t PACKET_ID = 0x2b00; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t users = {}; +}; + +template<> +struct Packet_Payload<0x2b01> +{ + static const uint16_t PACKET_ID = 0x2b01; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + CharId char_id = {}; + CharKey char_key = {}; + CharData char_data = {}; +}; + +template<> +struct Packet_Fixed<0x2b02> +{ + static const uint16_t PACKET_ID = 0x2b02; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + IP4Address ip = {}; +}; + +template<> +struct Packet_Fixed<0x2b03> +{ + static const uint16_t PACKET_ID = 0x2b03; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t unknown = {}; +}; + +template<> +struct Packet_Head<0x2b04> +{ + static const uint16_t PACKET_ID = 0x2b04; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; +template<> +struct Packet_Repeat<0x2b04> +{ + static const uint16_t PACKET_ID = 0x2b04; + + MapName map_name = {}; +}; + +template<> +struct Packet_Fixed<0x2b05> +{ + static const uint16_t PACKET_ID = 0x2b05; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + CharId char_id = {}; + MapName map_name = {}; + uint16_t x = {}; + uint16_t y = {}; + IP4Address map_ip = {}; + uint16_t map_port = {}; + SEX sex = {}; + IP4Address client_ip = {}; +}; + +template<> +struct Packet_Fixed<0x2b06> +{ + static const uint16_t PACKET_ID = 0x2b06; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t error = {}; + uint32_t unknown = {}; + CharId char_id = {}; + MapName map_name = {}; + uint16_t x = {}; + uint16_t y = {}; + IP4Address map_ip = {}; + uint16_t map_port = {}; +}; + +template<> +struct Packet_Head<0x2b0a> +{ + static const uint16_t PACKET_ID = 0x2b0a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2b0a> +{ + static const uint16_t PACKET_ID = 0x2b0a; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x2b0b> +{ + static const uint16_t PACKET_ID = 0x2b0b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x2b0c> +{ + static const uint16_t PACKET_ID = 0x2b0c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountEmail old_email = {}; + AccountEmail new_email = {}; +}; + +template<> +struct Packet_Fixed<0x2b0d> +{ + static const uint16_t PACKET_ID = 0x2b0d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x2b0e> +{ + static const uint16_t PACKET_ID = 0x2b0e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharName char_name = {}; + uint16_t operation = {}; + HumanTimeDiff ban_add = {}; +}; + +template<> +struct Packet_Fixed<0x2b0f> +{ + static const uint16_t PACKET_ID = 0x2b0f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharName char_name = {}; + uint16_t operation = {}; + uint16_t error = {}; +}; + +template<> +struct Packet_Head<0x2b10> +{ + static const uint16_t PACKET_ID = 0x2b10; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2b10> +{ + static const uint16_t PACKET_ID = 0x2b10; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Head<0x2b11> +{ + static const uint16_t PACKET_ID = 0x2b11; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2b11> +{ + static const uint16_t PACKET_ID = 0x2b11; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x2b12> +{ + static const uint16_t PACKET_ID = 0x2b12; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + CharId partner_id = {}; +}; + +template<> +struct Packet_Fixed<0x2b13> +{ + static const uint16_t PACKET_ID = 0x2b13; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x2b14> +{ + static const uint16_t PACKET_ID = 0x2b14; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t ban_not_status = {}; + TimeT status_or_ban_until = {}; +}; + +template<> +struct Packet_Head<0x2b15> +{ + static const uint16_t PACKET_ID = 0x2b15; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x2b15> +{ + static const uint16_t PACKET_ID = 0x2b15; + + AccountId account_id = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x2b16> +{ + static const uint16_t PACKET_ID = 0x2b16; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; +}; + +template<> +struct Packet_Head<0x3000> +{ + static const uint16_t PACKET_ID = 0x3000; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x3000> +{ + static const uint16_t PACKET_ID = 0x3000; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3001> +{ + static const uint16_t PACKET_ID = 0x3001; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName from_char_name = {}; + CharName to_char_name = {}; +}; +template<> +struct Packet_Repeat<0x3001> +{ + static const uint16_t PACKET_ID = 0x3001; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x3002> +{ + static const uint16_t PACKET_ID = 0x3002; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x3003> +{ + static const uint16_t PACKET_ID = 0x3003; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName char_name = {}; + GmLevel min_gm_level = {}; +}; +template<> +struct Packet_Repeat<0x3003> +{ + static const uint16_t PACKET_ID = 0x3003; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3004> +{ + static const uint16_t PACKET_ID = 0x3004; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3004> +{ + static const uint16_t PACKET_ID = 0x3004; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x3005> +{ + static const uint16_t PACKET_ID = 0x3005; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x3010> +{ + static const uint16_t PACKET_ID = 0x3010; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Payload<0x3011> +{ + static const uint16_t PACKET_ID = 0x3011; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + Storage storage = {}; +}; + +template<> +struct Packet_Fixed<0x3020> +{ + static const uint16_t PACKET_ID = 0x3020; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + PartyName party_name = {}; + CharName char_name = {}; + MapName map_name = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3021> +{ + static const uint16_t PACKET_ID = 0x3021; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; +}; + +template<> +struct Packet_Fixed<0x3022> +{ + static const uint16_t PACKET_ID = 0x3022; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + CharName char_name = {}; + MapName map_name = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3023> +{ + static const uint16_t PACKET_ID = 0x3023; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + uint16_t exp = {}; + uint16_t item = {}; +}; + +template<> +struct Packet_Fixed<0x3024> +{ + static const uint16_t PACKET_ID = 0x3024; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x3025> +{ + static const uint16_t PACKET_ID = 0x3025; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + MapName map_name = {}; + uint8_t online = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3026> +{ + static const uint16_t PACKET_ID = 0x3026; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; +}; + +template<> +struct Packet_Head<0x3027> +{ + static const uint16_t PACKET_ID = 0x3027; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyId party_id = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3027> +{ + static const uint16_t PACKET_ID = 0x3027; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x3028> +{ + static const uint16_t PACKET_ID = 0x3028; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + CharName char_name = {}; +}; + +template<> +struct Packet_Head<0x3800> +{ + static const uint16_t PACKET_ID = 0x3800; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x3800> +{ + static const uint16_t PACKET_ID = 0x3800; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3801> +{ + static const uint16_t PACKET_ID = 0x3801; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharId whisper_id = {}; + CharName src_char_name = {}; + CharName dst_char_name = {}; +}; +template<> +struct Packet_Repeat<0x3801> +{ + static const uint16_t PACKET_ID = 0x3801; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x3802> +{ + static const uint16_t PACKET_ID = 0x3802; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharName sender_char_name = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x3803> +{ + static const uint16_t PACKET_ID = 0x3803; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName char_name = {}; + GmLevel min_gm_level = {}; +}; +template<> +struct Packet_Repeat<0x3803> +{ + static const uint16_t PACKET_ID = 0x3803; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3804> +{ + static const uint16_t PACKET_ID = 0x3804; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3804> +{ + static const uint16_t PACKET_ID = 0x3804; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Payload<0x3810> +{ + static const uint16_t PACKET_ID = 0x3810; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + Storage storage = {}; +}; + +template<> +struct Packet_Fixed<0x3811> +{ + static const uint16_t PACKET_ID = 0x3811; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t unknown = {}; +}; + +template<> +struct Packet_Fixed<0x3820> +{ + static const uint16_t PACKET_ID = 0x3820; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t error = {}; + PartyId party_id = {}; + PartyName party_name = {}; +}; + +template<> +struct Packet_Head<0x3821> +{ + static const uint16_t PACKET_ID = 0x3821; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyId party_id = {}; +}; +template<> +struct Packet_Option<0x3821> +{ + static const uint16_t PACKET_ID = 0x3821; + + PartyMost party_most = {}; +}; + +template<> +struct Packet_Fixed<0x3822> +{ + static const uint16_t PACKET_ID = 0x3822; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x3823> +{ + static const uint16_t PACKET_ID = 0x3823; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + uint16_t exp = {}; + uint16_t item = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x3824> +{ + static const uint16_t PACKET_ID = 0x3824; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + CharName char_name = {}; +}; + +template<> +struct Packet_Fixed<0x3825> +{ + static const uint16_t PACKET_ID = 0x3825; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + MapName map_name = {}; + uint8_t online = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3826> +{ + static const uint16_t PACKET_ID = 0x3826; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x3827> +{ + static const uint16_t PACKET_ID = 0x3827; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyId party_id = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3827> +{ + static const uint16_t PACKET_ID = 0x3827; + + uint8_t c = {}; +}; + + +template<> +struct NetPacket_Fixed<0x2af7> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2af7>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2af7>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x2af7>) == 2, "sizeof(NetPacket_Fixed<0x2af7>) == 2"); + +template<> +struct NetPacket_Fixed<0x2af8> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> account_pass; + Little32 unused; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Fixed<0x2af8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2af8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, account_name) == 2, "offsetof(NetPacket_Fixed<0x2af8>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, account_pass) == 26, "offsetof(NetPacket_Fixed<0x2af8>, account_pass) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, unused) == 50, "offsetof(NetPacket_Fixed<0x2af8>, unused) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, ip) == 54, "offsetof(NetPacket_Fixed<0x2af8>, ip) == 54"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, port) == 58, "offsetof(NetPacket_Fixed<0x2af8>, port) == 58"); +static_assert(sizeof(NetPacket_Fixed<0x2af8>) == 60, "sizeof(NetPacket_Fixed<0x2af8>) == 60"); + +template<> +struct NetPacket_Fixed<0x2af9> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x2af9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2af9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2af9>, code) == 2, "offsetof(NetPacket_Fixed<0x2af9>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2af9>) == 3, "sizeof(NetPacket_Fixed<0x2af9>) == 3"); + +template<> +struct NetPacket_Head<0x2afa> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x2afa>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2afa>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2afa>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2afa>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x2afa>) == 4, "sizeof(NetPacket_Head<0x2afa>) == 4"); +template<> +struct NetPacket_Repeat<0x2afa> +{ + NetString<sizeof(MapName)> map_name; +}; +static_assert(offsetof(NetPacket_Repeat<0x2afa>, map_name) == 0, "offsetof(NetPacket_Repeat<0x2afa>, map_name) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2afa>) == 16, "sizeof(NetPacket_Repeat<0x2afa>) == 16"); + +template<> +struct NetPacket_Fixed<0x2afa> +{ + Little16 magic_packet_id; + Little32 source_item_id; + Little32 dest_item_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afa>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afa>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afa>, source_item_id) == 2, "offsetof(NetPacket_Fixed<0x2afa>, source_item_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2afa>, dest_item_id) == 6, "offsetof(NetPacket_Fixed<0x2afa>, dest_item_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2afa>) == 10, "sizeof(NetPacket_Fixed<0x2afa>) == 10"); + +template<> +struct NetPacket_Fixed<0x2afb> +{ + Little16 magic_packet_id; + Byte unknown; + NetString<sizeof(CharName)> whisper_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afb>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afb>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afb>, unknown) == 2, "offsetof(NetPacket_Fixed<0x2afb>, unknown) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2afb>, whisper_name) == 3, "offsetof(NetPacket_Fixed<0x2afb>, whisper_name) == 3"); +static_assert(sizeof(NetPacket_Fixed<0x2afb>) == 27, "sizeof(NetPacket_Fixed<0x2afb>) == 27"); + +template<> +struct NetPacket_Fixed<0x2afc> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 char_id; + Little32 login_id1; + Little32 login_id2; + IP4Address ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afc>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afc>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2afc>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, char_id) == 6, "offsetof(NetPacket_Fixed<0x2afc>, char_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, login_id1) == 10, "offsetof(NetPacket_Fixed<0x2afc>, login_id1) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, login_id2) == 14, "offsetof(NetPacket_Fixed<0x2afc>, login_id2) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, ip) == 18, "offsetof(NetPacket_Fixed<0x2afc>, ip) == 18"); +static_assert(sizeof(NetPacket_Fixed<0x2afc>) == 22, "sizeof(NetPacket_Fixed<0x2afc>) == 22"); + +template<> +struct NetPacket_Payload<0x2afd> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + Little32 login_id2; + Little32 connect_until; + Little16 packet_tmw_version; + CharKey char_key; + CharData char_data; +}; +static_assert(offsetof(NetPacket_Payload<0x2afd>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x2afd>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x2afd>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, account_id) == 4, "offsetof(NetPacket_Payload<0x2afd>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, login_id2) == 8, "offsetof(NetPacket_Payload<0x2afd>, login_id2) == 8"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, connect_until) == 12, "offsetof(NetPacket_Payload<0x2afd>, connect_until) == 12"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, packet_tmw_version) == 16, "offsetof(NetPacket_Payload<0x2afd>, packet_tmw_version) == 16"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, char_key) == 18, "offsetof(NetPacket_Payload<0x2afd>, char_key) == 18"); + +template<> +struct NetPacket_Fixed<0x2afe> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afe>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afe>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afe>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2afe>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2afe>) == 6, "sizeof(NetPacket_Fixed<0x2afe>) == 6"); + +template<> +struct NetPacket_Head<0x2aff> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little16 users; +}; +static_assert(offsetof(NetPacket_Head<0x2aff>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2aff>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2aff>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2aff>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2aff>, users) == 4, "offsetof(NetPacket_Head<0x2aff>, users) == 4"); +static_assert(sizeof(NetPacket_Head<0x2aff>) == 6, "sizeof(NetPacket_Head<0x2aff>) == 6"); +template<> +struct NetPacket_Repeat<0x2aff> +{ + Little32 char_id; +}; +static_assert(offsetof(NetPacket_Repeat<0x2aff>, char_id) == 0, "offsetof(NetPacket_Repeat<0x2aff>, char_id) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2aff>) == 4, "sizeof(NetPacket_Repeat<0x2aff>) == 4"); + +template<> +struct NetPacket_Fixed<0x2b00> +{ + Little16 magic_packet_id; + Little32 users; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b00>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b00>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b00>, users) == 2, "offsetof(NetPacket_Fixed<0x2b00>, users) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2b00>) == 6, "sizeof(NetPacket_Fixed<0x2b00>) == 6"); + +template<> +struct NetPacket_Payload<0x2b01> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + Little32 char_id; + CharKey char_key; + CharData char_data; +}; +static_assert(offsetof(NetPacket_Payload<0x2b01>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x2b01>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x2b01>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, account_id) == 4, "offsetof(NetPacket_Payload<0x2b01>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, char_id) == 8, "offsetof(NetPacket_Payload<0x2b01>, char_id) == 8"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, char_key) == 12, "offsetof(NetPacket_Payload<0x2b01>, char_key) == 12"); + +template<> +struct NetPacket_Fixed<0x2b02> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + IP4Address ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b02>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b02>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b02>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x2b02>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x2b02>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, ip) == 14, "offsetof(NetPacket_Fixed<0x2b02>, ip) == 14"); +static_assert(sizeof(NetPacket_Fixed<0x2b02>) == 18, "sizeof(NetPacket_Fixed<0x2b02>) == 18"); + +template<> +struct NetPacket_Fixed<0x2b03> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte unknown; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b03>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b03>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b03>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b03>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b03>, unknown) == 6, "offsetof(NetPacket_Fixed<0x2b03>, unknown) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b03>) == 7, "sizeof(NetPacket_Fixed<0x2b03>) == 7"); + +template<> +struct NetPacket_Head<0x2b04> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Head<0x2b04>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b04>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b04>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b04>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b04>, ip) == 4, "offsetof(NetPacket_Head<0x2b04>, ip) == 4"); +static_assert(offsetof(NetPacket_Head<0x2b04>, port) == 8, "offsetof(NetPacket_Head<0x2b04>, port) == 8"); +static_assert(sizeof(NetPacket_Head<0x2b04>) == 10, "sizeof(NetPacket_Head<0x2b04>) == 10"); +template<> +struct NetPacket_Repeat<0x2b04> +{ + NetString<sizeof(MapName)> map_name; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b04>, map_name) == 0, "offsetof(NetPacket_Repeat<0x2b04>, map_name) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2b04>) == 16, "sizeof(NetPacket_Repeat<0x2b04>) == 16"); + +template<> +struct NetPacket_Fixed<0x2b05> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + Little32 char_id; + NetString<sizeof(MapName)> map_name; + Little16 x; + Little16 y; + IP4Address map_ip; + Little16 map_port; + Byte sex; + IP4Address client_ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b05>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b05>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b05>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x2b05>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x2b05>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, char_id) == 14, "offsetof(NetPacket_Fixed<0x2b05>, char_id) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, map_name) == 18, "offsetof(NetPacket_Fixed<0x2b05>, map_name) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, x) == 34, "offsetof(NetPacket_Fixed<0x2b05>, x) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, y) == 36, "offsetof(NetPacket_Fixed<0x2b05>, y) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, map_ip) == 38, "offsetof(NetPacket_Fixed<0x2b05>, map_ip) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, map_port) == 42, "offsetof(NetPacket_Fixed<0x2b05>, map_port) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, sex) == 44, "offsetof(NetPacket_Fixed<0x2b05>, sex) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, client_ip) == 45, "offsetof(NetPacket_Fixed<0x2b05>, client_ip) == 45"); +static_assert(sizeof(NetPacket_Fixed<0x2b05>) == 49, "sizeof(NetPacket_Fixed<0x2b05>) == 49"); + +template<> +struct NetPacket_Fixed<0x2b06> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 error; + Little32 unknown; + Little32 char_id; + NetString<sizeof(MapName)> map_name; + Little16 x; + Little16 y; + IP4Address map_ip; + Little16 map_port; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b06>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b06>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b06>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, error) == 6, "offsetof(NetPacket_Fixed<0x2b06>, error) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, unknown) == 10, "offsetof(NetPacket_Fixed<0x2b06>, unknown) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, char_id) == 14, "offsetof(NetPacket_Fixed<0x2b06>, char_id) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, map_name) == 18, "offsetof(NetPacket_Fixed<0x2b06>, map_name) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, x) == 34, "offsetof(NetPacket_Fixed<0x2b06>, x) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, y) == 36, "offsetof(NetPacket_Fixed<0x2b06>, y) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, map_ip) == 38, "offsetof(NetPacket_Fixed<0x2b06>, map_ip) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, map_port) == 42, "offsetof(NetPacket_Fixed<0x2b06>, map_port) == 42"); +static_assert(sizeof(NetPacket_Fixed<0x2b06>) == 44, "sizeof(NetPacket_Fixed<0x2b06>) == 44"); + +template<> +struct NetPacket_Head<0x2b0a> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2b0a>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b0a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b0a>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b0a>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b0a>, account_id) == 4, "offsetof(NetPacket_Head<0x2b0a>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2b0a>) == 8, "sizeof(NetPacket_Head<0x2b0a>) == 8"); +template<> +struct NetPacket_Repeat<0x2b0a> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b0a>, c) == 0, "offsetof(NetPacket_Repeat<0x2b0a>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2b0a>) == 1, "sizeof(NetPacket_Repeat<0x2b0a>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b0b> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 gm_level; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0b>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0b>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0b>, gm_level) == 6, "offsetof(NetPacket_Fixed<0x2b0b>, gm_level) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b0b>) == 10, "sizeof(NetPacket_Fixed<0x2b0b>) == 10"); + +template<> +struct NetPacket_Fixed<0x2b0c> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountEmail)> old_email; + NetString<sizeof(AccountEmail)> new_email; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0c>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, old_email) == 6, "offsetof(NetPacket_Fixed<0x2b0c>, old_email) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, new_email) == 46, "offsetof(NetPacket_Fixed<0x2b0c>, new_email) == 46"); +static_assert(sizeof(NetPacket_Fixed<0x2b0c>) == 86, "sizeof(NetPacket_Fixed<0x2b0c>) == 86"); + +template<> +struct NetPacket_Fixed<0x2b0d> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0d>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0d>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0d>, sex) == 6, "offsetof(NetPacket_Fixed<0x2b0d>, sex) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b0d>) == 7, "sizeof(NetPacket_Fixed<0x2b0d>) == 7"); + +template<> +struct NetPacket_Fixed<0x2b0e> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + Little16 operation; + NetHumanTimeDiff ban_add; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0e>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, char_name) == 6, "offsetof(NetPacket_Fixed<0x2b0e>, char_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, operation) == 30, "offsetof(NetPacket_Fixed<0x2b0e>, operation) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, ban_add) == 32, "offsetof(NetPacket_Fixed<0x2b0e>, ban_add) == 32"); +static_assert(sizeof(NetPacket_Fixed<0x2b0e>) == 44, "sizeof(NetPacket_Fixed<0x2b0e>) == 44"); + +template<> +struct NetPacket_Fixed<0x2b0f> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + Little16 operation; + Little16 error; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0f>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, char_name) == 6, "offsetof(NetPacket_Fixed<0x2b0f>, char_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, operation) == 30, "offsetof(NetPacket_Fixed<0x2b0f>, operation) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, error) == 32, "offsetof(NetPacket_Fixed<0x2b0f>, error) == 32"); +static_assert(sizeof(NetPacket_Fixed<0x2b0f>) == 34, "sizeof(NetPacket_Fixed<0x2b0f>) == 34"); + +template<> +struct NetPacket_Head<0x2b10> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2b10>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b10>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b10>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b10>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b10>, account_id) == 4, "offsetof(NetPacket_Head<0x2b10>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2b10>) == 8, "sizeof(NetPacket_Head<0x2b10>) == 8"); +template<> +struct NetPacket_Repeat<0x2b10> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b10>, name) == 0, "offsetof(NetPacket_Repeat<0x2b10>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2b10>, value) == 32, "offsetof(NetPacket_Repeat<0x2b10>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x2b10>) == 36, "sizeof(NetPacket_Repeat<0x2b10>) == 36"); + +template<> +struct NetPacket_Head<0x2b11> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2b11>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b11>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b11>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b11>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b11>, account_id) == 4, "offsetof(NetPacket_Head<0x2b11>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2b11>) == 8, "sizeof(NetPacket_Head<0x2b11>) == 8"); +template<> +struct NetPacket_Repeat<0x2b11> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b11>, name) == 0, "offsetof(NetPacket_Repeat<0x2b11>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2b11>, value) == 32, "offsetof(NetPacket_Repeat<0x2b11>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x2b11>) == 36, "sizeof(NetPacket_Repeat<0x2b11>) == 36"); + +template<> +struct NetPacket_Fixed<0x2b12> +{ + Little16 magic_packet_id; + Little32 char_id; + Little32 partner_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b12>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b12>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b12>, char_id) == 2, "offsetof(NetPacket_Fixed<0x2b12>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b12>, partner_id) == 6, "offsetof(NetPacket_Fixed<0x2b12>, partner_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b12>) == 10, "sizeof(NetPacket_Fixed<0x2b12>) == 10"); + +template<> +struct NetPacket_Fixed<0x2b13> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b13>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b13>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b13>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b13>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2b13>) == 6, "sizeof(NetPacket_Fixed<0x2b13>) == 6"); + +template<> +struct NetPacket_Fixed<0x2b14> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte ban_not_status; + Little32 status_or_ban_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b14>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b14>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b14>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b14>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b14>, ban_not_status) == 6, "offsetof(NetPacket_Fixed<0x2b14>, ban_not_status) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b14>, status_or_ban_until) == 7, "offsetof(NetPacket_Fixed<0x2b14>, status_or_ban_until) == 7"); +static_assert(sizeof(NetPacket_Fixed<0x2b14>) == 11, "sizeof(NetPacket_Fixed<0x2b14>) == 11"); + +template<> +struct NetPacket_Head<0x2b15> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x2b15>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b15>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b15>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b15>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x2b15>) == 4, "sizeof(NetPacket_Head<0x2b15>) == 4"); +template<> +struct NetPacket_Repeat<0x2b15> +{ + Little32 account_id; + Byte gm_level; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b15>, account_id) == 0, "offsetof(NetPacket_Repeat<0x2b15>, account_id) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2b15>, gm_level) == 4, "offsetof(NetPacket_Repeat<0x2b15>, gm_level) == 4"); +static_assert(sizeof(NetPacket_Repeat<0x2b15>) == 5, "sizeof(NetPacket_Repeat<0x2b15>) == 5"); + +template<> +struct NetPacket_Fixed<0x2b16> +{ + Little16 magic_packet_id; + Little32 char_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b16>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b16>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b16>, char_id) == 2, "offsetof(NetPacket_Fixed<0x2b16>, char_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2b16>) == 6, "sizeof(NetPacket_Fixed<0x2b16>) == 6"); + +template<> +struct NetPacket_Head<0x3000> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x3000>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3000>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3000>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3000>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x3000>) == 4, "sizeof(NetPacket_Head<0x3000>) == 4"); +template<> +struct NetPacket_Repeat<0x3000> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3000>, c) == 0, "offsetof(NetPacket_Repeat<0x3000>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3000>) == 1, "sizeof(NetPacket_Repeat<0x3000>) == 1"); + +template<> +struct NetPacket_Head<0x3001> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> from_char_name; + NetString<sizeof(CharName)> to_char_name; +}; +static_assert(offsetof(NetPacket_Head<0x3001>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3001>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3001>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3001>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3001>, from_char_name) == 4, "offsetof(NetPacket_Head<0x3001>, from_char_name) == 4"); +static_assert(offsetof(NetPacket_Head<0x3001>, to_char_name) == 28, "offsetof(NetPacket_Head<0x3001>, to_char_name) == 28"); +static_assert(sizeof(NetPacket_Head<0x3001>) == 52, "sizeof(NetPacket_Head<0x3001>) == 52"); +template<> +struct NetPacket_Repeat<0x3001> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3001>, c) == 0, "offsetof(NetPacket_Repeat<0x3001>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3001>) == 1, "sizeof(NetPacket_Repeat<0x3001>) == 1"); + +template<> +struct NetPacket_Fixed<0x3002> +{ + Little16 magic_packet_id; + Little32 char_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3002>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3002>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3002>, char_id) == 2, "offsetof(NetPacket_Fixed<0x3002>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3002>, flag) == 6, "offsetof(NetPacket_Fixed<0x3002>, flag) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3002>) == 7, "sizeof(NetPacket_Fixed<0x3002>) == 7"); + +template<> +struct NetPacket_Head<0x3003> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> char_name; + Little16 min_gm_level; +}; +static_assert(offsetof(NetPacket_Head<0x3003>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3003>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3003>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3003>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3003>, char_name) == 4, "offsetof(NetPacket_Head<0x3003>, char_name) == 4"); +static_assert(offsetof(NetPacket_Head<0x3003>, min_gm_level) == 28, "offsetof(NetPacket_Head<0x3003>, min_gm_level) == 28"); +static_assert(sizeof(NetPacket_Head<0x3003>) == 30, "sizeof(NetPacket_Head<0x3003>) == 30"); +template<> +struct NetPacket_Repeat<0x3003> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3003>, c) == 0, "offsetof(NetPacket_Repeat<0x3003>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3003>) == 1, "sizeof(NetPacket_Repeat<0x3003>) == 1"); + +template<> +struct NetPacket_Head<0x3004> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3004>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3004>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3004>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3004>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3004>, account_id) == 4, "offsetof(NetPacket_Head<0x3004>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x3004>) == 8, "sizeof(NetPacket_Head<0x3004>) == 8"); +template<> +struct NetPacket_Repeat<0x3004> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x3004>, name) == 0, "offsetof(NetPacket_Repeat<0x3004>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x3004>, value) == 32, "offsetof(NetPacket_Repeat<0x3004>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x3004>) == 36, "sizeof(NetPacket_Repeat<0x3004>) == 36"); + +template<> +struct NetPacket_Fixed<0x3005> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3005>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3005>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3005>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3005>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3005>) == 6, "sizeof(NetPacket_Fixed<0x3005>) == 6"); + +template<> +struct NetPacket_Fixed<0x3010> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3010>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3010>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3010>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3010>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3010>) == 6, "sizeof(NetPacket_Fixed<0x3010>) == 6"); + +template<> +struct NetPacket_Payload<0x3011> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + Storage storage; +}; +static_assert(offsetof(NetPacket_Payload<0x3011>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x3011>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x3011>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x3011>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x3011>, account_id) == 4, "offsetof(NetPacket_Payload<0x3011>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x3011>, storage) == 8, "offsetof(NetPacket_Payload<0x3011>, storage) == 8"); + +template<> +struct NetPacket_Fixed<0x3020> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(PartyName)> party_name; + NetString<sizeof(CharName)> char_name; + NetString<sizeof(MapName)> map_name; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3020>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3020>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3020>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, party_name) == 6, "offsetof(NetPacket_Fixed<0x3020>, party_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, char_name) == 30, "offsetof(NetPacket_Fixed<0x3020>, char_name) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, map_name) == 54, "offsetof(NetPacket_Fixed<0x3020>, map_name) == 54"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, level) == 70, "offsetof(NetPacket_Fixed<0x3020>, level) == 70"); +static_assert(sizeof(NetPacket_Fixed<0x3020>) == 72, "sizeof(NetPacket_Fixed<0x3020>) == 72"); + +template<> +struct NetPacket_Fixed<0x3021> +{ + Little16 magic_packet_id; + Little32 party_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3021>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3021>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3021>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3021>, party_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3021>) == 6, "sizeof(NetPacket_Fixed<0x3021>) == 6"); + +template<> +struct NetPacket_Fixed<0x3022> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + NetString<sizeof(MapName)> map_name; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3022>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3022>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3022>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3022>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, char_name) == 10, "offsetof(NetPacket_Fixed<0x3022>, char_name) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, map_name) == 34, "offsetof(NetPacket_Fixed<0x3022>, map_name) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, level) == 50, "offsetof(NetPacket_Fixed<0x3022>, level) == 50"); +static_assert(sizeof(NetPacket_Fixed<0x3022>) == 52, "sizeof(NetPacket_Fixed<0x3022>) == 52"); + +template<> +struct NetPacket_Fixed<0x3023> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + Little16 exp; + Little16 item; +}; +static_assert(offsetof(NetPacket_Fixed<0x3023>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3023>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3023>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3023>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, exp) == 10, "offsetof(NetPacket_Fixed<0x3023>, exp) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, item) == 12, "offsetof(NetPacket_Fixed<0x3023>, item) == 12"); +static_assert(sizeof(NetPacket_Fixed<0x3023>) == 14, "sizeof(NetPacket_Fixed<0x3023>) == 14"); + +template<> +struct NetPacket_Fixed<0x3024> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3024>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3024>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3024>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3024>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3024>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3024>, account_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3024>) == 10, "sizeof(NetPacket_Fixed<0x3024>) == 10"); + +template<> +struct NetPacket_Fixed<0x3025> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(MapName)> map_name; + Byte online; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3025>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3025>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3025>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3025>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, map_name) == 10, "offsetof(NetPacket_Fixed<0x3025>, map_name) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, online) == 26, "offsetof(NetPacket_Fixed<0x3025>, online) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, level) == 27, "offsetof(NetPacket_Fixed<0x3025>, level) == 27"); +static_assert(sizeof(NetPacket_Fixed<0x3025>) == 29, "sizeof(NetPacket_Fixed<0x3025>) == 29"); + +template<> +struct NetPacket_Fixed<0x3026> +{ + Little16 magic_packet_id; + Little32 party_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3026>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3026>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3026>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3026>, party_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3026>) == 6, "sizeof(NetPacket_Fixed<0x3026>) == 6"); + +template<> +struct NetPacket_Head<0x3027> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 party_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3027>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3027>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3027>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3027>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3027>, party_id) == 4, "offsetof(NetPacket_Head<0x3027>, party_id) == 4"); +static_assert(offsetof(NetPacket_Head<0x3027>, account_id) == 8, "offsetof(NetPacket_Head<0x3027>, account_id) == 8"); +static_assert(sizeof(NetPacket_Head<0x3027>) == 12, "sizeof(NetPacket_Head<0x3027>) == 12"); +template<> +struct NetPacket_Repeat<0x3027> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3027>, c) == 0, "offsetof(NetPacket_Repeat<0x3027>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3027>) == 1, "sizeof(NetPacket_Repeat<0x3027>) == 1"); + +template<> +struct NetPacket_Fixed<0x3028> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x3028>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3028>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3028>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3028>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3028>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3028>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3028>, char_name) == 10, "offsetof(NetPacket_Fixed<0x3028>, char_name) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x3028>) == 34, "sizeof(NetPacket_Fixed<0x3028>) == 34"); + +template<> +struct NetPacket_Head<0x3800> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x3800>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3800>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3800>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3800>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x3800>) == 4, "sizeof(NetPacket_Head<0x3800>) == 4"); +template<> +struct NetPacket_Repeat<0x3800> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3800>, c) == 0, "offsetof(NetPacket_Repeat<0x3800>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3800>) == 1, "sizeof(NetPacket_Repeat<0x3800>) == 1"); + +template<> +struct NetPacket_Head<0x3801> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 whisper_id; + NetString<sizeof(CharName)> src_char_name; + NetString<sizeof(CharName)> dst_char_name; +}; +static_assert(offsetof(NetPacket_Head<0x3801>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3801>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3801>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3801>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3801>, whisper_id) == 4, "offsetof(NetPacket_Head<0x3801>, whisper_id) == 4"); +static_assert(offsetof(NetPacket_Head<0x3801>, src_char_name) == 8, "offsetof(NetPacket_Head<0x3801>, src_char_name) == 8"); +static_assert(offsetof(NetPacket_Head<0x3801>, dst_char_name) == 32, "offsetof(NetPacket_Head<0x3801>, dst_char_name) == 32"); +static_assert(sizeof(NetPacket_Head<0x3801>) == 56, "sizeof(NetPacket_Head<0x3801>) == 56"); +template<> +struct NetPacket_Repeat<0x3801> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3801>, c) == 0, "offsetof(NetPacket_Repeat<0x3801>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3801>) == 1, "sizeof(NetPacket_Repeat<0x3801>) == 1"); + +template<> +struct NetPacket_Fixed<0x3802> +{ + Little16 magic_packet_id; + NetString<sizeof(CharName)> sender_char_name; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3802>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3802>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3802>, sender_char_name) == 2, "offsetof(NetPacket_Fixed<0x3802>, sender_char_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3802>, flag) == 26, "offsetof(NetPacket_Fixed<0x3802>, flag) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x3802>) == 27, "sizeof(NetPacket_Fixed<0x3802>) == 27"); + +template<> +struct NetPacket_Head<0x3803> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> char_name; + Little16 min_gm_level; +}; +static_assert(offsetof(NetPacket_Head<0x3803>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3803>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3803>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3803>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3803>, char_name) == 4, "offsetof(NetPacket_Head<0x3803>, char_name) == 4"); +static_assert(offsetof(NetPacket_Head<0x3803>, min_gm_level) == 28, "offsetof(NetPacket_Head<0x3803>, min_gm_level) == 28"); +static_assert(sizeof(NetPacket_Head<0x3803>) == 30, "sizeof(NetPacket_Head<0x3803>) == 30"); +template<> +struct NetPacket_Repeat<0x3803> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3803>, c) == 0, "offsetof(NetPacket_Repeat<0x3803>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3803>) == 1, "sizeof(NetPacket_Repeat<0x3803>) == 1"); + +template<> +struct NetPacket_Head<0x3804> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3804>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3804>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3804>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3804>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3804>, account_id) == 4, "offsetof(NetPacket_Head<0x3804>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x3804>) == 8, "sizeof(NetPacket_Head<0x3804>) == 8"); +template<> +struct NetPacket_Repeat<0x3804> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x3804>, name) == 0, "offsetof(NetPacket_Repeat<0x3804>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x3804>, value) == 32, "offsetof(NetPacket_Repeat<0x3804>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x3804>) == 36, "sizeof(NetPacket_Repeat<0x3804>) == 36"); + +template<> +struct NetPacket_Payload<0x3810> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + Storage storage; +}; +static_assert(offsetof(NetPacket_Payload<0x3810>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x3810>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x3810>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x3810>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x3810>, account_id) == 4, "offsetof(NetPacket_Payload<0x3810>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x3810>, storage) == 8, "offsetof(NetPacket_Payload<0x3810>, storage) == 8"); + +template<> +struct NetPacket_Fixed<0x3811> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte unknown; +}; +static_assert(offsetof(NetPacket_Fixed<0x3811>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3811>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3811>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3811>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3811>, unknown) == 6, "offsetof(NetPacket_Fixed<0x3811>, unknown) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3811>) == 7, "sizeof(NetPacket_Fixed<0x3811>) == 7"); + +template<> +struct NetPacket_Fixed<0x3820> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte error; + Little32 party_id; + NetString<sizeof(PartyName)> party_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x3820>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3820>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3820>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, error) == 6, "offsetof(NetPacket_Fixed<0x3820>, error) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, party_id) == 7, "offsetof(NetPacket_Fixed<0x3820>, party_id) == 7"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, party_name) == 11, "offsetof(NetPacket_Fixed<0x3820>, party_name) == 11"); +static_assert(sizeof(NetPacket_Fixed<0x3820>) == 35, "sizeof(NetPacket_Fixed<0x3820>) == 35"); + +template<> +struct NetPacket_Head<0x3821> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 party_id; +}; +static_assert(offsetof(NetPacket_Head<0x3821>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3821>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3821>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3821>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3821>, party_id) == 4, "offsetof(NetPacket_Head<0x3821>, party_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x3821>) == 8, "sizeof(NetPacket_Head<0x3821>) == 8"); +template<> +struct NetPacket_Option<0x3821> +{ + PartyMost party_most; +}; +static_assert(offsetof(NetPacket_Option<0x3821>, party_most) == 0, "offsetof(NetPacket_Option<0x3821>, party_most) == 0"); + +template<> +struct NetPacket_Fixed<0x3822> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3822>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3822>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3822>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3822>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3822>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3822>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3822>, flag) == 10, "offsetof(NetPacket_Fixed<0x3822>, flag) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x3822>) == 11, "sizeof(NetPacket_Fixed<0x3822>) == 11"); + +template<> +struct NetPacket_Fixed<0x3823> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + Little16 exp; + Little16 item; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3823>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3823>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3823>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3823>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, exp) == 10, "offsetof(NetPacket_Fixed<0x3823>, exp) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, item) == 12, "offsetof(NetPacket_Fixed<0x3823>, item) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, flag) == 14, "offsetof(NetPacket_Fixed<0x3823>, flag) == 14"); +static_assert(sizeof(NetPacket_Fixed<0x3823>) == 15, "sizeof(NetPacket_Fixed<0x3823>) == 15"); + +template<> +struct NetPacket_Fixed<0x3824> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x3824>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3824>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3824>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3824>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3824>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3824>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3824>, char_name) == 10, "offsetof(NetPacket_Fixed<0x3824>, char_name) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x3824>) == 34, "sizeof(NetPacket_Fixed<0x3824>) == 34"); + +template<> +struct NetPacket_Fixed<0x3825> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(MapName)> map_name; + Byte online; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3825>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3825>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3825>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3825>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, map_name) == 10, "offsetof(NetPacket_Fixed<0x3825>, map_name) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, online) == 26, "offsetof(NetPacket_Fixed<0x3825>, online) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, level) == 27, "offsetof(NetPacket_Fixed<0x3825>, level) == 27"); +static_assert(sizeof(NetPacket_Fixed<0x3825>) == 29, "sizeof(NetPacket_Fixed<0x3825>) == 29"); + +template<> +struct NetPacket_Fixed<0x3826> +{ + Little16 magic_packet_id; + Little32 party_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3826>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3826>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3826>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3826>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3826>, flag) == 6, "offsetof(NetPacket_Fixed<0x3826>, flag) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3826>) == 7, "sizeof(NetPacket_Fixed<0x3826>) == 7"); + +template<> +struct NetPacket_Head<0x3827> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 party_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3827>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3827>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3827>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3827>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3827>, party_id) == 4, "offsetof(NetPacket_Head<0x3827>, party_id) == 4"); +static_assert(offsetof(NetPacket_Head<0x3827>, account_id) == 8, "offsetof(NetPacket_Head<0x3827>, account_id) == 8"); +static_assert(sizeof(NetPacket_Head<0x3827>) == 12, "sizeof(NetPacket_Head<0x3827>) == 12"); +template<> +struct NetPacket_Repeat<0x3827> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3827>, c) == 0, "offsetof(NetPacket_Repeat<0x3827>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3827>) == 1, "sizeof(NetPacket_Repeat<0x3827>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2af7> *network, Packet_Fixed<0x2af7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2af7> *native, NetPacket_Fixed<0x2af7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2af8> *network, Packet_Fixed<0x2af8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->account_pass, native.account_pass); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2af8> *native, NetPacket_Fixed<0x2af8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->account_pass, network.account_pass); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2af9> *network, Packet_Fixed<0x2af9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2af9> *native, NetPacket_Fixed<0x2af9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2afa> *network, Packet_Head<0x2afa> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2afa> *native, NetPacket_Head<0x2afa> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2afa> *network, Packet_Repeat<0x2afa> native) +{ + bool rv = true; + rv &= native_to_network(&network->map_name, native.map_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2afa> *native, NetPacket_Repeat<0x2afa> network) +{ + bool rv = true; + rv &= network_to_native(&native->map_name, network.map_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afa> *network, Packet_Fixed<0x2afa> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->source_item_id, native.source_item_id); + rv &= native_to_network(&network->dest_item_id, native.dest_item_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afa> *native, NetPacket_Fixed<0x2afa> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->source_item_id, network.source_item_id); + rv &= network_to_native(&native->dest_item_id, network.dest_item_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afb> *network, Packet_Fixed<0x2afb> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unknown, native.unknown); + rv &= native_to_network(&network->whisper_name, native.whisper_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afb> *native, NetPacket_Fixed<0x2afb> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unknown, network.unknown); + rv &= network_to_native(&native->whisper_name, network.whisper_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afc> *network, Packet_Fixed<0x2afc> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->ip, native.ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afc> *native, NetPacket_Fixed<0x2afc> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->ip, network.ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x2afd> *network, Packet_Payload<0x2afd> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->connect_until, native.connect_until); + rv &= native_to_network(&network->packet_tmw_version, native.packet_tmw_version); + rv &= native_to_network(&network->char_key, native.char_key); + rv &= native_to_network(&network->char_data, native.char_data); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x2afd> *native, NetPacket_Payload<0x2afd> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->connect_until, network.connect_until); + rv &= network_to_native(&native->packet_tmw_version, network.packet_tmw_version); + rv &= network_to_native(&native->char_key, network.char_key); + rv &= network_to_native(&native->char_data, network.char_data); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afe> *network, Packet_Fixed<0x2afe> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afe> *native, NetPacket_Fixed<0x2afe> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2aff> *network, Packet_Head<0x2aff> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->users, native.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2aff> *native, NetPacket_Head<0x2aff> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->users, network.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2aff> *network, Packet_Repeat<0x2aff> native) +{ + bool rv = true; + rv &= native_to_network(&network->char_id, native.char_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2aff> *native, NetPacket_Repeat<0x2aff> network) +{ + bool rv = true; + rv &= network_to_native(&native->char_id, network.char_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b00> *network, Packet_Fixed<0x2b00> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->users, native.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b00> *native, NetPacket_Fixed<0x2b00> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->users, network.users); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x2b01> *network, Packet_Payload<0x2b01> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->char_key, native.char_key); + rv &= native_to_network(&network->char_data, native.char_data); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x2b01> *native, NetPacket_Payload<0x2b01> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->char_key, network.char_key); + rv &= network_to_native(&native->char_data, network.char_data); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b02> *network, Packet_Fixed<0x2b02> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->ip, native.ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b02> *native, NetPacket_Fixed<0x2b02> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->ip, network.ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b03> *network, Packet_Fixed<0x2b03> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->unknown, native.unknown); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b03> *native, NetPacket_Fixed<0x2b03> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->unknown, network.unknown); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b04> *network, Packet_Head<0x2b04> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b04> *native, NetPacket_Head<0x2b04> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b04> *network, Packet_Repeat<0x2b04> native) +{ + bool rv = true; + rv &= native_to_network(&network->map_name, native.map_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b04> *native, NetPacket_Repeat<0x2b04> network) +{ + bool rv = true; + rv &= network_to_native(&native->map_name, network.map_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b05> *network, Packet_Fixed<0x2b05> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->map_ip, native.map_ip); + rv &= native_to_network(&network->map_port, native.map_port); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->client_ip, native.client_ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b05> *native, NetPacket_Fixed<0x2b05> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->map_ip, network.map_ip); + rv &= network_to_native(&native->map_port, network.map_port); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->client_ip, network.client_ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b06> *network, Packet_Fixed<0x2b06> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->error, native.error); + rv &= native_to_network(&network->unknown, native.unknown); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->map_ip, native.map_ip); + rv &= native_to_network(&network->map_port, native.map_port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b06> *native, NetPacket_Fixed<0x2b06> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->error, network.error); + rv &= network_to_native(&native->unknown, network.unknown); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->map_ip, network.map_ip); + rv &= network_to_native(&native->map_port, network.map_port); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b0a> *network, Packet_Head<0x2b0a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b0a> *native, NetPacket_Head<0x2b0a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b0a> *network, Packet_Repeat<0x2b0a> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b0a> *native, NetPacket_Repeat<0x2b0a> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0b> *network, Packet_Fixed<0x2b0b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0b> *native, NetPacket_Fixed<0x2b0b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0c> *network, Packet_Fixed<0x2b0c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->old_email, native.old_email); + rv &= native_to_network(&network->new_email, native.new_email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0c> *native, NetPacket_Fixed<0x2b0c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->old_email, network.old_email); + rv &= network_to_native(&native->new_email, network.new_email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0d> *network, Packet_Fixed<0x2b0d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0d> *native, NetPacket_Fixed<0x2b0d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0e> *network, Packet_Fixed<0x2b0e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->operation, native.operation); + rv &= native_to_network(&network->ban_add, native.ban_add); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0e> *native, NetPacket_Fixed<0x2b0e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->operation, network.operation); + rv &= network_to_native(&native->ban_add, network.ban_add); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0f> *network, Packet_Fixed<0x2b0f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->operation, native.operation); + rv &= native_to_network(&network->error, native.error); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0f> *native, NetPacket_Fixed<0x2b0f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->operation, network.operation); + rv &= network_to_native(&native->error, network.error); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b10> *network, Packet_Head<0x2b10> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b10> *native, NetPacket_Head<0x2b10> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b10> *network, Packet_Repeat<0x2b10> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b10> *native, NetPacket_Repeat<0x2b10> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b11> *network, Packet_Head<0x2b11> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b11> *native, NetPacket_Head<0x2b11> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b11> *network, Packet_Repeat<0x2b11> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b11> *native, NetPacket_Repeat<0x2b11> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b12> *network, Packet_Fixed<0x2b12> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->partner_id, native.partner_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b12> *native, NetPacket_Fixed<0x2b12> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->partner_id, network.partner_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b13> *network, Packet_Fixed<0x2b13> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b13> *native, NetPacket_Fixed<0x2b13> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b14> *network, Packet_Fixed<0x2b14> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->ban_not_status, native.ban_not_status); + rv &= native_to_network(&network->status_or_ban_until, native.status_or_ban_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b14> *native, NetPacket_Fixed<0x2b14> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->ban_not_status, network.ban_not_status); + rv &= network_to_native(&native->status_or_ban_until, network.status_or_ban_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b15> *network, Packet_Head<0x2b15> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b15> *native, NetPacket_Head<0x2b15> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b15> *network, Packet_Repeat<0x2b15> native) +{ + bool rv = true; + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b15> *native, NetPacket_Repeat<0x2b15> network) +{ + bool rv = true; + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b16> *network, Packet_Fixed<0x2b16> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b16> *native, NetPacket_Fixed<0x2b16> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3000> *network, Packet_Head<0x3000> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3000> *native, NetPacket_Head<0x3000> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3000> *network, Packet_Repeat<0x3000> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3000> *native, NetPacket_Repeat<0x3000> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3001> *network, Packet_Head<0x3001> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->from_char_name, native.from_char_name); + rv &= native_to_network(&network->to_char_name, native.to_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3001> *native, NetPacket_Head<0x3001> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->from_char_name, network.from_char_name); + rv &= network_to_native(&native->to_char_name, network.to_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3001> *network, Packet_Repeat<0x3001> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3001> *native, NetPacket_Repeat<0x3001> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3002> *network, Packet_Fixed<0x3002> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3002> *native, NetPacket_Fixed<0x3002> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3003> *network, Packet_Head<0x3003> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->min_gm_level, native.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3003> *native, NetPacket_Head<0x3003> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->min_gm_level, network.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3003> *network, Packet_Repeat<0x3003> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3003> *native, NetPacket_Repeat<0x3003> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3004> *network, Packet_Head<0x3004> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3004> *native, NetPacket_Head<0x3004> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3004> *network, Packet_Repeat<0x3004> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3004> *native, NetPacket_Repeat<0x3004> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3005> *network, Packet_Fixed<0x3005> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3005> *native, NetPacket_Fixed<0x3005> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3010> *network, Packet_Fixed<0x3010> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3010> *native, NetPacket_Fixed<0x3010> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x3011> *network, Packet_Payload<0x3011> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->storage, native.storage); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x3011> *native, NetPacket_Payload<0x3011> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->storage, network.storage); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3020> *network, Packet_Fixed<0x3020> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->party_name, native.party_name); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3020> *native, NetPacket_Fixed<0x3020> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->party_name, network.party_name); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3021> *network, Packet_Fixed<0x3021> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3021> *native, NetPacket_Fixed<0x3021> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3022> *network, Packet_Fixed<0x3022> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3022> *native, NetPacket_Fixed<0x3022> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3023> *network, Packet_Fixed<0x3023> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3023> *native, NetPacket_Fixed<0x3023> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3024> *network, Packet_Fixed<0x3024> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3024> *native, NetPacket_Fixed<0x3024> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3025> *network, Packet_Fixed<0x3025> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->online, native.online); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3025> *native, NetPacket_Fixed<0x3025> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->online, network.online); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3026> *network, Packet_Fixed<0x3026> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3026> *native, NetPacket_Fixed<0x3026> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3027> *network, Packet_Head<0x3027> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3027> *native, NetPacket_Head<0x3027> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3027> *network, Packet_Repeat<0x3027> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3027> *native, NetPacket_Repeat<0x3027> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3028> *network, Packet_Fixed<0x3028> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3028> *native, NetPacket_Fixed<0x3028> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3800> *network, Packet_Head<0x3800> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3800> *native, NetPacket_Head<0x3800> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3800> *network, Packet_Repeat<0x3800> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3800> *native, NetPacket_Repeat<0x3800> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3801> *network, Packet_Head<0x3801> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->whisper_id, native.whisper_id); + rv &= native_to_network(&network->src_char_name, native.src_char_name); + rv &= native_to_network(&network->dst_char_name, native.dst_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3801> *native, NetPacket_Head<0x3801> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->whisper_id, network.whisper_id); + rv &= network_to_native(&native->src_char_name, network.src_char_name); + rv &= network_to_native(&native->dst_char_name, network.dst_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3801> *network, Packet_Repeat<0x3801> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3801> *native, NetPacket_Repeat<0x3801> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3802> *network, Packet_Fixed<0x3802> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sender_char_name, native.sender_char_name); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3802> *native, NetPacket_Fixed<0x3802> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sender_char_name, network.sender_char_name); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3803> *network, Packet_Head<0x3803> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->min_gm_level, native.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3803> *native, NetPacket_Head<0x3803> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->min_gm_level, network.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3803> *network, Packet_Repeat<0x3803> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3803> *native, NetPacket_Repeat<0x3803> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3804> *network, Packet_Head<0x3804> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3804> *native, NetPacket_Head<0x3804> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3804> *network, Packet_Repeat<0x3804> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3804> *native, NetPacket_Repeat<0x3804> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x3810> *network, Packet_Payload<0x3810> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->storage, native.storage); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x3810> *native, NetPacket_Payload<0x3810> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->storage, network.storage); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3811> *network, Packet_Fixed<0x3811> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->unknown, native.unknown); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3811> *native, NetPacket_Fixed<0x3811> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->unknown, network.unknown); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3820> *network, Packet_Fixed<0x3820> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->error, native.error); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->party_name, native.party_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3820> *native, NetPacket_Fixed<0x3820> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->error, network.error); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->party_name, network.party_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3821> *network, Packet_Head<0x3821> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_id, native.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3821> *native, NetPacket_Head<0x3821> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_id, network.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Option<0x3821> *network, Packet_Option<0x3821> native) +{ + bool rv = true; + rv &= native_to_network(&network->party_most, native.party_most); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Option<0x3821> *native, NetPacket_Option<0x3821> network) +{ + bool rv = true; + rv &= network_to_native(&native->party_most, network.party_most); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3822> *network, Packet_Fixed<0x3822> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3822> *native, NetPacket_Fixed<0x3822> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3823> *network, Packet_Fixed<0x3823> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3823> *native, NetPacket_Fixed<0x3823> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3824> *network, Packet_Fixed<0x3824> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3824> *native, NetPacket_Fixed<0x3824> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3825> *network, Packet_Fixed<0x3825> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->online, native.online); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3825> *native, NetPacket_Fixed<0x3825> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->online, network.online); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3826> *network, Packet_Fixed<0x3826> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3826> *native, NetPacket_Fixed<0x3826> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3827> *network, Packet_Head<0x3827> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3827> *native, NetPacket_Head<0x3827> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3827> *network, Packet_Repeat<0x3827> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3827> *native, NetPacket_Repeat<0x3827> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + + +#pragma pack(pop) #endif // TMWA_PROTO2_CHAR_MAP_HPP diff --git a/src/proto2/char-user.hpp b/src/proto2/char-user.hpp index b31d9f1..3a51a2a 100644 --- a/src/proto2/char-user.hpp +++ b/src/proto2/char-user.hpp @@ -27,7 +27,587 @@ // This is a public protocol, and changes require client cooperation +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) +template<> +struct Packet_Fixed<0x0061> +{ + static const uint16_t PACKET_ID = 0x0061; + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountPass old_pass = {}; + AccountPass new_pass = {}; +}; + +template<> +struct Packet_Fixed<0x0062> +{ + static const uint16_t PACKET_ID = 0x0062; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t status = {}; +}; + +template<> +struct Packet_Fixed<0x0065> +{ + static const uint16_t PACKET_ID = 0x0065; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + uint16_t packet_tmw_version = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x0066> +{ + static const uint16_t PACKET_ID = 0x0066; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x0067> +{ + static const uint16_t PACKET_ID = 0x0067; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharName char_name = {}; + Stats6 stats = {}; + uint8_t slot = {}; + uint16_t hair_color = {}; + uint16_t hair_style = {}; +}; + +template<> +struct Packet_Fixed<0x0068> +{ + static const uint16_t PACKET_ID = 0x0068; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + AccountEmail email = {}; +}; + +template<> +struct Packet_Head<0x006b> +{ + static const uint16_t PACKET_ID = 0x006b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + VString<19> unused = {}; +}; +template<> +struct Packet_Repeat<0x006b> +{ + static const uint16_t PACKET_ID = 0x006b; + + CharSelect char_select = {}; +}; + +template<> +struct Packet_Fixed<0x006c> +{ + static const uint16_t PACKET_ID = 0x006c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x006d> +{ + static const uint16_t PACKET_ID = 0x006d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharSelect char_select = {}; +}; + +template<> +struct Packet_Fixed<0x006e> +{ + static const uint16_t PACKET_ID = 0x006e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x006f> +{ + static const uint16_t PACKET_ID = 0x006f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x0070> +{ + static const uint16_t PACKET_ID = 0x0070; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x0071> +{ + static const uint16_t PACKET_ID = 0x0071; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + MapName map_name = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; + + +template<> +struct NetPacket_Fixed<0x0061> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountPass)> old_pass; + NetString<sizeof(AccountPass)> new_pass; +}; +static_assert(offsetof(NetPacket_Fixed<0x0061>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0061>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0061>, old_pass) == 2, "offsetof(NetPacket_Fixed<0x0061>, old_pass) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0061>, new_pass) == 26, "offsetof(NetPacket_Fixed<0x0061>, new_pass) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x0061>) == 50, "sizeof(NetPacket_Fixed<0x0061>) == 50"); + +template<> +struct NetPacket_Fixed<0x0062> +{ + Little16 magic_packet_id; + Byte status; +}; +static_assert(offsetof(NetPacket_Fixed<0x0062>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0062>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0062>, status) == 2, "offsetof(NetPacket_Fixed<0x0062>, status) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0062>) == 3, "sizeof(NetPacket_Fixed<0x0062>) == 3"); + +template<> +struct NetPacket_Fixed<0x0065> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + Little16 packet_tmw_version; + Byte sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x0065>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0065>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0065>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x0065>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x0065>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, packet_tmw_version) == 14, "offsetof(NetPacket_Fixed<0x0065>, packet_tmw_version) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, sex) == 16, "offsetof(NetPacket_Fixed<0x0065>, sex) == 16"); +static_assert(sizeof(NetPacket_Fixed<0x0065>) == 17, "sizeof(NetPacket_Fixed<0x0065>) == 17"); + +template<> +struct NetPacket_Fixed<0x0066> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x0066>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0066>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0066>, code) == 2, "offsetof(NetPacket_Fixed<0x0066>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0066>) == 3, "sizeof(NetPacket_Fixed<0x0066>) == 3"); + +template<> +struct NetPacket_Fixed<0x0067> +{ + Little16 magic_packet_id; + NetString<sizeof(CharName)> char_name; + NetStats6 stats; + Byte slot; + Little16 hair_color; + Little16 hair_style; +}; +static_assert(offsetof(NetPacket_Fixed<0x0067>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0067>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, char_name) == 2, "offsetof(NetPacket_Fixed<0x0067>, char_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, stats) == 26, "offsetof(NetPacket_Fixed<0x0067>, stats) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, slot) == 32, "offsetof(NetPacket_Fixed<0x0067>, slot) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, hair_color) == 33, "offsetof(NetPacket_Fixed<0x0067>, hair_color) == 33"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, hair_style) == 35, "offsetof(NetPacket_Fixed<0x0067>, hair_style) == 35"); +static_assert(sizeof(NetPacket_Fixed<0x0067>) == 37, "sizeof(NetPacket_Fixed<0x0067>) == 37"); + +template<> +struct NetPacket_Fixed<0x0068> +{ + Little16 magic_packet_id; + Little32 char_id; + NetString<sizeof(AccountEmail)> email; +}; +static_assert(offsetof(NetPacket_Fixed<0x0068>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0068>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0068>, char_id) == 2, "offsetof(NetPacket_Fixed<0x0068>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0068>, email) == 6, "offsetof(NetPacket_Fixed<0x0068>, email) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0068>) == 46, "sizeof(NetPacket_Fixed<0x0068>) == 46"); + +template<> +struct NetPacket_Head<0x006b> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(VString<19>)> unused; +}; +static_assert(offsetof(NetPacket_Head<0x006b>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x006b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x006b>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x006b>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x006b>, unused) == 4, "offsetof(NetPacket_Head<0x006b>, unused) == 4"); +static_assert(sizeof(NetPacket_Head<0x006b>) == 24, "sizeof(NetPacket_Head<0x006b>) == 24"); +template<> +struct NetPacket_Repeat<0x006b> +{ + NetCharSelect char_select; +}; +static_assert(offsetof(NetPacket_Repeat<0x006b>, char_select) == 0, "offsetof(NetPacket_Repeat<0x006b>, char_select) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x006b>) == 106, "sizeof(NetPacket_Repeat<0x006b>) == 106"); + +template<> +struct NetPacket_Fixed<0x006c> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x006c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006c>, code) == 2, "offsetof(NetPacket_Fixed<0x006c>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x006c>) == 3, "sizeof(NetPacket_Fixed<0x006c>) == 3"); + +template<> +struct NetPacket_Fixed<0x006d> +{ + Little16 magic_packet_id; + NetCharSelect char_select; +}; +static_assert(offsetof(NetPacket_Fixed<0x006d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006d>, char_select) == 2, "offsetof(NetPacket_Fixed<0x006d>, char_select) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x006d>) == 108, "sizeof(NetPacket_Fixed<0x006d>) == 108"); + +template<> +struct NetPacket_Fixed<0x006e> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x006e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006e>, code) == 2, "offsetof(NetPacket_Fixed<0x006e>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x006e>) == 3, "sizeof(NetPacket_Fixed<0x006e>) == 3"); + +template<> +struct NetPacket_Fixed<0x006f> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x006f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006f>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x006f>) == 2, "sizeof(NetPacket_Fixed<0x006f>) == 2"); + +template<> +struct NetPacket_Fixed<0x0070> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x0070>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0070>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0070>, code) == 2, "offsetof(NetPacket_Fixed<0x0070>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0070>) == 3, "sizeof(NetPacket_Fixed<0x0070>) == 3"); + +template<> +struct NetPacket_Fixed<0x0071> +{ + Little16 magic_packet_id; + Little32 char_id; + NetString<sizeof(MapName)> map_name; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Fixed<0x0071>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0071>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, char_id) == 2, "offsetof(NetPacket_Fixed<0x0071>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, map_name) == 6, "offsetof(NetPacket_Fixed<0x0071>, map_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, ip) == 22, "offsetof(NetPacket_Fixed<0x0071>, ip) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, port) == 26, "offsetof(NetPacket_Fixed<0x0071>, port) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x0071>) == 28, "sizeof(NetPacket_Fixed<0x0071>) == 28"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0061> *network, Packet_Fixed<0x0061> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->old_pass, native.old_pass); + rv &= native_to_network(&network->new_pass, native.new_pass); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0061> *native, NetPacket_Fixed<0x0061> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->old_pass, network.old_pass); + rv &= network_to_native(&native->new_pass, network.new_pass); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0062> *network, Packet_Fixed<0x0062> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->status, native.status); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0062> *native, NetPacket_Fixed<0x0062> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->status, network.status); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0065> *network, Packet_Fixed<0x0065> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->packet_tmw_version, native.packet_tmw_version); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0065> *native, NetPacket_Fixed<0x0065> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->packet_tmw_version, network.packet_tmw_version); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0066> *network, Packet_Fixed<0x0066> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0066> *native, NetPacket_Fixed<0x0066> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0067> *network, Packet_Fixed<0x0067> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->stats, native.stats); + rv &= native_to_network(&network->slot, native.slot); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->hair_style, native.hair_style); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0067> *native, NetPacket_Fixed<0x0067> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->stats, network.stats); + rv &= network_to_native(&native->slot, network.slot); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->hair_style, network.hair_style); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0068> *network, Packet_Fixed<0x0068> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->email, native.email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0068> *native, NetPacket_Fixed<0x0068> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->email, network.email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x006b> *network, Packet_Head<0x006b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x006b> *native, NetPacket_Head<0x006b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x006b> *network, Packet_Repeat<0x006b> native) +{ + bool rv = true; + rv &= native_to_network(&network->char_select, native.char_select); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x006b> *native, NetPacket_Repeat<0x006b> network) +{ + bool rv = true; + rv &= network_to_native(&native->char_select, network.char_select); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006c> *network, Packet_Fixed<0x006c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006c> *native, NetPacket_Fixed<0x006c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006d> *network, Packet_Fixed<0x006d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_select, native.char_select); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006d> *native, NetPacket_Fixed<0x006d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_select, network.char_select); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006e> *network, Packet_Fixed<0x006e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006e> *native, NetPacket_Fixed<0x006e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006f> *network, Packet_Fixed<0x006f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006f> *native, NetPacket_Fixed<0x006f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0070> *network, Packet_Fixed<0x0070> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0070> *native, NetPacket_Fixed<0x0070> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0071> *network, Packet_Fixed<0x0071> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0071> *native, NetPacket_Fixed<0x0071> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} + + +#pragma pack(pop) #endif // TMWA_PROTO2_CHAR_USER_HPP diff --git a/src/proto2/fwd.hpp b/src/proto2/fwd.hpp index f050ab4..169f5e2 100644 --- a/src/proto2/fwd.hpp +++ b/src/proto2/fwd.hpp @@ -25,10 +25,14 @@ template<uint16_t PACKET_ID> class Packet_Fixed; template<uint16_t PACKET_ID> class NetPacket_Fixed; +template<uint16_t PACKET_ID> class Packet_Payload; +template<uint16_t PACKET_ID> class NetPacket_Payload; template<uint16_t PACKET_ID> class Packet_Head; template<uint16_t PACKET_ID> class NetPacket_Head; template<uint16_t PACKET_ID> class Packet_Repeat; template<uint16_t PACKET_ID> class NetPacket_Repeat; +template<uint16_t PACKET_ID> class Packet_Option; +template<uint16_t PACKET_ID> class NetPacket_Option; template<> struct Packet_Fixed<0x2709>; @@ -445,12 +449,458 @@ struct Packet_Fixed<0x006a>; template<> struct NetPacket_Fixed<0x006a>; + template<> -struct Packet_Fixed<0x0081>; +struct Packet_Fixed<0x2af7>; template<> -struct NetPacket_Fixed<0x0081>; +struct NetPacket_Fixed<0x2af7>; + +template<> +struct Packet_Fixed<0x2af8>; +template<> +struct NetPacket_Fixed<0x2af8>; + +template<> +struct Packet_Fixed<0x2af9>; +template<> +struct NetPacket_Fixed<0x2af9>; + +template<> +struct Packet_Head<0x2afa>; +template<> +struct NetPacket_Head<0x2afa>; +template<> +struct Packet_Repeat<0x2afa>; +template<> +struct NetPacket_Repeat<0x2afa>; + +template<> +struct Packet_Fixed<0x2afa>; +template<> +struct NetPacket_Fixed<0x2afa>; + +template<> +struct Packet_Fixed<0x2afb>; +template<> +struct NetPacket_Fixed<0x2afb>; + +template<> +struct Packet_Fixed<0x2afc>; +template<> +struct NetPacket_Fixed<0x2afc>; + +template<> +struct Packet_Payload<0x2afd>; +template<> +struct NetPacket_Payload<0x2afd>; + +template<> +struct Packet_Fixed<0x2afe>; +template<> +struct NetPacket_Fixed<0x2afe>; + +template<> +struct Packet_Head<0x2aff>; +template<> +struct NetPacket_Head<0x2aff>; +template<> +struct Packet_Repeat<0x2aff>; +template<> +struct NetPacket_Repeat<0x2aff>; + +template<> +struct Packet_Fixed<0x2b00>; +template<> +struct NetPacket_Fixed<0x2b00>; + +template<> +struct Packet_Payload<0x2b01>; +template<> +struct NetPacket_Payload<0x2b01>; + +template<> +struct Packet_Fixed<0x2b02>; +template<> +struct NetPacket_Fixed<0x2b02>; + +template<> +struct Packet_Fixed<0x2b03>; +template<> +struct NetPacket_Fixed<0x2b03>; + +template<> +struct Packet_Head<0x2b04>; +template<> +struct NetPacket_Head<0x2b04>; +template<> +struct Packet_Repeat<0x2b04>; +template<> +struct NetPacket_Repeat<0x2b04>; + +template<> +struct Packet_Fixed<0x2b05>; +template<> +struct NetPacket_Fixed<0x2b05>; + +template<> +struct Packet_Fixed<0x2b06>; +template<> +struct NetPacket_Fixed<0x2b06>; + +template<> +struct Packet_Head<0x2b0a>; +template<> +struct NetPacket_Head<0x2b0a>; +template<> +struct Packet_Repeat<0x2b0a>; +template<> +struct NetPacket_Repeat<0x2b0a>; + +template<> +struct Packet_Fixed<0x2b0b>; +template<> +struct NetPacket_Fixed<0x2b0b>; + +template<> +struct Packet_Fixed<0x2b0c>; +template<> +struct NetPacket_Fixed<0x2b0c>; + +template<> +struct Packet_Fixed<0x2b0d>; +template<> +struct NetPacket_Fixed<0x2b0d>; + +template<> +struct Packet_Fixed<0x2b0e>; +template<> +struct NetPacket_Fixed<0x2b0e>; + +template<> +struct Packet_Fixed<0x2b0f>; +template<> +struct NetPacket_Fixed<0x2b0f>; + +template<> +struct Packet_Head<0x2b10>; +template<> +struct NetPacket_Head<0x2b10>; +template<> +struct Packet_Repeat<0x2b10>; +template<> +struct NetPacket_Repeat<0x2b10>; + +template<> +struct Packet_Head<0x2b11>; +template<> +struct NetPacket_Head<0x2b11>; +template<> +struct Packet_Repeat<0x2b11>; +template<> +struct NetPacket_Repeat<0x2b11>; +template<> +struct Packet_Fixed<0x2b12>; +template<> +struct NetPacket_Fixed<0x2b12>; +template<> +struct Packet_Fixed<0x2b13>; +template<> +struct NetPacket_Fixed<0x2b13>; + +template<> +struct Packet_Fixed<0x2b14>; +template<> +struct NetPacket_Fixed<0x2b14>; + +template<> +struct Packet_Head<0x2b15>; +template<> +struct NetPacket_Head<0x2b15>; +template<> +struct Packet_Repeat<0x2b15>; +template<> +struct NetPacket_Repeat<0x2b15>; + +template<> +struct Packet_Fixed<0x2b16>; +template<> +struct NetPacket_Fixed<0x2b16>; + +template<> +struct Packet_Head<0x3000>; +template<> +struct NetPacket_Head<0x3000>; +template<> +struct Packet_Repeat<0x3000>; +template<> +struct NetPacket_Repeat<0x3000>; + +template<> +struct Packet_Head<0x3001>; +template<> +struct NetPacket_Head<0x3001>; +template<> +struct Packet_Repeat<0x3001>; +template<> +struct NetPacket_Repeat<0x3001>; + +template<> +struct Packet_Fixed<0x3002>; +template<> +struct NetPacket_Fixed<0x3002>; + +template<> +struct Packet_Head<0x3003>; +template<> +struct NetPacket_Head<0x3003>; +template<> +struct Packet_Repeat<0x3003>; +template<> +struct NetPacket_Repeat<0x3003>; + +template<> +struct Packet_Head<0x3004>; +template<> +struct NetPacket_Head<0x3004>; +template<> +struct Packet_Repeat<0x3004>; +template<> +struct NetPacket_Repeat<0x3004>; + +template<> +struct Packet_Fixed<0x3005>; +template<> +struct NetPacket_Fixed<0x3005>; + +template<> +struct Packet_Fixed<0x3010>; +template<> +struct NetPacket_Fixed<0x3010>; + +template<> +struct Packet_Payload<0x3011>; +template<> +struct NetPacket_Payload<0x3011>; + +template<> +struct Packet_Fixed<0x3020>; +template<> +struct NetPacket_Fixed<0x3020>; + +template<> +struct Packet_Fixed<0x3021>; +template<> +struct NetPacket_Fixed<0x3021>; + +template<> +struct Packet_Fixed<0x3022>; +template<> +struct NetPacket_Fixed<0x3022>; + +template<> +struct Packet_Fixed<0x3023>; +template<> +struct NetPacket_Fixed<0x3023>; + +template<> +struct Packet_Fixed<0x3024>; +template<> +struct NetPacket_Fixed<0x3024>; + +template<> +struct Packet_Fixed<0x3025>; +template<> +struct NetPacket_Fixed<0x3025>; + +template<> +struct Packet_Fixed<0x3026>; +template<> +struct NetPacket_Fixed<0x3026>; + +template<> +struct Packet_Head<0x3027>; +template<> +struct NetPacket_Head<0x3027>; +template<> +struct Packet_Repeat<0x3027>; +template<> +struct NetPacket_Repeat<0x3027>; + +template<> +struct Packet_Fixed<0x3028>; +template<> +struct NetPacket_Fixed<0x3028>; + +template<> +struct Packet_Head<0x3800>; +template<> +struct NetPacket_Head<0x3800>; +template<> +struct Packet_Repeat<0x3800>; +template<> +struct NetPacket_Repeat<0x3800>; + +template<> +struct Packet_Head<0x3801>; +template<> +struct NetPacket_Head<0x3801>; +template<> +struct Packet_Repeat<0x3801>; +template<> +struct NetPacket_Repeat<0x3801>; + +template<> +struct Packet_Fixed<0x3802>; +template<> +struct NetPacket_Fixed<0x3802>; + +template<> +struct Packet_Head<0x3803>; +template<> +struct NetPacket_Head<0x3803>; +template<> +struct Packet_Repeat<0x3803>; +template<> +struct NetPacket_Repeat<0x3803>; + +template<> +struct Packet_Head<0x3804>; +template<> +struct NetPacket_Head<0x3804>; +template<> +struct Packet_Repeat<0x3804>; +template<> +struct NetPacket_Repeat<0x3804>; + +template<> +struct Packet_Payload<0x3810>; +template<> +struct NetPacket_Payload<0x3810>; + +template<> +struct Packet_Fixed<0x3811>; +template<> +struct NetPacket_Fixed<0x3811>; + +template<> +struct Packet_Fixed<0x3820>; +template<> +struct NetPacket_Fixed<0x3820>; + +template<> +struct Packet_Head<0x3821>; +template<> +struct NetPacket_Head<0x3821>; +template<> +struct Packet_Option<0x3821>; +template<> +struct NetPacket_Option<0x3821>; + +template<> +struct Packet_Fixed<0x3822>; +template<> +struct NetPacket_Fixed<0x3822>; + +template<> +struct Packet_Fixed<0x3823>; +template<> +struct NetPacket_Fixed<0x3823>; + +template<> +struct Packet_Fixed<0x3824>; +template<> +struct NetPacket_Fixed<0x3824>; + +template<> +struct Packet_Fixed<0x3825>; +template<> +struct NetPacket_Fixed<0x3825>; + +template<> +struct Packet_Fixed<0x3826>; +template<> +struct NetPacket_Fixed<0x3826>; + +template<> +struct Packet_Head<0x3827>; +template<> +struct NetPacket_Head<0x3827>; +template<> +struct Packet_Repeat<0x3827>; +template<> +struct NetPacket_Repeat<0x3827>; + + +template<> +struct Packet_Fixed<0x0061>; +template<> +struct NetPacket_Fixed<0x0061>; + +template<> +struct Packet_Fixed<0x0062>; +template<> +struct NetPacket_Fixed<0x0062>; + +template<> +struct Packet_Fixed<0x0065>; +template<> +struct NetPacket_Fixed<0x0065>; + +template<> +struct Packet_Fixed<0x0066>; +template<> +struct NetPacket_Fixed<0x0066>; + +template<> +struct Packet_Fixed<0x0067>; +template<> +struct NetPacket_Fixed<0x0067>; + +template<> +struct Packet_Fixed<0x0068>; +template<> +struct NetPacket_Fixed<0x0068>; + +template<> +struct Packet_Head<0x006b>; +template<> +struct NetPacket_Head<0x006b>; +template<> +struct Packet_Repeat<0x006b>; +template<> +struct NetPacket_Repeat<0x006b>; + +template<> +struct Packet_Fixed<0x006c>; +template<> +struct NetPacket_Fixed<0x006c>; + +template<> +struct Packet_Fixed<0x006d>; +template<> +struct NetPacket_Fixed<0x006d>; + +template<> +struct Packet_Fixed<0x006e>; +template<> +struct NetPacket_Fixed<0x006e>; + +template<> +struct Packet_Fixed<0x006f>; +template<> +struct NetPacket_Fixed<0x006f>; + +template<> +struct Packet_Fixed<0x0070>; +template<> +struct NetPacket_Fixed<0x0070>; + +template<> +struct Packet_Fixed<0x0071>; +template<> +struct NetPacket_Fixed<0x0071>; template<> @@ -460,6 +910,11 @@ struct NetPacket_Fixed<0x0212>; template<> +struct Packet_Fixed<0x0081>; +template<> +struct NetPacket_Fixed<0x0081>; + +template<> struct Packet_Fixed<0x7530>; template<> struct NetPacket_Fixed<0x7530>; diff --git a/src/proto2/include_enums_test.cpp b/src/proto2/include_enums_test.cpp index 2b9ed36..49b4a95 100644 --- a/src/proto2/include_enums_test.cpp +++ b/src/proto2/include_enums_test.cpp @@ -21,3 +21,4 @@ #include "../poison.hpp" using Test_SEX = SEX; +using Test_Option = Option; diff --git a/src/proto2/include_mmo_test.cpp b/src/proto2/include_mmo_test.cpp new file mode 100644 index 0000000..feb2de2 --- /dev/null +++ b/src/proto2/include_mmo_test.cpp @@ -0,0 +1,26 @@ +#include "../mmo/mmo.hpp" +// include_mmo_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +using Test_CharKey = CharKey; +using Test_CharData = CharData; +using Test_PartyMost = PartyMost; +using Test_Storage = Storage; diff --git a/src/proto2/include_strs_test.cpp b/src/proto2/include_strs_test.cpp index 5bf516c..eeaed7c 100644 --- a/src/proto2/include_strs_test.cpp +++ b/src/proto2/include_strs_test.cpp @@ -24,4 +24,7 @@ using Test_AccountName = AccountName; using Test_AccountPass = AccountPass; using Test_AccountEmail = AccountEmail; using Test_ServerName = ServerName; +using Test_PartyName = PartyName; using Test_VarName = VarName; +using Test_CharName = CharName; +using Test_MapName = MapName; diff --git a/src/proto2/login-admin.hpp b/src/proto2/login-admin.hpp index f5cf0f7..7876d1d 100644 --- a/src/proto2/login-admin.hpp +++ b/src/proto2/login-admin.hpp @@ -27,6 +27,9 @@ // This is an internal protocol, and can be changed without notice +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) + template<> struct Packet_Head<0x2726> { @@ -2164,4 +2167,6 @@ bool network_to_native(Packet_Fixed<0x7955> *native, NetPacket_Fixed<0x7955> net } +#pragma pack(pop) + #endif // TMWA_PROTO2_LOGIN_ADMIN_HPP diff --git a/src/proto2/login-char.hpp b/src/proto2/login-char.hpp index 6b2004d..14d19a9 100644 --- a/src/proto2/login-char.hpp +++ b/src/proto2/login-char.hpp @@ -27,6 +27,9 @@ // This is an internal protocol, and can be changed without notice +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) + template<> struct Packet_Fixed<0x2709> { @@ -206,7 +209,7 @@ struct Packet_Fixed<0x2725> // TODO remove this uint16_t magic_packet_id = PACKET_ID; AccountId account_id = {}; - HumanTimeDiff deltas = {}; + HumanTimeDiff ban_add = {}; }; template<> @@ -532,11 +535,11 @@ struct NetPacket_Fixed<0x2725> { Little16 magic_packet_id; Little32 account_id; - NetHumanTimeDiff deltas; + NetHumanTimeDiff ban_add; }; static_assert(offsetof(NetPacket_Fixed<0x2725>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2725>, magic_packet_id) == 0"); static_assert(offsetof(NetPacket_Fixed<0x2725>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2725>, account_id) == 2"); -static_assert(offsetof(NetPacket_Fixed<0x2725>, deltas) == 6, "offsetof(NetPacket_Fixed<0x2725>, deltas) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2725>, ban_add) == 6, "offsetof(NetPacket_Fixed<0x2725>, ban_add) == 6"); static_assert(sizeof(NetPacket_Fixed<0x2725>) == 18, "sizeof(NetPacket_Fixed<0x2725>) == 18"); template<> @@ -975,7 +978,7 @@ bool native_to_network(NetPacket_Fixed<0x2725> *network, Packet_Fixed<0x2725> na bool rv = true; rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); rv &= native_to_network(&network->account_id, native.account_id); - rv &= native_to_network(&network->deltas, native.deltas); + rv &= native_to_network(&network->ban_add, native.ban_add); return rv; } inline __attribute__((warn_unused_result)) @@ -984,7 +987,7 @@ bool network_to_native(Packet_Fixed<0x2725> *native, NetPacket_Fixed<0x2725> net bool rv = true; rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); rv &= network_to_native(&native->account_id, network.account_id); - rv &= network_to_native(&native->deltas, network.deltas); + rv &= network_to_native(&native->ban_add, network.ban_add); return rv; } @@ -1204,4 +1207,6 @@ bool network_to_native(Packet_Fixed<0x2741> *native, NetPacket_Fixed<0x2741> net } +#pragma pack(pop) + #endif // TMWA_PROTO2_LOGIN_CHAR_HPP diff --git a/src/proto2/login-user.hpp b/src/proto2/login-user.hpp index dbdf322..7f0e5ea 100644 --- a/src/proto2/login-user.hpp +++ b/src/proto2/login-user.hpp @@ -27,6 +27,9 @@ // This is a public protocol, and changes require client cooperation +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) + template<> struct Packet_Head<0x0063> { @@ -99,16 +102,6 @@ struct Packet_Fixed<0x006a> timestamp_seconds_buffer error_message = {}; }; -template<> -struct Packet_Fixed<0x0081> -{ - static const uint16_t PACKET_ID = 0x0081; - - // TODO remove this - uint16_t magic_packet_id = PACKET_ID; - uint8_t error_code = {}; -}; - template<> struct NetPacket_Head<0x0063> @@ -196,16 +189,6 @@ static_assert(offsetof(NetPacket_Fixed<0x006a>, error_code) == 2, "offsetof(NetP static_assert(offsetof(NetPacket_Fixed<0x006a>, error_message) == 3, "offsetof(NetPacket_Fixed<0x006a>, error_message) == 3"); static_assert(sizeof(NetPacket_Fixed<0x006a>) == 23, "sizeof(NetPacket_Fixed<0x006a>) == 23"); -template<> -struct NetPacket_Fixed<0x0081> -{ - Little16 magic_packet_id; - Byte error_code; -}; -static_assert(offsetof(NetPacket_Fixed<0x0081>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0081>, magic_packet_id) == 0"); -static_assert(offsetof(NetPacket_Fixed<0x0081>, error_code) == 2, "offsetof(NetPacket_Fixed<0x0081>, error_code) == 2"); -static_assert(sizeof(NetPacket_Fixed<0x0081>) == 3, "sizeof(NetPacket_Fixed<0x0081>) == 3"); - inline __attribute__((warn_unused_result)) bool native_to_network(NetPacket_Head<0x0063> *network, Packet_Head<0x0063> native) @@ -335,22 +318,7 @@ bool network_to_native(Packet_Fixed<0x006a> *native, NetPacket_Fixed<0x006a> net return rv; } -inline __attribute__((warn_unused_result)) -bool native_to_network(NetPacket_Fixed<0x0081> *network, Packet_Fixed<0x0081> native) -{ - bool rv = true; - rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); - rv &= native_to_network(&network->error_code, native.error_code); - return rv; -} -inline __attribute__((warn_unused_result)) -bool network_to_native(Packet_Fixed<0x0081> *native, NetPacket_Fixed<0x0081> network) -{ - bool rv = true; - rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); - rv &= network_to_native(&native->error_code, network.error_code); - return rv; -} +#pragma pack(pop) #endif // TMWA_PROTO2_LOGIN_USER_HPP diff --git a/src/proto2/map-user.hpp b/src/proto2/map-user.hpp index d68f436..08d19fa 100644 --- a/src/proto2/map-user.hpp +++ b/src/proto2/map-user.hpp @@ -27,6 +27,9 @@ // This is a public protocol, and changes require client cooperation +// this is only needed for the payload packet right now, and that needs to die +#pragma pack(push, 1) + template<> struct Packet_Fixed<0x0212> { @@ -87,4 +90,6 @@ bool network_to_native(Packet_Fixed<0x0212> *native, NetPacket_Fixed<0x0212> net } +#pragma pack(pop) + #endif // TMWA_PROTO2_MAP_USER_HPP diff --git a/src/proto2/types.hpp b/src/proto2/types.hpp index 92413e3..594be22 100644 --- a/src/proto2/types.hpp +++ b/src/proto2/types.hpp @@ -29,6 +29,7 @@ # include "../mmo/enums.hpp" # include "../mmo/human_time_diff.hpp" # include "../mmo/ids.hpp" +# include "../mmo/mmo.hpp" # include "../mmo/strs.hpp" # include "../mmo/utils.hpp" # include "../mmo/version.hpp" @@ -71,6 +72,38 @@ bool network_to_native(VString<N-1> *native, NetString<N> network) return true; } +inline +bool native_to_network(NetString<24> *network, CharName native) +{ + VString<23> tmp = native.to__actual(); + bool rv = native_to_network(network, tmp); + return rv; +} +inline +bool network_to_native(CharName *native, NetString<24> network) +{ + VString<23> tmp; + bool rv = network_to_native(&tmp, network); + *native = stringish<CharName>(tmp); + return rv; +} + +inline +bool native_to_network(NetString<16> *network, MapName native) +{ + XString tmp = native; + bool rv = native_to_network(network, VString<15>(tmp)); + return rv; +} +inline +bool network_to_native(MapName *native, NetString<16> network) +{ + VString<15> tmp; + bool rv = network_to_native(&tmp, network); + *native = stringish<MapName>(tmp); + return rv; +} + template<class T, size_t N> struct SkewedLength { @@ -109,6 +142,24 @@ bool network_to_native(SEX *native, Byte network) return rv; } inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, Option native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Option *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<Option>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) bool native_to_network(Little16 *network, Species native) { bool rv = true; @@ -316,4 +367,244 @@ bool network_to_native(VERSION_2 *native, Byte network) // TODO this is what really should be doing a checked cast return rv; } +struct Stats6 +{ + uint8_t str = {}; + uint8_t agi = {}; + uint8_t vit = {}; + uint8_t int_ = {}; + uint8_t dex = {}; + uint8_t luk = {}; +}; +struct NetStats6 +{ + Byte str; + Byte agi; + Byte vit; + Byte int_; + Byte dex; + Byte luk; +}; +static_assert(offsetof(NetStats6, str) == 0, "offsetof(NetStats6, str) == 0"); +static_assert(offsetof(NetStats6, agi) == 1, "offsetof(NetStats6, agi) == 1"); +static_assert(offsetof(NetStats6, vit) == 2, "offsetof(NetStats6, vit) == 2"); +static_assert(offsetof(NetStats6, int_) == 3, "offsetof(NetStats6, int_) == 3"); +static_assert(offsetof(NetStats6, dex) == 4, "offsetof(NetStats6, dex) == 4"); +static_assert(offsetof(NetStats6, luk) == 5, "offsetof(NetStats6, luk) == 5"); +static_assert(sizeof(NetStats6) == 6, "sizeof(NetStats6) == 6"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetStats6 *network, Stats6 native) +{ + bool rv = true; + rv &= native_to_network(&network->str, native.str); + rv &= native_to_network(&network->agi, native.agi); + rv &= native_to_network(&network->vit, native.vit); + rv &= native_to_network(&network->int_, native.int_); + rv &= native_to_network(&network->dex, native.dex); + rv &= native_to_network(&network->luk, native.luk); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Stats6 *native, NetStats6 network) +{ + bool rv = true; + rv &= network_to_native(&native->str, network.str); + rv &= network_to_native(&native->agi, network.agi); + rv &= network_to_native(&native->vit, network.vit); + rv &= network_to_native(&native->int_, network.int_); + rv &= network_to_native(&native->dex, network.dex); + rv &= network_to_native(&native->luk, network.luk); + return rv; +} + +struct CharSelect +{ + CharId char_id = {}; + uint32_t base_exp = {}; + uint32_t zeny = {}; + uint32_t job_exp = {}; + uint32_t job_level = {}; + ItemNameId shoes = {}; + ItemNameId gloves = {}; + ItemNameId cape = {}; + ItemNameId misc1 = {}; + Option option = {}; + uint16_t unused = {}; + uint32_t karma = {}; + uint32_t manner = {}; + uint16_t status_point = {}; + uint16_t hp = {}; + uint16_t max_hp = {}; + uint16_t sp = {}; + uint16_t max_sp = {}; + uint16_t speed = {}; + Species species = {}; + uint16_t hair_style = {}; + uint16_t weapon = {}; + uint16_t base_level = {}; + uint16_t skill_point = {}; + ItemNameId head_bottom = {}; + ItemNameId shield = {}; + ItemNameId head_top = {}; + ItemNameId head_mid = {}; + uint16_t hair_color = {}; + ItemNameId misc2 = {}; + CharName char_name = {}; + Stats6 stats = {}; + uint8_t char_num = {}; + uint8_t unused2 = {}; +}; +struct NetCharSelect +{ + Little32 char_id; + Little32 base_exp; + Little32 zeny; + Little32 job_exp; + Little32 job_level; + Little16 shoes; + Little16 gloves; + Little16 cape; + Little16 misc1; + Little16 option; + Little16 unused; + Little32 karma; + Little32 manner; + Little16 status_point; + Little16 hp; + Little16 max_hp; + Little16 sp; + Little16 max_sp; + Little16 speed; + Little16 species; + Little16 hair_style; + Little16 weapon; + Little16 base_level; + Little16 skill_point; + Little16 head_bottom; + Little16 shield; + Little16 head_top; + Little16 head_mid; + Little16 hair_color; + Little16 misc2; + NetString<sizeof(CharName)> char_name; + NetStats6 stats; + Byte char_num; + Byte unused2; +}; +static_assert(offsetof(NetCharSelect, char_id) == 0, "offsetof(NetCharSelect, char_id) == 0"); +static_assert(offsetof(NetCharSelect, base_exp) == 4, "offsetof(NetCharSelect, base_exp) == 4"); +static_assert(offsetof(NetCharSelect, zeny) == 8, "offsetof(NetCharSelect, zeny) == 8"); +static_assert(offsetof(NetCharSelect, job_exp) == 12, "offsetof(NetCharSelect, job_exp) == 12"); +static_assert(offsetof(NetCharSelect, job_level) == 16, "offsetof(NetCharSelect, job_level) == 16"); +static_assert(offsetof(NetCharSelect, shoes) == 20, "offsetof(NetCharSelect, shoes) == 20"); +static_assert(offsetof(NetCharSelect, gloves) == 22, "offsetof(NetCharSelect, gloves) == 22"); +static_assert(offsetof(NetCharSelect, cape) == 24, "offsetof(NetCharSelect, cape) == 24"); +static_assert(offsetof(NetCharSelect, misc1) == 26, "offsetof(NetCharSelect, misc1) == 26"); +static_assert(offsetof(NetCharSelect, option) == 28, "offsetof(NetCharSelect, option) == 28"); +static_assert(offsetof(NetCharSelect, unused) == 30, "offsetof(NetCharSelect, unused) == 30"); +static_assert(offsetof(NetCharSelect, karma) == 32, "offsetof(NetCharSelect, karma) == 32"); +static_assert(offsetof(NetCharSelect, manner) == 36, "offsetof(NetCharSelect, manner) == 36"); +static_assert(offsetof(NetCharSelect, status_point) == 40, "offsetof(NetCharSelect, status_point) == 40"); +static_assert(offsetof(NetCharSelect, hp) == 42, "offsetof(NetCharSelect, hp) == 42"); +static_assert(offsetof(NetCharSelect, max_hp) == 44, "offsetof(NetCharSelect, max_hp) == 44"); +static_assert(offsetof(NetCharSelect, sp) == 46, "offsetof(NetCharSelect, sp) == 46"); +static_assert(offsetof(NetCharSelect, max_sp) == 48, "offsetof(NetCharSelect, max_sp) == 48"); +static_assert(offsetof(NetCharSelect, speed) == 50, "offsetof(NetCharSelect, speed) == 50"); +static_assert(offsetof(NetCharSelect, species) == 52, "offsetof(NetCharSelect, species) == 52"); +static_assert(offsetof(NetCharSelect, hair_style) == 54, "offsetof(NetCharSelect, hair_style) == 54"); +static_assert(offsetof(NetCharSelect, weapon) == 56, "offsetof(NetCharSelect, weapon) == 56"); +static_assert(offsetof(NetCharSelect, base_level) == 58, "offsetof(NetCharSelect, base_level) == 58"); +static_assert(offsetof(NetCharSelect, skill_point) == 60, "offsetof(NetCharSelect, skill_point) == 60"); +static_assert(offsetof(NetCharSelect, head_bottom) == 62, "offsetof(NetCharSelect, head_bottom) == 62"); +static_assert(offsetof(NetCharSelect, shield) == 64, "offsetof(NetCharSelect, shield) == 64"); +static_assert(offsetof(NetCharSelect, head_top) == 66, "offsetof(NetCharSelect, head_top) == 66"); +static_assert(offsetof(NetCharSelect, head_mid) == 68, "offsetof(NetCharSelect, head_mid) == 68"); +static_assert(offsetof(NetCharSelect, hair_color) == 70, "offsetof(NetCharSelect, hair_color) == 70"); +static_assert(offsetof(NetCharSelect, misc2) == 72, "offsetof(NetCharSelect, misc2) == 72"); +static_assert(offsetof(NetCharSelect, char_name) == 74, "offsetof(NetCharSelect, char_name) == 74"); +static_assert(offsetof(NetCharSelect, stats) == 98, "offsetof(NetCharSelect, stats) == 98"); +static_assert(offsetof(NetCharSelect, char_num) == 104, "offsetof(NetCharSelect, char_num) == 104"); +static_assert(offsetof(NetCharSelect, unused2) == 105, "offsetof(NetCharSelect, unused2) == 105"); +static_assert(sizeof(NetCharSelect) == 106, "sizeof(NetCharSelect) == 106"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetCharSelect *network, CharSelect native) +{ + bool rv = true; + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->base_exp, native.base_exp); + rv &= native_to_network(&network->zeny, native.zeny); + rv &= native_to_network(&network->job_exp, native.job_exp); + rv &= native_to_network(&network->job_level, native.job_level); + rv &= native_to_network(&network->shoes, native.shoes); + rv &= native_to_network(&network->gloves, native.gloves); + rv &= native_to_network(&network->cape, native.cape); + rv &= native_to_network(&network->misc1, native.misc1); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->manner, native.manner); + rv &= native_to_network(&network->status_point, native.status_point); + rv &= native_to_network(&network->hp, native.hp); + rv &= native_to_network(&network->max_hp, native.max_hp); + rv &= native_to_network(&network->sp, native.sp); + rv &= native_to_network(&network->max_sp, native.max_sp); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->hair_style, native.hair_style); + rv &= native_to_network(&network->weapon, native.weapon); + rv &= native_to_network(&network->base_level, native.base_level); + rv &= native_to_network(&network->skill_point, native.skill_point); + rv &= native_to_network(&network->head_bottom, native.head_bottom); + rv &= native_to_network(&network->shield, native.shield); + rv &= native_to_network(&network->head_top, native.head_top); + rv &= native_to_network(&network->head_mid, native.head_mid); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->misc2, native.misc2); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->stats, native.stats); + rv &= native_to_network(&network->char_num, native.char_num); + rv &= native_to_network(&network->unused2, native.unused2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(CharSelect *native, NetCharSelect network) +{ + bool rv = true; + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->base_exp, network.base_exp); + rv &= network_to_native(&native->zeny, network.zeny); + rv &= network_to_native(&native->job_exp, network.job_exp); + rv &= network_to_native(&native->job_level, network.job_level); + rv &= network_to_native(&native->shoes, network.shoes); + rv &= network_to_native(&native->gloves, network.gloves); + rv &= network_to_native(&native->cape, network.cape); + rv &= network_to_native(&native->misc1, network.misc1); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->manner, network.manner); + rv &= network_to_native(&native->status_point, network.status_point); + rv &= network_to_native(&native->hp, network.hp); + rv &= network_to_native(&native->max_hp, network.max_hp); + rv &= network_to_native(&native->sp, network.sp); + rv &= network_to_native(&native->max_sp, network.max_sp); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->hair_style, network.hair_style); + rv &= network_to_native(&native->weapon, network.weapon); + rv &= network_to_native(&native->base_level, network.base_level); + rv &= network_to_native(&native->skill_point, network.skill_point); + rv &= network_to_native(&native->head_bottom, network.head_bottom); + rv &= network_to_native(&native->shield, network.shield); + rv &= network_to_native(&native->head_top, network.head_top); + rv &= network_to_native(&native->head_mid, network.head_mid); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->misc2, network.misc2); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->stats, network.stats); + rv &= network_to_native(&native->char_num, network.char_num); + rv &= network_to_native(&native->unused2, network.unused2); + return rv; +} + #endif // TMWA_PROTO2_TYPES_HPP diff --git a/tools/protocol.py b/tools/protocol.py index 91b9190..45cf966 100755 --- a/tools/protocol.py +++ b/tools/protocol.py @@ -28,6 +28,9 @@ from posixpath import relpath # The following code should be relatively easy to understand, but please # keep your sanity fastened and your arms and legs inside at all times. +# important note: all numbers in this file will make a lot more sense in +# decimal, but they're written in hex. + generated = '// This is a generated file, edit %s instead\n' % __file__ copyright = '''// {filename} - {description} @@ -217,15 +220,30 @@ class StructType(Type): self.fields = fields self.size = size + def native_tag(self): + return self.name + + def network_tag(self): + return 'Net' + self.name + + def dump(self, f): + self.dump_native(f) + self.dump_network(f) + self.dump_convert(f) + f.write('\n') + def dump_fwd(self, fwd): - fwd.write('template<>\n') + if self.id is not None: + fwd.write('template<>\n') fwd.write('struct %s;\n' % self.name) - fwd.write('template<>\n') + if self.id is not None: + fwd.write('template<>\n') fwd.write('struct Net%s;\n' % self.name) def dump_native(self, f): name = self.name - f.write('template<>\n') + if self.id is not None: + f.write('template<>\n') f.write('struct %s\n{\n' % name) if self.id is not None: f.write(' static const uint16_t PACKET_ID = 0x%04x;\n\n' % self.id) @@ -240,7 +258,8 @@ class StructType(Type): def dump_network(self, f): name = 'Net%s' % self.name - f.write('template<>\n') + if self.id is not None: + f.write('template<>\n') f.write('struct %s\n{\n' % name) for (o, l, n) in self.fields: f.write(' %s %s;\n' % (l.network_tag(), n)) @@ -404,22 +423,36 @@ class VarPacket(object): def packet(id, fixed=None, fixed_size=None, + payload=None, payload_size=None, head=None, head_size=None, repeat=None, repeat_size=None, + option=None, option_size=None, ): assert (fixed is None) <= (fixed_size is None) + assert (payload is None) <= (payload_size is None) assert (head is None) <= (head_size is None) assert (repeat is None) <= (repeat_size is None) + assert (option is None) <= (option_size is None) if fixed is not None: - assert not head and not repeat + assert not head and not repeat and not option and not payload return FixedPacket( StructType(id, 'Packet_Fixed<0x%04x>' % id, fixed, fixed_size)) + elif payload is not None: + assert not head and not repeat and not option + return FixedPacket( + StructType(id, 'Packet_Payload<0x%04x>' % id, payload, payload_size)) else: - assert head and repeat - return VarPacket( - StructType(id, 'Packet_Head<0x%04x>' % id, head, head_size), - StructType(id, 'Packet_Repeat<0x%04x>' % id, repeat, repeat_size)) + assert head + if option: + return VarPacket( + StructType(id, 'Packet_Head<0x%04x>' % id, head, head_size), + StructType(id, 'Packet_Option<0x%04x>' % id, option, option_size)) + else: + assert repeat + return VarPacket( + StructType(id, 'Packet_Head<0x%04x>' % id, head, head_size), + StructType(id, 'Packet_Repeat<0x%04x>' % id, repeat, repeat_size)) class Channel(object): @@ -457,6 +490,9 @@ class Channel(object): else: f.write('// This is an internal protocol, and can be changed without notice\n') f.write('\n') + f.write('// this is only needed for the payload packet right now, and that needs to die\n') + f.write('#pragma pack(push, 1)\n') + f.write('\n') for p in self.packets: p.dump_fwd(fwd) fwd.write('\n') @@ -469,6 +505,8 @@ class Channel(object): for p in self.packets: p.dump_convert(f) f.write('\n') + f.write('#pragma pack(pop)\n') + f.write('\n') f.write('#endif // %s\n' % define) with open(os.path.join(outdir, test), 'w') as f: @@ -536,7 +574,7 @@ class Context(object): f.write('\n') f.write('# include "%s"\n\n' % sanity) f.write('# include <cstdint>\n\n') - for b in ['Fixed', 'Head', 'Repeat']: + for b in ['Fixed', 'Payload', 'Head', 'Repeat', 'Option']: c = 'Packet_' + b f.write('template<uint16_t PACKET_ID> class %s;\n' % c) f.write('template<uint16_t PACKET_ID> class Net%s;\n' % c) @@ -597,6 +635,34 @@ class Context(object): f.write(' return true;\n') f.write('}\n') f.write('\n') + f.write('inline\n') + f.write('bool native_to_network(NetString<24> *network, CharName native)\n{\n') + f.write(' VString<23> tmp = native.to__actual();\n') + f.write(' bool rv = native_to_network(network, tmp);\n') + f.write(' return rv;\n') + f.write('}\n') + f.write('inline\n') + f.write('bool network_to_native(CharName *native, NetString<24> network)\n{\n') + f.write(' VString<23> tmp;\n') + f.write(' bool rv = network_to_native(&tmp, network);\n') + f.write(' *native = stringish<CharName>(tmp);\n') + f.write(' return rv;\n') + f.write('}\n') + f.write('\n') + f.write('inline\n') + f.write('bool native_to_network(NetString<16> *network, MapName native)\n{\n') + f.write(' XString tmp = native;\n') + f.write(' bool rv = native_to_network(network, VString<15>(tmp));\n') + f.write(' return rv;\n') + f.write('}\n') + f.write('inline\n') + f.write('bool network_to_native(MapName *native, NetString<16> network)\n{\n') + f.write(' VString<15> tmp;\n') + f.write(' bool rv = network_to_native(&tmp, network);\n') + f.write(' *native = stringish<MapName>(tmp);\n') + f.write(' return rv;\n') + f.write('}\n') + f.write('\n') f.write('template<class T, size_t N>\n') f.write('struct SkewedLength\n{\n') @@ -641,9 +707,8 @@ class Context(object): self._types.append(rv) return rv - def struct(self, name, body): - # TODO fix this - rv = StructType(name, body) + def struct(self, name, body, size): + rv = StructType(None, name, body, size) self._types.append(rv) return rv @@ -673,6 +738,7 @@ def main(): enums_h = ctx.include('src/mmo/enums.hpp') human_time_diff_h = ctx.include('src/mmo/human_time_diff.hpp') ids_h = ctx.include('src/mmo/ids.hpp') + mmo_h = ctx.include('src/mmo/mmo.hpp') strs_h = ctx.include('src/mmo/strs.hpp') utils_h = ctx.include('src/mmo/utils.hpp') version_h = ctx.include('src/mmo/version.hpp') @@ -692,6 +758,7 @@ def main(): Little64 = endians_h.network('Little64') SEX = enums_h.native('SEX') + Option = enums_h.native('Option') Species = ids_h.native('Species') AccountId = ids_h.native('AccountId') @@ -724,8 +791,10 @@ def main(): #AccountCrypt = strs_h.native('AccountCrypt') AccountEmail = strs_h.native('AccountEmail') ServerName = strs_h.native('ServerName') - #PartyName = strs_h.native('PartyName') + PartyName = strs_h.native('PartyName') VarName = strs_h.native('VarName') + CharName = strs_h.native('CharName') + MapName = strs_h.native('MapName') #MobName = map_t_h.native('MobName') #NpcName = map_t_h.native('NpcName') #ScriptLabel = map_t_h.native('ScriptLabel') @@ -735,6 +804,12 @@ def main(): VERSION_2 = login_types_h.native('VERSION_2') + # TODO: fix LIES + char_key = mmo_h.neutral('CharKey') + char_data = mmo_h.neutral('CharData') + party_most = mmo_h.neutral('PartyMost') + storage = mmo_h.neutral('Storage') + # generated types u8 = ctx.provided(uint8_t, Byte) @@ -745,6 +820,8 @@ def main(): sex_char = ctx.provided(SEX, NeutralType('char')) sex = ctx.enum(SEX, u8) + option = ctx.enum(Option, u16) + species = ctx.wrap(Species, u16) account_id = ctx.wrap(AccountId, u32) char_id = ctx.wrap(CharId, u32) @@ -757,6 +834,7 @@ def main(): time64 = ctx.provided(TimeT, Little64) gm1 = ctx.provided(GmLevel, Byte) + gm2 = ctx.provided(GmLevel, Little16) gm = ctx.provided(GmLevel, Little32) str16 = ctx.string(VString16) @@ -772,8 +850,10 @@ def main(): #account_crypt = ctx.string(AccountCrypt) account_email = ctx.string(AccountEmail) server_name = ctx.string(ServerName) - #party_name = ctx.string(PartyName) + party_name = ctx.string(PartyName) var_name = ctx.string(VarName) + char_name = ctx.string(CharName) + map_name = ctx.string(MapName) #mob_name = ctx.string(MobName) #npc_name = ctx.string(NpcName) #script_label = ctx.string(ScriptLabel) @@ -809,8 +889,70 @@ def main(): version_2 = ctx.enum(VERSION_2, u8) + stats6 = ctx.struct( + 'Stats6', + [ + at(0, u8, 'str'), + at(1, u8, 'agi'), + at(2, u8, 'vit'), + at(3, u8, 'int_'), + at(4, u8, 'dex'), + at(5, u8, 'luk'), + ], + size=6, + ) + char_select = ctx.struct( + 'CharSelect', + [ + at(0, char_id, 'char id'), + at(4, u32, 'base exp'), + at(8, u32, 'zeny'), + at(12, u32, 'job exp'), + at(16, u32, 'job level'), + + at(20, item_name_id, 'shoes'), + at(22, item_name_id, 'gloves'), + at(24, item_name_id, 'cape'), + at(26, item_name_id, 'misc1'), + at(28, option, 'option'), + at(30, u16, 'unused'), + + at(32, u32, 'karma'), + at(36, u32, 'manner'), + + at(40, u16, 'status point'), + at(42, u16, 'hp'), + at(44, u16, 'max hp'), + at(46, u16, 'sp'), + at(48, u16, 'max sp'), + at(50, u16, 'speed'), + at(52, species, 'species'), + at(54, u16, 'hair_style'), + at(56, u16, 'weapon'), + at(58, u16, 'base level'), + at(60, u16, 'skill point'), + at(62, item_name_id, 'head bottom'), + at(64, item_name_id, 'shield'), + at(66, item_name_id, 'head top'), + at(68, item_name_id, 'head mid'), + at(70, u16, 'hair color'), + at(72, item_name_id, 'misc2'), + + at(74, char_name, 'char name'), + + at(98, stats6, 'stats'), + at(104, u8, 'char num'), + at(105, u8, 'unused2'), + ], + size=106, + ) + # packets + # this is a somewhat simplistic view. For packets that get forwarded, + # it may be worth pretending something like admin->char, map->login ... + # that does break the tree format though + login_char = ctx.chan('login', 'char') login_admin = ctx.chan('login', 'admin') login_bot = NotImplemented @@ -829,6 +971,21 @@ def main(): # * user + char_user.r(0x0061, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_pass, 'old pass'), + at(26, account_pass, 'new pass'), + ], + fixed_size=50, + ) + char_user.s(0x0062, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'status'), + ], + fixed_size=3, + ) login_user.r(0x0063, head=[ at(0, u16, 'packet id'), @@ -848,6 +1005,43 @@ def main(): ], fixed_size=55, ) + char_user.r(0x0065, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u32, 'login id1'), + at(10, u32, 'login id2'), + at(14, u16, 'packet tmw version'), + at(16, sex, 'sex'), + ], + fixed_size=17, + ) + char_user.r(0x0066, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'code'), + ], + fixed_size=3, + ) + char_user.r(0x0067, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_name, 'char name'), + at(26, stats6, 'stats'), + at(32, u8, 'slot'), + at(33, u16, 'hair color'), + at(35, u16, 'hair style'), + ], + fixed_size=37, + ) + char_user.r(0x0068, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_id, 'char id'), + at(6, account_email, 'email'), + ], + fixed_size=46, + ) login_user.r(0x0069, head=[ @@ -880,8 +1074,64 @@ def main(): ], fixed_size=23, ) + char_user.s(0x006b, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, str20, 'unused'), + ], + head_size=24, + repeat=[ + at(0, char_select, 'char select'), + ], + repeat_size=106, + ) + char_user.s(0x006c, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'code'), + ], + fixed_size=3, + ) + char_user.s(0x006d, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_select, 'char select'), + ], + fixed_size=108, + ) + char_user.s(0x006e, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'code'), + ], + fixed_size=3, + ) + char_user.s(0x006f, + fixed=[ + at(0, u16, 'packet id'), + ], + fixed_size=2, + ) + char_user.s(0x0070, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'code'), + ], + fixed_size=3, + ) + char_user.s(0x0071, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_id, 'char id'), + at(6, map_name, 'map name'), + at(22, ip4, 'ip'), + at(26, u16, 'port'), + ], + fixed_size=28, + ) - login_user.s(0x0081, + any_user.s(0x0081, fixed=[ at(0, u16, 'packet id'), at(2, u8, 'error code'), @@ -982,6 +1232,7 @@ def main(): ], fixed_size=50, ) + # 0x2b0a login_char.r(0x2720, head=[ at(0, u16, 'packet id'), @@ -1000,6 +1251,7 @@ def main(): ], fixed_size=10, ) + # 0x2b0c login_char.r(0x2722, fixed=[ at(0, u16, 'packet id'), @@ -1029,7 +1281,7 @@ def main(): fixed=[ at(0, u16, 'packet id'), at(2, account_id, 'account id'), - at(6, human_time_diff, 'deltas'), + at(6, human_time_diff, 'ban add'), ], fixed_size=18, ) @@ -1053,6 +1305,7 @@ def main(): ], fixed_size=6, ) + # 0x2b10, 0x2b11 for (id, cat) in [ (0x2728, login_char.r), (0x2729, login_char.s), @@ -1123,6 +1376,636 @@ def main(): fixed_size=7, ) + # char map + char_map.r(0x2af7, + fixed=[ + at(0, u16, 'packet id'), + ], + fixed_size=2, + ) + char_map.r(0x2af8, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_name, 'account name'), + at(26, account_pass, 'account pass'), + at(50, u32, 'unused'), + at(54, ip4, 'ip'), + at(58, u16, 'port'), + ], + fixed_size=60, + ) + char_map.s(0x2af9, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'code'), + ], + fixed_size=3, + ) + # wtf duplicate v + char_map.r(0x2afa, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + ], + head_size=4, + repeat=[ + at(0, map_name, 'map name'), + ], + repeat_size=16, + ) + # wtf duplicate ^ + char_map.s(0x2afa, + fixed=[ + at(0, u16, 'packet id'), + at(2, item_name_id4, 'source item id'), + at(6, item_name_id4, 'dest item id'), + ], + fixed_size=10, + ) + char_map.s(0x2afb, + fixed=[ + at(0, u16, 'packet id'), + at(2, u8, 'unknown'), + at(3, char_name, 'whisper name'), + ], + fixed_size=27, + ) + char_map.r(0x2afc, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, char_id, 'char id'), + at(10, u32, 'login id1'), + at(14, u32, 'login id2'), + at(18, ip4, 'ip'), + ], + fixed_size=22, + ) + char_map.s(0x2afd, + payload=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + at(8, u32, 'login id2'), + at(12, time32, 'connect until'), + at(16, u16, 'packet tmw version'), + at(18, char_key, 'char key'), + at(None, char_data, 'char data'), + ], + payload_size=None, + ) + char_map.s(0x2afe, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + ], + fixed_size=6, + ) + char_map.r(0x2aff, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, u16, 'users'), + ], + head_size=6, + repeat=[ + at(0, char_id, 'char id'), + ], + repeat_size=4, + ) + char_map.s(0x2b00, + fixed=[ + at(0, u16, 'packet id'), + at(2, u32, 'users'), + ], + fixed_size=6, + ) + char_map.r(0x2b01, + payload=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + at(8, char_id, 'char id'), + at(12, char_key, 'char key'), + at(None, char_data, 'char data'), + ], + payload_size=None, + ) + char_map.r(0x2b02, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u32, 'login id1'), + at(10, u32, 'login id2'), + at(14, ip4, 'ip'), + ], + fixed_size=18, + ) + char_map.s(0x2b03, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u8, 'unknown'), + ], + fixed_size=7, + ) + char_map.s(0x2b04, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, ip4, 'ip'), + at(8, u16, 'port'), + ], + head_size=10, + repeat=[ + at(0, map_name, 'map name'), + ], + repeat_size=16, + ) + char_map.r(0x2b05, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u32, 'login id1'), + at(10, u32, 'login id2'), + at(14, char_id, 'char id'), + at(18, map_name, 'map name'), + at(34, u16, 'x'), + at(36, u16, 'y'), + at(38, ip4, 'map_ip'), + at(42, u16, 'map_port'), + at(44, sex, 'sex'), + at(45, ip4, 'client_ip'), + ], + fixed_size=49, + ) + char_map.s(0x2b06, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u32, 'error'), + at(10, u32, 'unknown'), + at(14, char_id, 'char id'), + at(18, map_name, 'map name'), + at(34, u16, 'x'), + at(36, u16, 'y'), + at(38, ip4, 'map_ip'), + at(42, u16, 'map_port'), + ], + fixed_size=44, + ) + # 0x2720 + char_map.r(0x2b0a, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + ], + head_size=8, + repeat=[at(0, u8, 'c')], + repeat_size=1, + ) + char_map.s(0x2b0b, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, gm, 'gm level'), + ], + fixed_size=10, + ) + # 0x2722 + char_map.r(0x2b0c, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, account_email, 'old email'), + at(46, account_email, 'new email'), + ], + fixed_size=86, + ) + char_map.s(0x2b0d, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, sex, 'sex'), + ], + fixed_size=7, + ) + char_map.r(0x2b0e, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, char_name, 'char name'), + at(30, u16, 'operation'), + at(32, human_time_diff, 'ban add'), + ], + fixed_size=44, + ) + char_map.r(0x2b0f, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, char_name, 'char name'), + at(30, u16, 'operation'), + at(32, u16, 'error'), + ], + fixed_size=34, + ) + # 0x2728, 0x2729 + for (id, cat) in [ + (0x2b10, char_map.r), + (0x2b11, char_map.s), + ]: + cat(id, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + ], + head_size=8, + repeat=[ + at(0, var_name, 'name'), + at(32, u32, 'value'), + ], + repeat_size=36, + ) + char_map.s(0x2b12, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_id, 'char id'), + at(6, char_id, 'partner id'), + ], + fixed_size=10, + ) + char_map.s(0x2b13, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + ], + fixed_size=6, + ) + char_map.s(0x2b14, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u8, 'ban not status'), + at(7, time32, 'status or ban until'), + ], + fixed_size=11, + ) + char_map.s(0x2b15, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + ], + head_size=4, + repeat=[ + at(0, account_id, 'account id'), + at(4, gm1, 'gm level'), + ], + repeat_size=5, + ) + char_map.r(0x2b16, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_id, 'char id'), + ], + fixed_size=6, + ) + + char_map.r(0x3000, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + ], + head_size=4, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + char_map.r(0x3001, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, char_name, 'from char name'), + at(28, char_name, 'to char name'), + ], + head_size=52, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + char_map.r(0x3002, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_id, 'char id'), + at(6, u8, 'flag'), + ], + fixed_size=7, + ) + # 0x3803 + char_map.r(0x3003, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, char_name, 'char name'), + at(28, gm2, 'min gm level'), + ], + head_size=30, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + # 0x3804 + char_map.r(0x3004, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + ], + head_size=8, + repeat=[ + at(0, var_name, 'name'), + at(32, u32, 'value'), + ], + repeat_size=36, + ) + char_map.r(0x3005, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + ], + fixed_size=6, + ) + char_map.r(0x3010, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + ], + fixed_size=6, + ) + char_map.r(0x3011, + payload=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + at(8, storage, 'storage'), + ], + payload_size=None, + ) + char_map.r(0x3020, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, party_name, 'party name'), + at(30, char_name, 'char name'), + at(54, map_name, 'map name'), + at(70, u16, 'level'), + ], + fixed_size=72, + ) + char_map.r(0x3021, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + ], + fixed_size=6, + ) + char_map.r(0x3022, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, char_name, 'char name'), + at(34, map_name, 'map name'), + at(50, u16, 'level'), + ], + fixed_size=52, + ) + char_map.r(0x3023, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, u16, 'exp'), + at(12, u16, 'item'), + ], + fixed_size=14, + ) + char_map.r(0x3024, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + ], + fixed_size=10, + ) + char_map.r(0x3025, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, map_name, 'map name'), + at(26, u8, 'online'), + at(27, u16, 'level'), + ], + fixed_size=29, + ) + char_map.r(0x3026, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + ], + fixed_size=6, + ) + char_map.r(0x3027, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, party_id, 'party id'), + at(8, account_id, 'account id'), + ], + head_size=12, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + char_map.r(0x3028, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, char_name, 'char name'), + ], + fixed_size=34, + ) + + char_map.s(0x3800, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + ], + head_size=4, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + char_map.s(0x3801, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, char_id, 'whisper id'), + at(8, char_name, 'src char name'), + at(32, char_name, 'dst char name'), + ], + head_size=56, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + char_map.s(0x3802, + fixed=[ + at(0, u16, 'packet id'), + at(2, char_name, 'sender char name'), + at(26, u8, 'flag'), + ], + fixed_size=27, + ) + # 0x3003 + char_map.s(0x3803, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, char_name, 'char name'), + at(28, gm2, 'min gm level'), + ], + head_size=30, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + # 0x3004 + char_map.s(0x3804, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + ], + head_size=8, + repeat=[ + at(0, var_name, 'name'), + at(32, u32, 'value'), + ], + repeat_size=36, + ) + char_map.s(0x3810, + payload=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, account_id, 'account id'), + at(8, storage, 'storage'), + ], + payload_size=None, + ) + char_map.s(0x3811, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u8, 'unknown'), + ], + fixed_size=7, + ) + char_map.s(0x3820, + fixed=[ + at(0, u16, 'packet id'), + at(2, account_id, 'account id'), + at(6, u8, 'error'), + at(7, party_id, 'party id'), + at(11, party_name, 'party name'), + ], + fixed_size=35, + ) + char_map.s(0x3821, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, party_id, 'party id'), + ], + head_size=8, + option=[ + at(0, party_most, 'party most'), + ], + option_size=None, + ) + char_map.s(0x3822, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, u8, 'flag'), + ], + fixed_size=11, + ) + char_map.s(0x3823, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, u16, 'exp'), + at(12, u16, 'item'), + at(14, u8, 'flag'), + ], + fixed_size=15, + ) + char_map.s(0x3824, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, char_name, 'char name'), + ], + fixed_size=34, + ) + char_map.s(0x3825, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, account_id, 'account id'), + at(10, map_name, 'map name'), + at(26, u8, 'online'), + at(27, u16, 'level'), + ], + fixed_size=29, + ) + char_map.s(0x3826, + fixed=[ + at(0, u16, 'packet id'), + at(2, party_id, 'party id'), + at(6, u8, 'flag'), + ], + fixed_size=7, + ) + char_map.s(0x3827, + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, party_id, 'party id'), + at(8, account_id, 'account id'), + ], + head_size=12, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + ) + # any client any_user.r(0x7530, fixed=[ |