* 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://svn.code.sf.net/p/rathena/svn/trunk@13093 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
ultramage 2008-08-19 16:00:30 +00:00
parent 442204b547
commit e3d39453fd
6 changed files with 106 additions and 88 deletions

View File

@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2008/08/19 2008/08/19
* Fixed a storage saving issue with txt charserver (bugreport:2084) [ultramage]
- 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
* Added global sql settings 'sql.*' to inter_athena.conf. * Added global sql settings 'sql.*' to inter_athena.conf.
* Made account, ipban and loginlog use the global sql settings when the hostname is empty. * Made account, ipban and loginlog use the global sql settings when the hostname is empty.
* Commented 'ipban.sql.*' and 'account.sql.*' so they default to the global settings. * Commented 'ipban.sql.*' and 'account.sql.*' so they default to the global settings.

View File

@ -23,19 +23,18 @@
char storage_txt[1024]="save/storage.txt"; char storage_txt[1024]="save/storage.txt";
char guild_storage_txt[1024]="save/g_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* storage_db; // int account_id -> struct storage_data*
static DBMap* guild_storage_db; // int guild_id -> struct guild_storage* 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; 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++) for( i = 0; i < MAX_STORAGE; i++ )
if( (p->items[i].nameid) && (p->items[i].amount) ) if( p->items[i].nameid > 0 && p->items[i].amount > 0 )
{ {
str_p += sprintf(str_p, "%d,%d,%d,%d,%d,%d,%d", 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, 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++) for(j=0; j<MAX_SLOTS; j++)
str_p += sprintf(str_p,",%d",p->items[i].card[j]); str_p += sprintf(str_p,",%d",p->items[i].card[j]);
str_p += sprintf(str_p," "); str_p += sprintf(str_p," ");
f++;
} }
*(str_p++)='\t'; *(str_p++)='\t';
*str_p='\0'; *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]; int tmp_int[256];
char tmp_str[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); if( sscanf(str, "%d,%d%n", &tmp_int[0], &tmp_int[1], &next) != 2 )
p->storage_amount=tmp_int[1]; 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++; 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", 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[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6], tmp_str, &len) == 8) { &tmp_int[4], &tmp_int[5], &tmp_int[6], tmp_str, &len) != 8)
p->items[i].id = tmp_int[0]; return false;
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].id = tmp_int[0];
p->items[i].card[j] = 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];
next += len; for(j = 0; j < MAX_SLOTS && tmp_str && sscanf(tmp_str, ",%d%[0-9,-]",&tmp_int[0], tmp_str) > 0; j++)
if (str[next] == ' ') p->items[i].card[j] = tmp_int[0];
next++;
} next += len;
else return 1; 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); 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 guild_storage_tostr(char *str,struct guild_storage *p)
{ {
int i,j,f=0; int i,j,f=0;
@ -123,7 +118,6 @@ int guild_storage_tostr(char *str,struct guild_storage *p)
str[0]=0; str[0]=0;
return 0; return 0;
} }
#endif //TXT_SQL_CONVERT
int guild_storage_fromstr(char *str,struct guild_storage *p) 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 #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; struct guild_storage* gs = NULL;
gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1); gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1);
gs->guild_id=key.i; gs->guild_id=key.i;
return gs; return gs;
} }
struct guild_storage *guild2storage(int guild_id) /// Loads storage data into the provided data structure.
{ /// If data doesn't exist, the destination is zeroed and false is returned.
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
bool storage_load(int account_id, struct storage_data* storage) 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 ) if( s != NULL )
memcpy(storage, s, sizeof(struct storage_data)); memcpy(storage, s, sizeof(*storage));
else
memset(storage, 0x00, sizeof(*storage));
return( s != NULL ); 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) bool storage_save(int account_id, struct storage_data* storage)
{ {
struct storage_data* s = account2storage(account_id); if( storage->storage_amount > 0 )
if( s != NULL ) {
memcpy(s, storage, sizeof(struct storage_data)); struct storage_data* s = (struct storage_data*)idb_ensure(storage_db, account_id, create_storage);
return( s != NULL ); 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() int inter_storage_init()
{ {
char line[65536]; char line[65536];
int c=0,tmp_int; int c = 0;
struct storage_data *s;
struct guild_storage *gs;
FILE *fp; FILE *fp;
storage_db = idb_alloc(DB_OPT_RELEASE_DATA); storage_db = idb_alloc(DB_OPT_RELEASE_DATA);
@ -221,20 +220,24 @@ int inter_storage_init()
ShowError("can't read : %s\n",storage_txt); ShowError("can't read : %s\n",storage_txt);
return 1; 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); s = (struct storage_data*)aCalloc(sizeof(struct storage_data), 1);
if(s==NULL){ if( s == NULL )
{
ShowFatalError("int_storage: out of memory!\n"); ShowFatalError("int_storage: out of memory!\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
s->account_id=tmp_int;
if(s->account_id > 0 && storage_fromstr(line,s) == 0) { if( storage_fromstr(line,&account_id,s) )
idb_put(storage_db,s->account_id,s); {
idb_put(storage_db,account_id,s);
} }
else{ 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); aFree(s);
} }
c++; c++;
@ -251,6 +254,9 @@ int inter_storage_init()
} }
while(fgets(line, sizeof(line), fp)) while(fgets(line, sizeof(line), fp))
{ {
int tmp_int;
struct guild_storage *gs;
sscanf(line,"%d",&tmp_int); sscanf(line,"%d",&tmp_int);
gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1); gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
if(gs==NULL){ if(gs==NULL){
@ -284,6 +290,7 @@ void inter_storage_final() {
int inter_storage_save() int inter_storage_save()
{ {
struct DBIterator* iter; struct DBIterator* iter;
DBKey key;
struct storage_data* data; struct storage_data* data;
FILE *fp; FILE *fp;
int lock; int lock;
@ -293,12 +300,12 @@ int inter_storage_save()
} }
iter = storage_db->iterator(storage_db); 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]; char line[65536];
storage_tostr(line,data); storage_tostr(line,account_id,data);
if(*line) fprintf(fp,"%s\n",line);
fprintf(fp,"%s\n",line);
} }
iter->destroy(iter); iter->destroy(iter);
@ -366,6 +373,14 @@ int inter_guild_storage_delete(int guild_id)
return 0; 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への通信 // map serverへの通信

View File

@ -19,7 +19,7 @@ extern char storage_txt[1024];
extern char guild_storage_txt[1024]; extern char guild_storage_txt[1024];
//Exported for use in the TXT-SQL converter. //Exported for use in the TXT-SQL converter.
int storage_fromstr(char *str,struct storage_data *p); bool storage_fromstr(char* str, int* account_id, struct storage_data* p);
int guild_storage_fromstr(char *str,struct guild_storage *p); int guild_storage_fromstr(char *str,struct guild_storage *p);
bool storage_load(int account_id, struct storage_data* storage); bool storage_load(int account_id, struct storage_data* storage);

View File

@ -36,7 +36,6 @@ int storage_fromsql(int account_id, struct storage_data* p)
memset(p, 0, sizeof(struct storage_data)); //clean up memory memset(p, 0, sizeof(struct storage_data)); //clean up memory
p->storage_amount = 0; p->storage_amount = 0;
p->account_id = account_id;
// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
StringBuf_Init(&buf); StringBuf_Init(&buf);

View File

@ -184,7 +184,6 @@ struct status_change_data {
}; };
struct storage_data { struct storage_data {
int account_id; // used by charserver
int storage_amount; int storage_amount;
struct item items[MAX_STORAGE]; struct item items[MAX_STORAGE];
}; };

View File

@ -36,7 +36,7 @@ int convert_init(void)
{ {
char line[65536]; char line[65536];
int ret; int ret;
int set,tmp_int[2], lineno, count; int tmp_int[2], lineno, count;
char input; char input;
FILE *fp; FILE *fp;
@ -118,18 +118,19 @@ int convert_init(void)
lineno = count = 0; lineno = count = 0;
while(fgets(line, sizeof(line), fp)) while(fgets(line, sizeof(line), fp))
{ {
int account_id;
lineno++; lineno++;
set=sscanf(line,"%d,%d",&tmp_int[0],&tmp_int[1]); if( sscanf(line,"%d,%d",&tmp_int[0],&tmp_int[1]) != 2 )
if(set==2) { continue;
memset(&storage, 0, sizeof(struct storage_data));
storage.account_id = tmp_int[0]; memset(&storage, 0, sizeof(struct storage_data));
if (storage_fromstr(line,&storage) == 0) { if( storage_fromstr(line,&account_id,&storage) )
count++; {
storage_tosql(storage.account_id,&storage); //to sql. (dump) count++;
} else { storage_tosql(account_id,&storage); //to sql. (dump)
ShowError("Error parsing storage line [%s] (at %s:%d)\n", line, storage_txt, lineno); } else
} ShowError("Error parsing storage line [%s] (at %s:%d)\n", line, storage_txt, lineno);
}
} }
ShowStatus("Converted %d storages.\n", count); ShowStatus("Converted %d storages.\n", count);
fclose(fp); fclose(fp);