Pārlūkot izejas kodu

- Char-SQL: Removed the ridiculous check for existing party/guild each time a character is saved. The check should be done upon loading (when the guild/party is not found, the char's party/guild id is set to 0 THERE)
- Removed the 'Quick loaded char' messages from the char-sql server
- Some cleaning of the guild sql saving routine.
- Various checks around the char-SQL server and a few memory leak fixes.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5309 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 19 gadi atpakaļ
vecāks
revīzija
d57406c09e

+ 5 - 0
Changelog-Trunk.txt

@@ -5,6 +5,11 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.  EV
 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
 
 2006/02/17
+	* Char-SQL server updates: [Skotlex]
+	- Removed the unnecessary party/guild check on each char-save.
+	- Removed the 'quick loaded char' messages.
+	- Some code cleanup.
+	- Fixed one or two memory leaks.
 	* Applied the suggested fixes by Joshuaali to fix the compiling of the sql
 	  map server on Win32 systems. [Skotlex]
 	- note that irc.c is still uncompilable, but the rest "should be fine" now.

+ 21 - 53
src/char_sql/char.c

@@ -348,7 +348,7 @@ static void* create_charstatus(DBKey key, va_list args) {
 }
 
 int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
-	int i=0,j,party_exist,guild_exist;
+	int i=0,j;
 	int count = 0;
 	int diff = 0;
 	char *tmp_ptr; //Building a single query should be more efficient than running
@@ -430,38 +430,6 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
 		(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom)
 	)
 	{	//Save status
-		//Check for party
-		party_exist=1;
-		sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `party_id` = '%d'",party_db, p->party_id); // TBR
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		} else { //In case of failure, don't touch the data. [Skotlex
-			sql_res = mysql_store_result(&mysql_handle);
-			sql_row = sql_res?mysql_fetch_row(sql_res):NULL;
-			if (sql_row)
-				party_exist = atoi(sql_row[0]);
-			mysql_free_result(sql_res);
-		}
-
-		//check guild_exist
-		guild_exist=1;
-		sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id` = '%d'",guild_db, p->guild_id); // TBR
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		} else { //If we fail to confirm, don't touch the data.
-			sql_res = mysql_store_result(&mysql_handle);
-			sql_row = sql_res?mysql_fetch_row(sql_res):NULL;
-			if (sql_row)
-				guild_exist = atoi(sql_row[0]);
-			mysql_free_result(sql_res);
-		}
-		
-		if (guild_exist==0) p->guild_id=0;
-		if (party_exist==0) p->party_id=0;
-
-		//query
 		sprintf(tmp_sql ,"UPDATE `%s` SET `base_level`='%d', `job_level`='%d',"
 			"`base_exp`='%u', `job_exp`='%u', `zeny`='%d',"
 			"`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d',"
@@ -953,18 +921,13 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p){
 		p->partner_id = atoi(sql_row[20]); p->father = atoi(sql_row[21]); p->mother = atoi(sql_row[22]); p->child = atoi(sql_row[23]);
 		p->fame = atoi(sql_row[24]);
 
-		//free mysql result.
-		mysql_free_result(sql_res);
 		strcat (t_msg, " status2");
 	} else
 		ShowError("Char load failed (%d - table %s)\n", char_id, char_db);	//Error?! ERRRRRR WHAT THAT SAY!?
