소스 검색

Removed ugly struct cast in login.c
New version of buildin_query_sql which accept more than one column and can return the number of rows. See script_commands.txt for more details.

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

toms 19 년 전
부모
커밋
e61a6fb306
4개의 변경된 파일70개의 추가작업 그리고 36개의 파일을 삭제
  1. 3 0
      Changelog-Trunk.txt
  2. 8 9
      doc/script_commands.txt
  3. 4 6
      src/login_sql/login.c
  4. 55 21
      src/map/script.c

+ 3 - 0
Changelog-Trunk.txt

@@ -4,6 +4,9 @@ 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.
 
 2006/07/29
+	* Removed ugly struct cast in login.c [Toms]
+	* New version of buildin_query_sql which accept more than one column and
+	  can return the number of rows. See script_commands.txt for more details. [Toms]
 	* Fixed nullpo in merc_hom_skillup [Toms]
 	* Added a return value to buildin_rid2name if rid is invalid [Toms]
 	* Made the SQL ping interval default to 7 hours. [Skotlex]

+ 8 - 9
doc/script_commands.txt

@@ -4950,18 +4950,17 @@ Example:
 set @i, distance(100,200,101,202);
 
 ---------------------------------------
-*query_sql "your MySQL query", <array name>
-Returns up to 127 values into array.
+*query_sql "your MySQL query", <array name>, [<array name>]
+Returns up to 127 values into array and return the number of row
 
 Example:
-
-query_sql "SELECT name FROM 'char' ORDER BY fame DESC LIMIT 5", @most_fame_dude$;
+set @nb, query_sql("select name,fame from `char` ORDER BY fame DESC LIMIT 5", @name$, @fame);
 mes "Hall Of Fame: TOP5";
-mes "1."+@most_fame_dude$[0]; // Will return a person with the biggest fame value.
-mes "2."+@most_fame_dude$[1];
-mes "3."+@most_fame_dude$[2];
-mes "4."+@most_fame_dude$[3];
-mes "5."+@most_fame_dude$[4];
+mes "1."+@name$[0]+"("+@fame[0]+")"; // Will return a person with the biggest fame value.
+mes "2."+@name$[1]+"("+@fame[1]+")";
+mes "3."+@name$[2]+"("+@fame[2]+")";
+mes "4."+@name$[3]+"("+@fame[3]+")";
+mes "5."+@name$[4]+"("+@fame[4]+")";
 
 Note: It is available in SQL version only.
 Note: Use Text$[] array to recieve all data as text.

+ 4 - 6
src/login_sql/login.c

@@ -578,7 +578,7 @@ int mmo_auth( struct mmo_account* account , int fd){
 
 	char ip[16];
 
-	unsigned char *sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr;
+	unsigned char * sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr.s_addr;
 
 	char r_ip[16]; // [Zido]
 	char ip_dnsbl[256]; // [Zido]
@@ -905,7 +905,7 @@ int parse_fromchar(int fd){
 	MYSQL_RES* sql_res;
 	MYSQL_ROW  sql_row = NULL;
 
-	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
 	char ip[16];
 
 	sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
@@ -1508,10 +1508,8 @@ int parse_login(int fd) {
 	int packet_len;
 
 	int result, i;
-	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
-	//Since we can't cast a structure to a long, we take the base address as
-	//a pointer and cast it (somehow... this seems so wrong to do)
-	unsigned long ipl = *((unsigned long *) &session[fd]->client_addr.sin_addr); 
+	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
+	unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
 	char ip[16];
 
 	sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);

+ 55 - 21
src/map/script.c

@@ -11186,41 +11186,75 @@ int buildin_setd(struct script_state *st)
 
 #ifndef TXT_ONLY
 int buildin_query_sql(struct script_state *st) {
-	char *name, *query;
-	int num, i = 0;
+	char *name = NULL, *query;
+	int num, i = 0,j, nb_rows;
+	struct { char * dst_var_name; char type; } row[32];
 	struct map_session_data *sd = (st->rid)? script_rid2sd(st) : NULL;
 
 	query = conv_str(st,& (st->stack->stack_data[st->start+2]));
-    strcpy(tmp_sql, query);
+	strcpy(tmp_sql, query);
 	if(mysql_query(&mmysql_handle,tmp_sql)){
 		ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
 		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+		push_val(st->stack,C_INT,0);
 		return 1;
 	}
 
-	if(st->end > st->start+3) {
-		if(st->stack->stack_data[st->start+3].type != C_NAME){
-			ShowWarning("buildin_query_sql: 2nd parameter is not a variable!\n");
-		} else {
-			num=st->stack->stack_data[st->start+3].u.num;
-			name=(char *)(str_buf+str_data[num&0x00ffffff].str);
-			if((sql_res = mysql_store_result(&mmysql_handle))){
+	// If some data was returned
+	if((sql_res = mysql_store_result(&mmysql_handle))){
+		// Count the number of rows to store
+		nb_rows = mysql_num_fields(sql_res);
+
+		// Can't store more row than variable
+		if (nb_rows > st->end - (st->start+3))
+			nb_rows = st->end - (st->start+3);
+
+		if (!nb_rows)
+		{
+			push_val(st->stack,C_INT,0);
+			return 0; // Nothing to store
+		}
+
+		if (nb_rows > 32)
+		{
+			ShowWarning("buildin_query_sql: too much rows!\n");
+			push_val(st->stack,C_INT,0);
+			return 1;
+		}
+
+		memset(row, 0, sizeof(row));
+		// Verify argument types
+		for(j=0; j < nb_rows; j++)
+		{
+			if(st->stack->stack_data[st->start+3+j].type != C_NAME){
+				ShowWarning("buildin_query_sql: Parameter %d is not a variable!\n", j);
+				push_val(st->stack,C_INT,0);
+				return 0;
+			} else {
+				// Store type of variable (string = 0/int = 1)
+				num=st->stack->stack_data[st->start+3+j].u.num;
+				name=(char *)(str_buf+str_data[num&0x00ffffff].str);
 				if(name[strlen(name)-1] != '$') {
-					while(i<128 && (sql_row = mysql_fetch_row(sql_res))){
-						setd_sub(st,sd, name, i, (void *)atoi(sql_row[0]),st->stack->stack_data[st->start+3].ref);
-						i++;
-					}
-				} else {
-					while(i<128 && (sql_row = mysql_fetch_row(sql_res))){
-						setd_sub(st,sd, name, i, (void *)sql_row[0],st->stack->stack_data[st->start+3].ref);
-						i++;
-					}
+					row[j].type = 1;
 				}
-				mysql_free_result(sql_res);
+				row[j].dst_var_name = name;
 			}
 		}
+		// Store data
+		while(i<128 && (sql_row = mysql_fetch_row(sql_res))){
+			for(j=0; j < nb_rows; j++)
+			{
+				if (row[j].type == 1)
+					setd_sub(st,sd, row[j].dst_var_name, i, (void *)atoi(sql_row[j]),st->stack->stack_data[st->start+3+j].ref);
+				else
+					setd_sub(st,sd, row[j].dst_var_name, i, (void *)sql_row[j],st->stack->stack_data[st->start+3+j].ref);
+			}
+			i++;
+		}
+		// Free data
+		mysql_free_result(sql_res);
 	}
-
+	push_val(st->stack, C_INT, i);
 	return 0;
 }