From 7f024c8c6073c4fa1a4130c499a7f783e5a55ca1 Mon Sep 17 00:00:00 2001 From: toms Date: Sat, 29 Jul 2006 23:06:03 +0000 Subject: 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7975 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 3 ++ doc/script_commands.txt | 17 ++++++----- src/login_sql/login.c | 10 +++---- src/map/script.c | 76 +++++++++++++++++++++++++++++++++++-------------- 4 files changed, 70 insertions(+), 36 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 1be02f87a..f4af775e2 100644 --- a/Changelog-Trunk.txt +++ b/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] diff --git a/doc/script_commands.txt b/doc/script_commands.txt index da9a8227c..9b742984c 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -4950,18 +4950,17 @@ Example: set @i, distance(100,200,101,202); --------------------------------------- -*query_sql "your MySQL query", -Returns up to 127 values into array. +*query_sql "your MySQL query", , [] +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. diff --git a/src/login_sql/login.c b/src/login_sql/login.c index 395f091bf..78f7da3ca 100644 --- a/src/login_sql/login.c +++ b/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]); diff --git a/src/map/script.c b/src/map/script.c index a6ad56ffe..25f943d96 100644 --- a/src/map/script.c +++ b/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; } -- cgit v1.2.3-70-g09d2