-/* We shouldn't need this at all! [Skotlex]
-	if (p->last_point.x == 0 || p->last_point.y == 0 || p->last_point.map == 0)
-		memcpy(&p->last_point, &start_point, sizeof(start_point));
+	//free mysql result.
+	if (sql_res)
+		mysql_free_result(sql_res);
 
-	if (p->save_point.x == 0 || p->save_point.y == 0 || p->save_point.map == 0)
-		memcpy(&p->save_point, &start_point, sizeof(start_point));
-*/
 	//read memo data
 	//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
 	sprintf(tmp_sql, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`='%d' ORDER by `memo_id`",memo_db, char_id); // TBR
@@ -1032,7 +995,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p){
 	sql_res = mysql_store_result(&mysql_handle);
 	if (sql_res) {
 		for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
-		        p->cart[i].id = atoi(sql_row[0]);
+			p->cart[i].id = atoi(sql_row[0]);
 			p->cart[i].nameid = atoi(sql_row[1]);
 			p->cart[i].amount = atoi(sql_row[2]);
 			p->cart[i].equip = atoi(sql_row[3]);
@@ -1150,6 +1113,7 @@ int mmo_char_fromsql_short(int char_id, struct mmo_charstatus *p){
 		if (!sql_row)
 		{	//Just how does this happens? [Skotlex]
 			ShowError("Requested non-existant character id: %d!\n", char_id);
+		   mysql_free_result(sql_res); 
 			return 0;	
 		}
 		p->char_id = char_id;
@@ -1199,14 +1163,14 @@ int mmo_char_fromsql_short(int char_id, struct mmo_charstatus *p){
 		p->weapon = atoi(sql_row[6]);	p->shield = atoi(sql_row[7]);
 		p->head_top = atoi(sql_row[8]);	p->head_mid = atoi(sql_row[9]);	p->head_bottom = atoi(sql_row[10]);
 
-		//free mysql result.
-		mysql_free_result(sql_res);
 		strcat (t_msg, " status2");
 	} else
 		ShowError("Char load failed (%d - table %s)\n", char_id, char_db);	//Error?! ERRRRRR WHAT THAT SAY!?
-
-	if (save_log)
-		ShowInfo("Quick Loaded char (%d - %s): %s\n", char_id, p->name, t_msg);	//ok. all data load successfuly!
+	//free mysql result.
+	if (sql_res)
+		mysql_free_result(sql_res);
+//	if (save_log) //Too much spam :/
+//		ShowInfo("Quick Loaded char (%d - %s): %s\n", char_id, p->name, t_msg);	//ok. all data load successfuly!
 
 	return 1;
 }
@@ -1474,6 +1438,8 @@ int delete_char_sql(int char_id, int partner_id)
 	if (sql_res == NULL || sql_row == NULL)
 	{
 		ShowError("delete_char_sql: Unable to fetch character data, deletion aborted.\n");
+		if (sql_res)
+			mysql_free_result(sql_res);
 		return -1;
 	}
 	strncpy(char_name, sql_row[0], NAME_LENGTH);
@@ -1698,7 +1664,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
 	WFIFOW(fd, 2) = offset + found_num * 106;
 
 	if (save_log)
-		ShowInfo("Request Char Data ("CL_BOLD"%d"CL_RESET"):\n",sd->account_id);
+		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
 
 	for(i = 0; i < found_num; i++) {
 		mmo_char_fromsql_short(sd->found_char[i], char_dat);
@@ -1927,7 +1893,7 @@ int parse_tologin(int fd) {
 		  {
 			int acc, sex;
 			unsigned char buf[16];
-			MYSQL_RES* sql_res2; //Needed because it is used inside inter_guild_CharOffline; [Skotlex]
+			MYSQL_RES* sql_res2;
 			acc = RFIFOL(fd,2);
 			sex = RFIFOB(fd,6);
 			RFIFOSKIP(fd, 7);
@@ -2760,8 +2726,8 @@ int parse_frommap(int fd) {
 					if (++num == 10)
 						break;
 				}
+   			mysql_free_result(sql_res);
 			}
-   		mysql_free_result(sql_res);
 			WBUFW(buf, 6) = len; //Blacksmith block size
 
 			num = 0;
@@ -2781,8 +2747,8 @@ int parse_frommap(int fd) {
 					if (++num == 10)
 						break;
 				}
+				mysql_free_result(sql_res);
 			}
-			mysql_free_result(sql_res);
 			WBUFW(buf, 4) = len; //Alchemist block size
 
 			num = 0;
@@ -2802,8 +2768,8 @@ int parse_frommap(int fd) {
 					if (++num == 10)
 						break;
 				}
+				mysql_free_result(sql_res);
 			}
-			mysql_free_result(sql_res);
 			WBUFW(buf, 2) = len; //Total packet length
 
 			mapif_sendall(buf, len);
@@ -3080,7 +3046,9 @@ int parse_char(int fd) {
 			
 			if (sql_row)
 			{
-				mmo_char_fromsql(atoi(sql_row[0]), char_dat);
+				int char_id = atoi(sql_row[0]);
+				mysql_free_result(sql_res); //Free'd as soon as possible
+				mmo_char_fromsql(char_id, char_dat);
 				char_dat[0].sex = sd->sex;
 			} else {
 				mysql_free_result(sql_res);

+ 12 - 16
src/char_sql/int_guild.c

@@ -381,8 +381,7 @@ struct guild * inter_guild_fromsql(int guild_id)
 		return NULL;
 	}
 	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		int i;
+	if (sql_res) {
 		for(i=0;((sql_row = mysql_fetch_row(sql_res))&&i<g->max_member);i++){
 			struct guild_member *m = &g->member[i];
 			m->account_id=atoi(sql_row[1]);
@@ -402,8 +401,8 @@ struct guild * inter_guild_fromsql(int guild_id)
 
 			strncpy(m->name,sql_row[14],NAME_LENGTH-1);
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 
 	//printf("- Read guild_position %d from sql \n",guild_id);
 	sprintf(tmp_sql,"SELECT `guild_id`,`position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'",guild_position_db, guild_id);
@@ -415,8 +414,7 @@ struct guild * inter_guild_fromsql(int guild_id)
 		return NULL;
 	}
 	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		int i;
