summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-05-27 13:33:54 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-05-27 13:33:54 -0700
commitaf4acff261d579428e8eef042cc5359fa392f725 (patch)
treeca73d54da799c3751e87ec88a785d60e7561a2f0
parentcac49afdef0992b93d8718fd928d73d721d434f4 (diff)
downloadtmwa-af4acff261d579428e8eef042cc5359fa392f725.tar.gz
tmwa-af4acff261d579428e8eef042cc5359fa392f725.tar.bz2
tmwa-af4acff261d579428e8eef042cc5359fa392f725.tar.xz
tmwa-af4acff261d579428e8eef042cc5359fa392f725.zip
Generate the char server protocol
-rw-r--r--src/char/char.cpp1457
-rw-r--r--src/char/char.hpp4
-rw-r--r--src/char/int_party.cpp420
-rw-r--r--src/char/int_party.hpp2
-rw-r--r--src/char/int_storage.cpp88
-rw-r--r--src/char/int_storage.hpp4
-rw-r--r--src/char/inter.cpp311
-rw-r--r--src/char/inter.hpp4
-rw-r--r--src/login/login.cpp2
-rw-r--r--src/map/atcommand.cpp28
-rw-r--r--src/map/chrif.cpp3
-rw-r--r--src/map/clif.cpp30
-rw-r--r--src/map/clif.hpp20
-rw-r--r--src/map/intif.cpp25
-rw-r--r--src/map/intif.hpp2
-rw-r--r--src/map/mob.cpp8
-rw-r--r--src/map/party.cpp122
-rw-r--r--src/map/party.hpp10
-rw-r--r--src/map/pc.cpp24
-rw-r--r--src/map/script.cpp2
-rw-r--r--src/map/storage.cpp26
-rw-r--r--src/map/storage.hpp4
-rw-r--r--src/mmo/fwd.hpp17
-rw-r--r--src/mmo/ids.hpp16
-rw-r--r--src/mmo/mmo.hpp18
-rw-r--r--src/net/fwd.hpp2
-rw-r--r--src/net/packets.hpp169
-rw-r--r--src/proto2/any-user.hpp42
-rw-r--r--src/proto2/char-map.hpp3428
-rw-r--r--src/proto2/char-user.hpp580
-rw-r--r--src/proto2/fwd.hpp459
-rw-r--r--src/proto2/include_enums_test.cpp1
-rw-r--r--src/proto2/include_mmo_test.cpp26
-rw-r--r--src/proto2/include_strs_test.cpp3
-rw-r--r--src/proto2/login-admin.hpp5
-rw-r--r--src/proto2/login-char.hpp15
-rw-r--r--src/proto2/login-user.hpp40
-rw-r--r--src/proto2/map-user.hpp5
-rw-r--r--src/proto2/types.hpp291
-rwxr-xr-xtools/protocol.py917
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 = &pm;
+ 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)
&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 = &pm;
+ 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=[