summaryrefslogtreecommitdiff
path: root/src/char/int_storage.c
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-08-19 16:00:30 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-08-19 16:00:30 +0000
commit83bbf93278328b5530ce7f0d6d5a5160148e3e1e (patch)
tree3989709252e556de2fda83d617d56d589d8f13b1 /src/char/int_storage.c
parent73c06082f78f6ba79e40bf66c531d5ff99082fee (diff)
downloadhercules-83bbf93278328b5530ce7f0d6d5a5160148e3e1e.tar.gz
hercules-83bbf93278328b5530ce7f0d6d5a5160148e3e1e.tar.bz2
hercules-83bbf93278328b5530ce7f0d6d5a5160148e3e1e.tar.xz
hercules-83bbf93278328b5530ce7f0d6d5a5160148e3e1e.zip
* Fixed a storage saving issue with txt charserver (bugreport:2084)
- caused by incorrect idb_ensure -> idb_get change (see r12950) - removed redundant account_id variable from storage data - cleaned up the very messy txt storage handling code git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13093 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/char/int_storage.c')
-rw-r--r--src/char/int_storage.c161
1 files changed, 88 insertions, 73 deletions
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 981561043..a7dd66ec5 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -23,19 +23,18 @@
char storage_txt[1024]="save/storage.txt";
char guild_storage_txt[1024]="save/g_storage.txt";
-#ifndef TXT_SQL_CONVERT
static DBMap* storage_db; // int account_id -> struct storage_data*
static DBMap* guild_storage_db; // int guild_id -> struct guild_storage*
// 倉庫データを文字列に変換
-int storage_tostr(char* str, struct storage_data* p)
+bool storage_tostr(char* str, int account_id, struct storage_data* p)
{
- int i,j,f=0;
+ int i,j;
char *str_p = str;
- str_p += sprintf(str_p, "%d,%d\t", p->account_id, p->storage_amount);
+ str_p += sprintf(str_p, "%d,%d\t", account_id, p->storage_amount);
- for(i=0;i<MAX_STORAGE;i++)
- if( (p->items[i].nameid) && (p->items[i].amount) )
+ for( i = 0; i < MAX_STORAGE; i++ )
+ if( p->items[i].nameid > 0 && p->items[i].amount > 0 )
{
str_p += sprintf(str_p, "%d,%d,%d,%d,%d,%d,%d",
p->items[i].id,p->items[i].nameid,p->items[i].amount,p->items[i].equip,
@@ -43,62 +42,58 @@ int storage_tostr(char* str, struct storage_data* p)
for(j=0; j<MAX_SLOTS; j++)
str_p += sprintf(str_p,",%d",p->items[i].card[j]);
str_p += sprintf(str_p," ");
- f++;
}
*(str_p++)='\t';
*str_p='\0';
- if(!f)
- str[0]=0;
- return 0;
+ return true;
}
-#endif //TXT_SQL_CONVERT
// 文字列を倉庫データに変換
-int storage_fromstr(char* str, struct storage_data* p)
+bool storage_fromstr(char* str, int* account_id, struct storage_data* p)
{
int tmp_int[256];
char tmp_str[256];
- int set,next,len,i,j;
+ int next,len,i,j;
- set=sscanf(str,"%d,%d%n",&tmp_int[0],&tmp_int[1],&next);
- p->storage_amount=tmp_int[1];
+ if( sscanf(str, "%d,%d%n", &tmp_int[0], &tmp_int[1], &next) != 2 )
+ return false;
+
+ *account_id = tmp_int[0];
+ p->storage_amount = tmp_int[1]; //FIXME: limit to MAX_STORAGE?
- 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++)
+ for( i = 0; str[next] && str[next]!='\t' && i < MAX_STORAGE; i++ )
{
if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d%[0-9,-]%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
- &tmp_int[4], &tmp_int[5], &tmp_int[6], tmp_str, &len) == 8) {
- p->items[i].id = tmp_int[0];
- p->items[i].nameid = tmp_int[1];
- p->items[i].amount = tmp_int[2];
- p->items[i].equip = tmp_int[3];
- p->items[i].identify = tmp_int[4];
- p->items[i].refine = tmp_int[5];
- p->items[i].attribute = tmp_int[6];
+ &tmp_int[4], &tmp_int[5], &tmp_int[6], tmp_str, &len) != 8)
+ return false;
+
+ p->items[i].id = tmp_int[0];
+ p->items[i].nameid = tmp_int[1];
+ p->items[i].amount = tmp_int[2];
+ p->items[i].equip = tmp_int[3];
+ p->items[i].identify = tmp_int[4];
+ p->items[i].refine = tmp_int[5];
+ p->items[i].attribute = tmp_int[6];
- for(j = 0; j < MAX_SLOTS && tmp_str && sscanf(tmp_str, ",%d%[0-9,-]",&tmp_int[0], tmp_str) > 0; j++)
- p->items[i].card[j] = tmp_int[0];
+ for(j = 0; j < MAX_SLOTS && tmp_str && sscanf(tmp_str, ",%d%[0-9,-]",&tmp_int[0], tmp_str) > 0; j++)
+ p->items[i].card[j] = tmp_int[0];
- next += len;
- if (str[next] == ' ')
- next++;
- }
- else return 1;
+ next += len;
+ if (str[next] == ' ')
+ next++;
}
- if (i >= MAX_STORAGE && str[next] && str[next]!='\t')
+
+ if( i >= MAX_STORAGE && str[next] && str[next] != '\t' )
ShowWarning("storage_fromstr: Found a storage line with more items than MAX_STORAGE (%d), remaining items have been discarded!\n", MAX_STORAGE);
- return 0;
+
+ return true;
}
-#ifndef TXT_SQL_CONVERT
int guild_storage_tostr(char *str,struct guild_storage *p)
{
int i,j,f=0;
@@ -123,7 +118,6 @@ int guild_storage_tostr(char *str,struct guild_storage *p)
str[0]=0;
return 0;
}
-#endif //TXT_SQL_CONVERT
int guild_storage_fromstr(char *str,struct guild_storage *p)
{
@@ -165,43 +159,50 @@ int guild_storage_fromstr(char *str,struct guild_storage *p)
}
#ifndef TXT_SQL_CONVERT
-// アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
-struct storage_data *account2storage(int account_id)
+
+static void* create_storage(DBKey key, va_list args)
{
- return (struct storage_data*)idb_get(storage_db, account_id);
+ return (struct storage_data *) aCalloc(sizeof(struct storage_data), 1);
}
-static void* create_guildstorage(DBKey key, va_list args) {
+static void* create_guildstorage(DBKey key, va_list args)
+{
struct guild_storage* gs = NULL;
gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1);
gs->guild_id=key.i;
return gs;
}
-struct guild_storage *guild2storage(int guild_id)
-{
- struct guild_storage* gs = NULL;
- if(inter_guild_search(guild_id) != NULL)
- gs = (struct guild_storage*)idb_ensure(guild_storage_db, guild_id, create_guildstorage);
- return gs;
-}
-
-// loads storage data into the provided data structure
+/// Loads storage data into the provided data structure.
+/// If data doesn't exist, the destination is zeroed and false is returned.
bool storage_load(int account_id, struct storage_data* storage)
{
- struct storage_data* s = account2storage(account_id);
+ struct storage_data* s = (struct storage_data*)idb_get(storage_db, account_id);
+
if( s != NULL )
- memcpy(storage, s, sizeof(struct storage_data));
+ memcpy(storage, s, sizeof(*storage));
+ else
+ memset(storage, 0x00, sizeof(*storage));
+
return( s != NULL );
}
-// writes provided data into storage cache
+/// Writes provided data into storage cache.
+/// If data contains 0 items, any existing entry in cache is destroyed.
+/// If data contains 1+ items and no cache entry exists, a new one is created.
bool storage_save(int account_id, struct storage_data* storage)
{
- struct storage_data* s = account2storage(account_id);
- if( s != NULL )
- memcpy(s, storage, sizeof(struct storage_data));
- return( s != NULL );
+ if( storage->storage_amount > 0 )
+ {
+ struct storage_data* s = (struct storage_data*)idb_ensure(storage_db, account_id, create_storage);
+ memcpy(s, storage, sizeof(*storage));
+ }
+ else
+ {
+ idb_remove(storage_db, account_id);
+ }
+
+ return true;
}
//---------------------------------------------------------
@@ -209,9 +210,7 @@ bool storage_save(int account_id, struct storage_data* storage)
int inter_storage_init()
{
char line[65536];
- int c=0,tmp_int;
- struct storage_data *s;
- struct guild_storage *gs;
+ int c = 0;
FILE *fp;
storage_db = idb_alloc(DB_OPT_RELEASE_DATA);
@@ -221,20 +220,24 @@ int inter_storage_init()
ShowError("can't read : %s\n",storage_txt);
return 1;
}
- while(fgets(line, sizeof(line), fp))
+ while( fgets(line, sizeof(line), fp) )
{
- sscanf(line,"%d",&tmp_int);
+ int account_id;
+ struct storage_data *s;
+
s = (struct storage_data*)aCalloc(sizeof(struct storage_data), 1);
- if(s==NULL){
+ if( s == NULL )
+ {
ShowFatalError("int_storage: out of memory!\n");
exit(EXIT_FAILURE);
}
- s->account_id=tmp_int;
- if(s->account_id > 0 && storage_fromstr(line,s) == 0) {
- idb_put(storage_db,s->account_id,s);
+
+ if( storage_fromstr(line,&account_id,s) )
+ {
+ idb_put(storage_db,account_id,s);
}
else{
- ShowError("int_storage: broken data [%s] line %d\n",storage_txt,c);
+ ShowError("int_storage: broken data in [%s] line %d\n",storage_txt,c);
aFree(s);
}
c++;
@@ -251,6 +254,9 @@ int inter_storage_init()
}
while(fgets(line, sizeof(line), fp))
{
+ int tmp_int;
+ struct guild_storage *gs;
+
sscanf(line,"%d",&tmp_int);
gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
if(gs==NULL){
@@ -284,6 +290,7 @@ void inter_storage_final() {
int inter_storage_save()
{
struct DBIterator* iter;
+ DBKey key;
struct storage_data* data;
FILE *fp;
int lock;
@@ -293,12 +300,12 @@ int inter_storage_save()
}
iter = storage_db->iterator(storage_db);
- for( data = (struct storage_data*)iter->first(iter,NULL); iter->exists(iter); data = (struct storage_data*)iter->next(iter,NULL) )
+ for( data = (struct storage_data*)iter->first(iter,&key); iter->exists(iter); data = (struct storage_data*)iter->next(iter,&key) )
{
+ int account_id = key.i;
char line[65536];
- storage_tostr(line,data);
- if(*line)
- fprintf(fp,"%s\n",line);
+ storage_tostr(line,account_id,data);
+ fprintf(fp,"%s\n",line);
}
iter->destroy(iter);
@@ -366,6 +373,14 @@ int inter_guild_storage_delete(int guild_id)
return 0;
}
+struct guild_storage *guild2storage(int guild_id)
+{
+ struct guild_storage* gs = NULL;
+ if(inter_guild_search(guild_id) != NULL)
+ gs = (struct guild_storage*)idb_ensure(guild_storage_db, guild_id, create_guildstorage);
+ return gs;
+}
+
//---------------------------------------------------------
// map serverへの通信