+	if (sql_res) {
 		for(i=0;((sql_row = mysql_fetch_row(sql_res))&&i<MAX_GUILDPOSITION);i++){
 			int position = atoi(sql_row[1]);
 			struct guild_position *p = &g->position[position];
@@ -424,8 +422,8 @@ struct guild * inter_guild_fromsql(int guild_id)
 			p->mode=atoi(sql_row[3]);
 			p->exp_mode=atoi(sql_row[4]);
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 
 	//printf("- Read guild_alliance %d from sql \n",guild_id);
 	sprintf(tmp_sql,"SELECT `guild_id`,`opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'",guild_alliance_db, guild_id);
@@ -436,16 +434,15 @@ struct guild * inter_guild_fromsql(int guild_id)
 		return NULL;
 	}
 	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		int i;
+	if (sql_res) {
 		for(i=0;((sql_row = mysql_fetch_row(sql_res))&&i<MAX_GUILDALLIANCE);i++){
 			struct guild_alliance *a = &g->alliance[i];
 			a->opposition=atoi(sql_row[1]);
 			a->guild_id=atoi(sql_row[2]);
 			strncpy(a->name,sql_row[3],NAME_LENGTH-1);
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 
 	//printf("- Read guild_expulsion %d from sql \n",guild_id);
 	sprintf(tmp_sql,"SELECT `guild_id`,`name`,`mes`,`acc`,`account_id`,`rsv1`,`rsv2`,`rsv3` FROM `%s` WHERE `guild_id`='%d'",guild_expulsion_db, guild_id);
@@ -456,8 +453,7 @@ struct guild * inter_guild_fromsql(int guild_id)
 		return NULL;
 	}
 	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		int i;
+	if (sql_res) {
 		for(i=0;((sql_row = mysql_fetch_row(sql_res))&&i<MAX_GUILDEXPLUSION);i++){
 			struct guild_explusion *e = &g->explusion[i];
 
@@ -470,8 +466,8 @@ struct guild * inter_guild_fromsql(int guild_id)
 			e->rsv2=atoi(sql_row[6]);
 			e->rsv3=atoi(sql_row[7]);
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 
 	//printf("- Read guild_skill %d from sql \n",guild_id);
 	sprintf(tmp_sql,"SELECT `guild_id`,`id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`",guild_skill_db, guild_id);
@@ -488,15 +484,15 @@ struct guild * inter_guild_fromsql(int guild_id)
 	}
 
 	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
+	if (sql_res) {
 		while ((sql_row = mysql_fetch_row(sql_res))){
 			int id = atoi(sql_row[1])-GD_SKILLBASE;
 			if (id >= 0 && id < MAX_GUILDSKILL)
 			//I know this seems ridiculous, but the skills HAVE to be placed on their 'correct' array slot or things break x.x [Skotlex]
 				g->skill[id].lv=atoi(sql_row[2]);
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 
 	idb_put(guild_db_, guild_id, g); //Add to cache
 	g->save_flag |= GS_REMOVE; //But set it to be removed, in case it is not needed for long.
@@ -1129,7 +1125,7 @@ int mapif_guild_castle_alldataload(int fd) {
 		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
 	}
 	sql_res = mysql_store_result(&mysql_handle);
-	if (sql_res != NULL && mysql_num_rows(sql_res) > 0) {
+	if (sql_res) {
 		for(i = 0; ((sql_row = mysql_fetch_row(sql_res)) && i < MAX_GUILDCASTLE); i++) {
 			memset(gc, 0, sizeof(struct guild_castle));
 			gc->castle_id = atoi(sql_row[0]);
@@ -1161,8 +1157,8 @@ int mapif_guild_castle_alldataload(int fd) {
 			memcpy(WFIFOP(fd,len), gc, sizeof(struct guild_castle));
 			len += sizeof(struct guild_castle);
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 	WFIFOW(fd,2) = len;
 	WFIFOSET(fd,len);
 	

+ 12 - 11
src/char_sql/int_party.c

@@ -170,18 +170,19 @@ struct party *inter_party_fromsql(int party_id)
 	}
 
 	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res != NULL && mysql_num_rows(sql_res) > 0) {
-		sql_row = mysql_fetch_row(sql_res);
-		p->party_id = party_id;
-		memcpy(p->name, sql_row[1], NAME_LENGTH-1);
-		p->exp = atoi(sql_row[2])?1:0;
-		p->item = atoi(sql_row[3]);
-		leader_id = atoi(sql_row[4]);
-		leader_char = atoi(sql_row[5]);
-	} else {
+	if (!sql_res)
+		return NULL;
+	sql_row = mysql_fetch_row(sql_res);
+	if (!sql_row) {
 		mysql_free_result(sql_res);
 		return NULL;
 	}
+	p->party_id = party_id;
+	memcpy(p->name, sql_row[1], NAME_LENGTH-1);
+	p->exp = atoi(sql_row[2])?1:0;
+	p->item = atoi(sql_row[3]);
+	leader_id = atoi(sql_row[4]);
+	leader_char = atoi(sql_row[5]);
 	mysql_free_result(sql_res);
 
 	// Load members
@@ -193,7 +194,7 @@ struct party *inter_party_fromsql(int party_id)
 		return NULL;
 	}
 	sql_res = mysql_store_result(&mysql_handle);
-	if (sql_res != NULL && mysql_num_rows(sql_res) > 0) {
+	if (sql_res) {
 		int i;
 		for (i = 0; (sql_row = mysql_fetch_row(sql_res)); i++) {
 			struct party_member *m = &p->member[i];
@@ -205,8 +206,8 @@ struct party *inter_party_fromsql(int party_id)
 			m->map = mapindex_name2id(sql_row[4]);
 			m->online = atoi(sql_row[5])?1:0;
 		}
+		mysql_free_result(sql_res);
 	}
-	mysql_free_result(sql_res);
 
 	if (save_log)
 		ShowInfo("Party loaded (%d - %s).\n",party_id, p->name);

+ 6 - 6
src/char_sql/int_storage.c

@@ -80,7 +80,7 @@ int storage_fromsql(int account_id, struct storage *p){
 	sql_res = mysql_store_result(&mysql_handle) ;
 
 	if (sql_res) {
-		while((sql_row = mysql_fetch_row(sql_res))) {	//start to fetch
+		while((sql_row = mysql_fetch_row(sql_res)) && i<MAX_STORAGE) {	//start to fetch
 			p->storage_[i].id= atoi(sql_row[0]);
 			p->storage_[i].nameid= atoi(sql_row[1]);
 			p->storage_[i].amount= atoi(sql_row[2]);
@@ -90,8 +90,9 @@ int storage_fromsql(int account_id, struct storage *p){
 			p->storage_[i].attribute= atoi(sql_row[6]);
 			for (j=0; j<MAX_SLOTS; j++)
 				p->storage_[i].card[j]= atoi(sql_row[7+j]);
-			p->storage_amount = ++i;
+			i++;
 		}
+		p->storage_amount = i;
 		mysql_free_result(sql_res);
 	}
 
@@ -154,7 +155,7 @@ int guild_storage_fromsql(int guild_id, struct guild_storage *p){
 	sql_res = mysql_store_result(&mysql_handle) ;
 
 	if (sql_res) {
-		while((sql_row = mysql_fetch_row(sql_res))) {	//start to fetch
+		while((sql_row = mysql_fetch_row(sql_res)) && i < MAX_GUILD_STORAGE) {	//start to fetch
 			p->storage_[i].id= atoi(sql_row[0]);
 			p->storage_[i].nameid= atoi(sql_row[1]);
 			p->storage_[i].amount= atoi(sql_row[2]);
@@ -164,10 +165,9 @@ int guild_storage_fromsql(int guild_id, struct guild_storage *p){
 			p->storage_[i].attribute= atoi(sql_row[6]);
 			for (j=0; j<MAX_SLOTS; j++)
 				p->storage_[i].card[j] = atoi(sql_row[7+j]);
-			p->storage_amount = ++i;
-			if (i >= MAX_GUILD_STORAGE)
-				break;
+			i++;
 		}
+		p->storage_amount = i;
 		mysql_free_result(sql_res);
 	}
 	ShowInfo ("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount);