summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c30
-rw-r--r--src/char/char.h1
-rw-r--r--src/char/inter.c116
-rw-r--r--src/char/inter.h1
-rw-r--r--src/login/login.c40
-rw-r--r--src/map/clif.c11
-rw-r--r--src/map/packets.h3
-rw-r--r--src/map/skill.c6
8 files changed, 137 insertions, 71 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 709148db1..4ea1f8451 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 06c0556c5..372af91f7 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 2c07b20e2..b484a1610 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 249d008ec..252031bb8 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);
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 9fedea85e..2c2ed0d6c 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