diff options
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 868 |
1 files changed, 527 insertions, 341 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 827f57c45..69d9b6779 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -198,22 +198,6 @@ static inline bool disguised(struct block_list* bl) return true; } -//Guarantees that the given string does not exceeds the allowed size, as well as making sure it's null terminated. [Skotlex] -static inline unsigned int mes_len_check(char* mes, unsigned int len, unsigned int max) { - nullpo_retr(0, mes); - if (len <= 0) - { - mes[0] = '\0'; - Assert_retr(0, len > 0); - } - if( len > max ) - len = max; - - mes[len-1] = '\0'; - - return len; -} - /*========================================== * Ip setting of map-server *------------------------------------------*/ @@ -645,7 +629,7 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target break; default: - ShowError("clif_send: Unrecognized type %d\n",type); + ShowError("clif_send: Unrecognized type %u\n", type); return false; } @@ -1010,7 +994,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu #endif #if PACKETVER >= 20131223 p.AID = bl->id; - p.GID = (sd) ? sd->status.char_id : 0; // CCODE + p.GID = (sd) ? sd->status.char_id : 0; // CCODE #else p.GID = bl->id; #endif @@ -1065,6 +1049,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu #endif #if PACKETVER >= 20150513 p.body = vd->body_style; + safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH); #endif clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); @@ -1151,7 +1136,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { #endif #if PACKETVER >= 20131223 p.AID = bl->id; - p.GID = (sd) ? sd->status.char_id : 0; // CCODE + p.GID = (sd) ? sd->status.char_id : 0; // CCODE #else p.GID = bl->id; #endif @@ -1205,6 +1190,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { #endif #if PACKETVER >= 20150513 p.body = vd->body_style; + safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH); #endif if( disguised(bl) ) { nullpo_retv(sd); @@ -1246,7 +1232,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, #endif #if PACKETVER >= 20131223 p.AID = bl->id; - p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE + p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE #else p.GID = bl->id; #endif @@ -1296,6 +1282,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, #endif #if PACKETVER >= 20150513 p.body = vd->body_style; + safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH); #endif clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); @@ -1612,7 +1599,7 @@ void clif_homskillinfoblock(struct map_session_data *sd) { WFIFOW(fd, len + 8) = 0; WFIFOW(fd, len + 10) = 0; } - safestrncpy((char*)WFIFOP(fd, len + 12), skill->get_name(id), NAME_LENGTH); + safestrncpy(WFIFOP(fd, len + 12), skill->get_name(id), NAME_LENGTH); WFIFOB(fd, len + 36) = (hd->homunculus.hskill[j].lv < homun->skill_tree_get_max(id, hd->homunculus.class_)) ? 1 : 0; len += 37; } @@ -1816,7 +1803,7 @@ void clif_changemap(struct map_session_data *sd, short m, int x, int y) { WFIFOHEAD(fd,packet_len(0x91)); WFIFOW(fd,0) = 0x91; - mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name, (char*)WFIFOP(fd,2)); + mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name, WFIFOP(fd,2)); WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; WFIFOSET(fd,packet_len(0x91)); @@ -1831,7 +1818,7 @@ void clif_changemapserver(struct map_session_data* sd, unsigned short map_index, WFIFOHEAD(fd,packet_len(0x92)); WFIFOW(fd,0) = 0x92; - mapindex->getmapname_ext(mapindex_id2name(map_index), (char*)WFIFOP(fd,2)); + mapindex->getmapname_ext(mapindex_id2name(map_index), WFIFOP(fd,2)); WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; WFIFOL(fd,22) = htonl(ip); @@ -1984,7 +1971,7 @@ void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes) { WFIFOW(fd,0)=0xb4; WFIFOW(fd,2)=slen; WFIFOL(fd,4)=npcid; - memcpy((char*)WFIFOP(fd,8), mes, slen-8); + memcpy(WFIFOP(fd,8), mes, slen-8); WFIFOSET(fd,WFIFOW(fd,2)); } @@ -2103,7 +2090,7 @@ void clif_scriptmenu(struct map_session_data* sd, int npcid, const char* mes) { WFIFOW(fd,0)=0xb7; WFIFOW(fd,2)=slen; WFIFOL(fd,4)=npcid; - memcpy((char*)WFIFOP(fd,8), mes, slen-8); + memcpy(WFIFOP(fd,8), mes, slen-8); WFIFOSET(fd,WFIFOW(fd,2)); } @@ -2211,7 +2198,7 @@ void clif_cutin(struct map_session_data* sd, const char* image, int type) fd=sd->fd; WFIFOHEAD(fd, packet_len(0x1b3)); WFIFOW(fd,0)=0x1b3; - strncpy((char*)WFIFOP(fd,2),image,64); + strncpy(WFIFOP(fd,2),image,64); WFIFOB(fd,66)=type; WFIFOSET(fd,packet_len(0x1b3)); } @@ -2333,9 +2320,9 @@ void clif_add_random_options(unsigned char* buf, struct item* item) int i; nullpo_retv(buf); for (i = 0; i < 5; i++){ - WBUFW(buf,i*5+0) = 0; // OptIndex - WBUFW(buf,i*5+2) = 0; // Value - WBUFB(buf,i*5+4) = 0; // Param1 + WBUFW(buf,i*5+0) = 0; // OptIndex + WBUFW(buf,i*5+2) = 0; // Value + WBUFB(buf,i*5+4) = 0; // Param1 } } @@ -3642,7 +3629,7 @@ void clif_dispchat(struct chat_data* cd, int fd) WBUFW(buf,12) = cd->limit; WBUFW(buf,14) = (cd->owner->type == BL_NPC) ? cd->users+1 : cd->users; WBUFB(buf,16) = type; - memcpy((char*)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated + memcpy(WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated if( fd ) { WFIFOHEAD(fd,WBUFW(buf,2)); @@ -3679,7 +3666,7 @@ void clif_changechatstatus(struct chat_data* cd) WBUFW(buf,12) = cd->limit; WBUFW(buf,14) = (cd->owner->type == BL_NPC) ? cd->users+1 : cd->users; WBUFB(buf,16) = type; - memcpy((char*)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated + memcpy(WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated clif->send(buf,WBUFW(buf,2),cd->owner,CHAT); } @@ -3841,7 +3828,7 @@ void clif_traderequest(struct map_session_data *sd, const char *name) #if PACKETVER < 6 WFIFOHEAD(fd,packet_len(0xe5)); WFIFOW(fd,0) = 0xe5; - safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,2), name, NAME_LENGTH); WFIFOSET(fd,packet_len(0xe5)); #else // PACKETVER >= 6 tsd = map->id2sd(sd->trade_partner); @@ -3850,7 +3837,7 @@ void clif_traderequest(struct map_session_data *sd, const char *name) WFIFOHEAD(fd,packet_len(0x1f4)); WFIFOW(fd,0) = 0x1f4; - safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,2), name, NAME_LENGTH); WFIFOL(fd,26) = tsd->status.char_id; WFIFOW(fd,30) = tsd->status.base_level; WFIFOSET(fd,packet_len(0x1f4)); @@ -4330,7 +4317,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int p.leftDamage = damage2; } #if PACKETVER >= 20131223 - p.is_sp_damaged = 0; // [ToDo] IsSPDamage - Displays blue digits. + p.is_sp_damaged = 0; // TODO: IsSPDamage - Displays blue digits. #endif if(disguised(dst)) { @@ -4425,7 +4412,7 @@ void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_targe WBUFW(buf,2) = x; WBUFW(buf,4) = y; WBUFW(buf,6) = type; - mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name,(char*)WBUFP(buf,8)); + mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name, WBUFP(buf,8)); if( fd ) { WFIFOHEAD(fd,packet_len(0x192)); @@ -4735,7 +4722,7 @@ void clif_skillinfoblock(struct map_session_data *sd) WFIFOW(fd, len + 8) = 0; WFIFOW(fd, len + 10)= 0; } - safestrncpy((char*)WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH); + safestrncpy(WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH); if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill->tree_get_max(id, sd->status.class_))? 1:0; else @@ -4786,7 +4773,7 @@ void clif_addskill(struct map_session_data *sd, int id) WFIFOW(fd,10) = 0; WFIFOW(fd,12) = 0; } - safestrncpy((char*)WFIFOP(fd,14), skill->get_name(id), NAME_LENGTH); + safestrncpy(WFIFOP(fd,14), skill->get_name(id), NAME_LENGTH); if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) WFIFOB(fd,38) = (skill_lv < skill->tree_get_max(id, sd->status.class_))? 1:0; else @@ -5078,7 +5065,7 @@ int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick // type 6 (ACTION_SKILL) skills. So we have to do a small // hack to set all type 6 to be sent as type 8 ACTION_ATTACK_MULTIPLE #if PACKETVER < 20131223 - WBUFB(buf, 32) = type; + WBUFB(buf, 32) = type; #else WBUFB(buf, 32) = (type == BDT_SKILL) ? BDT_MULTIHIT : type; #endif @@ -5227,12 +5214,12 @@ void clif_skill_warppoint(struct map_session_data* sd, uint16 skill_id, uint16 s WFIFOW(fd,0) = 0x11c; WFIFOW(fd,2) = skill_id; memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT); - if (map1 == (unsigned short)-1) strcpy((char*)WFIFOP(fd,4), "Random"); + if (map1 == (unsigned short)-1) strcpy(WFIFOP(fd,4), "Random"); else // normal map name - if (map1 > 0) mapindex->getmapname_ext(mapindex_id2name(map1), (char*)WFIFOP(fd,4)); - if (map2 > 0) mapindex->getmapname_ext(mapindex_id2name(map2), (char*)WFIFOP(fd,20)); - if (map3 > 0) mapindex->getmapname_ext(mapindex_id2name(map3), (char*)WFIFOP(fd,36)); - if (map4 > 0) mapindex->getmapname_ext(mapindex_id2name(map4), (char*)WFIFOP(fd,52)); + if (map1 > 0) mapindex->getmapname_ext(mapindex_id2name(map1), WFIFOP(fd,4)); + if (map2 > 0) mapindex->getmapname_ext(mapindex_id2name(map2), WFIFOP(fd,20)); + if (map3 > 0) mapindex->getmapname_ext(mapindex_id2name(map3), WFIFOP(fd,36)); + if (map4 > 0) mapindex->getmapname_ext(mapindex_id2name(map4), WFIFOP(fd,52)); WFIFOSET(fd,packet_len(0x11c)); sd->menuskill_id = skill_id; @@ -5508,7 +5495,7 @@ void clif_displaymessage(const int fd, const char* mes) { WFIFOHEAD(fd, 5 + len); WFIFOW(fd,0) = 0x8e; WFIFOW(fd,2) = 5 + len; // 4 + len + NULL terminate - safestrncpy((char *)WFIFOP(fd,4), mes, len + 1); + safestrncpy(WFIFOP(fd,4), mes, len + 1); WFIFOSET(fd, 5 + len); } #endif @@ -5538,7 +5525,7 @@ void clif_displaymessage2(const int fd, const char* mes) { WFIFOHEAD(fd, 5 + len); WFIFOW(fd,0) = 0x8e; WFIFOW(fd,2) = 5 + len; // 4 + len + NULL terminate - safestrncpy((char *)WFIFOP(fd,4), line, len + 1); + safestrncpy(WFIFOP(fd,4), line, len + 1); WFIFOSET(fd, 5 + len); } } @@ -5567,11 +5554,11 @@ void clif_displaymessage_sprintf(const int fd, const char *mes, ...) { /* process */ va_start(ap,mes); - len += vsnprintf((char *)WFIFOP(fd,4), 255, mes, ap); + len += vsnprintf(WFIFOP(fd,4), 255, mes, ap); va_end(ap); /* adjusting */ - ptr = (char *)WFIFOP(fd,4); + ptr = WFIFOP(fd,4); ptr[len - 1] = '\0'; /* */ @@ -5625,7 +5612,7 @@ void clif_GlobalMessage(struct block_list* bl, const char* message) { WBUFW(buf,0)=0x8d; WBUFW(buf,2)=len+8; WBUFL(buf,4)=bl->id; - safestrncpy((char *) WBUFP(buf,8),message,len); + safestrncpy(WBUFP(buf,8),message,len); clif->send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT); } @@ -5818,8 +5805,8 @@ void clif_wis_message(int fd, const char *nick, const char *mes, size_t mes_len) WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4); WFIFOW(fd,0) = 0x97; WFIFOW(fd,2) = mes_len + NAME_LENGTH + 4; - safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH); - safestrncpy((char*)WFIFOP(fd,28), mes, mes_len); + safestrncpy(WFIFOP(fd,4), nick, NAME_LENGTH); + safestrncpy(WFIFOP(fd,28), mes, mes_len); WFIFOSET(fd,WFIFOW(fd,2)); #else ssd = map->nick2sd(nick); @@ -5827,9 +5814,9 @@ void clif_wis_message(int fd, const char *nick, const char *mes, size_t mes_len) WFIFOHEAD(fd, mes_len + NAME_LENGTH + 8); WFIFOW(fd,0) = 0x97; WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8; - safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH); + safestrncpy(WFIFOP(fd,4), nick, NAME_LENGTH); WFIFOL(fd,28) = (ssd && pc_get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char - safestrncpy((char*)WFIFOP(fd,32), mes, mes_len); + safestrncpy(WFIFOP(fd,32), mes, mes_len); WFIFOSET(fd,WFIFOW(fd,2)); #endif } @@ -5865,7 +5852,7 @@ void clif_solved_charname(int fd, int charid, const char* name) WFIFOHEAD(fd,packet_len(0x194)); WFIFOW(fd,0)=0x194; WFIFOL(fd,2)=charid; - safestrncpy((char*)WFIFOP(fd,6), name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,6), name, NAME_LENGTH); WFIFOSET(fd,packet_len(0x194)); } @@ -6089,7 +6076,7 @@ void clif_item_skill(struct map_session_data *sd,uint16 skill_id,uint16 skill_lv WFIFOW(fd, 8)=skill_lv; WFIFOW(fd,10)=skill->get_sp(skill_id,skill_lv); WFIFOW(fd,12)=skill->get_range2(&sd->bl, skill_id,skill_lv); - safestrncpy((char*)WFIFOP(fd,14),skill->get_name(skill_id),NAME_LENGTH); + safestrncpy(WFIFOP(fd,14),skill->get_name(skill_id),NAME_LENGTH); WFIFOB(fd,38)=0; WFIFOSET(fd,packet_len(0x147)); } @@ -6176,7 +6163,7 @@ void clif_showvendingboard(struct block_list* bl, const char* message, int fd) WBUFW(buf,0) = 0x131; WBUFL(buf,2) = bl->id; - safestrncpy((char*)WBUFP(buf,6), message, 80); + safestrncpy(WBUFP(buf,6), message, 80); if( fd ) { WFIFOHEAD(fd,packet_len(0x131)); @@ -6404,7 +6391,7 @@ void clif_party_member_info(struct party_data *p, struct map_session_data *sd) WBUFB(buf,14) = (p->party.member[i].online)?0:1; memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH); memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH); - mapindex->getmapname_ext(map->list[sd->bl.m].custom_name ? map->list[map->list[sd->bl.m].instance_src_map].name : map->list[sd->bl.m].name, (char*)WBUFP(buf,63)); + mapindex->getmapname_ext(map->list[sd->bl.m].custom_name ? map->list[map->list[sd->bl.m].instance_src_map].name : map->list[sd->bl.m].name, WBUFP(buf,63)); WBUFB(buf,79) = (p->party.item&1)?1:0; WBUFB(buf,80) = (p->party.item&2)?1:0; clif->send(buf,packet_len(0x1e9),&sd->bl,PARTY); @@ -6437,7 +6424,7 @@ void clif_party_info(struct party_data* p, struct map_session_data *sd) WBUFL(buf,28+c*46) = m->account_id; memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH); - mapindex->getmapname_ext(mapindex_id2name(m->map), (char*)WBUFP(buf,28+c*46+28)); + mapindex->getmapname_ext(mapindex_id2name(m->map), WBUFP(buf,28+c*46+28)); WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1; WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1; c++; @@ -6525,13 +6512,13 @@ void clif_party_inviteack(struct map_session_data* sd, const char* nick, int res #if PACKETVER < 20070821 WFIFOHEAD(fd,packet_len(0xfd)); WFIFOW(fd,0) = 0xfd; - safestrncpy((char*)WFIFOP(fd,2),nick,NAME_LENGTH); + safestrncpy(WFIFOP(fd,2),nick,NAME_LENGTH); WFIFOB(fd,26) = result; WFIFOSET(fd,packet_len(0xfd)); #else WFIFOHEAD(fd,packet_len(0x2c5)); WFIFOW(fd,0) = 0x2c5; - safestrncpy((char*)WFIFOP(fd,2),nick,NAME_LENGTH); + safestrncpy(WFIFOP(fd,2),nick,NAME_LENGTH); WFIFOL(fd,26) = result; WFIFOSET(fd,packet_len(0x2c5)); #endif @@ -6637,7 +6624,7 @@ void clif_party_message(struct party_data* p, int account_id, const char* mes, i WBUFW(buf,0)=0x109; WBUFW(buf,2)=len+8; WBUFL(buf,4)=account_id; - safestrncpy((char *)WBUFP(buf,8), mes, len); + safestrncpy(WBUFP(buf,8), mes, len); clif->send(buf,len+8,&sd->bl,PARTY); } } @@ -7303,7 +7290,7 @@ void clif_guild_basicinfo(struct map_session_data *sd) { memcpy(WFIFOP(fd,46),g->name, NAME_LENGTH); memcpy(WFIFOP(fd,70),g->master, NAME_LENGTH); - safestrncpy((char*)WFIFOP(fd,94),msg_sd(sd,300+guild->checkcastles(g)),16); // "'N' castles" + safestrncpy(WFIFOP(fd,94),msg_sd(sd,300+guild->checkcastles(g)),16); // "'N' castles" WFIFOL(fd,110) = 0; // zeny WFIFOSET(fd,packet_len(0x1b6)); @@ -7546,7 +7533,7 @@ void clif_guild_skillinfo(struct map_session_data* sd) WFIFOW(fd, p + 8) = 0; WFIFOW(fd, p + 10) = 0; } - safestrncpy((char*)WFIFOP(fd,p+12), skill->get_name(id), NAME_LENGTH); + safestrncpy(WFIFOP(fd,p+12), skill->get_name(id), NAME_LENGTH); WFIFOB(fd,p+36)= (g->skill[i].lv < guild->skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0; c++; } @@ -7647,8 +7634,8 @@ void clif_guild_expulsion(struct map_session_data* sd, const char* name, const c nullpo_retv(mes); WBUFW(buf,0) = cmd; - safestrncpy((char*)WBUFP(buf,2), name, NAME_LENGTH); - safestrncpy((char*)WBUFP(buf,26), mes, 40); + safestrncpy(WBUFP(buf,2), name, NAME_LENGTH); + safestrncpy(WBUFP(buf,26), mes, 40); #if PACKETVER < 20100803 memset(WBUFP(buf,66), 0, NAME_LENGTH); // account name (not used for security reasons) #endif @@ -7715,7 +7702,7 @@ void clif_guild_message(struct guild *g,int account_id,const char *mes,int len) WBUFW(buf, 0) = 0x17f; WBUFW(buf, 2) = len + 5; - safestrncpy((char*)WBUFP(buf,4), mes, len+1); + safestrncpy(WBUFP(buf,4), mes, len+1); if ((sd = guild->getavailablesd(g)) != NULL) clif->send(buf, WBUFW(buf,2), &sd->bl, GUILD_NOBG); @@ -7859,7 +7846,7 @@ void clif_talkiebox(struct block_list* bl, const char* talkie) WBUFW(buf,0) = 0x191; WBUFL(buf,2) = bl->id; - safestrncpy((char*)WBUFP(buf,6),talkie,MESSAGE_SIZE); + safestrncpy(WBUFP(buf,6),talkie,MESSAGE_SIZE); clif->send(buf,packet_len(0x191),bl,AREA); } @@ -7942,7 +7929,7 @@ void clif_marriage_proposal(int fd, struct map_session_data *sd, struct map_sess WFIFOW(fd,0) = 0x1e2; WFIFOL(fd,2) = ssd->status.account_id; WFIFOL(fd,6) = ssd->status.char_id; - safestrncpy((char*)WFIFOP(fd,10), ssd->status.name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,10), ssd->status.name, NAME_LENGTH); WFIFOSET(fd, packet_len(0x1e2)); } */ @@ -7967,7 +7954,7 @@ void clif_disp_message(struct block_list* src, const char* mes, size_t len, enum WBUFW(buf, 0) = 0x17f; WBUFW(buf, 2) = len + 5; - safestrncpy((char*)WBUFP(buf,4), mes, len+1); + safestrncpy(WBUFP(buf,4), mes, len+1); clif->send(buf, WBUFW(buf,2), src, target); } @@ -8041,7 +8028,7 @@ void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, WFIFOHEAD(fd,packet_len(0x14b)); WFIFOW(fd,0) = 0x14b; WFIFOB(fd,2) = type; - safestrncpy((char*)WFIFOP(fd,3), sd->status.name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,3), sd->status.name, NAME_LENGTH); WFIFOSET(fd, packet_len(0x14b)); } @@ -8099,7 +8086,7 @@ void clif_playBGM(struct map_session_data* sd, const char* name) fd = sd->fd; WFIFOHEAD(fd,packet_len(0x7fe)); WFIFOW(fd,0) = 0x7fe; - safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,2), name, NAME_LENGTH); WFIFOSET(fd,packet_len(0x7fe)); } @@ -8127,7 +8114,7 @@ void clif_soundeffect(struct map_session_data* sd, struct block_list* bl, const fd = sd->fd; WFIFOHEAD(fd,packet_len(0x1d3)); WFIFOW(fd,0) = 0x1d3; - safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,2), name, NAME_LENGTH); WFIFOB(fd,26) = type; WFIFOL(fd,27) = 0; WFIFOL(fd,31) = bl->id; @@ -8142,7 +8129,7 @@ void clif_soundeffectall(struct block_list* bl, const char* name, int type, enum nullpo_retv(name); WBUFW(buf,0) = 0x1d3; - safestrncpy((char*)WBUFP(buf,2), name, NAME_LENGTH); + safestrncpy(WBUFP(buf,2), name, NAME_LENGTH); WBUFB(buf,26) = type; WBUFL(buf,27) = 0; WBUFL(buf,31) = bl->id; @@ -8226,7 +8213,7 @@ void clif_messagecolor_self(int fd, uint32 color, const char *msg) WFIFOW(fd,2) = msg_len + 12; WFIFOL(fd,4) = 0; WFIFOL(fd,8) = RGB2BGR(color); - safestrncpy((char*)WFIFOP(fd,12), msg, msg_len); + safestrncpy(WFIFOP(fd,12), msg, msg_len); WFIFOSET(fd, msg_len + 12); } @@ -8475,7 +8462,7 @@ void clif_charnameack (int fd, struct block_list *bl) memcpy(WBUFP(buf,6), BL_UCCAST(BL_ELEM, bl)->db->name, NAME_LENGTH); break; default: - ShowError("clif_charnameack: bad type %d(%d)\n", bl->type, bl->id); + ShowError("clif_charnameack: bad type %u(%d)\n", bl->type, bl->id); return; } @@ -8586,14 +8573,14 @@ void clif_disp_overhead(struct block_list *bl, const char* mes) WBUFW(buf,0) = 0x8d; WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id) WBUFL(buf,4) = bl->id; - safestrncpy((char*)WBUFP(buf,8), mes, len_mes); + safestrncpy(WBUFP(buf,8), mes, len_mes); clif->send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); // send back message to the speaker if( bl->type == BL_PC ) { WBUFW(buf,0) = 0x8e; WBUFW(buf, 2) = len_mes + 4; - safestrncpy((char*)WBUFP(buf,4), mes, len_mes); + safestrncpy(WBUFP(buf,4), mes, len_mes); clif->send(buf, WBUFW(buf,2), bl, SELF); } @@ -8680,7 +8667,7 @@ void clif_starskill(struct map_session_data* sd, const char* mapname, int monste WFIFOHEAD(fd,packet_len(0x20e)); WFIFOW(fd,0) = 0x20e; - safestrncpy((char*)WFIFOP(fd,2), mapname, NAME_LENGTH); + safestrncpy(WFIFOP(fd,2), mapname, NAME_LENGTH); WFIFOL(fd,26) = monster_id; WFIFOB(fd,30) = star; WFIFOB(fd,31) = result; @@ -8884,8 +8871,9 @@ void clif_msgtable_skill(struct map_session_data* sd, uint16 skill_id, int msg_i /// Returns true if the packet was parsed successfully. /// Formats: 0 - <packet id>.w <packet len>.w (<name> : <message>).?B 00 /// 1 - <packet id>.w <packet len>.w <name>.24B <message>.?B 00 -bool clif_process_message(struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_) { - char *text, *name, *message; +bool clif_process_message(struct map_session_data *sd, int format, const char **name_, size_t *namelen_, const char **message_, size_t *messagelen_) +{ + const char *text, *name, *message; unsigned int packetlen, textlen; size_t namelen, messagelen; int fd = sd->fd; @@ -8909,7 +8897,7 @@ bool clif_process_message(struct map_session_data *sd, int format, char **name_, return false; } - text = (char*)RFIFOP(fd,4); + text = RFIFOP(fd,4); textlen = packetlen - 4; // process <name> part of the packet @@ -9000,7 +8988,7 @@ void clif_channel_msg(struct channel_data *chan, struct map_session_data *sd, ch WFIFOW(sd->fd,2) = msg_len + 12; WFIFOL(sd->fd,4) = 0; WFIFOL(sd->fd,8) = RGB2BGR(color); - safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len); + safestrncpy(WFIFOP(sd->fd,12), msg, msg_len); for (user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter)) { if( user->fd == sd->fd ) @@ -9033,7 +9021,7 @@ void clif_channel_msg2(struct channel_data *chan, char *msg) WBUFW(buf,2) = msg_len + 12; WBUFL(buf,4) = 0; WBUFL(buf,8) = RGB2BGR(color); - safestrncpy((char*)WBUFP(buf,12), msg, msg_len); + safestrncpy(WBUFP(buf,12), msg, msg_len); for (user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter)) { WFIFOHEAD(user->fd,msg_len + 12); @@ -9730,10 +9718,11 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) __attribute__ /// There are various variants of this packet. void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) { - const char* text = (char*)RFIFOP(fd,4); + const char *text = RFIFOP(fd,4); size_t textlen = RFIFOW(fd,2) - 4; - char *name, *message, *fakename = NULL; + const char *name = NULL, *message = NULL; + char *fakename = NULL; size_t namelen, messagelen; bool is_fake; @@ -9818,7 +9807,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) WFIFOW(fd,2) = mylen + 12; WFIFOL(fd,4) = sd->bl.id; WFIFOL(fd,8) = RGB2BGR(color); - safestrncpy((char*)WFIFOP(fd,12), mout, mylen); + safestrncpy(WFIFOP(fd,12), mout, mylen); clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS); WFIFOL(fd,4) = -sd->bl.id; WFIFOSET(fd, mylen + 12); @@ -9840,7 +9829,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) WFIFOW(fd,0) = 0x8d; WFIFOW(fd,2) = 8 + textlen; WFIFOL(fd,4) = sd->bl.id; - safestrncpy((char*)WFIFOP(fd,8), is_fake ? fakename : text, textlen); + safestrncpy(WFIFOP(fd,8), is_fake ? fakename : text, textlen); //FIXME: chat has range of 9 only clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC); @@ -9848,7 +9837,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) if( is_fake ) { WFIFOW(fd,0) = 0x8e; WFIFOW(fd,2) = textlen + 4; - safestrncpy((char*)WFIFOP(fd,4), fakename, textlen); + safestrncpy(WFIFOP(fd,4), fakename, textlen); aFree(fakename); } else { memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2)); @@ -9859,10 +9848,8 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) // Chat logging type 'O' / Global Chat logs->chat(LOG_CHAT_GLOBAL, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message); -#ifdef PCRE_SUPPORT // trigger listening npcs map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl); -#endif } void clif_parse_MapMove(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -9872,10 +9859,9 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd) __attribute__((nonn void clif_parse_MapMove(int fd, struct map_session_data *sd) { char command[MAP_NAME_LENGTH_EXT+25]; - char* map_name; + char map_name[MAP_NAME_LENGTH_EXT]; - map_name = (char*)RFIFOP(fd,2); - map_name[MAP_NAME_LENGTH_EXT-1]='\0'; + safestrncpy(map_name, RFIFOP(fd,2), MAP_NAME_LENGTH_EXT); sprintf(command, "%cmapmove %s %d %d", atcommand->at_symbol, map_name, RFIFOW(fd,18), RFIFOW(fd,20)); atcommand->exec(fd, sd, command, true); } @@ -10144,7 +10130,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) struct map_session_data* dstsd; int i; - char *target, *message; + const char *target, *message; size_t namelen, messagelen; // validate packet and retrieve name and message @@ -10174,7 +10160,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) // Lordalfa - Paperboy - To whisper NPC commands // //-------------------------------------------------------// if (target[0] && (strncasecmp(target,"NPC:",4) == 0) && (strlen(target) > 4)) { - char* str = target+4; //Skip the NPC: string part. + const char *str = target+4; //Skip the NPC: string part. struct npc_data *nd; if ((nd = npc->name2id(str))) { char split_data[NUM_WHISPER_VAR][CHAT_SIZE_MAX]; @@ -10209,7 +10195,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) return; } } else if( target[0] == '#' ) { - char *chname = target; + const char *chname = target; struct channel_data *chan = channel->search(chname, sd); if (chan) { @@ -10273,19 +10259,26 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) clif->wis_message(dstsd->fd, sd->status.name, message, messagelen); } -void clif_parse_Broadcast(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); +void clif_parse_Broadcast(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// /b /nb (CZ_BROADCAST). /// Request to broadcast a message on whole server. /// 0099 <packet len>.W <text>.?B 00 -void clif_parse_Broadcast(int fd, struct map_session_data* sd) { - char command[CHAT_SIZE_MAX+11]; - char* msg = (char*)RFIFOP(fd,4); - unsigned int len = RFIFOW(fd,2)-4; +void clif_parse_Broadcast(int fd, struct map_session_data *sd) +{ + const char commandname[] = "kami"; + char command[sizeof commandname + 2 + CHAT_SIZE_MAX] = ""; // '@' command + ' ' + message + NUL + int len = (int)RFIFOW(fd,2) - 4; - // as the length varies depending on the command used, just block unreasonably long strings - mes_len_check(msg, len, CHAT_SIZE_MAX); + if (len < 0) + return; - sprintf(command, "%ckami %s", atcommand->at_symbol, msg); + sprintf(command, "%c%s ", atcommand->at_symbol, commandname); + + // as the length varies depending on the command used, truncate unreasonably long strings + if (len >= (int)(sizeof command - strlen(command))) + len = (int)(sizeof command - strlen(command)) - 1; + + strncat(command, RFIFOP(fd,4), len); atcommand->exec(fd, sd, command, true); } @@ -10397,16 +10390,18 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) __attribute__((non /// Request to equip an item (CZ_REQ_WEAR_EQUIP). /// 00a9 <index>.W <position>.W /// 0998 <index>.W <position>.L -void clif_parse_EquipItem(int fd,struct map_session_data *sd) { - struct packet_equip_item *p = P2PTR(fd); +void clif_parse_EquipItem(int fd,struct map_session_data *sd) +{ + const struct packet_equip_item *p = RP2PTR(fd); + int index = 0; if(pc_isdead(sd)) { clif->clearunit_area(&sd->bl,CLR_DEAD); return; } - p->index = p->index - 2; - if (p->index >= MAX_INVENTORY) + index = p->index - 2; + if (index >= MAX_INVENTORY) return; //Out of bounds check. if( sd->npc_id ) { @@ -10417,26 +10412,26 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) { else if ( pc_cant_act2(sd) || sd->state.prerefining ) return; - if(!sd->status.inventory[p->index].identify) { - clif->equipitemack(sd,p->index,0,EIA_FAIL);// fail + if(!sd->status.inventory[index].identify) { + clif->equipitemack(sd, index, 0, EIA_FAIL);// fail return; } - if(!sd->inventory_data[p->index]) + if(!sd->inventory_data[index]) return; - if(sd->inventory_data[p->index]->type == IT_PETARMOR){ - pet->equipitem(sd,p->index); + if(sd->inventory_data[index]->type == IT_PETARMOR){ + pet->equipitem(sd, index); return; } pc->update_idle_time(sd, BCIDLE_USEITEM); //Client doesn't send the position for ammo. - if(sd->inventory_data[p->index]->type == IT_AMMO) - pc->equipitem(sd,p->index,EQP_AMMO); + if(sd->inventory_data[index]->type == IT_AMMO) + pc->equipitem(sd, index, EQP_AMMO); else - pc->equipitem(sd,p->index,p->wearLocation); + pc->equipitem(sd, index, p->wearLocation); } void clif_parse_UnequipItem(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); @@ -10542,14 +10537,30 @@ void clif_parse_NpcBuyListSend(int fd, struct map_session_data* sd) __attribute_ /// 00c8 <packet len>.W { <amount>.W <name id>.W }* void clif_parse_NpcBuyListSend(int fd, struct map_session_data* sd) { - int n = (RFIFOW(fd,2)-4) /4; - unsigned short* item_list = (unsigned short*)RFIFOP(fd,4); + int n = ((int)RFIFOW(fd,2)-4) / 4; int result; - if( sd->state.trading || !sd->npc_shopid || pc_has_permission(sd,PC_PERM_DISABLE_STORE) ) + Assert_retv(n >= 0); + + if( sd->state.trading || !sd->npc_shopid || pc_has_permission(sd,PC_PERM_DISABLE_STORE) ) { result = 1; - else - result = npc->buylist(sd,n,item_list); + } else { + struct itemlist item_list = { 0 }; + int i; + + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, n, 1); + for (i = 0; i < n; i++) { + struct itemlist_entry entry = { 0 }; + + entry.amount = RFIFOW(fd, 4 + 4 * i); + entry.id = RFIFOW(fd, 4 + 4 * i + 2); + + VECTOR_PUSH(item_list, entry); + } + result = npc->buylist(sd, &item_list); + VECTOR_CLEAR(item_list); + } sd->npc_shopid = 0; //Clear shop data. @@ -10578,15 +10589,32 @@ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd) __attribute_ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd) { int fail=0,n; - unsigned short *item_list; - n = (RFIFOW(fd,2)-4) /4; - item_list = (unsigned short*)RFIFOP(fd,4); + n = ((int)RFIFOW(fd,2)-4) /4; + + Assert_retv(n >= 0); - if (sd->state.trading || !sd->npc_shopid) + if (sd->state.trading || !sd->npc_shopid) { fail = 1; - else - fail = npc->selllist(sd,n,item_list); + } else { + struct itemlist item_list = { 0 }; + int i; + + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, n, 1); + + for (i = 0; i < n; i++) { + struct itemlist_entry entry = { 0 }; + + entry.id = (int)RFIFOW(fd, 4 + 4 * i) - 2; + entry.amount = RFIFOW(fd, 4 + 4 * i + 2); + + VECTOR_PUSH(item_list, entry); + } + fail = npc->selllist(sd, &item_list); + + VECTOR_CLEAR(item_list); + } sd->npc_shopid = 0; //Clear shop data. @@ -10604,8 +10632,8 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd) int len = RFIFOW(fd,2)-15; int limit = RFIFOW(fd,4); bool pub = (RFIFOB(fd,6) != 0); - const char* password = (char*)RFIFOP(fd,7); //not zero-terminated - const char* title = (char*)RFIFOP(fd,15); // not zero-terminated + const char *password = RFIFOP(fd,7); //not zero-terminated + const char *title = RFIFOP(fd,15); // not zero-terminated char s_password[CHATROOM_PASS_SIZE]; char s_title[CHATROOM_TITLE_SIZE]; @@ -10639,7 +10667,7 @@ void clif_parse_ChatAddMember(int fd, struct map_session_data* sd) __attribute__ void clif_parse_ChatAddMember(int fd, struct map_session_data* sd) { int chatid = RFIFOL(fd,2); - const char* password = (char*)RFIFOP(fd,6); // not zero-terminated + const char *password = RFIFOP(fd,6); // not zero-terminated chat->join(sd,chatid,password); } @@ -10655,8 +10683,8 @@ void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd) int len = RFIFOW(fd,2)-15; int limit = RFIFOW(fd,4); bool pub = (RFIFOB(fd,6) != 0); - const char* password = (char*)RFIFOP(fd,7); // not zero-terminated - const char* title = (char*)RFIFOP(fd,15); // not zero-terminated + const char *password = RFIFOP(fd,7); // not zero-terminated + const char *title = RFIFOP(fd,15); // not zero-terminated char s_password[CHATROOM_PASS_SIZE]; char s_title[CHATROOM_TITLE_SIZE]; @@ -10677,7 +10705,7 @@ void clif_parse_ChangeChatOwner(int fd, struct map_session_data* sd) __attribute /// 1 = normal void clif_parse_ChangeChatOwner(int fd, struct map_session_data* sd) { - chat->change_owner(sd,(char*)RFIFOP(fd,6)); + chat->change_owner(sd, RFIFOP(fd,6)); } void clif_parse_KickFromChat(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); @@ -10685,7 +10713,7 @@ void clif_parse_KickFromChat(int fd,struct map_session_data *sd) __attribute__(( /// 00e2 <name>.24B void clif_parse_KickFromChat(int fd,struct map_session_data *sd) { - chat->kick(sd,(char*)RFIFOP(fd,2)); + chat->kick(sd, RFIFOP(fd,2)); } void clif_parse_ChatLeave(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -10853,7 +10881,7 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd) } #endif - type = (int)RFIFOW(fd,2); + type = RFIFOW(fd,2); #ifdef NEW_CARTS if( (type == 9 && sd->status.base_level > 131) || (type == 8 && sd->status.base_level > 121) || @@ -10874,6 +10902,25 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd) pc->setcart(sd,type); } +/// Request to select cart's visual look for new cart design (CZ_SELECTCART). +/// 0980 <identity>.L <type>.B +void clif_parse_SelectCart(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20150805 // RagexeRE + int type; + + if (!sd || !pc->checkskill(sd, MC_CARTDECORATE) || RFIFOL(fd, 2) != sd->status.account_id) + return; + + type = RFIFOB(fd, 6); + + if (type <= MAX_BASE_CARTS || type > MAX_CARTS) + return; + + pc->setcart(sd, type); +#endif +} + void clif_parse_StatusUp(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); /// Request to increase status (CZ_STATUS_CHANGE). /// 00bb <status id>.W <amount>.B @@ -11154,7 +11201,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski return; } //You can't use Graffiti/TalkieBox AND have a vending open, so this is safe. - safestrncpy(sd->message, (char*)RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE); + safestrncpy(sd->message, RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE); } if( sd->ud.skilltimer != INVALID_TIMER ) @@ -11247,7 +11294,7 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data* sd) uint16 skill_id = RFIFOW(fd,2); char map_name[MAP_NAME_LENGTH]; - mapindex->getmapname((char*)RFIFOP(fd,4), map_name); + mapindex->getmapname(RFIFOP(fd,4), map_name); sd->state.workinprogress = 0; if(skill_id != sd->menuskill_id) @@ -11408,7 +11455,7 @@ void clif_parse_NpcAmountInput(int fd,struct map_session_data *sd) __attribute__ void clif_parse_NpcAmountInput(int fd,struct map_session_data *sd) { int npcid = RFIFOL(fd,2); - int amount = (int)RFIFOL(fd,6); + int amount = RFIFOL(fd,6); if (amount >= 0) sd->npc_amount = amount; @@ -11424,7 +11471,7 @@ void clif_parse_NpcStringInput(int fd, struct map_session_data* sd) { int message_len = RFIFOW(fd,2)-8; int npcid = RFIFOL(fd,4); - const char* message = (char*)RFIFOP(fd,8); + const char *message = RFIFOP(fd,8); if( message_len <= 0 ) return; // invalid input @@ -11465,6 +11512,22 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd) clif_menuskill_clear(sd); } +/// Identifying item with right-click (CZ_REQ_ONECLICK_ITEMIDENTIFY). +/// 0A35 <index>.W +void clif_parse_OneClick_ItemIdentify(int fd, struct map_session_data *sd) +{ + int cmd = RFIFOW(fd,0); + short idx = RFIFOW(fd, packet_db[cmd].pos[0]) - 2; + int n; + + if (idx < 0 || idx >= MAX_INVENTORY || sd->inventory_data[idx] == NULL || sd->status.inventory[idx].nameid <= 0) + return; + + if ((n = pc->have_magnifier(sd) ) != INDEX_NOT_FOUND && + pc->delitem(sd, n, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME) == 0) + skill->identify(sd, idx); +} + void clif_parse_SelectArrow(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); /// Answer to arrow crafting item selection dialog (CZ_REQ_MAKINGARROW). /// 01ae <name id>.W @@ -11562,20 +11625,26 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd) { atcommand->exec(fd, sd, cmd, true); } -void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); +void clif_parse_LocalBroadcast(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// /lb /nlb (CZ_LOCALBROADCAST). /// Request to broadcast a message on current map. /// 019c <packet len>.W <text>.?B -void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd) +void clif_parse_LocalBroadcast(int fd, struct map_session_data *sd) { - char command[CHAT_SIZE_MAX+16]; - char* msg = (char*)RFIFOP(fd,4); - unsigned int len = RFIFOW(fd,2)-4; + const char commandname[] = "lkami"; + char command[sizeof commandname + 2 + CHAT_SIZE_MAX] = ""; // '@' + command + ' ' + message + NUL + int len = (int)RFIFOW(fd,2) - 4; - // as the length varies depending on the command used, just block unreasonably long strings - mes_len_check(msg, len, CHAT_SIZE_MAX); + if (len < 0) + return; - sprintf(command, "%clkami %s", atcommand->at_symbol, msg); + sprintf(command, "%c%s ", atcommand->at_symbol, commandname); + + // as the length varies depending on the command used, truncate unreasonably long strings + if (len >= (int)(sizeof command - strlen(command))) + len = (int)(sizeof command - strlen(command)) - 1; + + strncat(command, RFIFOP(fd,4), len); atcommand->exec(fd, sd, command, true); } @@ -11722,9 +11791,11 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd) __attribute__(( /// Party creation request /// 00f9 <party name>.24B (CZ_MAKE_GROUP) /// 01e8 <party name>.24B <item pickup rule>.B <item share rule>.B (CZ_MAKE_GROUP2) -void clif_parse_CreateParty(int fd, struct map_session_data *sd) { - char* name = (char*)RFIFOP(fd,2); - name[NAME_LENGTH-1] = '\0'; +void clif_parse_CreateParty(int fd, struct map_session_data *sd) +{ + char name[NAME_LENGTH]; + + safestrncpy(name, RFIFOP(fd,2), NAME_LENGTH); if( map->list[sd->bl.m].flag.partylock ) { // Party locked. @@ -11740,11 +11811,13 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd) { } void clif_parse_CreateParty2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_CreateParty2(int fd, struct map_session_data *sd) { - char* name = (char*)RFIFOP(fd,2); +void clif_parse_CreateParty2(int fd, struct map_session_data *sd) +{ + char name[NAME_LENGTH]; int item1 = RFIFOB(fd,26); int item2 = RFIFOB(fd,27); - name[NAME_LENGTH-1] = '\0'; + + safestrncpy(name, RFIFOP(fd,2), NAME_LENGTH); if( map->list[sd->bl.m].flag.partylock ) { // Party locked. @@ -11783,10 +11856,12 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { } void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) { +void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) +{ struct map_session_data *t_sd; - char *name = (char*)RFIFOP(fd,2); - name[NAME_LENGTH-1] = '\0'; + char name[NAME_LENGTH]; + + safestrncpy(name, RFIFOP(fd,2), NAME_LENGTH); if(map->list[sd->bl.m].flag.partylock) { // Party locked. @@ -11843,7 +11918,7 @@ void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) { clif->message(fd, msg_fd(fd,227)); return; } - party->removemember(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6)); + party->removemember(sd, RFIFOL(fd,2), RFIFOP(fd,6)); } void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -11882,10 +11957,10 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd) __attribute__( /// 0108 <packet len>.W <text>.?B (<name> : <message>) 00 void clif_parse_PartyMessage(int fd, struct map_session_data* sd) { - const char* text = (char*)RFIFOP(fd,4); + const char *text = RFIFOP(fd,4); int textlen = RFIFOW(fd,2) - 4; - char *name, *message; + const char *name, *message; size_t namelen, messagelen; // validate packet and retrieve name and message @@ -12140,7 +12215,7 @@ void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data* sd) { #ifdef PARTY_RECRUIT short level = RFIFOW(fd,2); - const char *notice = (const char*)RFIFOP(fd, 4); + const char *notice = RFIFOP(fd, 4); party->recruit_register(sd, level, notice); #else @@ -12263,9 +12338,7 @@ void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd) __att void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT - const char *notice; - - notice = (const char*)RFIFOP(fd, 2); + const char *notice = RFIFOP(fd, 2); party->recruit_update(sd, notice); #else @@ -12566,8 +12639,8 @@ void clif_parse_PurchaseReq(int fd, struct map_session_data* sd) __attribute__(( void clif_parse_PurchaseReq(int fd, struct map_session_data* sd) { int len = (int)RFIFOW(fd,2) - 8; - int id = (int)RFIFOL(fd,4); - const uint8* data = (uint8*)RFIFOP(fd,8); + int id = RFIFOL(fd,4); + const uint8 *data = RFIFOP(fd,8); vending->purchase(sd, id, sd->vended_id, data, len/4); @@ -12581,9 +12654,9 @@ void clif_parse_PurchaseReq2(int fd, struct map_session_data* sd) __attribute__( void clif_parse_PurchaseReq2(int fd, struct map_session_data* sd) { int len = (int)RFIFOW(fd,2) - 12; - int aid = (int)RFIFOL(fd,4); - int uid = (int)RFIFOL(fd,8); - const uint8* data = (uint8*)RFIFOP(fd,12); + int aid = RFIFOL(fd,4); + int uid = RFIFOL(fd,8); + const uint8 *data = RFIFOP(fd,12); vending->purchase(sd, aid, uid, data, len/4); @@ -12600,9 +12673,9 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) __attribute__(( /// 1 = open void clif_parse_OpenVending(int fd, struct map_session_data* sd) { short len = (short)RFIFOW(fd,2) - 85; - const char* message = (char*)RFIFOP(fd,4); - bool flag = (bool)RFIFOB(fd,84); - const uint8* data = (uint8*)RFIFOP(fd,85); + const char *message = RFIFOP(fd,4); + bool flag = (RFIFOB(fd,84) != 0) ? true : false; + const uint8 *data = RFIFOP(fd,85); if( !flag ) sd->state.prevend = sd->state.workinprogress = 0; @@ -12627,9 +12700,10 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) { void clif_parse_CreateGuild(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); /// Guild creation request (CZ_REQ_MAKE_GUILD). /// 0165 <char id>.L <guild name>.24B -void clif_parse_CreateGuild(int fd,struct map_session_data *sd) { - char* name = (char*)RFIFOP(fd,6); - name[NAME_LENGTH-1] = '\0'; +void clif_parse_CreateGuild(int fd,struct map_session_data *sd) +{ + char name[NAME_LENGTH]; + safestrncpy(name, RFIFOP(fd,6), NAME_LENGTH); if(map->list[sd->bl.m].flag.guildlock) { //Guild locked. @@ -12684,7 +12758,7 @@ void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) clif->guild_expulsionlist(sd); break; default: - ShowError("clif: guild request info: unknown type %d\n", RFIFOL(fd,2)); + ShowError("clif: guild request info: unknown type %u\n", RFIFOL(fd,2)); break; } } @@ -12700,7 +12774,7 @@ void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) return; for(i = 4; i < RFIFOW(fd,2); i += 40 ){ - guild->change_position(sd->status.guild_id, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), (char*)RFIFOP(fd,i+16)); + guild->change_position(sd->status.guild_id, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), RFIFOP(fd,i+16)); } } @@ -12815,8 +12889,8 @@ bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len) { switch( RBUFW(buf,28) ) { case 8: // palette indexes { - const uint8 *indexes = (const uint8 *)RBUFP(buf,offbits); - const uint32 *palette = (const uint32 *)RBUFP(buf,BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE); + const uint8 *indexes = RBUFP(buf,offbits); + const uint32 *palette = RBUFP(buf,BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE); for (i = 0; i < BITMAP_WIDTH * BITMAP_HEIGHT; i++) { if( indexes[i] >= palettesize ) // Invalid color @@ -12834,7 +12908,7 @@ bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len) { } case 24: // full colors { - const struct s_bitmaptripple *pixels = (const struct s_bitmaptripple*)RBUFP(buf,offbits); + const struct s_bitmaptripple *pixels = RBUFP(buf,offbits); for (i = 0; i < BITMAP_WIDTH * BITMAP_HEIGHT; i++) { // if( pixels[i].r < 0xF8 || pixels[i].g > 0x07 || pixels[i].b < 0xF8 ) @@ -12882,18 +12956,22 @@ void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd) __attribu void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd) { int guild_id = RFIFOL(fd,2); - char* msg1 = (char*)RFIFOP(fd,6); - char* msg2 = (char*)RFIFOP(fd,66); + char *msg1 = NULL, *msg2 = NULL; - if(!sd->state.gmaster_flag) + if (!sd->state.gmaster_flag) return; + msg1 = aStrndup(RFIFOP(fd,6), MAX_GUILDMES1-1); + msg2 = aStrndup(RFIFOP(fd,66), MAX_GUILDMES2-1); + // compensate for some client defects when using multilingual mode if (msg1[0] == '|' && msg1[3] == '|') msg1+= 3; // skip duplicate marker if (msg2[0] == '|' && msg2[3] == '|') msg2+= 3; // skip duplicate marker if (msg2[0] == '|') msg2[strnlen(msg2, MAX_GUILDMES2)-1] = '\0'; // delete extra space at the end of string guild->change_notice(sd, guild_id, msg1, msg2); + aFree(msg1); + aFree(msg2); } // Helper function for guild invite functions @@ -12931,14 +13009,15 @@ void clif_parse_GuildInvite(int fd,struct map_session_data *sd) { void clif_parse_GuildInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// Guild invite request (/guildinvite) (CZ_REQ_JOIN_GUILD2). /// 0916 <char name>.24B -void clif_parse_GuildInvite2(int fd, struct map_session_data *sd) { - char *nick = (char*)RFIFOP(fd, 2); - struct map_session_data *t_sd = map->nick2sd(nick); +void clif_parse_GuildInvite2(int fd, struct map_session_data *sd) +{ + char nick[NAME_LENGTH]; + struct map_session_data *t_sd = NULL; - nick[NAME_LENGTH - 1] = '\0'; + safestrncpy(nick, RFIFOP(fd, 2), NAME_LENGTH); + t_sd = map->nick2sd(nick); - if (!clif_sub_guild_invite(fd, sd, t_sd)) - return; + clif_sub_guild_invite(fd, sd, t_sd); } void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); @@ -12966,7 +13045,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd) { return; } - guild->leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14)); + guild->leave(sd,RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOP(fd,14)); } void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd) __attribute__((nonnull (2))); @@ -12978,7 +13057,7 @@ void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd) { clif->message(fd, msg_fd(fd,228)); return; } - guild->expulsion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14)); + guild->expulsion(sd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOP(fd,14)); } void clif_parse_GuildMessage(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -12986,10 +13065,10 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd) __attribute__( /// 017e <packet len>.W <text>.?B (<name> : <message>) 00 void clif_parse_GuildMessage(int fd, struct map_session_data* sd) { - const char* text = (char*)RFIFOP(fd,4); + const char *text = RFIFOP(fd,4); int textlen = RFIFOW(fd,2) - 4; - char *name, *message; + const char *name, *message; size_t namelen, messagelen; // validate packet and retrieve name and message @@ -13109,7 +13188,7 @@ void clif_parse_GuildBreak(int fd, struct map_session_data *sd) { clif->message(fd, msg_fd(fd,228)); return; } - guild->dobreak(sd,(char*)RFIFOP(fd,2)); + guild->dobreak(sd, RFIFOP(fd,2)); } /// Pet @@ -13185,7 +13264,7 @@ void clif_parse_ChangePetName(int fd, struct map_session_data *sd) __attribute__ /// 01a5 <name>.24B void clif_parse_ChangePetName(int fd, struct map_session_data *sd) { - pet->change_name(sd,(char*)RFIFOP(fd,2)); + pet->change_name(sd, RFIFOP(fd,2)); } void clif_parse_GMKick(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -13208,7 +13287,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) { case BL_PC: { char command[NAME_LENGTH+6]; - sprintf(command, "%ckick %s", atcommand->at_symbol, status->get_name(target)); + sprintf(command, "%ckick %s", atcommand->at_symbol, clif->get_bl_name(target)); atcommand->exec(fd, sd, command, true); } break; @@ -13223,7 +13302,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) { clif->GM_kickack(sd, 0); return; } - sprintf(command, "/kick %s (%d)", status->get_name(target), status->get_class(target)); + sprintf(command, "/kick %s (%d)", clif->get_bl_name(target), status->get_class(target)); logs->atcommand(sd, command); status_percent_damage(&sd->bl, target, 100, 0, true); // can invalidate 'target' } @@ -13266,12 +13345,12 @@ void clif_parse_GMShift(int fd, struct map_session_data *sd) __attribute__((nonn /// Request to warp to a character with given name. /// 01bb <char name>.24B void clif_parse_GMShift(int fd, struct map_session_data *sd) -{// FIXME: remove is supposed to receive account name for clients prior 20100803RE - char *player_name; +{ + // FIXME: remove is supposed to receive account name for clients prior 20100803RE + char player_name[NAME_LENGTH]; char command[NAME_LENGTH+8]; - player_name = (char*)RFIFOP(fd,2); - player_name[NAME_LENGTH-1] = '\0'; + safestrncpy(player_name, RFIFOP(fd,2), NAME_LENGTH); sprintf(command, "%cjumpto %s", atcommand->at_symbol, player_name); atcommand->exec(fd, sd, command, true); @@ -13302,12 +13381,12 @@ void clif_parse_GMRecall(int fd, struct map_session_data *sd) __attribute__((non /// Request to summon a player with given name to own position. /// 01bd <char name>.24B void clif_parse_GMRecall(int fd, struct map_session_data *sd) -{// FIXME: recall is supposed to receive account name for clients prior 20100803RE - char *player_name; - char command [NAME_LENGTH+8]; +{ + // FIXME: recall is supposed to receive account name for clients prior 20100803RE + char player_name[NAME_LENGTH]; + char command[NAME_LENGTH+8]; - player_name = (char*)RFIFOP(fd,2); - player_name[NAME_LENGTH-1] = '\0'; + safestrncpy(player_name, RFIFOP(fd,2), NAME_LENGTH); sprintf(command, "%crecall %s", atcommand->at_symbol, player_name); atcommand->exec(fd, sd, command, true); @@ -13343,16 +13422,16 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) __attribute /// /item agitinvest - reset current global agit investments.(not yet implemented) /// 013f <item/mob name>.24B /// 09ce <item/mob name>.100B [Ind/Yommy<3] -void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) { - struct packet_gm_monster_item *p = P2PTR(fd); +void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) +{ + const struct packet_gm_monster_item *p = RP2PTR(fd); int i, count; - char *item_monster_name; + char item_monster_name[sizeof p->str]; struct item_data *item_array[10]; struct mob_db *mob_array[10]; char command[256]; - item_monster_name = p->str; - item_monster_name[(sizeof(struct packet_gm_monster_item)-2)-1] = '\0'; + safestrncpy(item_monster_name, p->str, sizeof(item_monster_name)); if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ) { for(i = 0; i < count; i++) { @@ -13473,9 +13552,10 @@ void clif_parse_GMRc(int fd, struct map_session_data* sd) __attribute__((nonnull void clif_parse_GMRc(int fd, struct map_session_data* sd) { char command[NAME_LENGTH+15]; - char *name = (char*)RFIFOP(fd,2); + char name[NAME_LENGTH]; + + safestrncpy(name, RFIFOP(fd,2), NAME_LENGTH); - name[NAME_LENGTH-1] = '\0'; sprintf(command, "%cmute %d %s", atcommand->at_symbol, 60, name); atcommand->exec(fd, sd, command, true); } @@ -13490,7 +13570,7 @@ void clif_account_name(struct map_session_data* sd, int account_id, const char* WFIFOHEAD(fd,packet_len(0x1e0)); WFIFOW(fd,0) = 0x1e0; WFIFOL(fd,2) = account_id; - safestrncpy((char*)WFIFOP(fd,6), accname, NAME_LENGTH); + safestrncpy(WFIFOP(fd,6), accname, NAME_LENGTH); WFIFOSET(fd,packet_len(0x1e0)); } @@ -13534,13 +13614,14 @@ void clif_parse_PMIgnore(int fd, struct map_session_data* sd) __attribute__((non /// type: /// 0 = (/ex nick) deny speech from nick /// 1 = (/in nick) allow speech from nick -void clif_parse_PMIgnore(int fd, struct map_session_data* sd) { - char* nick; +void clif_parse_PMIgnore(int fd, struct map_session_data* sd) +{ + char nick[NAME_LENGTH]; uint8 type; int i; - nick = (char*)RFIFOP(fd,2); // speed up - nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name has at most 23 characters + safestrncpy(nick, RFIFOP(fd,2), NAME_LENGTH); + type = RFIFOB(fd,26); if( type == 0 ) { // Add name to ignore list (block) @@ -13798,12 +13879,14 @@ void clif_friendlist_req(struct map_session_data* sd, int account_id, int char_i void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// Request to add a player as friend (CZ_ADD_FRIENDS). /// 0202 <name>.24B -void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) { +void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) +{ struct map_session_data *f_sd; int i; - char *nick = (char*)RFIFOP(fd,2); + char nick[NAME_LENGTH]; + + safestrncpy(nick, RFIFOP(fd,2), NAME_LENGTH); - nick[NAME_LENGTH - 1] = '\0'; f_sd = map->nick2sd(nick); // ensure that the request player's friend list is not full @@ -14022,17 +14105,17 @@ void clif_ranklist_sub(unsigned char *buf, enum fame_list_type type) { for( i = 0; i < 10 && i < MAX_FAME_LIST; i++ ) { if( list[i].id > 0 ) { if( strcmp(list[i].name, "-") == 0 && (name = map->charid2nick(list[i].id)) != NULL ) { - strncpy((char *)(WBUFP(buf, 24 * i)), name, NAME_LENGTH); + strncpy(WBUFP(buf, 24 * i), name, NAME_LENGTH); } else { - strncpy((char *)(WBUFP(buf, 24 * i)), list[i].name, NAME_LENGTH); + strncpy(WBUFP(buf, 24 * i), list[i].name, NAME_LENGTH); } } else { - strncpy((char *)(WBUFP(buf, 24 * i)), "None", 5); + strncpy(WBUFP(buf, 24 * i), "None", 5); } WBUFL(buf, 24 * 10 + i * 4) = list[i].fame; //points } for( ;i < 10; i++ ) { // In case the MAX is less than 10. - strncpy((char *)(WBUFP(buf, 24 * i)), "Unavailable", 12); + strncpy(WBUFP(buf, 24 * i), "Unavailable", 12); WBUFL(buf, 24 * 10 + i * 4) = 0; } } @@ -14215,7 +14298,7 @@ void clif_ranking_pk(struct map_session_data* sd) { WFIFOHEAD(fd,packet_len(0x238)); WFIFOW(fd,0) = 0x238; for (i = 0; i < 10;i ++) { - strncpy((char*)WFIFOP(fd, i * 24 + 2), "Unknown", NAME_LENGTH); + strncpy(WFIFOP(fd, i * 24 + 2), "Unknown", NAME_LENGTH); WFIFOL(fd,i*4+242) = 0; } WFIFOSET(fd, packet_len(0x238)); @@ -14275,8 +14358,9 @@ void clif_feel_req(int fd, struct map_session_data *sd, uint16 skill_lv) void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// Request to change homunculus' name (CZ_RENAME_MER). /// 0231 <name>.24B -void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) { - homun->change_name(sd,(char*)RFIFOP(fd,2)); +void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) +{ + homun->change_name(sd, RFIFOP(fd,2)); } void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -14443,7 +14527,7 @@ void clif_parse_Check(int fd, struct map_session_data *sd) if(!pc_has_permission(sd, PC_PERM_USE_CHECK)) return; - safestrncpy(charname, (const char*)RFIFOP(fd,packet_db[RFIFOW(fd,0)].pos[0]), sizeof(charname)); + safestrncpy(charname, RFIFOP(fd,packet_db[RFIFOW(fd,0)].pos[0]), sizeof(charname)); if( ( pl_sd = map->nick2sd(charname) ) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { return; @@ -14534,8 +14618,8 @@ void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title) WFIFOHEAD(fd,packet_len(0x24a)); WFIFOW(fd,0) = 0x24a; WFIFOL(fd,2) = mail_id; - safestrncpy((char*)WFIFOP(fd,6), title, MAIL_TITLE_LENGTH); - safestrncpy((char*)WFIFOP(fd,46), sender, NAME_LENGTH); + safestrncpy(WFIFOP(fd,6), title, MAIL_TITLE_LENGTH); + safestrncpy(WFIFOP(fd,46), sender, NAME_LENGTH); WFIFOSET(fd,packet_len(0x24a)); } @@ -14641,8 +14725,8 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) WFIFOW(fd,0) = 0x242; WFIFOW(fd,2) = len; WFIFOL(fd,4) = msg->id; - safestrncpy((char*)WFIFOP(fd,8), msg->title, MAIL_TITLE_LENGTH + 1); - safestrncpy((char*)WFIFOP(fd,48), msg->send_name, NAME_LENGTH + 1); + safestrncpy(WFIFOP(fd,8), msg->title, MAIL_TITLE_LENGTH + 1); + safestrncpy(WFIFOP(fd,48), msg->send_name, NAME_LENGTH + 1); WFIFOL(fd,72) = 0; WFIFOL(fd,76) = msg->zeny; @@ -14661,7 +14745,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) memset(WFIFOP(fd,80), 0x00, 19); WFIFOB(fd,99) = (unsigned char)msg_len; - safestrncpy((char*)WFIFOP(fd,100), msg->body, msg_len + 1); + safestrncpy(WFIFOP(fd,100), msg->body, msg_len + 1); WFIFOSET(fd,len); if (msg->status == MAIL_UNREAD) { @@ -14886,15 +14970,15 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd) msg.send_id = sd->status.char_id; msg.dest_id = 0; // will attempt to resolve name safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH); - safestrncpy(msg.dest_name, (char*)RFIFOP(fd,4), NAME_LENGTH); - safestrncpy(msg.title, (char*)RFIFOP(fd,28), MAIL_TITLE_LENGTH); + safestrncpy(msg.dest_name, RFIFOP(fd,4), NAME_LENGTH); + safestrncpy(msg.title, RFIFOP(fd,28), MAIL_TITLE_LENGTH); if (msg.title[0] == '\0') { return; // Message has no length and somehow client verification was skipped. } if (body_len) - safestrncpy(msg.body, (char*)RFIFOP(fd,69), body_len + 1); + safestrncpy(msg.body, RFIFOP(fd,69), body_len + 1); else memset(msg.body, 0x00, MAIL_BODY_LENGTH); @@ -14934,7 +15018,7 @@ void clif_Auction_openwindow(struct map_session_data *sd) /// Returns auction item search results (ZC_AUCTION_ITEM_REQ_SEARCH). /// 0252 <packet len>.W <pages>.L <count>.L { <auction id>.L <seller name>.24B <name id>.W <type>.L <amount>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <now price>.L <max price>.L <buyer name>.24B <delete time>.L }* -void clif_Auction_results(struct map_session_data *sd, short count, short pages, uint8 *buf) +void clif_Auction_results(struct map_session_data *sd, short count, short pages, const uint8 *buf) { int i, fd, len = sizeof(struct auction_data); struct auction_data auction; @@ -14953,7 +15037,7 @@ void clif_Auction_results(struct map_session_data *sd, short count, short pages, memcpy(&auction, RBUFP(buf,i * len), len); WFIFOL(fd,k) = auction.auction_id; - safestrncpy((char*)WFIFOP(fd,4+k), auction.seller_name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,4+k), auction.seller_name, NAME_LENGTH); if( (item = itemdb->exists(auction.item.nameid)) != NULL && item->view_id > 0 ) WFIFOW(fd,28+k) = item->view_id; @@ -14971,7 +15055,7 @@ void clif_Auction_results(struct map_session_data *sd, short count, short pages, WFIFOW(fd,45+k) = auction.item.card[3]; WFIFOL(fd,47+k) = auction.price; WFIFOL(fd,51+k) = auction.buynow; - safestrncpy((char*)WFIFOP(fd,55+k), auction.buyer_name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,55+k), auction.buyer_name, NAME_LENGTH); WFIFOL(fd,79+k) = (uint32)auction.timestamp; } WFIFOSET(fd,WFIFOW(fd,2)); @@ -15245,7 +15329,7 @@ void clif_parse_Auction_search(int fd, struct map_session_data* sd) clif->pAuction_cancelreg(fd, sd); - safestrncpy(search_text, (char*)RFIFOP(fd,8), sizeof(search_text)); + safestrncpy(search_text, RFIFOP(fd,8), sizeof(search_text)); intif->Auction_requestlist(sd->status.char_id, type, price, search_text, page); } @@ -15381,13 +15465,25 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd) int len = RFIFOW(fd,2); int points = RFIFOL(fd,4); int count = RFIFOW(fd,8); - unsigned short* item_list = (unsigned short*)RFIFOP(fd,10); + struct itemlist item_list = { 0 }; + int i; if( len < 10 || len != 10 + count * 4) { - ShowWarning("Player %u sent incorrect cash shop buy packet (len %u:%u)!\n", sd->status.char_id, len, 10 + count * 4); + ShowWarning("Player %d sent incorrect cash shop buy packet (len %d:%d)!\n", sd->status.char_id, len, 10 + count * 4); return; } - fail = npc->cashshop_buylist(sd,points,count,item_list); + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, count, 1); + for (i = 0; i < count; i++) { + struct itemlist_entry entry = { 0 }; + + entry.amount = RFIFOW(fd, 10 + 4 * i); + entry.id = RFIFOW(fd, 10 + 4 * i + 2); // Nameid + + VECTOR_PUSH(item_list, entry); + } + fail = npc->cashshop_buylist(sd, points, &item_list); + VECTOR_CLEAR(item_list); #endif } @@ -15506,7 +15602,7 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag) WFIFOW(fd,11) = hours; // Hours WFIFOW(fd,13) = minutes; // Minutes } - safestrncpy((char*)WFIFOP(fd,19), md->db->jname, NAME_LENGTH); + safestrncpy(WFIFOP(fd,19), md->db->jname, NAME_LENGTH); } WFIFOSET(fd,70); @@ -15538,7 +15634,7 @@ void clif_parse_EquipTick(int fd, struct map_session_data* sd) __attribute__((no /// 1 = enabled void clif_parse_EquipTick(int fd, struct map_session_data* sd) { - bool flag = (bool)RFIFOL(fd,6); + bool flag = (RFIFOL(fd,6) != 0) ? true : false; sd->status.show_equip = flag; clif->equiptickack(sd, flag); } @@ -15572,7 +15668,7 @@ void clif_quest_send_list(struct map_session_data *sd) + sd->avail_quests * (sizeof(struct packet_quest_list_info) + MAX_QUEST_OBJECTIVES * sizeof(struct packet_mission_info_sub)); // >= than the actual length buf = aMalloc(len); - packet = (struct packet_quest_list_header *)WBUFP(buf, 0); + packet = WBUFP(buf, 0); real_len = sizeof(*packet); packet->PacketType = questListType; @@ -15882,7 +15978,7 @@ void clif_mercenary_info(struct map_session_data *sd) { #endif WFIFOW(fd,18) = mstatus->flee; WFIFOW(fd,20) = mstatus->amotion; - safestrncpy((char*)WFIFOP(fd,22), md->db->name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,22), md->db->name, NAME_LENGTH); WFIFOW(fd,46) = md->db->lv; WFIFOL(fd,48) = mstatus->hp; WFIFOL(fd,52) = mstatus->max_hp; @@ -15924,7 +16020,7 @@ void clif_mercenary_skillblock(struct map_session_data *sd) WFIFOW(fd, len + 8) = 0; WFIFOW(fd, len + 10) = 0; } - safestrncpy((char*)WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH); + safestrncpy(WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH); WFIFOB(fd,len+36) = 0; // Skillable for Mercenary? len += 37; } @@ -16083,10 +16179,10 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd) __attribute__((n /// 0x2db <packet len>.W <text>.?B (<name> : <message>) 00 void clif_parse_BattleChat(int fd, struct map_session_data* sd) { - const char* text = (char*)RFIFOP(fd,4); + const char *text = RFIFOP(fd,4); int textlen = RFIFOW(fd,2) - 4; - char *name, *message; + const char *name, *message; size_t namelen, messagelen; if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) ) @@ -16146,7 +16242,7 @@ void clif_sendbgemblem_area(struct map_session_data *sd) WBUFW(buf, 0) = 0x2dd; WBUFL(buf,2) = sd->bl.id; - safestrncpy((char*)WBUFP(buf,6), sd->status.name, NAME_LENGTH); // name don't show in screen. + safestrncpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH); // name don't show in screen. WBUFW(buf,30) = sd->bg_id; clif->send(buf,packet_len(0x2dd), &sd->bl, AREA); } @@ -16157,7 +16253,7 @@ void clif_sendbgemblem_single(int fd, struct map_session_data *sd) WFIFOHEAD(fd,32); WFIFOW(fd,0) = 0x2dd; WFIFOL(fd,2) = sd->bl.id; - safestrncpy((char*)WFIFOP(fd,6), sd->status.name, NAME_LENGTH); + safestrncpy(WFIFOP(fd,6), sd->status.name, NAME_LENGTH); WFIFOW(fd,30) = sd->bg_id; WFIFOSET(fd,packet_len(0x2dd)); } @@ -16369,36 +16465,51 @@ void clif_parse_LessEffect(int fd, struct map_session_data* sd) sd->state.lesseffect = ( isLess != 0 ); } -void clif_parse_ItemListWindowSelected(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); +void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// S 07e4 <length>.w <option>.l <val>.l {<index>.w <amount>.w).4b* -void clif_parse_ItemListWindowSelected(int fd, struct map_session_data* sd) { - int n = (RFIFOW(fd,2)-12) / 4; +void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *sd) +{ + int n = ((int)RFIFOW(fd,2) - 12) / 4; int type = RFIFOL(fd,4); int flag = RFIFOL(fd,8); // Button clicked: 0 = Cancel, 1 = OK - unsigned short* item_list = (unsigned short*)RFIFOP(fd,12); + struct itemlist item_list = { 0 }; + int i; if( sd->state.trading || sd->npc_shopid ) return; - if( flag == 0 || n == 0) { + if (flag == 0 || n <= 0) { clif_menuskill_clear(sd); return; // Canceled by player. } - if( sd->menuskill_id != SO_EL_ANALYSIS && sd->menuskill_id != GN_CHANGEMATERIAL ) { + if (n > MAX_INVENTORY) + n = MAX_INVENTORY; // It should be impossible to have more than that. + + if (sd->menuskill_id != SO_EL_ANALYSIS && sd->menuskill_id != GN_CHANGEMATERIAL) { clif_menuskill_clear(sd); return; // Prevent hacking. } + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, n, 1); + for (i = 0; i < n; i++) { + struct itemlist_entry entry = { 0 }; + entry.id = (int)RFIFOW(fd, 12 + 4 * i) - 2; // Inventory index + entry.amount = RFIFOW(fd, 12 + 4 * i + 2); + VECTOR_PUSH(item_list, entry); + } + switch( type ) { case 0: // Change Material - skill->changematerial(sd,n,item_list); + skill->changematerial(sd, &item_list); break; case 1: // Level 1: Pure to Rough case 2: // Level 2: Rough to Pure - skill->elementalanalysis(sd,n,type,item_list); + skill->elementalanalysis(sd, type, &item_list); break; } + VECTOR_CLEAR(item_list); clif_menuskill_clear(sd); return; @@ -16483,7 +16594,7 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) __attrib /// 1 = open void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) { const unsigned int blocksize = 8; - uint8* itemlist; + const uint8 *itemlist; char storename[MESSAGE_SIZE]; unsigned char result; int zenylimit; @@ -16495,13 +16606,13 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) { // TODO: Make this check global for all variable length packets. if( packet_len < 89 ) {// minimum packet length - ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89, packet_len, sd->bl.id); + ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89U, packet_len, sd->bl.id); return; } zenylimit = RFIFOL(fd,info->pos[1]); result = RFIFOL(fd,info->pos[2]); - safestrncpy(storename, (const char*)RFIFOP(fd,info->pos[3]), sizeof(storename)); + safestrncpy(storename, RFIFOP(fd,info->pos[3]), sizeof(storename)); itemlist = RFIFOP(fd,info->pos[4]); // so that buyingstore_create knows, how many elements it has access to @@ -16665,7 +16776,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) __attri /// 0819 <packet len>.W <account id>.L <store id>.L { <index>.W <name id>.W <amount>.W }* void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) { const unsigned int blocksize = 6; - uint8* itemlist; + const uint8 *itemlist; int account_id; unsigned int count, packet_len, buyer_id; struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; @@ -16674,7 +16785,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) { if( packet_len < 12 ) {// minimum packet length - ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12, packet_len, sd->bl.id); + ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12U, packet_len, sd->bl.id); return; } @@ -16687,7 +16798,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) { if( packet_len%blocksize ) { - ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%u, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize); + ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%d, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize); return; } count = packet_len/blocksize; @@ -16794,7 +16905,7 @@ void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd) { if( packet_len < 15 ) {// minimum packet length - ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15, packet_len, sd->bl.id); + ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15U, packet_len, sd->bl.id); return; } @@ -16976,10 +17087,10 @@ void clif_parse_debug(int fd,struct map_session_data *sd) { if( packet_len == -1 ) {// variable length packet_len = RFIFOW(fd,2); // clif_parse ensures, that this amount of data is already received } - ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); + ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", (unsigned int)cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); } else { packet_len = (int)RFIFOREST(fd); - ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", cmd, packet_len, fd); + ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", (unsigned int)cmd, packet_len, fd); } ShowDump(RFIFOP(fd,0), packet_len); @@ -17275,8 +17386,8 @@ void clif_parse_MoveItem(int fd, struct map_session_data *sd) { /* [Ind/Hercules] */ void clif_cashshop_db(void) { - config_t cashshop_conf; - config_setting_t *cashshop = NULL, *cats = NULL; + struct config_t cashshop_conf; + struct config_setting_t *cashshop = NULL, *cats = NULL; const char *config_filename = "db/cashshop_db.conf"; // FIXME hardcoded name int i, item_count_t = 0; for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) { @@ -17284,16 +17395,14 @@ void clif_cashshop_db(void) { clif->cs.item_count[i] = 0; } - if (libconfig->read_file(&cashshop_conf, config_filename)) { - ShowError("can't read %s\n", config_filename); + if (!libconfig->load_file(&cashshop_conf, config_filename)) return; - } cashshop = libconfig->lookup(&cashshop_conf, "cash_shop"); if( cashshop != NULL && (cats = libconfig->setting_get_elem(cashshop, 0)) != NULL ) { for(i = 0; i < CASHSHOP_TAB_MAX; i++) { - config_setting_t *cat; + struct config_setting_t *cat; char entry_name[10]; sprintf(entry_name,"cat_%d",i); @@ -17302,7 +17411,7 @@ void clif_cashshop_db(void) { int k, item_count = libconfig->setting_length(cat); for(k = 0; k < item_count; k++) { - config_setting_t *entry = libconfig->setting_get_elem(cat,k); + struct config_setting_t *entry = libconfig->setting_get_elem(cat,k); const char *name = config_setting_name(entry); int price = libconfig->setting_get_int(entry); struct item_data * data = NULL; @@ -17547,18 +17656,18 @@ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) { p.PacketType = maptypeproperty2Type; p.type = 0x28; - p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; //PARTY - p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0; // GUILD - p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0; // SIEGE - p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // USE_SIMPLE_EFFECT - Forcing /mineffect in castles during WoE (probably redundant? I'm not sure) + p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; //PARTY + p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0; // GUILD + p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0; // SIEGE + p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // USE_SIMPLE_EFFECT - Forcing /mineffect in castles during WoE (probably redundant? I'm not sure) p.flag.nolockon = 0; // DISABLE_LOCKON - TODO - p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0; // COUNT_PK - p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0; // NO_PARTY_FORMATION - p.flag.bg = map->list[bl->m].flag.battleground ? 1 : 0; // BATTLEFIELD + p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0; // COUNT_PK + p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0; // NO_PARTY_FORMATION + p.flag.bg = map->list[bl->m].flag.battleground ? 1 : 0; // BATTLEFIELD p.flag.nocostume = (map->list[bl->m].flag.noviewid & EQP_COSTUME) ? 1 : 0; // DISABLE_COSTUMEITEM - Disables Costume Sprite p.flag.usecart = 1; // USECART - TODO p.flag.summonstarmiracle = 0; // SUNMOONSTAR_MIRACLE - TODO - p.flag.SpareBits = 0; // UNUSED + p.flag.SpareBits = 0; // UNUSED clif->send(&p,sizeof(p),bl,t); #endif @@ -17606,7 +17715,7 @@ void clif_ShowScript(struct block_list* bl, const char* message) { WBUFW(buf,0)=0x8b3; WBUFW(buf,2)=len+8; WBUFL(buf,4)=bl->id; - safestrncpy((char *) WBUFP(buf,8),message,len); + safestrncpy(WBUFP(buf,8),message,len); clif->send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT); } @@ -17646,7 +17755,8 @@ void clif_bgqueue_ack(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK } } -void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name) { +void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, const char *name) +{ struct packet_bgqueue_notice_delete p; nullpo_retv(sd); @@ -17658,8 +17768,9 @@ void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_ } void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) { - struct packet_bgqueue_register *p = P2PTR(fd); +void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) +{ + const struct packet_bgqueue_register *p = RP2PTR(fd); struct bg_arena *arena = NULL; if( !bg->queue_on ) return; /* temp, until feature is complete */ @@ -17696,19 +17807,22 @@ void clif_bgqueue_update_info(struct map_session_data *sd, unsigned char arena_i } void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) { - struct packet_bgqueue_checkstate *p = P2PTR(fd); +void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) +{ + const struct packet_bgqueue_checkstate *p = RP2PTR(fd); nullpo_retv(sd); - if ( sd->bg_queue.arena && sd->bg_queue.type ) { + if (sd->bg_queue.arena && sd->bg_queue.type) { clif->bgqueue_update_info(sd,sd->bg_queue.arena->id,bg->id2pos(sd->bg_queue.arena->queue_id,sd->status.account_id)); - } else + } else { clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,p->bg_name); + } } void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) { - struct packet_bgqueue_revoke_req *p = P2PTR(fd); +void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) +{ + const struct packet_bgqueue_revoke_req *p = RP2PTR(fd); if( sd->bg_queue.arena ) bg->queue_pc_cleanup(sd); @@ -17717,8 +17831,9 @@ void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) { } void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) { - struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd); +void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) +{ + const struct packet_bgqueue_battlebegin_ack *p = RP2PTR(fd); struct bg_arena *arena; if( !bg->queue_on ) return; /* temp, until feature is complete */ @@ -17854,10 +17969,11 @@ void clif_cart_additem_ack(struct map_session_data *sd, int flag) { clif->send(&p,sizeof(p), &sd->bl, SELF); } -void clif_parse_BankDeposit(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); /* Bank System [Yommy/Hercules] */ -void clif_parse_BankDeposit(int fd, struct map_session_data* sd) { - struct packet_banking_deposit_req *p = P2PTR(fd); +void clif_parse_BankDeposit(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +void clif_parse_BankDeposit(int fd, struct map_session_data *sd) +{ + const struct packet_banking_deposit_req *p = RP2PTR(fd); int money; if (!battle_config.feature_banking) { @@ -17870,9 +17986,10 @@ void clif_parse_BankDeposit(int fd, struct map_session_data* sd) { pc->bank_deposit(sd,money); } -void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); -void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) { - struct packet_banking_withdraw_req *p = P2PTR(fd); +void clif_parse_BankWithdraw(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +void clif_parse_BankWithdraw(int fd, struct map_session_data *sd) +{ + const struct packet_banking_withdraw_req *p = RP2PTR(fd); int money; if (!battle_config.feature_banking) { @@ -18107,32 +18224,30 @@ void clif_parse_NPCMarketClosed(int fd, struct map_session_data *sd) { sd->npc_shopid = 0; } -void clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response) { +void clif_npc_market_purchase_ack(struct map_session_data *sd, const struct itemlist *item_list, unsigned char response) +{ #if PACKETVER >= 20131223 unsigned short c = 0; nullpo_retv(sd); - nullpo_retv(req); + nullpo_retv(item_list); npcmarket_result.PacketType = npcmarketresultackType; npcmarket_result.result = response == 0 ? 1 : 0;/* find other values */ - if( npcmarket_result.result ) { - unsigned short i, list_size = (req->PacketLength - 4) / sizeof(req->list[0]), j; - struct npc_data* nd; - struct npc_item_list *shop = NULL; - unsigned short shop_size = 0; - - nd = map->id2nd(sd->npc_shopid); - - shop = nd->u.scr.shop->item; - shop_size = nd->u.scr.shop->items; + if (npcmarket_result.result) { + struct npc_data *nd = map->id2nd(sd->npc_shopid); + struct npc_item_list *shop = nd->u.scr.shop->item; + unsigned short shop_size = nd->u.scr.shop->items; + int i; - for(i = 0; i < list_size; i++) { + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + int j; - npcmarket_result.list[i].ITID = req->list[i].ITID; - npcmarket_result.list[i].qty = req->list[i].qty; + npcmarket_result.list[i].ITID = entry->id; + npcmarket_result.list[i].qty = entry->amount; - ARR_FIND( 0, shop_size, j, req->list[i].ITID == shop[j].nameid ); + ARR_FIND( 0, shop_size, j, entry->id == shop[j].nameid); npcmarket_result.list[i].price = (j != shop_size) ? shop[j].value : 0; @@ -18147,11 +18262,32 @@ void clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc } void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) { +void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) +{ #if PACKETVER >= 20131223 - struct packet_npc_market_purchase *p = P2PTR(fd); + const struct packet_npc_market_purchase *p = RP2PTR(fd); + int response = 0, i; + int count = (p->PacketLength - 4) / sizeof p->list[0]; + struct itemlist item_list; + + Assert_retv(count >= 0 && count <= MAX_INVENTORY); + + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, count, 1); + + for (i = 0; i < count; i++) { + struct itemlist_entry entry = { 0 }; + + entry.id = p->list[i].ITID; + entry.amount = p->list[i].qty; + + VECTOR_PUSH(item_list, entry); + } - clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p)); + response = npc->market_buylist(sd, &item_list); + clif->npc_market_purchase_ack(sd, &item_list, response); + + VECTOR_CLEAR(item_list); #endif } @@ -18271,7 +18407,7 @@ void clif_parse_RouletteGenerate(int fd, struct map_session_data* sd) { it.nameid = clif->rd.nameid[stage][0]; it.identify = 1; - pc->additem(sd, &it, clif->rd.qty[stage][0], LOG_TYPE_OTHER);/** TODO maybe a new log type for roulette items? **/ + pc->additem(sd, &it, clif->rd.qty[stage][0], LOG_TYPE_ROULETTE);/** TODO maybe a new log type for roulette items? **/ sd->roulette.stage = 0; result = GENERATE_ROULETTE_LOSING; @@ -18306,7 +18442,7 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) { it.nameid = clif->rd.nameid[sd->roulette.prizeStage][sd->roulette.prizeIdx]; it.identify = 1; - switch (pc->additem(sd, &it, clif->rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_OTHER)) { + switch (pc->additem(sd, &it, clif->rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_ROULETTE)) { case 0: p.Result = RECV_ITEM_SUCCESS; sd->roulette.claimPrize = false; @@ -18335,8 +18471,8 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) { } bool clif_parse_roulette_db(void) { - config_t roulette_conf; - config_setting_t *roulette = NULL, *levels = NULL; + struct config_t roulette_conf; + struct config_setting_t *roulette = NULL, *levels = NULL; const char *config_filename = "db/roulette_db.conf"; // FIXME hardcoded name int i, j, item_count_t = 0; @@ -18344,15 +18480,13 @@ bool clif_parse_roulette_db(void) { clif->rd.items[i] = 0; } - if (libconfig->read_file(&roulette_conf, config_filename)) { - ShowError("can't read %s\n", config_filename); + if (!libconfig->load_file(&roulette_conf, config_filename)) return false; - } roulette = libconfig->lookup(&roulette_conf, "roulette"); if( roulette != NULL && (levels = libconfig->setting_get_elem(roulette, 0)) != NULL ) { for(i = 0; i < MAX_ROULETTE_LEVEL; i++) { - config_setting_t *level; + struct config_setting_t *level; char entry_name[10]; sprintf(entry_name,"level_%d",i+1); @@ -18361,7 +18495,7 @@ bool clif_parse_roulette_db(void) { int k, item_count = libconfig->setting_length(level); for(k = 0; k < item_count; k++) { - config_setting_t *entry = libconfig->setting_get_elem(level,k); + struct config_setting_t *entry = libconfig->setting_get_elem(level,k); const char *name = config_setting_name(entry); int qty = libconfig->setting_get_int(entry); struct item_data * data = NULL; @@ -18607,6 +18741,44 @@ void clif_dressroom_open(struct map_session_data *sd, int view) WFIFOSET(fd,packet_len(0xa02)); } +/// Request to select cart's visual look for new cart design (ZC_SELECTCART). +/// 097f <Length>.W <identity>.L <type>.B +void clif_selectcart(struct map_session_data *sd) +{ +#if PACKETVER >= 20150805 + int i = 0, fd; + + fd = sd->fd; + + WFIFOHEAD(fd, 8 + MAX_CARTDECORATION_CARTS); + WFIFOW(fd, 0) = 0x97f; + WFIFOW(fd, 2) = 8 + MAX_CARTDECORATION_CARTS; + WFIFOL(fd, 4) = sd->status.account_id; + + for (i = 0; i < MAX_CARTDECORATION_CARTS; i++) { + WFIFOB(fd, 8 + i) = MAX_BASE_CARTS + 1 + i; + } + + WFIFOSET(fd, 8 + MAX_CARTDECORATION_CARTS); +#endif +} + +/** + * Returns the name of the given bl, in a client-friendly format. + * + * @param bl The requested bl. + * @return The bl's name (guaranteed to be non-NULL). + */ +const char *clif_get_bl_name(const struct block_list *bl) +{ + const char *name = status->get_name(bl); + + if (name == NULL) + return "Unknown"; + + return name; +} + /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -18688,25 +18860,25 @@ int clif_parse(int fd) { if (RFIFOREST(fd) < 2) return 0; + if (sd) + parse_cmd_func = sd->parse_cmd_func; + else + parse_cmd_func = clif->parse_cmd; + + cmd = parse_cmd_func(fd,sd); + if (VECTOR_LENGTH(HPM->packets[hpClif_Parse]) > 0) { - int result = HPM->parse_packets(fd,hpClif_Parse); + int result = HPM->parse_packets(fd,cmd,hpClif_Parse); if (result == 1) continue; if (result == 2) return 0; } - if( sd ) - parse_cmd_func = sd->parse_cmd_func; - else - parse_cmd_func = clif->parse_cmd; - - cmd = parse_cmd_func(fd,sd); - // filter out invalid / unsupported packets if (cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0) { ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x (0x%04x), %"PRIuS" bytes received), disconnecting session #%d.\n", - cmd, RFIFOW(fd,0), RFIFOREST(fd), fd); + (unsigned int)cmd, RFIFOW(fd,0), RFIFOREST(fd), fd); #ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); #endif @@ -18722,7 +18894,7 @@ int clif_parse(int fd) { packet_len = RFIFOW(fd,2); if (packet_len < 4 || packet_len > 32768) { - ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd); + ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", (unsigned int)cmd, packet_len, fd); #ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); #endif @@ -18736,7 +18908,11 @@ int clif_parse(int fd) { return 0; // not enough data received to form the packet if( battle_config.packet_obfuscation == 2 || cmd != RFIFOW(fd, 0) || (sd && sd->parse_cmd_func == clif_parse_cmd_decrypt) ) { - RFIFOW(fd, 0) = cmd; + // Note: Overriding const qualifier to re-inject the decoded packet ID. +#define RFIFOP_mutable(fd, pos) ((void *)(sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos + (pos))) + int16 *packet_id = RFIFOP_mutable(fd, 0); +#undef RFIFOP_mutable + *packet_id = cmd; if( sd ) { sd->cryptKey = (( sd->cryptKey * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF; // Update key for the next packet } @@ -18810,7 +18986,12 @@ static void __attribute__ ((unused)) packetdb_addpacket(short cmd, int len, ...) pFunc func; if (cmd > MAX_PACKET_DB) { - ShowError("Packet Error: packet 0x%x is greater than the maximum allowed (0x%x), skipping...\n", cmd, MAX_PACKET_DB); + ShowError("Packet Error: packet 0x%x is greater than the maximum allowed (0x%x), skipping...\n", (unsigned int)cmd, (unsigned int)MAX_PACKET_DB); + return; + } + + if (cmd < MIN_PACKET_DB) { + ShowError("Packet Error: packet 0x%x is lower than the minimum allowed (0x%x), skipping...\n", (unsigned int)cmd, (unsigned int)MIN_PACKET_DB); return; } @@ -19419,6 +19600,8 @@ void clif_defaults(void) { clif->cancelmergeitem = clif_cancelmergeitem; clif->comparemergeitem = clif_comparemergeitem; clif->ackmergeitems = clif_ackmergeitems; + /* Cart Deco */ + clif->selectcart = clif_selectcart; /*------------------------ *- Parse Incoming Packet @@ -19467,6 +19650,7 @@ void clif_defaults(void) { clif->pGetItemFromCart = clif_parse_GetItemFromCart; clif->pRemoveOption = clif_parse_RemoveOption; clif->pChangeCart = clif_parse_ChangeCart; + clif->pSelectCart = clif_parse_SelectCart; clif->pStatusUp = clif_parse_StatusUp; clif->pSkillUp = clif_parse_SkillUp; clif->pUseSkillToId = clif_parse_UseSkillToId; @@ -19663,4 +19847,6 @@ void clif_defaults(void) { clif->add_random_options = clif_add_random_options; clif->pHotkeyRowShift = clif_parse_HotkeyRowShift; clif->dressroom_open = clif_dressroom_open; + clif->pOneClick_ItemIdentify = clif_parse_OneClick_ItemIdentify; + clif->get_bl_name = clif_get_bl_name; } |