diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-04-22 11:46:23 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-04-22 13:20:52 -0700 |
commit | ad049a15b43b7ddba3fe7d0a898652fc8022629d (patch) | |
tree | 142624e70ead3e89a8da6d56de41651f171524d0 /src/char/char.cpp | |
parent | ceeda2e337077b2edaf1af09cc4df2c30e8205a1 (diff) | |
download | tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.tar.gz tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.tar.bz2 tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.tar.xz tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.zip |
Use strict ID types
Possibly some missing for the far side of the network.
AccountId and BlockId are still terribly entangled.
Diffstat (limited to 'src/char/char.cpp')
-rw-r--r-- | src/char/char.cpp | 307 |
1 files changed, 166 insertions, 141 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp index 87e48cb..f714dda 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -42,6 +42,7 @@ #include "../compat/alg.hpp" #include "../ints/cmp.hpp" +#include "../ints/udl.hpp" #include "../strings/mstring.hpp" #include "../strings/astring.hpp" @@ -117,10 +118,14 @@ static int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor] static std::bitset<256> char_name_letters; // list of letters/symbols authorised (or not) in a character name. by [Yor] +static constexpr +GmLevel default_gm_level = GmLevel::from(0_u32); + struct char_session_data : SessionData { - int account_id, login_id1, login_id2; + AccountId account_id; + int login_id1, login_id2; SEX sex; unsigned short packet_tmw_version; AccountEmail email; @@ -134,8 +139,8 @@ void SessionDeleter::operator()(SessionData *sd) struct AuthFifoEntry { - int account_id; - int char_id; + AccountId account_id; + CharId char_id; int login_id1, login_id2; IP4Address ip; int delflag; @@ -152,7 +157,7 @@ static int check_ip_flag = 1; // It's to check IP of a player between char-server and other servers (part of anti-hacking system) static -int char_id_count = 150000; +CharId char_id_count = wrap<CharId>(150000); static std::vector<CharPair> char_keys; static @@ -177,7 +182,7 @@ int online_sorting_option = 0; // sorting option to display online players in on static int online_refresh_html = 20; // refresh time (in sec) of the html file in the explorer static -int online_gm_display_min_level = 20; // minimum GM level to display 'GM' when we want to display it +GmLevel online_gm_display_min_level = GmLevel::from(20_u32); // minimum GM level to display 'GM' when we want to display it static std::vector<Session *> online_chars; // same size of char_keys, and id value of current server (or -1) @@ -235,12 +240,12 @@ void char_log(XString line) // and returns its level (or 0 if it isn't a GM account or if not found) //---------------------------------------------------------------------- static -int isGM(int account_id) +GmLevel isGM(AccountId account_id) { for (GM_Account& gma : gm_accounts) if (gma.account_id == account_id) return gma.level; - return 0; + return default_gm_level; } //---------------------------------------------- @@ -266,7 +271,7 @@ const CharPair *search_character(CharName character_name) return nullptr; } -const CharPair *search_character_id(int char_id) +const CharPair *search_character_id(CharId char_id) { for (const CharPair& cd : char_keys) { @@ -342,7 +347,7 @@ AString mmo_char_tostr(struct CharPair *cp) if (p->inventory[i].nameid) { str_p += STRPRINTF("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d "_fmt, - p->inventory[i].id, + 0 /*id*/, p->inventory[i].nameid, p->inventory[i].amount, p->inventory[i].equip, @@ -450,7 +455,7 @@ bool extract(XString str, CharPair *cp) return false; // TODO replace *every* lookup with a map lookup - static std::set<int> seen_ids; + static std::set<CharId> seen_ids; static std::set<CharName> seen_names; // we don't have to worry about deleted characters, // this is only called during startup @@ -518,8 +523,8 @@ int mmo_char_init(void) continue; { - int i, j = 0; - if (SSCANF(line, "%d\t%%newid%%%n"_fmt, &i, &j) == 1 && j > 0) + CharId i; + if (extract(line, record<'\t'>(&i, "%newid%"_s))) { if (char_id_count < i) char_id_count = i; @@ -533,8 +538,8 @@ int mmo_char_init(void) CHAR_LOG("Char skipped\n%s"_fmt, line); continue; } - if (cd.key.char_id >= char_id_count) - char_id_count = cd.key.char_id + 1; + if (char_id_count < next(cd.key.char_id)) + char_id_count = next(cd.key.char_id); char_keys.push_back(std::move(cd)); online_chars.push_back(nullptr); } @@ -740,11 +745,11 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui CharKey& ck = cp.key; CharData& cd = *cp.data; - ck.char_id = char_id_count++; + ck.char_id = char_id_count; char_id_count = next(char_id_count); ck.account_id = sd->account_id; ck.char_num = slot; ck.name = name; - cd.species = 0; + cd.species = Species(); cd.base_level = 1; cd.job_level = 1; cd.base_exp = 0; @@ -765,17 +770,17 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui cd.option = static_cast<Option>(0x0000); // Option is only declared cd.karma = 0; cd.manner = 0; - cd.party_id = 0; + cd.party_id = PartyId(); //cd.guild_id = 0; cd.hair = hair_style; cd.hair_color = hair_color; cd.clothes_color = 0; // removed initial armor/weapon - unused and problematic cd.weapon = ItemLook::NONE; - cd.shield = 0; - cd.head_top = 0; - cd.head_mid = 0; - cd.head_bottom = 0; + cd.shield = ItemNameId(); + cd.head_top = ItemNameId(); + cd.head_mid = ItemNameId(); + cd.head_bottom = ItemNameId(); cd.last_point = start_point; cd.save_point = start_point; char_keys.push_back(std::move(cp)); @@ -844,16 +849,16 @@ void create_online_files(void) // displaying the character name { // without/with 'GM' display - int gml = isGM(cd.key.account_id); + GmLevel gml = isGM(cd.key.account_id); { - if (gml >= online_gm_display_min_level) + if (gml.satisfies(online_gm_display_min_level)) FPRINTF(fp, "%-24s (GM) "_fmt, cd.key.name); else FPRINTF(fp, "%-24s "_fmt, cd.key.name); } // name of the character in the html (no < >, because that create problem in html code) FPRINTF(fp2, " <td>"_fmt); - if (gml >= online_gm_display_min_level) + if (gml.satisfies(online_gm_display_min_level)) FPRINTF(fp2, "<b>"_fmt); for (char c : cd.key.name.to__actual()) { @@ -873,7 +878,7 @@ void create_online_files(void) break; }; } - if (gml >= online_gm_display_min_level) + if (gml.satisfies(online_gm_display_min_level)) FPRINTF(fp2, "</b> (GM)"_fmt); FPRINTF(fp2, "</td>\n"_fmt); } @@ -927,14 +932,14 @@ int count_users(void) // [Fate] Find inventory item based on equipment mask, return view. ID must match view ID (!). //---------------------------------------- static -int find_equip_view(const CharPair *cp, EPOS equipmask) +ItemNameId find_equip_view(const CharPair *cp, EPOS equipmask) { CharData *p = cp->data.get(); for (int i = 0; i < MAX_INVENTORY; i++) if (p->inventory[i].nameid && p->inventory[i].amount && bool(p->inventory[i].equip & equipmask)) return p->inventory[i].nameid; - return 0; + return ItemNameId(); } //---------------------------------------- @@ -969,39 +974,39 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd) const CharKey *k = &cp->key; const CharData *p = cp->data.get(); - WFIFOL(s, j) = k->char_id; + WFIFOL(s, j) = unwrap<CharId>(k->char_id); WFIFOL(s, j + 4) = p->base_exp; WFIFOL(s, j + 8) = p->zeny; WFIFOL(s, j + 12) = p->job_exp; WFIFOL(s, j + 16) = p->job_level; - WFIFOW(s, j + 20) = find_equip_view(cp, EPOS::SHOES); - WFIFOW(s, j + 22) = find_equip_view(cp, EPOS::GLOVES); - WFIFOW(s, j + 24) = find_equip_view(cp, EPOS::CAPE); - WFIFOW(s, j + 26) = find_equip_view(cp, EPOS::MISC1); + WFIFOW(s, j + 20) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::SHOES)); + WFIFOW(s, j + 22) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::GLOVES)); + WFIFOW(s, j + 24) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::CAPE)); + WFIFOW(s, j + 26) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::MISC1)); WFIFOL(s, j + 28) = static_cast<uint16_t>(p->option); WFIFOL(s, j + 32) = p->karma; WFIFOL(s, j + 36) = p->manner; WFIFOW(s, j + 40) = p->status_point; - WFIFOW(s, j + 42) = (p->hp > 0x7fff) ? 0x7fff : p->hp; - WFIFOW(s, j + 44) = (p->max_hp > 0x7fff) ? 0x7fff : p->max_hp; - WFIFOW(s, j + 46) = (p->sp > 0x7fff) ? 0x7fff : p->sp; - WFIFOW(s, j + 48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp; + WFIFOW(s, j + 42) = std::min(p->hp, 0x7fff); + WFIFOW(s, j + 44) = std::min(p->max_hp, 0x7fff); + WFIFOW(s, j + 46) = std::min(p->sp, 0x7fff); + WFIFOW(s, j + 48) = std::min(p->max_sp, 0x7fff); WFIFOW(s, j + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed; - WFIFOW(s, j + 52) = p->species; + WFIFOW(s, j + 52) = unwrap<Species>(p->species); WFIFOW(s, j + 54) = p->hair; // WFIFOW(s,j+56) = p->weapon; // dont send weapon since TMW does not support it WFIFOW(s, j + 56) = 0; WFIFOW(s, j + 58) = p->base_level; WFIFOW(s, j + 60) = p->skill_point; - WFIFOW(s, j + 62) = p->head_bottom; - WFIFOW(s, j + 64) = p->shield; - WFIFOW(s, j + 66) = p->head_top; - WFIFOW(s, j + 68) = p->head_mid; + WFIFOW(s, j + 62) = unwrap<ItemNameId>(p->head_bottom); + WFIFOW(s, j + 64) = unwrap<ItemNameId>(p->shield); + WFIFOW(s, j + 66) = unwrap<ItemNameId>(p->head_top); + WFIFOW(s, j + 68) = unwrap<ItemNameId>(p->head_mid); WFIFOW(s, j + 70) = p->hair_color; - WFIFOW(s, j + 72) = find_equip_view(cp, EPOS::MISC2); + WFIFOW(s, j + 72) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::MISC2)); // WFIFOW(s,j+72) = p->clothes_color; WFIFO_STRING(s, j + 74, k->name.to__actual(), 24); @@ -1021,7 +1026,7 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd) } static -int set_account_reg2(int acc, Slice<global_reg> reg) +int set_account_reg2(AccountId acc, Slice<global_reg> reg) { size_t num = reg.size(); assert (num < ACCOUNT_REG2_NUM); @@ -1053,43 +1058,44 @@ int char_divorce(CharPair *cp) CharKey *ck = &cp->key; CharData *cs = cp->data.get(); - if (cs->partner_id <= 0) + if (!cs->partner_id) { WBUFW(buf, 0) = 0x2b12; - WBUFL(buf, 2) = ck->char_id; - WBUFL(buf, 6) = 0; // partner id 0 means failure + WBUFL(buf, 2) = unwrap<CharId>(ck->char_id); + // partner id 0 means failure + WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); mapif_sendall(buf, 10); return 0; } WBUFW(buf, 0) = 0x2b12; - WBUFL(buf, 2) = ck->char_id; + WBUFL(buf, 2) = unwrap<CharId>(ck->char_id); for (CharPair& cd : char_keys) { if (cd.key.char_id == cs->partner_id && cd.data->partner_id == ck->char_id) { - WBUFL(buf, 6) = cs->partner_id; + WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); mapif_sendall(buf, 10); - cs->partner_id = 0; - cd.data->partner_id = 0; + cs->partner_id = CharId(); + cd.data->partner_id = CharId(); return 0; } // The other char doesn't have us as their partner, so just clear our partner // Don't worry about this, as the map server should verify itself that the other doesn't have us as a partner, and so won't mess with their marriage else if (cd.key.char_id == cs->partner_id) { - WBUFL(buf, 6) = cs->partner_id; + WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); mapif_sendall(buf, 10); - cs->partner_id = 0; + cs->partner_id = CharId(); return 0; } } // Our partner wasn't found, so just clear our marriage - WBUFL(buf, 6) = cs->partner_id; - cs->partner_id = 0; + WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id); + cs->partner_id = CharId(); mapif_sendall(buf, 10); return 0; @@ -1099,25 +1105,24 @@ int char_divorce(CharPair *cp) // Force disconnection of an online player (with account value) by [Yor] //---------------------------------------------------------------------- static -int disconnect_player(int accound_id) +void disconnect_player(AccountId accound_id) { // disconnect player if online on char-server for (io::FD i : iter_fds()) { - if (!get_session(i)) + Session *s = get_session(i); + if (!s) continue; - struct char_session_data *sd = static_cast<char_session_data *>(get_session(i)->session_data.get()); + struct char_session_data *sd = static_cast<char_session_data *>(s->session_data.get()); if (sd) { if (sd->account_id == accound_id) { - get_session(i)->set_eof(); - return 1; + s->set_eof(); + return; } } } - - return 0; } // キャラ削除に伴うデータ削除 @@ -1138,7 +1143,7 @@ int char_delete(CharPair *cp) { unsigned char buf[6]; WBUFW(buf, 0) = 0x2afe; - WBUFL(buf, 2) = ck->account_id; + WBUFL(buf, 2) = unwrap<AccountId>(ck->account_id); mapif_sendall(buf, 6); } @@ -1193,11 +1198,12 @@ void parse_tologin(Session *ls) return; for (io::FD i : iter_fds()) { + AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); Session *s2 = get_session(i); if (!s2) continue; sd = static_cast<char_session_data *>(s2->session_data.get()); - if (sd && sd->account_id == RFIFOL(ls, 2)) + if (sd && sd->account_id == acc) { if (RFIFOB(ls, 6) != 0) { @@ -1234,13 +1240,14 @@ void parse_tologin(Session *ls) return; for (io::FD i : iter_fds()) { + AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); Session *s2 = get_session(i); if (!s2) continue; sd = static_cast<char_session_data *>(s2->session_data.get()); if (sd) { - if (sd->account_id == RFIFOL(ls, 2)) + if (sd->account_id == acc) { sd->email = stringish<AccountEmail>(RFIFO_STRING<40>(ls, 6)); if (!e_mail_check(sd->email)) @@ -1257,10 +1264,12 @@ void parse_tologin(Session *ls) if (RFIFOREST(ls) < 10) return; { + AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); + GmLevel gml = GmLevel::from(RFIFOL(ls, 2)); unsigned char buf[10]; WBUFW(buf, 0) = 0x2b0b; - WBUFL(buf, 2) = RFIFOL(ls, 2); // account - WBUFL(buf, 6) = RFIFOL(ls, 6); // GM level + WBUFL(buf, 2) = unwrap<AccountId>(acc); + WBUFL(buf, 6) = gml.get_all_bits(); mapif_sendall(buf, 10); } RFIFOSKIP(ls, 10); @@ -1271,10 +1280,10 @@ void parse_tologin(Session *ls) return; { unsigned char buf[7]; - int acc = RFIFOL(ls, 2); + AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); SEX sex = static_cast<SEX>(RFIFOB(ls, 6)); RFIFOSKIP(ls, 7); - if (acc > 0) + if (acc) { for (CharPair& cp : char_keys) { @@ -1292,17 +1301,17 @@ void parse_tologin(Session *ls) cd.inventory[j].equip = EPOS::ZERO; } cd.weapon = ItemLook::NONE; - cd.shield = 0; - cd.head_top = 0; - cd.head_mid = 0; - cd.head_bottom = 0; + cd.shield = ItemNameId(); + cd.head_top = ItemNameId(); + cd.head_mid = ItemNameId(); + cd.head_bottom = ItemNameId(); } } // disconnect player if online on char-server disconnect_player(acc); } WBUFW(buf, 0) = 0x2b0d; - WBUFL(buf, 2) = acc; + WBUFL(buf, 2) = unwrap<AccountId>(acc); WBUFB(buf, 6) = static_cast<uint8_t>(sex); mapif_sendall(buf, 7); } @@ -1353,8 +1362,8 @@ void parse_tologin(Session *ls) return; { Array<struct global_reg, ACCOUNT_REG2_NUM> reg; - int j, p, acc; - acc = RFIFOL(ls, 4); + int j, p; + AccountId acc = wrap<AccountId>(RFIFOL(ls, 4)); for (p = 8, j = 0; p < RFIFOW(ls, 2) && j < ACCOUNT_REG2_NUM; p += 36, j++) @@ -1377,13 +1386,13 @@ void parse_tologin(Session *ls) { // [Fate] Itemfrob package: forwarded from login-server if (RFIFOREST(ls) < 10) return; - int source_id = RFIFOL(ls, 2); - int dest_id = RFIFOL(ls, 6); + ItemNameId source_id = wrap<ItemNameId>(RFIFOL(ls, 2)); + ItemNameId dest_id = wrap<ItemNameId>(RFIFOL(ls, 6)); unsigned char buf[10]; WBUFW(buf, 0) = 0x2afa; - WBUFL(buf, 2) = source_id; - WBUFL(buf, 6) = dest_id; + WBUFL(buf, 2) = unwrap<ItemNameId>(source_id); + WBUFL(buf, 6) = unwrap<ItemNameId>(dest_id); mapif_sendall(buf, 10); // forward package to map servers for (CharPair& cp : char_keys) @@ -1425,6 +1434,9 @@ void parse_tologin(Session *ls) case 0x2730: if (RFIFOREST(ls) < 6) return; + { + AccountId aid = wrap<AccountId>(RFIFOL(ls, 2)); + // Deletion of all characters of the account //#warning "This comment is a lie, but it's still true." // needs to use index because they may move during resize @@ -1432,7 +1444,7 @@ void parse_tologin(Session *ls) { CharPair& cp = char_keys[idx]; CharKey& ck = cp.key; - if (ck.account_id == RFIFOL(ls, 2)) + if (ck.account_id == aid) { char_delete(&cp); if (&cp != &char_keys.back()) @@ -1441,7 +1453,7 @@ void parse_tologin(Session *ls) // if moved character owns to deleted account, check again it's character // YES this is the newly swapped one // we could avoid this by working backwards - if (ck.account_id == RFIFOL(ls, 2)) + if (ck.account_id == aid) { idx--; // Correct moved character reference in the character's owner by [Yor] @@ -1451,16 +1463,17 @@ void parse_tologin(Session *ls) } } // Deletion of the storage - inter_storage_delete(RFIFOL(ls, 2)); + inter_storage_delete(aid); // send to all map-servers to disconnect the player { unsigned char buf[6]; WBUFW(buf, 0) = 0x2b13; - WBUFL(buf, 2) = RFIFOL(ls, 2); + WBUFL(buf, 2) = unwrap<AccountId>(aid); mapif_sendall(buf, 6); } // disconnect player if online on char-server - disconnect_player(RFIFOL(ls, 2)); + disconnect_player(aid); + } RFIFOSKIP(ls, 6); break; @@ -1468,17 +1481,20 @@ void parse_tologin(Session *ls) case 0x2731: if (RFIFOREST(ls) < 11) return; + { + AccountId aid = wrap<AccountId>(RFIFOL(ls, 2)); // send to all map-servers to disconnect the player { unsigned char buf[11]; WBUFW(buf, 0) = 0x2b14; - WBUFL(buf, 2) = RFIFOL(ls, 2); + WBUFL(buf, 2) = unwrap<AccountId>(aid); WBUFB(buf, 6) = RFIFOB(ls, 6); // 0: change of statut, 1: ban WBUFL(buf, 7) = RFIFOL(ls, 7); // status or final date of a banishment mapif_sendall(buf, 11); } // disconnect player if online on char-server - disconnect_player(RFIFOL(ls, 2)); + disconnect_player(aid); + } RFIFOSKIP(ls, 11); break; @@ -1493,7 +1509,7 @@ void parse_tologin(Session *ls) gm_accounts.reserve((len - 4) / 5); for (int i = 4; i < len; i += 5) { - gm_accounts.push_back({static_cast<int>(RFIFOL(ls, i)), RFIFOB(ls, i + 4)}); + gm_accounts.push_back({wrap<AccountId>(RFIFOL(ls, i)), GmLevel::from(static_cast<uint32_t>(RFIFOB(ls, i + 4)))}); } PRINTF("From login-server: receiving of %zu GM accounts information.\n"_fmt, gm_accounts.size()); @@ -1512,7 +1528,7 @@ void parse_tologin(Session *ls) if (RFIFOREST(ls) < 7) return; { - int acc = RFIFOL(ls, 2); + AccountId acc = wrap<AccountId>(RFIFOL(ls, 2)); int status = RFIFOB(ls, 6); for (io::FD i : iter_fds()) @@ -1668,8 +1684,8 @@ void parse_frommap(Session *ms) if (RFIFOREST(ms) < 22) return; { - int account_id = RFIFOL(ms, 2); - int char_id = RFIFOL(ms, 6); + AccountId account_id = wrap<AccountId>(RFIFOL(ms, 2)); + CharId char_id = wrap<CharId>(RFIFOL(ms, 6)); int login_id1 = RFIFOL(ms, 10); int login_id2 = RFIFOL(ms, 14); IP4Address ip = RFIFOIP(ms, 18); @@ -1700,7 +1716,7 @@ void parse_frommap(Session *ms) afi.delflag = 1; WFIFOW(ms, 0) = 0x2afd; WFIFOW(ms, 2) = 18 + sizeof(*ck) + sizeof(*cd); - WFIFOL(ms, 4) = account_id; + WFIFOL(ms, 4) = unwrap<AccountId>(account_id); WFIFOL(ms, 8) = afi.login_id2; WFIFOL(ms, 12) = static_cast<time_t>(afi.connect_until_time); cd->sex = afi.sex; @@ -1716,7 +1732,7 @@ void parse_frommap(Session *ms) } { WFIFOW(ms, 0) = 0x2afe; - WFIFOL(ms, 2) = account_id; + WFIFOL(ms, 2) = unwrap<AccountId>(account_id); WFIFOSET(ms, 6); PRINTF("auth_fifo search error! account %d not authentified.\n"_fmt, account_id); @@ -1743,7 +1759,7 @@ void parse_frommap(Session *ms) // add online players in the list by [Yor] for (int i = 0; i < server[id].users; i++) { - int char_id = RFIFOL(ms, 6 + i * 4); + CharId char_id = wrap<CharId>(RFIFOL(ms, 6 + i * 4)); for (const CharPair& cd : char_keys) { if (cd.key.char_id == char_id) @@ -1768,16 +1784,20 @@ void parse_frommap(Session *ms) case 0x2b01: if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) return; + { + AccountId aid = wrap<AccountId>(RFIFOL(ms, 4)); + CharId cid = wrap<CharId>(RFIFOL(ms, 8)); for (CharPair& cd : char_keys) { - if (cd.key.account_id == RFIFOL(ms, 4) && - cd.key.char_id == RFIFOL(ms, 8)) + if (cd.key.account_id == aid && + cd.key.char_id == cid) { RFIFO_STRUCT(ms, 12, cd.key); RFIFO_STRUCT(ms, 12 + sizeof(cd.key), *cd.data); break; } } + } RFIFOSKIP(ms, RFIFOW(ms, 2)); break; @@ -1786,11 +1806,11 @@ void parse_frommap(Session *ms) if (RFIFOREST(ms) < 18) return; { - int account_id = RFIFOL(ms, 2); + AccountId account_id = wrap<AccountId>(RFIFOL(ms, 2)); if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); auth_fifo_iter->account_id = account_id; - auth_fifo_iter->char_id = 0; + auth_fifo_iter->char_id = CharId(); auth_fifo_iter->login_id1 = RFIFOL(ms, 6); auth_fifo_iter->login_id2 = RFIFOL(ms, 10); auth_fifo_iter->delflag = 2; @@ -1798,7 +1818,7 @@ void parse_frommap(Session *ms) auth_fifo_iter->ip = RFIFOIP(ms, 14); auth_fifo_iter++; WFIFOW(ms, 0) = 0x2b03; - WFIFOL(ms, 2) = account_id; + WFIFOL(ms, 2) = unwrap<AccountId>(account_id); WFIFOB(ms, 6) = 0; WFIFOSET(ms, 7); } @@ -1815,8 +1835,8 @@ void parse_frommap(Session *ms) RFIFO_WFIFO_CLONE(ms, ms, 44); // overwrite WFIFOW(ms, 0) = 0x2b06; - auth_fifo_iter->account_id = RFIFOL(ms, 2); - auth_fifo_iter->char_id = RFIFOL(ms, 14); + auth_fifo_iter->account_id = wrap<AccountId>(RFIFOL(ms, 2)); + auth_fifo_iter->char_id = wrap<CharId>(RFIFOL(ms, 14)); auth_fifo_iter->login_id1 = RFIFOL(ms, 6); auth_fifo_iter->login_id2 = RFIFOL(ms, 10); auth_fifo_iter->delflag = 0; @@ -1827,13 +1847,17 @@ void parse_frommap(Session *ms) // default, if not found in the loop WFIFOW(ms, 6) = 1; for (const CharPair& cd : char_keys) - if (cd.key.account_id == RFIFOL(ms, 2) && - cd.key.char_id == RFIFOL(ms, 14)) + { + AccountId aid = wrap<AccountId>(RFIFOL(ms, 2)); + CharId cid = wrap<CharId>(RFIFOL(ms, 14)); + if (cd.key.account_id == aid && + cd.key.char_id == cid) { auth_fifo_iter++; WFIFOL(ms, 6) = 0; break; } + } WFIFOSET(ms, 44); RFIFOSKIP(ms, 49); break; @@ -1880,12 +1904,12 @@ void parse_frommap(Session *ms) if (RFIFOREST(ms) < 44) return; { - int acc = RFIFOL(ms, 2); // account_id of who ask (-1 if nobody) + AccountId acc = wrap<AccountId>(RFIFOL(ms, 2)); // account_id of who ask (-1 if nobody) CharName character_name = stringish<CharName>(RFIFO_STRING<24>(ms, 6)); int operation = RFIFOW(ms, 30); // prepare answer WFIFOW(ms, 0) = 0x2b0f; // answer - WFIFOL(ms, 2) = acc; // who want do operation + WFIFOL(ms, 2) = unwrap<AccountId>(acc); // who want do operation WFIFOW(ms, 30) = operation; // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5-changesex // search character const CharPair *cd = search_character(character_name); @@ -1897,13 +1921,13 @@ void parse_frommap(Session *ms) switch (RFIFOW(ms, 30)) { case 1: // block - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server WFIFOW(login_session, 0) = 0x2724; - WFIFOL(login_session, 2) = ck->account_id; // account value + WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value WFIFOL(login_session, 6) = 5; // status of the account WFIFOSET(login_session, 10); } @@ -1914,13 +1938,13 @@ void parse_frommap(Session *ms) WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline break; case 2: // ban - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server WFIFOW(login_session, 0) = 0x2725; - WFIFOL(login_session, 2) = ck->account_id; // account value + WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value HumanTimeDiff ban_change; RFIFO_STRUCT(ms, 32, ban_change); WFIFO_STRUCT(login_session, 6, ban_change); @@ -1933,13 +1957,13 @@ void parse_frommap(Session *ms) WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline break; case 3: // unblock - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server WFIFOW(login_session, 0) = 0x2724; - WFIFOL(login_session, 2) = ck->account_id; // account value + WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value WFIFOL(login_session, 6) = 0; // status of the account WFIFOSET(login_session, 10); } @@ -1950,13 +1974,13 @@ void parse_frommap(Session *ms) WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline break; case 4: // unban - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server WFIFOW(login_session, 0) = 0x272a; - WFIFOL(login_session, 2) = ck->account_id; // account value + WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value WFIFOSET(login_session, 6); } else @@ -1966,13 +1990,13 @@ void parse_frommap(Session *ms) WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline break; case 5: // changesex - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server WFIFOW(login_session, 0) = 0x2727; - WFIFOL(login_session, 2) = ck->account_id; // account value + WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value WFIFOSET(login_session, 6); } else @@ -1990,7 +2014,7 @@ void parse_frommap(Session *ms) WFIFOW(ms, 32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline } // send answer if a player ask, not if the server ask - if (acc != -1) + if (acc) { WFIFOSET(ms, 34); } @@ -2007,7 +2031,7 @@ void parse_frommap(Session *ms) { Array<struct global_reg, ACCOUNT_REG2_NUM> reg; int p, j; - int acc = RFIFOL(ms, 4); + AccountId acc = wrap<AccountId>(RFIFOL(ms, 4)); for (p = 8, j = 0; p < RFIFOW(ms, 2) && j < ACCOUNT_REG2_NUM; p += 36, j++) @@ -2033,8 +2057,9 @@ void parse_frommap(Session *ms) if (RFIFOREST(ms) < 4) return; { + CharId cid = wrap<CharId>(RFIFOL(ms, 2)); for (CharPair& cd : char_keys) - if (cd.key.char_id == RFIFOL(ms, 2)) + if (cd.key.char_id == cid) { char_divorce(&cd); break; @@ -2144,7 +2169,7 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP } } WFIFOW(s, 0) = 0x71; - WFIFOL(s, 2) = ck->char_id; + WFIFOL(s, 2) = unwrap<CharId>(ck->char_id); WFIFO_STRING(s, 6, cd->last_point.map_, 16); PRINTF("Character selection '%s' (account: %d, slot: %d) [%s]\n"_fmt, ck->name, @@ -2204,7 +2229,7 @@ void parse_char(Session *s) return; { WFIFOW(login_session, 0) = 0x2740; - WFIFOL(login_session, 2) = sd->account_id; + WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id); AccountPass old_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 2)); WFIFO_STRING(login_session, 6, old_pass, 24); AccountPass new_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); @@ -2218,8 +2243,8 @@ void parse_char(Session *s) if (RFIFOREST(s) < 17) return; { - int account_id = RFIFOL(s, 2); - int GM_value = isGM(account_id); + AccountId account_id = wrap<AccountId>(RFIFOL(s, 2)); + GmLevel GM_value = isGM(account_id); if (GM_value) PRINTF("Account Logged On; Account ID: %d (GM level %d).\n"_fmt, account_id, GM_value); @@ -2239,7 +2264,7 @@ void parse_char(Session *s) sd->packet_tmw_version = RFIFOW(s, 14); sd->sex = static_cast<SEX>(RFIFOB(s, 16)); // send back account_id - WFIFOL(s, 0) = account_id; + WFIFOL(s, 0) = unwrap<AccountId>(account_id); WFIFOSET(s, 4); // search authentification for (AuthFifoEntry& afi : auth_fifo) @@ -2259,7 +2284,7 @@ void parse_char(Session *s) { // don't send request if no login-server // request to login-server to obtain e-mail/time limit WFIFOW(login_session, 0) = 0x2716; - WFIFOL(login_session, 2) = sd->account_id; + WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id); WFIFOSET(login_session, 6); } // Record client version @@ -2284,7 +2309,7 @@ void parse_char(Session *s) { // don't send request if no login-server WFIFOW(login_session, 0) = 0x2712; // ask login-server to authentify an account - WFIFOL(login_session, 2) = sd->account_id; + WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id); WFIFOL(login_session, 6) = sd->login_id1; WFIFOL(login_session, 10) = sd->login_id2; // relate to the versions higher than 18 WFIFOB(login_session, 14) = static_cast<uint8_t>(sd->sex); @@ -2336,7 +2361,7 @@ void parse_char(Session *s) WFIFOW(s, 0) = 0x6d; WFIFO_ZERO(s, 2, 106); - WFIFOL(s, 2) = ck->char_id; + WFIFOL(s, 2) = unwrap<CharId>(ck->char_id); WFIFOL(s, 2 + 4) = cd->base_exp; WFIFOL(s, 2 + 8) = cd->zeny; WFIFOL(s, 2 + 12) = cd->job_exp; @@ -2351,15 +2376,15 @@ void parse_char(Session *s) WFIFOW(s, 2 + 46) = saturate<int16_t>(cd->sp); WFIFOW(s, 2 + 48) = saturate<int16_t>(cd->max_sp); WFIFOW(s, 2 + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // cd->speed; - WFIFOW(s, 2 + 52) = cd->species; + WFIFOW(s, 2 + 52) = unwrap<Species>(cd->species); WFIFOW(s, 2 + 54) = cd->hair; WFIFOW(s, 2 + 58) = cd->base_level; WFIFOW(s, 2 + 60) = cd->skill_point; - WFIFOW(s, 2 + 64) = cd->shield; - WFIFOW(s, 2 + 66) = cd->head_top; - WFIFOW(s, 2 + 68) = cd->head_mid; + WFIFOW(s, 2 + 64) = unwrap<ItemNameId>(cd->shield); + WFIFOW(s, 2 + 66) = unwrap<ItemNameId>(cd->head_top); + WFIFOW(s, 2 + 68) = unwrap<ItemNameId>(cd->head_mid); WFIFOW(s, 2 + 70) = cd->hair_color; WFIFO_STRING(s, 2 + 74, ck->name.to__actual(), 24); @@ -2387,10 +2412,11 @@ void parse_char(Session *s) { { + CharId cid = wrap<CharId>(RFIFOL(s, 2)); CharPair *cs = nullptr; for (CharPair& cd : char_keys) { - if (cd.key.char_id == RFIFOL(s, 2)) + if (cd.key.char_id == cid) { cs = &cd; break; @@ -2467,8 +2493,8 @@ void parse_char(Session *s) WFIFOW(s, 0) = 0x2b15; for (const GM_Account& gma : gm_accounts) { - WFIFOL(s, len) = gma.account_id; - WFIFOB(s, len + 4) = gma.level; + WFIFOL(s, len) = unwrap<AccountId>(gma.account_id); + WFIFOB(s, len + 4) = gma.level.get_all_bits(); len += 5; } WFIFOW(s, 2) = len; @@ -2794,10 +2820,9 @@ bool char_config(XString w1, ZString w2) online_sorting_option = atoi(w2.c_str()); } else if (w1 == "online_gm_display_min_level"_s) - { // minimum GM level to display 'GM' when we want to display it - online_gm_display_min_level = atoi(w2.c_str()); - if (online_gm_display_min_level < 5) // send online file every 5 seconds to player is enough - online_gm_display_min_level = 5; + { + // minimum GM level to display 'GM' when we want to display it + return extract(w2, &online_gm_display_min_level); } else if (w1 == "online_refresh_html"_s) { |