summaryrefslogtreecommitdiff
path: root/src/char/int_storage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/char/int_storage.cpp')
-rw-r--r--src/char/int_storage.cpp570
1 files changed, 108 insertions, 462 deletions
diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp
index a962b92..ba55538 100644
--- a/src/char/int_storage.cpp
+++ b/src/char/int_storage.cpp
@@ -1,442 +1,161 @@
-// $Id: int_storage.c,v 1.1.1.1 2004/09/10 17:26:51 MagicalTux Exp $
+#include "int_storage.hpp"
-#include <string.h>
-#include <stdlib.h>
+#include <cstdlib>
+#include <cstring>
-#include "../common/mmo.hpp"
-#include "../common/socket.hpp"
+#include <functional>
+#include <fstream>
+
+#include "../common/cxxstdio.hpp"
#include "../common/db.hpp"
+#include "../common/extract.hpp"
#include "../common/lock.hpp"
-#include "char.hpp"
-#include "inter.hpp"
-#include "int_storage.hpp"
-#include "int_guild.hpp"
+#include "../common/mmo.hpp"
+#include "../common/socket.hpp"
+
+#include "../poison.hpp"
// ファイル名のデフォルト
// inter_config_read()で再設定される
char storage_txt[1024] = "save/storage.txt";
-char guild_storage_txt[1024] = "save/g_storage.txt";
-static struct dbt *storage_db;
-static struct dbt *guild_storage_db;
+static
+Map<int, struct storage> storage_db;
// 倉庫データを文字列に変換
static
-int storage_tostr (char *str, struct storage *p)
+std::string storage_tostr(struct storage *p)
{
- int i, f = 0;
- char *str_p = str;
- str_p += sprintf (str_p, "%d,%d\t", p->account_id, p->storage_amount);
+ std::string str = STRPRINTF(
+ "%d,%d\t",
+ p->account_id, p->storage_amount);
- for (i = 0; i < MAX_STORAGE; i++)
- if ((p->storage_[i].nameid) && (p->storage_[i].amount))
+ int f = 0;
+ for (int i = 0; i < MAX_STORAGE; i++)
+ if (p->storage_[i].nameid && p->storage_[i].amount)
{
- str_p += sprintf (str_p, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
- p->storage_[i].id, p->storage_[i].nameid,
- p->storage_[i].amount, p->storage_[i].equip,
- p->storage_[i].identify, p->storage_[i].refine,
- p->storage_[i].attribute,
- p->storage_[i].card[0], p->storage_[i].card[1],
- p->storage_[i].card[2], p->storage_[i].card[3]);
+ str += STRPRINTF(
+ "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
+ p->storage_[i].id,
+ p->storage_[i].nameid,
+ p->storage_[i].amount,
+ p->storage_[i].equip,
+ p->storage_[i].identify,
+ p->storage_[i].refine,
+ p->storage_[i].attribute,
+ p->storage_[i].card[0],
+ p->storage_[i].card[1],
+ p->storage_[i].card[2],
+ p->storage_[i].card[3]);
f++;
}
- *(str_p++) = '\t';
+ str += '\t';
- *str_p = '\0';
if (!f)
- str[0] = 0;
- return 0;
+ str.clear();
+ return str;
}
// 文字列を倉庫データに変換
static
-int storage_fromstr (char *str, struct storage *p)
+bool extract(const_string str, struct storage *p)
{
- int tmp_int[256];
- int set, next, len, i;
+ std::vector<struct item> storage_items;
+ if (!extract(str,
+ record<'\t'>(
+ record<','>(
+ &p->account_id,
+ &p->storage_amount),
+ vrec<' '>(&storage_items))))
+ return false;
- set = sscanf (str, "%d,%d%n", &tmp_int[0], &tmp_int[1], &next);
- p->storage_amount = tmp_int[1];
+ if (p->account_id <= 0)
+ return false;
- if (set != 2)
- return 1;
- if (str[next] == '\n' || str[next] == '\r')
- return 0;
- next++;
- for (i = 0; str[next] && str[next] != '\t' && i < MAX_STORAGE; i++)
- {
- if (sscanf (str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
- &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
- &tmp_int[4], &tmp_int[5], &tmp_int[6],
- &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10],
- &tmp_int[10], &len) == 12)
- {
- p->storage_[i].id = tmp_int[0];
- p->storage_[i].nameid = tmp_int[1];
- p->storage_[i].amount = tmp_int[2];
- p->storage_[i].equip = tmp_int[3];
- p->storage_[i].identify = tmp_int[4];
- p->storage_[i].refine = tmp_int[5];
- p->storage_[i].attribute = tmp_int[6];
- p->storage_[i].card[0] = tmp_int[7];
- p->storage_[i].card[1] = tmp_int[8];
- p->storage_[i].card[2] = tmp_int[9];
- p->storage_[i].card[3] = tmp_int[10];
- next += len;
- if (str[next] == ' ')
- next++;
- }
-
- else if (sscanf (str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
- &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
- &tmp_int[4], &tmp_int[5], &tmp_int[6],
- &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10],
- &len) == 11)
- {
- p->storage_[i].id = tmp_int[0];
- p->storage_[i].nameid = tmp_int[1];
- p->storage_[i].amount = tmp_int[2];
- p->storage_[i].equip = tmp_int[3];
- p->storage_[i].identify = tmp_int[4];
- p->storage_[i].refine = tmp_int[5];
- p->storage_[i].attribute = tmp_int[6];
- p->storage_[i].card[0] = tmp_int[7];
- p->storage_[i].card[1] = tmp_int[8];
- p->storage_[i].card[2] = tmp_int[9];
- p->storage_[i].card[3] = tmp_int[10];
- next += len;
- if (str[next] == ' ')
- next++;
- }
+ if (storage_items.size() >= MAX_STORAGE)
+ return false;
+ std::copy(storage_items.begin(), storage_items.end(), p->storage_);
- else
- return 1;
- }
- if (i >= MAX_STORAGE && str[next] && str[next] != '\t')
- printf
- ("storage_fromstr: Found a storage line with more items than MAX_STORAGE (%d), remaining items have been discarded!\n",
- MAX_STORAGE);
- return 0;
-}
-
-static
-int guild_storage_tostr (char *str, struct guild_storage *p)
-{
- int i, f = 0;
- char *str_p = str;
- str_p += sprintf (str, "%d,%d\t", p->guild_id, p->storage_amount);
-
- for (i = 0; i < MAX_GUILD_STORAGE; i++)
- if ((p->storage_[i].nameid) && (p->storage_[i].amount))
- {
- str_p += sprintf (str_p, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
- p->storage_[i].id, p->storage_[i].nameid,
- p->storage_[i].amount, p->storage_[i].equip,
- p->storage_[i].identify, p->storage_[i].refine,
- p->storage_[i].attribute,
- p->storage_[i].card[0], p->storage_[i].card[1],
- p->storage_[i].card[2], p->storage_[i].card[3]);
- f++;
- }
-
- *(str_p++) = '\t';
-
- *str_p = '\0';
- if (!f)
- str[0] = 0;
- return 0;
-}
-
-static
-int guild_storage_fromstr (char *str, struct guild_storage *p)
-{
- int tmp_int[256];
- int set, next, len, i;
-
- set = sscanf (str, "%d,%d%n", &tmp_int[0], &tmp_int[1], &next);
- p->storage_amount = tmp_int[1];
-
- if (set != 2)
- return 1;
- if (str[next] == '\n' || str[next] == '\r')
- return 0;
- next++;
- for (i = 0; str[next] && str[next] != '\t' && i < MAX_GUILD_STORAGE; i++)
- {
- if (sscanf (str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
- &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
- &tmp_int[4], &tmp_int[5], &tmp_int[6],
- &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10],
- &tmp_int[10], &len) == 12)
- {
- p->storage_[i].id = tmp_int[0];
- p->storage_[i].nameid = tmp_int[1];
- p->storage_[i].amount = tmp_int[2];
- p->storage_[i].equip = tmp_int[3];
- p->storage_[i].identify = tmp_int[4];
- p->storage_[i].refine = tmp_int[5];
- p->storage_[i].attribute = tmp_int[6];
- p->storage_[i].card[0] = tmp_int[7];
- p->storage_[i].card[1] = tmp_int[8];
- p->storage_[i].card[2] = tmp_int[9];
- p->storage_[i].card[3] = tmp_int[10];
- next += len;
- if (str[next] == ' ')
- next++;
- }
-
- else if (sscanf (str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
- &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
- &tmp_int[4], &tmp_int[5], &tmp_int[6],
- &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10],
- &len) == 11)
- {
- p->storage_[i].id = tmp_int[0];
- p->storage_[i].nameid = tmp_int[1];
- p->storage_[i].amount = tmp_int[2];
- p->storage_[i].equip = tmp_int[3];
- p->storage_[i].identify = tmp_int[4];
- p->storage_[i].refine = tmp_int[5];
- p->storage_[i].attribute = tmp_int[6];
- p->storage_[i].card[0] = tmp_int[7];
- p->storage_[i].card[1] = tmp_int[8];
- p->storage_[i].card[2] = tmp_int[9];
- p->storage_[i].card[3] = tmp_int[10];
- next += len;
- if (str[next] == ' ')
- next++;
- }
-
- else
- return 1;
- }
- if (i >= MAX_GUILD_STORAGE && str[next] && str[next] != '\t')
- printf
- ("guild_storage_fromstr: Found a storage line with more items than MAX_GUILD_STORAGE (%d), remaining items have been discarded!\n",
- MAX_GUILD_STORAGE);
- return 0;
+ return true;
}
// アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
-struct storage *account2storage (int account_id)
+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;
}
-static
-struct guild_storage *guild2storage (int guild_id)
-{
- struct guild_storage *gs = NULL;
- if (inter_guild_search (guild_id) != NULL)
- {
- gs = (struct guild_storage *) numdb_search (guild_storage_db,
- guild_id);
- if (gs == NULL)
- {
- CREATE (gs, struct guild_storage, 1);
- gs->guild_id = guild_id;
- numdb_insert (guild_storage_db, gs->guild_id, gs);
- }
- }
- return gs;
-}
-
//---------------------------------------------------------
// 倉庫データを読み込む
-int inter_storage_init (void)
+int inter_storage_init(void)
{
- char line[65536];
- int c = 0, tmp_int;
- struct storage *s;
- struct guild_storage *gs;
- FILE *fp;
-
- storage_db = numdb_init ();
+ int c = 0;
- fp = fopen_ (storage_txt, "r");
- if (fp == NULL)
+ std::ifstream in(storage_txt);
+ if (!in.is_open())
{
- printf ("cant't read : %s\n", storage_txt);
+ PRINTF("cant't read : %s\n", storage_txt);
return 1;
}
- while (fgets (line, 65535, fp))
- {
- sscanf (line, "%d", &tmp_int);
- CREATE (s, struct storage, 1);
- s->account_id = tmp_int;
- if (s->account_id > 0 && storage_fromstr (line, s) == 0)
- {
- numdb_insert (storage_db, s->account_id, s);
- }
- else
- {
- printf ("int_storage: broken data [%s] line %d\n", storage_txt,
- c);
- free (s);
- }
- c++;
- }
- fclose_ (fp);
-
- c = 0;
- guild_storage_db = numdb_init ();
- fp = fopen_ (guild_storage_txt, "r");
- if (fp == NULL)
- {
- printf ("cant't read : %s\n", guild_storage_txt);
- return 1;
- }
- while (fgets (line, 65535, fp))
+ std::string line;
+ while (std::getline(in, line))
{
- sscanf (line, "%d", &tmp_int);
- CREATE (gs, struct guild_storage, 1);
- gs->guild_id = tmp_int;
- if (gs->guild_id > 0 && guild_storage_fromstr (line, gs) == 0)
+ struct storage s {};
+ if (extract(line, &s))
{
- numdb_insert (guild_storage_db, gs->guild_id, gs);
+ storage_db.insert(s.account_id, s);
}
else
{
- printf ("int_storage: broken data [%s] line %d\n",
- guild_storage_txt, c);
- free (gs);
+ PRINTF("int_storage: broken data [%s] line %d\n",
+ storage_txt, c);
}
c++;
}
- fclose_ (fp);
return 0;
}
static
-void storage_db_final (db_key_t k, db_val_t data, va_list ap)
-{
- struct storage *p = (struct storage *) data;
- if (p)
- free (p);
-}
-
-static
-void guild_storage_db_final (db_key_t k, db_val_t data, va_list ap)
+void inter_storage_save_sub(struct storage *data, FILE *fp)
{
- struct guild_storage *p = (struct guild_storage *) data;
- if (p)
- free (p);
-}
-
-void inter_storage_final (void)
-{
- numdb_final (storage_db, storage_db_final);
- numdb_final (guild_storage_db, guild_storage_db_final);
- return;
-}
-
-static
-void inter_storage_save_sub (db_key_t key, db_val_t data, va_list ap)
-{
- char line[65536];
- FILE *fp;
- storage_tostr (line, (struct storage *) data);
- fp = va_arg (ap, FILE *);
- if (*line)
- fprintf (fp, "%s\n", line);
+ std::string line = storage_tostr(data);
+ if (!line.empty())
+ FPRINTF(fp, "%s\n", line);
}
//---------------------------------------------------------
// 倉庫データを書き込む
-int inter_storage_save (void)
+int inter_storage_save(void)
{
FILE *fp;
- int lock;
-
- if (!storage_db)
- return 1;
+ int lock;
- if ((fp = lock_fopen (storage_txt, &lock)) == NULL)
+ if ((fp = lock_fopen(storage_txt, &lock)) == NULL)
{
- printf ("int_storage: cant write [%s] !!! data is lost !!!\n",
+ PRINTF("int_storage: cant write [%s] !!! data is lost !!!\n",
storage_txt);
return 1;
}
- numdb_foreach (storage_db, inter_storage_save_sub, fp);
- lock_fclose (fp, storage_txt, &lock);
-// printf("int_storage: %s saved.\n",storage_txt);
- return 0;
-}
-
-static
-void inter_guild_storage_save_sub (db_key_t key, db_val_t data, va_list ap)
-{
- char line[65536];
- FILE *fp;
-
- if (inter_guild_search (((struct guild_storage *) data)->guild_id) !=
- NULL)
- {
- guild_storage_tostr (line, (struct guild_storage *) data);
- fp = va_arg (ap, FILE *);
- if (*line)
- fprintf (fp, "%s\n", line);
- }
-}
-
-//---------------------------------------------------------
-// 倉庫データを書き込む
-int inter_guild_storage_save (void)
-{
- FILE *fp;
- int lock;
-
- if (!guild_storage_db)
- return 1;
-
- if ((fp = lock_fopen (guild_storage_txt, &lock)) == NULL)
- {
- printf ("int_storage: cant write [%s] !!! data is lost !!!\n",
- guild_storage_txt);
- return 1;
- }
- numdb_foreach (guild_storage_db, inter_guild_storage_save_sub, fp);
- lock_fclose (fp, guild_storage_txt, &lock);
-// printf("int_storage: %s saved.\n",guild_storage_txt);
+ 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;
-}
-
-// ギルド倉庫データ削除
-int inter_guild_storage_delete (int guild_id)
-{
- struct guild_storage *gs =
- (struct guild_storage *) numdb_search (guild_storage_db, guild_id);
- if (gs)
- {
- numdb_erase (guild_storage_db, guild_id);
- free (gs);
- }
- return 0;
+ storage_db.erase(account_id);
}
//---------------------------------------------------------
@@ -444,60 +163,25 @@ int inter_guild_storage_delete (int guild_id)
// 倉庫データの送信
static
-int mapif_load_storage (int fd, int account_id)
+int mapif_load_storage(int fd, int account_id)
{
- struct storage *s = account2storage (account_id);
- WFIFOW (fd, 0) = 0x3810;
- WFIFOW (fd, 2) = sizeof (struct storage) + 8;
- WFIFOL (fd, 4) = account_id;
- memcpy (WFIFOP (fd, 8), s, sizeof (struct storage));
- WFIFOSET (fd, WFIFOW (fd, 2));
+ struct storage *s = account2storage(account_id);
+ WFIFOW(fd, 0) = 0x3810;
+ WFIFOW(fd, 2) = sizeof(struct storage) + 8;
+ WFIFOL(fd, 4) = account_id;
+ memcpy(WFIFOP(fd, 8), s, sizeof(struct storage));
+ WFIFOSET(fd, WFIFOW(fd, 2));
return 0;
}
// 倉庫データ保存完了送信
static
-int mapif_save_storage_ack (int fd, int account_id)
+int mapif_save_storage_ack(int fd, int account_id)
{
- WFIFOW (fd, 0) = 0x3811;
- WFIFOL (fd, 2) = account_id;
- WFIFOB (fd, 6) = 0;
- WFIFOSET (fd, 7);
- return 0;
-}
-
-static
-int mapif_load_guild_storage (int fd, int account_id, int guild_id)
-{
- struct guild_storage *gs = guild2storage (guild_id);
- WFIFOW (fd, 0) = 0x3818;
- if (gs)
- {
- WFIFOW (fd, 2) = sizeof (struct guild_storage) + 12;
- WFIFOL (fd, 4) = account_id;
- WFIFOL (fd, 8) = guild_id;
- memcpy (WFIFOP (fd, 12), gs, sizeof (struct guild_storage));
- }
- else
- {
- WFIFOW (fd, 2) = 12;
- WFIFOL (fd, 4) = account_id;
- WFIFOL (fd, 8) = 0;
- }
- WFIFOSET (fd, WFIFOW (fd, 2));
-
- return 0;
-}
-
-static
-int mapif_save_guild_storage_ack (int fd, int account_id, int guild_id,
- int fail)
-{
- WFIFOW (fd, 0) = 0x3819;
- WFIFOL (fd, 2) = account_id;
- WFIFOL (fd, 6) = guild_id;
- WFIFOB (fd, 10) = fail;
- WFIFOSET (fd, 11);
+ WFIFOW(fd, 0) = 0x3811;
+ WFIFOL(fd, 2) = account_id;
+ WFIFOB(fd, 6) = 0;
+ WFIFOSET(fd, 7);
return 0;
}
@@ -506,61 +190,29 @@ int mapif_save_guild_storage_ack (int fd, int account_id, int guild_id,
// 倉庫データ要求受信
static
-int mapif_parse_LoadStorage (int fd)
+int mapif_parse_LoadStorage(int fd)
{
- mapif_load_storage (fd, RFIFOL (fd, 2));
+ mapif_load_storage(fd, RFIFOL(fd, 2));
return 0;
}
// 倉庫データ受信&保存
static
-int mapif_parse_SaveStorage (int fd)
+int mapif_parse_SaveStorage(int fd)
{
struct storage *s;
- int account_id = RFIFOL (fd, 4);
- int len = RFIFOW (fd, 2);
- if (sizeof (struct storage) != len - 8)
- {
- printf ("inter storage: data size error %d %d\n",
- sizeof (struct storage), len - 8);
- }
- else
+ int account_id = RFIFOL(fd, 4);
+ int len = RFIFOW(fd, 2);
+ if (sizeof(struct storage) != len - 8)
{
- s = account2storage (account_id);
- memcpy (s, RFIFOP (fd, 8), sizeof (struct storage));
- mapif_save_storage_ack (fd, account_id);
- }
- return 0;
-}
-
-static
-int mapif_parse_LoadGuildStorage (int fd)
-{
- mapif_load_guild_storage (fd, RFIFOL (fd, 2), RFIFOL (fd, 6));
- return 0;
-}
-
-static
-int mapif_parse_SaveGuildStorage (int fd)
-{
- struct guild_storage *gs;
- int guild_id = RFIFOL (fd, 8);
- int len = RFIFOW (fd, 2);
- if (sizeof (struct guild_storage) != len - 12)
- {
- printf ("inter storage: data size error %d %d\n",
- sizeof (struct guild_storage), len - 12);
+ PRINTF("inter storage: data size error %zu %d\n",
+ sizeof(struct storage), len - 8);
}
else
{
- gs = guild2storage (guild_id);
- if (gs)
- {
- memcpy (gs, RFIFOP (fd, 12), sizeof (struct guild_storage));
- mapif_save_guild_storage_ack (fd, RFIFOL (fd, 4), guild_id, 0);
- }
- else
- mapif_save_guild_storage_ack (fd, RFIFOL (fd, 4), guild_id, 1);
+ s = account2storage(account_id);
+ memcpy(s, RFIFOP(fd, 8), sizeof(struct storage));
+ mapif_save_storage_ack(fd, account_id);
}
return 0;
}
@@ -570,21 +222,15 @@ int mapif_parse_SaveGuildStorage (int fd)
// ・パケット長データはinter.cにセットしておくこと
// ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない
// ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない
-int inter_storage_parse_frommap (int fd)
+int inter_storage_parse_frommap(int fd)
{
- switch (RFIFOW (fd, 0))
+ switch (RFIFOW(fd, 0))
{
case 0x3010:
- mapif_parse_LoadStorage (fd);
+ mapif_parse_LoadStorage(fd);
break;
case 0x3011:
- mapif_parse_SaveStorage (fd);
- break;
- case 0x3018:
- mapif_parse_LoadGuildStorage (fd);
- break;
- case 0x3019:
- mapif_parse_SaveGuildStorage (fd);
+ mapif_parse_SaveStorage(fd);
break;
default:
return 0;