summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/char/char.cpp28
-rw-r--r--src/char/int_party.cpp8
-rw-r--r--src/char/int_storage.cpp2
-rw-r--r--src/char/inter.cpp4
-rw-r--r--src/login/login.cpp4
-rw-r--r--src/map/atcommand.cpp26
-rw-r--r--src/map/chrif.cpp6
-rw-r--r--src/map/clif.cpp4
-rw-r--r--src/map/magic-expr.cpp10
-rw-r--r--src/map/magic-expr.hpp4
-rw-r--r--src/map/magic-stmt.cpp4
-rw-r--r--src/map/map.cpp6
-rw-r--r--src/map/map.hpp14
-rw-r--r--src/map/mob.cpp6
-rw-r--r--src/map/npc.cpp2
-rw-r--r--src/map/party.cpp4
-rw-r--r--src/map/pc.cpp100
-rw-r--r--src/map/pc.hpp2
-rw-r--r--src/map/script.cpp4
-rw-r--r--src/map/storage.cpp4
-rw-r--r--src/mmo/consts.cpp21
-rw-r--r--src/mmo/consts.hpp65
-rw-r--r--src/mmo/extract.cpp4
-rw-r--r--src/mmo/extract.hpp4
-rw-r--r--src/mmo/fwd.hpp12
-rw-r--r--src/mmo/mmo.hpp145
-rw-r--r--src/proto2/any-user.hpp5
-rw-r--r--src/proto2/char-map.hpp19
-rw-r--r--src/proto2/char-user.hpp5
-rw-r--r--src/proto2/include_consts_test.cpp (renamed from src/proto2/include_mmo_test.cpp)9
-rw-r--r--src/proto2/include_enums_test.cpp1
-rw-r--r--src/proto2/login-admin.hpp5
-rw-r--r--src/proto2/login-char.hpp5
-rw-r--r--src/proto2/login-user.hpp5
-rw-r--r--src/proto2/map-user.hpp5
-rw-r--r--src/proto2/types.hpp514
-rwxr-xr-xtools/protocol.py263
37 files changed, 987 insertions, 342 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp
index 7bc17ba..965693b 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -175,7 +175,7 @@ std::chrono::milliseconds autosave_time = DEFAULT_AUTOSAVE_INTERVAL;
// Initial position (it's possible to set it in conf file)
static
-struct point start_point = { {"001-1.gat"_s}, 273, 354 };
+Point start_point = { {"001-1.gat"_s}, 273, 354 };
static
std::vector<GM_Account> gm_accounts;
@@ -402,7 +402,7 @@ AString mmo_char_tostr(struct CharPair *cp)
}
static
-bool extract(XString str, struct point *p)
+bool extract(XString str, Point *p)
{
return extract(str, record<','>(&p->map_, &p->x, &p->y));
}
@@ -437,10 +437,10 @@ bool extract(XString str, CharPair *cp)
uint32_t unused_guild_id, unused_pet_id;
XString unused_memos;
- std::vector<struct item> inventory;
+ std::vector<Item> inventory;
XString unused_cart;
std::vector<struct skill_loader> skills;
- std::vector<struct global_reg> vars;
+ std::vector<GlobalReg> vars;
if (!extract(str,
record<'\t'>(
&k->char_id,
@@ -1010,10 +1010,10 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd)
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.hp = std::min(p->hp, 0x7fffu);
+ sel.max_hp = std::min(p->max_hp, 0x7fffu);
+ sel.sp = std::min(p->sp, 0x7fffu);
+ sel.max_sp = std::min(p->max_sp, 0x7fffu);
sel.speed = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed;
sel.species = p->species;
sel.hair_style = p->hair;
@@ -1047,7 +1047,7 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd)
}
static
-int set_account_reg2(AccountId acc, Slice<global_reg> reg)
+int set_account_reg2(AccountId acc, Slice<GlobalReg> reg)
{
size_t num = reg.size();
assert (num < ACCOUNT_REG2_NUM);
@@ -1060,7 +1060,7 @@ int set_account_reg2(AccountId acc, Slice<global_reg> reg)
cd.data->account_reg2[i] = reg[i];
cd.data->account_reg2_num = num;
for (int i = num; i < ACCOUNT_REG2_NUM; ++i)
- cd.data->account_reg2[i] = global_reg{};
+ cd.data->account_reg2[i] = GlobalReg{};
c++;
}
}
@@ -1426,7 +1426,7 @@ void parse_tologin(Session *ls)
break;
{
- Array<struct global_reg, ACCOUNT_REG2_NUM> reg;
+ Array<GlobalReg, ACCOUNT_REG2_NUM> reg;
int j = 0;
AccountId acc = head.account_id;
for (const auto& info : repeat)
@@ -1437,7 +1437,7 @@ void parse_tologin(Session *ls)
if (j == ACCOUNT_REG2_NUM)
break;
}
- set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), j));
+ set_account_reg2(acc, Slice<GlobalReg>(reg.begin(), j));
Packet_Head<0x2b11> head_11;
head_11.account_id = head.account_id;
@@ -2211,7 +2211,7 @@ void parse_frommap(Session *ms)
break;
{
- Array<struct global_reg, ACCOUNT_REG2_NUM> reg;
+ Array<GlobalReg, ACCOUNT_REG2_NUM> reg;
AccountId acc = head.account_id;
auto jlim = std::min(repeat.size(), ACCOUNT_REG2_NUM);
for (size_t j = 0; j < jlim; ++j)
@@ -2219,7 +2219,7 @@ void parse_frommap(Session *ms)
reg[j].str = repeat[j].name;
reg[j].value = repeat[j].value;
}
- set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), jlim));
+ set_account_reg2(acc, Slice<GlobalReg>(reg.begin(), jlim));
// loginサーバーへ送る
if (login_session)
{
diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp
index 64e3158..b86b3a4 100644
--- a/src/char/int_party.cpp
+++ b/src/char/int_party.cpp
@@ -74,7 +74,7 @@ AString inter_party_tostr(PartyPair p)
p->exp, p->item);
for (int i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
+ PartyMember *m = &p->member[i];
if (!m->account_id)
continue;
str += STRPRINTF(
@@ -111,7 +111,7 @@ bool extract(XString str, PartyPair *pp)
for (int i = 0; begin != end && i < MAX_PARTY; ++i)
{
- struct party_member *m = &p->member[i];
+ PartyMember *m = &p->member[i];
if (begin == end || !extract(*begin, record<','>(&m->account_id, &m->leader)))
return false;
@@ -142,7 +142,7 @@ void party_check_deleted_init(PartyPair p)
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->member[i] = party_member{};
+ p->member[i] = PartyMember{};
}
}
}
@@ -608,7 +608,7 @@ void mapif_parse_PartyLeave(Session *, PartyId party_id, AccountId account_id)
continue;
mapif_party_leaved(party_id, account_id, p->member[i].name);
- p->member[i] = party_member{};
+ p->member[i] = PartyMember{};
if (party_check_empty(p) == 0)
mapif_party_info(nullptr, p); // まだ人がいるのでデータ送信
return;
diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp
index 6ff6e2e..7a41f43 100644
--- a/src/char/int_storage.cpp
+++ b/src/char/int_storage.cpp
@@ -89,7 +89,7 @@ AString storage_tostr(Storage *p)
static
bool extract(XString str, Storage *p)
{
- std::vector<struct item> storage_items;
+ std::vector<Item> storage_items;
if (!extract(str,
record<'\t'>(
record<','>(
diff --git a/src/char/inter.cpp b/src/char/inter.cpp
index 9eb43cf..04c1146 100644
--- a/src/char/inter.cpp
+++ b/src/char/inter.cpp
@@ -58,7 +58,7 @@ struct accreg
{
AccountId account_id;
int reg_num;
- Array<struct global_reg, ACCOUNT_REG_NUM> reg;
+ Array<GlobalReg, ACCOUNT_REG_NUM> reg;
};
static
Map<AccountId, struct accreg> accreg_db;
@@ -83,7 +83,7 @@ AString inter_accreg_tostr(struct accreg *reg)
static
bool extract(XString str, struct accreg *reg)
{
- std::vector<struct global_reg> vars;
+ std::vector<GlobalReg> vars;
if (!extract(str,
record<'\t'>(
&reg->account_id,
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 7537927..b86950d 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -214,7 +214,7 @@ struct AuthData
IP4Address last_ip; // save of last IP of connection
VString<254> memo; // a memo field
int account_reg2_num;
- Array<struct global_reg, ACCOUNT_REG2_NUM> account_reg2;
+ Array<GlobalReg, ACCOUNT_REG2_NUM> account_reg2;
};
static
std::vector<AuthData> auth_data;
@@ -494,7 +494,7 @@ AString mmo_auth_tostr(const AuthData *p)
static
bool extract(XString line, AuthData *ad)
{
- std::vector<struct global_reg> vars;
+ std::vector<GlobalReg> vars;
VString<1> sex;
VString<15> ip;
if (!extract(line,
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 6833b15..d2f154f 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -1366,7 +1366,7 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd,
}
for (i = 0; i < number; i += get_count)
{
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = item_id;
PickupFail flag;
if ((flag = pc_additem(sd, &item_tmp, get_count))
@@ -1457,10 +1457,9 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
if (sd->status.status_point > 0)
{
for (i = 0; i > level; i--)
- sd->status.status_point -=
- (sd->status.base_level + i + 14) / 4;
- if (sd->status.status_point < 0)
- sd->status.status_point = 0;
+ sd->status.status_point -= std::min(
+ static_cast<int>(sd->status.status_point),
+ (sd->status.base_level + i + 14) / 4);
clif_updatestatus(sd, SP::STATUSPOINT);
}
// to add: remove status points from stats
@@ -1521,9 +1520,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::NEXTJOBEXP);
if (sd->status.skill_point > 0)
{
- sd->status.skill_point += level;
- if (sd->status.skill_point < 0)
- sd->status.skill_point = 0;
+ sd->status.skill_point += std::max(level, -sd->status.skill_point);
clif_updatestatus(sd, SP::SKILLPOINT);
}
// to add: remove status points from skills
@@ -2588,10 +2585,9 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
if (pl_sd->status.status_point > 0)
{
for (i = 0; i > level; i--)
- pl_sd->status.status_point -=
- (pl_sd->status.base_level + i + 14) / 4;
- if (pl_sd->status.status_point < 0)
- pl_sd->status.status_point = 0;
+ pl_sd->status.status_point -= std::min(
+ static_cast<int>(pl_sd->status.status_point),
+ (pl_sd->status.base_level + i + 14) / 4);
clif_updatestatus(pl_sd, SP::STATUSPOINT);
}
// to add: remove status points from stats
@@ -2672,9 +2668,7 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::NEXTJOBEXP);
if (pl_sd->status.skill_point > 0)
{
- pl_sd->status.skill_point += level;
- if (pl_sd->status.skill_point < 0)
- pl_sd->status.skill_point = 0;
+ pl_sd->status.skill_point += std::max(level, -pl_sd->status.skill_point);
clif_updatestatus(pl_sd, SP::SKILLPOINT);
}
// to add: remove status points from skills
@@ -3156,7 +3150,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
}
// Give knife and shirt
- struct item item;
+ Item item;
item.nameid = wrap<ItemNameId>(1201);
pc_additem(pl_sd, &item, 1);
item.nameid = wrap<ItemNameId>(1202);
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 3e20c3f..3a329f8 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -677,7 +677,7 @@ int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd)
std::vector<Packet_Repeat<0x2b10>> repeat_10;
for (size_t j = 0; j < sd->status.account_reg2_num; j++)
{
- struct global_reg *reg = &sd->status.account_reg2[j];
+ GlobalReg *reg = &sd->status.account_reg2[j];
if (reg->str && reg->value != 0)
{
Packet_Repeat<0x2b10> info;
@@ -918,7 +918,7 @@ int chrif_reloadGMdb(void)
*/
static
-void ladmin_itemfrob_fix_item(ItemNameId source, ItemNameId dest, struct item *item)
+void ladmin_itemfrob_fix_item(ItemNameId source, ItemNameId dest, Item *item)
{
if (item && item->nameid == source)
{
@@ -975,7 +975,7 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameI
case BL::MOB:
{
dumb_ptr<mob_data> mob = bl->is_mob();
- for (struct item& itm : mob->lootitemv)
+ for (Item& itm : mob->lootitemv)
FIX(itm);
break;
}
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 3548324..2275023 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -1701,8 +1701,6 @@ not_b0:
{
case SP::ZENY:
trade_verifyzeny(sd);
- if (sd->status.zeny < 0)
- sd->status.zeny = 0;
fixed_b1.value = sd->status.zeny;
break;
@@ -2973,7 +2971,7 @@ int clif_party_info(PartyPair p, Session *s)
head_fb.party_name = p->name;
for (i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
+ PartyMember *m = &p->member[i];
if (m->account_id)
{
Packet_Repeat<0x00fb> info;
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index 3631ca7..b0e68fb 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -135,7 +135,7 @@ AString show_entity(dumb_ptr<block_list> entity)
case BL::ITEM:
assert (0 && "There is no way this code did what it was supposed to do!"_s);
/* Sorry about this one... */
- // WTF? item_data is a struct item, not a struct item_data
+ // WTF? item_data is a Item, not a struct item_data
// return ((struct item_data *) (&entity->is_item()->item_data))->name;
abort();
case BL::SPELL:
@@ -796,7 +796,7 @@ int fun_hash_entity(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
}
// ret -1: not a string, ret 1: no such item, ret 0: OK
-int magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable)
+int magic_find_item(Slice<val_t> args, int index, Item *item_, int *stackable)
{
struct item_data *item_data;
int must_add_sequentially;
@@ -821,7 +821,7 @@ int magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stack
if (stackable)
*stackable = !must_add_sequentially;
- *item_ = item();
+ *item_ = Item();
item_->nameid = item_data->nameid;
return 0;
@@ -832,7 +832,7 @@ int fun_count_item(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
int stackable;
- struct item item;
+ Item item;
GET_ARG_ITEM(1, item, stackable);
@@ -848,7 +848,7 @@ int fun_is_equipped(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
int stackable;
- struct item item;
+ Item item;
bool retval = false;
GET_ARG_ITEM(1, item, stackable);
diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp
index 1c4d00e..c5c63a5 100644
--- a/src/map/magic-expr.hpp
+++ b/src/map/magic-expr.hpp
@@ -29,6 +29,8 @@
# include "../strings/zstring.hpp"
# include "../strings/literal.hpp"
+# include "../mmo/fwd.hpp"
+
# include "magic-interpreter.t.hpp"
/*
@@ -83,7 +85,7 @@ void magic_copy_var(val_t *dest, val_t *src);
void magic_random_location(location_t *dest, dumb_ptr<area_t> area);
// ret -1: not a string, ret 1: no such item, ret 0: OK
-int magic_find_item(Slice<val_t> args, int index, struct item *item, int *stackable);
+int magic_find_item(Slice<val_t> args, int index, Item *item, int *stackable);
# define GET_ARG_ITEM(index, dest, stackable) \
switch (magic_find_item(args, index, &dest, &stackable)) \
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index ae59ae7..2cfb43e 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -623,7 +623,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args)
static
int op_create_item(dumb_ptr<env_t>, Slice<val_t> args)
{
- struct item item;
+ Item item;
dumb_ptr<block_list> entity = ARGENTITY(0);
dumb_ptr<map_session_data> subject;
int stackable;
@@ -903,7 +903,7 @@ int op_set_hair_style(dumb_ptr<env_t>, Slice<val_t> args)
static
int op_drop_item_for (dumb_ptr<env_t>, Slice<val_t> args)
{
- struct item item;
+ Item item;
int stackable;
location_t *loc = &ARGLOCATION(0);
int count = ARGINT(2);
diff --git a/src/map/map.cpp b/src/map/map.cpp
index dde617a..28d618b 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -697,7 +697,7 @@ std::pair<uint16_t, uint16_t> map_searchrandfreecell(map_local *m, int x, int y,
* item_dataはamount以外をcopyする
*------------------------------------------
*/
-BlockId map_addflooritem_any(struct item *item_data, int amount,
+BlockId map_addflooritem_any(Item *item_data, int amount,
map_local *m, int x, int y,
dumb_ptr<map_session_data> *owners, interval_t *owner_protection,
interval_t lifetime, int dispersal)
@@ -762,7 +762,7 @@ BlockId map_addflooritem_any(struct item *item_data, int amount,
return fitem->bl_id;
}
-BlockId map_addflooritem(struct item *item_data, int amount,
+BlockId map_addflooritem(Item *item_data, int amount,
map_local *m, int x, int y,
dumb_ptr<map_session_data> first_sd,
dumb_ptr<map_session_data> second_sd,
@@ -1658,7 +1658,7 @@ void term_func(void)
map_close_logfile();
}
-int compare_item(struct item *a, struct item *b)
+int compare_item(Item *a, Item *b)
{
return (a->nameid == b->nameid);
}
diff --git a/src/map/map.hpp b/src/map/map.hpp
index cbe8b27..7e61e56 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -473,7 +473,7 @@ struct mob_data : block_list
};
// logically a map ...
std::vector<DmgLogEntry> dmglogv;
- std::vector<struct item> lootitemv;
+ std::vector<Item> lootitemv;
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short sc_count;
@@ -524,8 +524,8 @@ struct map_local : map_abstract
int npc_num;
int users;
MapFlags flag;
- struct point save;
- struct point resave;
+ Point save;
+ Point resave;
Array<dumb_ptr<npc_data>, MAX_NPC_PER_MAP> npc;
};
@@ -549,7 +549,7 @@ struct flooritem_data : block_list
Timer cleartimer;
BlockId first_get_id, second_get_id, third_get_id;
tick_t first_get_tick, second_get_tick, third_get_tick;
- struct item item_data;
+ Item item_data;
};
extern interval_t autosave_time;
@@ -619,11 +619,11 @@ void map_clearflooritem(BlockId id)
{
map_clearflooritem_timer(nullptr, tick_t(), id);
}
-BlockId map_addflooritem_any(struct item *, int amount,
+BlockId map_addflooritem_any(Item *, int amount,
map_local *m, int x, int y,
dumb_ptr<map_session_data> *owners, interval_t *owner_protection,
interval_t lifetime, int dispersal);
-BlockId map_addflooritem(struct item *, int,
+BlockId map_addflooritem(Item *, int,
map_local *, int, int,
dumb_ptr<map_session_data>, dumb_ptr<map_session_data>,
dumb_ptr<map_session_data>);
@@ -677,7 +677,7 @@ void map_deliddb(dumb_ptr<block_list> bl);
void map_addnickdb(dumb_ptr<map_session_data>);
int map_scriptcont(dumb_ptr<map_session_data> sd, BlockId id); /* Continues a script either on a spell or on an NPC */
dumb_ptr<map_session_data> map_nick2sd(CharName);
-int compare_item(struct item *a, struct item *b);
+int compare_item(Item *a, Item *b);
dumb_ptr<map_session_data> map_get_first_session(void);
dumb_ptr<map_session_data> map_get_last_session(void);
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 74e00be..336dbe7 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -2179,7 +2179,7 @@ struct delay_item_drop2
{
map_local *m;
int x, y;
- struct item item_data;
+ Item item_data;
dumb_ptr<map_session_data> first_sd, second_sd, third_sd;
};
@@ -2190,7 +2190,7 @@ struct delay_item_drop2
static
void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem)
{
- struct item temp_item {};
+ Item temp_item {};
PickupFail flag;
temp_item.nameid = ditem.nameid;
@@ -2644,7 +2644,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
}
{
int i = 0;
- for (struct item lit : md->lootitemv)
+ for (Item lit : md->lootitemv)
{
struct delay_item_drop2 ditem {};
ditem.item_data = lit;
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 7b31729..3232e4d 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -849,7 +849,7 @@ int npc_buylist(dumb_ptr<map_session_data> sd,
if ((item_data = itemdb_exists(item_l_id)) != NULL)
{
int amount = item_l_count;
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = item_data->nameid;
diff --git a/src/map/party.cpp b/src/map/party.cpp
index 5f69de5..24ce66a 100644
--- a/src/map/party.cpp
+++ b/src/map/party.cpp
@@ -544,7 +544,7 @@ void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname,
return;
for (i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
+ PartyMember *m = &p->member[i];
if (m == NULL)
{
PRINTF("party_recv_movemap nullpo?\n"_fmt);
@@ -785,7 +785,7 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func,
for (i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
+ PartyMember *m = &p->member[i];
if (m->sd != NULL)
{
if (sd->bl_m != m->sd->bl_m)
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index e3a672e..4d104d1 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -948,7 +948,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
b_max_weight = sd->max_weight;
earray<int, ATTR, ATTR::COUNT> b_paramb = sd->paramb;
earray<int, ATTR, ATTR::COUNT> b_parame = sd->paramc;
- earray<skill_value, SkillID, MAX_SKILL> b_skill = sd->status.skill;
+ earray<SkillValue, SkillID, MAX_SKILL> b_skill = sd->status.skill;
b_hit = sd->hit;
b_flee = sd->flee;
interval_t b_aspd = sd->aspd;
@@ -1338,7 +1338,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->sprate != 100)
sd->status.max_sp = sd->status.max_sp * sd->sprate / 100;
- if (sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
+ if (sd->status.max_sp > battle_config.max_sp)
sd->status.max_sp = battle_config.max_sp;
//自然回復HP
@@ -1969,7 +1969,7 @@ int pc_remove_items(dumb_ptr<map_session_data> player, ItemNameId item_id, int c
* アイテム追加。個数のみitem構造体の数字を無視
*------------------------------------------
*/
-PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data,
+PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data,
int amount)
{
struct item_data *data;
@@ -2047,7 +2047,7 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
{
if (bool(sd->status.inventory[n].equip))
pc_unequipitem(sd, n, CalcStatus::NOW);
- sd->status.inventory[n] = item{};
+ sd->status.inventory[n] = Item{};
sd->inventory_data[n] = NULL;
}
if (!(type & 1))
@@ -3017,6 +3017,8 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
}
}
+ if (base_exp < 0 && -base_exp > sd->status.base_exp)
+ base_exp = -sd->status.base_exp;
sd->status.base_exp += base_exp;
// [Fate] Adjust experience points that healers can extract from this character
@@ -3030,10 +3032,8 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
sd->heal_xp = max_heal_xp;
}
- if (sd->status.base_exp < 0)
- sd->status.base_exp = 0;
-
- while (pc_checkbaselevelup(sd));
+ while (pc_checkbaselevelup(sd))
+ {}
clif_updatestatus(sd, SP::BASEEXP);
if (!battle_config.multi_level_up && pc_nextjobafter(sd))
@@ -3046,11 +3046,12 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
}
}
+ if (job_exp < 0 && -job_exp > sd->status.job_exp)
+ job_exp = -sd->status.job_exp;
sd->status.job_exp += job_exp;
- if (sd->status.job_exp < 0)
- sd->status.job_exp = 0;
- while (pc_checkjoblevelup(sd));
+ while (pc_checkjoblevelup(sd))
+ {}
clif_updatestatus(sd, SP::JOBEXP);
@@ -3471,52 +3472,48 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
{
if (battle_config.death_penalty_type == 1
&& battle_config.death_penalty_base > 0)
- sd->status.base_exp -=
- static_cast<double>(pc_nextbaseexp(sd)) *
- static_cast<double>(battle_config.death_penalty_base) / 10000;
+ sd->status.base_exp -= std::min(sd->status.base_exp,
+ static_cast<uint32_t>(static_cast<double>(pc_nextbaseexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000));
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
- sd->status.base_exp -=
- static_cast<double>(pc_nextbaseexp(sd)) *
- static_cast<double>(battle_config.death_penalty_base) / 10000;
+ sd->status.base_exp -= std::min(sd->status.base_exp,
+ static_cast<uint32_t>(static_cast<double>(pc_nextbaseexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000));
else if (battle_config.death_penalty_type == 2
&& battle_config.death_penalty_base > 0)
{
if (pc_nextbaseexp(sd) > 0)
- sd->status.base_exp -=
- static_cast<double>(sd->status.base_exp) *
- static_cast<double>(battle_config.death_penalty_base) / 10000;
+ sd->status.base_exp -= std::min(sd->status.base_exp,
+ static_cast<uint32_t>(static_cast<double>(sd->status.base_exp) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000));
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
- sd->status.base_exp -=
- static_cast<double>(sd->status.base_exp) *
- static_cast<double>(battle_config.death_penalty_base) / 10000;
+ sd->status.base_exp -= std::min(sd->status.base_exp,
+ static_cast<uint32_t>(static_cast<double>(sd->status.base_exp) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000));
}
- if (sd->status.base_exp < 0)
- sd->status.base_exp = 0;
clif_updatestatus(sd, SP::BASEEXP);
if (battle_config.death_penalty_type == 1
&& battle_config.death_penalty_job > 0)
- sd->status.job_exp -=
- static_cast<double>(pc_nextjobexp(sd)) *
- static_cast<double>(battle_config.death_penalty_job) / 10000;
+ sd->status.job_exp -= std::min(sd->status.job_exp,
+ static_cast<uint32_t>(static_cast<double>(pc_nextjobexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000));
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
- sd->status.job_exp -=
- static_cast<double>(pc_nextjobexp(sd)) *
- static_cast<double>(battle_config.death_penalty_job) / 10000;
+ sd->status.job_exp -= std::min(sd->status.job_exp,
+ static_cast<uint32_t>(static_cast<double>(pc_nextjobexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000));
else if (battle_config.death_penalty_type == 2
&& battle_config.death_penalty_job > 0)
{
if (pc_nextjobexp(sd) > 0)
- sd->status.job_exp -=
- static_cast<double>(sd->status.job_exp) *
- static_cast<double>(battle_config.death_penalty_job) / 10000;
+ sd->status.job_exp -= std::min(sd->status.job_exp,
+ static_cast<uint32_t>(static_cast<double>(sd->status.job_exp) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000));
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
- sd->status.job_exp -=
- static_cast<double>(sd->status.job_exp) *
- static_cast<double>(battle_config.death_penalty_job) / 10000;
+ sd->status.job_exp -= std::min(sd->status.job_exp,
+ static_cast<uint32_t>(static_cast<double>(sd->status.job_exp) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000));
}
- if (sd->status.job_exp < 0)
- sd->status.job_exp = 0;
clif_updatestatus(sd, SP::JOBEXP);
}
}
@@ -3709,18 +3706,18 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val)
case SP::BASEEXP:
if (pc_nextbaseexp(sd) > 0)
{
+ if (val < 0)
+ val = 0;
sd->status.base_exp = val;
- if (sd->status.base_exp < 0)
- sd->status.base_exp = 0;
pc_checkbaselevelup(sd);
}
break;
case SP::JOBEXP:
if (pc_nextjobexp(sd) > 0)
{
+ if (val < 0)
+ val = 0;
sd->status.job_exp = val;
- if (sd->status.job_exp < 0)
- sd->status.job_exp = 0;
pc_checkjoblevelup(sd);
}
break;
@@ -3983,11 +3980,16 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp)
}
else
{
- sd->status.sp += sd->status.max_sp * sp / 100;
- if (sd->status.sp > sd->status.max_sp)
- sd->status.sp = sd->status.max_sp;
- if (sd->status.sp < 0)
- sd->status.sp = 0;
+ if (sp > 0)
+ {
+ sd->status.sp += sd->status.max_sp * sp / 100;
+ if (sd->status.sp > sd->status.max_sp)
+ sd->status.sp = sd->status.max_sp;
+ }
+ if (sp < 0)
+ {
+ sd->status.sp -= std::min(sd->status.sp, sd->status.max_sp * -sp / 100);
+ }
}
}
if (hp)
@@ -4646,7 +4648,7 @@ int pc_checkitem(dumb_ptr<map_session_data> sd)
j++;
}
for (k = j; k < MAX_INVENTORY; ++k)
- sd->status.inventory[k] = item{};
+ sd->status.inventory[k] = Item{};
for (k = j; k < MAX_INVENTORY; k++)
sd->inventory_data[k] = NULL;
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 53e5c1d..87ed708 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -100,7 +100,7 @@ ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, ItemNameId, int);
int pc_inventoryblank(dumb_ptr<map_session_data>);
int pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id);
int pc_payzeny(dumb_ptr<map_session_data>, int);
-PickupFail pc_additem(dumb_ptr<map_session_data>, struct item *, int);
+PickupFail pc_additem(dumb_ptr<map_session_data>, Item *, int);
int pc_getzeny(dumb_ptr<map_session_data>, int);
int pc_delitem(dumb_ptr<map_session_data>, int, int, int);
int pc_checkitem(dumb_ptr<map_session_data>);
diff --git a/src/map/script.cpp b/src/map/script.cpp
index b1af725..ab9f848 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -2041,7 +2041,7 @@ void builtin_getitem(ScriptState *st)
if (nameid)
{
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = nameid;
if (HARGO2(5)) //アイテムを指定したIDに渡す
sd = map_id2sd(wrap<BlockId>(conv_num(st, &AARGO2(5))));
@@ -2099,7 +2099,7 @@ void builtin_makeitem(ScriptState *st)
if (nameid)
{
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = nameid;
map_addflooritem(&item_tmp, amount, m, x, y, NULL, NULL, NULL);
diff --git a/src/map/storage.cpp b/src/map/storage.cpp
index f8dbd0f..e9c2cd6 100644
--- a/src/map/storage.cpp
+++ b/src/map/storage.cpp
@@ -102,7 +102,7 @@ int storage_storageopen(dumb_ptr<map_session_data> sd)
*/
static
int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor,
- struct item *item_data, int amount)
+ Item *item_data, int amount)
{
struct item_data *data;
int i;
@@ -157,7 +157,7 @@ int storage_delitem(dumb_ptr<map_session_data> sd, Storage *stor,
stor->storage_[n].amount -= amount;
if (stor->storage_[n].amount == 0)
{
- stor->storage_[n] = item{};
+ stor->storage_[n] = Item{};
stor->storage_amount--;
clif_updatestorageamount(sd, stor);
}
diff --git a/src/mmo/consts.cpp b/src/mmo/consts.cpp
new file mode 100644
index 0000000..ee59429
--- /dev/null
+++ b/src/mmo/consts.cpp
@@ -0,0 +1,21 @@
+#include "consts.hpp"
+// consts.cpp - empty mess of constants
+//
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "../poison.hpp"
diff --git a/src/mmo/consts.hpp b/src/mmo/consts.hpp
new file mode 100644
index 0000000..f7dbc36
--- /dev/null
+++ b/src/mmo/consts.hpp
@@ -0,0 +1,65 @@
+#ifndef TMWA_MMO_CONSTS_HPP
+#define TMWA_MMO_CONSTS_HPP
+// consts.hpp - Huge mess of constants.
+//
+// Copyright © ????-2004 Athena Dev Teams
+// Copyright © 2004-2011 The Mana World Development Team
+// Copyright © 2011-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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# include "fwd.hpp"
+
+# include "../net/timer.t.hpp"
+
+# include "ids.hpp"
+# include "strs.hpp"
+
+constexpr int FIFOSIZE_SERVERLINK = 256 * 1024;
+
+constexpr int MAX_MAP_PER_SERVER = 512;
+constexpr int MAX_INVENTORY = 100;
+constexpr int MAX_AMOUNT = 30000;
+constexpr int MAX_ZENY = 1000000000; // 1G zeny
+constexpr int TRADE_MAX = 10;
+
+constexpr int GLOBAL_REG_NUM = 96;
+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();
+constexpr interval_t MAX_WALK_SPEED = std::chrono::seconds(1);
+constexpr int MAX_STORAGE = 300;
+constexpr int MAX_PARTY = 12;
+
+# define MIN_HAIR_STYLE battle_config.min_hair_style
+# define MAX_HAIR_STYLE battle_config.max_hair_style
+# define MIN_HAIR_COLOR battle_config.min_hair_color
+# define MAX_HAIR_COLOR battle_config.max_hair_color
+# define MIN_CLOTH_COLOR battle_config.min_cloth_color
+# define MAX_CLOTH_COLOR battle_config.max_cloth_color
+
+// WTF is this doing here?
+struct PartyMember
+{
+ AccountId account_id;
+ CharName name;
+ MapName map;
+ int leader, online, lv;
+ struct map_session_data *sd;
+};
+
+#endif // TMWA_MMO_CONSTS_HPP
diff --git a/src/mmo/extract.cpp b/src/mmo/extract.cpp
index b0a01f1..deb3a64 100644
--- a/src/mmo/extract.cpp
+++ b/src/mmo/extract.cpp
@@ -40,13 +40,13 @@ bool extract(XString str, AString *rv)
return true;
}
-bool extract(XString str, struct global_reg *var)
+bool extract(XString str, GlobalReg *var)
{
return extract(str,
record<','>(&var->str, &var->value));
}
-bool extract(XString str, struct item *it)
+bool extract(XString str, Item *it)
{
XString ignored;
return extract(str,
diff --git a/src/mmo/extract.hpp b/src/mmo/extract.hpp
index ab65661..1154545 100644
--- a/src/mmo/extract.hpp
+++ b/src/mmo/extract.hpp
@@ -208,9 +208,9 @@ bool extract(XString str, VRecord<split, T> rec)
&& extract(str.xislice_t(s + 1), rec);
}
-bool extract(XString str, struct global_reg *var);
+bool extract(XString str, GlobalReg *var);
-bool extract(XString str, struct item *it);
+bool extract(XString str, Item *it);
bool extract(XString str, MapName *m);
diff --git a/src/mmo/fwd.hpp b/src/mmo/fwd.hpp
index 3217fc1..7bf766e 100644
--- a/src/mmo/fwd.hpp
+++ b/src/mmo/fwd.hpp
@@ -45,11 +45,13 @@ class VarName;
class MapName;
class CharName;
+class Item;
+# if 0
+class Point;
+class SkillValue;
+# endif
+class GlobalReg;
# if 0
-class item;
-class point;
-class skill_value;
-class global_reg;
class CharKey;
class CharData;
class CharPair;
@@ -57,7 +59,7 @@ class CharPair;
class Storage;
# if 0
class GM_Account;
-class party_member;
+class PartyMember;
# endif
class PartyMost;
class PartyPair;
diff --git a/src/mmo/mmo.hpp b/src/mmo/mmo.hpp
index 89aef6d..d749daa 100644
--- a/src/mmo/mmo.hpp
+++ b/src/mmo/mmo.hpp
@@ -1,6 +1,6 @@
#ifndef TMWA_MMO_MMO_HPP
#define TMWA_MMO_MMO_HPP
-// mmo.hpp - Huge mess of structures and constants.
+// mmo.hpp - Huge mess of structures.
//
// Copyright © ????-2004 Athena Dev Teams
// Copyright © 2004-2011 The Mana World Development Team
@@ -23,119 +23,20 @@
# include "fwd.hpp"
-# include <algorithm>
-
# include "../compat/memory.hpp"
-# include "../generic/array.hpp"
-
-# include "../net/timer.t.hpp"
-
-# include "enums.hpp"
-# include "ids.hpp"
-# include "strs.hpp"
-
-constexpr int FIFOSIZE_SERVERLINK = 256 * 1024;
-
-constexpr int MAX_MAP_PER_SERVER = 512;
-constexpr int MAX_INVENTORY = 100;
-constexpr int MAX_AMOUNT = 30000;
-constexpr int MAX_ZENY = 1000000000; // 1G zeny
-constexpr int TRADE_MAX = 10;
-
-constexpr int GLOBAL_REG_NUM = 96;
-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();
-constexpr interval_t MAX_WALK_SPEED = std::chrono::seconds(1);
-constexpr int MAX_STORAGE = 300;
-constexpr int MAX_PARTY = 12;
+# include "../proto2/types.hpp"
-# define MIN_HAIR_STYLE battle_config.min_hair_style
-# define MAX_HAIR_STYLE battle_config.max_hair_style
-# define MIN_HAIR_COLOR battle_config.min_hair_color
-# define MAX_HAIR_COLOR battle_config.max_hair_color
-# define MIN_CLOTH_COLOR battle_config.min_cloth_color
-# define MAX_CLOTH_COLOR battle_config.max_cloth_color
-
-struct item
+inline
+bool operator == (const SkillValue& l, const SkillValue& r)
{
- ItemNameId nameid;
- short amount;
- EPOS equip;
-};
-
-struct point
+ return l.lv == r.lv && l.flags == r.flags;
+}
+inline
+bool operator != (const SkillValue& l, const SkillValue& r)
{
- MapName map_;
- short x, y;
-};
-
-struct skill_value
-{
- unsigned short lv;
- SkillFlags flags;
-
- friend bool operator == (const skill_value& l, const skill_value& r)
- {
- return l.lv == r.lv && l.flags == r.flags;
- }
- friend bool operator != (const skill_value& l, const skill_value& r)
- {
- return !(l == r);
- }
-};
-
-struct global_reg
-{
- VarName str;
- int value;
-};
-
-struct CharKey
-{
- CharName name;
- AccountId account_id;
- CharId char_id;
- unsigned char char_num;
-};
-
-struct CharData
-{
- CharId partner_id;
-
- int base_exp, job_exp, zeny;
-
- Species species;
- short status_point, skill_point;
- int hp, max_hp, sp, max_sp;
- Option option;
- short karma, manner;
- short hair, hair_color, clothes_color;
- PartyId party_id;
-
- ItemLook weapon;
- ItemNameId shield;
- ItemNameId head_top, head_mid, head_bottom;
-
- unsigned char base_level, job_level;
- earray<short, ATTR, ATTR::COUNT> attrs;
- SEX sex;
-
- unsigned long mapip;
- unsigned int mapport;
-
- struct point last_point, save_point;
- Array<struct item, MAX_INVENTORY> inventory;
- earray<skill_value, SkillID, MAX_SKILL> skill;
- int global_reg_num;
- Array<struct global_reg, GLOBAL_REG_NUM> global_reg;
- int account_reg_num;
- Array<struct global_reg, ACCOUNT_REG_NUM> account_reg;
- int account_reg2_num;
- Array<struct global_reg, ACCOUNT_REG2_NUM> account_reg2;
-};
+ return !(l == r);
+}
struct CharPair
{
@@ -147,38 +48,12 @@ struct CharPair
{}
};
-struct Storage
-{
- bool dirty;
- AccountId account_id;
- short storage_status;
- short storage_amount;
- Array<struct item, MAX_STORAGE> storage_;
-};
-
struct GM_Account
{
AccountId account_id;
GmLevel level;
};
-struct party_member
-{
- AccountId account_id;
- CharName name;
- MapName map;
- int leader, online, lv;
- struct map_session_data *sd;
-};
-
-struct PartyMost
-{
- PartyName name;
- int exp;
- int item;
- Array<struct party_member, MAX_PARTY> member;
-};
-
struct PartyPair
{
PartyId party_id = {};
diff --git a/src/proto2/any-user.hpp b/src/proto2/any-user.hpp
index 4e14712..6cbf8e3 100644
--- a/src/proto2/any-user.hpp
+++ b/src/proto2/any-user.hpp
@@ -27,9 +27,6 @@
// 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>
{
@@ -214,6 +211,4 @@ bool network_to_native(Packet_Payload<0x8000> *native, NetPacket_Payload<0x8000>
}
-# pragma pack(pop)
-
#endif // TMWA_PROTO2_ANY_USER_HPP
diff --git a/src/proto2/char-map.hpp b/src/proto2/char-map.hpp
index f543b90..6383130 100644
--- a/src/proto2/char-map.hpp
+++ b/src/proto2/char-map.hpp
@@ -27,9 +27,6 @@
// 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>
{
@@ -1033,8 +1030,8 @@ struct NetPacket_Payload<0x2afd>
Little32 login_id2;
Little32 connect_until;
Little16 packet_tmw_version;
- CharKey char_key;
- CharData char_data;
+ NetCharKey char_key;
+ NetCharData 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");
@@ -1095,8 +1092,8 @@ struct NetPacket_Payload<0x2b01>
Little16 magic_packet_length;
Little32 account_id;
Little32 char_id;
- CharKey char_key;
- CharData char_data;
+ NetCharKey char_key;
+ NetCharData 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");
@@ -1558,7 +1555,7 @@ struct NetPacket_Payload<0x3011>
Little16 magic_packet_id;
Little16 magic_packet_length;
Little32 account_id;
- Storage storage;
+ NetStorage 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");
@@ -1822,7 +1819,7 @@ struct NetPacket_Payload<0x3810>
Little16 magic_packet_id;
Little16 magic_packet_length;
Little32 account_id;
- Storage storage;
+ NetStorage 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");
@@ -1875,7 +1872,7 @@ static_assert(alignof(NetPacket_Head<0x3821>) == 1, "alignof(NetPacket_Head<0x38
template<>
struct NetPacket_Option<0x3821>
{
- PartyMost party_most;
+ NetPartyMost party_most;
};
static_assert(offsetof(NetPacket_Option<0x3821>, party_most) == 0, "offsetof(NetPacket_Option<0x3821>, party_most) == 0");
static_assert(alignof(NetPacket_Option<0x3821>) == 1, "alignof(NetPacket_Option<0x3821>) == 1");
@@ -3536,6 +3533,4 @@ bool network_to_native(Packet_Repeat<0x3827> *native, NetPacket_Repeat<0x3827> n
}
-# pragma pack(pop)
-
#endif // TMWA_PROTO2_CHAR_MAP_HPP
diff --git a/src/proto2/char-user.hpp b/src/proto2/char-user.hpp
index 2c1d1ac..2fc3856 100644
--- a/src/proto2/char-user.hpp
+++ b/src/proto2/char-user.hpp
@@ -27,9 +27,6 @@
// 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>
{
@@ -622,6 +619,4 @@ bool network_to_native(Packet_Fixed<0x0071> *native, NetPacket_Fixed<0x0071> net
}
-# pragma pack(pop)
-
#endif // TMWA_PROTO2_CHAR_USER_HPP
diff --git a/src/proto2/include_mmo_test.cpp b/src/proto2/include_consts_test.cpp
index feb2de2..b093dab 100644
--- a/src/proto2/include_mmo_test.cpp
+++ b/src/proto2/include_consts_test.cpp
@@ -1,5 +1,5 @@
-#include "../mmo/mmo.hpp"
-// include_mmo_test.cpp - testsuite for protocol includes
+#include "../mmo/consts.hpp"
+// include_consts_test.cpp - testsuite for protocol includes
//
// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -20,7 +20,4 @@
#include "../poison.hpp"
-using Test_CharKey = CharKey;
-using Test_CharData = CharData;
-using Test_PartyMost = PartyMost;
-using Test_Storage = Storage;
+using Test_PartyMember = PartyMember;
diff --git a/src/proto2/include_enums_test.cpp b/src/proto2/include_enums_test.cpp
index cad9b12..6fd81f8 100644
--- a/src/proto2/include_enums_test.cpp
+++ b/src/proto2/include_enums_test.cpp
@@ -23,3 +23,4 @@
using Test_SEX = SEX;
using Test_Option = Option;
using Test_EPOS = EPOS;
+using Test_ItemLook = ItemLook;
diff --git a/src/proto2/login-admin.hpp b/src/proto2/login-admin.hpp
index e3962b9..30cdb8b 100644
--- a/src/proto2/login-admin.hpp
+++ b/src/proto2/login-admin.hpp
@@ -27,9 +27,6 @@
// 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>
{
@@ -2218,6 +2215,4 @@ 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 53e99f9..a2e0b8e 100644
--- a/src/proto2/login-char.hpp
+++ b/src/proto2/login-char.hpp
@@ -27,9 +27,6 @@
// 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>
{
@@ -1235,6 +1232,4 @@ 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 af4a070..5eda66c 100644
--- a/src/proto2/login-user.hpp
+++ b/src/proto2/login-user.hpp
@@ -27,9 +27,6 @@
// 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>
{
@@ -325,6 +322,4 @@ bool network_to_native(Packet_Fixed<0x006a> *native, NetPacket_Fixed<0x006a> net
}
-# pragma pack(pop)
-
#endif // TMWA_PROTO2_LOGIN_USER_HPP
diff --git a/src/proto2/map-user.hpp b/src/proto2/map-user.hpp
index ef401f4..b4ea4d8 100644
--- a/src/proto2/map-user.hpp
+++ b/src/proto2/map-user.hpp
@@ -27,9 +27,6 @@
// 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<0x0072>
{
@@ -7931,6 +7928,4 @@ 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 0113138..f46acf3 100644
--- a/src/proto2/types.hpp
+++ b/src/proto2/types.hpp
@@ -21,22 +21,26 @@
# include "fwd.hpp"
+# include "../generic/array.hpp"
+# include "../mmo/consts.hpp"
+
//TODO split the includes
# include <cstdint>
# include "../ints/little.hpp"
# include "../strings/vstring.hpp"
# include "../net/ip.hpp"
# include "../net/timer.t.hpp"
+# include "../mmo/consts.hpp"
# 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"
# include "../login/login.t.hpp"
# include "../map/clif.t.hpp"
# include "../map/skill.t.hpp"
+
template<class T>
bool native_to_network(T *network, T native)
{
@@ -49,6 +53,52 @@ bool network_to_native(T *native, T network)
*native = network;
return true;
}
+template<class T, size_t N>
+struct NetArray
+{
+ T data[N];
+};
+template<class T, class U, size_t N>
+bool native_to_network(NetArray<T, N> *network, Array<U, N> native)
+{
+ for (size_t i = 0; i < N; ++i)
+ {
+ if (!native_to_network(&(*network).data[i], native[i]))
+ return false;
+ }
+ return true;
+}
+template<class T, class U, size_t N>
+bool network_to_native(Array<U, N> *native, NetArray<T, N> network)
+{
+ for (size_t i = 0; i < N; ++i)
+ {
+ if (!network_to_native(&(*native)[i], network.data[i]))
+ return false;
+ }
+ return true;
+}
+template<class T, class U, size_t N, class I>
+bool native_to_network(NetArray<T, N> *network, earray<U, I, static_cast<I>(N)> native)
+{
+ for (size_t i = 0; i < N; ++i)
+ {
+ if (!native_to_network(&(*network).data[i], native[static_cast<I>(i)]))
+ return false;
+ }
+ return true;
+}
+template<class T, class U, size_t N, class I>
+bool network_to_native(earray<U, I, static_cast<I>(N)> *native, NetArray<T, N> network)
+{
+ for (size_t i = 0; i < N; ++i)
+ {
+ if (!network_to_native(&(*native)[static_cast<I>(i)], network.data[i]))
+ return false;
+ }
+ return true;
+}
+
template<size_t N>
struct NetString
{
@@ -415,6 +465,24 @@ bool network_to_native(EPOS *native, Little16 network)
return rv;
}
inline __attribute__((warn_unused_result))
+bool native_to_network(Little16 *network, ItemLook 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(ItemLook *native, Little16 network)
+{
+ bool rv = true;
+ uint16_t tmp;
+ rv &= network_to_native(&tmp, network);
+ *native = static_cast<ItemLook>(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;
@@ -925,4 +993,448 @@ bool network_to_native(SkillInfo *native, NetSkillInfo network)
return rv;
}
+struct Item
+{
+ ItemNameId nameid = {};
+ uint16_t amount = {};
+ EPOS equip = {};
+};
+struct NetItem
+{
+ Little16 nameid;
+ Little16 amount;
+ Little16 equip;
+};
+static_assert(alignof(NetItem) == 1, "alignof(NetItem) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetItem *network, Item native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->nameid, native.nameid);
+ rv &= native_to_network(&network->amount, native.amount);
+ rv &= native_to_network(&network->equip, native.equip);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(Item *native, NetItem network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->nameid, network.nameid);
+ rv &= network_to_native(&native->amount, network.amount);
+ rv &= network_to_native(&native->equip, network.equip);
+ return rv;
+}
+
+struct Point
+{
+ MapName map_ = {};
+ uint16_t x = {};
+ uint16_t y = {};
+ Point() = default;
+ Point(MapName _map_, uint16_t _x, uint16_t _y) : map_(_map_), x(_x), y(_y) {}
+};
+struct NetPoint
+{
+ NetString<sizeof(MapName)> map_;
+ Little16 x;
+ Little16 y;
+};
+static_assert(alignof(NetPoint) == 1, "alignof(NetPoint) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetPoint *network, Point native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->map_, native.map_);
+ rv &= native_to_network(&network->x, native.x);
+ rv &= native_to_network(&network->y, native.y);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(Point *native, NetPoint network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->map_, network.map_);
+ rv &= network_to_native(&native->x, network.x);
+ rv &= network_to_native(&native->y, network.y);
+ return rv;
+}
+
+struct SkillValue
+{
+ uint16_t lv = {};
+ SkillFlags flags = {};
+};
+struct NetSkillValue
+{
+ Little16 lv;
+ Little16 flags;
+};
+static_assert(alignof(NetSkillValue) == 1, "alignof(NetSkillValue) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetSkillValue *network, SkillValue native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->lv, native.lv);
+ rv &= native_to_network(&network->flags, native.flags);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(SkillValue *native, NetSkillValue network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->lv, network.lv);
+ rv &= network_to_native(&native->flags, network.flags);
+ return rv;
+}
+
+struct GlobalReg
+{
+ VarName str = {};
+ uint32_t value = {};
+};
+struct NetGlobalReg
+{
+ NetString<sizeof(VarName)> str;
+ Little32 value;
+};
+static_assert(alignof(NetGlobalReg) == 1, "alignof(NetGlobalReg) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetGlobalReg *network, GlobalReg native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->str, native.str);
+ rv &= native_to_network(&network->value, native.value);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(GlobalReg *native, NetGlobalReg network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->str, network.str);
+ rv &= network_to_native(&native->value, network.value);
+ return rv;
+}
+
+struct CharKey
+{
+ CharName name = {};
+ AccountId account_id = {};
+ CharId char_id = {};
+ uint8_t char_num = {};
+};
+struct NetCharKey
+{
+ NetString<sizeof(CharName)> name;
+ Little32 account_id;
+ Little32 char_id;
+ Byte char_num;
+};
+static_assert(alignof(NetCharKey) == 1, "alignof(NetCharKey) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetCharKey *network, CharKey native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->name, native.name);
+ 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_num, native.char_num);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(CharKey *native, NetCharKey network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->name, network.name);
+ 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_num, network.char_num);
+ return rv;
+}
+
+struct CharData
+{
+ CharId partner_id = {};
+ uint32_t base_exp = {};
+ uint32_t job_exp = {};
+ uint32_t zeny = {};
+ Species species = {};
+ uint16_t status_point = {};
+ uint16_t skill_point = {};
+ uint32_t hp = {};
+ uint32_t max_hp = {};
+ uint32_t sp = {};
+ uint32_t max_sp = {};
+ Option option = {};
+ uint16_t karma = {};
+ uint16_t manner = {};
+ uint16_t hair = {};
+ uint16_t hair_color = {};
+ uint16_t clothes_color = {};
+ PartyId party_id = {};
+ ItemLook weapon = {};
+ ItemNameId shield = {};
+ ItemNameId head_top = {};
+ ItemNameId head_mid = {};
+ ItemNameId head_bottom = {};
+ uint8_t base_level = {};
+ uint8_t job_level = {};
+ earray<uint16_t, ATTR, ATTR::COUNT> attrs = {};
+ SEX sex = {};
+ IP4Address mapip = {};
+ uint16_t mapport = {};
+ Point last_point = {};
+ Point save_point = {};
+ Array<Item, MAX_INVENTORY> inventory = {};
+ earray<SkillValue, SkillID, MAX_SKILL> skill = {};
+ uint32_t global_reg_num = {};
+ Array<GlobalReg, GLOBAL_REG_NUM> global_reg = {};
+ uint32_t account_reg_num = {};
+ Array<GlobalReg, ACCOUNT_REG_NUM> account_reg = {};
+ uint32_t account_reg2_num = {};
+ Array<GlobalReg, ACCOUNT_REG2_NUM> account_reg2 = {};
+};
+struct NetCharData
+{
+ Little32 partner_id;
+ Little32 base_exp;
+ Little32 job_exp;
+ Little32 zeny;
+ Little16 species;
+ Little16 status_point;
+ Little16 skill_point;
+ Little32 hp;
+ Little32 max_hp;
+ Little32 sp;
+ Little32 max_sp;
+ Little16 option;
+ Little16 karma;
+ Little16 manner;
+ Little16 hair;
+ Little16 hair_color;
+ Little16 clothes_color;
+ Little32 party_id;
+ Little16 weapon;
+ Little16 shield;
+ Little16 head_top;
+ Little16 head_mid;
+ Little16 head_bottom;
+ Byte base_level;
+ Byte job_level;
+ NetArray<Little16, static_cast<size_t>(ATTR::COUNT)> attrs;
+ Byte sex;
+ IP4Address mapip;
+ Little16 mapport;
+ NetPoint last_point;
+ NetPoint save_point;
+ NetArray<NetItem, MAX_INVENTORY> inventory;
+ NetArray<NetSkillValue, static_cast<size_t>(MAX_SKILL)> skill;
+ Little32 global_reg_num;
+ NetArray<NetGlobalReg, GLOBAL_REG_NUM> global_reg;
+ Little32 account_reg_num;
+ NetArray<NetGlobalReg, ACCOUNT_REG_NUM> account_reg;
+ Little32 account_reg2_num;
+ NetArray<NetGlobalReg, ACCOUNT_REG2_NUM> account_reg2;
+};
+static_assert(alignof(NetCharData) == 1, "alignof(NetCharData) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetCharData *network, CharData native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->partner_id, native.partner_id);
+ rv &= native_to_network(&network->base_exp, native.base_exp);
+ rv &= native_to_network(&network->job_exp, native.job_exp);
+ rv &= native_to_network(&network->zeny, native.zeny);
+ rv &= native_to_network(&network->species, native.species);
+ rv &= native_to_network(&network->status_point, native.status_point);
+ rv &= native_to_network(&network->skill_point, native.skill_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->option, native.option);
+ rv &= native_to_network(&network->karma, native.karma);
+ rv &= native_to_network(&network->manner, native.manner);
+ rv &= native_to_network(&network->hair, native.hair);
+ rv &= native_to_network(&network->hair_color, native.hair_color);
+ rv &= native_to_network(&network->clothes_color, native.clothes_color);
+ rv &= native_to_network(&network->party_id, native.party_id);
+ rv &= native_to_network(&network->weapon, native.weapon);
+ 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->head_bottom, native.head_bottom);
+ rv &= native_to_network(&network->base_level, native.base_level);
+ rv &= native_to_network(&network->job_level, native.job_level);
+ rv &= native_to_network(&network->attrs, native.attrs);
+ rv &= native_to_network(&network->sex, native.sex);
+ rv &= native_to_network(&network->mapip, native.mapip);
+ rv &= native_to_network(&network->mapport, native.mapport);
+ rv &= native_to_network(&network->last_point, native.last_point);
+ rv &= native_to_network(&network->save_point, native.save_point);
+ rv &= native_to_network(&network->inventory, native.inventory);
+ rv &= native_to_network(&network->skill, native.skill);
+ rv &= native_to_network(&network->global_reg_num, native.global_reg_num);
+ rv &= native_to_network(&network->global_reg, native.global_reg);
+ rv &= native_to_network(&network->account_reg_num, native.account_reg_num);
+ rv &= native_to_network(&network->account_reg, native.account_reg);
+ rv &= native_to_network(&network->account_reg2_num, native.account_reg2_num);
+ rv &= native_to_network(&network->account_reg2, native.account_reg2);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(CharData *native, NetCharData network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->partner_id, network.partner_id);
+ rv &= network_to_native(&native->base_exp, network.base_exp);
+ rv &= network_to_native(&native->job_exp, network.job_exp);
+ rv &= network_to_native(&native->zeny, network.zeny);
+ rv &= network_to_native(&native->species, network.species);
+ rv &= network_to_native(&native->status_point, network.status_point);
+ rv &= network_to_native(&native->skill_point, network.skill_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->option, network.option);
+ rv &= network_to_native(&native->karma, network.karma);
+ rv &= network_to_native(&native->manner, network.manner);
+ rv &= network_to_native(&native->hair, network.hair);
+ rv &= network_to_native(&native->hair_color, network.hair_color);
+ rv &= network_to_native(&native->clothes_color, network.clothes_color);
+ rv &= network_to_native(&native->party_id, network.party_id);
+ rv &= network_to_native(&native->weapon, network.weapon);
+ 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->head_bottom, network.head_bottom);
+ rv &= network_to_native(&native->base_level, network.base_level);
+ rv &= network_to_native(&native->job_level, network.job_level);
+ rv &= network_to_native(&native->attrs, network.attrs);
+ rv &= network_to_native(&native->sex, network.sex);
+ rv &= network_to_native(&native->mapip, network.mapip);
+ rv &= network_to_native(&native->mapport, network.mapport);
+ rv &= network_to_native(&native->last_point, network.last_point);
+ rv &= network_to_native(&native->save_point, network.save_point);
+ rv &= network_to_native(&native->inventory, network.inventory);
+ rv &= network_to_native(&native->skill, network.skill);
+ rv &= network_to_native(&native->global_reg_num, network.global_reg_num);
+ rv &= network_to_native(&native->global_reg, network.global_reg);
+ rv &= network_to_native(&native->account_reg_num, network.account_reg_num);
+ rv &= network_to_native(&native->account_reg, network.account_reg);
+ rv &= network_to_native(&native->account_reg2_num, network.account_reg2_num);
+ rv &= network_to_native(&native->account_reg2, network.account_reg2);
+ return rv;
+}
+
+struct NetPartyMember
+{
+ Little32 account_id;
+ NetString<sizeof(CharName)> name;
+ NetString<sizeof(MapName)> map;
+ Little32 leader;
+ Little32 online;
+ Little32 lv;
+};
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetPartyMember *network, PartyMember native)
+{
+ bool rv = true;
+ AccountId account_id = native.account_id; rv &= native_to_network(&network->account_id, account_id);
+ CharName name = native.name; rv &= native_to_network(&network->name, name);
+ MapName map = native.map; rv &= native_to_network(&network->map, map);
+ uint32_t leader = native.leader; rv &= native_to_network(&network->leader, leader);
+ uint32_t online = native.online; rv &= native_to_network(&network->online, online);
+ uint32_t lv = native.lv; rv &= native_to_network(&network->lv, lv);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(PartyMember *native, NetPartyMember network)
+{
+ bool rv = true;
+ AccountId account_id; rv &= network_to_native(&account_id, network.account_id); native->account_id = account_id;
+ CharName name; rv &= network_to_native(&name, network.name); native->name = name;
+ MapName map; rv &= network_to_native(&map, network.map); native->map = map;
+ uint32_t leader; rv &= network_to_native(&leader, network.leader); native->leader = leader;
+ uint32_t online; rv &= network_to_native(&online, network.online); native->online = online;
+ uint32_t lv; rv &= network_to_native(&lv, network.lv); native->lv = lv;
+ return rv;
+}
+
+struct PartyMost
+{
+ PartyName name = {};
+ uint32_t exp = {};
+ uint32_t item = {};
+ Array<PartyMember, MAX_PARTY> member = {};
+};
+struct NetPartyMost
+{
+ NetString<sizeof(PartyName)> name;
+ Little32 exp;
+ Little32 item;
+ NetArray<NetPartyMember, MAX_PARTY> member;
+};
+static_assert(alignof(NetPartyMost) == 1, "alignof(NetPartyMost) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetPartyMost *network, PartyMost native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->name, native.name);
+ rv &= native_to_network(&network->exp, native.exp);
+ rv &= native_to_network(&network->item, native.item);
+ rv &= native_to_network(&network->member, native.member);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(PartyMost *native, NetPartyMost network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->name, network.name);
+ rv &= network_to_native(&native->exp, network.exp);
+ rv &= network_to_native(&native->item, network.item);
+ rv &= network_to_native(&native->member, network.member);
+ return rv;
+}
+
+struct Storage
+{
+ bool dirty = {};
+ AccountId account_id = {};
+ uint16_t storage_status = {};
+ uint16_t storage_amount = {};
+ Array<Item, MAX_STORAGE> storage_ = {};
+};
+struct NetStorage
+{
+ bool dirty;
+ Little32 account_id;
+ Little16 storage_status;
+ Little16 storage_amount;
+ NetArray<NetItem, MAX_STORAGE> storage_;
+};
+static_assert(alignof(NetStorage) == 1, "alignof(NetStorage) == 1");
+inline __attribute__((warn_unused_result))
+bool native_to_network(NetStorage *network, Storage native)
+{
+ bool rv = true;
+ rv &= native_to_network(&network->dirty, native.dirty);
+ rv &= native_to_network(&network->account_id, native.account_id);
+ rv &= native_to_network(&network->storage_status, native.storage_status);
+ rv &= native_to_network(&network->storage_amount, native.storage_amount);
+ rv &= native_to_network(&network->storage_, native.storage_);
+ return rv;
+}
+inline __attribute__((warn_unused_result))
+bool network_to_native(Storage *native, NetStorage network)
+{
+ bool rv = true;
+ rv &= network_to_native(&native->dirty, network.dirty);
+ rv &= network_to_native(&native->account_id, network.account_id);
+ rv &= network_to_native(&native->storage_status, network.storage_status);
+ rv &= network_to_native(&native->storage_amount, network.storage_amount);
+ rv &= network_to_native(&native->storage_, network.storage_);
+ return rv;
+}
+
#endif // TMWA_PROTO2_TYPES_HPP
diff --git a/tools/protocol.py b/tools/protocol.py
index e92144b..4090b2b 100755
--- a/tools/protocol.py
+++ b/tools/protocol.py
@@ -212,13 +212,14 @@ class SkewLengthType(Type):
pass
class StructType(Type):
- __slots__ = ('id', 'name', 'fields', 'size')
+ __slots__ = ('id', 'name', 'fields', 'size', 'ctor')
- def __init__(self, id, name, fields, size):
+ def __init__(self, id, name, fields, size, ctor=False):
self.id = id
self.name = name
self.fields = fields
self.size = size
+ self.ctor = ctor
def native_tag(self):
return self.name
@@ -254,6 +255,13 @@ class StructType(Type):
f.write(' %s %s = PACKET_ID;\n' % (l.native_tag(), n))
else:
f.write(' %s %s = {};\n' % (l.native_tag(), n))
+ if self.ctor:
+ f.write(' %s() = default;\n' % name)
+ f.write(' %s(' % name)
+ f.write(', '.join('%s _%s' % (l.native_tag(), n) for (_, l, n) in self.fields))
+ f.write(') : ')
+ f.write(', '.join('%s(_%s)' % (n, n) for (_, _, n) in self.fields))
+ f.write(' {}\n')
f.write('};\n')
def dump_network(self, f):
@@ -331,6 +339,33 @@ class PartialStructType(Type):
f.write('}\n')
f.write('\n')
+class ArrayType(Type):
+ __slots__ = ('element', 'count')
+
+ def __init__(self, element, count):
+ self.element = element
+ self.count = count
+
+ def native_tag(self):
+ return 'Array<%s, %s>' % (self.element.native_tag(), self.count)
+
+ def network_tag(self):
+ return 'NetArray<%s, %s>' % (self.element.network_tag(), self.count)
+
+class EArrayType(Type):
+ __slots__ = ('element', 'index', 'count')
+
+ def __init__(self, element, index, count):
+ self.element = element
+ self.index = index
+ self.count = count
+
+ def native_tag(self):
+ return 'earray<%s, %s, %s>' % (self.element.native_tag(), self.index, self.count)
+
+ def network_tag(self):
+ return 'NetArray<%s, static_cast<size_t>(%s)>' % (self.element.network_tag(), self.count)
+
class Include(object):
__slots__ = ('path', '_types')
@@ -493,9 +528,6 @@ 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')
@@ -508,8 +540,6 @@ 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:
@@ -598,11 +628,15 @@ class Context(object):
f.write(copyright.format(filename=header, description=desc))
f.write('\n')
f.write('# include "fwd.hpp"\n\n')
- f.write('//TODO split the includes\n')
+ f.write('# include "../generic/array.hpp"\n')
+ f.write('# include "../mmo/consts.hpp"\n')
+
+ f.write('\n//TODO split the includes\n')
for inc in self._includes:
f.write(inc.pp(1))
# this is writing another file
inc.testcase(outdir)
+ f.write('\n')
f.write('template<class T>\n')
f.write('bool native_to_network(T *network, T native)\n{\n')
@@ -615,6 +649,48 @@ class Context(object):
f.write(' return true;\n')
f.write('}\n')
+ f.write('template<class T, size_t N>\n')
+ f.write('struct NetArray\n{\n')
+ f.write(' T data[N];\n')
+ f.write('};\n')
+ f.write('template<class T, class U, size_t N>\n')
+ f.write('bool native_to_network(NetArray<T, N> *network, Array<U, N> native)\n{\n')
+ f.write(' for (size_t i = 0; i < N; ++i)\n')
+ f.write(' {\n')
+ f.write(' if (!native_to_network(&(*network).data[i], native[i]))\n')
+ f.write(' return false;\n')
+ f.write(' }\n')
+ f.write(' return true;\n')
+ f.write('}\n')
+ f.write('template<class T, class U, size_t N>\n')
+ f.write('bool network_to_native(Array<U, N> *native, NetArray<T, N> network)\n{\n')
+ f.write(' for (size_t i = 0; i < N; ++i)\n')
+ f.write(' {\n')
+ f.write(' if (!network_to_native(&(*native)[i], network.data[i]))\n')
+ f.write(' return false;\n')
+ f.write(' }\n')
+ f.write(' return true;\n')
+ f.write('}\n')
+ f.write('template<class T, class U, size_t N, class I>\n')
+ f.write('bool native_to_network(NetArray<T, N> *network, earray<U, I, static_cast<I>(N)> native)\n{\n')
+ f.write(' for (size_t i = 0; i < N; ++i)\n')
+ f.write(' {\n')
+ f.write(' if (!native_to_network(&(*network).data[i], native[static_cast<I>(i)]))\n')
+ f.write(' return false;\n')
+ f.write(' }\n')
+ f.write(' return true;\n')
+ f.write('}\n')
+ f.write('template<class T, class U, size_t N, class I>\n')
+ f.write('bool network_to_native(earray<U, I, static_cast<I>(N)> *native, NetArray<T, N> network)\n{\n')
+ f.write(' for (size_t i = 0; i < N; ++i)\n')
+ f.write(' {\n')
+ f.write(' if (!network_to_native(&(*native)[static_cast<I>(i)], network.data[i]))\n')
+ f.write(' return false;\n')
+ f.write(' }\n')
+ f.write(' return true;\n')
+ f.write('}\n')
+ f.write('\n')
+
f.write('template<size_t N>\n')
f.write('struct NetString\n{\n')
f.write(' char data[N];\n')
@@ -710,8 +786,8 @@ class Context(object):
self._types.append(rv)
return rv
- def struct(self, name, body, size):
- rv = StructType(None, name, body, size)
+ def struct(self, name, body, size, ctor=False):
+ rv = StructType(None, name, body, size, ctor)
self._types.append(rv)
return rv
@@ -720,6 +796,16 @@ class Context(object):
self._types.append(rv)
return rv
+ def array(self, element, count):
+ rv = ArrayType(element, count)
+ return rv
+
+ def earray(self, element, index, count=None):
+ if count is None:
+ count = index + '::COUNT'
+ rv = EArrayType(element, index, count)
+ return rv
+
def main():
@@ -739,10 +825,10 @@ def main():
ip_h = ctx.include('src/net/ip.hpp')
timer_th = ctx.include('src/net/timer.t.hpp')
+ consts_h = ctx.include('src/mmo/consts.hpp')
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')
@@ -752,6 +838,10 @@ def main():
clif_th = ctx.include('src/map/clif.t.hpp')
skill_th = ctx.include('src/map/skill.t.hpp')
+ ## primitive types
+ char = NeutralType('char')
+ bit = NeutralType('bool')
+
## included types
uint8_t = cstdint.native('uint8_t')
@@ -767,6 +857,7 @@ def main():
SEX = enums_h.native('SEX')
Option = enums_h.native('Option')
EPOS = enums_h.native('EPOS')
+ ItemLook = enums_h.native('ItemLook')
Species = ids_h.native('Species')
AccountId = ids_h.native('AccountId')
@@ -776,6 +867,8 @@ def main():
BlockId = ids_h.native('BlockId')
GmLevel = ids_h.native('GmLevel')
+ party_member = consts_h.native('PartyMember')
+
HumanTimeDiff = human_time_diff_h.native('HumanTimeDiff')
Version = version_h.native('Version')
@@ -813,13 +906,6 @@ def main():
VERSION_2 = login_th.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')
-
-
Position1 = clif_th.native('Position1')
NetPosition1 = clif_th.network('NetPosition1')
Position2 = clif_th.native('Position2')
@@ -849,7 +935,7 @@ def main():
u32 = ctx.provided(uint32_t, Little32)
u64 = ctx.provided(uint64_t, Little64)
- sex_char = ctx.provided(SEX, NeutralType('char'))
+ sex_char = ctx.provided(SEX, char)
dir = ctx.enum(DIR, u8)
pos1 = ctx.provided(Position1, NetPosition1)
@@ -875,6 +961,7 @@ def main():
sex = ctx.enum(SEX, u8)
option = ctx.enum(Option, u16)
epos = ctx.enum(EPOS, u16)
+ item_look = ctx.enum(ItemLook, u16)
species = ctx.wrap(Species, u16)
account_id = ctx.wrap(AccountId, u32)
@@ -901,19 +988,12 @@ def main():
millis = ctx.string(timestamp_milliseconds_buffer)
account_name = ctx.string(AccountName)
account_pass = ctx.string(AccountPass)
- #account_crypt = ctx.string(AccountCrypt)
account_email = ctx.string(AccountEmail)
server_name = ctx.string(ServerName)
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)
- #item_name = ctx.string(ItemName)
- #md5_string = ctx.string(md5_string)
- #salt_string = ctx.string(SaltString)
# this will be *so* useful when I do the party copy!
human_time_diff = ctx.partial_struct(
@@ -1015,6 +1095,137 @@ def main():
size=37,
)
+ item = ctx.struct(
+ 'Item',
+ [
+ at(None, item_name_id, 'nameid'),
+ at(None, u16, 'amount'),
+ at(None, epos, 'equip'),
+ ],
+ size=None,
+ )
+
+ point = ctx.struct(
+ 'Point',
+ [
+ at(None, map_name, 'map_'),
+ at(None, u16, 'x'),
+ at(None, u16, 'y'),
+ ],
+ size=None,
+ ctor=True,
+ )
+
+ skill_value = ctx.struct(
+ 'SkillValue',
+ [
+ at(None, u16, 'lv'),
+ at(None, skill_flags, 'flags'),
+ ],
+ size=None,
+ )
+
+ global_reg = ctx.struct(
+ 'GlobalReg',
+ [
+ at(None, var_name, 'str'),
+ at(None, u32, 'value'),
+ ],
+ size=None,
+ )
+
+ char_key = ctx.struct(
+ 'CharKey',
+ [
+ at(None, char_name, 'name'),
+ at(None, account_id, 'account id'),
+ at(None, char_id, 'char id'),
+ at(None, u8, 'char num'),
+ ],
+ size=None,
+ )
+ char_data = ctx.struct(
+ 'CharData',
+ [
+ at(None, char_id, 'partner id'),
+ at(None, u32, 'base exp'),
+ at(None, u32, 'job exp'),
+ at(None, u32, 'zeny'),
+ at(None, species, 'species'),
+ at(None, u16, 'status point'),
+ at(None, u16, 'skill point'),
+ at(None, u32, 'hp'),
+ at(None, u32, 'max hp'),
+ at(None, u32, 'sp'),
+ at(None, u32, 'max sp'),
+ at(None, option, 'option'),
+ at(None, u16, 'karma'),
+ at(None, u16, 'manner'),
+ at(None, u16, 'hair'),
+ at(None, u16, 'hair color'),
+ at(None, u16, 'clothes color'),
+ at(None, party_id, 'party id'),
+ at(None, item_look, 'weapon'),
+ at(None, item_name_id, 'shield'),
+ at(None, item_name_id, 'head top'),
+ at(None, item_name_id, 'head mid'),
+ at(None, item_name_id, 'head bottom'),
+ at(None, u8, 'base level'),
+ at(None, u8, 'job level'),
+ at(None, ctx.earray(u16, 'ATTR'), 'attrs'),
+ at(None, sex, 'sex'),
+ at(None, ip4, 'mapip'),
+ at(None, u16, 'mapport'),
+ at(None, point, 'last point'),
+ at(None, point, 'save point'),
+ at(None, ctx.array(item, 'MAX_INVENTORY'), 'inventory'),
+ at(None, ctx.earray(skill_value, 'SkillID', 'MAX_SKILL'), 'skill'),
+ at(None, u32, 'global reg num'),
+ at(None, ctx.array(global_reg, 'GLOBAL_REG_NUM'), 'global reg'),
+ at(None, u32, 'account reg num'),
+ at(None, ctx.array(global_reg, 'ACCOUNT_REG_NUM'), 'account reg'),
+ at(None, u32, 'account reg2 num'),
+ at(None, ctx.array(global_reg, 'ACCOUNT_REG2_NUM'), 'account reg2'),
+ ],
+ size=None,
+ )
+
+ party_member = ctx.partial_struct(
+ party_member,
+ [
+ ('account_id', account_id),
+ ('name', char_name),
+ ('map', map_name),
+ ('leader', u32),
+ ('online', u32),
+ ('lv', u32),
+ ]
+ )
+
+ party_most = ctx.struct(
+ 'PartyMost',
+ [
+ at(None, party_name, 'name'),
+ at(None, u32, 'exp'),
+ at(None, u32, 'item'),
+ at(None, ctx.array(party_member, 'MAX_PARTY'), 'member'),
+ ],
+ size=None,
+ )
+
+ storage = ctx.struct(
+ 'Storage',
+ [
+ at(None, bit, 'dirty'),
+ at(None, account_id, 'account id'),
+ at(None, u16, 'storage status'),
+ at(None, u16, 'storage amount'),
+ at(None, ctx.array(item, 'MAX_STORAGE'), 'storage_'),
+ ],
+ size=None,
+ )
+
+
## packet channels
# this is a somewhat simplistic view. For packets that get forwarded,