diff options
Diffstat (limited to 'src/char/inter.c')
-rw-r--r-- | src/char/inter.c | 566 |
1 files changed, 320 insertions, 246 deletions
diff --git a/src/char/inter.c b/src/char/inter.c index 2dc15933b..ff99865f8 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -42,26 +42,25 @@ char char_server_pw[32] = "ragnarok"; char char_server_db[32] = "ragnarok"; char default_codepage[32] = ""; //Feature by irmin. -static struct accreg *accreg_pt; unsigned int party_share_level = 10; // recv. packet list int inter_recv_packet_length[] = { -1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000- - 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- - -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party - -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- - -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- - -1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] - 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] - -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil] - 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080- - -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator] + 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- + -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party + -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- + -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- + -1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus], Item Bound [Mhalicot] + 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] + -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil] + 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080- + -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator] }; struct WisData { int id, fd, count, len; - unsigned long tick; + int64 tick; unsigned char src[24], dst[24], msg[512]; }; static DBMap* wis_db = NULL; // int wis_id -> struct WisData* @@ -341,8 +340,11 @@ const char* job_name(int class_) { case JOB_OBORO: return msg_txt(653 - JOB_KAGEROU+class_); - default: + case JOB_REBELLION: return msg_txt(655); + + default: + return msg_txt(656); } } @@ -509,207 +511,287 @@ void mapif_parse_accinfo(int fd) { } /* it will only get here if we have a single match */ + /* and we will send packet with account id to login server asking for account info */ if( account_id ) { - char userid[NAME_LENGTH], user_pass[NAME_LENGTH], email[40], last_ip[20], lastlogin[30], pin_code[5], birthdate[11]; - short level = -1; - int logincount = 0,state = 0; - // FIXME: No, this doesn't really look right. We can't, and shouldn't, access the login table from the char server. - if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `userid`, `user_pass`, `email`, `last_ip`, `group_id`, `lastlogin`, `logincount`, `state`,`pincode`,`birthdate` FROM `login` WHERE `account_id` = '%d' LIMIT 1", account_id) - || SQL->NumRows(sql_handle) == 0 ) { - if( SQL->NumRows(sql_handle) == 0 ) { - inter_msg_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id ); - } else { - inter_msg_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it."); - Sql_ShowDebug(sql_handle); - } - } else { - SQL->NextRow(sql_handle); - SQL->GetData(sql_handle, 0, &data, NULL); safestrncpy(userid, data, sizeof(userid)); - SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(user_pass, data, sizeof(user_pass)); - SQL->GetData(sql_handle, 2, &data, NULL); safestrncpy(email, data, sizeof(email)); - SQL->GetData(sql_handle, 3, &data, NULL); safestrncpy(last_ip, data, sizeof(last_ip)); - SQL->GetData(sql_handle, 4, &data, NULL); level = atoi(data); - SQL->GetData(sql_handle, 5, &data, NULL); safestrncpy(lastlogin, data, sizeof(lastlogin)); - SQL->GetData(sql_handle, 6, &data, NULL); logincount = atoi(data); - SQL->GetData(sql_handle, 7, &data, NULL); state = atoi(data); - SQL->GetData(sql_handle, 8, &data, NULL); safestrncpy(pin_code, data, sizeof(pin_code)); - SQL->GetData(sql_handle, 9, &data, NULL); safestrncpy(birthdate, data, sizeof(birthdate)); - } - - SQL->FreeResult(sql_handle); - - if (level == -1) - return; - - inter_msg_to_fd(fd, u_fd, aid, "-- Account %d --", account_id ); - inter_msg_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state ); - - if (level < castergroup) { /* only show pass if your gm level is greater than the one you're searching for */ - if( strlen(pin_code) ) - inter_msg_to_fd(fd, u_fd, aid, "Password: %s (PIN:%s)", user_pass, pin_code ); - else - inter_msg_to_fd(fd, u_fd, aid, "Password: %s", user_pass ); - } - - inter_msg_to_fd(fd, u_fd, aid, "Account e-mail: %s | Birthdate: %s", email, birthdate); - inter_msg_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) ); - inter_msg_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin ); - inter_msg_to_fd(fd, u_fd, aid, "-- Character Details --" ); - - - if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS) - || SQL->NumRows(sql_handle) == 0 ) { - - if( SQL->NumRows(sql_handle) == 0 ) - inter_msg_to_fd(fd, u_fd, aid,"This account doesn't have characters."); - else { - inter_msg_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it."); - Sql_ShowDebug(sql_handle); - } - - } else { - while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { - int char_id, class_; - short char_num, base_level, job_level, online; - char name[NAME_LENGTH]; - - SQL->GetData(sql_handle, 0, &data, NULL); char_id = atoi(data); - SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name)); - SQL->GetData(sql_handle, 2, &data, NULL); char_num = atoi(data); - SQL->GetData(sql_handle, 3, &data, NULL); class_ = atoi(data); - SQL->GetData(sql_handle, 4, &data, NULL); base_level = atoi(data); - SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data); - SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data); - - inter_msg_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off"); - } - } - SQL->FreeResult(sql_handle); + mapif_on_parse_accinfo(account_id, u_fd, aid, castergroup, fd); } return; } -//-------------------------------------------------------- -// Save registry to sql -int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type) -{ - struct global_reg* r; - StringBuf buf; - int i; +void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state) { + if (map_fd <= 0 || !session_isActive(map_fd)) + return; // check if we have a valid fd - if( account_id <= 0 ) - return 0; - reg->account_id = account_id; - reg->char_id = char_id; - - //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) - switch( type ) - { - case 3: //Char Reg - if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) ) - Sql_ShowDebug(sql_handle); - account_id = 0; - break; - case 2: //Account Reg - if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) ) - Sql_ShowDebug(sql_handle); - char_id = 0; - break; - case 1: //Account2 Reg - ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); - return 0; - default: - ShowError("inter_accreg_tosql: Invalid type %d\n", type); - return 0; + if (!success) { + inter_msg_to_fd(map_fd, u_fd, u_aid, "No account with ID '%d' was found.", account_id); + return; } - if( reg->reg_num <= 0 ) - return 0; + inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Account %d --", account_id); + inter_msg_to_fd(map_fd, u_fd, u_aid, "User: %s | GM Group: %d | State: %d", userid, group_id, state); - StrBuf->Init(&buf); - StrBuf->Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db); - - for( i = 0; i < reg->reg_num; ++i ) { - r = ®->reg[i]; - if( r->str[0] != '\0' && r->value[0] != '\0' ) { - char str[32]; - char val[256]; - - if( i > 0 ) - StrBuf->AppendStr(&buf, ","); + if (user_pass && *user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */ + if (pin_code && *pin_code != '\0') + inter_msg_to_fd(map_fd, u_fd, u_aid, "Password: %s (PIN:%s)", user_pass, pin_code); + else + inter_msg_to_fd(map_fd, u_fd, u_aid, "Password: %s", user_pass ); + } - SQL->EscapeString(sql_handle, str, r->str); - SQL->EscapeString(sql_handle, val, r->value); + inter_msg_to_fd(map_fd, u_fd, u_aid, "Account e-mail: %s | Birthdate: %s", email, birthdate); + inter_msg_to_fd(map_fd, u_fd, u_aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip))); + inter_msg_to_fd(map_fd, u_fd, u_aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin); + inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Character Details --"); - StrBuf->Printf(&buf, "('%d','%d','%d','%s','%s')", type, account_id, char_id, str, val); + if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` " + "FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS) + || SQL->NumRows(sql_handle) == 0 ) { + if (SQL->NumRows(sql_handle) == 0) { + inter_msg_to_fd(map_fd, u_fd, u_aid, "This account doesn't have characters."); + } else { + inter_msg_to_fd(map_fd, u_fd, u_aid, "An error occured, bother your admin about it."); + Sql_ShowDebug(sql_handle); + } + } else { + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + char *data; + int char_id, class_; + short char_num, base_level, job_level, online; + char name[NAME_LENGTH]; + + SQL->GetData(sql_handle, 0, &data, NULL); char_id = atoi(data); + SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name)); + SQL->GetData(sql_handle, 2, &data, NULL); char_num = atoi(data); + SQL->GetData(sql_handle, 3, &data, NULL); class_ = atoi(data); + SQL->GetData(sql_handle, 4, &data, NULL); base_level = atoi(data); + SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data); + SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data); + + inter_msg_to_fd(map_fd, u_fd, u_aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off"); } } + SQL->FreeResult(sql_handle); - if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) { - Sql_ShowDebug(sql_handle); + return; +} +/** + * Handles save reg data from map server and distributes accordingly. + * + * @param val either str or int, depending on type + * @param type false when int, true otherwise + **/ +void inter_savereg(int account_id, int char_id, const char *key, unsigned int index, intptr_t val, bool is_string) { + /* to login server we go! */ + if( key[0] == '#' && key[1] == '#' ) {/* global account reg */ + global_accreg_to_login_add(key,index,val,is_string); + } else if ( key[0] == '#' ) {/* local account reg */ + if( is_string ) { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", acc_reg_str_db, account_id, key, index, (char*)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_str_db, account_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } else { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", acc_reg_num_db, account_id, key, index, (int)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_num_db, account_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } + } else { /* char reg */ + if( is_string ) { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", char_reg_str_db, char_id, key, index, (char*)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_str_db, char_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } else { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", char_reg_num_db, char_id, key, index, (int)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_num_db, char_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } } - - StrBuf->Destroy(&buf); - - return 1; + } // Load account_reg from sql (type=2) -int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type) +int inter_accreg_fromsql(int account_id,int char_id, int fd, int type) { - struct global_reg* r; char* data; size_t len; - int i; - - if( reg == NULL) - return 0; + unsigned int plen = 0; - memset(reg, 0, sizeof(struct accreg)); - reg->account_id = account_id; - reg->char_id = char_id; + switch( type ) { + case 3: //char reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) ) + Sql_ShowDebug(sql_handle); + break; + case 2: //account reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_str_db, account_id) ) + Sql_ShowDebug(sql_handle); + break; + case 1: //account2 reg + ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); + return 0; + default: + ShowError("inter_accreg_fromsql: Invalid type %d\n", type); + return 0; + } + + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 1;/* is string type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + + /** + * Vessel! + * + * str type + * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) } + **/ + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + + SQL->GetData(sql_handle, 0, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + SQL->GetData(sql_handle, 1, &data, NULL); + + WFIFOL(fd, plen) = (unsigned int)atol(data); + plen += 4; + + SQL->GetData(sql_handle, 2, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + WFIFOW(fd, 14) += 1; + + if( plen > 60000 ) { + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + /* prepare follow up */ + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 1;/* is string type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + } + } + + /* mark & go. */ + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); - //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) - switch( type ) - { - case 3: //char reg - if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) ) - Sql_ShowDebug(sql_handle); - break; - case 2: //account reg - if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) ) - Sql_ShowDebug(sql_handle); - break; - case 1: //account2 reg - ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); - return 0; - default: - ShowError("inter_accreg_fromsql: Invalid type %d\n", type); - return 0; + SQL->FreeResult(sql_handle); + + switch( type ) { + case 3: //char reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) ) + Sql_ShowDebug(sql_handle); + break; + case 2: //account reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_num_db, account_id) ) + Sql_ShowDebug(sql_handle); + break; + case 1: //account2 reg + ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); + return 0; } - for( i = 0; i < MAX_REG_NUM && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i ) - { - r = ®->reg[i]; - // str - SQL->GetData(sql_handle, 0, &data, &len); - memcpy(r->str, data, min(len, sizeof(r->str))); - // value - SQL->GetData(sql_handle, 1, &data, &len); - memcpy(r->value, data, min(len, sizeof(r->value))); + + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 0;/* is int type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + + /** + * Vessel! + * + * int type + * { keyLength(B), key(<keyLength>), index(L), value(L) } + **/ + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + + SQL->GetData(sql_handle, 0, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + SQL->GetData(sql_handle, 1, &data, NULL); + + WFIFOL(fd, plen) = (unsigned int)atol(data); + plen += 4; + + SQL->GetData(sql_handle, 2, &data, NULL); + + WFIFOL(fd, plen) = atoi(data); + plen += 4; + + WFIFOW(fd, 14) += 1; + + if( plen > 60000 ) { + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + /* prepare follow up */ + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 0;/* is int type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + } } - reg->reg_num = i; + + /* mark as complete & go. */ + WFIFOB(fd, 12) = type; + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + SQL->FreeResult(sql_handle); return 1; } -// Initialize -int inter_accreg_sql_init(void) -{ - CREATE(accreg_pt, struct accreg, 1); - return 0; - -} - /*========================================== * read config file *------------------------------------------*/ @@ -830,7 +912,6 @@ int inter_init_sql(const char *file) inter_homunculus_sql_init(); inter_mercenary_sql_init(); inter_elemental_sql_init(); - inter_accreg_sql_init(); inter_mail_sql_init(); inter_auction_sql_init(); @@ -854,8 +935,6 @@ void inter_final(void) inter_mail_sql_final(); inter_auction_sql_final(); - if (accreg_pt) aFree(accreg_pt); - do_final_msg(); return; } @@ -869,7 +948,7 @@ int inter_mapif_init(int fd) //-------------------------------------------------------- // broadcast sending -int mapif_broadcast(unsigned char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd) +int mapif_broadcast(unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd) { unsigned char *buf = (unsigned char*)aMalloc((len)*sizeof(unsigned char)); @@ -918,36 +997,15 @@ int mapif_wis_end(struct WisData *wd, int flag) } // Account registry transfer to map-server -static void mapif_account_reg(int fd, unsigned char *src) -{ - WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO - mapif_sendallwos(fd, src, WBUFW(src,2)); -} +//static void mapif_account_reg(int fd, unsigned char *src) +//{ +// WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO +// mapif_sendallwos(fd, src, WBUFW(src,2)); +//} // Send the requested account_reg -int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) -{ - struct accreg *reg=accreg_pt; - WFIFOHEAD(fd, 13 + 5000); - inter_accreg_fromsql(account_id,char_id,reg,type); - - WFIFOW(fd,0)=0x3804; - WFIFOL(fd,4)=account_id; - WFIFOL(fd,8)=char_id; - WFIFOB(fd,12)=type; - if(reg->reg_num==0){ - WFIFOW(fd,2)=13; - }else{ - int i,p; - for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) { - p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place. - p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].value)+1; - } - WFIFOW(fd,2)=p; - if (p>= 5000) - ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id); - } - WFIFOSET(fd,WFIFOW(fd,2)); +int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) { + inter_accreg_fromsql(account_id,char_id,fd,type); return 0; } @@ -974,9 +1032,9 @@ int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason) */ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) { - unsigned long tick; + int64 tick; struct WisData *wd = DB->data2ptr(data); - tick = va_arg(ap, unsigned long); + tick = va_arg(ap, int64); if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX) wis_dellist[wis_delnum++] = wd->id; @@ -986,7 +1044,7 @@ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) int check_ttl_wisdata(void) { - unsigned long tick = timer->gettick(); + int64 tick = timer->gettick(); int i; do { @@ -1125,34 +1183,50 @@ int mapif_parse_WisToGM(int fd) // Save account_reg into sql (type=2) int mapif_parse_Registry(int fd) { - int j,p,len, max; - struct accreg *reg=accreg_pt; - - memset(accreg_pt,0,sizeof(struct accreg)); - switch (RFIFOB(fd, 12)) { - case 3: //Character registry - max = GLOBAL_REG_NUM; - break; - case 2: //Account Registry - max = ACCOUNT_REG_NUM; - break; - case 1: //Account2 registry, must be sent over to login server. - return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4); - default: - return 1; - } - for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){ - sscanf((char*)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len); - reg->reg[j].str[len]='\0'; - p +=len+1; //+1 to skip the '\0' between strings. - sscanf((char*)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len); - reg->reg[j].value[len]='\0'; - p +=len+1; - } - reg->reg_num=j; + int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12); + + if( count ) { + int cursor = 14, i; + char key[32], sval[254]; + unsigned int index; + + global_accreg_to_login_start(account_id,char_id); + + for(i = 0; i < count; i++) { + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + + index = RFIFOL(fd, cursor); + cursor += 4; + + switch (RFIFOB(fd, cursor++)) { + /* int */ + case 0: + inter_savereg(account_id,char_id,key,index,RFIFOL(fd, cursor),false); + cursor += 4; + break; + case 1: + inter_savereg(account_id,char_id,key,index,0,false); + break; + /* str */ + case 2: + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + inter_savereg(account_id,char_id,key,index,(intptr_t)sval,true); + break; + case 3: + inter_savereg(account_id,char_id,key,index,0,true); + break; + + default: + ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1)); + return 1; + } - inter_accreg_tosql(RFIFOL(fd,4),RFIFOL(fd,8),reg, RFIFOB(fd,12)); - mapif_account_reg(fd,RFIFOP(fd,0)); // Send updated accounts to other map servers. + } + + global_accreg_to_login_send(); + } return 0; } |