From b60826b40d84bd3807fe8fa18bce8117fc5051e3 Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 21 Nov 2006 18:23:08 +0000 Subject: - Moved ignoreAll to state.ignoreAll so it saves some space. - Cleaned up clif_parse_Wis to prevent crashes from forged packets (using a strlen() on a string where you don't know if it's null-terminated is a NO-NO) - Cleaned up the implementation of the ignore list so it's more efficient. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9282 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 6 + src/map/clif.c | 415 +++++++++++++++++++++++++++------------------------- src/map/intif.c | 48 +++--- src/map/map.h | 2 +- 4 files changed, 246 insertions(+), 225 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 649352a66..32c7a4999 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,12 @@ 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/21 + * Moved ignoreAll to state.ignoreAll so it saves some space. [Skotlex] + * Cleaned up clif_parse_Wis to prevent crashes from forged packets + [Skotlex] + * Cleaned up the implementation of the ignore list so it's more efficient. + [Skotlex] 2006/11/20 * Implemented NPC_DEFENDER. Reduces ranged Physical+Misc damage by 80% [Skotlex] diff --git a/src/map/clif.c b/src/map/clif.c index 0d04d0bc3..548369d5d 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9056,46 +9056,49 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) { *------------------------------------------ */ void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 .w .24B .?B // rewritten by [Yor] - char *gm_command; + char *command, *msg; struct map_session_data *dstsd; int i=0; struct npc_data *npc; char split_data[10][50]; char target[NAME_LENGTH+1]; char output[256]; - unsigned int speclen, scanlen; + unsigned int len; RFIFOHEAD(fd); - - //printf("clif_parse_Wis: message: '%s'.\n", RFIFOP(fd,28)); - - // Prevent hacked packets like missing null terminator or wrong len specification. [Lance] - speclen = (unsigned int)RFIFOW(fd,2); - scanlen = strlen((const char*)RFIFOP(fd,28)) + 29; - - if(scanlen != speclen){ - ShowWarning("Hack on Whisper: %s (AID: %d)!\n", sd->status.name, sd->bl.id); - clif_GM_kick(sd,sd,0); + len = RFIFOW(fd,2); //Packet length + if (len < 28) + { //Invalid packet, specified size is less than minimum! [Skotlex] + ShowWarning("Hack on Whisper: %s (AID/CID: %d:%d)!\n", sd->status.name, sd->status.account_id, sd->status.char_id); + clif_setwaitclose(fd); return; } - - gm_command = (char*)aMallocA(speclen * sizeof(char)); // 24+3+(RFIFOW(fd,2)-28)+1 or 24+3+(strlen(RFIFOP(fd,28))+1 (size can be wrong with hacker) - - sprintf(gm_command, "%s : %s", sd->status.name, RFIFOP(fd,28)); - if ((is_charcommand(fd, sd, gm_command) != CharCommand_None) || - (is_atcommand(fd, sd, gm_command) != AtCommand_None)) { - if(gm_command) aFree(gm_command); + if (len == 28) return; //Not sure if client really lets you send a blank line. + len-=28; //Message length + // 24+3+(RFIFOW(fd,2)-28)+1 <- last 1 is '\0' + command = (char*)aMallocA((NAME_LENGTH+4+len) * sizeof(char)); + //No need for out of memory checks, malloc.c aborts the map when that happens. + msg = command; + msg+= sprintf(command, "%s : ", sd->status.name); + memcpy(msg, RFIFOP(fd, 28), len); + msg[len]='\0'; //Force a terminator + if ((is_charcommand(fd, sd, command) != CharCommand_None) || + (is_atcommand(fd, sd, command) != AtCommand_None)) { + aFree(command); return; } - if(gm_command) aFree(gm_command); if (sd->sc.count && (sd->sc.data[SC_BERSERK].timer!=-1 || - (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT))) + (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT))) { + aFree(command); return; + } if (battle_config.min_chat_delay) { //[Skotlex] - if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0) + if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0) { + aFree(command); return; + } sd->cantalk_tick = gettick() + battle_config.min_chat_delay; } @@ -9106,21 +9109,17 @@ void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 .w status.char_id, sd->status.account_id, (char*)mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, (char*)RFIFOP(fd, 28)); - + log_chat("W", 0, sd->status.char_id, sd->status.account_id, (char*)mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, msg); //-------------------------------------------------------// // Lordalfa - Paperboy - To whisper NPC commands // //-------------------------------------------------------// if (target[0] && (strncasecmp(target,"NPC:",4) == 0) && (strlen(target) >4)) { - char *whisper_tmp = target+4; //Skip the NPC: string part. - if ((npc = npc_name2id(whisper_tmp))) + char *str= target+4; //Skip the NPC: string part. + if ((npc = npc_name2id(str))) { - char *split, *str; - whisper_tmp=(char *)aMallocA((strlen((char *)(RFIFOP(fd,28)))+1)*sizeof(char)); - - str=whisper_tmp; - sprintf(whisper_tmp, "%s", (const char*)RFIFOP(fd,28)); + char *split; + str = msg; for( i=0; i < 10; ++i ) {// Splits the message using '#' as separators split = strchr(str,'#'); @@ -9129,7 +9128,7 @@ void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 .w .w name)+18)*sizeof(char)); + sprintf(output, "@whispervar%d$", i); + set_var(sd,output,(char *) split_data[i]); + } - sprintf(whisper_tmp, "%s::OnWhisperGlobal", npc->name); - npc_event(sd,whisper_tmp,0); // Calls the NPC label + sprintf(output, "%s::OnWhisperGlobal", npc->name); + npc_event(sd,output,0); // Calls the NPC label - aFree(whisper_tmp); //I rewrote it a little to use memory allocation, a bit more stable =P [Kevin] + aFree(command); return; - } //should have just removed the one below that was a my bad =P - } + } + } // Main chat [LuzZza] if(strcmpi(target, main_chat_nick) == 0) { - if(!sd->state.mainchat) { + if(!sd->state.mainchat) clif_displaymessage(fd, msg_txt(388)); // You should enable main chat with "@main on" command. - return; + else { + sprintf(output, msg_txt(386), sd->status.name, msg); + intif_announce(output, strlen(output) + 1, 0xFE000000, 0); } - sprintf(output, msg_txt(386), sd->status.name, (char *)RFIFOP(fd,28)); - intif_announce(output, strlen(output) + 1, 0xFE000000, 0); + aFree(command); return; } // searching destination character dstsd = map_nick2sd(target); // player is not on this map-server - if (dstsd == NULL || // At this point, don't send wisp/page if it's not exactly the same name, because (example) // if there are 'Test' player on an other map-server and 'test' player on this map-server, // and if we ask for 'Test', we must not contact 'test' player // so, we send information to inter-server, which is the only one which decide (and copy correct name). - strcmp(dstsd->status.name, target) != 0) // not exactly same name - // send message to inter-server - intif_wis_message(sd, target, (char*)RFIFOP(fd,28), RFIFOW(fd,2)-28); + if (dstsd == NULL || + strcmp(dstsd->status.name, target) != 0) + { // send message to inter-server + intif_wis_message(sd, target, msg, len); + aFree(command); + return; + } // player is on this map-server - else { + if (dstsd->fd == fd) { // if you send to your self, don't send anything to others - if (dstsd->fd == fd) // but, normaly, it's impossible! - clif_wis_message(fd, wisp_server_name, "You can not page yourself. Sorry.", strlen("You can not page yourself. Sorry.") + 1); - // otherwise, send message and answer immediatly - else { - if (dstsd->ignoreAll == 1) { - if (dstsd->sc.option & OPTION_INVISIBLE && pc_isGM(sd) < pc_isGM(dstsd)) - clif_wis_end(fd, 1); // 1: target character is not loged in - else - clif_wis_end(fd, 3); // 3: everyone ignored by target - } else { - // if player ignore the source character - for(i = 0; i < MAX_IGNORE_LIST; i++) - if (strcmp(dstsd->ignore[i].name, sd->status.name) == 0) { - clif_wis_end(fd, 2); // 2: ignored by target - break; - } - // if source player not found in ignore list - if (i == MAX_IGNORE_LIST) { - if(strlen(dstsd->away_message) > 0) { // Send away automessage [LuzZza] - //(Automessage has been sent) - sprintf(output, "%s %s", (char*)RFIFOP(fd,28),msg_txt(543)); - clif_wis_message(dstsd->fd, sd->status.name, output, strlen(output) + 1); - clif_wis_end(fd, 0); // 0: success to send wisper - if(dstsd->state.autotrade) - //"Away [AT] - \"%s\"" - sprintf(output, msg_txt(544), dstsd->away_message); - else - //"Away - \"%s\"" - sprintf(output, msg_txt(545), dstsd->away_message); - clif_wis_message(fd, dstsd->status.name, output, strlen(output) + 1); - } else { // Normal message - clif_wis_message(dstsd->fd, sd->status.name, (char*)RFIFOP(fd,28), RFIFOW(fd,2) - 28); - clif_wis_end(fd, 0); // 0: success to send wisper - } - } - } - } + // but, normaly, it's impossible! + clif_wis_message(fd, wisp_server_name, + "You can not page yourself. Sorry.", + strlen("You can not page yourself. Sorry.") + 1); + aFree(command); + return; + } + // otherwise, send message and answer immediatly + if (dstsd->state.ignoreAll) { + if (dstsd->sc.option & OPTION_INVISIBLE && pc_isGM(sd) < pc_isGM(dstsd)) + clif_wis_end(fd, 1); // 1: target character is not loged in + else + clif_wis_end(fd, 3); // 3: everyone ignored by target + aFree(command); + return; } + // if player ignore the source character + for(i = 0; i < MAX_IGNORE_LIST && + dstsd->ignore[i].name[0] != '\0' && + strcmp(dstsd->ignore[i].name, sd->status.name) != 0 + ; i++); + if(i < MAX_IGNORE_LIST && dstsd->ignore[i].name[0] != '\0') + { //Ignored + clif_wis_end(fd, 2); // 2: ignored by target + aFree(command); + return; + } + + // if source player not found in ignore list + if(dstsd->away_message[0] != '\0') { // Send away automessage [LuzZza] + //(Automessage has been sent) + sprintf(output, "%s %s", msg, msg_txt(543)); + clif_wis_message(dstsd->fd, sd->status.name, output, strlen(output) + 1); + clif_wis_end(fd, 0); // 0: success to send wisper + if(dstsd->state.autotrade) + //"Away [AT] - \"%s\"" + sprintf(output, msg_txt(544), dstsd->away_message); + else + //"Away - \"%s\"" + sprintf(output, msg_txt(545), dstsd->away_message); + aFree(command); + clif_wis_message(fd, dstsd->status.name, output, strlen(output) + 1); + return; + } + // Normal message + clif_wis_message(dstsd->fd, sd->status.name, msg, len); + clif_wis_end(fd, 0); // 0: success to send wisper + aFree(command); return; } @@ -11028,126 +11035,148 @@ void clif_parse_GMReqNoChatCount(int fd, struct map_session_data *sd) return; } +static int pstrcmp(const void *a, const void *b) +{ + return strcmp((char *)a, (char *)b); +} + void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by [Yor] char output[512]; char *nick; // S 00cf .24B .B: 00 (/ex nick) deny speech from nick, 01 (/in nick) allow speech from nick - int i, pos; + int i; RFIFOHEAD(fd); malloc_tsetdword(output, '\0', sizeof(output)); nick = (char*)RFIFOP(fd,2); // speed up RFIFOB(fd,NAME_LENGTH+1) = '\0'; // to be sure that the player name have at maximum 23 characters (nick range: [2]->[26]) - //printf("Ignore: char '%s' state: %d\n", nick, RFIFOB(fd,26)); WFIFOHEAD(fd,packet_len_table[0xd1]); WFIFOW(fd,0) = 0x0d1; // R 00d1 .B .B: type: 0: deny, 1: allow, fail: 0: success, 1: fail WFIFOB(fd,2) = RFIFOB(fd,26); // do nothing only if nick can not exist - if (strlen(nick) < 4) { + if ((i = strlen(nick)) < 4 || i > NAME_LENGTH) { WFIFOB(fd,3) = 1; // fail WFIFOSET(fd, packet_len_table[0x0d1]); - if (RFIFOB(fd,26) == 0) // type - clif_wis_message(fd, wisp_server_name, "It's impossible to block this player.", strlen("It's impossible to block this player.") + 1); - else - clif_wis_message(fd, wisp_server_name, "It's impossible to unblock this player.", strlen("It's impossible to unblock this player.") + 1); + clif_wis_message(fd, wisp_server_name, + "This player name is not valid.", + strlen("This player name is not valid.")+1); return; + } // name can exist - } else { - // deny action (we add nick only if it's not already exist - if (RFIFOB(fd,26) == 0) { // type - pos = -1; - for(i = 0; i < MAX_IGNORE_LIST; i++) { - if (strcmp(sd->ignore[i].name, nick) == 0) { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - clif_wis_message(fd, wisp_server_name, "This player is already blocked.", strlen("This player is already blocked.") + 1); - if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. - sprintf(output, "Character '%s' (account: %d) has tried AGAIN to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); - } - return; - } else if (pos == -1 && sd->ignore[i].name[0] == '\0') - pos = i; - } - // if a position is found and name not found, we add it in the list - if (pos != -1) { - memcpy(sd->ignore[pos].name, nick, NAME_LENGTH-1); - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d1]); - if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. - sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); - // send something to be inform and force bot to ignore twice... If GM receiving block + block again, it's a bot :) - clif_wis_message(fd, wisp_server_name, "Add me in your ignore list, doesn't block my wisps.", strlen("Add me in your ignore list, doesn't block my wisps.") + 1); - } - } else { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - clif_wis_message(fd, wisp_server_name, "You can not block more people.", strlen("You can not block more people.") + 1); - if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. - sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); - } + // deny action (we add nick only if it's not already exist + if (RFIFOB(fd,26) == 0) { // Add block + for(i = 0; i < MAX_IGNORE_LIST && + sd->ignore[i].name[0] != '\0' && + strcmp(sd->ignore[i].name, nick) != 0 + ; i++); + + if (i == MAX_IGNORE_LIST) { //Full List + WFIFOB(fd,3) = 1; // fail + WFIFOSET(fd, packet_len_table[0x0d1]); + clif_wis_message(fd, wisp_server_name, + "You can not block more people.", + strlen("You can not block more people.") + 1); + if (strcmp(wisp_server_name, nick) == 0) + { // to found possible bot users who automaticaly ignore people. + sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); + intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); } - // allow action (we remove all same nicks if they exist) - } else { - pos = -1; - for(i = 0; i < MAX_IGNORE_LIST; i++) - if (strcmp(sd->ignore[i].name, nick) == 0) { - malloc_tsetdword(sd->ignore[i].name, 0, sizeof(sd->ignore[i].name)); - if (pos == -1) { - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d1]); - pos = i; // don't break, to remove ALL same nick - } - } - if (pos == -1) { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - clif_wis_message(fd, wisp_server_name, "This player is not blocked by you.", strlen("This player is not blocked by you.") + 1); + return; + } + if(sd->ignore[i].name[0] != '\0') + { //Name already exists. + WFIFOB(fd,3) = 1; // fail + WFIFOSET(fd, packet_len_table[0x0d1]); + clif_wis_message(fd, wisp_server_name, + "This player is already blocked.", + strlen("This player is already blocked.") + 1); + if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. + sprintf(output, "Character '%s' (account: %d) has tried AGAIN to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); + intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); } + return; } + //Insert in position i + memcpy(sd->ignore[i].name, nick, NAME_LENGTH-1); + WFIFOB(fd,3) = 0; // success + WFIFOSET(fd, packet_len_table[0x0d1]); + if (strcmp(wisp_server_name, nick) == 0) + { // to found possible bot users who automaticaly ignore people. + sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); + intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); + // send something to be inform and force bot to ignore twice... If GM receiving block + block again, it's a bot :) + clif_wis_message(fd, wisp_server_name, + "Adding me in your ignore list will not block my wisps.", + strlen("Adding me in your ignore list will not block my wisps.") + 1); + } + //Sort the ignore list. + qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp); + return; } + //Remove name + for(i = 0; i < MAX_IGNORE_LIST && + sd->ignore[i].name[0] != '\0' && + strcmp(sd->ignore[i].name, nick) != 0 + ; i++); -// for(i = 0; i < MAX_IGNORE_LIST; i++) // for debug only -// if (sd->ignore[i].name[0] != '\0') -// printf("Ignored player: '%s'\n", sd->ignore[i].name); - + if (i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0') + { //Not found + WFIFOB(fd,3) = 1; // fail + WFIFOSET(fd, packet_len_table[0x0d1]); + clif_wis_message(fd, wisp_server_name, + "This player is not blocked by you.", + strlen("This player is not blocked by you.") + 1); + return; + } + //Move everything one place down to overwrite removed entry. + memmove(sd->ignore[i].name, sd->ignore[i+1].name, + (MAX_IGNORE_LIST-i-1)*sizeof(sd->ignore[0].name)); + malloc_tsetdword(sd->ignore[MAX_IGNORE_LIST-1].name, 0, sizeof(sd->ignore[0].name)); + // success + WFIFOB(fd,3) = 0; + WFIFOSET(fd, packet_len_table[0x0d1]); + +// for debug only +// for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0'; i++) / +// ShowDebug("Ignored player: '%s'\n", sd->ignore[i].name); return; } void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { // Rewritten by [Yor] //printf("Ignore all: state: %d\n", RFIFOB(fd,2)); RFIFOHEAD(fd); - if (RFIFOB(fd,2) == 0) {// S 00d0 len.B: 00 (/exall) deny all speech, 01 (/inall) allow all speech - WFIFOHEAD(fd,packet_len_table[0xd2]); - WFIFOW(fd,0) = 0x0d2; // R 00d2 .B .B: type: 0: deny, 1: allow, fail: 0: success, 1: fail - WFIFOB(fd,2) = 0; - if (sd->ignoreAll == 0) { - sd->ignoreAll = 1; - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d2]); - } else { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d2]); - clif_wis_message(fd, wisp_server_name, "You already block everyone.", strlen("You already block everyone.") + 1); - } - } else { - WFIFOHEAD(fd,packet_len_table[0xd2]); - WFIFOW(fd,0) = 0x0d2; // R 00d2 .B .B: type: 0: deny, 1: allow, fail: 0: success, 1: fail - WFIFOB(fd,2) = 1; - if (sd->ignoreAll == 1) { - sd->ignoreAll = 0; - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d2]); - } else { + WFIFOHEAD(fd,packet_len_table[0xd2]); + // R 00d2 .B .B: type: 0: deny, 1: allow, fail: 0: success, 1: fail + // S 00d0 len.B: 00 (/exall) deny all speech, 01 (/inall) allow all speech + WFIFOW(fd,0) = 0x0d2; + WFIFOB(fd,2) = RFIFOB(fd,2); + if (RFIFOB(fd,2) == 0) { //Deny all + if (sd->state.ignoreAll) { WFIFOB(fd,3) = 1; // fail WFIFOSET(fd, packet_len_table[0x0d2]); - clif_wis_message(fd, wisp_server_name, "You already allow everyone.", strlen("You already allow everyone.") + 1); + clif_wis_message(fd, wisp_server_name, + "You already block everyone.", + strlen("You already block everyone.") + 1); + return; } + sd->state.ignoreAll = 1; + WFIFOB(fd,3) = 0; // success + WFIFOSET(fd, packet_len_table[0x0d2]); + return ; } - + //Unblock everyone + if (!sd->state.ignoreAll) { + WFIFOB(fd,3) = 1; // fail + WFIFOSET(fd, packet_len_table[0x0d2]); + clif_wis_message(fd, wisp_server_name, + "You already allow everyone.", + strlen("You already allow everyone.") + 1); + return; + } + sd->state.ignoreAll = 0; + WFIFOB(fd,3) = 0; // success + WFIFOSET(fd, packet_len_table[0x0d2]); return; } @@ -11155,32 +11184,18 @@ void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { // Rewritten * Wis拒否リスト *------------------------------------------ */ - int pstrcmp(const void *a, const void *b) -{ - return strcmp((char *)a, (char *)b); -} void clif_parse_PMIgnoreList(int fd,struct map_session_data *sd) { - int i,j=0,count=0; + int i; - qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp); - for(i = 0; i < MAX_IGNORE_LIST; i++){ //中身があるのを数える - if(sd->ignore[i].name[0] != 0) - count++; - } - WFIFOHEAD(fd, 4 + (NAME_LENGTH * count)); + WFIFOHEAD(fd, 4 + (NAME_LENGTH * MAX_IGNORE_LIST)); WFIFOW(fd,0) = 0xd4; - WFIFOW(fd,2) = 4 + (NAME_LENGTH * count); - for(i = 0; i < MAX_IGNORE_LIST; i++){ - if(sd->ignore[i].name[0] != 0){ - memcpy(WFIFOP(fd, 4 + j * 24),sd->ignore[i].name, NAME_LENGTH); - j++; - } - } - WFIFOSET(fd, WFIFOW(fd,2)); - if(count >= MAX_IGNORE_LIST) //満タンなら最後の1個を消す - sd->ignore[MAX_IGNORE_LIST - 1].name[0] = 0; + for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0'; i++) + memcpy(WFIFOP(fd, 4 + i * NAME_LENGTH),sd->ignore[i].name, NAME_LENGTH); + + WFIFOW(fd,2) = 4 + i * NAME_LENGTH; + WFIFOSET(fd, WFIFOW(fd,2)); return; } diff --git a/src/map/intif.c b/src/map/intif.c index bab76b40b..025d76c9b 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -845,33 +845,33 @@ int intif_parse_WisMessage(int fd) { // rewritten by [Yor] int id, i; RFIFOHEAD(fd); id=RFIFOL(fd,4); - i=0; //,j=0; -// if(battle_config.etc_log) -// printf("intif_parse_wismessage: %d %s %s %s\n",id,RFIFOP(fd,6),RFIFOP(fd,30),RFIFOP(fd,54) ); memcpy(name, RFIFOP(fd,32), NAME_LENGTH); name[NAME_LENGTH-1] = '\0'; //In case name arrived without it's terminator. [Skotlex] - sd=(struct map_session_data *) map_nick2sd(name); // 送信先を探す - if(sd!=NULL && strcmp(sd->status.name, name) == 0){ - if(sd->ignoreAll == 1) - intif_wis_replay(RFIFOL(fd,4), 2); // 受信拒否 - else { - wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor] - for(i=0;iignore[i].name, wisp_source)==0){ - break; - } - } - if(i==MAX_IGNORE_LIST) // run out of list, so we are not ignored - { - clif_wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56); - intif_wis_replay(id,0); // 送信成功 - } - else - intif_wis_replay(id, 2); // 受信拒否 - } - }else - intif_wis_replay(id,1); // そんな人いません + sd = map_nick2sd(name); + if(sd == NULL || strcmp(sd->status.name, name) != 0) + { //Not found + intif_wis_replay(id,1); + return 0; + } + if(sd->state.ignoreAll) { + intif_wis_replay(id, 2); + return 0; + } + wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor] + for(i=0; i < MAX_IGNORE_LIST && + sd->ignore[i].name[0] != '\0' && + strcmp(sd->ignore[i].name, wisp_source) != 0 + ; i++); + + if (i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0') + { //Ignored + intif_wis_replay(id, 2); + return 0; + } + //Success to send whisper. + clif_wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56); + intif_wis_replay(id,0); // 送信成功 return 0; } diff --git a/src/map/map.h b/src/map/map.h index 934acb31f..2061e93bb 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -596,6 +596,7 @@ struct map_session_data { unsigned killer : 1; unsigned killable : 1; unsigned doridori : 1; + unsigned ignoreAll : 1; unsigned short autoloot; struct guild *gmaster_flag; } state; @@ -638,7 +639,6 @@ struct map_session_data { struct{ char name[NAME_LENGTH]; } ignore[MAX_IGNORE_LIST]; - int ignoreAll; int followtimer; // [MouseJstr] int followtarget; -- cgit v1.2.3-70-g09d2