summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-02-23 14:28:21 -0800
committerBen Longbons <b.r.longbons@gmail.com>2013-02-23 15:13:16 -0800
commit1e77f5dc8d95bbf912205c85274d294a80ea65c9 (patch)
tree054aa52764297b205431dfe82119a7f3e5e7ecd1
parent25823b36905a84d92f9299ba7f9f0c713141c8fb (diff)
downloadtmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.tar.gz
tmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.tar.bz2
tmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.tar.xz
tmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.zip
Replace struct dbt with typesafe std::map wrappers
Also fix broken save/accreg.txt reading.
-rw-r--r--src/char/int_party.cpp166
-rw-r--r--src/char/int_party.hpp2
-rw-r--r--src/char/int_storage.cpp40
-rw-r--r--src/char/int_storage.hpp2
-rw-r--r--src/char/inter.cpp93
-rw-r--r--src/common/db.cpp545
-rw-r--r--src/common/db.hpp174
-rw-r--r--src/login/login.cpp42
-rw-r--r--src/map/itemdb.cpp37
-rw-r--r--src/map/itemdb.hpp2
-rw-r--r--src/map/map.cpp124
-rw-r--r--src/map/map.hpp6
-rw-r--r--src/map/mob.cpp14
-rw-r--r--src/map/npc.cpp124
-rw-r--r--src/map/party.cpp33
-rw-r--r--src/map/script.cpp115
-rw-r--r--src/map/script.hpp10
-rw-r--r--src/map/storage.cpp47
-rw-r--r--src/map/storage.hpp2
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<int, struct party> 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<int, struct storage> 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 <cassert>
#include <cstdlib>
#include <cstring>
@@ -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<int, struct accreg> 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<int, struct WisData> 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, &reg))
{
- 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<const char *>(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 <cstdlib>
-#include <cstring>
-
-#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<K, V>
+//
+// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "sanity.hpp"
-# include <functional>
+# include <map>
-/// 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 K, class V>
+class Map
{
- RED,
- BLACK,
-} dbn_color;
+ typedef std::map<K, V> 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<void(db_key_t, db_val_t)> 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<K, V>(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 K, class V>
+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<K, V> 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<int, struct gm_account> 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<int, struct item_data> 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<ScriptCode *>(id->use_script));
if (id->equip_script)
free(const_cast<ScriptCode *>(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<int, struct block_list *> id_db;
+
static
-struct dbt *map_db = NULL;
+DMap<std::string, struct map_data *> map_db;
+
static
-struct dbt *nick_db = NULL;
+DMap<std::string, struct map_session_data *> nick_db;
+
+struct charid2nick
+{
+ char nick[24];
+ int req_id;
+};
+
static
-struct dbt *charid_db = NULL;
+Map<int, struct charid2nick> 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,21 +1148,12 @@ 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<void(struct block_list *)>,
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<int, struct block_list *> 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,17 +40,17 @@ 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<std::string, struct event_data> ev_db;
+static
+DMap<std::string, struct npc_data *> 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<char *>(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<ScriptCode *>(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<int, struct party> 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<int, int> mapreg_db;
static
-struct dbt *mapregstr_db = NULL;
+DMap<int, char *> 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<std::string, int> scriptlabel_db;
+DMap<std::string, const ScriptCode *> 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<const ScriptCode *>(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<ScriptCode *>(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 <cstdint>
+#include <string>
+
+#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<std::string, int> scriptlabel_db;
+extern
+DMap<std::string, const ScriptCode *> 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<int, struct storage> storage_db;
/*==========================================
* 倉庫内アイテムソート
@@ -41,13 +41,6 @@ int storage_comp_item(const void *_i1, const void *_i2)
}
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)
{
nullpo_retv(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);