From 16d301eb02e84f03df387db15750e4cb52beaf9f Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 24 Nov 2006 12:41:38 +0000 Subject: - Added all the missing FIFOHEADs in the login/sql servers (required for TURBO support) - Fixed the fact that the TURBO code breaks when you attempt to handle more than one connection at a time within the same function. However this broke map-server compilation, therefore, don't use TURBO yet! It needs more fixing (and I need more time to fix it) - While at it, cleaned a few packet implementations in the char/login servers which were not only ugly, but had some really stupid flaws within (stuff like escaping a string, and then using the non-escaped variable to insert to SQL? T_T) And will someone explain me why the TXT servers are coded much more cleanly, and without such horribly broken code as I find in the SQL ones? T_T; git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9307 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 7 ++ Makefile | 1 + src/char/char.c | 159 ++++++++++++----------- src/char_sql/char.c | 306 ++++++++++++++++++++++++--------------------- src/char_sql/int_guild.c | 5 +- src/char_sql/int_homun.c | 14 ++- src/char_sql/int_party.c | 2 + src/char_sql/int_pet.c | 16 ++- src/char_sql/int_storage.c | 22 +++- src/char_sql/inter.c | 47 ++++--- src/common/socket.c | 1 - src/common/socket.h | 8 +- src/login/login.c | 4 +- src/login_sql/login.c | 72 +++++++---- src/map/clif.c | 212 ++++++++++++++----------------- src/map/mercenary.c | 8 +- src/map/mob.c | 2 +- 17 files changed, 495 insertions(+), 391 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index d1095b76e..1aa4e2b39 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,13 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2006/11/24 + * Fixed the fact that the TURBO code breaks when you attempt to handle more + than one connection at a time within the same function. However this broke + map-server compilation, therefore, don't use TURBO yet! [Skotlex] + * While at it, cleaned a few packet implementations in the char/login + servers which were not only ugly, but had some really stupid flaws within. + [Skotlex] 2006/11/23 * Completed Reddozen's hanging mapwarp code to support party and old syntax. [Lance] * Updated sql files [Playtester] diff --git a/Makefile b/Makefile index 3102d2644..75ddf6689 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ OPT += -Wall -Wno-sign-compare # Makes map-wide script variables be saved to SQL instead of TXT files. # OPT += -DMAPREGSQL # Turbo is an alternate socket access implementation which should be faster. +# DO NOT ENABLE YET as it isn't quite ready for general usage. # OPT += -DTURBO # Enable the perl regular expression support for scripts # OPT += -DPCRE_SUPPORT diff --git a/src/char/char.c b/src/char/char.c index b043809aa..e57b0bd20 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1995,7 +1995,7 @@ int parse_tologin(int fd) { } else { // refuse connection: too much online players // printf("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user); - WFIFOHEAD(fd, 3); + WFIFOHEAD(i, 3); WFIFOW(i,0) = 0x6c; WFIFOW(i,2) = 0; WFIFOSET(i,3); @@ -2403,7 +2403,7 @@ int parse_tologin(int fd) { for(i = 0; i < fd_max; i++) { if (session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid) { - WFIFOHEAD(fd, 3); + WFIFOHEAD(i, 3); WFIFOW(i,0) = 0x81; WFIFOB(i,2) = 2; WFIFOSET(i,3); @@ -2502,7 +2502,7 @@ int char_parse_Registry(int account_id, int char_id, unsigned char *buf, int buf //Reply to map server with acc reg values. int char_account_reg_reply(int fd,int account_id,int char_id) { int i,j,p; - WFIFOHEAD(login_fd, GLOBAL_REG_NUM*288 + 13); + WFIFOHEAD(fd, GLOBAL_REG_NUM*288 + 13); WFIFOW(fd,0)=0x3804; WFIFOL(fd,4)=account_id; WFIFOL(fd,8)=char_id; @@ -2894,6 +2894,7 @@ int parse_frommap(int fd) { if (map_fd>=0 && session[map_fd] && char_data) { //Send the map server the auth of this player. //Update the "last map" as this is where the player must be spawned on the new map server. + WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus)); char_data->last_point.map = RFIFOW(fd,18); char_data->last_point.x = RFIFOW(fd,20); char_data->last_point.y = RFIFOW(fd,22); @@ -2949,10 +2950,12 @@ int parse_frommap(int fd) { return 0; // printf("parse_frommap: change gm -> login, account: %d, pass: '%s'.\n", RFIFOL(fd,4), RFIFOP(fd,8)); if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, RFIFOW(fd,2)); WFIFOW(login_fd,0) = 0x2720; memcpy(WFIFOP(login_fd,2), RFIFOP(fd,2), RFIFOW(fd,2)-2); WFIFOSET(login_fd, RFIFOW(fd,2)); } else { + WFIFOHEAD(fd, 10); WFIFOW(fd,0) = 0x2b0b; WFIFOL(fd,2) = RFIFOL(fd,4); WFIFOL(fd,6) = 0; @@ -2966,6 +2969,7 @@ int parse_frommap(int fd) { if (RFIFOREST(fd) < 86) return 0; if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 86); memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), 86); // 0x2722 .L .40B .40B WFIFOW(login_fd,0) = 0x2722; WFIFOSET(login_fd, 86); @@ -2996,6 +3000,7 @@ int parse_frommap(int fd) { case 1: // block if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 10); WFIFOW(login_fd,0) = 0x2724; WFIFOL(login_fd,2) = char_dat[i].status.account_id; // account value WFIFOL(login_fd,6) = 5; // status of the account @@ -3009,6 +3014,7 @@ int parse_frommap(int fd) { case 2: // ban if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd,18); WFIFOW(login_fd, 0) = 0x2725; WFIFOL(login_fd, 2) = char_dat[i].status.account_id; // account value WFIFOW(login_fd, 6) = RFIFOW(fd,32); // year @@ -3028,6 +3034,7 @@ int parse_frommap(int fd) { case 3: // unblock if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 10); WFIFOW(login_fd,0) = 0x2724; WFIFOL(login_fd,2) = char_dat[i].status.account_id; // account value WFIFOL(login_fd,6) = 0; // status of the account @@ -3041,6 +3048,7 @@ int parse_frommap(int fd) { case 4: // unban if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 6); WFIFOW(login_fd, 0) = 0x272a; WFIFOL(login_fd, 2) = char_dat[i].status.account_id; // account value WFIFOSET(login_fd, 6); @@ -3053,6 +3061,7 @@ int parse_frommap(int fd) { case 5: // changesex if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 6); WFIFOW(login_fd, 0) = 0x2727; WFIFOL(login_fd, 2) = char_dat[i].status.account_id; // account value WFIFOSET(login_fd, 6); @@ -3341,29 +3350,26 @@ int parse_char(int fd) { return 0; { int GM_value; - if ((GM_value = isGM(RFIFOL(fd,2)))) - ShowInfo("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), GM_value); - else - ShowInfo("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2)); - if (sd == NULL) { - sd = (struct char_session_data*)aCalloc(sizeof(struct char_session_data), 1); - session[fd]->session_data = sd; - -// memset(sd, 0, sizeof(struct char_session_data)); aCalloc does this [Skotlex] - strncpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail - sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server) - } else { + WFIFOHEAD(fd, 4); + if (sd) { //Received again auth packet for already authentified account?? Discard it. //TODO: Perhaps log this as a hack attempt? RFIFOSKIP(fd,17); break; } + if ((GM_value = isGM(RFIFOL(fd,2)))) + ShowInfo("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), GM_value); + else + ShowInfo("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2)); + sd = (struct char_session_data*)aCalloc(sizeof(struct char_session_data), 1); + session[fd]->session_data = sd; + strncpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail + sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server) sd->account_id = RFIFOL(fd,2); sd->login_id1 = RFIFOL(fd,6); sd->login_id2 = RFIFOL(fd,10); sd->sex = RFIFOB(fd,16); // send back account_id - WFIFOHEAD(fd, 4); WFIFOL(fd,0) = RFIFOL(fd,2); WFIFOSET(fd,4); // search authentification @@ -3417,6 +3423,7 @@ int parse_char(int fd) { if (max_connect_user == 0 || count_users() < max_connect_user) { if (login_fd > 0) { // don't send request if no login-server // request to login-server to obtain e-mail/time limit + WFIFOHEAD(login_fd, 6); WFIFOW(login_fd,0) = 0x2716; WFIFOL(login_fd,2) = sd->account_id; WFIFOSET(login_fd,6); @@ -3435,6 +3442,7 @@ int parse_char(int fd) { // authentification not found if (i == AUTH_FIFO_SIZE) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd,19); WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account WFIFOL(login_fd,2) = sd->account_id; WFIFOL(login_fd,6) = sd->login_id1; @@ -3443,6 +3451,7 @@ int parse_char(int fd) { WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr; WFIFOSET(login_fd,19); } else { // if no login-server, we must refuse connection + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x6c; WFIFOW(fd,2) = 0; WFIFOSET(fd,3); @@ -3527,20 +3536,24 @@ int parse_char(int fd) { ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j)); cd->last_point.map = j; } - WFIFOHEAD(fd, 28); - WFIFOW(fd,0) = 0x71; - WFIFOL(fd,2) = cd->char_id; - memcpy(WFIFOP(fd,6), mapindex_id2name(cd->last_point.map), MAP_NAME_LENGTH); - ShowInfo("Character selection '%s' (account: %d, slot: %d).\n", cd->name, sd->account_id, ch); + { //Send player to map + WFIFOHEAD(fd, 28); + WFIFOW(fd,0) = 0x71; + WFIFOL(fd,2) = cd->char_id; + memcpy(WFIFOP(fd,6), mapindex_id2name(cd->last_point.map), MAP_NAME_LENGTH); - // Advanced subnet check [LuzZza] - if((subnet_map_ip = lan_subnetcheck((long *)p))) - WFIFOL(fd,22) = subnet_map_ip; - else - WFIFOL(fd,22) = server[i].ip; + // Advanced subnet check [LuzZza] + if((subnet_map_ip = lan_subnetcheck((long *)p))) + WFIFOL(fd,22) = subnet_map_ip; + else + WFIFOL(fd,22) = server[i].ip; + + WFIFOW(fd,26) = server[i].port; + WFIFOSET(fd,28); - WFIFOW(fd,26) = server[i].port; - WFIFOSET(fd,28); + ShowInfo("Character selection '%s' (account: %d, slot: %d).\n", + cd->name, sd->account_id, ch); + } if (auth_fifo_pos >= AUTH_FIFO_SIZE) auth_fifo_pos = 0; auth_fifo[auth_fifo_pos].account_id = sd->account_id; @@ -3556,6 +3569,7 @@ int parse_char(int fd) { //Send NEW auth packet [Kevin] if ((map_fd = server_fd[i]) < 1 || session[map_fd] == NULL) { //0 Should not be a valid server_fd [Skotlex] + WFIFOHEAD(fd, 3); ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i); server_fd[i] = -1; memset(&server[i], 0, sizeof(struct mmo_map_server)); @@ -3565,15 +3579,17 @@ int parse_char(int fd) { WFIFOSET(fd,3); break; } - WFIFOW(map_fd,0) = 0x2afd; - WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus); - WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id; - WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1; - WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2; - WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time; - memcpy(WFIFOP(map_fd,20), cd, sizeof(struct mmo_charstatus)); - WFIFOSET(map_fd, WFIFOW(map_fd,2)); - + { //Send auth to server. + WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus)); + WFIFOW(map_fd,0) = 0x2afd; + WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus); + WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id; + WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1; + WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2; + WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time; + memcpy(WFIFOP(map_fd,20), cd, sizeof(struct mmo_charstatus)); + WFIFOSET(map_fd, WFIFOW(map_fd,2)); + } set_char_online(i, cd->char_id, cd->account_id); //Sets char online in the party and breaks even share if needed. inter_party_logged(cd->party_id, cd->account_id, cd->char_id); @@ -3589,34 +3605,22 @@ int parse_char(int fd) { i = -2; else i = make_new_char(fd, RFIFOP(fd,2)); - - if(i == -1){ //added some better faile reporting to client on the txt version [Kevin] - //already exists - WFIFOHEAD(fd, 3); - WFIFOW(fd, 0) = 0x6e; - WFIFOB(fd, 2) = 0x00; - WFIFOSET(fd, 3); - RFIFOSKIP(fd, 37); - break; - }else if(i == -2){ - //denied - WFIFOHEAD(fd, 3); - WFIFOW(fd, 0) = 0x6e; - WFIFOB(fd, 2) = 0x02; - WFIFOSET(fd, 3); - RFIFOSKIP(fd, 37); - break; - }else if(i == -3){ - //underaged XD - WFIFOHEAD(fd, 3); - WFIFOW(fd, 0) = 0x6e; - WFIFOB(fd, 2) = 0x01; - WFIFOSET(fd, 3); - RFIFOSKIP(fd, 37); - break; - } - - WFIFOHEAD(fd, 108); + //added some better fail reporting to client on the txt version [Kevin] + if (i < 0) + { + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x6e; + switch (i) { + case -1: WFIFOB(fd, 2) = 0x00; break; + case -2: WFIFOB(fd, 2) = 0x02; break; + case -3: WFIFOB(fd, 2) = 0x01; break; + } + WFIFOSET(fd, 3); + RFIFOSKIP(fd, 37); + break; + } + { //Send to player. + WFIFOHEAD(fd, 108); WFIFOW(fd,0) = 0x6d; memset(WFIFOP(fd,2), 0, 106); @@ -3658,6 +3662,7 @@ int parse_char(int fd) { WFIFOSET(fd,108); RFIFOSKIP(fd,37); + } for(ch = 0; ch < 9; ch++) { if (sd->found_char[ch] == -1) { sd->found_char[ch] = i; @@ -3667,7 +3672,9 @@ int parse_char(int fd) { case 0x68: // delete char //Yor's Fix FIFOSD_CHECK(46); - + { + WFIFOHEAD(fd, 46); + WFIFOHEAD(login_fd,46); memcpy(email, RFIFOP(fd,6), 40); if (e_mail_check(email) == 0) strncpy(email, "a@a.com", 40); // default e-mail @@ -3760,17 +3767,26 @@ int parse_char(int fd) { } RFIFOSKIP(fd,46); } + } break; case 0x2af8: // マップサーバーログイン if (RFIFOREST(fd) < 60) return 0; + { + char *l_user = RFIFOP(fd, 2); + char *l_pass = RFIFOP(fd, 26); + WFIFOHEAD(fd, 4+5*GM_num); + l_user[23] = '\0'; + l_pass[23] = '\0'; WFIFOW(fd,0) = 0x2af9; for(i = 0; i < MAX_MAP_SERVERS; i++) { if (server_fd[i] < 0) break; } - if (i == MAX_MAP_SERVERS || strcmp((char*)RFIFOP(fd,2), userid) || strcmp((char*)RFIFOP(fd,26), passwd)){ + if (i == MAX_MAP_SERVERS || + strcmp(l_user, userid) || + strcmp(l_pass, passwd)){ WFIFOB(fd,2) = 3; WFIFOSET(fd,3); RFIFOSKIP(fd,60); @@ -3799,6 +3815,7 @@ int parse_char(int fd) { WFIFOSET(fd,len); return 0; } + } break; case 0x187: // Alive信号? @@ -3808,6 +3825,8 @@ int parse_char(int fd) { break; case 0x7530: // Athena情報所得 + { + WFIFOHEAD(fd, 10); WFIFOW(fd,0) = 0x7531; WFIFOB(fd,2) = ATHENA_MAJOR_VERSION; WFIFOB(fd,3) = ATHENA_MINOR_VERSION; @@ -3819,7 +3838,7 @@ int parse_char(int fd) { WFIFOSET(fd,10); RFIFOSKIP(fd,2); return 0; - + } case 0x7532: // 接続の切断(defaultと処理は一緒だが明示的にするため) default: session[fd]->eof = 1; @@ -3862,6 +3881,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len) { for(i = 0; i < MAX_MAP_SERVERS; i++) { int fd; if ((fd = server_fd[i]) >= 0) { +#if 0 //This seems to have been fixed long long ago. if (session[fd] == NULL) { //Could this be the crash's source? [Skotlex] ShowError("mapif_sendall: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", fd, i); @@ -3869,9 +3889,8 @@ int mapif_sendall(unsigned char *buf, unsigned int len) { memset(&server[i], 0, sizeof(struct mmo_map_server)); continue; } +#endif WFIFOHEAD(fd, len); - if (WFIFOSPACE(fd) < len) //Increase buffer size. - realloc_writefifo(fd, len); memcpy(WFIFOP(fd,0), buf, len); WFIFOSET(fd,len); c++; diff --git a/src/char_sql/char.c b/src/char_sql/char.c index b2395623b..8fb53945d 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -249,12 +249,13 @@ void set_char_online(int map_id, int char_id, int account_id) { cp = idb_get(char_db_,char_id); inter_guild_CharOnline(char_id, cp?cp->guild_id:-1); } - if (login_fd <= 0 || session[login_fd]->eof) - return; - - WFIFOW(login_fd,0) = 0x272b; - WFIFOL(login_fd,2) = account_id; - WFIFOSET(login_fd,6); + if (login_fd > 0 && !session[login_fd]->eof) + { + WFIFOHEAD(login_fd,6); + WFIFOW(login_fd,0) = 0x272b; + WFIFOL(login_fd,2) = account_id; + WFIFOSET(login_fd,6); + } } void set_char_offline(int char_id, int account_id) { @@ -285,12 +286,13 @@ void set_char_offline(int char_id, int account_id) { character->waiting_disconnect = 0; } - if (login_fd <= 0 || session[login_fd]->eof) - return; - - WFIFOW(login_fd,0) = 0x272c; - WFIFOL(login_fd,2) = account_id; - WFIFOSET(login_fd,6); + if (login_fd > 0 && !session[login_fd]->eof) + { + WFIFOHEAD(login_fd,6); + WFIFOW(login_fd,0) = 0x272c; + WFIFOL(login_fd,2) = account_id; + WFIFOSET(login_fd,6); + } } static int char_db_setoffline(DBKey key, void* data, va_list ap) { @@ -1674,18 +1676,10 @@ int count_users(void) { int mmo_char_send006b(int fd, struct char_session_data *sd) { int i, j, found_num = 0; struct mmo_charstatus *p = NULL; -// hehe. commented other. anyway there's no need to use older version. -// if use older packet version just uncomment that! -//#ifdef NEW_006b const int offset = 24; -//#else -// int offset = 4; -//#endif - -// ShowDebug("mmo_char_send006b start.. (account:%d)\n",sd->account_id); -// printf("offset -> %d...\n",offset); - - set_char_online(-1, 99,sd->account_id); + WFIFOHEAD(fd, offset +9*106); + + set_char_online(-1, 99,sd->account_id); //search char. sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id` = '%d'",char_db, sd->account_id); @@ -1705,8 +1699,6 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { mysql_free_result(sql_res); } -// printf("char fetching end (total: %d)....\n", found_num); - for(i = found_num; i < 9; i++) sd->found_char[i] = -1; @@ -1776,7 +1768,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, int data); int parse_tologin(int fd) { int i; struct char_session_data *sd; - + RFIFOHEAD(fd); // only login-server can have an access to here. // so, if it isn't the login-server, we disconnect the session. //session eof check! @@ -1831,6 +1823,7 @@ int parse_tologin(int fd) { return 0; for(i = 0; i < fd_max; i++) { if (session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) { + WFIFOHEAD(i,3); if (RFIFOB(fd,6) != 0) { WFIFOW(i,0) = 0x6c; WFIFOB(i,2) = 0x42; @@ -2160,6 +2153,7 @@ int parse_tologin(int fd) { for(i = 0; i < fd_max; i++) { if (session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid) { + WFIFOHEAD(i,3); WFIFOW(i,0) = 0x81; WFIFOB(i,2) = 2; WFIFOSET(i,3); @@ -2192,6 +2186,7 @@ int parse_tologin(int fd) { { //Update ip. char_ip = new_ip; ShowInfo("Updating IP for [%s].\n",char_ip_str); + WFIFOHEAD(fd,6); WFIFOW(fd,0) = 0x2736; WFIFOL(fd,2) = char_ip; WFIFOSET(fd,6); @@ -2212,6 +2207,7 @@ int parse_tologin(int fd) { int request_accreg2(int account_id, int char_id) { if (login_fd > 0) { + WFIFOHEAD(login_fd, 10); WFIFOW(login_fd, 0) = 0x272e; WFIFOL(login_fd, 2) = account_id; WFIFOL(login_fd, 6) = char_id; @@ -2368,7 +2364,7 @@ int char_loadName(int char_id, char* name) int parse_frommap(int fd) { int i = 0, j = 0; int id; -// int auth_fifo_flag=0; + RFIFOHEAD(fd); // Sometimes fd=0, and it will cause server crash. Don't know why. :( if (fd <= 0) { @@ -2411,8 +2407,6 @@ int parse_frommap(int fd) { } while(RFIFOREST(fd) >= 2 && !session[fd]->eof) { - //ShowDebug("Received packet 0x%4x (%d bytes) from map-server (connection %d)\n", RFIFOW(fd, 0), RFIFOREST(fd), fd); - switch(RFIFOW(fd, 0)) { // map-server alive packet @@ -2426,6 +2420,7 @@ int parse_frommap(int fd) { read_gm_account(); //Send to login request to reload gm accounts. else if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 2); WFIFOW(login_fd,0) = 0x2709; WFIFOSET(login_fd, 2); } @@ -2435,61 +2430,64 @@ int parse_frommap(int fd) { case 0x2afa: if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; + { + unsigned char *p = (unsigned char *)&server[id].ip; + unsigned char buf[16384]; + int x; + WFIFOHEAD(fd,3+NAME_LENGTH); + memset(server[id].map, 0, sizeof(server[id].map)); j = 0; for(i = 4; i < RFIFOW(fd,2); i += 4) { server[id].map[j] = RFIFOW(fd,i); -// printf("set map %d.%d : %s\n", id, j, server[id].map[j]); j++; } - i = server[id].ip; - { - unsigned char *p = (unsigned char *)&server[id].ip; - ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n", - id, j, p[0], p[1], p[2], p[3], server[id].port); - ShowStatus("Map-server %d loading complete.\n", id); - - if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID) - mapif_send_maxid(max_account_id, max_char_id); //Send the current max ids to the server to keep in sync [Skotlex] - } + + ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n", + id, j, p[0], p[1], p[2], p[3], server[id].port); + ShowStatus("Map-server %d loading complete.\n", id); + + if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID) + mapif_send_maxid(max_account_id, max_char_id); //Send the current max ids to the server to keep in sync [Skotlex] + WFIFOW(fd,0) = 0x2afb; WFIFOB(fd,2) = 0; - memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); // name for wisp to player + // name for wisp to player + memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); WFIFOSET(fd,3+NAME_LENGTH); + char_send_fame_list(fd); //Send fame list. - //WFIFOSET(fd,27); - { - unsigned char buf[16384]; - int x; - if (j == 0) { - ShowWarning("Map-Server %d have NO maps.\n", id); + + if (j == 0) + ShowWarning("Map-Server %d have NO maps.\n", id); + else { // Transmitting maps information to the other map-servers - } else { - WBUFW(buf,0) = 0x2b04; - WBUFW(buf,2) = j * 4 + 10; - WBUFL(buf,4) = server[id].ip; - WBUFW(buf,8) = server[id].port; - memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4); - mapif_sendallwos(fd, buf, WBUFW(buf,2)); - } - // Transmitting the maps of the other map-servers to the new map-server - for(x = 0; x < MAX_MAP_SERVERS; x++) { - if (server_fd[x] > 0 && x != id) { - WFIFOW(fd,0) = 0x2b04; - WFIFOL(fd,4) = server[x].ip; - WFIFOW(fd,8) = server[x].port; - j = 0; - for(i = 0; i < MAX_MAP_PER_SERVER; i++) - if (server[x].map[i]) - WFIFOW(fd,10+(j++)*4) = server[x].map[i]; - if (j > 0) { - WFIFOW(fd,2) = j * 4 + 10; - WFIFOSET(fd,WFIFOW(fd,2)); - } + WBUFW(buf,0) = 0x2b04; + WBUFW(buf,2) = j * 4 + 10; + WBUFL(buf,4) = server[id].ip; + WBUFW(buf,8) = server[id].port; + memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4); + mapif_sendallwos(fd, buf, WBUFW(buf,2)); + } + // Transmitting the maps of the other map-servers to the new map-server + for(x = 0; x < MAX_MAP_SERVERS; x++) { + if (server_fd[x] > 0 && x != id) { + WFIFOHEAD(fd, 10 +4*MAX_MAP_PER_SERVER); + WFIFOW(fd,0) = 0x2b04; + WFIFOL(fd,4) = server[x].ip; + WFIFOW(fd,8) = server[x].port; + j = 0; + for(i = 0; i < MAX_MAP_PER_SERVER; i++) + if (server[x].map[i]) + WFIFOW(fd,10+(j++)*4) = server[x].map[i]; + if (j > 0) { + WFIFOW(fd,2) = j * 4 + 10; + WFIFOSET(fd,WFIFOW(fd,2)); } } } RFIFOSKIP(fd,RFIFOW(fd,2)); + } break; //Packet command is now used for sc_data request. [Skotlex] case 0x2afc: @@ -2512,10 +2510,11 @@ int parse_frommap(int fd) { if (sql_res) { struct status_change_data data; int count = 0; + WFIFOHEAD(fd, 14+50*sizeof(struct status_change_data)); WFIFOW(fd, 0) = 0x2b1d; WFIFOL(fd, 4) = aid; WFIFOL(fd, 8) = cid; - while((sql_row = mysql_fetch_row(sql_res))) + while((sql_row = mysql_fetch_row(sql_res)) && count < 50) { data.type = atoi(sql_row[0]); data.tick = atoi(sql_row[1]); @@ -2526,6 +2525,8 @@ int parse_frommap(int fd) { memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &data, sizeof(struct status_change_data)); count++; } + if (count >= 50) + ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid); mysql_free_result(sql_res); if (count > 0) { @@ -2610,6 +2611,7 @@ int parse_frommap(int fd) { if (RFIFOB(fd,12)) { //Flag? Set character offline after saving [Skotlex] set_char_offline(cid, aid); + WFIFOHEAD(fd, 10); WFIFOW(fd, 0) = 0x2b21; //Save ack only needed on final save. WFIFOL(fd, 2) = aid; WFIFOL(fd, 6) = cid; @@ -2635,12 +2637,13 @@ int parse_frommap(int fd) { auth_fifo[auth_fifo_pos].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server) auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,14); auth_fifo_pos++; - + { + WFIFOHEAD(fd, 7); WFIFOW(fd, 0) = 0x2b03; WFIFOL(fd, 2) = RFIFOL(fd, 2); WFIFOB(fd, 6) = 0; WFIFOSET(fd, 7); - + } RFIFOSKIP(fd, 18); break; @@ -2653,8 +2656,6 @@ int parse_frommap(int fd) { int map_id, map_fd = -1; struct online_char_data* data; struct mmo_charstatus* char_data; - - name = RFIFOW(fd,18); map_id = search_mapserver(name, RFIFOL(fd,24), RFIFOW(fd,28)); //Locate mapserver by ip and port. if (map_id >= 0) @@ -2670,6 +2671,8 @@ int parse_frommap(int fd) { if (map_fd>=0 && session[map_fd] && char_data) { //Send the map server the auth of this player. //Update the "last map" as this is where the player must be spawned on the new map server. + WFIFOHEAD(fd, 30); + WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus)); char_data->last_point.map = RFIFOW(fd,18); char_data->last_point.x = RFIFOW(fd,20); char_data->last_point.y = RFIFOW(fd,22); @@ -2692,6 +2695,7 @@ int parse_frommap(int fd) { memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28); WFIFOSET(fd, 30); } else { //Reply with nak + WFIFOHEAD(fd, 30); WFIFOW(fd, 0) = 0x2b06; memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28); WFIFOL(fd, 6) = 0; //Set login1 to 0. @@ -2707,6 +2711,7 @@ int parse_frommap(int fd) { return 0; { char name[NAME_LENGTH]; + WFIFOHEAD(fd,30); char_loadName((int)RFIFOL(fd,2), name); WFIFOW(fd,0) = 0x2b09; WFIFOL(fd,2) = RFIFOL(fd,2); @@ -2737,6 +2742,7 @@ int parse_frommap(int fd) { if (RFIFOREST(fd) < 86) return 0; if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 86); memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), 86); // 0x2722 .L .40B .40B WFIFOW(login_fd,0) = 0x2722; WFIFOSET(login_fd, 86); @@ -2751,6 +2757,7 @@ int parse_frommap(int fd) { { char character_name[NAME_LENGTH], t_name[NAME_LENGTH*2]; int acc = RFIFOL(fd,2); // account_id of who ask (-1 if nobody) + WFIFOHEAD(fd, 34); memcpy(character_name, RFIFOP(fd,6), NAME_LENGTH); character_name[NAME_LENGTH-1] = '\0'; jstrescapecpy(t_name, character_name); //Escape string for sql use... [Skotlex] @@ -2776,6 +2783,7 @@ int parse_frommap(int fd) { case 1: // block if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 10); WFIFOW(login_fd,0) = 0x2724; WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value WFIFOL(login_fd,6) = 5; // status of the account @@ -2788,6 +2796,7 @@ int parse_frommap(int fd) { case 2: // ban if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 18); WFIFOW(login_fd, 0) = 0x2725; WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value WFIFOW(login_fd, 6) = RFIFOW(fd,32); // year @@ -2805,6 +2814,7 @@ int parse_frommap(int fd) { case 3: // unblock if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 10); WFIFOW(login_fd,0) = 0x2724; WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value WFIFOL(login_fd,6) = 0; // status of the account @@ -2817,6 +2827,7 @@ int parse_frommap(int fd) { case 4: // unban if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 6); WFIFOW(login_fd, 0) = 0x272a; WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value WFIFOSET(login_fd, 6); @@ -2828,6 +2839,7 @@ int parse_frommap(int fd) { case 5: // changesex if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd, 6); WFIFOW(login_fd, 0) = 0x2727; WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value WFIFOSET(login_fd, 6); @@ -3086,6 +3098,7 @@ int parse_char(int fd) { struct char_session_data *sd; unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr; long subnet_map_ip; + RFIFOHEAD(fd); sd = (struct char_session_data*)session[fd]->session_data; @@ -3134,17 +3147,17 @@ int parse_char(int fd) { if (RFIFOREST(fd) < 17) return 0; { - if (sd == NULL) { - CREATE(session[fd]->session_data, struct char_session_data, 1); - sd = (struct char_session_data*)session[fd]->session_data; - sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server) - } else { + WFIFOHEAD(fd, 4); + + if (sd) { //Received again auth packet for already authentified account?? Discard it. //TODO: Perhaps log this as a hack attempt? RFIFOSKIP(fd,17); break; } - + CREATE(session[fd]->session_data, struct char_session_data, 1); + sd = (struct char_session_data*)session[fd]->session_data; + sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server) sd->account_id = RFIFOL(fd, 2); sd->login_id1 = RFIFOL(fd, 6); sd->login_id2 = RFIFOL(fd, 10); @@ -3203,6 +3216,7 @@ int parse_char(int fd) { if (max_connect_user == 0 || count_users() < max_connect_user) { if (login_fd > 0) { // don't send request if no login-server // request to login-server to obtain e-mail/time limit + WFIFOHEAD(login_fd, 6); WFIFOW(login_fd,0) = 0x2716; WFIFOL(login_fd,2) = sd->account_id; WFIFOSET(login_fd,6); @@ -3221,6 +3235,7 @@ int parse_char(int fd) { } if (i == AUTH_FIFO_SIZE) { if (login_fd > 0) { // don't send request if no login-server + WFIFOHEAD(login_fd,19); WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account WFIFOL(login_fd,2) = sd->account_id; WFIFOL(login_fd,6) = sd->login_id1; @@ -3229,6 +3244,7 @@ int parse_char(int fd) { WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr; WFIFOSET(login_fd,19); } else { // if no login-server, we must refuse connection + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x6c; WFIFOB(fd,2) = 0; WFIFOSET(fd,3); @@ -3311,6 +3327,7 @@ int parse_char(int fd) { char_dat.last_point.y = 103; } else { ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(char_dat.last_point.map)); + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 1; // 01 = Server closed WFIFOSET(fd,3); @@ -3319,18 +3336,21 @@ int parse_char(int fd) { ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(char_dat.last_point.map), mapindex_id2name(j)); char_dat.last_point.map = j; } - WFIFOW(fd, 0) =0x71; - WFIFOL(fd, 2) =char_dat.char_id; - memcpy(WFIFOP(fd,6), mapindex_id2name(char_dat.last_point.map), MAP_NAME_LENGTH); - - // Andvanced subnet check [LuzZza] - if((subnet_map_ip = lan_subnetcheck((long *)p))) - WFIFOL(fd,22) = subnet_map_ip; - else - WFIFOL(fd,22) = server[i].ip; - - WFIFOW(fd,26) = server[i].port; - WFIFOSET(fd,28); + { //Send player to map. + WFIFOHEAD(fd,28); + WFIFOW(fd, 0) =0x71; + WFIFOL(fd, 2) =char_dat.char_id; + memcpy(WFIFOP(fd,6), mapindex_id2name(char_dat.last_point.map), MAP_NAME_LENGTH); + + // Advanced subnet check [LuzZza] + if((subnet_map_ip = lan_subnetcheck((long *)p))) + WFIFOL(fd,22) = subnet_map_ip; + else + WFIFOL(fd,22) = server[i].ip; + + WFIFOW(fd,26) = server[i].port; + WFIFOSET(fd,28); + } if (auth_fifo_pos >= AUTH_FIFO_SIZE) { auth_fifo_pos = 0; } @@ -3352,15 +3372,17 @@ int parse_char(int fd) { memset(&server[i], 0, sizeof(struct mmo_map_server)); break; } - - WFIFOW(map_fd,0) = 0x2afd; - WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus); - WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id; - WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1; - WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2; - WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time; - memcpy(WFIFOP(map_fd,20), &char_dat, sizeof(struct mmo_charstatus)); - WFIFOSET(map_fd, WFIFOW(map_fd,2)); + { //Send auth ok to map server + WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus)); + WFIFOW(map_fd,0) = 0x2afd; + WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus); + WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id; + WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1; + WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2; + WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time; + memcpy(WFIFOP(map_fd,20), &char_dat, sizeof(struct mmo_charstatus)); + WFIFOSET(map_fd, WFIFOW(map_fd,2)); + } set_char_online(i, auth_fifo[auth_fifo_pos].char_id, auth_fifo[auth_fifo_pos].account_id); //Checks to see if the even share setting of the party must be broken. @@ -3376,38 +3398,23 @@ int parse_char(int fd) { else i = make_new_char_sql(fd, RFIFOP(fd, 2)); - //if (i < 0) { - // WFIFOW(fd, 0) = 0x6e; - // WFIFOB(fd, 2) = 0x00; - // WFIFOSET(fd, 3); - // RFIFOSKIP(fd, 37); - // break; - //} - //Changed that we can support 'Charname already exists' (-1) amd 'Char creation denied' (-2) + //'Charname already exists' (-1), 'Char creation denied' (-2) //And 'You are underaged' (-3) (XD) [Sirius] - if(i == -1){ - //already exists - WFIFOW(fd, 0) = 0x6e; - WFIFOB(fd, 2) = 0x00; - WFIFOSET(fd, 3); - RFIFOSKIP(fd, 37); - break; - }else if(i == -2){ - //denied - WFIFOW(fd, 0) = 0x6e; - WFIFOB(fd, 2) = 0x02; - WFIFOSET(fd, 3); - RFIFOSKIP(fd, 37); - break; - }else if(i == -3){ - //underaged XD - WFIFOW(fd, 0) = 0x6e; - WFIFOB(fd, 2) = 0x01; - WFIFOSET(fd, 3); - RFIFOSKIP(fd, 37); - break; + if (i < 0) + { + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x6e; + switch (i) { + case -1: WFIFOB(fd, 2) = 0x00; break; + case -2: WFIFOB(fd, 2) = 0x02; break; + case -3: WFIFOB(fd, 2) = 0x01; break; + } + WFIFOSET(fd, 3); + RFIFOSKIP(fd, 37); + break; } - + { //Send data. + WFIFOHEAD(fd, 108); WFIFOW(fd, 0) = 0x6d; memset(WFIFOP(fd, 2), 0x00, 106); @@ -3450,7 +3457,7 @@ int parse_char(int fd) { WFIFOSET(fd, 108); RFIFOSKIP(fd, 37); - + } //to do for(ch = 0; ch < 9; ch++) { if (sd->found_char[ch] == -1) { @@ -3463,6 +3470,7 @@ int parse_char(int fd) { FIFOSD_CHECK(46); { int cid = RFIFOL(fd,2); + WFIFOHEAD(fd, 46); ShowInfo(CL_RED" Request Char Deletion:"CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid); memcpy(email, RFIFOP(fd,6), 40); @@ -3556,12 +3564,21 @@ int parse_char(int fd) { case 0x2af8: // login as map-server if (RFIFOREST(fd) < 60) return 0; + { + char *l_userid = RFIFOP(fd,2); + char *l_password = RFIFOP(fd,26); + WFIFOHEAD(fd, 4+5*GM_num); + + l_userid[23] = '\0'; + l_password[23] = '\0'; WFIFOW(fd, 0) = 0x2af9; for(i = 0; i < MAX_MAP_SERVERS; i++) { if (server_fd[i] <= 0) break; } - if (i == MAX_MAP_SERVERS || strcmp((const char*)RFIFOP(fd,2), userid) || strcmp((const char*)RFIFOP(fd,26), passwd)) { + if (i == MAX_MAP_SERVERS || + strcmp(l_userid, userid) || + strcmp(l_password, passwd)) { WFIFOB(fd,2) = 3; WFIFOSET(fd, 3); } else { @@ -3589,7 +3606,7 @@ int parse_char(int fd) { } RFIFOSKIP(fd,60); break; - + } case 0x187: // Alive? if (RFIFOREST(fd) < 6) { return 0; @@ -3598,6 +3615,8 @@ int parse_char(int fd) { break; case 0x7530: // Athena info get + { + WFIFOHEAD(fd, 10); WFIFOW(fd, 0) = 0x7531; WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION; WFIFOB(fd, 3) = ATHENA_MINOR_VERSION; @@ -3609,7 +3628,7 @@ int parse_char(int fd) { WFIFOSET(fd, 10); RFIFOSKIP(fd, 2); return 0; - + } case 0x7532: // disconnect(default also disconnect) default: session[fd]->eof = 1; @@ -3653,6 +3672,8 @@ int mapif_sendall(unsigned char *buf, unsigned int len) { c = 0; for(i = 0; i < MAX_MAP_SERVERS; i++) { if ((fd = server_fd[i]) > 0) { //0 Should not be a valid server_fd [Skotlex] + WFIFOHEAD(fd,len); +#if 0 //This seems to have been fixed long long ago. if (session[fd] == NULL) { //Could this be the crash's source? [Skotlex] ShowError("mapif_sendall: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", fd, i); @@ -3660,8 +3681,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len) { memset(&server[i], 0, sizeof(struct mmo_map_server)); continue; } - if (WFIFOSPACE(fd) < len) //Increase buffer size. - realloc_writefifo(fd, len); +#endif memcpy(WFIFOP(fd,0), buf, len); WFIFOSET(fd,len); c++; @@ -3678,8 +3698,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len) { c = 0; for(i=0, c=0;i 0 && fd != sfd) { - if (WFIFOSPACE(fd) < len) //Increase buffer size. - realloc_writefifo(fd, len); + WFIFOHEAD(fd, len); memcpy(WFIFOP(fd,0), buf, len); WFIFOSET(fd, len); c++; @@ -3695,8 +3714,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) { if (fd >= 0) { for(i = 0; i < MAX_MAP_SERVERS; i++) { if (fd == server_fd[i]) { - if (WFIFOSPACE(fd) < len) //Increase buffer size. - realloc_writefifo(fd, len); + WFIFOHEAD(fd,len); memcpy(WFIFOP(fd,0), buf, len); WFIFOSET(fd,len); return 1; @@ -3712,6 +3730,7 @@ int send_users_tologin(int tid, unsigned int tick, int id, int data) { if (login_fd > 0 && session[login_fd]) { // send number of user to login server + WFIFOHEAD(login_fd,6); WFIFOW(login_fd,0) = 0x2714; WFIFOL(login_fd,2) = users; WFIFOSET(login_fd,6); @@ -3767,6 +3786,8 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) { } session[login_fd]->func_parse = parse_tologin; realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); + { + WFIFOHEAD(login_fd, 86); WFIFOW(login_fd,0) = 0x2710; memcpy(WFIFOP(login_fd,2), userid, 24); memcpy(WFIFOP(login_fd,26), passwd, 24); @@ -3776,10 +3797,9 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) { memcpy(WFIFOP(login_fd,60), server_name, 20); WFIFOW(login_fd,80) = 0; WFIFOW(login_fd,82) = char_maintenance; - WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] - WFIFOSET(login_fd,86); + } return 0; } diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c index 1a1ce718a..81333db16 100644 --- a/src/char_sql/int_guild.c +++ b/src/char_sql/int_guild.c @@ -987,6 +987,7 @@ int guild_calcinfo(struct guild *g) int mapif_guild_created(int fd,int account_id,struct guild *g) { + WFIFOHEAD(fd, 10); WFIFOW(fd,0)=0x3830; WFIFOL(fd,2)=account_id; if(g != NULL) @@ -1031,6 +1032,7 @@ int mapif_guild_info(int fd,struct guild *g) // ACK member add int mapif_guild_memberadded(int fd,int guild_id,int account_id,int char_id,int flag) { + WFIFOHEAD(fd, 15); WFIFOW(fd,0)=0x3832; WFIFOL(fd,2)=guild_id; WFIFOL(fd,6)=account_id; @@ -1232,7 +1234,7 @@ int mapif_guild_castle_datasave(int castle_id,int index,int value) // reg_num; i++) { + for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) { p+= sprintf(WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place. p+= sprintf(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)); return 0; @@ -547,14 +550,16 @@ void mapif_send_maxid(int account_id, int char_id) //Request to kick char from a certain map server. [Skotlex] int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason) { - if (fd < 0) - return -1; - - WFIFOW(fd,0) = 0x2b1f; - WFIFOL(fd,2) = account_id; - WFIFOB(fd,6) = reason; - WFIFOSET(fd,7); - return 0; + if (fd >= 0) + { + WFIFOHEAD(fd,7); + WFIFOW(fd,0) = 0x2b1f; + WFIFOL(fd,2) = account_id; + WFIFOB(fd,6) = reason; + WFIFOSET(fd,7); + return 0; + } + return -1; } //-------------------------------------------------------- @@ -595,6 +600,7 @@ int check_ttl_wisdata(void) { // GM message sending int mapif_parse_GMmessage(int fd) { + RFIFOHEAD(fd); mapif_GMmessage(RFIFOP(fd, 8), RFIFOW(fd, 2), RFIFOL(fd, 4), fd); return 0; } @@ -605,7 +611,7 @@ int mapif_parse_WisRequest(int fd) { struct WisData* wd; static int wisid = 0; char name[NAME_LENGTH], t_name[NAME_LENGTH*2]; //Needs space to allocate names with escaped chars [Skotlex] - + RFIFOHEAD(fd); if ( fd <= 0 ) {return 0;} // check if we have a valid fd if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) { @@ -675,9 +681,12 @@ int mapif_parse_WisRequest(int fd) { // Wisp/page transmission result int mapif_parse_WisReply(int fd) { - int id = RFIFOL(fd,2), flag = RFIFOB(fd,6); - struct WisData *wd = idb_get(wis_db, id); - + int id, flag; + struct WisData *wd; + RFIFOHEAD(fd); + id = RFIFOL(fd,2); + flag = RFIFOB(fd,6); + wd = idb_get(wis_db, id); if (wd == NULL) return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server @@ -692,7 +701,7 @@ int mapif_parse_WisReply(int fd) { // Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers) int mapif_parse_WisToGM(int fd) { unsigned char buf[2048]; // 0x3003/0x3803 .w .24B .w .?B - + RFIFOHEAD(fd); ShowDebug("Sent packet back!\n"); memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2)); WBUFW(buf, 0) = 0x3803; @@ -706,7 +715,7 @@ int mapif_parse_Registry(int fd) { int j,p,len, max; struct accreg *reg=accreg_pt; - + RFIFOHEAD(fd); memset(accreg_pt,0,sizeof(struct accreg)); switch (RFIFOB(fd, 12)) { case 3: //Character registry @@ -754,9 +763,10 @@ int mapif_parse_RegistryRequest(int fd) //-------------------------------------------------------- int inter_parse_frommap(int fd) { - int cmd=RFIFOW(fd,0); + int cmd; int len=0; - + RFIFOHEAD(fd); + cmd=RFIFOW(fd,0); // inter鯖管轄かを調べ if(cmd < 0x3000 || cmd >= 0x3000 + (sizeof(inter_recv_packet_length)/ sizeof(inter_recv_packet_length[0]) ) ) @@ -797,6 +807,7 @@ int inter_parse_frommap(int fd) // RFIFO check int inter_check_length(int fd, int length) { + RFIFOHEAD(fd); if(length==-1){ // v-len packet if(RFIFOREST(fd)<4) // packet not yet return 0; diff --git a/src/common/socket.c b/src/common/socket.c index f7cb5d33b..1273677b6 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -877,7 +877,6 @@ int do_parsepacket(void) continue; } } - RFIFOHEAD(i); RFIFOFLUSH(i); } return 0; diff --git a/src/common/socket.h b/src/common/socket.h index 02badae3f..ae13353b2 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -26,8 +26,8 @@ extern time_t stall_time; #define RFIFOSPACE(fd) (session[fd]->max_rdata-session[fd]->rdata_size) #ifdef TURBO -#define RFIFOHEAD(fd) char *rbPtr = session[fd]->rdata+session[fd]->rdata_pos -#define RFIFOP(fd,pos) (&rbPtr[pos]) +#define RFIFOHEAD(fd) char *rbPtr ## fd = session[fd]->rdata+session[fd]->rdata_pos +#define RFIFOP(fd,pos) (&rbPtr ## fd[pos]) #else //Make it a comment so it does not disrupts the rest of code. #define RFIFOHEAD(fd) // @@ -55,8 +55,8 @@ extern time_t stall_time; #define WFIFOSPACE(fd) (session[fd]->max_wdata-session[fd]->wdata_size) #ifdef TURBO -#define WFIFOHEAD(fd, x) char *wbPtr = session[fd]->wdata+session[fd]->wdata_size; -#define WFIFOP(fd,pos) (&wbPtr[pos]) +#define WFIFOHEAD(fd, x) char *wbPtr ## fd = fd?(session[fd]->wdata+session[fd]->wdata_size):0; +#define WFIFOP(fd,pos) (&wbPtr ## fd[pos]) #else #define WFIFOHEAD(fd, size) { if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo(fd, size); } diff --git a/src/login/login.c b/src/login/login.c index 34f2f401a..4582a9c00 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -3278,6 +3278,7 @@ int parse_login(int fd) { { int GM_value, len; char* server_name; + WFIFOHEAD(fd, 3); memcpy(account.userid,RFIFOP(fd,2),NAME_LENGTH); account.userid[23] = '\0'; remove_control_chars((unsigned char *)account.userid); @@ -3286,7 +3287,7 @@ int parse_login(int fd) { remove_control_chars((unsigned char *)account.passwd); account.passwdenc = 0; server_name = (char*)RFIFOP(fd,60); - server_name[19] = '\0'; + server_name[20] = '\0'; remove_control_chars((unsigned char *)server_name); login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)" RETCODE, server_name, RFIFOB(fd,54), RFIFOB(fd,55), RFIFOB(fd,56), RFIFOB(fd,57), RFIFOW(fd,58), ip); @@ -3303,7 +3304,6 @@ int parse_login(int fd) { server[account.account_id].maintenance = RFIFOW(fd,82); server[account.account_id].new_ = RFIFOW(fd,84); server_fd[account.account_id] = fd; - WFIFOHEAD(fd, 3); WFIFOW(fd,0) = 0x2711; WFIFOB(fd,2) = 0; WFIFOSET(fd,3); diff --git a/src/login_sql/login.c b/src/login_sql/login.c index 8133849d7..a0b3770ed 100644 --- a/src/login_sql/login.c +++ b/src/login_sql/login.c @@ -268,8 +268,9 @@ void send_GM_accounts(int fd) { charif_sendallwos(-1, buf, len); else { + WFIFOHEAD(fd, len); memcpy(WFIFOP(fd,0), buf, len); - WFIFOSET(fd,len); + WFIFOSET(fd, len); } return; } @@ -548,6 +549,7 @@ int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) { c = 0; for(i = 0; i < MAX_SERVERS; i++) { if ((fd = server_fd[i]) > 0 && fd != sfd) { + WFIFOHEAD(fd,len); if (WFIFOSPACE(fd) < len) //Increase buffer size. realloc_writefifo(fd, len); memcpy(WFIFOP(fd,0), buf, len); @@ -898,6 +900,7 @@ int parse_fromchar(int fd){ 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]; + RFIFOHEAD(fd); sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); @@ -949,6 +952,7 @@ int parse_fromchar(int fd){ return 0; { int account_id; + WFIFOHEAD(fd,51); account_id = RFIFOL(fd,2); // speed up for(i=0;i= 9000) + ShowWarning("Too many account2 registries for AID %d. Some registries were not sent.\n", account_id); WFIFOW(fd,2) = p; WFIFOSET(fd,WFIFOW(fd,2)); mysql_free_result(sql_res); @@ -1499,6 +1510,7 @@ int parse_login(int fd) { 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]; + RFIFOHEAD(fd); sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); @@ -1579,11 +1591,12 @@ int parse_login(int fd) { // int gm_level = isGM(account.account_id); // removed by [zzo] if (min_level_to_connect > account.level) { + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 1; // 01 = Server closed WFIFOSET(fd,3); } else { - + WFIFOHEAD(fd,47+32*MAX_SERVERS); if (p[0] != 127 && log_login) { sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, (unsigned int)ntohl(ipl), t_uid); //query @@ -1641,6 +1654,7 @@ int parse_login(int fd) { } else { char tmp_sql[512]; char error[64]; + WFIFOHEAD(fd,23); if (log_login) { sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %%s')", loginlog_db, (unsigned int)ntohl(ipl), t_uid, result); @@ -1817,12 +1831,16 @@ int parse_login(int fd) { session[fd]->eof = 1; return 0; } - ShowDebug("Request Password key -%s\n",md5key); - RFIFOSKIP(fd,2); + { + WFIFOHEAD(fd,4+md5keylen); WFIFOW(fd,0)=0x01dc; WFIFOW(fd,2)=4+md5keylen; memcpy(WFIFOP(fd,4),md5key,md5keylen); WFIFOSET(fd,WFIFOW(fd,2)); + + ShowDebug("Request Password key -%s\n",md5key); + RFIFOSKIP(fd,2); + } break; case 0x2710: // request Char-server connection @@ -1830,9 +1848,27 @@ int parse_login(int fd) { return 0; { unsigned char* server_name; + WFIFOHEAD(fd, 3); + memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH); + account.userid[23] = '\0'; + memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH); + account.passwd[23] = '\0'; + account.passwdenc = 0; + server_name = RFIFOP(fd,60); + server_name[20] = '\0'; + ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n", + server_name, RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58), + p[0], p[1], p[2], p[3]); + jstrescapecpy(t_uid,server_name); if (log_login) { - sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, (unsigned int)ntohl(ipl), RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58)); + char t_login[50]; + jstrescapecpy(t_login,account.userid); + sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", + loginlog_db, (unsigned int)ntohl(ipl), + t_login, t_uid, t_uid, + RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), + RFIFOW(fd, 58)); //query if(mysql_query(&mysql_handle, tmpsql)) { @@ -1840,15 +1876,6 @@ int parse_login(int fd) { ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql); } } - ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n", - RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58), - p[0], p[1], p[2], p[3]); - memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH); - account.userid[23] = '\0'; - memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH); - account.passwd[23] = '\0'; - account.passwdenc = 0; - server_name = RFIFOP(fd,60); result = mmo_auth(&account, fd); //printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id); @@ -1857,7 +1884,7 @@ int parse_login(int fd) { memset(&server[account.account_id], 0, sizeof(struct mmo_char_server)); server[account.account_id].ip=RFIFOL(fd,54); server[account.account_id].port=RFIFOW(fd,58); - memcpy(server[account.account_id].name,RFIFOP(fd,60),20); + memcpy(server[account.account_id].name,server_name,20); server[account.account_id].users=0; server[account.account_id].maintenance=RFIFOW(fd,82); server[account.account_id].new_=RFIFOW(fd,84); @@ -1869,9 +1896,8 @@ int parse_login(int fd) { ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql); } - jstrescapecpy(t_uid,server[account.account_id].name); sprintf(tmpsql,"INSERT INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')", - account.account_id, server[account.account_id].name,0); + account.account_id, t_uid,0); //query if(mysql_query(&mysql_handle, tmpsql)) { ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); @@ -1894,6 +1920,8 @@ int parse_login(int fd) { return 0; case 0x7530: // request Athena information + { + WFIFOHEAD(fd,10); WFIFOW(fd,0)=0x7531; WFIFOB(fd,2)=ATHENA_MAJOR_VERSION; WFIFOB(fd,3)=ATHENA_MINOR_VERSION; @@ -1906,7 +1934,7 @@ int parse_login(int fd) { RFIFOSKIP(fd,2); ShowInfo ("Athena version check...\n"); break; - + } case 0x7532: ShowStatus ("End of connection (ip: %s)" RETCODE, ip); session[fd]->eof = 1; diff --git a/src/map/clif.c b/src/map/clif.c index 3b2f02634..97251a343 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -275,13 +275,14 @@ int clif_send_sub(struct block_list *bl, va_list ap) struct block_list *src_bl; struct map_session_data *sd; unsigned char *buf; - int len, type; + int len, type, fd; nullpo_retr(0, bl); nullpo_retr(0, ap); nullpo_retr(0, sd = (struct map_session_data *)bl); - if (!sd->fd) //Avoid attempting to send to disconnected chars (may prevent buffer overrun errors?) [Skotlex] + fd = sd->fd; + if (!fd) //Don't send to disconnected clients. return 0; buf = va_arg(ap,unsigned char*); @@ -307,29 +308,29 @@ int clif_send_sub(struct block_list *bl, va_list ap) break; } - if (session[sd->fd] != NULL) { - WFIFOHEAD(sd->fd, len); - if (WFIFOP(sd->fd,0) == buf) { + if (session[fd] != NULL) { + WFIFOHEAD(fd, len); + if (WFIFOP(fd,0) == buf) { printf("WARNING: Invalid use of clif_send function\n"); printf(" Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0)); printf(" Please correct your code.\n"); // don't send to not move the pointer of the packet for next sessions in the loop } else { if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); + memcpy(WFIFOP(fd,0), buf, len); //Check if hidden, better to modify the char's buffer than the //given buffer to prevent intravision affecting the packet as //it's being received by everyone. [Skotlex] /* New implementation... not quite correct yet as the client no longer * displays correctly the SI_INTRAVISION effect. if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 ) - && bl != src_bl && WFIFOW(sd->fd,0) == 0x0196) + && bl != src_bl && WFIFOW(fd,0) == 0x0196) { //New intravision method, just modify the status change/start packet. [Skotlex] - switch (WFIFOW(sd->fd,2)) { + switch (WFIFOW(fd,2)) { case SI_HIDING: case SI_CLOAKING: case SI_CHASEWALK: - WFIFOW(sd->fd,2) = SI_INTRAVISION; + WFIFOW(fd,2) = SI_INTRAVISION; } } */ @@ -344,17 +345,17 @@ int clif_send_sub(struct block_list *bl, va_list ap) { #if PACKETVER > 6 case 0x229: - WFIFOL(sd->fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK); + WFIFOL(fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK); break; case 0x22a: case 0x22b: case 0x22c: - WFIFOL(sd->fd,12) &=~(OPTION_HIDE|OPTION_CLOAK); + WFIFOL(fd,12) &=~(OPTION_HIDE|OPTION_CLOAK); break; #endif #if PACKETVER > 3 case 0x119: - WFIFOW(sd->fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK); + WFIFOW(fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK); break; case 0x1d8: case 0x1d9: @@ -365,12 +366,12 @@ int clif_send_sub(struct block_list *bl, va_list ap) case 0x7a: case 0x7b: case 0x7c: - WFIFOW(sd->fd,12) &=~(OPTION_HIDE|OPTION_CLOAK); + WFIFOW(fd,12) &=~(OPTION_HIDE|OPTION_CLOAK); break; } } } - WFIFOSET(sd->fd,len); + WFIFOSET(fd,len); } } } @@ -387,7 +388,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { struct map_session_data *sd = NULL; struct party_data *p = NULL; struct guild *g = NULL; - int x0 = 0, x1 = 0, y0 = 0, y1 = 0; + int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd; if (type != ALL_CLIENT && type != CHAT_MAINCHAT) { @@ -452,11 +453,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { if (type == CHAT_WOS && cd->usersd[i] == sd) continue; if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - if (cd->usersd[i]->fd >0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW] + if ((fd=cd->usersd[i]->fd) >0 && session[fd]) // Added check to see if session exists [PoW] { - WFIFOHEAD(cd->usersd[i]->fd,len); - memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len); - WFIFOSET(cd->usersd[i]->fd,len); + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); } } } @@ -466,10 +467,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { for(i=1; ifunc_parse == clif_parse && (sd = (struct map_session_data*)session[i]->session_data) != NULL && - sd->state.mainchat && sd->fd) { - WFIFOHEAD(sd->fd, len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd, len); + sd->state.mainchat && (fd=sd->fd)) + { + WFIFOHEAD(fd, len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd, len); } } break; @@ -490,8 +492,8 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { for(i=0;idata[i].sd) == NULL) continue; - if (!sd->fd || session[sd->fd] == NULL || sd->state.auth == 0 - || session[sd->fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER) + if (!(fd=sd->fd) || session[fd] == NULL || sd->state.auth == 0 + || session[fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER) continue; if (sd->bl.id == bl->id && (type == PARTY_WOS || type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS)) @@ -505,9 +507,9 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { continue; if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - WFIFOHEAD(sd->fd,len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); } } if (!enable_spy) //Skip unnecessary parsing. [Skotlex] @@ -516,12 +518,12 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { if (session[i] && session[i]->func_parse == clif_parse && (sd = (struct map_session_data*)session[i]->session_data) != NULL && - sd->state.auth && sd->fd && sd->partyspy == p->party.party_id) + sd->state.auth && (fd=sd->fd) && sd->partyspy == p->party.party_id) { - if (sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - WFIFOHEAD(sd->fd,len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); + if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); } } } @@ -547,10 +549,10 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { } break; case SELF: - if (sd && sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - WFIFOHEAD(sd->fd,len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); + if (sd && (fd=sd->fd) && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); } break; @@ -571,8 +573,8 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { if (g) { for(i = 0; i < g->max_member; i++) { if ((sd = g->member[i].sd) != NULL) { - if (!sd->fd || session[sd->fd] == NULL || sd->state.auth == 0 - || session[sd->fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER) + if (!(fd=sd->fd) || session[fd] == NULL || sd->state.auth == 0 + || session[fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER) continue; if (sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS)) @@ -586,9 +588,9 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { continue; if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - WFIFOHEAD(sd->fd,len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); } } } @@ -597,11 +599,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) { for (i = 1; i < fd_max; i++){ // guildspy [Syrus22] if (session[i] && session[i]->func_parse == clif_parse && (sd = (struct map_session_data*)session[i]->session_data) != NULL && - sd->state.auth && sd->fd && sd->guildspy == g->guild_id) { + sd->state.auth && (fd=sd->fd) && sd->guildspy == g->guild_id) { if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - WFIFOHEAD(sd->fd,len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); + WFIFOHEAD(fd,len); + memcpy(WFIFOP(fd,0), buf, len); + WFIFOSET(fd,len); } } } @@ -1590,12 +1592,11 @@ int clif_homskillinfoblock(struct map_session_data *sd) { //[orn] void clif_homskillup(struct map_session_data *sd, int skill_num) { //[orn] struct homun_data *hd; - int fd,skillid; - WFIFOHEAD(sd->fd, packet_len_table[0x239]); + int fd=sd->fd, skillid; + WFIFOHEAD(fd, packet_len_table[0x239]); nullpo_retv(sd); skillid = skill_num - HM_SKILLBASE - 1; - fd=sd->fd; hd=sd->hd; WFIFOW(fd,0) = 0x239; @@ -1685,12 +1686,8 @@ void clif_parse_HomMenu(int fd, struct map_session_data *sd) { //[orn] int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn] { - int fd; - WFIFOHEAD(sd->fd,packet_len_table[0x22f]); - - nullpo_retr(0, sd); - - fd=sd->fd; + int fd=sd->fd; + WFIFOHEAD(fd,packet_len_table[0x22f]); WFIFOW(fd,0)=0x22f; WFIFOB(fd,2)=fail; WFIFOW(fd,3)=foodid; @@ -1705,12 +1702,8 @@ int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn] */ int clif_walkok(struct map_session_data *sd) { - int fd; - WFIFOHEAD(sd->fd, packet_len_table[0x87]); - - nullpo_retr(0, sd); - - fd=sd->fd; + int fd=sd->fd; + WFIFOHEAD(fd, packet_len_table[0x87]); WFIFOW(fd,0)=0x87; WFIFOL(fd,2)=gettick(); WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y); @@ -3922,7 +3915,7 @@ void clif_getareachar_char(struct map_session_data* sd,struct block_list *bl) { struct unit_data *ud; struct view_data *vd; - int len; + int len, fd = sd->fd; vd = status_get_viewdata(bl); @@ -3933,24 +3926,24 @@ void clif_getareachar_char(struct map_session_data* sd,struct block_list *bl) if (ud && ud->walktimer != -1) { #if PACKETVER > 6 - WFIFOHEAD(sd->fd, packet_len_table[0x22c]); + WFIFOHEAD(fd, packet_len_table[0x22c]); #elif PACKETVER > 3 - WFIFOHEAD(sd->fd, packet_len_table[0x1da]); + WFIFOHEAD(fd, packet_len_table[0x1da]); #else - WFIFOHEAD(sd->fd, packet_len_table[0x7b]); + WFIFOHEAD(fd, packet_len_table[0x7b]); #endif - len = clif_set007b(bl,vd,ud,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); + len = clif_set007b(bl,vd,ud,WFIFOP(fd,0)); + WFIFOSET(fd,len); } else { #if PACKETVER > 6 - WFIFOHEAD(sd->fd,packet_len_table[0x22a]); + WFIFOHEAD(fd,packet_len_table[0x22a]); #elif PACKETVER > 3 - WFIFOHEAD(sd->fd,packet_len_table[0x1d8]); + WFIFOHEAD(fd,packet_len_table[0x1d8]); #else - WFIFOHEAD(sd->fd,packet_len_table[0x78]); + WFIFOHEAD(fd,packet_len_table[0x78]); #endif - len = clif_set0078(bl,vd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); + len = clif_set0078(bl,vd,WFIFOP(fd,0)); + WFIFOSET(fd,len); } if (vd->cloth_color) @@ -4980,13 +4973,8 @@ int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst) // The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex] // WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_fix(NULL,dst,100,i+1,status->def_ele, status->ele_lv))<0?0:fix); - if(sd->status.party_id>0) - clif_send(buf,packet_len_table[0x18c],&sd->bl,PARTY_SAMEMAP); - else{ - WFIFOHEAD(sd->fd,packet_len_table[0x18c]); - memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x18c]); - WFIFOSET(sd->fd,packet_len_table[0x18c]); - } + clif_send(buf,packet_len_table[0x18c],&sd->bl, + sd->status.party_id>0?PARTY_SAMEMAP:SELF); return 0; } /*========================================== @@ -7636,23 +7624,19 @@ void clif_parse_QuitGame(int fd,struct map_session_data *sd); int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type) { - nullpo_retr(0, tsd); - + int fd = tsd->fd; + WFIFOHEAD(fd,packet_len_table[0x18b]); if(type) clif_GM_kickack(sd,tsd->status.account_id); - WFIFOHEAD(tsd->fd,packet_len_table[0x18b]); - WFIFOW(tsd->fd,0) = 0x18b; - WFIFOW(tsd->fd,2) = 0; - WFIFOSET(tsd->fd,packet_len_table[0x18b]); - - if (tsd->fd) - { - ShowDebug("clif_GM_kick: Disconnecting session #%d\n", tsd->fd); - clif_setwaitclose(tsd->fd); - } else { //Player has no session attached, delete it right away. [Skotlex] + if (!fd) { map_quit(tsd); + return 0; } + WFIFOW(fd,0) = 0x18b; + WFIFOW(fd,2) = 0; + WFIFOSET(fd,packet_len_table[0x18b]); + clif_setwaitclose(fd); return 0; } @@ -9650,7 +9634,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) struct map_session_data *t_sd; RFIFOHEAD(fd); - t_sd = map_id2sd(RFIFOL(sd->fd,2)); + t_sd = map_id2sd(RFIFOL(fd,2)); if(!sd->chatID && clif_cant_act(sd)) return; //You can trade while in a chatroom. @@ -9678,7 +9662,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) void clif_parse_TradeAck(int fd,struct map_session_data *sd) { RFIFOHEAD(fd); - trade_tradeack(sd,RFIFOB(sd->fd,2)); + trade_tradeack(sd,RFIFOB(fd,2)); } /*========================================== @@ -9688,7 +9672,7 @@ void clif_parse_TradeAck(int fd,struct map_session_data *sd) void clif_parse_TradeAddItem(int fd,struct map_session_data *sd) { RFIFOHEAD(fd); - trade_tradeadditem(sd,RFIFOW(sd->fd,2),RFIFOL(sd->fd,4)); + trade_tradeadditem(sd,RFIFOW(fd,2),RFIFOL(fd,4)); } /*========================================== @@ -10431,7 +10415,7 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { return; } - t_sd = map_id2sd(RFIFOL(sd->fd,2)); + t_sd = map_id2sd(RFIFOL(fd,2)); // @noask [LuzZza] if(t_sd && t_sd->state.noask) { @@ -10698,7 +10682,7 @@ void clif_parse_GuildInvite(int fd,struct map_session_data *sd) { return; } - t_sd = map_id2sd(RFIFOL(sd->fd,2)); + t_sd = map_id2sd(RFIFOL(fd,2)); // @noask [LuzZza] if(t_sd && t_sd->state.noask) { @@ -10789,7 +10773,7 @@ void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) { return; } - t_sd = map_id2sd(RFIFOL(sd->fd,2)); + t_sd = map_id2sd(RFIFOL(fd,2)); // @noask [LuzZza] if(t_sd && t_sd->state.noask) { @@ -10830,7 +10814,6 @@ void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) { void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) { struct map_session_data *t_sd; - RFIFOHEAD(fd); if(map[sd->bl.m].flag.guildlock) @@ -10839,7 +10822,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) { return; } - t_sd = map_id2sd(RFIFOL(sd->fd,2)); + t_sd = map_id2sd(RFIFOL(fd,2)); // @noask [LuzZza] if(t_sd && t_sd->state.noask) { @@ -11296,7 +11279,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd) */ void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int char_id, int online) { //Toggles a single friend online/offline [Skotlex] - int i; + int i, fd = sd->fd; //Seek friend. for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id && @@ -11305,13 +11288,12 @@ void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int cha if(i == MAX_FRIENDS || sd->status.friends[i].char_id == 0) return; //Not found - WFIFOHEAD(sd->fd,packet_len_table[0x206]); - WFIFOW(sd->fd, 0) = 0x206; - WFIFOL(sd->fd, 2) = sd->status.friends[i].account_id; - WFIFOL(sd->fd, 6) = sd->status.friends[i].char_id; - WFIFOB(sd->fd,10) = !online; //Yeah, a 1 here means "logged off", go figure... - - WFIFOSET(sd->fd, packet_len_table[0x206]); + WFIFOHEAD(fd,packet_len_table[0x206]); + WFIFOW(fd, 0) = 0x206; + WFIFOL(fd, 2) = sd->status.friends[i].account_id; + WFIFOL(fd, 6) = sd->status.friends[i].char_id; + WFIFOB(fd,10) = !online; //Yeah, a 1 here means "logged off", go figure... + WFIFOSET(fd, packet_len_table[0x206]); } //Subfunction called from clif_foreachclient to toggle friends on/off [Skotlex] @@ -11327,21 +11309,21 @@ int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap) //For sending the whole friends list. void clif_friendslist_send(struct map_session_data *sd) { - int i = 0, n; + int i = 0, n, fd = sd->fd; // Send friends list - WFIFOHEAD(sd->fd, MAX_FRIENDS * 32 + 4); - WFIFOW(sd->fd, 0) = 0x201; + WFIFOHEAD(fd, MAX_FRIENDS * 32 + 4); + WFIFOW(fd, 0) = 0x201; for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) { - WFIFOL(sd->fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id; - WFIFOL(sd->fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id; - memcpy(WFIFOP(sd->fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH); + WFIFOL(fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id; + WFIFOL(fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id; + memcpy(WFIFOP(fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH); } if (i) { - WFIFOW(sd->fd,2) = 4 + 32 * i; - WFIFOSET(sd->fd, WFIFOW(sd->fd,2)); + WFIFOW(fd,2) = 4 + 32 * i; + WFIFOSET(fd, WFIFOW(fd,2)); } for (n = 0; n < i; n++) diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 2beccb554..1b7a3100c 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -186,9 +186,11 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum) hd->homunculus.hskill[i].lv++ ; hd->homunculus.skillpts-- ; status_calc_homunculus(hd,0) ; - clif_homskillup(hd->master, skillnum) ; - clif_hominfo(hd->master,hd,0) ; - clif_homskillinfoblock(hd->master) ; + if (hd->master) { + clif_homskillup(hd->master, skillnum); + clif_hominfo(hd->master,hd,0); + clif_homskillinfoblock(hd->master); + } } } } diff --git a/src/map/mob.c b/src/map/mob.c index a53b5717b..97564cfd1 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -134,7 +134,7 @@ int mobdb_checkid(const int id) * Returns the view data associated to this mob class. *------------------------------------------ */ -struct view_data * mob_get_viewdata(class_) +struct view_data * mob_get_viewdata(int class_) { if (mob_db(class_) == mob_dummy) return 0; -- cgit v1.2.3-70-g09d2