- 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://svn.code.sf.net/p/rathena/svn/trunk@9282 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
7abcd45cd3
commit
0f433c6c45
@ -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]
|
||||
|
421
src/map/clif.c
421
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]
|
||||
sprintf(output, "@whispervar%d$", i);
|
||||
set_var(sd,output,(char *) split_data[i]);
|
||||
}
|
||||
|
||||
aFree(whisper_tmp);
|
||||
whisper_tmp=(char *)aMallocA((strlen(npc->name)+18)*sizeof(char));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// name can exist
|
||||
// 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++);
|
||||
|
||||
// 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) { //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);
|
||||
}
|
||||
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++);
|
||||
|
||||
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 {
|
||||
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 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 {
|
||||
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‹‘”ÛƒŠƒXƒg
|
||||
*------------------------------------------
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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); // ‘—<E28098>M<EFBFBD>¬Œ÷
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user