diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-08-19 16:00:30 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-08-19 16:00:30 +0000 |
commit | 83bbf93278328b5530ce7f0d6d5a5160148e3e1e (patch) | |
tree | 3989709252e556de2fda83d617d56d589d8f13b1 /src/char/int_storage.c | |
parent | 73c06082f78f6ba79e40bf66c531d5ff99082fee (diff) | |
download | hercules-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.c | 161 |
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への通信 |