diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-11-08 10:17:44 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-11-08 10:17:44 +0000 |
commit | 49e40b5b5281ebbe4177a3a0c48dc2e0769c1dc4 (patch) | |
tree | b7ba5a72e1f99282968df5b25d318b717a8422f8 | |
parent | 9eb222426c4275cf35648ac8dc2e6c83cdbba14c (diff) | |
download | hercules-49e40b5b5281ebbe4177a3a0c48dc2e0769c1dc4.tar.gz hercules-49e40b5b5281ebbe4177a3a0c48dc2e0769c1dc4.tar.bz2 hercules-49e40b5b5281ebbe4177a3a0c48dc2e0769c1dc4.tar.xz hercules-49e40b5b5281ebbe4177a3a0c48dc2e0769c1dc4.zip |
Synced charserver char creation creation code
* removed most of the creation failure messages printed to console
* fixed sql charserver letting you use control chars in char names
* new chars will not start with the 'Knife' and 'Cotton Shirt' equipped anymore (charserver blindly placed magic values into the equip field)
Fixed a glitch where all packets immediately after the map->char login packet would get discarded and the mapserver disconnected.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11696 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | Changelog-Trunk.txt | 7 | ||||
-rw-r--r-- | src/char/char.c | 167 | ||||
-rw-r--r-- | src/char_sql/char.c | 220 |
3 files changed, 140 insertions, 254 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index fc9bfc072..3e626e957 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,13 @@ 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. 2007/11/08 + * Fixed a glitch where all packets immediately after the map->char + login packet would get discarded and the mapserver disconnected + * Synced charserver char creation creation code [ultramage] + - removed most of the creation failure messages printed to console + - fixed sql charserver letting you use control chars in char names + - new chars will not start with the 'Knife' and 'Cotton Shirt' equipped + anymore (charserver blindly placed magic values into the equip field) * Updated configure script: - small correction to the help text of --with-mysql and --with-pcre - added the -Wno-switch compiler option to suppress the diff --git a/src/char/char.c b/src/char/char.c index 1c2dd5caf..557a107a7 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1156,33 +1156,23 @@ int make_new_char(struct char_session_data* sd, char* name_, int str, int agi, i safestrncpy(name, name_, NAME_LENGTH); normalize_name(name,TRIM_CHARS); - if( remove_control_chars(name) ) { - char_log("Make new char error (control char received in the name): (connection #%d, account: %d).\n", sd->fd, sd->account_id); - return -2; - } // check length of character name - if( name[0] == '\0' ) { - char_log("Make new char error (character name too small): (connection #%d, account: %d, name: '%s').\n", sd->fd, sd->account_id, name); - return -2; - } + if( name[0] == '\0' ) + return -2; // empty character name - // check name != main chat nick [LuzZza] - if( strcmpi(name, main_chat_nick) == 0 ) { - char_log("Create char failed (%d): this nick (%s) reserved for mainchat messages.\n", sd->account_id, name); - return -1; - } + // check content of character name + if( remove_control_chars(name) ) + return -2; // control chars in name - if (strcmpi(wisp_server_name, name) == 0) { - char_log("Make new char error (name used is wisp name for server): (connection #%d, account: %d) slot %d, name: %s, stats: %d/%d/%d/%d/%d/%d, hair: %d, hair color: %d.\n", - sd->fd, sd->account_id, slot, name, str, agi, vit, int_, dex, luk, hair_style, hair_color); - return -1; - } + // check for reserved names + if( strcmpi(name, main_chat_nick) == 0 || strcmpi(name, wisp_server_name) == 0 ) + return -1; // nick reserved for internal server messages // Check Authorised letters/symbols in the name of the character if( char_name_option == 1 ) { // only letters/symbols in char_name_letters are authorised for( i = 0; i < NAME_LENGTH && name[i]; i++ ) - if (strchr(char_name_letters, name[i]) == NULL) + if( strchr(char_name_letters, name[i]) == NULL ) return -2; } else if( char_name_option == 2 ) { // letters/symbols in char_name_letters are forbidden @@ -1191,22 +1181,12 @@ int make_new_char(struct char_session_data* sd, char* name_, int str, int agi, i return -2; } // else, all letters/symbols are authorised (except control char removed before) - //FIXME: the code way below actually depends on the value of 'i' that's used here! [ultramage] - for( i = 0; i < char_num; i++ ) { - // check if name doesn't already exist - if( (name_ignoring_case && strncmp(char_dat[i].status.name, name, NAME_LENGTH) == 0) || - (!name_ignoring_case && strncmpi(char_dat[i].status.name, name, NAME_LENGTH) == 0) ) { - char_log("Make new char error (name already exists): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %d), stats: %d/%d/%d/%d/%d/%d, hair: %d, hair color: %d.\n", - sd->fd, sd->account_id, slot, name, char_dat[i].status.name, str, agi, vit, int_, dex, luk, hair_style, hair_color); - return -1; - } - // check if this account's slot is not already occupied - if (char_dat[i].status.account_id == sd->account_id && char_dat[i].status.slot == slot) { - char_log("Make new char error (slot already used): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %d), stats: %d/%d/%d/%d/%d/%d, hair: %d, hair color: %d.\n", - sd->fd, sd->account_id, slot, name, char_dat[i].status.name, str, agi, vit, int_, dex, luk, hair_style, hair_color); - return -1; - } - } + // check name (already in use?) + ARR_FIND( 0, char_num, i, + name_ignoring_case && strncmp(char_dat[i].status.name, name, NAME_LENGTH) == 0 || + !name_ignoring_case && strncmpi(char_dat[i].status.name, name, NAME_LENGTH) == 0 ); + if( i < char_num ) + return -1; // name already exists //check other inputs if((slot >= MAX_CHARS) // slots @@ -1215,11 +1195,12 @@ int make_new_char(struct char_session_data* sd, char* name_, int str, int agi, i || (str + agi + vit + int_ + dex + luk != 6*5 ) // stats || (str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) // individual stat values || (str + int_ != 10 || agi + luk != 10 || vit + dex != 10) ) // pairs - { - char_log("Make new char error (invalid values): (connection #%d, account: %d) slot %d, name: %s, stats: %d/%d/%d/%d/%d/%d, hair: %d, hair color: %d\n", - sd->fd, sd->account_id, slot, name, str, agi, vit, int_, dex, luk, hair_style, hair_color); - return -2; - } + return -2; // invalid input + + // check char slot + ARR_FIND( 0, char_num, i, char_dat[i].status.account_id == sd->account_id && char_dat[i].status.slot == slot ); + if( i < char_num ) + return -2; // slot already in use if (char_num >= char_max) { char_max += 256; @@ -1231,15 +1212,17 @@ int make_new_char(struct char_session_data* sd, char* name_, int str, int agi, i } } - char_log("Creation of New Character: (connection #%d, account: %d) slot %d, character Name: %s, stats: %d/%d/%d/%d/%d/%d, hair: %d, hair color: %d.\n", - sd->fd, sd->account_id, slot, name, str, agi, vit, int_, dex, luk, hair_style, hair_color); + // validation success, log result + char_log("make new char: account: %d, slot %d, name: %s, stats: %d/%d/%d/%d/%d/%d, hair: %d, hair color: %d.\n", + sd->account_id, slot, name, str, agi, vit, int_, dex, luk, hair_style, hair_color); + i = char_num; memset(&char_dat[i], 0, sizeof(struct character_data)); char_dat[i].status.char_id = char_id_count++; char_dat[i].status.account_id = sd->account_id; char_dat[i].status.slot = slot; - strcpy(char_dat[i].status.name,name); + safestrncpy(char_dat[i].status.name,name,NAME_LENGTH); char_dat[i].status.class_ = 0; char_dat[i].status.base_level = 1; char_dat[i].status.job_level = 1; @@ -1268,13 +1251,11 @@ int make_new_char(struct char_session_data* sd, char* name_, int str, int agi, i char_dat[i].status.clothes_color = 0; char_dat[i].status.inventory[0].nameid = start_weapon; // Knife char_dat[i].status.inventory[0].amount = 1; - char_dat[i].status.inventory[0].equip = 0x02; char_dat[i].status.inventory[0].identify = 1; char_dat[i].status.inventory[1].nameid = start_armor; // Cotton Shirt char_dat[i].status.inventory[1].amount = 1; - char_dat[i].status.inventory[1].equip = 0x10; char_dat[i].status.inventory[1].identify = 1; - char_dat[i].status.weapon = 1; + char_dat[i].status.weapon = 0; // W_FIST char_dat[i].status.shield = 0; char_dat[i].status.head_top = 0; char_dat[i].status.head_mid = 0; @@ -1283,6 +1264,7 @@ int make_new_char(struct char_session_data* sd, char* name_, int str, int agi, i memcpy(&char_dat[i].status.save_point, &start_point, sizeof(start_point)); char_num++; + ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, i, slot, name); mmo_char_sync(); return i; } @@ -2062,32 +2044,6 @@ int parse_fromlogin(int fd) RFIFOSKIP(fd,2); break; - // Receiving authentification from Freya-type login server (to avoid char->login->char) - case 0x2719: - if (RFIFOREST(fd) < 18) - return 0; - // to conserv a maximum of authentification, search if account is already authentified and replace it - // that will reduce multiple connection too - for(i = 0; i < AUTH_FIFO_SIZE; i++) - if (auth_fifo[i].account_id == RFIFOL(fd,2)) - break; - // if not found, use next value - if (i == AUTH_FIFO_SIZE) { - if (auth_fifo_pos >= AUTH_FIFO_SIZE) - auth_fifo_pos = 0; - i = auth_fifo_pos; - auth_fifo_pos++; - } - auth_fifo[i].account_id = RFIFOL(fd,2); - auth_fifo[i].char_id = 0; - auth_fifo[i].login_id1 = RFIFOL(fd,6); - auth_fifo[i].login_id2 = RFIFOL(fd,10); - auth_fifo[i].delflag = 2; // 0: auth_fifo canceled/void, 2: auth_fifo received from login/map server in memory, 1: connection authentified - auth_fifo[i].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server) - auth_fifo[i].ip = ntohl(RFIFOL(fd,14)); - RFIFOSKIP(fd,18); - break; - case 0x2721: // gm reply if (RFIFOREST(fd) < 10) return 0; @@ -2338,7 +2294,7 @@ int parse_fromlogin(int fd) unsigned char buf[32000]; if (gm_account != NULL) aFree(gm_account); - gm_account = (struct gm_account*)aCalloc(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1); + CREATE(gm_account, struct gm_account, (RFIFOW(fd,2) - 4)/5); GM_num = 0; for (i = 4; i < RFIFOW(fd,2); i = i + 5) { gm_account[GM_num].account_id = RFIFOL(fd,i); @@ -2358,63 +2314,6 @@ int parse_fromlogin(int fd) } break; - // Receive GM accounts [Freya login server packet by Yor] - case 0x2733: - if (RFIFOREST(fd) < 7) - return 0; - { - int new_level = 0; - for(i = 0; i < GM_num; i++) - if (gm_account[i].account_id == RFIFOL(fd,2)) { - if (gm_account[i].level != (int)RFIFOB(fd,6)) { - gm_account[i].level = (int)RFIFOB(fd,6); - new_level = 1; - } - break; - } - // if not found, add it - if (i == GM_num) { - // limited to 4000, because we send information to char-servers (more than 4000 GM accounts???) - // int (id) + int (level) = 8 bytes * 4000 = 32k (limit of packets in windows) - if (((int)RFIFOB(fd,6)) > 0 && GM_num < 4000) { - if (GM_num == 0) { - gm_account = (struct gm_account*)aMalloc(sizeof(struct gm_account)); - } else { - gm_account = (struct gm_account*)aRealloc(gm_account, sizeof(struct gm_account) * (GM_num + 1)); - } - gm_account[GM_num].account_id = RFIFOL(fd,2); - gm_account[GM_num].level = (int)RFIFOB(fd,6); - new_level = 1; - GM_num++; - if (GM_num >= 4000) { - ShowWarning("4000 GM accounts found. Next GM accounts are not readed.\n"); - char_log("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n"); - } - } - } - if (new_level == 1) { - unsigned char buf[32000]; - int len; - ShowStatus("From login-server: receiving GM account information (%d: level %d).\n", RFIFOL(fd,2), (int)RFIFOB(fd,6)); - char_log("From login-server: receiving a GM account information (%d: level %d).\n", RFIFOL(fd,2), (int)RFIFOB(fd,6)); - //create_online_files(); // not change online file for only 1 player (in next timer, that will be done - // send gm acccounts level to map-servers - len = 4; - WBUFW(buf,0) = 0x2b15; - - for(i = 0; i < GM_num; i++) { - WBUFL(buf, len) = gm_account[i].account_id; - WBUFB(buf, len+4) = (unsigned char)gm_account[i].level; - len += 5; - } - WBUFW(buf, 2) = len; - mapif_sendall(buf, len); - } - - RFIFOSKIP(fd,7); - } - break; - //Login server request to kick a character out. [Skotlex] case 0x2734: if (RFIFOREST(fd) < 6) @@ -2858,8 +2757,6 @@ int parse_frommap(int fd) return 0; //TODO: When data mismatches memory, update guild/party online/offline states. server[id].users = RFIFOW(fd,4); - // add online players in the list by [Yor], adapted to use dbs by [Skotlex] - j = 0; online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown' for(i = 0; i < server[id].users; i++) { int aid, cid; @@ -3765,7 +3662,7 @@ int parse_char(int fd) RFIFOSKIP(fd,60); } - break; + return 0; // avoid processing of followup packets here // Athena info get case 0x7530: @@ -4365,11 +4262,11 @@ int do_init(int argc, char **argv) add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect"); add_timer_func_list(online_data_cleanup, "online_data_cleanup"); - add_timer_interval(gettick() + 600*1000, online_data_cleanup, 0, 0, 600 * 1000); add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000); add_timer_interval(gettick() + 1000, send_users_tologin, 0, 0, 5 * 1000); - add_timer_interval(gettick() + 3600*1000, send_accounts_tologin, 0, 0, 3600*1000); //Sync online accounts every hour + add_timer_interval(gettick() + 3600*1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour add_timer_interval(gettick() + autosave_interval, mmo_char_sync_timer, 0, 0, autosave_interval); + add_timer_interval(gettick() + 600*1000, online_data_cleanup, 0, 0, 600 * 1000); char_read_fame_list(); //Read fame lists. diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 84c79e420..94e1af1c8 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -1088,53 +1088,31 @@ int mmo_char_sql_init(void) return 0; } -//========================================================================================================== - +//----------------------------------- +// Function to create a new character +//----------------------------------- int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style) { char name[NAME_LENGTH]; char esc_name[NAME_LENGTH*2+1]; unsigned int i; int char_id; - bool valid; safestrncpy(name, name_, NAME_LENGTH); normalize_name(name,TRIM_CHARS); Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); - ShowInfo("New character request (%d)\n", sd->account_id); - - // check the number of already existing chars in this account - if( char_per_account != 0 ) { - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) ) - Sql_ShowDebug(sql_handle); - if( Sql_NumRows(sql_handle) >= char_per_account ) { - ShowInfo("Create char failed (%d): charlimit exceeded.\n", sd->account_id); - Sql_FreeResult(sql_handle); - return -2; - } - } - - // check char slot. - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d'", char_db, sd->account_id, slot) ) - Sql_ShowDebug(sql_handle); - if( Sql_NumRows(sql_handle) > 0 ) - { - ShowWarning("Create char failed (%d, slot: %d), slot already in use\n", sd->account_id, slot); - return -2; - } - // check length of character name - if( name[0] == '\0' ) { - ShowInfo("Create char failed (empty character name): (connection #%d, account: %d).\n", sd->fd, sd->account_id); - return -2; - } + if( name[0] == '\0' ) + return -2; // empty character name - // check name != main chat nick [LuzZza] - if( strcmpi(name, main_chat_nick) == 0 ) { - ShowInfo("Create char failed (%d): this nick (%s) reserved for mainchat messages.\n", sd->account_id, name); - return -2; - } + // check content of character name + if( remove_control_chars(name) ) + return -2; // control chars in name + + // check for reserved names + if( strcmpi(name, main_chat_nick) == 0 || strcmpi(name, wisp_server_name) == 0 ) + return -1; // nick reserved for internal server messages // Check Authorised letters/symbols in the name of the character if( char_name_option == 1 ) { // only letters/symbols in char_name_letters are authorised @@ -1153,10 +1131,8 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag Sql_ShowDebug(sql_handle); return -2; } - if( Sql_NumRows(sql_handle) > 0 ) { - ShowInfo("Create char failed: charname already in use\n"); - return -1; - } + if( Sql_NumRows(sql_handle) > 0 ) + return -1; // name already exists //check other inputs if((slot >= MAX_CHARS) // slots @@ -1165,24 +1141,31 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag || (str + agi + vit + int_ + dex + luk != 6*5 ) // stats || (str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) // individual stat values || (str + int_ != 10 || agi + luk != 10 || vit + dex != 10) ) // pairs - valid = false; - else - valid = true; + return -2; // invalid input + + // check the number of already existing chars in this account + if( char_per_account != 0 ) { + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) ) + Sql_ShowDebug(sql_handle); + if( Sql_NumRows(sql_handle) >= char_per_account ) + return -2; // character account limit exceeded + } - // log result + // check char slot + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d'", char_db, sd->account_id, slot) ) + Sql_ShowDebug(sql_handle); + if( Sql_NumRows(sql_handle) > 0 ) + return -2; // slot already in use + + // validation success, log result if (log_char) { if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)" "VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')", - charlog_db,(valid?"make new char":"make new char error"), sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) ) + charlog_db, "make new char", sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) ) Sql_ShowDebug(sql_handle); } - if( !valid ) { - ShowWarning("Create char failed (%d): stats error (bot cheat?!)\n", sd->account_id); - return -2; - } - - //Insert the char to the 'chardb' ^^ + //Insert the new char entry to the database if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`," "`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES (" "'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')", @@ -1193,16 +1176,15 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag Sql_ShowDebug(sql_handle); return -2; //No, stop the procedure! } - //Now we need the charid from sql! + //Retrieve the newly auto-generated char id char_id = (int)Sql_LastInsertId(sql_handle); //Give the char the default items - //`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`) if (start_weapon > 0) { //add Start Weapon (Knife?) - if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')", inventory_db, char_id, start_weapon, 1, 0x02, 1) ) + if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_weapon, 1, 1) ) Sql_ShowDebug(sql_handle); } if (start_armor > 0) { //Add default armor (cotton shirt?) - if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')", inventory_db, char_id, start_armor, 1, 0x10, 1) ) + if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_armor, 1, 1) ) Sql_ShowDebug(sql_handle); } @@ -1458,6 +1440,71 @@ int mmo_char_send006b(int fd, struct char_session_data* sd) return 0; } +int char_married(int pl1, int pl2) +{ + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", char_db, pl1) ) + Sql_ShowDebug(sql_handle); + else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) + { + char* data; + + Sql_GetData(sql_handle, 0, &data, NULL); + if( pl2 == atoi(data) ) + { + Sql_FreeResult(sql_handle); + return 1; + } + } + Sql_FreeResult(sql_handle); + return 0; +} + +int char_child(int parent_id, int child_id) +{ + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", char_db, parent_id) ) + Sql_ShowDebug(sql_handle); + else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) + { + char* data; + + Sql_GetData(sql_handle, 0, &data, NULL); + if( child_id == atoi(data) ) + { + Sql_FreeResult(sql_handle); + return 1; + } + } + Sql_FreeResult(sql_handle); + return 0; +} + +int char_family(int pl1, int pl2, int pl3) +{ + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`partner_id`,`child` FROM `%s` WHERE `char_id` IN ('%d','%d','%d')", char_db, pl1, pl2, pl3) ) + Sql_ShowDebug(sql_handle); + else while( SQL_SUCCESS == Sql_NextRow(sql_handle) ) + { + int charid; + int partnerid; + int childid; + char* data; + + Sql_GetData(sql_handle, 0, &data, NULL); charid = atoi(data); + Sql_GetData(sql_handle, 1, &data, NULL); partnerid = atoi(data); + Sql_GetData(sql_handle, 2, &data, NULL); childid = atoi(data); + + if( (pl1 == charid && ((pl2 == partnerid && pl3 == childid ) || (pl2 == childid && pl3 == partnerid))) || + (pl1 == partnerid && ((pl2 == charid && pl3 == childid ) || (pl2 == childid && pl3 == charid ))) || + (pl1 == childid && ((pl2 == charid && pl3 == partnerid) || (pl2 == partnerid && pl3 == charid ))) ) + { + Sql_FreeResult(sql_handle); + return childid; + } + } + Sql_FreeResult(sql_handle); + return 0; +} + static void char_auth_ok(int fd, struct char_session_data *sd) { struct online_char_data* character; @@ -3099,7 +3146,7 @@ int parse_char(int fd) RFIFOSKIP(fd,60); } - break; + return 0; // avoid processing of followup packets here // Athena info get case 0x7530: @@ -3798,69 +3845,4 @@ int do_init(int argc, char **argv) return 0; } -int char_child(int parent_id, int child_id) -{ - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", char_db, parent_id) ) - Sql_ShowDebug(sql_handle); - else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) - { - char* data; - - Sql_GetData(sql_handle, 0, &data, NULL); - if( child_id == atoi(data) ) - { - Sql_FreeResult(sql_handle); - return 1; - } - } - Sql_FreeResult(sql_handle); - return 0; -} - -int char_married(int pl1, int pl2) -{ - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", char_db, pl1) ) - Sql_ShowDebug(sql_handle); - else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) - { - char* data; - - Sql_GetData(sql_handle, 0, &data, NULL); - if( pl2 == atoi(data) ) - { - Sql_FreeResult(sql_handle); - return 1; - } - } - Sql_FreeResult(sql_handle); - return 0; -} - -int char_family(int pl1, int pl2, int pl3) -{ - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`partner_id`,`child` FROM `%s` WHERE `char_id` IN ('%d','%d','%d')", char_db, pl1, pl2, pl3) ) - Sql_ShowDebug(sql_handle); - else while( SQL_SUCCESS == Sql_NextRow(sql_handle) ) - { - int charid; - int partnerid; - int childid; - char* data; - - Sql_GetData(sql_handle, 0, &data, NULL); charid = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); partnerid = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); childid = atoi(data); - - if( (pl1 == charid && ((pl2 == partnerid && pl3 == childid ) || (pl2 == childid && pl3 == partnerid))) || - (pl1 == partnerid && ((pl2 == charid && pl3 == childid ) || (pl2 == childid && pl3 == charid ))) || - (pl1 == childid && ((pl2 == charid && pl3 == partnerid) || (pl2 == partnerid && pl3 == charid ))) ) - { - Sql_FreeResult(sql_handle); - return childid; - } - } - Sql_FreeResult(sql_handle); - return 0; -} - #endif //TXT_SQL_CONVERT |