diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 20 | ||||
-rw-r--r-- | src/map/chrif.c | 14 | ||||
-rw-r--r-- | src/map/clif.c | 676 | ||||
-rw-r--r-- | src/map/clif.h | 9 | ||||
-rw-r--r-- | src/map/elemental.c | 3 | ||||
-rw-r--r-- | src/map/elemental.h | 2 | ||||
-rw-r--r-- | src/map/guild.c | 14 | ||||
-rw-r--r-- | src/map/guild.h | 12 | ||||
-rw-r--r-- | src/map/homunculus.c | 63 | ||||
-rw-r--r-- | src/map/homunculus.h | 8 | ||||
-rw-r--r-- | src/map/intif.c | 100 | ||||
-rw-r--r-- | src/map/intif.h | 6 | ||||
-rw-r--r-- | src/map/irc-bot.c | 19 | ||||
-rw-r--r-- | src/map/itemdb.h | 8 | ||||
-rw-r--r-- | src/map/mercenary.c | 3 | ||||
-rw-r--r-- | src/map/mercenary.h | 2 | ||||
-rw-r--r-- | src/map/npc.c | 232 | ||||
-rw-r--r-- | src/map/npc.h | 14 | ||||
-rw-r--r-- | src/map/packets_struct.h | 2 | ||||
-rw-r--r-- | src/map/party.c | 11 | ||||
-rw-r--r-- | src/map/party.h | 8 | ||||
-rw-r--r-- | src/map/pc.c | 3 | ||||
-rw-r--r-- | src/map/pc.h | 2 | ||||
-rw-r--r-- | src/map/pet.c | 14 | ||||
-rw-r--r-- | src/map/pet.h | 4 | ||||
-rw-r--r-- | src/map/script.c | 2 | ||||
-rw-r--r-- | src/map/skill.c | 35 | ||||
-rw-r--r-- | src/map/skill.h | 5 |
28 files changed, 730 insertions, 561 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 4cf9a5b54..cb1541f66 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7379,19 +7379,19 @@ void Hercules_report(char* date, char *time_c) { WBUFW(buf,2) = 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) ); WBUFW(buf,4) = 0x9f; - safestrncpy((char*)WBUFP(buf,6), date, 12); - safestrncpy((char*)WBUFP(buf,18), time_c, 9); - safestrncpy((char*)WBUFP(buf,27), timestring, 24); + safestrncpy(WBUFP(buf,6), date, 12); + safestrncpy(WBUFP(buf,18), time_c, 9); + safestrncpy(WBUFP(buf,27), timestring, 24); - safestrncpy((char*)WBUFP(buf,51), sysinfo->platform(), 16); - safestrncpy((char*)WBUFP(buf,67), sysinfo->osversion(), 50); - safestrncpy((char*)WBUFP(buf,117), sysinfo->cpu(), 32); + safestrncpy(WBUFP(buf,51), sysinfo->platform(), 16); + safestrncpy(WBUFP(buf,67), sysinfo->osversion(), 50); + safestrncpy(WBUFP(buf,117), sysinfo->cpu(), 32); WBUFL(buf,149) = sysinfo->cpucores(); - safestrncpy((char*)WBUFP(buf,153), sysinfo->arch(), 8); + safestrncpy(WBUFP(buf,153), sysinfo->arch(), 8); WBUFB(buf,161) = sysinfo->vcstypeid(); WBUFB(buf,162) = sysinfo->is64bit(); - safestrncpy((char*)WBUFP(buf,163), sysinfo->vcsrevision_src(), 41); - safestrncpy((char*)WBUFP(buf,204), sysinfo->vcsrevision_scripts(), 41); + safestrncpy(WBUFP(buf,163), sysinfo->vcsrevision_src(), 41); + safestrncpy(WBUFP(buf,204), sysinfo->vcsrevision_scripts(), 41); WBUFB(buf,245) = (sysinfo->is_superuser()? 1 : 0); WBUFL(buf,246) = map->getusers(); @@ -7400,7 +7400,7 @@ void Hercules_report(char* date, char *time_c) { WBUFL(buf,258) = bd_size; for( i = 0; i < bd_size; i++ ) { - safestrncpy((char*)WBUFP(buf,262 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, BFLAG_LENGTH); + safestrncpy(WBUFP(buf,262 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, BFLAG_LENGTH); WBUFL(buf,262 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val; } diff --git a/src/map/chrif.c b/src/map/chrif.c index 4de82ef07..0f158b645 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -594,7 +594,7 @@ void chrif_authok(int fd) { int account_id, group_id, char_id; uint32 login_id1,login_id2; time_t expiration_time; - struct mmo_charstatus* charstatus; + const struct mmo_charstatus *charstatus; struct auth_node *node; bool changing_mapservers; struct map_session_data *sd = NULL; @@ -611,7 +611,7 @@ void chrif_authok(int fd) { expiration_time = (time_t)(int32)RFIFOL(fd,16); group_id = RFIFOL(fd,20); changing_mapservers = (RFIFOB(fd,24)); - charstatus = (struct mmo_charstatus*)RFIFOP(fd,25); + charstatus = RFIFOP(fd,25); char_id = charstatus->char_id; //Check if we don't already have player data in our server @@ -796,7 +796,7 @@ bool chrif_char_ask_name(int acc, const char* character_name, unsigned short ope WFIFOHEAD(chrif->fd,44); WFIFOW(chrif->fd,0) = 0x2b0e; WFIFOL(chrif->fd,2) = acc; - safestrncpy((char*)WFIFOP(chrif->fd,6), character_name, NAME_LENGTH); + safestrncpy(WFIFOP(chrif->fd,6), character_name, NAME_LENGTH); WFIFOW(chrif->fd,30) = operation_type; if (operation_type == CHAR_ASK_NAME_BAN || operation_type == CHAR_ASK_NAME_CHARBAN) { @@ -827,7 +827,7 @@ bool chrif_changesex(struct map_session_data *sd, bool change_account) WFIFOHEAD(chrif->fd,44); WFIFOW(chrif->fd,0) = 0x2b0e; WFIFOL(chrif->fd,2) = sd->status.account_id; - safestrncpy((char*)WFIFOP(chrif->fd,6), sd->status.name, NAME_LENGTH); + safestrncpy(WFIFOP(chrif->fd,6), sd->status.name, NAME_LENGTH); WFIFOW(chrif->fd,30) = change_account ? CHAR_ASK_NAME_CHANGESEX : CHAR_ASK_NAME_CHANGECHARSEX; if (!change_account) WFIFOB(chrif->fd,32) = sd->status.sex == SEX_MALE ? SEX_FEMALE : SEX_MALE; @@ -1221,7 +1221,7 @@ bool chrif_load_scdata(int fd) { count = RFIFOW(fd,12); //sc_count for (i = 0; i < count; i++) { - struct status_change_data *data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data)); + const struct status_change_data *data = RFIFOP(fd,14 + i*sizeof(struct status_change_data)); status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE); } @@ -1436,10 +1436,10 @@ int chrif_parse(int fd) { case 0x2b03: clif->charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break; case 0x2b04: chrif->recvmap(fd); break; case 0x2b06: chrif->changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break; - case 0x2b09: map->addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break; + case 0x2b09: map->addnickdb(RFIFOL(fd,2), RFIFOP(fd,6)); break; case 0x2b0a: sockt->datasync(fd, false); break; case 0x2b0d: chrif->changedsex(fd); break; - case 0x2b0f: chrif->char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break; + case 0x2b0f: chrif->char_ask_name_answer(RFIFOL(fd,2), RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break; case 0x2b12: chrif->divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break; case 0x2b14: chrif->idbanned(fd); break; case 0x2b1b: chrif->recvfamelist(fd); break; diff --git a/src/map/clif.c b/src/map/clif.c index a7d73d91f..07b0b323b 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 *------------------------------------------*/ @@ -1612,7 +1596,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 +1800,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 +1815,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 +1968,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 +2087,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 +2195,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)); } @@ -3642,7 +3626,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 +3663,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 +3825,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 +3834,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)); @@ -4425,7 +4409,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 +4719,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 +4770,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 @@ -5227,12 +5211,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 +5492,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 +5522,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 +5551,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 +5609,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 +5802,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 +5811,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 +5849,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 +6073,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 +6160,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 +6388,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 +6421,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 +6509,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 +6621,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 +7287,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 +7530,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 +7631,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 +7699,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 +7843,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 +7926,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 +7951,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 +8025,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 +8083,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 +8111,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 +8126,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 +8210,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); } @@ -8586,14 +8570,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 +8664,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 +8868,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 +8894,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 +8985,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 +9018,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 +9715,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 +9804,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 +9826,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 +9834,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)); @@ -9870,10 +9856,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); } @@ -10142,7 +10127,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 @@ -10172,7 +10157,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]; @@ -10207,7 +10192,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) { @@ -10271,19 +10256,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; + + if (len < 0) + return; + + sprintf(command, "%c%s ", atcommand->at_symbol, commandname); - // as the length varies depending on the command used, just block unreasonably long strings - mes_len_check(msg, len, CHAT_SIZE_MAX); + // 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; - sprintf(command, "%ckami %s", atcommand->at_symbol, msg); + strncat(command, RFIFOP(fd,4), len); atcommand->exec(fd, sd, command, true); } @@ -10395,16 +10387,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 = RP2PTR(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 ) { @@ -10415,26 +10409,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))); @@ -10540,14 +10534,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. @@ -10576,15 +10586,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. @@ -10602,8 +10629,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]; @@ -10637,7 +10664,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); } @@ -10653,8 +10680,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]; @@ -10675,7 +10702,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))); @@ -10683,7 +10710,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))); @@ -10851,7 +10878,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) || @@ -10882,7 +10909,7 @@ void clif_parse_SelectCart(int fd, struct map_session_data *sd) if (!sd || !pc->checkskill(sd, MC_CARTDECORATE) || RFIFOL(fd, 2) != sd->status.account_id) return; - type = (int)RFIFOB(fd, 6); + type = RFIFOB(fd, 6); if (type <= MAX_BASE_CARTS || type > MAX_CARTS) return; @@ -11171,7 +11198,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 ) @@ -11264,7 +11291,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) @@ -11425,7 +11452,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; @@ -11441,7 +11468,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 @@ -11595,20 +11622,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; + + if (len < 0) + return; - // as the length varies depending on the command used, just block unreasonably long strings - mes_len_check(msg, len, CHAT_SIZE_MAX); + sprintf(command, "%c%s ", atcommand->at_symbol, commandname); - sprintf(command, "%clkami %s", atcommand->at_symbol, msg); + // 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); } @@ -11755,9 +11788,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. @@ -11773,11 +11808,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. @@ -11816,10 +11853,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. @@ -11876,7 +11915,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))); @@ -11915,10 +11954,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 @@ -12173,7 +12212,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 @@ -12296,9 +12335,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 @@ -12599,8 +12636,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); @@ -12614,9 +12651,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); @@ -12633,9 +12670,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; @@ -12660,9 +12697,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. @@ -12733,7 +12771,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)); } } @@ -12848,8 +12886,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 @@ -12867,7 +12905,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 ) @@ -12915,18 +12953,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 @@ -12964,14 +13006,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))); @@ -12999,7 +13042,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))); @@ -13011,7 +13054,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))); @@ -13019,10 +13062,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 @@ -13142,7 +13185,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 @@ -13218,7 +13261,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))); @@ -13299,12 +13342,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); @@ -13335,12 +13378,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); @@ -13376,16 +13419,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 = RP2PTR(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++) { @@ -13506,9 +13549,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); } @@ -13523,7 +13567,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)); } @@ -13567,13 +13611,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) @@ -13831,12 +13876,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 @@ -14055,17 +14102,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; } } @@ -14248,7 +14295,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)); @@ -14308,8 +14355,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))); @@ -14476,7 +14524,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; @@ -14567,8 +14615,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)); } @@ -14674,8 +14722,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; @@ -14694,7 +14742,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) { @@ -14919,15 +14967,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); @@ -14967,7 +15015,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; @@ -14986,7 +15034,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; @@ -15004,7 +15052,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)); @@ -15278,7 +15326,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); } @@ -15414,13 +15462,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 %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 } @@ -15539,7 +15599,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); @@ -15571,7 +15631,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); } @@ -15605,7 +15665,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; @@ -15915,7 +15975,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; @@ -15957,7 +16017,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; } @@ -16116,10 +16176,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) ) @@ -16179,7 +16239,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); } @@ -16190,7 +16250,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)); } @@ -16402,36 +16462,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; @@ -16516,7 +16591,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; @@ -16534,7 +16609,7 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) { 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 @@ -16698,7 +16773,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)]; @@ -17637,7 +17712,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); } @@ -17677,7 +17752,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); @@ -17689,8 +17765,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 = RP2PTR(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 */ @@ -17727,19 +17804,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 = RP2PTR(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 = RP2PTR(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); @@ -17748,8 +17828,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 = RP2PTR(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 */ @@ -17885,10 +17966,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 = RP2PTR(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) { @@ -17901,9 +17983,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 = RP2PTR(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) { @@ -18138,32 +18221,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; @@ -18178,11 +18259,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 = RP2PTR(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); + } + + response = npc->market_buylist(sd, &item_list); + clif->npc_market_purchase_ack(sd, &item_list, response); - clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p)); + VECTOR_CLEAR(item_list); #endif } @@ -18787,7 +18889,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 } diff --git a/src/map/clif.h b/src/map/clif.h index d68a09393..ac0191210 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -40,6 +40,7 @@ struct guild; struct homun_data; struct item; struct item_data; +struct itemlist; // map/itemdb.h struct map_session_data; struct mercenary_data; struct mob_data; @@ -855,7 +856,7 @@ struct clif_interface { void (*messageln) (const int fd, const char* mes); /* message+s(printf) */ void (*messages) (const int fd, const char *mes, ...) __attribute__((format(printf, 2, 3))); - bool (*process_message) (struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_); + bool (*process_message) (struct map_session_data *sd, int format, const char **name_, size_t *namelen_, const char **message_, size_t *messagelen_); void (*wisexin) (struct map_session_data *sd,int type,int flag); void (*wisall) (struct map_session_data *sd,int type,int flag); void (*PMIgnoreList) (struct map_session_data* sd); @@ -997,7 +998,7 @@ struct clif_interface { void (*mail_setattachment) (int fd, int index, uint8 flag); /* auction-related */ void (*auction_openwindow) (struct map_session_data *sd); - void (*auction_results) (struct map_session_data *sd, short count, short pages, uint8 *buf); + void (*auction_results) (struct map_session_data *sd, short count, short pages, const uint8 *buf); void (*auction_message) (int fd, unsigned char flag); void (*auction_close) (int fd, unsigned char flag); void (*auction_setitem) (int fd, int index, bool fail); @@ -1051,7 +1052,7 @@ struct clif_interface { void (*elemental_updatestatus) (struct map_session_data *sd, int type); /* bgqueue */ void (*bgqueue_ack) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK response, unsigned char arena_id); - void (*bgqueue_notice_delete) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name); + void (*bgqueue_notice_delete) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, const char *name); void (*bgqueue_update_info) (struct map_session_data *sd, unsigned char arena_id, int position); void (*bgqueue_joined) (struct map_session_data *sd, int pos); void (*bgqueue_pcleft) (struct map_session_data *sd); @@ -1080,7 +1081,7 @@ struct clif_interface { int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data); /* NPC Market */ void (*npc_market_open) (struct map_session_data *sd, struct npc_data *nd); - void (*npc_market_purchase_ack) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response); + void (*npc_market_purchase_ack) (struct map_session_data *sd, const struct itemlist *item_list, unsigned char response); /* */ bool (*parse_roulette_db) (void); void (*roulette_generate_ack) (struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID); diff --git a/src/map/elemental.c b/src/map/elemental.c index a87deb7d7..0eed4e799 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -254,7 +254,8 @@ void elemental_summon_init(struct elemental_data *ed) { ed->regen.state.block = 0; } -int elemental_data_received(struct s_elemental *ele, bool flag) { +int elemental_data_received(const struct s_elemental *ele, bool flag) +{ struct map_session_data *sd; struct elemental_data *ed; struct s_elemental_db *db; diff --git a/src/map/elemental.h b/src/map/elemental.h index 1a98670e0..8a9bf9414 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -122,7 +122,7 @@ struct elemental_interface { struct view_data * (*get_viewdata) (int class_); int (*create) (struct map_session_data *sd, int class_, unsigned int lifetime); - int (*data_received) (struct s_elemental *ele, bool flag); + int (*data_received) (const struct s_elemental *ele, bool flag); int (*save) (struct elemental_data *ed); int (*change_mode_ack) (struct elemental_data *ed, int mode); diff --git a/src/map/guild.c b/src/map/guild.c index f4f0c0528..f14ee4611 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -230,7 +230,7 @@ struct map_session_data* guild_getavailablesd(struct guild* g) } /// lookup: player AID/CID -> member index -int guild_getindex(struct guild *g,int account_id,int char_id) +int guild_getindex(const struct guild *g, int account_id, int char_id) { int i; @@ -433,7 +433,7 @@ int guild_npc_request_info(int guild_id,const char *event) } //Confirmation of the character belongs to guild -int guild_check_member(struct guild *g) +int guild_check_member(const struct guild *g) { int i; struct map_session_data *sd; @@ -475,7 +475,8 @@ int guild_recv_noinfo(int guild_id) } //Get and display information for all member -int guild_recv_info(struct guild *sg) { +int guild_recv_info(const struct guild *sg) +{ struct guild *g,before; int i,bm,m; DBData data; @@ -1126,7 +1127,7 @@ int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char /*==================================================== * Notification of member has changed his guild title *---------------------------------------------------*/ -int guild_position_changed(int guild_id,int idx,struct guild_position *p) +int guild_position_changed(int guild_id, int idx, const struct guild_position *p) { struct guild *g=guild->search(guild_id); int i; @@ -1883,7 +1884,8 @@ int guild_gm_changed(int guild_id, int account_id, int char_id) /*==================================================== * Guild disbanded *---------------------------------------------------*/ -int guild_break(struct map_session_data *sd,char *name) { +int guild_break(struct map_session_data *sd, const char *name) +{ struct guild *g; struct unit_data *ud; int i; @@ -2064,7 +2066,7 @@ void guild_castle_reconnect(int castle_id, int index, int value) } // Load castle data then invoke OnAgitInit* on last -int guild_castledataloadack(int len, struct guild_castle *gc) +int guild_castledataloadack(int len, const struct guild_castle *gc) { int i; int n = (len-4) / sizeof(struct guild_castle); diff --git a/src/map/guild.h b/src/map/guild.h index 10749f8ad..cd796adb3 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -98,7 +98,7 @@ struct guild_interface { struct guild_castle *(*mapindex2gc) (short map_index); /* */ struct map_session_data *(*getavailablesd) (struct guild *g); - int (*getindex) (struct guild *g,int account_id,int char_id); + int (*getindex) (const struct guild *g, int account_id, int char_id); int (*getposition) (struct guild *g, struct map_session_data *sd); unsigned int (*payexp) (struct map_session_data *sd,unsigned int exp); int (*getexp) (struct map_session_data *sd,int exp); // [Celest] @@ -107,7 +107,7 @@ struct guild_interface { int (*created) (int account_id,int guild_id); int (*request_info) (int guild_id); int (*recv_noinfo) (int guild_id); - int (*recv_info) (struct guild *sg); + int (*recv_info) (const struct guild *sg); int (*npc_request_info) (int guild_id,const char *ev); int (*invite) (struct map_session_data *sd,struct map_session_data *tsd); int (*reply_invite) (struct map_session_data *sd,int guild_id,int flag); @@ -130,7 +130,7 @@ struct guild_interface { int (*change_memberposition) (int guild_id,int account_id,int char_id,short idx); int (*memberposition_changed) (struct guild *g,int idx,int pos); int (*change_position) (int guild_id,int idx,int mode,int exp_mode,const char *name); - int (*position_changed) (int guild_id,int idx,struct guild_position *p); + int (*position_changed) (int guild_id, int idx, const struct guild_position *p); int (*change_notice) (struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2); int (*notice_changed) (int guild_id,const char *mes1,const char *mes2); int (*change_emblem) (struct map_session_data *sd,int len,const char *data); @@ -139,14 +139,14 @@ struct guild_interface { int (*recv_message) (int guild_id,int account_id,const char *mes,int len); int (*send_dot_remove) (struct map_session_data *sd); int (*skillupack) (int guild_id,uint16 skill_id,int account_id); - int (*dobreak) (struct map_session_data *sd,char *name); + int (*dobreak) (struct map_session_data *sd, const char *name); int (*broken) (int guild_id,int flag); int (*gm_change) (int guild_id, struct map_session_data *sd); int (*gm_changed) (int guild_id, int account_id, int char_id); /* */ void (*castle_map_init) (void); int (*castledatasave) (int castle_id,int index,int value); - int (*castledataloadack) (int len, struct guild_castle *gc); + int (*castledataloadack) (int len, const struct guild_castle *gc); void (*castle_reconnect) (int castle_id, int index, int value); /* */ void (*agit_start) (void); @@ -176,7 +176,7 @@ struct guild_interface { int (*broken_sub) (DBKey key, DBData *data, va_list ap); int (*castle_broken_sub) (DBKey key, DBData *data, va_list ap); void (*makemember) (struct guild_member *m,struct map_session_data *sd); - int (*check_member) (struct guild *g); + int (*check_member) (const struct guild *g); int (*get_alliance_count) (struct guild *g,int flag); void (*castle_reconnect_sub) (void *key, void *data, va_list ap); }; diff --git a/src/map/homunculus.c b/src/map/homunculus.c index b642c197f..d10cea64a 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -705,7 +705,8 @@ void homunculus_hunger_timer_delete(struct homun_data *hd) { } } -int homunculus_change_name(struct map_session_data *sd,char *name) { +int homunculus_change_name(struct map_session_data *sd, const char *name) +{ int i; struct homun_data *hd; nullpo_retr(1, sd); @@ -725,21 +726,26 @@ int homunculus_change_name(struct map_session_data *sd,char *name) { return intif_rename_hom(sd, name); } -bool homunculus_change_name_ack(struct map_session_data *sd, char* name, int flag) { +bool homunculus_change_name_ack(struct map_session_data *sd, const char *name, int flag) +{ struct homun_data *hd; + char *newname = NULL; nullpo_retr(false, sd); nullpo_retr(false, name); hd = sd->hd; nullpo_retr(false, hd); if (!homun_alive(hd)) return false; - normalize_name(name," ");//bugreport:3032 + newname = aStrndup(name, NAME_LENGTH-1); + normalize_name(newname, " ");//bugreport:3032 // FIXME[Haru]: This should be normalized by the inter-server (so that it's const here) - if ( !flag || !strlen(name) ) { + if (flag == 0 || strlen(newname) == 0) { clif->message(sd->fd, msg_sd(sd,280)); // You cannot use this name + aFree(newname); return false; } - safestrncpy(hd->homunculus.name,name,NAME_LENGTH); + safestrncpy(hd->homunculus.name, newname, NAME_LENGTH); + aFree(newname); clif->charnameack (0,&hd->bl); hd->homunculus.rename_flag = 1; clif->hominfo(sd,hd,0); @@ -769,8 +775,19 @@ int homunculus_db_search(int key,int type) { return -1; } -// Create homunc structure -bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { +/** + * Creates and initializes an homunculus. + * + * @remark + * The char_id field in the source homunculus data is ignored (the sd's + * character ID is used instead). + * + * @param sd The owner character. + * @param hom The homunculus source data. + * @retval false in case of errors. + */ +bool homunculus_create(struct map_session_data *sd, const struct s_homunculus *hom) +{ struct homun_data *hd; int i = 0; @@ -794,6 +811,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { hd->master = sd; hd->homunculusDB = &homun->dbs->db[i]; memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus)); + hd->homunculus.char_id = sd->status.char_id; // Fix character ID if necessary. hd->exp_next = homun->dbs->exptable[hd->homunculus.level - 1]; status->set_viewdata(&hd->bl, hd->homunculus.class_); @@ -863,35 +881,38 @@ bool homunculus_call(struct map_session_data *sd) { } // Receive homunculus data from char server -bool homunculus_recv_data(int account_id, struct s_homunculus *sh, int flag) { +bool homunculus_recv_data(int account_id, const struct s_homunculus *sh, int flag) +{ struct map_session_data *sd; struct homun_data *hd; nullpo_retr(false, sh); + sd = map->id2sd(account_id); - if(!sd) + if (sd == NULL) return false; - if (sd->status.char_id != sh->char_id) { - if (sd->status.hom_id == sh->hom_id) - sh->char_id = sd->status.char_id; //Correct char id. - else - return false; - } - if(!flag) { // Failed to load + + if (flag == 0) { // Failed to load sd->status.hom_id = 0; return false; } - if (!sd->status.hom_id) //Hom just created. + if (sd->status.char_id != sh->char_id && sd->status.hom_id != sh->hom_id) + return false; + + if (sd->status.hom_id == 0) //Hom just created. sd->status.hom_id = sh->hom_id; - if (sd->hd) //uh? Overwrite the data. - memcpy(&sd->hd->homunculus, sh, sizeof(struct s_homunculus)); - else + if (sd->hd != NULL) { + //uh? Overwrite the data. + memcpy(&sd->hd->homunculus, sh, sizeof sd->hd->homunculus); + sd->hd->homunculus.char_id = sd->status.char_id; // Correct char id if necessary. + } else { homun->create(sd, sh); + } hd = sd->hd; - if(hd && hd->homunculus.hp && hd->homunculus.vaporize == HOM_ST_ACTIVE && hd->bl.prev == NULL && sd->bl.prev != NULL) { + if(hd != NULL && hd->homunculus.hp && hd->homunculus.vaporize == HOM_ST_ACTIVE && hd->bl.prev == NULL && sd->bl.prev != NULL) { enum homun_type htype = homun->class2type(hd->homunculus.class_); map->addblock(&hd->bl); diff --git a/src/map/homunculus.h b/src/map/homunculus.h index c2ce042ec..3dd9e4772 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -186,13 +186,13 @@ struct homunculus_interface { bool (*feed) (struct map_session_data *sd, struct homun_data *hd); int (*hunger_timer) (int tid, int64 tick, int id, intptr_t data); void (*hunger_timer_delete) (struct homun_data *hd); - int (*change_name) (struct map_session_data *sd,char *name); - bool (*change_name_ack) (struct map_session_data *sd, char* name, int flag); + int (*change_name) (struct map_session_data *sd, const char *name); + bool (*change_name_ack) (struct map_session_data *sd, const char *name, int flag); int (*db_search) (int key,int type); - bool (*create) (struct map_session_data *sd, struct s_homunculus *hom); + bool (*create) (struct map_session_data *sd, const struct s_homunculus *hom); void (*init_timers) (struct homun_data * hd); bool (*call) (struct map_session_data *sd); - bool (*recv_data) (int account_id, struct s_homunculus *sh, int flag); + bool (*recv_data) (int account_id, const struct s_homunculus *sh, int flag); bool (*creation_request) (struct map_session_data *sd, int class_); bool (*ressurect) (struct map_session_data* sd, unsigned char per, short x, short y); void (*revive) (struct homun_data *hd, unsigned int hp, unsigned int sp); diff --git a/src/map/intif.c b/src/map/intif.c index 9722b8f9a..4445d04e0 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -132,7 +132,7 @@ int intif_delete_petdata(int pet_id) return 1; } -int intif_rename(struct map_session_data *sd, int type, char *name) +int intif_rename(struct map_session_data *sd, int type, const char *name) { if (intif->CheckForCharServer()) return 1; @@ -231,7 +231,7 @@ int intif_main_message(struct map_session_data* sd, const char* message) } // The transmission of Wisp/Page to inter-server (player not found on this server) -int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, size_t mes_len) +int intif_wis_message(struct map_session_data *sd, const char *nick, const char *mes, size_t mes_len) { if (intif->CheckForCharServer()) return 0; @@ -350,7 +350,7 @@ int intif_saveregistry(struct map_session_data *sd) { WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ plen += 1; - safestrncpy((char*)WFIFOP(inter_fd,plen), varname, len); + safestrncpy(WFIFOP(inter_fd,plen), varname, len); plen += len; WFIFOL(inter_fd, plen) = script_getvaridx(key.i64); @@ -368,7 +368,7 @@ int intif_saveregistry(struct map_session_data *sd) { WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ plen += 1; - safestrncpy((char*)WFIFOP(inter_fd,plen), p->value, len); + safestrncpy(WFIFOP(inter_fd,plen), p->value, len); plen += len; } else { script->reg_destroy_single(sd,key.i64,&p->flag); @@ -463,7 +463,7 @@ int intif_send_guild_storage(int account_id,struct guild_storage *gstor) } // Party creation request -int intif_create_party(struct party_member *member,char *name,int item,int item2) +int intif_create_party(struct party_member *member, const char *name, int item, int item2) { if (intif->CheckForCharServer()) return 0; @@ -684,7 +684,7 @@ int intif_guild_leave(int guild_id,int account_id,int char_id,int flag,const cha WFIFOL(inter_fd, 6) = account_id; WFIFOL(inter_fd,10) = char_id; WFIFOB(inter_fd,14) = flag; - safestrncpy((char*)WFIFOP(inter_fd,15),mes,40); + safestrncpy(WFIFOP(inter_fd,15),mes,40); WFIFOSET(inter_fd,55); return 0; } @@ -956,13 +956,13 @@ int intif_homunculus_requestdelete(int homun_id) // Wisp/Page reception // rewritten by [Yor] void intif_parse_WisMessage(int fd) { struct map_session_data* sd; - char *wisp_source; + const char *wisp_source; char name[NAME_LENGTH]; int id, i; id=RFIFOL(fd,4); - safestrncpy(name, (char*)RFIFOP(fd,32), NAME_LENGTH); + safestrncpy(name, RFIFOP(fd,32), NAME_LENGTH); sd = map->nick2sd(name); if(sd == NULL || strcmp(sd->status.name, name) != 0) { //Not found @@ -973,7 +973,7 @@ void intif_parse_WisMessage(int fd) { intif_wis_replay(id, 2); return; } - wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor] + wisp_source = RFIFOP(fd,8); // speed up [Yor] for(i=0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0' && strcmp(sd->ignore[i].name, wisp_source) != 0 @@ -985,17 +985,19 @@ void intif_parse_WisMessage(int fd) { return; } //Success to send whisper. - clif->wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56); + clif->wis_message(sd->fd, wisp_source, RFIFOP(fd,56),RFIFOW(fd,2)-56); intif_wis_replay(id,0); // success } // Wisp/page transmission result reception -void intif_parse_WisEnd(int fd) { +void intif_parse_WisEnd(int fd) +{ struct map_session_data* sd; + const char *playername = RFIFOP(fd, 2); if (battle_config.etc_log) - ShowInfo("intif_parse_wisend: player: %s, flag: %d\n", RFIFOP(fd,2), RFIFOB(fd,26)); // flag: 0: success to send whisper, 1: target character is not logged in?, 2: ignored by target - sd = map->nick2sd((char *)RFIFOP(fd,2)); + ShowInfo("intif_parse_wisend: player: %s, flag: %d\n", playername, RFIFOB(fd,26)); // flag: 0: success to send whisper, 1: target character is not logged in?, 2: ignored by target + sd = map->nick2sd(playername); if (sd != NULL) clif->wis_end(sd->fd, RFIFOB(fd,26)); @@ -1032,8 +1034,8 @@ void mapif_parse_WisToGM(int fd) message = (char *) (mes_len >= 255 ? (char *) aMalloc(mes_len) : mbuf); permission = RFIFOL(fd,28); - safestrncpy(Wisp_name, (char*)RFIFOP(fd,4), NAME_LENGTH); - safestrncpy(message, (char*)RFIFOP(fd,32), mes_len); + safestrncpy(Wisp_name, RFIFOP(fd,4), NAME_LENGTH); + safestrncpy(message, RFIFOP(fd,32), mes_len); // information is sent to all online GM map->foreachpc(mapif_parse_WisToGM_sub, permission, Wisp_name, message, mes_len); @@ -1098,14 +1100,14 @@ void intif_parse_Registers(int fd) char sval[254]; for (i = 0; i < max; i++) { int len = RFIFOB(fd, cursor); - safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); cursor += len + 1; index = RFIFOL(fd, cursor); cursor += 4; len = RFIFOB(fd, cursor); - safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); + safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); cursor += len + 1; script->set_reg(NULL,sd,reference_uid(script->add_str(key), index), key, (void*)sval, NULL); @@ -1121,7 +1123,7 @@ void intif_parse_Registers(int fd) int ival; int len = RFIFOB(fd, cursor); - safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); cursor += len + 1; index = RFIFOL(fd, cursor); @@ -1195,7 +1197,7 @@ void intif_parse_PartyCreated(int fd) { if(battle_config.etc_log) ShowInfo("intif: party created by account %u\n\n", RFIFOL(fd,2)); - party->created(RFIFOL(fd,2), RFIFOL(fd,6),RFIFOB(fd,10),RFIFOL(fd,11), (char *)RFIFOP(fd,15)); + party->created(RFIFOL(fd,2), RFIFOL(fd,6),RFIFOB(fd,10),RFIFOL(fd,11), RFIFOP(fd,15)); } // Receive party info @@ -1209,7 +1211,7 @@ void intif_parse_PartyInfo(int fd) { if (RFIFOW(fd,2) != 8+sizeof(struct party)) ShowError("intif: party info: data size mismatch (char_id=%u party_id=%u packet_len=%d expected_len=%"PRIuS")\n", RFIFOL(fd,4), RFIFOL(fd,8), RFIFOW(fd,2), 8+sizeof(struct party)); - party->recv_info((struct party *)RFIFOP(fd,8), RFIFOL(fd,4)); + party->recv_info(RFIFOP(fd,8), RFIFOL(fd,4)); } // ACK adding party member @@ -1247,7 +1249,7 @@ void intif_parse_PartyMove(int fd) // ACK party messages void intif_parse_PartyMessage(int fd) { - party->recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12); + party->recv_message(RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12), RFIFOW(fd,2)-12); } // ACK guild creation @@ -1265,7 +1267,7 @@ void intif_parse_GuildInfo(int fd) { if (RFIFOW(fd,2)!=sizeof(struct guild)+4) ShowError("intif: guild info: data size mismatch - Gid: %u recv size: %d Expected size: %"PRIuS"\n", RFIFOL(fd,4), RFIFOW(fd,2), sizeof(struct guild)+4); - guild->recv_info((struct guild *)RFIFOP(fd,4)); + guild->recv_info(RFIFOP(fd,4)); } // ACK adding guild member @@ -1277,7 +1279,7 @@ void intif_parse_GuildMemberAdded(int fd) { // ACK member leaving guild void intif_parse_GuildMemberWithdraw(int fd) { - guild->member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),(char *)RFIFOP(fd,55),(char *)RFIFOP(fd,15)); + guild->member_withdraw(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOB(fd,14), RFIFOP(fd,55), RFIFOP(fd,15)); } // ACK guild member basic info @@ -1308,15 +1310,19 @@ void intif_parse_GuildBasicInfoChanged(int fd) { case GBI_SKILLPOINT: g->skill_point = RFIFOL(fd,10); break; case GBI_SKILLLV: { int idx, max; - struct guild_skill *gs = (struct guild_skill *)RFIFOP(fd,10); + const struct guild_skill *p_gs = RFIFOP(fd,10); + struct guild_skill *gs = NULL; - idx = gs->id - GD_SKILLBASE; + idx = p_gs->id - GD_SKILLBASE; Assert_retv(idx >= 0 && idx < MAX_GUILDSKILL); + + gs = &g->skill[idx]; + memcpy(gs, p_gs, sizeof(*gs)); + max = guild->skill_get_max(gs->id); - if( gs->lv > max ) + if (gs->lv > max) gs->lv = max; - memcpy(&(g->skill[idx]), gs, sizeof(g->skill[idx])); break; } } @@ -1359,7 +1365,7 @@ void intif_parse_GuildPosition(int fd) { if (RFIFOW(fd,2)!=sizeof(struct guild_position)+12) ShowError("intif: guild info: data size mismatch (%u) %d != %"PRIuS"\n", RFIFOL(fd,4), RFIFOW(fd,2), sizeof(struct guild_position) + 12); - guild->position_changed(RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12)); + guild->position_changed(RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12)); } // ACK change of guild skill update @@ -1369,27 +1375,27 @@ void intif_parse_GuildSkillUp(int fd) { // ACK change of guild relationship void intif_parse_GuildAlliance(int fd) { - guild->allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43)); + guild->allianceack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOB(fd,18), RFIFOP(fd,19), RFIFOP(fd,43)); } // ACK change of guild notice void intif_parse_GuildNotice(int fd) { - guild->notice_changed(RFIFOL(fd,2),(char *) RFIFOP(fd,6),(char *) RFIFOP(fd,66)); + guild->notice_changed(RFIFOL(fd,2), RFIFOP(fd,6), RFIFOP(fd,66)); } // ACK change of guild emblem void intif_parse_GuildEmblem(int fd) { - guild->emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8), (char *)RFIFOP(fd,12)); + guild->emblem_changed(RFIFOW(fd,2)-12, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12)); } // ACK guild message void intif_parse_GuildMessage(int fd) { - guild->recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12); + guild->recv_message(RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12), RFIFOW(fd,2)-12); } // Reply guild castle data request void intif_parse_GuildCastleDataLoad(int fd) { - guild->castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4)); + guild->castledataloadack(RFIFOW(fd,2), RFIFOP(fd,4)); } // ACK change of guildmaster @@ -1440,10 +1446,10 @@ void intif_parse_ChangeNameOk(int fd) case 0: //Players [NOT SUPPORTED YET] break; case 1: //Pets - pet->change_name_ack(sd, (char*)RFIFOP(fd,12), RFIFOB(fd,11)); + pet->change_name_ack(sd, RFIFOP(fd,12), RFIFOB(fd,11)); break; case 2: //Hom - homun->change_name_ack(sd, (char*)RFIFOP(fd,12), RFIFOB(fd,11)); + homun->change_name_ack(sd, RFIFOP(fd,12), RFIFOB(fd,11)); break; } return; @@ -1459,7 +1465,7 @@ void intif_parse_CreateHomunculus(int fd) { ShowError("intif: create homun data: data size mismatch %d != %"PRIuS"\n", len, sizeof(struct s_homunculus)); return; } - homun->recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8)) ; + homun->recv_data(RFIFOL(fd,4), RFIFOP(fd,9), RFIFOB(fd,8)) ; } void intif_parse_RecvHomunculusData(int fd) { @@ -1470,7 +1476,7 @@ void intif_parse_RecvHomunculusData(int fd) { ShowError("intif: homun data: data size mismatch %d != %"PRIuS"\n", len, sizeof(struct s_homunculus)); return; } - homun->recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8)); + homun->recv_data(RFIFOL(fd,4), RFIFOP(fd,9), RFIFOB(fd,8)); } /* Really? Whats the point, shouldn't be sent when successful then [Ind] */ @@ -1527,7 +1533,7 @@ void intif_parse_QuestLog(int fd) { sd->quest_log = NULL; } } else { - struct quest *received = (struct quest *)RFIFOP(fd, 8); + const struct quest *received = RFIFOP(fd, 8); int i, k = num_received; if (sd->quest_log) { RECREATE(sd->quest_log, struct quest, num_received); @@ -1837,8 +1843,8 @@ void intif_parse_MailSend(int fd) { void intif_parse_MailNew(int fd) { struct map_session_data *sd = map->charid2sd(RFIFOL(fd,2)); int mail_id = RFIFOL(fd,6); - const char* sender_name = (char*)RFIFOP(fd,10); - const char* title = (char*)RFIFOP(fd,34); + const char *sender_name = RFIFOP(fd,10); + const char *title = RFIFOP(fd,34); if( sd == NULL ) return; @@ -1876,7 +1882,7 @@ void intif_parse_AuctionResults(int fd) { struct map_session_data *sd = map->charid2sd(RFIFOL(fd,4)); short count = RFIFOW(fd,8); short pages = RFIFOW(fd,10); - uint8* data = RFIFOP(fd,12); + const uint8 *data = RFIFOP(fd,12); if( sd == NULL ) return; @@ -2063,7 +2069,7 @@ void intif_parse_MercenaryReceived(int fd) { return; } - mercenary->data_received((struct s_mercenary*)RFIFOP(fd,5), RFIFOB(fd,4)); + mercenary->data_received(RFIFOP(fd,5), RFIFOB(fd,4)); } int intif_mercenary_request(int merc_id, int char_id) @@ -2145,7 +2151,7 @@ void intif_parse_ElementalReceived(int fd) { return; } - elemental->data_received((struct s_elemental*)RFIFOP(fd,5), RFIFOB(fd,4)); + elemental->data_received(RFIFOP(fd,5), RFIFOB(fd,4)); } int intif_elemental_request(int ele_id, int char_id) @@ -2207,7 +2213,7 @@ void intif_request_accinfo( int u_fd, int aid, int group_lv, char* query ) { WFIFOL(inter_fd,2) = u_fd; WFIFOL(inter_fd,6) = aid; WFIFOL(inter_fd,10) = group_lv; - safestrncpy((char *)WFIFOP(inter_fd,14), query, NAME_LENGTH); + safestrncpy(WFIFOP(inter_fd,14), query, NAME_LENGTH); WFIFOSET(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH); @@ -2224,7 +2230,7 @@ void intif_parse_MessageToFD(int fd) { /* matching e.g. previous fd owner didn't dc during request or is still the same */ if( sd && sd->bl.id == aid ) { char msg[512]; - safestrncpy(msg, (char*)RFIFOP(fd,12), RFIFOW(fd,2) - 12); + safestrncpy(msg, RFIFOP(fd,12), RFIFOW(fd,2) - 12); clif->messagecolor_self(u_fd, COLOR_DEFAULT ,msg); } @@ -2288,9 +2294,9 @@ int intif_parse(int fd) switch(cmd){ case 0x3800: if (RFIFOL(fd,4) == 0xFF000000) //Normal announce. - clif->broadcast(NULL, (char *) RFIFOP(fd,16), packet_len-16, BC_DEFAULT, ALL_CLIENT); + clif->broadcast(NULL, RFIFOP(fd,16), packet_len-16, BC_DEFAULT, ALL_CLIENT); else //Color announce. - clif->broadcast2(NULL, (char *) RFIFOP(fd,16), packet_len-16, RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), ALL_CLIENT); + clif->broadcast2(NULL, RFIFOP(fd,16), packet_len-16, RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), ALL_CLIENT); break; case 0x3801: intif->pWisMessage(fd); break; case 0x3802: intif->pWisEnd(fd); break; diff --git a/src/map/intif.h b/src/map/intif.h index 0bcaae941..dccd31d80 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -62,13 +62,13 @@ struct intif_interface { int (*broadcast) (const char* mes, size_t len, int type); int (*broadcast2) (const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY); int (*main_message) (struct map_session_data* sd, const char* message); - int (*wis_message) (struct map_session_data *sd,char *nick,char *mes,size_t mes_len); + int (*wis_message) (struct map_session_data *sd, const char *nick, const char *mes, size_t mes_len); int (*wis_message_to_gm) (char *Wisp_name, int permission, char *mes); int (*saveregistry) (struct map_session_data *sd); int (*request_registry) (struct map_session_data *sd, int flag); int (*request_guild_storage) (int account_id, int guild_id); int (*send_guild_storage) (int account_id, struct guild_storage *gstor); - int (*create_party) (struct party_member *member,char *name,int item,int item2); + int (*create_party) (struct party_member *member, const char *name, int item, int item2); int (*request_partyinfo) (int party_id, int char_id); int (*party_addmember) (int party_id,struct party_member *member); int (*party_changeoption) (int party_id, int account_id, int exp, int item); @@ -98,7 +98,7 @@ struct intif_interface { int (*request_petdata) (int account_id, int char_id, int pet_id); int (*save_petdata) (int account_id, struct s_pet *p); int (*delete_petdata) (int pet_id); - int (*rename) (struct map_session_data *sd, int type, char *name); + int (*rename) (struct map_session_data *sd, int type, const char *name); int (*homunculus_create) (int account_id, struct s_homunculus *sh); bool (*homunculus_requestload) (int account_id, int homun_id); int (*homunculus_requestsave) (int account_id, struct s_homunculus* sh); diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c index 3d8ec8b5d..b520e9e91 100644 --- a/src/map/irc-bot.c +++ b/src/map/irc-bot.c @@ -134,7 +134,7 @@ struct irc_func* irc_func_search(char* function_name) { * @see do_sockets */ int irc_parse(int fd) { - char *parse_string = NULL, *str_safe = NULL; + char *parse_string = NULL, *p = NULL, *str_safe = NULL; if (sockt->session[fd]->flag.eof) { sockt->close(fd); @@ -150,18 +150,19 @@ int irc_parse(int fd) { if( !RFIFOREST(fd) ) return 0; - parse_string = (char*)RFIFOP(fd,0); - parse_string[ RFIFOREST(fd) - 1 ] = '\0'; + parse_string = aMalloc(RFIFOREST(fd)); + safestrncpy(parse_string, RFIFOP(fd,0), RFIFOREST(fd)); + RFIFOSKIP(fd, RFIFOREST(fd)); + RFIFOFLUSH(fd); - parse_string = strtok_r(parse_string,"\r\n",&str_safe); + p = strtok_r(parse_string,"\r\n",&str_safe); - while (parse_string != NULL) { + while (p != NULL) { ircbot->parse_sub(fd,parse_string); - parse_string = strtok_r(NULL,"\r\n",&str_safe); + p = strtok_r(NULL,"\r\n",&str_safe); } + aFree(parse_string); - RFIFOSKIP(fd, RFIFOREST(fd)); - RFIFOFLUSH(fd); return 0; } @@ -244,7 +245,7 @@ void irc_send(char *str) { if (len > IRC_MESSAGE_LENGTH-3) len = IRC_MESSAGE_LENGTH-3; WFIFOHEAD(ircbot->fd, len); - snprintf((char*)WFIFOP(ircbot->fd,0),IRC_MESSAGE_LENGTH, "%s\r\n", str); + snprintf(WFIFOP(ircbot->fd,0),IRC_MESSAGE_LENGTH, "%s\r\n", str); WFIFOSET(ircbot->fd, len); } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 23a4bb1ca..47446d617 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -395,6 +395,14 @@ enum ItemNouseRestrictions { INR_ALL = 0x1 ///< Sum of all the above values }; +/** Convenience item list (entry) used in various functions */ +struct itemlist_entry { + int id; ///< Item ID or (inventory) index + int16 amount; ///< Amount +}; +/** Convenience item list used in various functions */ +VECTOR_STRUCT_DECL(itemlist, struct itemlist_entry); + struct item_combo { struct script_code *script; unsigned short nameid[MAX_ITEMS_PER_COMBO];/* nameid array */ diff --git a/src/map/mercenary.c b/src/map/mercenary.c index e6c911ef6..ec0b2291f 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -301,7 +301,8 @@ void merc_contract_init(struct mercenary_data *md) md->regen.state.block = 0; } -int merc_data_received(struct s_mercenary *merc, bool flag) { +int merc_data_received(const struct s_mercenary *merc, bool flag) +{ struct map_session_data *sd; struct mercenary_data *md; struct s_mercenary_db *db; diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 1b3453a84..142460e2a 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -120,7 +120,7 @@ struct mercenary_interface { struct view_data * (*get_viewdata) (int class_); int (*create) (struct map_session_data *sd, int class_, unsigned int lifetime); - int (*data_received) (struct s_mercenary *merc, bool flag); + int (*data_received) (const struct s_mercenary *merc, bool flag); int (*save) (struct mercenary_data *md); void (*heal) (struct mercenary_data *md, int hp, int sp); diff --git a/src/map/npc.c b/src/map/npc.c index 9bd6698d2..2b1a541d8 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1386,8 +1386,9 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) { /*========================================== * Cash Shop Buy List *------------------------------------------*/ -int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) { - int i, j, nameid, amount, new_, w, vt; +int npc_cashshop_buylist(struct map_session_data *sd, int points, struct itemlist *item_list) +{ + int i, j, new_, w, vt; struct npc_data *nd = NULL; struct npc_item_list *shop = NULL; unsigned short shop_size = 0; @@ -1395,7 +1396,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns if( sd->state.trading ) return ERROR_TYPE_EXCHANGE; - if( count <= 0 ) + if (VECTOR_LENGTH(*item_list) <= 0) return ERROR_TYPE_ITEM_ID; if( points < 0 ) @@ -1421,24 +1422,23 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns vt = 0; // Global Value // Validating Process ---------------------------------------------------- - for( i = 0; i < count; i++ ) { - nameid = item_list[i*2+1]; - amount = item_list[i*2+0]; + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); - if( !itemdb->exists(nameid) || amount <= 0 ) + if (!itemdb->exists(entry->id) || entry->amount <= 0) return ERROR_TYPE_ITEM_ID; - ARR_FIND(0,shop_size,j,shop[j].nameid == nameid); - if( j == shop_size || shop[j].value <= 0 ) + ARR_FIND(0,shop_size,j,shop[j].nameid == entry->id); + if (j == shop_size || shop[j].value <= 0) return ERROR_TYPE_ITEM_ID; - if( !itemdb->isstackable(nameid) && amount > 1 ) { + if (!itemdb->isstackable(entry->id) && entry->amount > 1) { ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of non-stackable item %d!\n", - sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); - amount = item_list[i*2+0] = 1; + sd->status.name, sd->status.account_id, sd->status.char_id, entry->amount, entry->id); + entry->amount = 1; } - switch( pc->checkadditem(sd,nameid,amount) ) { + switch (pc->checkadditem(sd, entry->id, entry->amount)) { case ADDITEM_NEW: new_++; break; @@ -1446,8 +1446,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns return ERROR_TYPE_INVENTORY_WEIGHT; } - vt += shop[j].value * amount; - w += itemdb_weight(nameid) * amount; + vt += shop[j].value * entry->amount; + w += itemdb_weight(entry->id) * entry->amount; } if( w + sd->weight > sd->max_weight ) @@ -1468,18 +1468,16 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns pc->paycash(sd,vt,points); } // Delivery Process ---------------------------------------------------- - for( i = 0; i < count; i++ ) { + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); struct item item_tmp; - nameid = item_list[i*2+1]; - amount = item_list[i*2+0]; - memset(&item_tmp,0,sizeof(item_tmp)); - if( !pet->create_egg(sd,nameid) ) { - item_tmp.nameid = nameid; + if (!pet->create_egg(sd, entry->id)) { + item_tmp.nameid = entry->id; item_tmp.identify = 1; - pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC); + pc->additem(sd, &item_tmp, entry->amount, LOG_TYPE_NPC); } } @@ -1487,7 +1485,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns } //npc_buylist for script-controlled shops. -int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd) +int npc_buylist_sub(struct map_session_data *sd, struct itemlist *item_list, struct npc_data *nd) { char npc_ev[EVENT_NAME_LENGTH]; int i; @@ -1499,9 +1497,12 @@ int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_lis script->cleararray_pc(sd, "@bought_quantity", (void*)0); // save list of bought items - for( i = 0; i < n; i++ ) { - script->setarray_pc(sd, "@bought_nameid", i, (void*)(intptr_t)item_list[i*2+1], &key_nameid); - script->setarray_pc(sd, "@bought_quantity", i, (void*)(intptr_t)item_list[i*2], &key_amount); + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + intptr_t nameid = entry->id; + intptr_t amount = entry->amount; + script->setarray_pc(sd, "@bought_nameid", i, (void *)nameid, &key_nameid); + script->setarray_pc(sd, "@bought_quantity", i, (void *)amount, &key_amount); } // invoke event @@ -1805,11 +1806,15 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po return ERROR_TYPE_NONE; } -/// Player item purchase from npc shop. -/// -/// @param item_list 'n' pairs <amount,itemid> -/// @return result code for clif->parse_NpcBuyListSend -int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { +/** + * Processes a player item purchase from npc shop. + * + * @param sd Buyer character. + * @param item_list List of items. + * @return result code for clif->parse_NpcBuyListSend. + */ +int npc_buylist(struct map_session_data *sd, struct itemlist *item_list) +{ struct npc_data* nd; struct npc_item_list *shop = NULL; int64 z; @@ -1838,30 +1843,29 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { w = 0; new_ = 0; // process entries in buy list, one by one - for( i = 0; i < n; ++i ) { - int nameid, amount, value; + for (i = 0; i < VECTOR_LENGTH(*item_list); ++i) { + int value; + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); // find this entry in the shop's sell list ARR_FIND( 0, shop_size, j, - item_list[i*2+1] == shop[j].nameid || //Normal items - item_list[i*2+1] == itemdb_viewid(shop[j].nameid) //item_avail replacement + entry->id == shop[j].nameid || //Normal items + entry->id == itemdb_viewid(shop[j].nameid) //item_avail replacement ); - - if( j == shop_size ) + if (j == shop_size) return 3; // no such item in shop - amount = item_list[i*2+0]; - nameid = item_list[i*2+1] = shop[j].nameid; //item_avail replacement + entry->id = shop[j].nameid; //item_avail replacement value = shop[j].value; - if( !itemdb->exists(nameid) ) + if (!itemdb->exists(entry->id)) return 3; // item no longer in itemdb - if( !itemdb->isstackable(nameid) && amount > 1 ) { + if (!itemdb->isstackable(entry->id) && entry->amount > 1) { //Exploit? You can't buy more than 1 of equipment types o.O ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of non-stackable item %d!\n", - sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); - amount = item_list[i*2+0] = 1; + sd->status.name, sd->status.account_id, sd->status.char_id, entry->amount, entry->id); + entry->amount = 1; } if( nd->master_nd ) { @@ -1869,7 +1873,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { continue; } - switch( pc->checkadditem(sd,nameid,amount) ) { + switch (pc->checkadditem(sd, entry->id, entry->amount)) { case ADDITEM_EXIST: break; @@ -1883,12 +1887,12 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { value = pc->modifybuyvalue(sd,value); - z += (int64)value * amount; - w += itemdb_weight(nameid) * amount; + z += (int64)value * entry->amount; + w += itemdb_weight(entry->id) * entry->amount; } - if( nd->master_nd != NULL ) //Script-based shops. - return npc->buylist_sub(sd,n,item_list,nd->master_nd); + if (nd->master_nd != NULL) //Script-based shops. + return npc->buylist_sub(sd, item_list, nd->master_nd); if (z > sd->status.zeny) return 1; // Not enough Zeny @@ -1899,19 +1903,17 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { pc->payzeny(sd, (int)z, LOG_TYPE_NPC, NULL); - for( i = 0; i < n; ++i ) { - int nameid = item_list[i*2+1]; - int amount = item_list[i*2+0]; - - if (itemdb_type(nameid) == IT_PETEGG) { - pet->create_egg(sd, nameid); + for (i = 0; i < VECTOR_LENGTH(*item_list); ++i) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + if (itemdb_type(entry->id) == IT_PETEGG) { + pet->create_egg(sd, entry->id); } else { struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = nameid; + item_tmp.nameid = entry->id; item_tmp.identify = 1; - pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC); + pc->additem(sd, &item_tmp, entry->amount, LOG_TYPE_NPC); } } @@ -1932,9 +1934,10 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { } /** - * parses incoming npc market purchase list + * Processes incoming npc market purchase list **/ -int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p) { +int npc_market_buylist(struct map_session_data *sd, struct itemlist *item_list) +{ struct npc_data* nd; struct npc_item_list *shop = NULL; int64 z; @@ -1942,11 +1945,11 @@ int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, st unsigned short shop_size = 0; nullpo_retr(1, sd); - nullpo_retr(1, p); + nullpo_retr(1, item_list); nd = npc->checknear(sd,map->id2bl(sd->npc_shopid)); - if( nd == NULL || nd->subtype != SCRIPT || !list_size || !nd->u.scr.shop || nd->u.scr.shop->type != NST_MARKET ) + if (nd == NULL || nd->subtype != SCRIPT || VECTOR_LENGTH(*item_list) == 0 || !nd->u.scr.shop || nd->u.scr.shop->type != NST_MARKET) return 1; shop = nd->u.scr.shop->item; @@ -1957,37 +1960,37 @@ int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, st new_ = 0; // process entries in buy list, one by one - for( i = 0; i < list_size; ++i ) { - int nameid, amount, value; + for (i = 0; i < VECTOR_LENGTH(*item_list); ++i) { + int value; + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); // find this entry in the shop's sell list ARR_FIND( 0, shop_size, j, - p->list[i].ITID == shop[j].nameid || //Normal items - p->list[i].ITID == itemdb_viewid(shop[j].nameid) //item_avail replacement + entry->id == shop[j].nameid || //Normal items + entry->id == itemdb_viewid(shop[j].nameid) //item_avail replacement ); - - if( j == shop_size ) /* TODO find official response for this */ + if (j == shop_size) /* TODO find official response for this */ return 1; // no such item in shop - if( p->list[i].qty > shop[j].qty ) + entry->id = shop[j].nameid; //item_avail replacement + + if (entry->amount > (int)shop[j].qty) return 1; - amount = p->list[i].qty; - nameid = p->list[i].ITID = shop[j].nameid; //item_avail replacement value = shop[j].value; npc_market_qty[i] = j; - if( !itemdb->exists(nameid) ) /* TODO find official response for this */ + if (!itemdb->exists(entry->id)) /* TODO find official response for this */ return 1; // item no longer in itemdb - if( !itemdb->isstackable(nameid) && amount > 1 ) { + if (!itemdb->isstackable(entry->id) && entry->amount > 1) { //Exploit? You can't buy more than 1 of equipment types o.O ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of non-stackable item %d!\n", - sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); - amount = p->list[i].qty = 1; + sd->status.name, sd->status.account_id, sd->status.char_id, entry->amount, entry->id); + entry->amount = 1; } - switch( pc->checkadditem(sd,nameid,amount) ) { + switch (pc->checkadditem(sd, entry->id, entry->amount)) { case ADDITEM_EXIST: break; case ADDITEM_NEW: @@ -1997,8 +2000,8 @@ int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, st return 1; } - z += (int64)value * amount; - w += itemdb_weight(nameid) * amount; + z += (int64)value * entry->amount; + w += itemdb_weight(entry->id) * entry->amount; } if (z > sd->status.zeny) /* TODO find official response for this */ @@ -2012,28 +2015,27 @@ int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, st pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL); - for( i = 0; i < list_size; ++i ) { - int nameid = p->list[i].ITID; - int amount = p->list[i].qty; + for (i = 0; i < VECTOR_LENGTH(*item_list); ++i) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); j = npc_market_qty[i]; - if( p->list[i].qty > shop[j].qty ) /* wohoo someone tampered with the packet. */ + if (entry->amount > (int)shop[j].qty) /* wohoo someone tampered with the packet. */ return 1; - shop[j].qty -= amount; + shop[j].qty -= entry->amount; npc->market_tosql(nd,j); - if (itemdb_type(nameid) == IT_PETEGG) { - pet->create_egg(sd, nameid); + if (itemdb_type(entry->id) == IT_PETEGG) { + pet->create_egg(sd, entry->id); } else { struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = nameid; + item_tmp.nameid = entry->id; item_tmp.identify = 1; - pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC); + pc->additem(sd, &item_tmp, entry->amount, LOG_TYPE_NPC); } } @@ -2041,7 +2043,7 @@ int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, st } /// npc_selllist for script-controlled shops -int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd) +int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_list, struct npc_data *nd) { char npc_ev[EVENT_NAME_LENGTH]; char card_slot[NAME_LENGTH]; @@ -2068,21 +2070,28 @@ int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_li } // save list of to be sold items - for (i = 0; i < n; i++) { - int idx = item_list[i*2]-2; - - script->setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid); - script->setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount); + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + struct item *item = &sd->status.inventory[entry->id]; + intptr_t nameid = item->nameid; + intptr_t amount = entry->amount; + intptr_t refine = item->refine; + intptr_t attribute = item->attribute; + intptr_t identify = item->identify; + + script->setarray_pc(sd, "@sold_nameid", i, (void*)nameid, &key_nameid); + script->setarray_pc(sd, "@sold_quantity", i, (void*)amount, &key_amount); // process item based information into the arrays - script->setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine); - script->setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute); - script->setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify); + script->setarray_pc(sd, "@sold_refine", i, (void*)refine, &key_refine); + script->setarray_pc(sd, "@sold_attribute", i, (void*)attribute, &key_attribute); + script->setarray_pc(sd, "@sold_identify", i, (void*)identify, &key_identify); for (j = 0; j < MAX_SLOTS; j++) { + intptr_t card = item->card[j]; // store each of the cards/special info from the item in the array snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1); - script->setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->status.inventory[idx].card[j], &key_card[j]); + script->setarray_pc(sd, card_slot, i, (void*)card, &key_card[j]); } } @@ -2097,7 +2106,8 @@ int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_li /// /// @param item_list 'n' pairs <index,amount> /// @return result code for clif->parse_NpcSellListSend -int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) { +int npc_selllist(struct map_session_data *sd, struct itemlist *item_list) +{ int64 z; int i,skill_t, skill_idx = skill->get_index(MC_OVERCHARGE); struct npc_data *nd; @@ -2118,13 +2128,11 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) z = 0; // verify the sell list - for (i = 0; i < n; i++) { - int nameid, amount, idx, value; + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + int nameid, value, idx = entry->id; - idx = item_list[i*2]-2; - amount = item_list[i*2+1]; - - if (idx >= MAX_INVENTORY || idx < 0 || amount < 0) { + if (idx >= MAX_INVENTORY || idx < 0 || entry->amount < 0) { return 1; } @@ -2136,7 +2144,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) nameid = sd->status.inventory[idx].nameid; - if (!nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < amount) { + if (!nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < entry->amount) { return 1; } @@ -2147,27 +2155,25 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) value = pc->modifysellvalue(sd, sd->inventory_data[idx]->value_sell); - z += (int64)value * amount; + z += (int64)value * entry->amount; } if( nd->master_nd ) { // Script-controlled shops - return npc->selllist_sub(sd, n, item_list, nd->master_nd); + return npc->selllist_sub(sd, item_list, nd->master_nd); } // delete items - for( i = 0; i < n; i++ ) { - int amount, idx; - - idx = item_list[i*2]-2; - amount = item_list[i*2+1]; + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + int idx = entry->id; - if( sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET ) { - if( pet->search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0 ) { + if (sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET) { + if (pet->search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0) { intif->delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2])); } } - pc->delitem(sd, idx, amount, 0, DELITEM_SOLD, LOG_TYPE_NPC); + pc->delitem(sd, idx, entry->amount, 0, DELITEM_SOLD, LOG_TYPE_NPC); } if( z > MAX_ZENY ) diff --git a/src/map/npc.h b/src/map/npc.h index be878933e..9867055a3 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -29,7 +29,9 @@ #include <pcre.h> +/* Forward declarations */ struct hplugin_data_store; +struct itemlist; // map/itemdb.h struct view_data; enum npc_parse_options { @@ -230,12 +232,12 @@ struct npc_interface { int (*click) (struct map_session_data *sd, struct npc_data *nd); int (*scriptcont) (struct map_session_data *sd, int id, bool closing); int (*buysellsel) (struct map_session_data *sd, int id, int type); - int (*cashshop_buylist) (struct map_session_data *sd, int points, int count, unsigned short *item_list); - int (*buylist_sub) (struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd); + int (*cashshop_buylist) (struct map_session_data *sd, int points, struct itemlist *item_list); + int (*buylist_sub) (struct map_session_data *sd, struct itemlist *item_list, struct npc_data *nd); int (*cashshop_buy) (struct map_session_data *sd, int nameid, int amount, int points); - int (*buylist) (struct map_session_data *sd, int n, unsigned short *item_list); - int (*selllist_sub) (struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd); - int (*selllist) (struct map_session_data *sd, int n, unsigned short *item_list); + int (*buylist) (struct map_session_data *sd, struct itemlist *item_list); + int (*selllist_sub) (struct map_session_data *sd, struct itemlist *item_list, struct npc_data *nd); + int (*selllist) (struct map_session_data *sd, struct itemlist *item_list); int (*remove_map) (struct npc_data *nd); int (*unload_ev) (DBKey key, DBData *data, va_list ap); int (*unload_ev_label) (DBKey key, DBData *data, va_list ap); @@ -291,7 +293,7 @@ struct npc_interface { void (*trader_count_funds) (struct npc_data *nd, struct map_session_data *sd); bool (*trader_pay) (struct npc_data *nd, struct map_session_data *sd, int price, int points); void (*trader_update) (int master); - int (*market_buylist) (struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p); + int (*market_buylist) (struct map_session_data *sd, struct itemlist *item_list); bool (*trader_open) (struct map_session_data *sd, struct npc_data *nd); void (*market_fromsql) (void); void (*market_tosql) (struct npc_data *nd, unsigned short index); diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index cc8389a6b..f23cefb26 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -1105,7 +1105,7 @@ struct packet_npc_market_purchase { struct { unsigned short ITID; int qty; - } list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */ + } list[]; // Note: We assume this should be <= MAX_INVENTORY (since you can't hold more than MAX_INVENTORY items thus cant buy that many at once). } __attribute__((packed)); struct packet_npc_market_result_ack { diff --git a/src/map/party.c b/src/map/party.c index a3e59c281..39c6e25fb 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -148,7 +148,7 @@ struct party_data* party_searchname(const char* str) return p; } -int party_create(struct map_session_data *sd,char *name,int item,int item2) +int party_create(struct map_session_data *sd, const char *name,int item,int item2) { struct party_member leader; char tname[NAME_LENGTH]; @@ -175,7 +175,8 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2) return 0; } -void party_created(int account_id,int char_id,int fail,int party_id,char *name) { +void party_created(int account_id, int char_id, int fail, int party_id, const char *name) +{ struct map_session_data *sd; sd=map->id2sd(account_id); @@ -241,10 +242,10 @@ void party_check_state(struct party_data *p) { } } -int party_recv_info(struct party* sp, int char_id) +int party_recv_info(const struct party *sp, int char_id) { struct party_data* p; - struct party_member* member; + const struct party_member *member; struct map_session_data* sd; int removed[MAX_PARTY];// member_id in old data int removed_count = 0; @@ -510,7 +511,7 @@ int party_member_added(int party_id,int account_id,int char_id, int flag) { } /// Party member 'sd' requesting kick of member with <account_id, name>. -int party_removemember(struct map_session_data* sd, int account_id, char* name) +int party_removemember(struct map_session_data* sd, int account_id, const char *name) { struct party_data *p; int i; diff --git a/src/map/party.h b/src/map/party.h index 828916b88..b66a9770c 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -97,18 +97,18 @@ struct party_interface { int (*getmemberid) (struct party_data* p, struct map_session_data* sd); struct map_session_data* (*getavailablesd) (struct party_data *p); - int (*create) (struct map_session_data *sd,char *name, int item, int item2); - void (*created) (int account_id,int char_id,int fail,int party_id,char *name); + int (*create) (struct map_session_data *sd, const char *name, int item, int item2); + void (*created) (int account_id, int char_id, int fail, int party_id, const char *name); int (*request_info) (int party_id, int char_id); int (*invite) (struct map_session_data *sd,struct map_session_data *tsd); void (*member_joined) (struct map_session_data *sd); int (*member_added) (int party_id,int account_id,int char_id,int flag); int (*leave) (struct map_session_data *sd); - int (*removemember) (struct map_session_data *sd,int account_id,char *name); + int (*removemember) (struct map_session_data *sd, int account_id, const char *name); int (*member_withdraw) (int party_id,int account_id,int char_id); void (*reply_invite) (struct map_session_data *sd,int party_id,int flag); int (*recv_noinfo) (int party_id, int char_id); - int (*recv_info) (struct party* sp, int char_id); + int (*recv_info) (const struct party *sp, int char_id); int (*recv_movemap) (int party_id,int account_id,int char_id, unsigned short mapid,int online,int lv); int (*broken) (int party_id); int (*optionchanged) (int party_id,int account_id,int exp,int item,int flag); diff --git a/src/map/pc.c b/src/map/pc.c index 0eda9ebe3..a79247134 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1033,7 +1033,8 @@ int pc_isequip(struct map_session_data *sd,int n) * No problem with the session id * set the status that has been sent from char server *------------------------------------------*/ -bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) { +bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, const struct mmo_charstatus *st, bool changing_mapservers) +{ int i; int64 tick = timer->gettick(); uint32 ip = sockt->session[sd->fd]->client_addr; diff --git a/src/map/pc.h b/src/map/pc.h index 06bc5e5ae..246209f87 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -834,7 +834,7 @@ END_ZEROED_BLOCK; /* End */ int (*makesavestatus) (struct map_session_data *sd); void (*respawn) (struct map_session_data* sd, clr_type clrtype); int (*setnewpc) (struct map_session_data *sd, int account_id, int char_id, int login_id1, unsigned int client_tick, int sex, int fd); - bool (*authok) (struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers); + bool (*authok) (struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, const struct mmo_charstatus *st, bool changing_mapservers); void (*authfail) (struct map_session_data *sd); int (*reg_received) (struct map_session_data *sd); diff --git a/src/map/pet.c b/src/map/pet.c index c6f7e8cca..71d8d1eb3 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -646,7 +646,7 @@ int pet_menu(struct map_session_data *sd,int menunum) return 0; } -int pet_change_name(struct map_session_data *sd,char *name) +int pet_change_name(struct map_session_data *sd, const char *name) { int i; struct pet_data *pd; @@ -664,19 +664,23 @@ int pet_change_name(struct map_session_data *sd,char *name) return intif_rename_pet(sd, name); } -int pet_change_name_ack(struct map_session_data *sd, char* name, int flag) +int pet_change_name_ack(struct map_session_data *sd, const char *name, int flag) { struct pet_data *pd = sd->pd; + char *newname = NULL; if (!pd) return 0; - normalize_name(name," ");//bugreport:3032 + newname = aStrndup(name, NAME_LENGTH-1); + normalize_name(newname, " ");//bugreport:3032 // FIXME[Haru]: This should be normalized by the inter-server (so that it's const here) - if ( !flag || !strlen(name) ) { + if (flag == 0 || strlen(newname) == 0) { clif->message(sd->fd, msg_sd(sd,280)); // You cannot use this name for your pet. clif->send_petstatus(sd); //Send status so client knows oet name change got rejected. + aFree(newname); return 0; } - memcpy(pd->pet.name, name, NAME_LENGTH); + memcpy(pd->pet.name, newname, NAME_LENGTH); + aFree(newname); clif->charnameack (0,&pd->bl); pd->pet.rename_flag = 1; clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom); diff --git a/src/map/pet.h b/src/map/pet.h index 83e39a887..79cbeddae 100644 --- a/src/map/pet.h +++ b/src/map/pet.h @@ -154,8 +154,8 @@ struct pet_interface { int (*food) (struct map_session_data *sd, struct pet_data *pd); int (*ai_sub_hard_lootsearch) (struct block_list *bl, va_list ap); int (*menu) (struct map_session_data *sd, int menunum); - int (*change_name) (struct map_session_data *sd, char *name); - int (*change_name_ack) (struct map_session_data *sd, char *name, int flag); + int (*change_name) (struct map_session_data *sd, const char *name); + int (*change_name_ack) (struct map_session_data *sd, const char *name, int flag); int (*equipitem) (struct map_session_data *sd, int index); int (*randomwalk) (struct pet_data *pd, int64 tick); int (*ai_sub_hard) (struct pet_data *pd, struct map_session_data *sd, int64 tick); diff --git a/src/map/script.c b/src/map/script.c index 289ea36e2..9388e8f5f 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -5003,7 +5003,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) { RECREATE(st->buf, char, st->len + inner_len); WBUFB(st->buf, st->len) = lang_id; - safestrncpy((char*)WBUFP(st->buf, st->len + 1), msgstr.ptr, msgstr_len + 1); + safestrncpy(WBUFP(st->buf, st->len + 1), msgstr.ptr, msgstr_len + 1); st->translations++; st->len += inner_len; diff --git a/src/map/skill.c b/src/map/skill.c index a13e3a071..68cb3ff0e 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -17879,27 +17879,31 @@ int skill_select_menu(struct map_session_data *sd,uint16 skill_id) { sc_start4(&sd->bl,&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl)); return 0; } -int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, unsigned short* item_list) { + +int skill_elementalanalysis(struct map_session_data *sd, uint16 skill_lv, const struct itemlist *item_list) +{ int i; nullpo_ret(sd); nullpo_ret(item_list); - if( n <= 0 ) + if (VECTOR_LENGTH(*item_list) <= 0) return 1; - for (i = 0; i < n; i++) { - int nameid, add_amount, del_amount, idx, product; + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { struct item tmp_item; - - idx = item_list[i*2+0]-2; - del_amount = item_list[i*2+1]; + const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + int nameid, add_amount, product; + int del_amount = entry->amount; + int idx = entry->id; if( skill_lv == 2 ) del_amount -= (del_amount % 10); add_amount = (skill_lv == 1) ? del_amount * (5 + rnd()%5) : del_amount / 10 ; - if( (nameid = sd->status.inventory[idx].nameid) <= 0 || del_amount > sd->status.inventory[idx].amount ) { + if (idx < 0 || idx >= MAX_INVENTORY + || (nameid = sd->status.inventory[idx].nameid) <= 0 + || del_amount < 0 || del_amount > sd->status.inventory[idx].amount) { clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0); return 1; } @@ -17949,7 +17953,8 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, return 0; } -int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list) { +int skill_changematerial(struct map_session_data *sd, const struct itemlist *item_list) +{ int i, j, k, c, p = 0, nameid, amount; nullpo_ret(sd); @@ -17964,11 +17969,13 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite // Verification of overlap between the objects required and the list submitted. for( j = 0; j < MAX_PRODUCE_RESOURCE; j++ ) { if( skill->dbs->produce_db[i].mat_id[j] > 0 ) { - for( k = 0; k < n; k++ ) { - int idx = item_list[k*2+0]-2; + for (k = 0; k < VECTOR_LENGTH(*item_list); k++) { + const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, k); + int idx = entry->id; + Assert_ret(idx >= 0 && idx < MAX_INVENTORY); + amount = entry->amount; nameid = sd->status.inventory[idx].nameid; - amount = item_list[k*2+1]; - if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){ + if (nameid > 0 && sd->status.inventory[idx].identify == 0) { clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NEED_IDENTIFY); return 0; } @@ -17981,7 +17988,7 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite break; // No more items required } p++; - } while(n == j && c == n); + } while (c == j && VECTOR_LENGTH(*item_list) == c); p--; if ( p > 0 ) { skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->dbs->produce_db[i].nameid,0,0,0,p); diff --git a/src/map/skill.h b/src/map/skill.h index 96bef090a..fb2acfb62 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -32,6 +32,7 @@ **/ struct Damage; struct homun_data; +struct itemlist; // map/itemdb.h struct map_session_data; struct mercenary_data; struct unit_data; @@ -2060,8 +2061,8 @@ struct skill_interface { int (*magicdecoy) (struct map_session_data *sd, int nameid); int (*poisoningweapon) ( struct map_session_data *sd, int nameid); int (*select_menu) (struct map_session_data *sd,uint16 skill_id); - int (*elementalanalysis) (struct map_session_data *sd, int n, uint16 skill_lv, unsigned short *item_list); - int (*changematerial) (struct map_session_data *sd, int n, unsigned short *item_list); + int (*elementalanalysis) (struct map_session_data *sd, uint16 skill_lv, const struct itemlist *item_list); + int (*changematerial) (struct map_session_data *sd, const struct itemlist *item_list); int (*get_elemental_type) (uint16 skill_id, uint16 skill_lv); void (*cooldown_save) (struct map_session_data * sd); int (*get_new_group_id) (void); |