diff options
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'>( ®->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, |