From 1e77f5dc8d95bbf912205c85274d294a80ea65c9 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 23 Feb 2013 14:28:21 -0800 Subject: Replace struct dbt with typesafe std::map wrappers Also fix broken save/accreg.txt reading. --- src/char/int_party.cpp | 166 +++++++-------- src/char/int_party.hpp | 2 +- src/char/int_storage.cpp | 40 ++-- src/char/int_storage.hpp | 2 +- src/char/inter.cpp | 93 ++++---- src/common/db.cpp | 545 ----------------------------------------------- src/common/db.hpp | 174 ++++++++------- src/login/login.cpp | 42 ++-- src/map/itemdb.cpp | 37 ++-- src/map/itemdb.hpp | 2 +- src/map/map.cpp | 124 ++++------- src/map/map.hpp | 6 +- src/map/mob.cpp | 14 +- src/map/npc.cpp | 124 ++++------- src/map/party.cpp | 33 ++- src/map/script.cpp | 115 ++++------ src/map/script.hpp | 10 +- src/map/storage.cpp | 47 +--- src/map/storage.hpp | 2 +- 19 files changed, 433 insertions(+), 1145 deletions(-) diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 065398a..c64b208 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -17,7 +17,7 @@ char party_txt[1024] = "save/party.txt"; static -struct dbt *party_db; +Map party_db; static int party_newid = 100; @@ -26,7 +26,7 @@ int mapif_party_broken(int party_id, int flag); static int party_check_empty(struct party *p); static -int mapif_parse_PartyLeave(int fd, int party_id, int account_id); +void mapif_parse_PartyLeave(int fd, int party_id, int account_id); // パーティデータの文字列への変換 static @@ -94,13 +94,10 @@ int inter_party_fromstr(char *str, struct party *p) int inter_party_init(void) { char line[8192]; - struct party *p; FILE *fp; int c = 0; int i, j; - party_db = numdb_init(); - if ((fp = fopen_(party_txt, "r")) == NULL) return 1; @@ -115,19 +112,18 @@ int inter_party_init(void) continue; } - CREATE(p, struct party, 1); - if (inter_party_fromstr(line, p) == 0 && p->party_id > 0) + struct party p {}; + if (inter_party_fromstr(line, &p) == 0 && p.party_id > 0) { - if (p->party_id >= party_newid) - party_newid = p->party_id + 1; - numdb_insert(party_db, p->party_id, p); - party_check_empty(p); + if (p.party_id >= party_newid) + party_newid = p.party_id + 1; + party_db.insert(p.party_id, p); + party_check_empty(&p); } else { PRINTF("int_party: broken data [%s] line %d\n", party_txt, c + 1); - free(p); } c++; } @@ -139,9 +135,9 @@ int inter_party_init(void) // パーティーデータのセーブ用 static -void inter_party_save_sub(db_key_t, db_val_t data, FILE *fp) +void inter_party_save_sub(struct party *data, FILE *fp) { - std::string line = inter_party_tostr((struct party *) data); + std::string line = inter_party_tostr(data); FPRINTF(fp, "%s\n", line); } @@ -157,7 +153,8 @@ int inter_party_save(void) party_txt); return 1; } - numdb_foreach(party_db, std::bind(inter_party_save_sub, ph::_1, ph::_2, fp)); + for (auto& pair : party_db) + inter_party_save_sub(&pair.second, fp); // FPRINTF(fp, "%d\t%%newid%%\n", party_newid); lock_fclose(fp, party_txt, &lock); // PRINTF("int_party: %s saved.\n", party_txt); @@ -167,10 +164,8 @@ int inter_party_save(void) // パーティ名検索用 static -void search_partyname_sub(db_key_t, db_val_t data, const char *str, struct party **dst) +void search_partyname_sub(struct party *p, const char *str, struct party **dst) { - struct party *p = (struct party *) data; - if (strcasecmp(p->name, str) == 0) *dst = p; } @@ -180,7 +175,8 @@ static struct party *search_partyname(const char *str) { struct party *p = NULL; - numdb_foreach(party_db, std::bind(search_partyname_sub, ph::_1, ph::_2, str, &p)); + for (auto& pair : party_db) + search_partyname_sub(&pair.second, str, &p); return p; } @@ -223,18 +219,16 @@ int party_check_empty(struct party *p) } // 誰もいないので解散 mapif_party_broken(p->party_id, 0); - numdb_erase(party_db, p->party_id); - free(p); + party_db.erase(p->party_id); return 1; } // キャラの競合がないかチェック用 static -void party_check_conflict_sub(db_key_t, db_val_t data, +void party_check_conflict_sub(struct party *p, int party_id, int account_id, const char *nick) { - struct party *p = (struct party *) data; int i; if (p->party_id == party_id) // 本来の所属なので問題なし @@ -257,9 +251,9 @@ void party_check_conflict_sub(db_key_t, db_val_t data, static int party_check_conflict(int party_id, int account_id, const char *nick) { - numdb_foreach(party_db, - std::bind(party_check_conflict_sub, ph::_1, ph::_2, - party_id, account_id, nick)); + for (auto& pair : party_db) + party_check_conflict_sub(&pair.second, + party_id, account_id, nick); return 0; } @@ -428,7 +422,6 @@ static int mapif_parse_CreateParty(int fd, int account_id, const char *name, const char *nick, const char *map, int lv) { - struct party *p; int i; for (i = 0; i < 24 && name[i]; i++) @@ -441,28 +434,28 @@ int mapif_parse_CreateParty(int fd, int account_id, const char *name, const char } } - if ((p = search_partyname(name)) != NULL) + if (search_partyname(name) != NULL) { PRINTF("int_party: same name party exists [%s]\n", name); mapif_party_created(fd, account_id, NULL); return 0; } - CREATE(p, struct party, 1); - p->party_id = party_newid++; - memcpy(p->name, name, 24); - p->exp = 0; - p->item = 0; - p->member[0].account_id = account_id; - memcpy(p->member[0].name, nick, 24); - memcpy(p->member[0].map, map, 16); - p->member[0].leader = 1; - p->member[0].online = 1; - p->member[0].lv = lv; - - numdb_insert(party_db, p->party_id, p); - - mapif_party_created(fd, account_id, p); - mapif_party_info(fd, p); + struct party p {}; + p.party_id = party_newid++; + memcpy(p.name, name, 24); + p.exp = 0; + p.item = 0; + p.member[0].account_id = account_id; + memcpy(p.member[0].name, nick, 24); + memcpy(p.member[0].map, map, 16); + p.member[0].leader = 1; + p.member[0].online = 1; + p.member[0].lv = lv; + + party_db.insert(p.party_id, p); + + mapif_party_created(fd, account_id, &p); + mapif_party_info(fd, &p); return 0; } @@ -471,7 +464,7 @@ int mapif_parse_CreateParty(int fd, int account_id, const char *name, const char static int mapif_parse_PartyInfo(int fd, int party_id) { - struct party *p = (struct party *)numdb_search(party_db, party_id); + struct party *p = party_db.search(party_id); if (p != NULL) mapif_party_info(fd, p); else @@ -485,7 +478,7 @@ static int mapif_parse_PartyAddMember(int fd, int party_id, int account_id, const char *nick, const char *map, int lv) { - struct party *p = (struct party *)numdb_search(party_db, party_id); + struct party *p = party_db.search(party_id); if (p == NULL) { mapif_party_memberadded(fd, party_id, account_id, 1); @@ -527,7 +520,7 @@ static int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp, int item) { - struct party *p = (struct party *)numdb_search(party_db, party_id); + struct party *p = party_db.search(party_id); if (p == NULL) return 0; @@ -546,74 +539,65 @@ int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, } // パーティ脱退要求 -int mapif_parse_PartyLeave(int, int party_id, int account_id) +void mapif_parse_PartyLeave(int, int party_id, int account_id) { - struct party *p = (struct party *)numdb_search(party_db, party_id); - if (p != NULL) + struct party *p = party_db.search(party_id); + if (!p) + return; + for (int i = 0; i < MAX_PARTY; i++) { - for (int i = 0; i < MAX_PARTY; i++) - { - if (p->member[i].account_id == account_id) - { - mapif_party_leaved(party_id, account_id, p->member[i].name); + if (p->member[i].account_id != account_id) + continue; + mapif_party_leaved(party_id, account_id, p->member[i].name); - memset(&p->member[i], 0, sizeof(struct party_member)); - if (party_check_empty(p) == 0) - mapif_party_info(-1, p); // まだ人がいるのでデータ送信 - return 0; - } - } + memset(&p->member[i], 0, sizeof(struct party_member)); + if (party_check_empty(p) == 0) + mapif_party_info(-1, p); // まだ人がいるのでデータ送信 + return; } - - return 0; } // パーティマップ更新要求 static -int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, +void mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, const char *map, int online, int lv) { - struct party *p = (struct party *)numdb_search(party_db, party_id); + struct party *p = party_db.search(party_id); if (p == NULL) - return 0; + return; for (int i = 0; i < MAX_PARTY; i++) { - if (p->member[i].account_id == account_id) - { - int flag = 0; + if (p->member[i].account_id != account_id) + continue; + int flag = 0; - memcpy(p->member[i].map, map, 16); - p->member[i].online = online; - p->member[i].lv = lv; - mapif_party_membermoved(p, i); + memcpy(p->member[i].map, map, 16); + p->member[i].online = online; + p->member[i].lv = lv; + mapif_party_membermoved(p, i); - if (p->exp > 0 && !party_check_exp_share(p)) - { - p->exp = 0; - flag = 1; - } - if (flag) - mapif_party_optionchanged(fd, p, 0, 0); - break; + if (p->exp > 0 && !party_check_exp_share(p)) + { + p->exp = 0; + flag = 1; } + if (flag) + mapif_party_optionchanged(fd, p, 0, 0); + return; } - - return 0; } // パーティ解散要求 static -int mapif_parse_BreakParty(int fd, int party_id) +void mapif_parse_BreakParty(int fd, int party_id) { - struct party *p = (struct party *)numdb_search(party_db, party_id); + struct party *p = party_db.search(party_id); if (p == NULL) - return 0; + return; - numdb_erase(party_db, party_id); + party_db.erase(party_id); mapif_party_broken(fd, party_id); - - return 0; } // パーティメッセージ送信 @@ -684,7 +668,7 @@ int inter_party_parse_frommap(int fd) } // サーバーから脱退要求(キャラ削除用) -int inter_party_leave(int party_id, int account_id) +void inter_party_leave(int party_id, int account_id) { - return mapif_parse_PartyLeave(-1, party_id, account_id); + mapif_parse_PartyLeave(-1, party_id, account_id); } diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index eca5893..8a59b49 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -6,7 +6,7 @@ int inter_party_save(void); int inter_party_parse_frommap(int fd); -int inter_party_leave(int party_id, int account_id); +void inter_party_leave(int party_id, int account_id); extern char party_txt[1024]; diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index 9ca841f..b7feae1 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -20,7 +20,7 @@ char storage_txt[1024] = "save/storage.txt"; static -struct dbt *storage_db; +Map storage_db; // 倉庫データを文字列に変換 static @@ -83,14 +83,11 @@ bool extract(const_string str, struct storage *p) // アカウントから倉庫データインデックスを得る(新規倉庫追加可能) struct storage *account2storage(int account_id) { - struct storage *s; - s = (struct storage *) numdb_search(storage_db, account_id); + struct storage *s = storage_db.search(account_id); if (s == NULL) { - CREATE(s, struct storage, 1); - memset(s, 0, sizeof(struct storage)); + s = storage_db.init(account_id); s->account_id = account_id; - numdb_insert(storage_db, s->account_id, s); } return s; } @@ -101,8 +98,6 @@ int inter_storage_init(void) { int c = 0; - storage_db = numdb_init(); - std::ifstream in(storage_txt); if (!in.is_open()) { @@ -113,17 +108,15 @@ int inter_storage_init(void) std::string line; while (std::getline(in, line)) { - struct storage *s; - CREATE(s, struct storage, 1); - if (extract(line, s)) + struct storage s {}; + if (extract(line, &s)) { - numdb_insert(storage_db, s->account_id, s); + storage_db.insert(s.account_id, s); } else { PRINTF("int_storage: broken data [%s] line %d\n", storage_txt, c); - free(s); } c++; } @@ -132,9 +125,9 @@ int inter_storage_init(void) } static -void inter_storage_save_sub(db_key_t, db_val_t data, FILE *fp) +void inter_storage_save_sub(struct storage *data, FILE *fp) { - std::string line = storage_tostr((struct storage *) data); + std::string line = storage_tostr(data); if (!line.empty()) FPRINTF(fp, "%s\n", line); } @@ -146,32 +139,23 @@ int inter_storage_save(void) FILE *fp; int lock; - if (!storage_db) - return 1; - if ((fp = lock_fopen(storage_txt, &lock)) == NULL) { PRINTF("int_storage: cant write [%s] !!! data is lost !!!\n", storage_txt); return 1; } - numdb_foreach(storage_db, std::bind(inter_storage_save_sub, ph::_1, ph::_2, fp)); + for (auto& pair : storage_db) + inter_storage_save_sub(&pair.second, fp); lock_fclose(fp, storage_txt, &lock); // PRINTF("int_storage: %s saved.\n",storage_txt); return 0; } // 倉庫データ削除 -int inter_storage_delete(int account_id) +void inter_storage_delete(int account_id) { - struct storage *s = - (struct storage *) numdb_search(storage_db, account_id); - if (s) - { - numdb_erase(storage_db, account_id); - free(s); - } - return 0; + storage_db.erase(account_id); } //--------------------------------------------------------- diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index 286c5a6..691f16d 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -3,7 +3,7 @@ int inter_storage_init(void); int inter_storage_save(void); -int inter_storage_delete(int account_id); +void inter_storage_delete(int account_id); struct storage *account2storage(int account_id); int inter_storage_parse_frommap(int fd); diff --git a/src/char/inter.cpp b/src/char/inter.cpp index 3ca70e9..9efb28c 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -1,5 +1,6 @@ #include "inter.hpp" +#include #include #include @@ -30,14 +31,14 @@ char inter_log_filename[1024] = "log/inter.log"; static char accreg_txt[1024] = "save/accreg.txt"; -static -struct dbt *accreg_db = NULL; struct accreg { int account_id, reg_num; struct global_reg reg[ACCOUNT_REG_NUM]; }; +static +Map accreg_db; int party_share_level = 10; @@ -57,12 +58,13 @@ int inter_recv_packet_length[] = { struct WisData { - int id, fd, count, len; + int id, fd, count; tick_t tick; - unsigned char src[24], dst[24], msg[1024]; + unsigned char src[24], dst[24]; + std::string msg; }; static -struct dbt *wis_db = NULL; +Map wis_db; static int wis_dellist[WISDELLIST_MAX], wis_delnum; @@ -104,25 +106,21 @@ int inter_accreg_init(void) { int c = 0; - accreg_db = numdb_init(); - std::ifstream in(accreg_txt); if (!in.is_open()) return 1; std::string line; while (std::getline(in, line)) { - struct accreg *reg; - CREATE(reg, struct accreg, 1); - if (!extract(line, reg)) + struct accreg reg {}; + if (extract(line, ®)) { - numdb_insert(accreg_db, reg->account_id, reg); + accreg_db.insert(reg.account_id, reg); } else { PRINTF("inter: accreg: broken data [%s] line %d\n", accreg_txt, c); - free(reg); } c++; } @@ -132,10 +130,8 @@ int inter_accreg_init(void) // アカウント変数のセーブ用 static -void inter_accreg_save_sub(db_key_t, db_val_t data, FILE *fp) +void inter_accreg_save_sub(struct accreg *reg, FILE *fp) { - struct accreg *reg = (struct accreg *) data; - if (reg->reg_num > 0) { std::string line = inter_accreg_tostr(reg); @@ -157,7 +153,8 @@ int inter_accreg_save(void) accreg_txt); return 1; } - numdb_foreach(accreg_db, std::bind(inter_accreg_save_sub, ph::_1, ph::_2, fp)); + for (auto& pair : accreg_db) + inter_accreg_save_sub(&pair.second, fp); lock_fclose(fp, accreg_txt, &lock); return 0; @@ -236,8 +233,6 @@ int inter_init(const char *file) { inter_config_read(file); - wis_db = numdb_init(); - inter_party_init(); inter_storage_init(); inter_accreg_init(); @@ -264,14 +259,14 @@ void mapif_GMmessage(const uint8_t *mes, int len) static int mapif_wis_message(struct WisData *wd) { - unsigned char buf[56 + wd->len]; + unsigned char buf[56 + wd->msg.size()]; WBUFW(buf, 0) = 0x3801; - WBUFW(buf, 2) = 56 + wd->len; + WBUFW(buf, 2) = 56 + wd->msg.size(); WBUFL(buf, 4) = wd->id; memcpy(WBUFP(buf, 8), wd->src, 24); memcpy(WBUFP(buf, 32), wd->dst, 24); - memcpy(WBUFP(buf, 56), wd->msg, wd->len); + memcpy(WBUFP(buf, 56), wd->msg.data(), wd->msg.size()); wd->count = mapif_sendall(buf, WBUFW(buf, 2)); return 0; @@ -308,7 +303,7 @@ int mapif_account_reg(int fd, const uint8_t *src) static int mapif_account_reg_reply(int fd, int account_id) { - struct accreg *reg = (struct accreg *)numdb_search(accreg_db, account_id); + struct accreg *reg = accreg_db.search(account_id); WFIFOW(fd, 0) = 0x3804; WFIFOL(fd, 4) = account_id; @@ -335,10 +330,8 @@ int mapif_account_reg_reply(int fd, int account_id) // Existence check of WISP data static -void check_ttl_wisdata_sub(db_key_t, db_val_t data, tick_t tick) +void check_ttl_wisdata_sub(struct WisData *wd, tick_t tick) { - struct WisData *wd = (struct WisData *) data; - if (tick > wd->tick + WISDATA_TTL && wis_delnum < WISDELLIST_MAX) wis_dellist[wis_delnum++] = wd->id; @@ -353,16 +346,17 @@ int check_ttl_wisdata(void) do { wis_delnum = 0; - numdb_foreach(wis_db, std::bind(check_ttl_wisdata_sub, ph::_1, ph::_2, tick)); + for (auto& pair : wis_db) + check_ttl_wisdata_sub(&pair.second, tick); for (i = 0; i < wis_delnum; i++) { - struct WisData *wd = (struct WisData *)numdb_search(wis_db, wis_dellist[i]); + struct WisData *wd = wis_db.search(wis_dellist[i]); + assert (wd); PRINTF("inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst); // removed. not send information after a timeout. Just no answer for the player //mapif_wis_end(wd, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - numdb_erase(wis_db, wd->id); - free(wd); + wis_db.erase(wd->id); } } while (wis_delnum >= WISDELLIST_MAX); @@ -386,16 +380,10 @@ int mapif_parse_GMmessage(int fd) static int mapif_parse_WisRequest(int fd) { - struct WisData *wd; static int wisid = 0; int index; - if (RFIFOW(fd, 2) - 52 >= sizeof(wd->msg)) - { - PRINTF("inter: Wis message size too long.\n"); - return 0; - } - else if (RFIFOW(fd, 2) - 52 <= 0) + if (RFIFOW(fd, 2) - 52 <= 0) { // normaly, impossible, but who knows... PRINTF("inter: Wis message doesn't exist.\n"); return 0; @@ -426,20 +414,20 @@ int mapif_parse_WisRequest(int fd) } else { - CREATE(wd, struct WisData, 1); + struct WisData wd; // Whether the failure of previous wisp/page transmission (timeout) check_ttl_wisdata(); - wd->id = ++wisid; - wd->fd = fd; - wd->len = RFIFOW(fd, 2) - 52; - memcpy(wd->src, RFIFOP(fd, 4), 24); - memcpy(wd->dst, RFIFOP(fd, 28), 24); - memcpy(wd->msg, RFIFOP(fd, 52), wd->len); - wd->tick = gettick(); - numdb_insert(wis_db, wd->id, wd); - mapif_wis_message(wd); + wd.id = ++wisid; + wd.fd = fd; + size_t len = RFIFOW(fd, 2) - 52; + memcpy(wd.src, RFIFOP(fd, 4), 24); + memcpy(wd.dst, RFIFOP(fd, 28), 24); + wd.msg = std::string(static_cast(RFIFOP(fd, 52)), len); + wd.tick = gettick(); + wis_db.insert(wd.id, wd); + mapif_wis_message(&wd); } } @@ -451,7 +439,7 @@ static int mapif_parse_WisReply(int fd) { int id = RFIFOL(fd, 2), flag = RFIFOB(fd, 6); - struct WisData *wd = (struct WisData *)numdb_search(wis_db, id); + struct WisData *wd = wis_db.search(id); if (wd == NULL) return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server @@ -459,8 +447,7 @@ int mapif_parse_WisReply(int fd) if ((--wd->count) <= 0 || flag != 1) { mapif_wis_end(wd, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - numdb_erase(wis_db, id); - free(wd); + wis_db.erase(id); } return 0; @@ -484,13 +471,13 @@ static int mapif_parse_AccReg(int fd) { int j, p; - struct accreg *reg = (struct accreg*)numdb_search(accreg_db, (numdb_key_t)RFIFOL(fd, 4)); + struct accreg *reg = accreg_db.search(RFIFOL(fd, 4)); if (reg == NULL) { - CREATE(reg, struct accreg, 1); - reg->account_id = RFIFOL(fd, 4); - numdb_insert(accreg_db, (numdb_key_t)RFIFOL(fd, 4), reg); + int account_id = RFIFOL(fd, 4); + reg = accreg_db.init(account_id); + reg->account_id = account_id; } for (j = 0, p = 8; j < ACCOUNT_REG_NUM && p < RFIFOW(fd, 2); diff --git a/src/common/db.cpp b/src/common/db.cpp index 970e054..cc58ad8 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -1,548 +1,3 @@ #include "db.hpp" -#include -#include - -#include "utils.hpp" - #include "../poison.hpp" - -static -int strdb_cmp(struct dbt *table, const char *a, const char* b) -{ - if (table->maxlen) - return strncmp(a, b, table->maxlen); - return strcmp(a, b); -} - -static -hash_t strdb_hash(struct dbt *table, const char *a) -{ - size_t i = table->maxlen; - if (i == 0) - i = (size_t)-1; - hash_t h = 0; - const unsigned char *p = (const unsigned char*)a; - while (*p && i--) - { - h = (h * 33 + *p++) ^ (h >> 24); - } - return h; -} - -struct dbt *strdb_init(size_t maxlen) -{ - struct dbt *table; - CREATE(table, struct dbt, 1); - table->type = DB_STRING; - table->maxlen = maxlen; - return table; -} - -static -int numdb_cmp(numdb_key_t a, numdb_key_t b) -{ - if (a == b) - return 0; - if (a < b) - return -1; - return 1; -} - -static -hash_t numdb_hash(numdb_key_t a) -{ - return (hash_t) a; -} - -struct dbt *numdb_init(void) -{ - struct dbt *table; - CREATE(table, struct dbt, 1); - table->type = DB_NUMBER; - return table; -} - -static -int table_cmp(struct dbt *table, db_key_t a, db_key_t b) -{ - switch (table->type) - { - case DB_NUMBER: return numdb_cmp(a.i, b.i); - case DB_STRING: return strdb_cmp(table, a.s, b.s); - } - abort(); -} - -static -hash_t table_hash(struct dbt *table, db_key_t key) -{ - switch (table->type) - { - case DB_NUMBER: return numdb_hash(key.i); - case DB_STRING: return strdb_hash(table, key.s); - } - abort(); -} - -/// Search for a node with the given key -db_val_t db_search(struct dbt *table, db_key_t key) -{ - struct dbn *p = table->ht[table_hash(table, key) % HASH_SIZE]; - - while (p) - { - int c = table_cmp(table, key, p->key); - if (c == 0) - return p->data; - if (c < 0) - p = p->left; - else - p = p->right; - } - return NULL; -} - -// Tree maintainance methods -static -void db_rotate_left(struct dbn *p, struct dbn **root) -{ - struct dbn *y = p->right; - p->right = y->left; - if (y->left) - y->left->parent = p; - y->parent = p->parent; - - if (p == *root) - *root = y; - else if (p == p->parent->left) - p->parent->left = y; - else - p->parent->right = y; - y->left = p; - p->parent = y; -} - -static -void db_rotate_right(struct dbn *p, struct dbn **root) -{ - struct dbn *y = p->left; - p->left = y->right; - if (y->right) - y->right->parent = p; - y->parent = p->parent; - - if (p == *root) - *root = y; - else if (p == p->parent->right) - p->parent->right = y; - else - p->parent->left = y; - y->right = p; - p->parent = y; -} - -static -void db_rebalance(struct dbn *p, struct dbn **root) -{ - p->color = RED; - while (p != *root && p->parent->color == RED) - { - if (p->parent == p->parent->parent->left) - { - struct dbn *y = p->parent->parent->right; - if (y && y->color == RED) - { - p->parent->color = BLACK; - y->color = BLACK; - p->parent->parent->color = RED; - p = p->parent->parent; - } - else - { - if (p == p->parent->right) - { - p = p->parent; - db_rotate_left(p, root); - } - p->parent->color = BLACK; - p->parent->parent->color = RED; - db_rotate_right(p->parent->parent, root); - } - } - else - { - struct dbn *y = p->parent->parent->left; - if (y && y->color == RED) - { - p->parent->color = BLACK; - y->color = BLACK; - p->parent->parent->color = RED; - p = p->parent->parent; - } - else - { - if (p == p->parent->left) - { - p = p->parent; - db_rotate_right(p, root); - } - p->parent->color = BLACK; - p->parent->parent->color = RED; - db_rotate_left(p->parent->parent, root); - } - } - } - (*root)->color = BLACK; -} - -// param z = node to remove -static -void db_rebalance_erase(struct dbn *z, struct dbn **root) -{ - struct dbn *y = z; - struct dbn *x = NULL; - - if (!y->left) - x = y->right; - else if (!y->right) - x = y->left; - else - { - y = y->right; - while (y->left) - y = y->left; - x = y->right; - } - struct dbn *x_parent = NULL; - if (y != z) - { - z->left->parent = y; - y->left = z->left; - if (y != z->right) - { - x_parent = y->parent; - if (x) - x->parent = y->parent; - y->parent->left = x; - y->right = z->right; - z->right->parent = y; - } - else - x_parent = y; - if (*root == z) - *root = y; - else if (z->parent->left == z) - z->parent->left = y; - else - z->parent->right = y; - y->parent = z->parent; - { - dbn_color tmp = y->color; - y->color = z->color; - z->color = tmp; - } - y = z; - } - else - { - x_parent = y->parent; - if (x) - x->parent = y->parent; - if (*root == z) - *root = x; - else if (z->parent->left == z) - z->parent->left = x; - else - z->parent->right = x; - } - if (y->color != RED) - { - while (x != *root && (!x || x->color == BLACK)) - if (x == x_parent->left) - { - struct dbn *w = x_parent->right; - if (w->color == RED) - { - w->color = BLACK; - x_parent->color = RED; - db_rotate_left(x_parent, root); - w = x_parent->right; - } - if ((!w->left || w->left->color == BLACK) && - (!w->right || w->right->color == BLACK)) - { - w->color = RED; - x = x_parent; - x_parent = x->parent; - } - else - { - if (!w->right|| w->right->color == BLACK) - { - if (w->left) - w->left->color = BLACK; - w->color = RED; - db_rotate_right(w, root); - w = x_parent->right; - } - w->color = x_parent->color; - x_parent->color = BLACK; - if (w->right) - w->right->color = BLACK; - db_rotate_left(x_parent, root); - break; - } - } - else - { - // same as above, with right <-> left. - struct dbn *w = x_parent->left; - if (w->color == RED) - { - w->color = BLACK; - x_parent->color = RED; - db_rotate_right(x_parent, root); - w = x_parent->left; - } - if ((!w->right || w->right->color == BLACK) && - (!w->left || w->left->color == BLACK)) - { - w->color = RED; - x = x_parent; - x_parent = x_parent->parent; - } - else - { - if (!w->left || w->left->color == BLACK) - { - if (w->right) - w->right->color = BLACK; - w->color = RED; - db_rotate_left(w, root); - w = x_parent->left; - } - w->color = x_parent->color; - x_parent->color = BLACK; - if (w->left) - w->left->color = BLACK; - db_rotate_right(x_parent, root); - break; - } - } - if (x) - x->color = BLACK; - } -} - -struct dbn *db_insert(struct dbt *table, db_key_t key, db_val_t data) -{ - hash_t hash = table_hash(table, key) % HASH_SIZE; - int c = 0; - struct dbn *prev = NULL; - struct dbn *p = table->ht[hash]; - while (p) - { - c = table_cmp(table, key, p->key); - if (c == 0) - { - // key found in table, replace - // Tell the user of the table to free the key and value - if (table->release) - table->release(p->key, p->data); - p->data = data; - p->key = key; - return p; - } - // prev is always p->parent? - prev = p; - if (c < 0) - p = p->left; - else - p = p->right; - } - CREATE(p, struct dbn, 1); - p->key = key; - p->data = data; - p->color = RED; - if (c == 0) - { // hash entry is empty - table->ht[hash] = p; - p->color = BLACK; - return p; - } - p->parent = prev; - if (c < 0) - prev->left = p; - else - prev->right = p; - if (prev->color == RED) - { - // must rebalance - db_rebalance(p, &table->ht[hash]); - } - return p; -} - -db_val_t db_erase(struct dbt *table, db_key_t key) -{ - hash_t hash = table_hash(table, key) % HASH_SIZE; - struct dbn *p = table->ht[hash]; - while (p) - { - int c = table_cmp(table, key, p->key); - if (c == 0) - break; - if (c < 0) - p = p->left; - else - p = p->right; - } - if (!p) - return NULL; - db_val_t data = p->data; - db_rebalance_erase(p, &table->ht[hash]); - free(p); - return data; -} -#ifdef SMART_WALK_TREE -static -void db_walk_tree(bool dealloc, struct dbn* p, db_func_t func) -{ - if (!p) - return; - if (!dealloc && !func) - { - FPRINTF(stderr, "DEBUG: Must walk tree to either free or invoke a function.\n"); - abort(); - } - if (p->parent) - { - FPRINTF(stderr, "DEBUG: Root nodes must not have parents\n"); - abort(); - } - while (true) - { - // apply_func loop - if (func) - func(p->key, p->data); - if (p->left) - { - // continue descending - p = p->left; - continue; //goto apply_func; - } - if (p->right) - { - // descending the other side - p = p->right; - continue; //goto apply_func; - } - while (true) - { - // backtrack loop - if (!p->parent) - { - if (dealloc) - free(p); - // if we have already done both children, there is no more to do - return; - } - if (p->parent->left == p && p->parent->right) - { - // finished the left tree, now walk the right tree - p = p->parent->right; - if (dealloc) - free(p->parent->left); - break; //goto apply_func; - } - // p->parent->right == p - // or p->parent->left == p but p->parent->right == NULL - // keep backtracking - p = p->parent; - if (dealloc) - free(p->right?:p->left); - } //backtrack loop - } // apply_func loop -} -#endif // SMART_WALK_TREE - -void db_foreach(struct dbt *table, db_func_t func) -{ - for (int i = 0; i < HASH_SIZE; i++) - { -#ifdef SMART_WALK_TREE - db_walk_tree(false, table->ht[i], func, ap); -#else - struct dbn *p = table->ht[i]; - if (!p) - continue; - struct dbn *stack[64]; - int sp = 0; - while (1) - { - func(p->key, p->data); - struct dbn *pn = p->left; - if (pn) - { - if (p->right) - stack[sp++] = p->right; - p = pn; - } - else // pn == NULL, time to do the right branch - { - if (p->right) - p = p->right; - else - { - if (sp == 0) - break; - p = stack[--sp]; - } - } // if pn else if !pn - } // while true -#endif // else ! SMART_WALK_TREE - } // for i -} - -// This function is suspiciously similar to the previous -void db_final(struct dbt *table, db_func_t func) -{ - for (int i = 0; i < HASH_SIZE; i++) - { -#ifdef SMART_WALK_TREE - db_walk_tree(true, table->ht[i], func); -#else - struct dbn *p = table->ht[i]; - if (!p) - continue; - struct dbn *stack[64]; - int sp = 0; - while (1) - { - if (func) - func(p->key, p->data); - struct dbn *pn = p->left; - if (pn) - { - if (p->right) - stack[sp++] = p->right; - } - else // pn == NULL, check the right - { - if (p->right) - pn = p->right; - else - { - if (sp == 0) - break; - pn = stack[--sp]; - } - } // if pn else if !pn - free(p); - p = pn; - } // while true -#endif // else ! SMART_WALK_TREE - } // for i - free(table); -} diff --git a/src/common/db.hpp b/src/common/db.hpp index 7d07b1d..d171429 100644 --- a/src/common/db.hpp +++ b/src/common/db.hpp @@ -1,91 +1,119 @@ -// WARNING: there is a system header by this name #ifndef DB_HPP #define DB_HPP +// db.hpp - convenience wrappers over std::map +// +// Copyright © 2013 Ben Longbons +// +// 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 . # include "sanity.hpp" -# include +# include -/// Number of tree roots -// Somewhat arbitrary - larger wastes more space but is faster for large trees -// num % HASH_SIZE minimize collisions even for similar num -constexpr int HASH_SIZE = 256 + 27; - -typedef enum dbn_color +template +class Map { - RED, - BLACK, -} dbn_color; + typedef std::map Impl; -typedef intptr_t numdb_key_t; -typedef union db_key_t -{ - char *ms __attribute__((deprecated)); - const char* s; - numdb_key_t i; + Impl impl; +public: + typedef typename Impl::iterator iterator; + typedef typename Impl::const_iterator const_iterator; - db_key_t(numdb_key_t n) : i(n) {} - db_key_t(const char * z) : s(z) {} -} db_key_t; -typedef void* db_val_t; -typedef uint32_t hash_t; -typedef std::function db_func_t; + iterator begin() { return impl.begin(); } + iterator end() { return impl.end(); } + const_iterator begin() const { return impl.begin(); } + const_iterator end() const { return impl.end(); } -/// DataBase Node -struct dbn -{ - struct dbn *parent, *left, *right; - dbn_color color; - db_key_t key; - db_val_t data; -}; + V *search(const K& k) + { + iterator it = impl.find(k); + if (it == impl.end()) + return nullptr; + return &it->second; + } + const V *search(const K& k) const + { + const_iterator it = impl.find(k); + if (it == impl.end()) + return nullptr; + return &it->second; + } + void insert(K k, V v) + { + // As far as I can tell, this is the simplest way to + // implement move-only insert-with-replacement. + iterator it = impl.lower_bound(k); + // invariant: if it is valid, it->first >= k + if (it != impl.end() && it->first == k) + it->second = std::move(v); + else + it = impl.insert(std::pair(std::move(k), std::move(v))).first; + return (void)&it->second; -typedef enum dbt_type -{ - DB_NUMBER, - DB_STRING, -} dbt_type; + } + V *init(K k) + { + return &impl[k]; + } + void erase(const K& k) + { + impl.erase(k); + } + void clear() + { + impl.clear(); + } + bool empty() + { + return impl.empty(); + } +}; -/// DataBase Table -struct dbt +template +class DMap { - dbt_type type; - /// Note, before replacement, key/values to be replaced - // TODO refactor to decrease/eliminate the uses of this? - void(*release)(db_key_t, db_val_t) __attribute__((deprecated)); - /// Maximum length of a string key - TODO refactor to ensure all strings are NUL-terminated - size_t maxlen __attribute__((deprecated)); - /// The root trees - struct dbn *ht[HASH_SIZE]; -}; + typedef Map Impl; -# define strdb_search(t,k) db_search((t), (db_key_t)(k)) -# define strdb_insert(t,k,d) db_insert((t), (db_key_t)(k), (db_val_t)(d)) -# define strdb_erase(t,k) db_erase((t), (db_key_t)(k)) -# define strdb_foreach db_foreach -# define strdb_final db_final -# define numdb_search(t,k) db_search((t), (db_key_t)(k)) -# define numdb_insert(t,k,d) db_insert((t), (db_key_t)(k), (db_val_t)(d)) -# define numdb_erase(t,k) db_erase((t), (db_key_t)(k)) -# define numdb_foreach db_foreach -# define numdb_final db_final + Impl impl; +public: + typedef typename Impl::iterator iterator; + typedef typename Impl::const_iterator const_iterator; -/// Create a map from char* to void*, with strings possibly not null-terminated -struct dbt *strdb_init(size_t maxlen); -/// Create a map from int to void* -struct dbt *numdb_init(void); -/// Return the value corresponding to the key, or NULL if not found -db_val_t db_search(struct dbt *table, db_key_t key); -/// Add or replace table[key] = data -// if it was already there, call release -struct dbn *db_insert(struct dbt *table, db_key_t key, db_val_t data); -/// Remove a key from the table, returning the data -db_val_t db_erase(struct dbt *table, db_key_t key); + iterator begin() { return impl.begin(); } + iterator end() { return impl.end(); } + const_iterator begin() const { return impl.begin(); } + const_iterator end() const { return impl.end(); } -/// Execute a function for every element, in unspecified order -void db_foreach(struct dbt *, db_func_t); -// opposite of init? Calls release for every element and frees memory -// This probably isn't really needed: we don't have to free memory while exiting -void db_final(struct dbt *, db_func_t) __attribute__((deprecated)); + V get(K k) + { + V *vp = impl.search(k); + return vp ? *vp : V(); + } + void put(K k, V v) + { + if (v == V()) + impl.erase(k); + else + impl.insert(k, v); + } + void clear() + { + impl.clear(); + } +}; #endif // DB_HPP diff --git a/src/login/login.cpp b/src/login/login.cpp index 94ae4b5..10f6395 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -196,7 +196,7 @@ static int level_new_gm = 60; static -struct dbt *gm_account_db; +Map gm_account_db; static pid_t pid = 0; // For forked DB writes @@ -237,7 +237,7 @@ void login_log(const_string line) static int isGM(int account_id) { - struct gm_account *p = (struct gm_account*) numdb_search(gm_account_db, account_id); + struct gm_account *p = gm_account_db.search(account_id); if (p == NULL) return 0; return p->level; @@ -250,13 +250,11 @@ static int read_gm_account(void) { char line[512]; - struct gm_account *p; FILE *fp; int c = 0; int GM_level; - free(gm_account_db); - gm_account_db = numdb_init(); + gm_account_db.clear(); creation_time_GM_account_file = file_modified(GM_account_filename); @@ -277,35 +275,35 @@ int read_gm_account(void) if ((line[0] == '/' && line[1] == '/') || line[0] == '\0' || line[0] == '\n' || line[0] == '\r') continue; - CREATE(p, struct gm_account, 1); - if (sscanf(line, "%d %d", &p->account_id, &p->level) != 2 - && sscanf(line, "%d: %d", &p->account_id, &p->level) != 2) + struct gm_account p {}; + if (sscanf(line, "%d %d", &p.account_id, &p.level) != 2 + && sscanf(line, "%d: %d", &p.account_id, &p.level) != 2) PRINTF("read_gm_account: file [%s], invalid 'id_acount level' format.\n", GM_account_filename); - else if (p->level <= 0) + else if (p.level <= 0) PRINTF("read_gm_account: file [%s] %dth account (invalid level [0 or negative]: %d).\n", - GM_account_filename, c + 1, p->level); + GM_account_filename, c + 1, p.level); else { - if (p->level > 99) + if (p.level > 99) { PRINTF("read_gm_account: file [%s] %dth account (invalid level, but corrected: %d->99).\n", - GM_account_filename, c + 1, p->level); - p->level = 99; + GM_account_filename, c + 1, p.level); + p.level = 99; } - if ((GM_level = isGM(p->account_id)) > 0) + if ((GM_level = isGM(p.account_id)) > 0) { // if it's not a new account - if (GM_level == p->level) + if (GM_level == p.level) PRINTF("read_gm_account: GM account %d defined twice (same level: %d).\n", - p->account_id, p->level); + p.account_id, p.level); else PRINTF("read_gm_account: GM account %d defined twice (levels: %d and %d).\n", - p->account_id, GM_level, p->level); + p.account_id, GM_level, p.level); } - if (GM_level != p->level) + if (GM_level != p.level) { // if new account or new level - numdb_insert(gm_account_db, p->account_id, p); - //PRINTF("GM account:%d, level: %d->%d\n", p->account_id, GM_level, p->level); + gm_account_db.insert(p.account_id, p); + //PRINTF("GM account:%d, level: %d->%d\n", p.account_id, GM_level, p.level); if (GM_level == 0) { // if new account c++; @@ -4276,7 +4274,7 @@ void term_func(void) mmo_auth_sync(); free(auth_dat); - free(gm_account_db); + gm_account_db.clear(); for (i = 0; i < MAX_SERVERS; i++) { if ((fd = server_fd[i]) >= 0) @@ -4303,8 +4301,6 @@ int do_init(int argc, char **argv) for (int i = 0; i < MAX_SERVERS; i++) server_fd[i] = -1; - gm_account_db = numdb_init(); - read_gm_account(); mmo_auth_init(); // set_termfunc (mmo_auth_sync); diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 9c6d4e6..115893b 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -18,7 +18,7 @@ constexpr int MAX_RANDITEM = 2000; //#define ITEMDB_OVERRIDE_NAME_VERBOSE 1 static -struct dbt *item_db; +Map item_db; // Function declarations @@ -37,9 +37,8 @@ int itemdb_read_noequip(void); */ // name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) static -void itemdb_searchname_sub(db_key_t, db_val_t data, const char *str, struct item_data **dst) +void itemdb_searchname_sub(struct item_data *item, const char *str, struct item_data **dst) { - struct item_data *item = (struct item_data *) data; if (strcasecmp(item->name, str) == 0) //by lupus *dst = item; } @@ -51,7 +50,8 @@ void itemdb_searchname_sub(db_key_t, db_val_t data, const char *str, struct item struct item_data *itemdb_searchname(const char *str) { struct item_data *item = NULL; - numdb_foreach(item_db, std::bind(itemdb_searchname_sub, ph::_1, ph::_2, str, &item)); + for (auto& pair : item_db) + itemdb_searchname_sub(&pair.second, str, &item); return item; } @@ -61,7 +61,7 @@ struct item_data *itemdb_searchname(const char *str) */ struct item_data *itemdb_exists(int nameid) { - return (struct item_data *)numdb_search(item_db, nameid); + return item_db.search(nameid); } /*========================================== @@ -70,12 +70,11 @@ struct item_data *itemdb_exists(int nameid) */ struct item_data *itemdb_search(int nameid) { - struct item_data *id = (struct item_data *)numdb_search(item_db, nameid); + struct item_data *id = item_db.search(nameid); if (id) return id; - id = (struct item_data *) calloc(1, sizeof(struct item_data)); - numdb_insert(item_db, nameid, id); + id = item_db.init(nameid); id->nameid = nameid; id->value_buy = 10; @@ -366,18 +365,12 @@ int itemdb_read_noequip(void) *------------------------------------------ */ static -void itemdb_final(db_key_t, db_val_t data) +void itemdb_final(struct item_data *id) { - struct item_data *id; - - id = (struct item_data *)data; - nullpo_retv(id); - if (id->use_script) free(const_cast(id->use_script)); if (id->equip_script) free(const_cast(id->equip_script)); - free(id); } void itemdb_reload(void) @@ -398,11 +391,9 @@ void itemdb_reload(void) */ void do_final_itemdb(void) { - if (item_db) - { - numdb_final(item_db, itemdb_final); - item_db = NULL; - } + for (auto& pair : item_db) + itemdb_final(&pair.second); + item_db.clear(); } /* @@ -438,11 +429,7 @@ void itemdb_read(void) * *------------------------------------------ */ -int do_init_itemdb(void) +void do_init_itemdb(void) { - item_db = numdb_init(); - itemdb_read(); - - return 0; } diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp index 3b808a8..056213e 100644 --- a/src/map/itemdb.hpp +++ b/src/map/itemdb.hpp @@ -110,6 +110,6 @@ int itemdb_isequip3(int); void itemdb_reload(void); void do_final_itemdb(void); -int do_init_itemdb(void); +void do_init_itemdb(void); #endif // ITEMDB_HPP diff --git a/src/map/map.cpp b/src/map/map.cpp index 65fdc38..4fa56c2 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -39,15 +39,22 @@ #include "../poison.hpp" -// 極力 staticでローカルに収める -static -struct dbt *id_db = NULL; +DMap id_db; + static -struct dbt *map_db = NULL; +DMap map_db; + static -struct dbt *nick_db = NULL; +DMap nick_db; + +struct charid2nick +{ + char nick[24]; + int req_id; +}; + static -struct dbt *charid_db = NULL; +Map charid_db; static int users = 0; @@ -77,12 +84,6 @@ int map_port = 0; interval_t autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; int save_settings = 0xFFFF; -struct charid2nick -{ - char nick[24]; - int req_id; -}; - char motd_txt[256] = "conf/motd.txt"; char help_txt[256] = "conf/help.txt"; @@ -645,7 +646,7 @@ int map_addobject(struct block_list *bl) if (last_object_id < i) last_object_id = i; object[i] = bl; - numdb_insert(id_db, i, bl); + id_db.put(i, bl); return i; } @@ -668,7 +669,7 @@ int map_delobjectnofree(int id, BL type) } map_delblock(object[id]); - numdb_erase(id_db, id); + id_db.put(id, nullptr); // map_freeblock(object[id]); object[id] = NULL; @@ -888,35 +889,12 @@ int map_addflooritem(struct item *item_data, int amount, */ void map_addchariddb(int charid, const char *name) { - struct charid2nick *p = (struct charid2nick *)numdb_search(charid_db, charid); + struct charid2nick *p = charid_db.search(charid); if (p == NULL) - { // データベースにない - CREATE(p, struct charid2nick, 1); - p->req_id = 0; - } - else - numdb_erase(charid_db, charid); + p = charid_db.init(charid); memcpy(p->nick, name, 24); p->req_id = 0; - numdb_insert(charid_db, charid, p); -} - -/*========================================== - * charid_dbへ追加(返信要求のみ) - *------------------------------------------ - */ -int map_reqchariddb(struct map_session_data *sd, int charid) -{ - nullpo_ret(sd); - - struct charid2nick *p = (struct charid2nick *)numdb_search(charid_db, charid); - if (p != NULL) // データベースにすでにある - return 0; - CREATE(p, struct charid2nick, 1); - p->req_id = sd->bl.id; - numdb_insert(charid_db, charid, p); - return 0; } /*========================================== @@ -927,7 +905,7 @@ void map_addiddb(struct block_list *bl) { nullpo_retv(bl); - numdb_insert(id_db, bl->id, bl); + id_db.put(bl->id, bl); } /*========================================== @@ -938,7 +916,7 @@ void map_deliddb(struct block_list *bl) { nullpo_retv(bl); - numdb_erase(id_db, bl->id); + id_db.put(bl->id, nullptr); } /*========================================== @@ -949,7 +927,7 @@ void map_addnickdb(struct map_session_data *sd) { nullpo_retv(sd); - strdb_insert(nick_db, sd->status.name, sd); + nick_db.put(sd->status.name, sd); } /*========================================== @@ -958,9 +936,9 @@ void map_addnickdb(struct map_session_data *sd) * quit処理の主体が違うような気もしてきた *------------------------------------------ */ -int map_quit(struct map_session_data *sd) +void map_quit(struct map_session_data *sd) { - nullpo_ret(sd); + nullpo_retv(sd); if (sd->chatID) // チャットから出る chat_leavechat(sd); @@ -1004,11 +982,9 @@ int map_quit(struct map_session_data *sd) map_delblock(&sd->bl); - numdb_erase(id_db, sd->bl.id); - strdb_erase(nick_db, sd->status.name); - numdb_erase(charid_db, sd->status.char_id); - - return 0; + id_db.put(sd->bl.id, nullptr); + nick_db.put(sd->status.name, nullptr); + charid_db.erase(sd->status.char_id); } /*========================================== @@ -1047,7 +1023,7 @@ struct map_session_data *map_id2sd(int id) */ char *map_charid2nick(int id) { - struct charid2nick *p = (struct charid2nick *)numdb_search(charid_db, id); + struct charid2nick *p = charid_db.search(id); if (p == NULL) return NULL; @@ -1172,20 +1148,11 @@ struct block_list *map_id2bl(int id) if (id < sizeof(object) / sizeof(object[0])) bl = object[id]; else - bl = (struct block_list *)numdb_search(id_db, id); + bl = id_db.get(id); return bl; } -/*========================================== - * id_db内の全てにfuncを実行 - *------------------------------------------ - */ -void map_foreachiddb(db_func_t func) -{ - numdb_foreach(id_db, func); -} - /*========================================== * map.npcへ追加 (warp等の領域持ちのみ) *------------------------------------------ @@ -1213,7 +1180,7 @@ int map_addnpc(int m, struct npc_data *nd) map[m].npc[i] = nd; nd->n = i; - numdb_insert(id_db, nd->bl.id, nd); + id_db.put(nd->bl.id, (struct block_list *)nd); return i; } @@ -1231,7 +1198,7 @@ void map_removenpc(void) { clif_clearchar(&map[m].npc[i]->bl, BeingRemoveWhy::QUIT); map_delblock(&map[m].npc[i]->bl); - numdb_erase(id_db, map[m].npc[i]->bl.id); + id_db.put(map[m].npc[i]->bl.id, nullptr); if (map[m].npc[i]->bl.subtype == NpcSubtype::SCRIPT) { // free(map[m].npc[i]->u.scr.script); @@ -1252,7 +1219,7 @@ void map_removenpc(void) */ int map_mapname2mapid(const char *name) { - struct map_data *md = (struct map_data *)strdb_search(map_db, name); + struct map_data *md = map_db.get(name); if (md == NULL || md->gat == NULL) return -1; return md->m; @@ -1264,7 +1231,7 @@ int map_mapname2mapid(const char *name) */ int map_mapname2ipport(const char *name, struct in_addr *ip, int *port) { - struct map_data_other_server *mdos = (struct map_data_other_server *)strdb_search(map_db, name); + struct map_data_other_server *mdos = (struct map_data_other_server *)map_db.get(name); if (mdos == NULL || mdos->gat) return -1; *ip = mdos->ip; @@ -1372,22 +1339,23 @@ void map_setcell(int m, int x, int y, MapCell t) */ int map_setipport(const char *name, struct in_addr ip, int port) { - struct map_data_other_server *mdos = NULL; - - struct map_data *md = (struct map_data *)strdb_search(map_db, name); + struct map_data *md = map_db.get(name); if (md == NULL) - { // not exist -> add new data + { + struct map_data_other_server *mdos = NULL; + // not exist -> add new data CREATE(mdos, struct map_data_other_server, 1); memcpy(mdos->name, name, 24); mdos->gat = NULL; mdos->ip = ip; mdos->port = port; - strdb_insert(map_db, mdos->name, mdos); + map_db.put(mdos->name, (struct map_data *)mdos); } else { if (md->gat) - { // local -> check data + { + // local -> check data if (ip.s_addr != clif_getip().s_addr || port != clif_getport()) { PRINTF("from char server : %s -> %s:%d\n", name, ip2str(ip), @@ -1396,7 +1364,9 @@ int map_setipport(const char *name, struct in_addr ip, int port) } } else - { // update + { + // update + struct map_data_other_server *mdos = NULL; mdos = (struct map_data_other_server *) md; mdos->ip = ip; mdos->port = port; @@ -1450,7 +1420,7 @@ bool map_readmap(int m, const_string fn) CREATE(map[m].block_count, int, size); CREATE(map[m].block_mob_count, int, size); - strdb_insert(map_db, map[m].name, &map[m]); + map_db.put(map[m].name, &map[m]); return true; } @@ -1783,11 +1753,6 @@ void term_func(void) map_removenpc(); - numdb_final(id_db, NULL); - strdb_final(map_db, NULL); - strdb_final(nick_db, NULL); - numdb_final(charid_db, NULL); - for (i = 0; i <= map_num; i++) { map[i].gat = nullptr; @@ -1855,11 +1820,6 @@ int do_init(int argc, char *argv[]) atcommand_config_read(ATCOMMAND_CONF_FILENAME); script_config_read(); - id_db = numdb_init(); - map_db = strdb_init(16); - nick_db = strdb_init(24); - charid_db = numdb_init(); - map_readallmap(); do_init_chrif (); diff --git a/src/map/map.hpp b/src/map/map.hpp index 29680a6..7fb6026 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -533,7 +533,7 @@ int map_delobjectnofree(int id, BL type); void map_foreachobject(std::function, BL); // -int map_quit(struct map_session_data *); +void map_quit(struct map_session_data *); // npc int map_addnpc(int, struct npc_data *); @@ -560,8 +560,9 @@ int map_addflooritem(struct item *, int, int, int, int, struct map_session_data *); // キャラid=>キャラ名 変換関連 +extern +DMap id_db; void map_addchariddb(int charid, const char *name); -int map_reqchariddb(struct map_session_data *sd, int charid); char *map_charid2nick(int); struct map_session_data *map_id2sd(int); @@ -571,7 +572,6 @@ int map_mapname2ipport(const char *, struct in_addr *, int *); int map_setipport(const char *name, struct in_addr ip, int port); void map_addiddb(struct block_list *); void map_deliddb(struct block_list *bl); -void map_foreachiddb(db_func_t); void map_addnickdb(struct map_session_data *); int map_scriptcont(struct map_session_data *sd, int id); /* Continues a script either on a spell or on an NPC */ struct map_session_data *map_nick2sd(const char *); diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 79a21ea..709df2b 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -2094,17 +2094,14 @@ void mob_ai_hard(TimerData *, tick_t tick) *------------------------------------------ */ static -void mob_ai_sub_lazy(db_key_t, db_val_t data, tick_t tick) +void mob_ai_sub_lazy(struct block_list *bl, tick_t tick) { - struct mob_data *md = (struct mob_data *)data; - - nullpo_retv(md); + nullpo_retv(bl); - if (md == NULL) + if (bl->type != BL::MOB) return; - if (md->bl.type == BL::NUL || md->bl.type != BL::MOB) - return; + struct mob_data *md = (struct mob_data *)bl; if (tick < md->last_thinktime + MIN_MOBTHINKTIME * 10) return; @@ -2161,7 +2158,8 @@ void mob_ai_sub_lazy(db_key_t, db_val_t data, tick_t tick) static void mob_ai_lazy(TimerData *, tick_t tick) { - map_foreachiddb(std::bind(mob_ai_sub_lazy, ph::_1, ph::_2, tick)); + for (auto& pair : id_db) + mob_ai_sub_lazy(pair.second, tick); } /*========================================== diff --git a/src/map/npc.cpp b/src/map/npc.cpp index b65c263..f0cacb9 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -40,16 +40,16 @@ int npc_get_new_npc_id(void) return npc_id++; } -static -struct dbt *ev_db; -static -struct dbt *npcname_db; - struct event_data { struct npc_data *nd; int pos; }; +static +Map ev_db; +static +DMap npcname_db; + static struct tm ev_tm_b; // 時計イベント用 @@ -84,7 +84,7 @@ void npc_enable_sub(struct block_list *bl, struct npc_data *nd) int npc_enable(const char *name, bool flag) { - struct npc_data *nd = (struct npc_data *)strdb_search(npcname_db, name); + struct npc_data *nd = npcname_db.get(name); if (nd == NULL) return 0; @@ -112,7 +112,7 @@ int npc_enable(const char *name, bool flag) */ struct npc_data *npc_name2id(const char *name) { - return (struct npc_data *)strdb_search(npcname_db, name); + return npcname_db.get(name); } /*========================================== @@ -157,7 +157,7 @@ int npc_delete(struct npc_data *nd) int npc_timer_event(const char *eventname) // Added by RoVeRT { - struct event_data *ev = (struct event_data *)strdb_search(ev_db, eventname); + struct event_data *ev = ev_db.search(eventname); struct npc_data *nd; // int xs,ys; @@ -177,13 +177,11 @@ int npc_timer_event(const char *eventname) // Added by RoVeRT *------------------------------------------ */ static -void npc_event_doall_sub(db_key_t key, db_val_t data, +void npc_event_doall_sub(const std::string& key, struct event_data *ev, int *c, const char *name, int rid, int argc, argrec_t *argv) { - const char *p = key.s; - struct event_data *ev; + const char *p = key.c_str(); - ev = (struct event_data *) data; nullpo_retv(ev); if ((p = strchr(p, ':')) && p && strcasecmp(name, p) == 0) @@ -201,18 +199,17 @@ int npc_event_doall_l(const char *name, int rid, int argc, argrec_t *args) strncpy(buf + 2, name, sizeof(buf)-3); buf[sizeof(buf)-1] = '\0'; - strdb_foreach(ev_db, std::bind(npc_event_doall_sub, ph::_1, ph::_2, &c, buf, rid, argc, args)); + for (auto& pair : ev_db) + npc_event_doall_sub(pair.first, &pair.second, &c, buf, rid, argc, args); return c; } static -void npc_event_do_sub(db_key_t key, db_val_t data, +void npc_event_do_sub(const std::string& key, struct event_data *ev, int *c, const char *name, int rid, int argc, argrec_t *argv) { - const char *p = key.s; - struct event_data *ev; + const char *p = key.c_str(); - ev = (struct event_data *) data; nullpo_retv(ev); if (p && strcasecmp(name, p) == 0) @@ -232,7 +229,8 @@ int npc_event_do_l(const char *name, int rid, int argc, argrec_t *args) return npc_event_doall_l(name + 2, rid, argc, args); } - strdb_foreach(ev_db, std::bind(npc_event_do_sub, ph::_1, ph::_2, &c, name, rid, argc, args)); + for (auto& pair : ev_db) + npc_event_do_sub(pair.first, &pair.second, &c, name, rid, argc, args); return c; } @@ -408,7 +406,7 @@ int npc_settimerevent_tick(struct npc_data *nd, interval_t newtimer) int npc_event(struct map_session_data *sd, const char *eventname, int mob_kill) { - struct event_data *ev = (struct event_data *)strdb_search(ev_db, eventname); + struct event_data *ev = ev_db.search(eventname); struct npc_data *nd; int xs, ys; char mobevent[100]; @@ -428,7 +426,7 @@ int npc_event(struct map_session_data *sd, const char *eventname, { strcpy(mobevent, eventname); strcat(mobevent, "::OnMyMobDead"); - ev = (struct event_data *)strdb_search(ev_db, mobevent); + ev = ev_db.search(mobevent); if (ev == NULL || (nd = ev->nd) == NULL) { if (strncasecmp(eventname, "GM_MONSTER", 10) != 0) @@ -493,10 +491,9 @@ int npc_event(struct map_session_data *sd, const char *eventname, } static -void npc_command_sub(db_key_t key, db_val_t data, const char *npcname, const char *command) +void npc_command_sub(const std::string& key, struct event_data *ev, const char *npcname, const char *command) { - const char *p = key.s; - struct event_data *ev = (struct event_data *) data; + const char *p = key.c_str(); char temp[100]; if (strcmp(ev->nd->name, npcname) == 0 && (p = strchr(p, ':')) && p @@ -511,7 +508,8 @@ void npc_command_sub(db_key_t key, db_val_t data, const char *npcname, const cha int npc_command(struct map_session_data *, const char *npcname, const char *command) { - strdb_foreach(ev_db, std::bind(npc_command_sub, ph::_1, ph::_2, npcname, command)); + for (auto& pair : ev_db) + npc_command_sub(pair.first, &pair.second, npcname, command); return 0; } @@ -1031,7 +1029,7 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) nd->bl.subtype = NpcSubtype::WARP; map_addblock(&nd->bl); clif_spawnnpc(nd); - strdb_insert(npcname_db, nd->name, nd); + npcname_db.put(nd->name, nd); return 0; } @@ -1136,7 +1134,7 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) nd->n = map_addnpc(m, nd); map_addblock(&nd->bl); clif_spawnnpc(nd); - strdb_insert(npcname_db, nd->name, nd); + npcname_db.put(nd->name, nd); return 0; } @@ -1146,14 +1144,10 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) *------------------------------------------ */ static -void npc_convertlabel_db(db_key_t key, db_val_t data, struct npc_data *nd) +void npc_convertlabel_db(const std::string& lname, int pos, struct npc_data *nd) { - const char *lname = key.s; - int pos = (int) data; struct npc_label_list *lst; int num; - // this exists for evil purposes - char *p = const_cast(strchr(lname, ':')); nullpo_retv(nd); @@ -1169,11 +1163,7 @@ void npc_convertlabel_db(db_key_t key, db_val_t data, struct npc_data *nd) lst = (struct npc_label_list *) realloc(lst, sizeof(struct npc_label_list) * (num + 1)); - *p = '\0'; - // temporarily NUL-terminate lname - strncpy(lst[num].name, lname, sizeof(lst[num].name)-1); - lst[num].name[sizeof(lst[num].name)-1] = '\0'; - *p = ':'; + strzcpy(lst[num].name, lname.c_str(), sizeof(lst[num].name)); lst[num].pos = pos; nd->u.scr.label_list = lst; nd->u.scr.label_list_num = num + 1; @@ -1198,7 +1188,6 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, char line[1024]; struct npc_data *nd; int evflag = 0; - struct dbt *label_db; char *p; struct npc_label_list *label_dup = NULL; int label_dupnum = 0; @@ -1392,16 +1381,15 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, if (evflag) { // イベント型 - struct event_data *ev = - (struct event_data *) calloc(1, sizeof(struct event_data)); - ev->nd = nd; - ev->pos = 0; - strdb_insert(ev_db, nd->exname, ev); + struct event_data ev {}; + ev.nd = nd; + ev.pos = 0; + ev_db.insert(nd->exname, ev); } else clif_spawnnpc(nd); } - strdb_insert(npcname_db, nd->exname, nd); + npcname_db.put(nd->exname, nd); //----------------------------------------- // ラベルデータの準備 @@ -1410,8 +1398,8 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, // script本体がある場合の処理 // ラベルデータのコンバート - label_db = script_get_label_db(); - strdb_foreach(label_db, std::bind(npc_convertlabel_db, ph::_1, ph::_2, nd)); + for (auto& pair : scriptlabel_db) + npc_convertlabel_db(pair.first, pair.second, nd); // もう使わないのでバッファ解放 free(srcbuf); @@ -1438,24 +1426,16 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) { - struct event_data *ev; - char *buf; - // エクスポートされる - ev = (struct event_data *) calloc(1, - sizeof(struct event_data)); - buf = (char *) calloc(50, sizeof(char)); if (strlen(lname) > 24) { PRINTF("npc_parse_script: label name error !\n"); exit(1); } - else - { - ev->nd = nd; - ev->pos = pos; - sprintf(buf, "%s::%s", nd->exname, lname); - strdb_insert(ev_db, buf, ev); - } + struct event_data ev {}; + ev.nd = nd; + ev.pos = pos; + std::string buf = STRPRINTF("%s::%s", nd->exname, lname); + ev_db.insert(buf, ev); } } @@ -1516,8 +1496,6 @@ int npc_parse_function(char *, char *, char *w3, char *, int startline = 0; char line[1024]; int i; -// struct dbt *label_db; - char *p; // スクリプトの解析 srcbuf = (char *) calloc(srcsize, sizeof(char)); @@ -1563,20 +1541,12 @@ int npc_parse_function(char *, char *, char *w3, char *, return 1; } - p = (char *) calloc(50, sizeof(char)); - - strncpy(p, w3, 49); - // db_val_t takes a void *, we do restore safely ... - ScriptCode *script_ = const_cast(script); - strdb_insert(script_get_userfunc_db(), p, script_); - -// label_db=script_get_label_db(); + std::string p = w3; + userfunc_db.put(p, script); // もう使わないのでバッファ解放 free(srcbuf); -// PRINTF("function %s => %p\n",p,script); - return 0; } @@ -1825,7 +1795,7 @@ struct npc_data *npc_spawn_text(int m, int x, int y, map_addblock(&retval->bl); map_addiddb(&retval->bl); if (retval->name && retval->name[0]) - strdb_insert(npcname_db, retval->name, retval); + npcname_db.put(retval->name, retval); return retval; } @@ -1882,13 +1852,6 @@ void npc_free(struct npc_data *nd) npc_free_internal(nd); } -static -void ev_release(db_key_t key, db_val_t val) -{ - free(key.ms); - free(val); -} - /*========================================== * npc初期化 *------------------------------------------ @@ -1900,11 +1863,6 @@ int do_init_npc(void) char line[1024]; int m, lines; - ev_db = strdb_init(24); - npcname_db = strdb_init(24); - - ev_db->release = ev_release; - memset(&ev_tm_b, -1, sizeof(ev_tm_b)); for (nsl = npc_src_first; nsl; nsl = nsl->next) diff --git a/src/map/party.cpp b/src/map/party.cpp index f6cb84b..277d0c8 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -21,7 +21,7 @@ constexpr interval_t PARTY_SEND_XYHP_INVERVAL = std::chrono::seconds(1); static -struct dbt *party_db; +Map party_db; static int party_check_conflict(struct map_session_data *sd); @@ -31,7 +31,6 @@ void party_send_xyhp_timer(TimerData *tid, tick_t tick); // 初期化 void do_init_party(void) { - party_db = numdb_init(); add_timer_interval(gettick() + PARTY_SEND_XYHP_INVERVAL, party_send_xyhp_timer, PARTY_SEND_XYHP_INVERVAL); @@ -40,13 +39,12 @@ void do_init_party(void) // 検索 struct party *party_search(int party_id) { - return (struct party *)numdb_search(party_db, party_id); + return party_db.search(party_id); } static -void party_searchname_sub(db_key_t, db_val_t data, const char *str, struct party **dst) +void party_searchname_sub(struct party *p, const char *str, struct party **dst) { - struct party *p = (struct party *) data; if (strcasecmp(p->name, str) == 0) *dst = p; } @@ -55,7 +53,8 @@ void party_searchname_sub(db_key_t, db_val_t data, const char *str, struct party struct party *party_searchname(const char *str) { struct party *p = NULL; - numdb_foreach(party_db, std::bind(party_searchname_sub, ph::_1, ph::_2, str, &p)); + for (auto& pair : party_db) + party_searchname_sub(&pair.second, str, &p); return p; } @@ -93,19 +92,18 @@ int party_created(int account_id, int fail, int party_id, const char *name) /* The party name is valid and not already taken. */ if (!fail) { - struct party *p; sd->status.party_id = party_id; - if ((p = (struct party *)numdb_search(party_db, party_id)) != NULL) + struct party *p = party_db.search(party_id); + if (p != NULL) { PRINTF("party_created(): ID already exists!\n"); exit(1); } - CREATE(p, struct party, 1); + p = party_db.init(party_id); p->party_id = party_id; memcpy(p->name, name, 24); - numdb_insert(party_db, party_id, p); /* The party was created successfully. */ clif_party_created(sd, 0); @@ -184,15 +182,14 @@ int party_recv_noinfo(int party_id) // 情報所得 int party_recv_info(const struct party *sp) { - struct party *p; int i; nullpo_ret(sp); - if ((p = (struct party *)numdb_search(party_db, sp->party_id)) == NULL) + struct party *p = party_db.search(sp->party_id); + if (p == NULL) { - CREATE(p, struct party, 1); - numdb_insert(party_db, sp->party_id, p); + p = party_db.init(sp->party_id); // 最初のロードなのでユーザーのチェックを行う *p = *sp; @@ -466,7 +463,7 @@ int party_broken(int party_id) p->member[i].sd->party_sended = 0; } } - numdb_erase(party_db, party_id); + party_db.erase(party_id); return 0; } @@ -633,9 +630,8 @@ int party_check_conflict(struct map_session_data *sd) // 位置やHP通知用 static -void party_send_xyhp_timer_sub(db_key_t, db_val_t data) +void party_send_xyhp_timer_sub(struct party *p) { - struct party *p = (struct party *) data; int i; nullpo_retv(p); @@ -666,7 +662,8 @@ void party_send_xyhp_timer_sub(db_key_t, db_val_t data) // 位置やHP通知 void party_send_xyhp_timer(TimerData *, tick_t) { - numdb_foreach(party_db, party_send_xyhp_timer_sub); + for (auto& pair : party_db) + party_send_xyhp_timer_sub(&pair.second); } // 位置通知クリア diff --git a/src/map/script.cpp b/src/map/script.cpp index e7f957d..a39186e 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -67,30 +67,16 @@ static int str_hash[16]; static -struct dbt *mapreg_db = NULL; +DMap mapreg_db; static -struct dbt *mapregstr_db = NULL; +DMap mapregstr_db; static int mapreg_dirty = -1; char mapreg_txt[256] = "save/mapreg.txt"; constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = std::chrono::seconds(10); -static -struct dbt *scriptlabel_db = NULL; -static -struct dbt *userfunc_db = NULL; - -struct dbt *script_get_label_db(void) -{ - return scriptlabel_db; -} - -struct dbt *script_get_userfunc_db(void) -{ - if (!userfunc_db) - userfunc_db = strdb_init(50); - return userfunc_db; -} +Map scriptlabel_db; +DMap userfunc_db; static const char *pos[11] = @@ -910,9 +896,7 @@ const ScriptCode *parse_script(const char *src, int line) } // 外部用label dbの初期化 - if (scriptlabel_db != NULL) - strdb_final(scriptlabel_db, NULL); - scriptlabel_db = strdb_init(50); + scriptlabel_db.clear(); // for error message startptr = src; @@ -942,7 +926,8 @@ const ScriptCode *parse_script(const char *src, int line) exit(1); } set_label(l, script_pos); - strdb_insert(scriptlabel_db, p, script_pos); // 外部用label db登録 + std::string str(p, skip_word(p)); + scriptlabel_db.insert(str, script_pos); *tmpp = c; p = tmpp + 1; continue; @@ -1049,8 +1034,7 @@ void get_val(ScriptState *st, struct script_data *data) } else if (prefix == '$') { - data->u.str = - (char *) numdb_search(mapregstr_db, data->u.num); + data->u.str = mapregstr_db.get(data->u.num); } else { @@ -1084,7 +1068,7 @@ void get_val(ScriptState *st, struct script_data *data) } else if (prefix == '$') { - data->u.num = (int) numdb_search(mapreg_db, data->u.num); + data->u.num = mapreg_db.get(data->u.num); } else if (prefix == '#') { @@ -1374,8 +1358,7 @@ void builtin_callfunc(ScriptState *st) const ScriptCode *scr; const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2])); - // note: strdb_search returns a void *; but ScriptCode is really const - if ((scr = static_cast(strdb_search(script_get_userfunc_db(), str)))) + if ((scr = userfunc_db.get(str))) { int j = 0; #if 0 @@ -4889,10 +4872,7 @@ int run_script_l(const ScriptCode *script, int pos_, int rid, int oid, */ void mapreg_setreg(int num, int val) { - if (val != 0) - numdb_insert(mapreg_db, num, val); - else - numdb_erase(mapreg_db, num); + mapreg_db.put(num, val); mapreg_dirty = 1; } @@ -4903,20 +4883,16 @@ void mapreg_setreg(int num, int val) */ void mapreg_setregstr(int num, const char *str) { - char *p; - - if ((p = (char *)numdb_search(mapregstr_db, num)) != NULL) + char *p = mapregstr_db.get(num); + if (p) free(p); - if (str == NULL || *str == 0) - { - numdb_erase(mapregstr_db, num); - mapreg_dirty = 1; - return; - } - p = (char *) calloc(strlen(str) + 1, 1); - strcpy(p, str); - numdb_insert(mapregstr_db, num, p); + if (!str || !*str) + p = NULL; + else + p = strdup(str); + + mapregstr_db.put(num, p); mapreg_dirty = 1; } @@ -4951,14 +4927,14 @@ void script_load_mapreg(void) if (buf1.back() == '$') { char *p = strdup(buf2.c_str()); - numdb_insert(mapregstr_db, key, p); + mapregstr_db.put(key, p); } else { int v; if (!extract(buf2, &v)) goto borken; - numdb_insert(mapreg_db, key, v); + mapreg_db.put(key, v); } } else @@ -4976,30 +4952,30 @@ void script_load_mapreg(void) *------------------------------------------ */ static -void script_save_mapreg_intsub(db_key_t key, db_val_t data, FILE *fp) +void script_save_mapreg_intsub(int key, int data, FILE *fp) { - int num = key.i & 0x00ffffff, i = key.i >> 24; + int num = key & 0x00ffffff, i = key >> 24; char *name = str_buf + str_data[num].str; if (name[1] != '@') { if (i == 0) - FPRINTF(fp, "%s\t%d\n", name, (int) data); + FPRINTF(fp, "%s\t%d\n", name, data); else - FPRINTF(fp, "%s,%d\t%d\n", name, i, (int) data); + FPRINTF(fp, "%s,%d\t%d\n", name, i, data); } } static -void script_save_mapreg_strsub(db_key_t key, db_val_t data, FILE *fp) +void script_save_mapreg_strsub(int key, char *data, FILE *fp) { - int num = key.i & 0x00ffffff, i = key.i >> 24; + int num = key & 0x00ffffff, i = key >> 24; char *name = str_buf + str_data[num].str; if (name[1] != '@') { if (i == 0) - FPRINTF(fp, "%s\t%s\n", name, (char *) data); + FPRINTF(fp, "%s\t%s\n", name, data); else - FPRINTF(fp, "%s,%d\t%s\n", name, i, (char *) data); + FPRINTF(fp, "%s,%d\t%s\n", name, i, data); } } @@ -5011,8 +4987,10 @@ void script_save_mapreg(void) if ((fp = lock_fopen(mapreg_txt, &lock)) == NULL) return; - numdb_foreach(mapreg_db, std::bind(script_save_mapreg_intsub, ph::_1, ph::_2, fp)); - numdb_foreach(mapregstr_db, std::bind(script_save_mapreg_strsub, ph::_1, ph::_2, fp)); + for (auto& pair : mapreg_db) + script_save_mapreg_intsub(pair.first, pair.second, fp); + for (auto& pair : mapregstr_db) + script_save_mapreg_strsub(pair.first, pair.second, fp); lock_fclose(fp, mapreg_txt, &lock); mapreg_dirty = 0; } @@ -5040,16 +5018,15 @@ void script_config_read() */ static -void mapregstr_db_final(db_key_t, db_val_t data) +void mapregstr_db_final(char *data) { free(data); } static -void userfunc_db_final(db_key_t key, db_val_t data) +void userfunc_db_final(const ScriptCode *data) { - free(key.ms); - free(data); + free(const_cast(data)); } void do_final_script(void) @@ -5065,14 +5042,14 @@ void do_final_script(void) free(script_buf); #endif - if (mapreg_db) - numdb_final(mapreg_db, NULL); - if (mapregstr_db) - strdb_final(mapregstr_db, mapregstr_db_final); - if (scriptlabel_db) - strdb_final(scriptlabel_db, NULL); - if (userfunc_db) - strdb_final(userfunc_db, userfunc_db_final); + mapreg_db.clear(); + for (auto& pair : mapregstr_db) + mapregstr_db_final(pair.second); + mapregstr_db.clear(); + scriptlabel_db.clear(); + for (auto& pair : userfunc_db) + userfunc_db_final(pair.second); + userfunc_db.clear(); if (str_data) free(str_data); @@ -5086,15 +5063,11 @@ void do_final_script(void) */ void do_init_script(void) { - mapreg_db = numdb_init(); - mapregstr_db = numdb_init(); script_load_mapreg(); add_timer_interval(gettick() + MAPREG_AUTOSAVE_INTERVAL, script_autosave_mapreg, MAPREG_AUTOSAVE_INTERVAL); - - scriptlabel_db = strdb_init(50); } #define BUILTIN(func, args) \ diff --git a/src/map/script.hpp b/src/map/script.hpp index e09baf8..352164b 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -3,6 +3,10 @@ #include +#include + +#include "../common/db.hpp" + enum class ScriptCode : uint8_t; struct script_data @@ -50,8 +54,10 @@ typedef struct argrec int run_script_l(const ScriptCode *, int, int, int, int, argrec_t *args); int run_script(const ScriptCode *, int, int, int); -struct dbt *script_get_label_db(void); -struct dbt *script_get_userfunc_db(void); +extern +Map scriptlabel_db; +extern +DMap userfunc_db; void script_config_read(); void do_init_script(void); diff --git a/src/map/storage.cpp b/src/map/storage.cpp index bcdf8bc..dcd0dd7 100644 --- a/src/map/storage.cpp +++ b/src/map/storage.cpp @@ -19,7 +19,7 @@ #include "../poison.hpp" static -struct dbt *storage_db; +Map storage_db; /*========================================== * 倉庫内アイテムソート @@ -40,13 +40,6 @@ int storage_comp_item(const void *_i1, const void *_i2) return i1->nameid - i2->nameid; } -static -void storage_db_final(db_key_t, db_val_t data) -{ - struct storage *stor = (struct storage *) data; - free(stor); -} - static void sortage_sortitem(struct storage *stor) { @@ -55,31 +48,22 @@ void sortage_sortitem(struct storage *stor) storage_comp_item); } -/*========================================== - * 初期化とか - *------------------------------------------ - */ -int do_init_storage(void) // map.c::do_init()から呼ばれる +void do_init_storage(void) { - storage_db = numdb_init(); - return 1; } -void do_final_storage(void) // by [MC Cameri] +void do_final_storage(void) { - if (storage_db) - numdb_final(storage_db, storage_db_final); + storage_db.clear(); } struct storage *account2storage(int account_id) { - struct storage *stor = - (struct storage *) numdb_search(storage_db, account_id); + struct storage *stor = storage_db.search(account_id); if (stor == NULL) { - CREATE(stor, struct storage, 1); + stor = storage_db.init(account_id); stor->account_id = account_id; - numdb_insert(storage_db, stor->account_id, stor); } return stor; } @@ -87,20 +71,13 @@ struct storage *account2storage(int account_id) // Just to ask storage, without creation struct storage *account2storage2(int account_id) { - return (struct storage *) numdb_search(storage_db, account_id); + return storage_db.search(account_id); } static -int storage_delete(int account_id) +void storage_delete(int account_id) { - struct storage *stor = - (struct storage *) numdb_search(storage_db, account_id); - if (stor) - { - numdb_erase(storage_db, account_id); - free(stor); - } - return 0; + storage_db.erase(account_id); } /*========================================== @@ -109,15 +86,13 @@ int storage_delete(int account_id) */ int storage_storageopen(struct map_session_data *sd) { - struct storage *stor; nullpo_ret(sd); if (sd->state.storage_open) return 1; //Already open? - if ((stor = - (struct storage *) numdb_search(storage_db, - sd->status.account_id)) == NULL) + struct storage *stor = storage_db.search(sd->status.account_id); + if (stor == NULL) { //Request storage. intif_request_storage(sd->status.account_id); return 1; diff --git a/src/map/storage.hpp b/src/map/storage.hpp index 9daa446..1974efb 100644 --- a/src/map/storage.hpp +++ b/src/map/storage.hpp @@ -8,7 +8,7 @@ int storage_storageopen(struct map_session_data *sd); int storage_storageadd(struct map_session_data *sd, int index, int amount); int storage_storageget(struct map_session_data *sd, int index, int amount); int storage_storageclose(struct map_session_data *sd); -int do_init_storage(void); +void do_init_storage(void); void do_final_storage(void); struct storage *account2storage(int account_id); struct storage *account2storage2(int account_id); -- cgit v1.2.3-60-g2f50