Browse Source

* 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

ultramage 16 years ago
parent
commit
e3d39453fd

+ 4 - 0
Changelog-Trunk.txt

@@ -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.

+ 88 - 73
src/char/int_storage.c

@@ -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++)
-		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",
 			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);
-	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++;
 	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) {
-			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);
 		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)
-{
-	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)
 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( 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()
 int inter_storage_init()
 {
 {
 	char line[65536];
 	char line[65536];
-	int c=0,tmp_int;
-	struct storage_data *s;
-	struct guild_storage *gs;
+	int c = 0;
 	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) {
-			idb_put(storage_db,s->account_id,s);
+
+		if( storage_fromstr(line,&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);
- 		if(*line)
- 			fprintf(fp,"%s\n",line);
+		storage_tostr(line,account_id,data);
+		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への通信
 
 

+ 1 - 1
src/char/int_storage.h

@@ -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);

+ 0 - 1
src/char_sql/int_storage.c

@@ -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);

+ 0 - 1
src/common/mmo.h

@@ -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];
 };
 };

+ 13 - 12
src/txt-converter/char-converter.c

@@ -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(set==2) {
-				memset(&storage, 0, sizeof(struct storage_data));
-				storage.account_id = tmp_int[0];
-				if (storage_fromstr(line,&storage) == 0) {
-					count++;
-					storage_tosql(storage.account_id,&storage); //to sql. (dump)
-				} else {
-					ShowError("Error parsing storage line [%s] (at %s:%d)\n", line, storage_txt, lineno);
-				}
-			}
+			if( sscanf(line,"%d,%d",&tmp_int[0],&tmp_int[1]) != 2 )
+				continue;
+
+			memset(&storage, 0, sizeof(struct storage_data));
+			if( storage_fromstr(line,&account_id,&storage) )
+			{
+				count++;
+				storage_tosql(account_id,&storage); //to sql. (dump)
+			} 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);