From da233d52bba427b42265aeef08605504d51147ea Mon Sep 17 00:00:00 2001 From: Ibrahim Hossam Date: Sun, 2 Feb 2014 14:09:39 +0200 Subject: Update inter server so ask login server for account information Instead of do query to login table. Thanks to Haruna to clean it up. --- src/char/char.c | 30 ++++++++++++++ src/char/char.h | 1 + src/char/inter.c | 116 +++++++++++++++++++++++------------------------------- src/char/inter.h | 1 + src/login/login.c | 40 +++++++++++++++++++ 5 files changed, 121 insertions(+), 67 deletions(-) diff --git a/src/char/char.c b/src/char/char.c index efe02031f..4079e10bb 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2558,6 +2558,26 @@ int parse_fromlogin(int fd) { } break; + case 0x2736: // Failed accinfo lookup to forward to mapserver + if (RFIFOREST(fd) < 18) + return 0; + + mapif_parse_accinfo2(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), + NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, 0, 0); + RFIFOSKIP(fd,18); + break; + + case 0x2737: // Successful accinfo lookup to forward to mapserver + if (RFIFOREST(fd) < 183) + return 0; + + mapif_parse_accinfo2(true, RFIFOL(fd,167), RFIFOL(fd,171), RFIFOL(fd,175), RFIFOL(fd,179), + (char*)RFIFOP(fd,2), (char*)RFIFOP(fd,26), (char*)RFIFOP(fd,59), + (char*)RFIFOP(fd,99), (char*)RFIFOP(fd,119), (char*)RFIFOP(fd,151), + (char*)RFIFOP(fd,156), RFIFOL(fd,115), RFIFOL(fd,143), RFIFOL(fd,147)); + RFIFOSKIP(fd,183); + break; + default: ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command); set_eof(fd); @@ -2852,6 +2872,16 @@ void mapif_on_disconnect(int id) mapif_server_reset(id); } +void mapif_on_parse_accinfo(int account_id, int u_fd, int u_aid, int u_group, int map_fd) { + WFIFOHEAD(login_fd,22); + WFIFOW(login_fd,0) = 0x2740; + WFIFOL(login_fd,2) = account_id; + WFIFOL(login_fd,6) = u_fd; + WFIFOL(login_fd,10) = u_aid; + WFIFOL(login_fd,14) = u_group; + WFIFOL(login_fd,18) = map_fd; + WFIFOSET(login_fd,22); +} int parse_frommap(int fd) { diff --git a/src/char/char.h b/src/char/char.h index 3e3774c1f..1fb3b543f 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -63,6 +63,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit int mapif_sendall(unsigned char *buf,unsigned int len); int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len); int mapif_send(int fd,unsigned char *buf,unsigned int len); +void mapif_on_parse_accinfo(int account_id,int u_fd, int aid, int castergroup, int map_fd); int char_married(int pl1,int pl2); int char_child(int parent_id, int child_id); diff --git a/src/char/inter.c b/src/char/inter.c index 34ecebd36..ff99865f8 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -511,83 +511,65 @@ 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 ); + mapif_on_parse_accinfo(account_id, u_fd, aid, castergroup, fd); + } - 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 ); - } + return; +} +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 - 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 (!success) { + inter_msg_to_fd(map_fd, u_fd, u_aid, "No account with ID '%d' was found.", account_id); + return; + } + 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); - 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 (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 ); + } - 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); - } + 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 --"); + 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 { - 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"); - } + 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); } + SQL->FreeResult(sql_handle); return; } diff --git a/src/char/inter.h b/src/char/inter.h index 9b958dc72..aa47496a1 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -15,6 +15,7 @@ int inter_parse_frommap(int fd); int inter_mapif_init(int fd); int mapif_send_gmaccounts(void); int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason); +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); int inter_log(char *fmt,...); int inter_vlog(char *fmt, va_list ap); diff --git a/src/login/login.c b/src/login/login.c index e9d0eac9d..d427641f5 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -832,6 +832,46 @@ int parse_fromchar(int fd) } break; + case 0x2740: // Accinfo request forwarded by charserver on mapserver's account + if( RFIFOREST(fd) < 22 ) + return 0; + else { + struct mmo_account acc; + int account_id = RFIFOL(fd, 2), u_fd = RFIFOL(fd, 6), u_aid = RFIFOL(fd, 10), u_group = RFIFOL(fd, 14), map_fd = RFIFOL(fd, 18); + if (accounts->load_num(accounts, &acc, account_id)) { + WFIFOHEAD(fd,183); + WFIFOW(fd,0) = 0x2737; + safestrncpy((char*)WFIFOP(fd,2), acc.userid, NAME_LENGTH); + if (u_group >= acc.group_id) { + safestrncpy((char*)WFIFOP(fd,26), acc.pass, 33); + } + safestrncpy((char*)WFIFOP(fd,59), acc.email, 40); + safestrncpy((char*)WFIFOP(fd,99), acc.last_ip, 16); + WFIFOL(fd,115) = acc.group_id; + safestrncpy((char*)WFIFOP(fd,119), acc.lastlogin, 24); + WFIFOL(fd,143) = acc.logincount; + WFIFOL(fd,147) = acc.state; + if (u_group >= acc.group_id) { + safestrncpy((char*)WFIFOP(fd,151), acc.pincode, 5); + } + safestrncpy((char*)WFIFOP(fd,156), acc.birthdate, 11); + WFIFOL(fd,167) = map_fd; + WFIFOL(fd,171) = u_fd; + WFIFOL(fd,175) = u_aid; + WFIFOL(fd,179) = account_id; + WFIFOSET(fd,183); + } else { + WFIFOHEAD(fd,18); + WFIFOW(fd,0) = 0x2736; + WFIFOL(fd,2) = map_fd; + WFIFOL(fd,6) = u_fd; + WFIFOL(fd,10) = u_aid; + WFIFOL(fd,14) = account_id; + WFIFOSET(fd,18); + } + RFIFOSKIP(fd,22); + } + break; default: ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command); set_eof(fd); -- cgit v1.2.3-60-g2f50 From 537e621b81b8fdd8763342703083c1abcfb3cc3a Mon Sep 17 00:00:00 2001 From: malufett Date: Tue, 11 Feb 2014 01:18:22 +0800 Subject: Fixed Bug#7983 (Thanks to Kiu) -http://hercules.ws/board/tracker/issue-7983-whisper-display Fixed Bug#8012 -http://hercules.ws/board/tracker/issue-8012-bonus-bvariablecastrate-and-bfixedcastrate-not-working-properly/ Signed-off-by: malufett --- src/map/clif.c | 11 ++++++++--- src/map/packets.h | 3 ++- src/map/skill.c | 6 ++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 5dacf6360..15b546cc5 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5897,10 +5897,15 @@ void clif_wis_message(int fd, const char* nick, const char* mes, size_t mes_len) /// 3 = everyone ignored by target void clif_wis_end(int fd, int flag) { - WFIFOHEAD(fd,packet_len(0x98)); - WFIFOW(fd,0) = 0x98; +#if PACKETVER >= 20131223 + const int cmd = 0x9df; +#else + const int cmd = 0x98; +#endif + WFIFOHEAD(fd,packet_len(cmd)); + WFIFOW(fd,0) = cmd; WFIFOW(fd,2) = flag; - WFIFOSET(fd,packet_len(0x98)); + WFIFOSET(fd,packet_len(cmd)); } diff --git a/src/map/packets.h b/src/map/packets.h index 4cf6f6d6a..3ff202bae 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2415,7 +2415,7 @@ packet(0x020d,-1); packet(0x0873,36,clif->pStoragePassword,0); packet(0x097C,4,clif->pRanklist); #endif - + //2013-08-07Ragexe (Shakto) #if PACKETVER >= 20130807 packet(0x0369,7,clif->pActionRequest,2,6); @@ -2490,6 +2490,7 @@ packet(0x020d,-1); /* NPC Market */ packet(0x09d8,2,clif->pNPCMarketClosed); packet(0x09d6,-1,clif->pNPCMarketPurchase); + packet(0x09df,7); #endif /* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ diff --git a/src/map/skill.c b/src/map/skill.c index a66ead4ae..d336d165e 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -14012,6 +14012,12 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 if( sd && !(skill->get_castnodex(skill_id, skill_lv)&4) ){ VARCAST_REDUCTION( max(sd->bonus.varcastrate, 0) + max(i, 0) ); fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0); + for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ ) + if( sd->skillcast[i].id == skill_id ){ // bonus2 bVariableCastrate + if( (i=sd->skillcast[i].val) > 0) + VARCAST_REDUCTION(i); + break; + } } if( varcast_r < 0 ) // now compute overall factors -- cgit v1.2.3-60-g2f50