diff options
-rw-r--r-- | Changelog-Trunk.txt | 6 | ||||
-rw-r--r-- | src/map/clif.c | 415 | ||||
-rw-r--r-- | src/map/intif.c | 48 | ||||
-rw-r--r-- | 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 <len>.w <nick>.24B <message>.?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 <len>.w <ni if(log_config.chat&1 //we log everything then
|| ( log_config.chat&2 //if Whisper bit is on
&& ( !agit_flag || !(log_config.chat&16) ))) //if WOE ONLY flag is off or AGIT is OFF
- log_chat("W", 0, sd->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 <len>.w <ni strncpy(split_data[i], str, sizeof(split_data[0])/sizeof(char));
split_data[i][sizeof(split_data[0])/sizeof(char)-1] = '\0';
for( ++i; i < 10; ++i )
- split_data[i][0] = '\0';
+ split_data[i][0] = '\0';
break;
}
*split = '\0';
@@ -9138,90 +9137,98 @@ void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 <len>.w <ni str = split+1;
}
- aFree(whisper_tmp);
- whisper_tmp=(char *)aMallocA(15*sizeof(char));
-
for (i=0;i<10;i++)
{
- sprintf(whisper_tmp, "@whispervar%d$", i);
- set_var(sd,whisper_tmp,(char *) split_data[i]);
- }//You don't need to zero them, just reset them [Kevin]
-
- aFree(whisper_tmp);
- whisper_tmp=(char *)aMallocA((strlen(npc->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 <nick>.24B <type>.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 <type>.B <fail>.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 <type>len.B: 00 (/exall) deny all speech, 01 (/inall) allow all speech
- WFIFOHEAD(fd,packet_len_table[0xd2]);
- WFIFOW(fd,0) = 0x0d2; // R 00d2 <type>.B <fail>.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 <type>.B <fail>.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 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
+ // S 00d0 <type>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;i<MAX_IGNORE_LIST;i++){ //拒否リストに名前があるかどうか判定してあれば拒否
- if(strcmp(sd->ignore[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;
|