diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-01-14 19:13:16 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-01-14 19:13:16 +0000 |
commit | a9dd834853966a4b7421cc643c30ad9996f6b039 (patch) | |
tree | 32983448f8498c02f29733bf3995b6752077c050 /src/map/clif.c | |
parent | 05bff4bc98f620ae2f037028b72c11caddb6ac3f (diff) | |
download | hercules-a9dd834853966a4b7421cc643c30ad9996f6b039.tar.gz hercules-a9dd834853966a4b7421cc643c30ad9996f6b039.tar.bz2 hercules-a9dd834853966a4b7421cc643c30ad9996f6b039.tar.xz hercules-a9dd834853966a4b7421cc643c30ad9996f6b039.zip |
* Client packet corrections
- 0x01df is not 'gmreqnochatcount', but for requesting a player's account name via right-click menu (which currently can't be done)
- added /remove and /recall, aliases to /shift and /summon
- added /changemaptype, which alters a single cell's gat type
- gm kick will no longer exit the client (now it goes to the login screen)
- removed the quicksort invocation in /ignore code
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12076 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 274 |
1 files changed, 156 insertions, 118 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 79ec6e8e4..4b0b7e7ec 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3613,16 +3613,15 @@ void clif_standing(struct block_list* bl) /*========================================== * Inform client(s) about a map-cell change *------------------------------------------*/ -void clif_changemapcell(int fd, struct block_list* pos, int type, enum send_target target) +void clif_changemapcell(int fd, int m, int x, int y, int type, enum send_target target) { unsigned char buf[32]; - nullpo_retv(pos); WBUFW(buf,0) = 0x192; - WBUFW(buf,2) = pos->x; - WBUFW(buf,4) = pos->y; + WBUFW(buf,2) = x; + WBUFW(buf,4) = y; WBUFW(buf,6) = type; - mapindex_getmapname_ext(map[pos->m].name,(char*)WBUFP(buf,8)); + mapindex_getmapname_ext(map[m].name,(char*)WBUFP(buf,8)); if( fd ) { @@ -3631,7 +3630,14 @@ void clif_changemapcell(int fd, struct block_list* pos, int type, enum send_targ WFIFOSET(fd,packet_len(0x192)); } else - clif_send(buf,packet_len(0x192),pos,target); + { + struct block_list dummy_bl; + dummy_bl.type = BL_NUL; + dummy_bl.x = x; + dummy_bl.y = y; + dummy_bl.m = m; + clif_send(buf,packet_len(0x192),&dummy_bl,target); + } } /*========================================== @@ -3696,7 +3702,7 @@ static void clif_getareachar_skillunit(struct map_session_data *sd, struct skill WFIFOSET(fd,packet_len(0x11f)); if(unit->group->skill_id == WZ_ICEWALL) - clif_changemapcell(fd,&unit->bl,5,SELF); + clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,5,SELF); } /*========================================== @@ -3712,7 +3718,7 @@ static void clif_clearchar_skillunit(struct skill_unit *unit, int fd) WFIFOSET(fd,packet_len(0x120)); if(unit->group && unit->group->skill_id == WZ_ICEWALL) - clif_changemapcell(fd,&unit->bl,unit->val2,SELF); + clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,SELF); } /*========================================== @@ -6878,23 +6884,18 @@ int clif_GM_kickack(struct map_session_data *sd, int id) return 0; } -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) { int fd = tsd->fd; - WFIFOHEAD(fd,packet_len(0x18b)); - if(type) - clif_GM_kickack(sd,tsd->status.account_id); - if (!fd) { + + if( fd > 0 ) + clif_authfail_fd(fd, 15); + else map_quit(tsd); - return 0; - } - WFIFOW(fd,0) = 0x18b; - WFIFOW(fd,2) = 0; - WFIFOSET(fd,packet_len(0x18b)); - clif_setwaitclose(fd); + if( type ) + clif_GM_kickack(sd,tsd->status.account_id); + return 0; } @@ -10202,7 +10203,11 @@ void clif_parse_ChangePetName(int fd, struct map_session_data *sd) pet_change_name(sd,(char*)RFIFOP(fd,2)); } -// Kick (right click menu for GM "(name) force to quit") +/*========================================== + * /kill <???> + * (or right click menu for GM "(name) force to quit") + * S 00cc <id>.L + *------------------------------------------*/ void clif_parse_GMKick(int fd, struct map_session_data *sd) { struct block_list *target; @@ -10265,9 +10270,17 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) } /*========================================== - * /shift + * /killall + *------------------------------------------*/ +void clif_parse_GMKickAll(int fd, struct map_session_data* sd) +{ + is_atcommand(fd, sd, "@kickall"); +} + +/*========================================== + * /shift <name> *------------------------------------------*/ -void clif_parse_Shift(int fd, struct map_session_data *sd) +void clif_parse_GMShift(int fd, struct map_session_data *sd) { char *player_name; int lv; @@ -10285,13 +10298,12 @@ void clif_parse_Shift(int fd, struct map_session_data *sd) sprintf(message, "/shift %s", player_name); log_atcommand(sd, message); } - return; } /*========================================== - * /recall + * /recall <name> *------------------------------------------*/ -void clif_parse_Recall(int fd, struct map_session_data *sd) +void clif_parse_GMRecall(int fd, struct map_session_data *sd) { char *player_name; int lv; @@ -10310,7 +10322,6 @@ void clif_parse_Recall(int fd, struct map_session_data *sd) sprintf(message, "/recall %s", player_name); log_atcommand(sd, message); } - return; } /*========================================== @@ -10380,23 +10391,23 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd) } /*========================================== - * GMによるチャット禁止時間付与 + * GM adjustment of a player's manner value + * /red + * S 0149 <id>.L <type>.B <value>.W + * type: 0 - positive points + * 1 - negative points *------------------------------------------*/ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) { - int type, limit, level; - struct block_list *bl; + int type, value, level; struct map_session_data *dstsd; - bl = map_id2bl(RFIFOL(fd,2)); - if (!bl || bl->type != BL_PC) - return; - dstsd =(struct map_session_data *)bl; - + dstsd = map_id2sd(RFIFOL(fd,2)); type = RFIFOB(fd,6); - limit = RFIFOW(fd,7); + value = RFIFOW(fd,7); + if (type == 0) - limit = 0 - limit; + value = 0 - value; //If type is 2 and the ids don't match, this is a crafted hacked packet! //Disabled because clients keep self-muting when you give players public @ commands... [Skotlex] @@ -10408,65 +10419,83 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) || (type == 2 && !level)) { clif_GM_silence(sd, dstsd, ((type == 2) ? 1 : type)); - dstsd->status.manner -= limit; + dstsd->status.manner -= value; if(dstsd->status.manner < 0) - sc_start(bl,SC_NOCHAT,100,0,0); + sc_start(&sd->bl,SC_NOCHAT,100,0,0); else { dstsd->status.manner = 0; - status_change_end(bl,SC_NOCHAT,-1); + status_change_end(&sd->bl,SC_NOCHAT,-1); } } - - return; } + /*========================================== - * GMによるチャット禁止時間参照(?) + * GM requesting account name (for right-click gm menu) + * S 01df <id>.L + * R 01e0 <id>.L <name>.24B *------------------------------------------*/ -void clif_parse_GMReqNoChatCount(int fd, struct map_session_data *sd) +void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd) { int tid; tid = RFIFOL(fd,2); + //TODO: find out if this works for any player or only for authorized GMs + WFIFOHEAD(fd,packet_len(0x1e0)); WFIFOW(fd,0) = 0x1e0; WFIFOL(fd,2) = tid; - sprintf((char*)WFIFOP(fd,6),"%d",tid); + safestrncpy((char*)WFIFOP(fd,6), "", 24); // insert account name here >_< WFIFOSET(fd, packet_len(0x1e0)); - - return; } -static int pstrcmp(const void *a, const void *b) +/*========================================== + * GM single cell type change request + * /changemaptype <x> <y> <type> + * S 0198 <x>.W <y>.W <gat>.W + *------------------------------------------*/ +void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd) { - char *name1 = (char *)a; - char *name2 = (char *)b; - if (name1[0] && name2[0]) - return strcmp(name1, name2); - //Since names are sorted in ascending order, send blank entries to the bottom. - if (name1[0]) - return -1; - if (name2[0]) - return 1; - return 0; + int x,y,type; + + if( battle_config.atc_gmonly && !pc_isGM(sd) ) + return; + + if( pc_isGM(sd) < 99 ) //TODO: add proper check + return; + + x = RFIFOW(fd,2); + y = RFIFOW(fd,4); + type = RFIFOW(fd,6); + + map_setgatcell(sd->bl.m,x,y,type); + clif_changemapcell(0,sd->bl.m,x,y,type,ALL_SAMEMAP); + //FIXME: once players leave the map, the client 'forgets' this information. } -void clif_parse_PMIgnore(int fd, struct map_session_data *sd) +/// S 00cf <nick>.24B <type>.B +/// type: 0 (/ex nick) deny speech from nick +/// 1 (/in nick) allow speech from nick +/// +/// R 00d1 <type>.B <result>.B +/// type: 0: deny, 1: allow +/// result: 0: success, 1: fail 2: list full +void clif_parse_PMIgnore(int fd, struct map_session_data* sd) { 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 + char* nick; + uint8 type; int i; - memset(output, '\0', sizeof(output)); - nick = (char*)RFIFOP(fd,2); // speed up - nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name have at maximum 23 characters + nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name has at most 23 characters + type = RFIFOB(fd,26); WFIFOHEAD(fd,packet_len(0xd1)); - WFIFOW(fd,0) = 0x0d1; // R 00d1 <type>.B <result>.B: type: 0: deny, 1: allow, result: 0: success, 1: fail 2: list full - WFIFOB(fd,2) = RFIFOB(fd,26); + WFIFOW(fd,0) = 0x0d1; + WFIFOB(fd,2) = type; - if (RFIFOB(fd,26) == 0) + if( type == 0 ) { // Add name to ignore list (block) // Bot-check... @@ -10480,83 +10509,87 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) } // try to find a free spot, while checking for duplicates at the same time - 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) { // no space for new entry + ARR_FIND( 0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0 ); + if( i == MAX_IGNORE_LIST ) + {// no space for new entry WFIFOB(fd,3) = 2; // fail WFIFOSET(fd, packet_len(0x0d1)); return; } - if(sd->ignore[i].name[0] != '\0') { // name already exists + if( sd->ignore[i].name[0] != '\0' ) + {// name already exists WFIFOB(fd,3) = 0; // Aegis reports success. WFIFOSET(fd, packet_len(0x0d1)); return; } + //Insert in position i - memcpy(sd->ignore[i].name, nick, NAME_LENGTH); + safestrncpy(sd->ignore[i].name, nick, NAME_LENGTH); + WFIFOB(fd,3) = 0; // success WFIFOSET(fd, packet_len(0x0d1)); - - //Sort the ignore list. - //FIXME: why not just use a simple shift-and-insert scheme instead? [ultramage] - qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp); } else { // Remove name from ignore list (unblock) - - 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 + // find entry + ARR_FIND( 0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0 ); + if( i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0' ) + { //Not found WFIFOB(fd,3) = 1; // fail WFIFOSET(fd, packet_len(0x0d1)); return; } - //Move everything one place down to overwrite removed entry. + // 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)); + // wipe last entry memset(sd->ignore[MAX_IGNORE_LIST-1].name, 0, sizeof(sd->ignore[0].name)); + WFIFOB(fd,3) = 0; // success WFIFOSET(fd, packet_len(0x0d1)); } - //for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0'; i++) - // ShowDebug("Ignored player: '%s'\n", sd->ignore[i].name); return; } +/// S 00d0 <type>.B +/// type: 0 (/exall) deny all speech +/// 1 (/inall) allow all speech +/// +/// R 00d2 <type>.B <fail>.B +/// type: 0: deny, 1: allow +/// fail: 0: success, 1: fail void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { - //printf("Ignore all: state: %d\n", RFIFOB(fd,2)); - // 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 WFIFOHEAD(fd,packet_len(0xd2)); WFIFOW(fd,0) = 0x0d2; WFIFOB(fd,2) = RFIFOB(fd,2); - if (RFIFOB(fd,2) == 0) { //Deny all - if (sd->state.ignoreAll) { + + if( RFIFOB(fd,2) == 0 ) + {// Deny all + if( sd->state.ignoreAll ) { WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len(0x0d2)); - return; + } else { + sd->state.ignoreAll = 1; + WFIFOB(fd,3) = 0; // success } - sd->state.ignoreAll = 1; - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len(0x0d2)); - return; } - //Unblock everyone - if (!sd->state.ignoreAll) { - if (sd->ignore[0].name[0] != '\0') - { //Wipe the ignore list. - memset(sd->ignore, 0, sizeof(sd->ignore)); - WFIFOB(fd,3) = 0; - WFIFOSET(fd, packet_len(0x0d2)); - return; + else + {//Unblock everyone + if( sd->state.ignoreAll ) { + sd->state.ignoreAll = 0; + WFIFOB(fd,3) = 0; // success + } else { + if (sd->ignore[0].name[0] != '\0') + { //Wipe the ignore list. + memset(sd->ignore, 0, sizeof(sd->ignore)); + WFIFOB(fd,3) = 0; // success + } else { + WFIFOB(fd,3) = 1; // fail + } } - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len(0x0d2)); - return; } - sd->state.ignoreAll = 0; - WFIFOB(fd,3) = 0; // success + WFIFOSET(fd, packet_len(0x0d2)); return; } @@ -10844,14 +10877,6 @@ void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd) } /*========================================== - * /killall - *------------------------------------------*/ -void clif_parse_GMKillAll(int fd, struct map_session_data* sd) -{ - is_atcommand(fd, sd, "@kickall"); -} - -/*========================================== * /pvpinfo *------------------------------------------*/ void clif_parse_PVPInfo(int fd,struct map_session_data *sd) @@ -11131,6 +11156,13 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd) pc_delitem(sd, item_position, 1, 0); } +/// /check <string> +/// S 0213 <string>.24B +void clif_parse_Check(int fd, struct map_session_data *sd) +{ + // no info +} + #ifndef TXT_ONLY /*========================================== * MAIL SYSTEM @@ -11898,10 +11930,19 @@ static int packetdb_readdb(void) {clif_parse_SelectEgg,"selectegg"}, {clif_parse_SendEmotion,"sendemotion"}, {clif_parse_ChangePetName,"changepetname"}, + {clif_parse_GMKick,"gmkick"}, {clif_parse_GMHide,"gmhide"}, {clif_parse_GMReqNoChat,"gmreqnochat"}, - {clif_parse_GMReqNoChatCount,"gmreqnochatcount"}, + {clif_parse_GMReqAccountName,"gmreqaccname"}, + {clif_parse_GMKickAll,"killall"}, + {clif_parse_GMRecall,"recall"}, + {clif_parse_GMRecall,"summon"}, + {clif_parse_GM_Monster_Item,"itemmonster"}, + {clif_parse_GMShift,"remove"}, + {clif_parse_GMShift,"shift"}, + {clif_parse_GMChangeMapType,"changemaptype"}, + {clif_parse_NoviceDoriDori,"sndoridori"}, {clif_parse_NoviceExplosionSpirits,"snexplosionspirits"}, {clif_parse_PMIgnore,"wisexin"}, @@ -11910,10 +11951,6 @@ static int packetdb_readdb(void) {clif_parse_FriendsListAdd,"friendslistadd"}, {clif_parse_FriendsListRemove,"friendslistremove"}, {clif_parse_FriendsListReply,"friendslistreply"}, - {clif_parse_GMKillAll,"killall"}, - {clif_parse_Recall,"summon"}, - {clif_parse_GM_Monster_Item,"itemmonster"}, - {clif_parse_Shift,"shift"}, {clif_parse_Blacksmith,"blacksmith"}, {clif_parse_Alchemist,"alchemist"}, {clif_parse_Taekwon,"taekwon"}, @@ -11929,6 +11966,7 @@ static int packetdb_readdb(void) {clif_parse_StoragePassword,"storagepassword"}, {clif_parse_Hotkey,"hotkey"}, {clif_parse_AutoRevive,"autorevive"}, + {clif_parse_Check,"check"}, #ifndef TXT_ONLY // MAIL SYSTEM {clif_parse_Mail_refreshinbox,"mailrefresh"}, |