summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c2649
1 files changed, 1537 insertions, 1112 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 3b2f255ef..524378439 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2015 Hercules Dev Team
+ * Copyright (C) 2012-2016 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -190,7 +190,7 @@ static inline void RFIFOPOS2(int fd, unsigned short pos, short* x0, short* y0, s
#endif // 0
//To identify disguised characters.
-static inline bool disguised(struct block_list* bl)
+bool clif_isdisguised(struct block_list* bl)
{
struct map_session_data *sd = BL_CAST(BL_PC, bl);
if (sd == NULL || sd->disguise == -1)
@@ -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
*------------------------------------------*/
@@ -281,24 +265,50 @@ uint32 clif_refresh_ip(void)
return 0;
}
+unsigned char clif_bl_type(struct block_list *bl)
+{
#if PACKETVER >= 20071106
-static inline unsigned char clif_bl_type(struct block_list *bl) {
- nullpo_retr(0x1, bl);
+ struct view_data *vd;
+ nullpo_retr(CLUT_NPC, bl);
+
switch (bl->type) {
- case BL_PC: return (disguised(bl) && !pc->db_checkid(status->get_viewdata(bl)->class_))? 0x1:0x0; //PC_TYPE
- case BL_ITEM: return 0x2; //ITEM_TYPE
- case BL_SKILL: return 0x3; //SKILL_TYPE
- case BL_CHAT: return 0x4; //UNKNOWN_TYPE
- case BL_MOB: return pc->db_checkid(status->get_viewdata(bl)->class_)?0x0:0x5; //NPC_MOB_TYPE
- case BL_NPC: return pc->db_checkid(status->get_viewdata(bl)->class_)?0x0:0x6; //NPC_EVT_TYPE
- case BL_PET: return pc->db_checkid(status->get_viewdata(bl)->class_)?0x0:0x7; //NPC_PET_TYPE
- case BL_HOM: return 0x8; //NPC_HOM_TYPE
- case BL_MER: return 0x9; //NPC_MERSOL_TYPE
- case BL_ELEM: return 0xa; //NPC_ELEMENTAL_TYPE
- default: return 0x1; //NPC_TYPE
+ case BL_PC:
+ vd = status->get_viewdata(bl);
+ nullpo_retr(CLUT_NPC, vd);
+
+ if (clif->isdisguised(bl) && !pc->db_checkid(vd->class))
+ return CLUT_NPC;
+ return CLUT_PC;
+ case BL_ITEM:
+ return CLUT_ITEM;
+ case BL_SKILL:
+ return CLUT_SKILL;
+ case BL_CHAT:
+ return CLUT_UNKNOWN;
+ case BL_MOB:
+ vd = status->get_viewdata(bl);
+ nullpo_retr(CLUT_NPC, vd);
+ return pc->db_checkid(vd->class) ? CLUT_PC : CLUT_MOB;
+ case BL_NPC:
+ vd = status->get_viewdata(bl);
+ nullpo_retr(CLUT_NPC, vd);
+ return pc->db_checkid(vd->class) ? CLUT_PC : CLUT_EVENT;
+ case BL_PET:
+ vd = status->get_viewdata(bl);
+ nullpo_retr(CLUT_NPC, vd);
+ return pc->db_checkid(vd->class) ? CLUT_PC : CLUT_PET;
+ case BL_HOM:
+ return CLUT_HOMNUCLUS;
+ case BL_MER:
+ return CLUT_MERCNARY;
+ case BL_ELEM:
+ return CLUT_ELEMENTAL;
+ default:
+ return CLUT_NPC;
}
-}
#endif
+ return CLUT_UNKNOWN;
+}
/*==========================================
* sub process of clif_send
@@ -335,17 +345,17 @@ int clif_send_sub(struct block_list *bl, va_list ap) {
return 0;
break;
case AREA_WOC:
- if (sd->chatID || bl == src_bl)
+ if (sd->chat_id != 0 || bl == src_bl)
return 0;
break;
case AREA_WOSC: {
if (src_bl->type == BL_PC) {
const struct map_session_data *ssd = BL_UCCAST(BL_PC, src_bl);
- if (ssd != NULL && sd->chatID != 0 && (sd->chatID == ssd->chatID))
+ if (ssd != NULL && sd->chat_id != 0 && (sd->chat_id == ssd->chat_id))
return 0;
} else if (src_bl->type == BL_NPC) {
const struct npc_data *nd = BL_UCCAST(BL_NPC, src_bl);
- if (nd != NULL && sd->chatID != 0 && (sd->chatID == nd->chat_id))
+ if (nd != NULL && sd->chat_id != 0 && (sd->chat_id == nd->chat_id))
return 0;
}
}
@@ -441,8 +451,8 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target
break;
case AREA_CHAT_WOC:
nullpo_retr(true, bl);
- map->foreachinarea(clif->send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5),
- bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC);
+ map->foreachinarea(clif->send_sub, bl->m, bl->x-CHAT_AREA_SIZE, bl->y-CHAT_AREA_SIZE,
+ bl->x+CHAT_AREA_SIZE, bl->y+CHAT_AREA_SIZE, BL_PC, buf, len, bl, AREA_WOC);
break;
case CHAT:
@@ -451,7 +461,7 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target
{
const struct chat_data *cd = NULL;
if (sd != NULL) {
- cd = map->id2cd(sd->chatID);
+ cd = map->id2cd(sd->chat_id);
} else {
cd = BL_CCAST(BL_CHAT, bl);
}
@@ -645,7 +655,7 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target
break;
default:
- ShowError("clif_send: Unrecognized type %d\n",type);
+ ShowError("clif_send: Unrecognized type %u\n", type);
return false;
}
@@ -667,7 +677,8 @@ void clif_authok(struct map_session_data *sd)
#if PACKETVER >= 20080102
p.font = sd->status.font;
#endif
-#if PACKETVER >= 20141016
+// Some clients smaller than 20160330 cant be tested [4144]
+#if PACKETVER >= 20141016 && PACKETVER < 20160330
p.sex = sd->status.sex;
#endif
clif->send(&p,sizeof(p),&sd->bl,SELF);
@@ -839,7 +850,7 @@ void clif_clearunit_area(struct block_list* bl, clr_type type)
clif->send(buf, packet_len(0x80), bl, type == CLR_DEAD ? AREA : AREA_WOS);
- if(disguised(bl)) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2) = -bl->id;
clif->send(buf, packet_len(0x80), bl, SELF);
}
@@ -944,21 +955,22 @@ void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, en
p.PacketType = idle_unit2Type;
#if PACKETVER >= 20071106
- p.objecttype = clif_bl_type(bl);
+ p.objecttype = clif->bl_type(bl);
#endif
p.GID = bl->id;
p.speed = status->get_speed(bl);
p.bodyState = (sc) ? sc->opt1 : 0;
p.healthState = (sc) ? sc->opt2 : 0;
p.effectState = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
- p.job = vd->class_;
+ p.job = vd->class;
p.head = vd->hair_style;
p.weapon = vd->weapon;
p.accessory = vd->head_bottom;
p.shield = vd->shield;
p.accessory2 = vd->head_top;
p.accessory3 = vd->head_mid;
- if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this?
+ if (bl->type == BL_NPC && vd->class == FLAG_CLASS) {
+ // The hell, why flags work like this?
p.shield = status->get_emblem_id(bl);
p.accessory2 = GetWord(g_id, 1);
p.accessory3 = GetWord(g_id, 0);
@@ -995,7 +1007,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
nullpo_retv(bl);
#if PACKETVER < 20091103
- if( !pc->db_checkid(vd->class_) ) {
+ if (!pc->db_checkid(vd->class)) {
clif->set_unit_idle2(bl,tsd,target);
return;
}
@@ -1006,7 +1018,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
p.PacketType = idle_unitType;
#if PACKETVER >= 20091103
p.PacketLength = sizeof(p);
- p.objecttype = clif_bl_type(bl);
+ p.objecttype = clif->bl_type(bl);
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
@@ -1018,7 +1030,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
p.bodyState = (sc) ? sc->opt1 : 0;
p.healthState = (sc) ? sc->opt2 : 0;
p.effectState = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
- p.job = vd->class_;
+ p.job = vd->class;
p.head = vd->hair_style;
p.weapon = vd->weapon;
p.accessory = vd->head_bottom;
@@ -1027,7 +1039,8 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
#endif
p.accessory2 = vd->head_top;
p.accessory3 = vd->head_mid;
- if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this?
+ if (bl->type == BL_NPC && vd->class == FLAG_CLASS) {
+ // The hell, why flags work like this?
p.accessory = status->get_emblem_id(bl);
p.accessory2 = GetWord(g_id, 1);
p.accessory3 = GetWord(g_id, 0);
@@ -1066,13 +1079,20 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
#if PACKETVER >= 20150513
p.body = vd->body_style;
#endif
-
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
+ safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH);
+#endif
clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target);
- if( disguised(bl) ) {
+ if (clif->isdisguised(bl)) {
#if PACKETVER >= 20091103
- p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+ p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+#if PACKETVER >= 20131223
+ p.AID = -bl->id;
+#else
p.GID = -bl->id;
+#endif
#else
p.GID = -bl->id;
#endif
@@ -1094,7 +1114,7 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) {
p.PacketType = spawn_unit2Type;
#if PACKETVER >= 20071106
- p.objecttype = clif_bl_type(bl);
+ p.objecttype = clif->bl_type(bl);
#endif
p.GID = bl->id;
p.speed = status->get_speed(bl);
@@ -1104,11 +1124,12 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) {
p.head = vd->hair_style;
p.weapon = vd->weapon;
p.accessory = vd->head_bottom;
- p.job = vd->class_;
+ p.job = vd->class;
p.shield = vd->shield;
p.accessory2 = vd->head_top;
p.accessory3 = vd->head_mid;
- if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this?
+ if (bl->type == BL_NPC && vd->class == FLAG_CLASS) {
+ // The hell, why flags work like this?
p.shield = status->get_emblem_id(bl);
p.accessory2 = GetWord(g_id, 1);
p.accessory3 = GetWord(g_id, 0);
@@ -1136,7 +1157,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
nullpo_retv(bl);
#if PACKETVER < 20091103
- if( !pc->db_checkid(vd->class_) ) {
+ if (!pc->db_checkid(vd->class)) {
clif->spawn_unit2(bl,target);
return;
}
@@ -1147,7 +1168,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
p.PacketType = spawn_unitType;
#if PACKETVER >= 20091103
p.PacketLength = sizeof(p);
- p.objecttype = clif_bl_type(bl);
+ p.objecttype = clif->bl_type(bl);
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
@@ -1159,7 +1180,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
p.bodyState = (sc) ? sc->opt1 : 0;
p.healthState = (sc) ? sc->opt2 : 0;
p.effectState = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
- p.job = vd->class_;
+ p.job = vd->class;
p.head = vd->hair_style;
p.weapon = vd->weapon;
p.accessory = vd->head_bottom;
@@ -1168,7 +1189,8 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
#endif
p.accessory2 = vd->head_top;
p.accessory3 = vd->head_mid;
- if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this?
+ if (bl->type == BL_NPC && vd->class == FLAG_CLASS) {
+ // The hell, why flags work like this?
p.accessory = status->get_emblem_id(bl);
p.accessory2 = GetWord(g_id, 1);
p.accessory3 = GetWord(g_id, 0);
@@ -1206,13 +1228,21 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
#if PACKETVER >= 20150513
p.body = vd->body_style;
#endif
- if( disguised(bl) ) {
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
+ safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH);
+#endif
+ if (clif->isdisguised(bl)) {
nullpo_retv(sd);
- if( sd->status.class_ != sd->disguise )
+ if (sd->status.class != sd->disguise)
clif->send(&p,sizeof(p),bl,target);
#if PACKETVER >= 20091103
- p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+ p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+#if PACKETVER >= 20131223
+ p.AID = -bl->id;
+#else
p.GID = -bl->id;
+#endif
#else
p.GID = -bl->id;
#endif
@@ -1242,11 +1272,11 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
p.PacketLength = sizeof(p);
#endif
#if PACKETVER >= 20071106
- p.objecttype = clif_bl_type(bl);
+ p.objecttype = clif->bl_type(bl);
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
- p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE
+ p.GID = (sd) ? sd->status.char_id : 0; // CCODE
#else
p.GID = bl->id;
#endif
@@ -1254,7 +1284,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
p.bodyState = (sc) ? sc->opt1 : 0;
p.healthState = (sc) ? sc->opt2 : 0;
p.effectState = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
- p.job = vd->class_;
+ p.job = vd->class;
p.head = vd->hair_style;
p.weapon = vd->weapon;
p.accessory = vd->head_bottom;
@@ -1297,13 +1327,21 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
#if PACKETVER >= 20150513
p.body = vd->body_style;
#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
+ safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH);
+#endif
clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target);
- if( disguised(bl) ) {
+ if (clif->isdisguised(bl)) {
#if PACKETVER >= 20091103
- p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class_) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+ p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+#if PACKETVER >= 20131223
+ p.AID = -bl->id;
+#else
p.GID = -bl->id;
+#endif
#else
p.GID = -bl->id;
#endif
@@ -1315,7 +1353,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
/// 01b0 <id>.L <type>.B <value>.L
/// type:
/// unused
-void clif_class_change(struct block_list *bl, int class_, int type)
+void clif_class_change(struct block_list *bl, int class_, int type, struct map_session_data *sd)
{
nullpo_retv(bl);
@@ -1326,7 +1364,11 @@ void clif_class_change(struct block_list *bl, int class_, int type)
WBUFL(buf,2)=bl->id;
WBUFB(buf,6)=type;
WBUFL(buf,7)=class_;
- clif->send(buf,packet_len(0x1b0),bl,AREA);
+
+ if (sd == NULL)
+ clif->send(buf, packet_len(0x1b0), bl, AREA);
+ else
+ clif->send(buf, packet_len(0x1b0), &sd->bl, SELF);
}
}
@@ -1347,6 +1389,7 @@ void clif_spiritball_single(int fd, struct map_session_data *sd) {
*------------------------------------------*/
void clif_charm_single(int fd, struct map_session_data *sd)
{
+#if PACKETVER >= 20110809
nullpo_retv(sd);
WFIFOHEAD(fd, packet_len(0x08cf));
WFIFOW(fd,0) = 0x08cf;
@@ -1354,6 +1397,7 @@ void clif_charm_single(int fd, struct map_session_data *sd)
WFIFOW(fd,6) = sd->charm_type;
WFIFOW(fd,8) = sd->charm_count;
WFIFOSET(fd, packet_len(0x08cf));
+#endif
}
/*==========================================
@@ -1412,7 +1456,7 @@ bool clif_spawn(struct block_list *bl)
if( !vd )
return false;
- if (vd->class_ == INVISIBLE_CLASS)
+ if (vd->class == INVISIBLE_CLASS)
return true; // Doesn't need to be spawned, so everything is alright
if (bl->type == BL_NPC) {
@@ -1442,7 +1486,7 @@ bool clif_spawn(struct block_list *bl)
if (sd->bg_id != 0 && map->list[sd->bl.m].flag.battleground)
clif->sendbgemblem_area(sd);
for (i = 0; i < sd->sc_display_count; i++) {
- clif->sc_load(&sd->bl, sd->bl.id,AREA,status->dbs->IconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
+ clif->sc_continue(&sd->bl, sd->bl.id,AREA,status->dbs->IconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
}
if (sd->charm_type != CHARM_TYPE_NONE && sd->charm_count > 0)
clif->spiritcharm(sd);
@@ -1482,6 +1526,15 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
struct status_data *hstatus;
unsigned char buf[128];
enum homun_type htype;
+ int offset = 0;
+
+// probably can works also for < 20141223, but in 3CeaM packet size defined only for 20150513
+#if PACKETVER < 20150513
+ int cmd = 0x22e;
+#else
+ int cmd = 0x9f7;
+#endif
+ int len = packet_len(cmd);
nullpo_retv(sd);
nullpo_retv(hd);
@@ -1489,65 +1542,75 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
hstatus = &hd->battle_status;
htype = homun->class2type(hd->homunculus.class_);
- memset(buf,0,packet_len(0x22e));
- WBUFW(buf,0)=0x22e;
- memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH);
+ memset(buf, 0, len);
+ WBUFW(buf, 0) = cmd;
+ memcpy(WBUFP(buf, 2), hd->homunculus.name, NAME_LENGTH);
// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
- WBUFB(buf,26)=(battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0);
- WBUFW(buf,27)=hd->homunculus.level;
- WBUFW(buf,29)=hd->homunculus.hunger;
- WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ;
- WBUFW(buf,33)=0; // equip id
+ WBUFB(buf, 26) = (!battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0);
+ WBUFW(buf, 27) = hd->homunculus.level;
+ WBUFW(buf, 29) = hd->homunculus.hunger;
+ WBUFW(buf, 31) = (unsigned short) (hd->homunculus.intimacy / 100) ;
+ WBUFW(buf, 33) = 0; // equip id
#ifdef RENEWAL
WBUFW(buf, 35) = cap_value(hstatus->rhw.atk2, 0, INT16_MAX);
#else
- WBUFW(buf,35)=cap_value(hstatus->rhw.atk2+hstatus->batk, 0, INT16_MAX);
+ WBUFW(buf,35) = cap_value(hstatus->rhw.atk2 + hstatus->batk, 0, INT16_MAX);
#endif
- WBUFW(buf,37)=cap_value(hstatus->matk_max, 0, INT16_MAX);
- WBUFW(buf,39)=hstatus->hit;
+ WBUFW(buf,37) = cap_value(hstatus->matk_max, 0, INT16_MAX);
+ WBUFW(buf,39) = hstatus->hit;
if (battle_config.hom_setting&0x10)
- WBUFW(buf,41)=hstatus->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious]
+ WBUFW(buf, 41) = hstatus->luk / 3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious]
else
- WBUFW(buf,41)=hstatus->cri/10;
+ WBUFW(buf, 41) = hstatus->cri / 10;
#ifdef RENEWAL
WBUFW(buf, 43) = hstatus->def + hstatus->def2;
WBUFW(buf, 45) = hstatus->mdef + hstatus->mdef2;
#else
- WBUFW(buf,43)=hstatus->def + hstatus->vit ;
+ WBUFW(buf, 43) =hstatus->def + hstatus->vit ;
WBUFW(buf, 45) = hstatus->mdef;
#endif
- WBUFW(buf,47)=hstatus->flee;
- WBUFW(buf,49)=(flag)?0:hstatus->amotion;
+ WBUFW(buf, 47) = hstatus->flee;
+ WBUFW(buf, 49) = (flag) ? 0 : hstatus->amotion;
+
+// probably can works also for < 20141223, but in 3CeaM packet size defined only for 20150513
+#if PACKETVER < 20150513
if (hstatus->max_hp > INT16_MAX) {
- WBUFW(buf,51) = hstatus->hp/(hstatus->max_hp/100);
- WBUFW(buf,53) = 100;
+ WBUFW(buf, 51) = hstatus->hp / (hstatus->max_hp / 100);
+ WBUFW(buf, 53) = 100;
} else {
- WBUFW(buf,51)=hstatus->hp;
- WBUFW(buf,53)=hstatus->max_hp;
+ WBUFW(buf, 51) = hstatus->hp;
+ WBUFW(buf, 53) = hstatus->max_hp;
}
+#else
+ WBUFL(buf, 51) = hstatus->hp;
+ WBUFL(buf, 55) = hstatus->max_hp;
+ offset = 4;
+#endif
+
if (hstatus->max_sp > INT16_MAX) {
- WBUFW(buf,55) = hstatus->sp/(hstatus->max_sp/100);
- WBUFW(buf,57) = 100;
+ WBUFW(buf, 55 + offset) = hstatus->sp / (hstatus->max_sp / 100);
+ WBUFW(buf, 57 + offset) = 100;
} else {
- WBUFW(buf,55)=hstatus->sp;
- WBUFW(buf,57)=hstatus->max_sp;
+ WBUFW(buf, 55 + offset) = hstatus->sp;
+ WBUFW(buf, 57 + offset) = hstatus->max_sp;
}
- WBUFL(buf,59)=hd->homunculus.exp;
- WBUFL(buf,63)=hd->exp_next;
- switch( htype ) {
+ WBUFL(buf, 59 + offset) = hd->homunculus.exp;
+ WBUFL(buf, 63 + offset) = hd->exp_next;
+ switch (htype) {
case HT_REG:
case HT_EVO:
- if( hd->homunculus.level >= battle_config.hom_max_level )
- WBUFL(buf,63)=0;
+ if (hd->homunculus.level >= battle_config.hom_max_level)
+ WBUFL(buf, 63 + offset) = 0;
break;
case HT_S:
- if( hd->homunculus.level >= battle_config.hom_S_max_level )
- WBUFL(buf,63)=0;
+ if (hd->homunculus.level >= battle_config.hom_S_max_level)
+ WBUFL(buf, 63 + offset) = 0;
break;
}
- WBUFW(buf,67)=hd->homunculus.skillpts;
- WBUFW(buf,69)=status_get_range(&hd->bl);
- clif->send(buf,packet_len(0x22e),&sd->bl,SELF);
+ WBUFW(buf, 67 + offset) = hd->homunculus.skillpts;
+ WBUFW(buf, 69 + offset) = status_get_range(&hd->bl);
+
+ clif->send(buf, len, &sd->bl, SELF);
}
/// Notification about a change in homunuculus' state (ZC_CHANGESTATE_MER).
@@ -1612,7 +1675,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;
}
@@ -1740,7 +1803,7 @@ void clif_move(struct unit_data *ud)
bl = ud->bl;
nullpo_retv(bl);
vd = status->get_viewdata(bl);
- if (!vd || vd->class_ == INVISIBLE_CLASS)
+ if (vd == NULL || vd->class == INVISIBLE_CLASS)
return; //This performance check is needed to keep GM-hidden objects from being notified to bots.
if (bl->type == BL_NPC) {
@@ -1769,7 +1832,7 @@ void clif_move(struct unit_data *ud)
clif->send(buf, packet_len(0x86), bl, AREA_WOS);
- if (disguised(bl)) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2)=-bl->id;
clif->send(buf, packet_len(0x86), bl, SELF);
}
@@ -1816,7 +1879,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 +1894,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);
@@ -1862,7 +1925,7 @@ void clif_fixpos(struct block_list *bl) {
WBUFW(buf,8) = bl->y;
clif->send(buf, packet_len(0x88), bl, AREA);
- if( disguised(bl) ) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2) = -bl->id;
clif->send(buf, packet_len(0x88), bl, SELF);
}
@@ -1970,21 +2033,38 @@ void clif_selllist(struct map_session_data *sd)
/// - set npcid of dialog window (0 by default)
/// - if set to clear on next mes, clear contents
/// - append this text
-void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes) {
- int fd = sd->fd;
- size_t slen;
+void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes)
+{
+ int fd, slen;
+#ifdef SCRIPT_MES_STRIP_LINEBREAK
+ char *stripmes = NULL;
+ int i;
+#endif
nullpo_retv(sd);
nullpo_retv(mes);
- slen = strlen(mes) + 9;
+
+ fd = sd->fd;
+ slen = (int)strlen(mes) + 9;
+ Assert_retv(slen <= INT16_MAX);
sd->state.dialog = 1;
WFIFOHEAD(fd, slen);
- WFIFOW(fd,0)=0xb4;
- WFIFOW(fd,2)=slen;
- WFIFOL(fd,4)=npcid;
- memcpy((char*)WFIFOP(fd,8), mes, slen-8);
+ WFIFOW(fd,0) = 0xb4;
+ WFIFOW(fd,2) = slen;
+ WFIFOL(fd,4) = npcid;
+#ifdef SCRIPT_MES_STRIP_LINEBREAK
+ stripmes = aStrdup(mes);
+ for (i = 0; stripmes[i] != '\0'; ++i) {
+ if (stripmes[i] == '\r')
+ stripmes[i] = ' ';
+ }
+ memcpy(WFIFOP(fd,8), stripmes, slen-8);
+ aFree(stripmes);
+#else // ! SCRIPT_MES_STRIP_LINEBREAK
+ memcpy(WFIFOP(fd,8), mes, slen-8);
+#endif // SCRIPT_MES_STRIP_LINEBREAK
WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -2085,25 +2165,28 @@ void clif_sendfakenpc(struct map_session_data *sd, int npcid) {
/// WARNING: the 'cancel' button closes other windows besides the dialog window and the menu window.
/// Which suggests their have intertwined behavior. (probably the mouse targeting)
/// TODO investigate behavior of other windows [FlavioJS]
-void clif_scriptmenu(struct map_session_data* sd, int npcid, const char* mes) {
- int fd;
- size_t slen;
+void clif_scriptmenu(struct map_session_data *sd, int npcid, const char *mes)
+{
+ int fd, slen;
struct block_list *bl = NULL;
nullpo_retv(sd);
nullpo_retv(mes);
+
fd = sd->fd;
- slen = strlen(mes) + 9;
+ slen = (int)strlen(mes) + 9;
+ Assert_retv(slen <= INT16_MAX);
+
if (!sd->state.using_fake_npc && (npcid == npc->fake_nd->bl.id || ((bl = map->id2bl(npcid)) != NULL && (bl->m!=sd->bl.m ||
bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
clif->sendfakenpc(sd, npcid);
WFIFOHEAD(fd, slen);
- WFIFOW(fd,0)=0xb7;
- WFIFOW(fd,2)=slen;
- WFIFOL(fd,4)=npcid;
- memcpy((char*)WFIFOP(fd,8), mes, slen-8);
+ WFIFOW(fd,0) = 0xb7;
+ WFIFOW(fd,2) = slen;
+ WFIFOL(fd,4) = npcid;
+ memcpy(WFIFOP(fd,8), mes, slen-8);
WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -2211,7 +2294,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));
}
@@ -2320,23 +2403,37 @@ void clif_addcards2(unsigned short *cards, struct item* item) {
}
/**
- * Fills in RandomOptions(Bonuses) of items into the buffer
+ * Fills in ItemOptions(Bonuses) of items into the buffer
*
- * Dummy datais used since this feature isn't supported yet (ITEM_RDM_OPT).
- * A maximum of 5 random options can be supported.
+ * A maximum of 5 item options can be supported.
*
* @param buf[in,out] The buffer to write to. The pointer must be valid and initialized.
* @param item[in] The source item.
*/
-void clif_add_random_options(unsigned char* buf, struct item* item)
+ int clif_add_item_options(struct ItemOptions *buf, const struct item *it)
{
- int i;
- nullpo_retv(buf);
- for (i = 0; i < 5; i++){
- WBUFW(buf,i*5+0) = 0; // OptIndex
- WBUFW(buf,i*5+2) = 0; // Value
- WBUFB(buf,i*5+4) = 0; // Param1
+ int i = 0, j = 0, total_options = 0;
+
+ nullpo_ret(buf);
+
+ // Append the buffer with existing options first.
+ for (i = 0; i < MAX_ITEM_OPTIONS; i++) {
+ if (it->option[i].index) {
+ WBUFW(buf, j * 5 + 0) = it->option[i].index; // OptIndex
+ WBUFW(buf, j * 5 + 2) = it->option[i].value; // Value
+ WBUFB(buf, j * 5 + 4) = it->option[i].param; // Param1
+ total_options++;
+ j++;
+ }
}
+ // Append the remaining buffer with no values;
+ for (; j < MAX_ITEM_OPTIONS || j < 5; j++) {
+ WBUFW(buf, j * 5 + 0) = 0;
+ WBUFW(buf, j * 5 + 2) = 0;
+ WBUFB(buf, j * 5 + 4) = 0;
+ }
+
+ return total_options;
}
/// Notifies the client, about a received inventory item or the result of a pick-up request.
@@ -2360,9 +2457,6 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
p.count = amount;
if( !fail ) {
-#if PACKETVER >= 20150226
- int i;
-#endif
if( n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL )
return;
@@ -2372,7 +2466,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
p.nameid = sd->status.inventory[n].nameid;
p.IsIdentified = sd->status.inventory[n].identify ? 1 : 0;
- p.IsDamaged = sd->status.inventory[n].attribute ? 1 : 0;
+ p.IsDamaged = (sd->status.inventory[n].attribute & ATTR_BROKEN) != 0 ? 1 : 0;
p.refiningLevel =sd->status.inventory[n].refine;
clif->addcards2(&p.slot.card[0], &sd->status.inventory[n]);
p.location = pc->equippoint(sd,n);
@@ -2387,11 +2481,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
p.bindOnEquipType = sd->status.inventory[n].bound && !itemdb->isstackable2(sd->inventory_data[n]) ? 2 : sd->inventory_data[n]->flag.bindonequip ? 1 : 0;
#endif
#if PACKETVER >= 20150226
- for (i=0; i<5; i++){
- p.option_data[i].index = 0;
- p.option_data[i].value = 0;
- p.option_data[i].param = 0;
- }
+ clif->add_item_options(&p.option_data[0], &sd->status.inventory[n]);
#endif
}
p.result = (unsigned char)fail;
@@ -2464,41 +2554,39 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
}
-void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct item_data *id, int eqp_pos) {
-#if PACKETVER >= 20150226
- int j;
-#endif
+void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *it, struct item_data *id, int eqp_pos)
+{
nullpo_retv(p);
- nullpo_retv(i);
+ nullpo_retv(it);
nullpo_retv(id);
p->index = idx;
if (id->view_id > 0)
p->ITID = id->view_id;
else
- p->ITID = i->nameid;
+ p->ITID = it->nameid;
p->type = itemtype(id->type);
#if PACKETVER < 20120925
- p->IsIdentified = i->identify ? 1 : 0;
+ p->IsIdentified = it->identify ? 1 : 0;
#endif
p->location = eqp_pos;
- p->WearState = i->equip;
+ p->WearState = it->equip;
#if PACKETVER < 20120925
- p->IsDamaged = i->attribute ? 1 : 0;
+ p->IsDamaged = (it->attribute & ATTR_BROKEN) != 0 ? 1 : 0;
#endif
- p->RefiningLevel = i->refine;
+ p->RefiningLevel = it->refine;
- clif->addcards2(&p->slot.card[0], i);
+ clif->addcards2(&p->slot.card[0], it);
#if PACKETVER >= 20071002
- p->HireExpireDate = i->expire_time;
+ p->HireExpireDate = it->expire_time;
#endif
#if PACKETVER >= 20080102
- p->bindOnEquipType = i->bound ? 2 : id->flag.bindonequip ? 1 : 0;
+ p->bindOnEquipType = it->bound ? 2 : id->flag.bindonequip ? 1 : 0;
#endif
#if PACKETVER >= 20100629
@@ -2506,19 +2594,14 @@ void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct
#endif
#if PACKETVER >= 20120925
- p->Flag.IsIdentified = i->identify ? 1 : 0;
- p->Flag.IsDamaged = i->attribute ? 1 : 0;
- p->Flag.PlaceETCTab = i->favorite ? 1 : 0;
+ p->Flag.IsIdentified = it->identify ? 1 : 0;
+ p->Flag.IsDamaged = (it->attribute & ATTR_BROKEN) != 0 ? 1 : 0;
+ p->Flag.PlaceETCTab = it->favorite ? 1 : 0;
p->Flag.SpareBits = 0;
#endif
#if PACKETVER >= 20150226
- p->option_count = 0;
- for (j=0; j<5; j++){
- p->option_data[j].index = 0;
- p->option_data[j].value = 0;
- p->option_data[j].param = 0;
- }
+ p->option_count = clif->add_item_options(p->option_data, it);
#endif
}
@@ -3111,31 +3194,31 @@ void clif_changelook(struct block_list *bl,int type,int val)
vd->shield = val;
break;
case LOOK_BASE:
- if( !sd ) break;
+ if (sd == NULL)
+ break;
- if ( val == INVISIBLE_CLASS ) /* nothing to change look */
+ if (val == INVISIBLE_CLASS) /* nothing to change look */
return;
- if( sd->sc.option&OPTION_COSTUME )
+ if (sd->sc.option & OPTION_COSTUME)
vd->weapon = vd->shield = 0;
- if( !vd->cloth_color )
+ if (!vd->cloth_color)
break;
- if (sd->sc.option&OPTION_WEDDING && battle_config.wedding_ignorepalette)
+ if ((sd->sc.option & OPTION_WEDDING) != 0 && battle_config.wedding_ignorepalette == true)
vd->cloth_color = 0;
- if (sd->sc.option&OPTION_XMAS && battle_config.xmas_ignorepalette)
+ if ((sd->sc.option & OPTION_XMAS) != 0 && battle_config.xmas_ignorepalette == true)
vd->cloth_color = 0;
- if (sd->sc.option&OPTION_SUMMER && battle_config.summer_ignorepalette)
+ if ((sd->sc.option & OPTION_SUMMER) != 0 && battle_config.summer_ignorepalette == true)
vd->cloth_color = 0;
- if (sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette)
+ if ((sd->sc.option & OPTION_HANBOK) != 0 && battle_config.hanbok_ignorepalette == true)
vd->cloth_color = 0;
- if (sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */)
+ if ((sd->sc.option & OPTION_OKTOBERFEST) != 0 && battle_config.oktoberfest_ignorepalette == true)
vd->cloth_color = 0;
- if (vd->body_style && (
- sd->sc.option&OPTION_WEDDING || sd->sc.option&OPTION_XMAS ||
- sd->sc.option&OPTION_SUMMER || sd->sc.option&OPTION_HANBOK ||
- sd->sc.option&OPTION_OKTOBERFEST))
+ if ((sd->sc.option & OPTION_SUMMER2) != 0 && battle_config.summer2_ignorepalette == true)
+ vd->cloth_color = 0;
+ if (vd->body_style != 0 && (sd->sc.option & OPTION_COSTUME) != 0)
vd->body_style = 0;
break;
case LOOK_HAIR:
@@ -3154,16 +3237,18 @@ void clif_changelook(struct block_list *bl,int type,int val)
vd->hair_color = val;
break;
case LOOK_CLOTHES_COLOR:
- if( val && sd ) {
- if( sd->sc.option&OPTION_WEDDING && battle_config.wedding_ignorepalette )
+ if (val && sd != NULL) {
+ if ((sd->sc.option & OPTION_WEDDING) != 0 && battle_config.wedding_ignorepalette == true)
+ val = 0;
+ if ((sd->sc.option & OPTION_XMAS) != 0 && battle_config.xmas_ignorepalette == true)
val = 0;
- if( sd->sc.option&OPTION_XMAS && battle_config.xmas_ignorepalette )
+ if ((sd->sc.option & OPTION_SUMMER) != 0 && battle_config.summer_ignorepalette == true)
val = 0;
- if( sd->sc.option&OPTION_SUMMER && battle_config.summer_ignorepalette )
+ if ((sd->sc.option & OPTION_HANBOK) != 0 && battle_config.hanbok_ignorepalette == true)
val = 0;
- if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
+ if ((sd->sc.option & OPTION_OKTOBERFEST) != 0 && battle_config.oktoberfest_ignorepalette == true)
val = 0;
- if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+ if ((sd->sc.option & OPTION_SUMMER2) != 0 && battle_config.summer2_ignorepalette == true)
val = 0;
}
vd->cloth_color = val;
@@ -3195,17 +3280,14 @@ void clif_changelook(struct block_list *bl,int type,int val)
#endif
break;
case LOOK_BODY2:
- if (val && (
- sd->sc.option&OPTION_WEDDING || sd->sc.option&OPTION_XMAS ||
- sd->sc.option&OPTION_SUMMER || sd->sc.option&OPTION_HANBOK ||
- sd->sc.option&OPTION_OKTOBERFEST))
+ if (sd != NULL && (sd->sc.option&OPTION_COSTUME) != OPTION_NOTHING)
val = 0;
vd->body_style = val;
break;
}
// prevent leaking the presence of GM-hidden objects
- if( sc && sc->option&OPTION_INVISIBLE && !disguised(bl) )
+ if (sc && sc->option&OPTION_INVISIBLE && !clif->isdisguised(bl))
target = SELF;
#if PACKETVER < 4
clif->sendlook(bl, bl->id, type, val, 0, target);
@@ -3216,11 +3298,12 @@ void clif_changelook(struct block_list *bl,int type,int val)
val = vd->weapon;
val2 = vd->shield;
}
- if( disguised(bl) ) {
+ if (clif->isdisguised(bl)) {
clif->sendlook(bl, bl->id, type, val, val2, AREA_WOS);
clif->sendlook(bl, -bl->id, type, val, val2, SELF);
- } else
+ } else {
clif->sendlook(bl, bl->id, type, val, val2, target);
+ }
#endif
}
@@ -3501,15 +3584,16 @@ void clif_changeoption(struct block_list* bl)
WBUFW(buf,8) = (sc) ? sc->opt2 : 0;
WBUFL(buf,10) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
WBUFB(buf,14) = (sd)? sd->status.karma : 0;
- if(disguised(bl)) {
+ if (clif->isdisguised(bl)) {
clif->send(buf,packet_len(0x229),bl,AREA_WOS);
WBUFL(buf,2) = -bl->id;
clif->send(buf,packet_len(0x229),bl,SELF);
WBUFL(buf,2) = bl->id;
WBUFL(buf,10) = OPTION_INVISIBLE;
clif->send(buf,packet_len(0x229),bl,SELF);
- } else
+ } else {
clif->send(buf,packet_len(0x229),bl,AREA);
+ }
#else
WBUFW(buf,0) = 0x119;
WBUFL(buf,2) = bl->id;
@@ -3517,15 +3601,16 @@ void clif_changeoption(struct block_list* bl)
WBUFW(buf,8) = (sc) ? sc->opt2 : 0;
WBUFL(buf,10) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
WBUFB(buf,12) = (sd)? sd->status.karma : 0;
- if(disguised(bl)) {
+ if (clif->isdisguised(bl)) {
clif->send(buf,packet_len(0x119),bl,AREA_WOS);
WBUFL(buf,2) = -bl->id;
clif->send(buf,packet_len(0x119),bl,SELF);
WBUFL(buf,2) = bl->id;
WBUFW(buf,10) = OPTION_INVISIBLE;
clif->send(buf,packet_len(0x119),bl,SELF);
- } else
+ } else {
clif->send(buf,packet_len(0x119),bl,AREA);
+ }
#endif
}
@@ -3543,15 +3628,16 @@ void clif_changeoption2(struct block_list* bl) {
WBUFL(buf,6) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
WBUFL(buf,10) = clif_setlevel(bl);
WBUFL(buf,14) = (sc) ? sc->opt3 : 0;
- if(disguised(bl)) {
+ if (clif->isdisguised(bl)) {
clif->send(buf,packet_len(0x28a),bl,AREA_WOS);
WBUFL(buf,2) = -bl->id;
clif->send(buf,packet_len(0x28a),bl,SELF);
WBUFL(buf,2) = bl->id;
WBUFL(buf,6) = OPTION_INVISIBLE;
clif->send(buf,packet_len(0x28a),bl,SELF);
- } else
+ } else {
clif->send(buf,packet_len(0x28a),bl,AREA);
+ }
}
/// Notifies the client about the result of an item use request.
@@ -3623,26 +3709,29 @@ void clif_createchat(struct map_session_data* sd, int flag)
/// 1 = public
/// 2 = arena (npc waiting room)
/// 3 = PK zone (non-clickable)
-void clif_dispchat(struct chat_data* cd, int fd)
+void clif_dispchat(struct chat_data *cd, int fd)
{
unsigned char buf[128];
uint8 type;
+ int len;
- if( cd == NULL || cd->owner == NULL )
+ if (cd == NULL || cd->owner == NULL)
return;
type = (cd->owner->type == BL_PC ) ? (cd->pub) ? 1 : 0
: (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
: 1;
+ len = (int)strlen(cd->title);
+ Assert_retv(len <= INT16_MAX - 17);
WBUFW(buf, 0) = 0xd7;
- WBUFW(buf, 2) = 17 + strlen(cd->title);
+ WBUFW(buf, 2) = 17 + len;
WBUFL(buf, 4) = cd->owner->id;
WBUFL(buf, 8) = cd->bl.id;
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, len); // not zero-terminated
if( fd ) {
WFIFOHEAD(fd,WBUFW(buf,2));
@@ -3660,10 +3749,11 @@ void clif_dispchat(struct chat_data* cd, int fd)
/// 1 = public
/// 2 = arena (npc waiting room)
/// 3 = PK zone (non-clickable)
-void clif_changechatstatus(struct chat_data* cd)
+void clif_changechatstatus(struct chat_data *cd)
{
unsigned char buf[128];
uint8 type;
+ int len;
if( cd == NULL || cd->usersd[0] == NULL )
return;
@@ -3671,15 +3761,17 @@ void clif_changechatstatus(struct chat_data* cd)
type = (cd->owner->type == BL_PC ) ? (cd->pub) ? 1 : 0
: (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
: 1;
+ len = (int)strlen(cd->title);
+ Assert_retv(len <= INT16_MAX - 17);
WBUFW(buf, 0) = 0xdf;
- WBUFW(buf, 2) = 17 + strlen(cd->title);
+ WBUFW(buf, 2) = 17 + len;
WBUFL(buf, 4) = cd->owner->id;
WBUFL(buf, 8) = cd->bl.id;
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, len); // not zero-terminated
clif->send(buf,WBUFW(buf,2),cd->owner,CHAT);
}
@@ -3841,7 +3933,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 +3942,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));
@@ -3927,7 +4019,7 @@ void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd
WBUFW(buf,15)= 0; //card (4w)
WBUFW(buf,17)= 0; //card (4w)
#if PACKETVER >= 20150226
- clif->add_random_options(WBUFP(buf, 19), &sd->status.inventory[index]);
+ clif->add_item_options(WBUFP(buf, 19), &sd->status.inventory[index]);
#endif
}
else
@@ -3953,7 +4045,7 @@ void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd
WBUFB(buf,10)= sd->status.inventory[index].refine; //refine
clif->addcards(WBUFP(buf, 11), &sd->status.inventory[index]);
#if PACKETVER >= 20150226
- clif->add_random_options(WBUFP(buf, 19), &sd->status.inventory[index]);
+ clif->add_item_options(WBUFP(buf, 19), &sd->status.inventory[index]);
#endif
}
WFIFOSET(fd,packet_len(tradeaddType));
@@ -4084,7 +4176,7 @@ void clif_storageitemadded(struct map_session_data* sd, struct item* i, int inde
WFIFOB(fd,12+offset) = i->refine; //refine
clif->addcards(WFIFOP(fd,13+offset), i);
#if PACKETVER >= 20150226
- clif->add_random_options(WFIFOP(fd,21+offset), i);
+ clif->add_item_options(WFIFOP(fd, 21 + offset), i);
#endif
WFIFOSET(fd,packet_len(storageaddType));
}
@@ -4097,12 +4189,13 @@ void clif_storageitemremoved(struct map_session_data* sd, int index, int amount)
nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xf6));
- WFIFOW(fd,0)=0xf6; // Storage item removed
- WFIFOW(fd,2)=index+1;
- WFIFOL(fd,4)=amount;
- WFIFOSET(fd,packet_len(0xf6));
+ fd = sd->fd;
+
+ WFIFOHEAD(fd, packet_len(0xf6));
+ WFIFOW(fd, 0) = 0xf6; // Storage item removed
+ WFIFOW(fd, 2) = index + 1;
+ WFIFOL(fd, 4) = amount;
+ WFIFOSET(fd, packet_len(0xf6));
}
/// Closes storage (ZC_CLOSE_STORE).
@@ -4128,8 +4221,8 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
nullpo_retv(sd);
nullpo_retv(dstsd);
- if( dstsd->chatID ) {
- struct chat_data *cd = map->id2cd(dstsd->chatID);
+ if (dstsd->chat_id != 0) {
+ struct chat_data *cd = map->id2cd(dstsd->chat_id);
if (cd != NULL && cd->usersd[0] == dstsd)
clif->dispchat(cd,sd->fd);
} else if( dstsd->state.vending )
@@ -4143,7 +4236,7 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
clif->charm_single(sd->fd, dstsd);
for( i = 0; i < dstsd->sc_display_count; i++ ) {
- clif->sc_load(&sd->bl,dstsd->bl.id,SELF,status->dbs->IconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
+ clif->sc_continue(&sd->bl,dstsd->bl.id,SELF,status->dbs->IconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
}
if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
(sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
@@ -4170,7 +4263,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) {
nullpo_retv(bl);
vd = status->get_viewdata(bl);
- if (!vd || vd->class_ == INVISIBLE_CLASS)
+ if (vd == NULL || vd->class == INVISIBLE_CLASS)
return;
if (bl->type == BL_NPC) {
@@ -4333,16 +4426,17 @@ int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int
p.is_sp_damaged = 0; // TODO: IsSPDamage - Displays blue digits.
#endif
- if(disguised(dst)) {
+ if (clif->isdisguised(dst)) {
clif->send(&p,sizeof(p),dst,AREA_WOS);
p.targetGID = -dst->id;
clif->send(&p,sizeof(p),dst,SELF);
- } else
+ } else {
clif->send(&p,sizeof(p),dst,AREA);
+ }
- if(disguised(src)) {
+ if (clif->isdisguised(src)) {
p.GID = -src->id;
- if (disguised(dst))
+ if (clif->isdisguised(dst))
p.targetGID = dst->id;
if(damage > 0) p.damage = -1;
@@ -4391,7 +4485,7 @@ void clif_sitting(struct block_list* bl)
WBUFB(buf,26) = 2;
clif->send(buf, packet_len(0x8a), bl, AREA);
- if(disguised(bl)) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf, 2) = - bl->id;
clif->send(buf, packet_len(0x8a), bl, SELF);
}
@@ -4410,7 +4504,7 @@ void clif_standing(struct block_list* bl)
WBUFB(buf,26) = 3;
clif->send(buf, packet_len(0x8a), bl, AREA);
- if(disguised(bl)) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf, 2) = - bl->id;
clif->send(buf, packet_len(0x8a), bl, SELF);
}
@@ -4425,7 +4519,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));
@@ -4629,11 +4723,11 @@ int clif_outsight(struct block_list *bl,va_list ap)
nullpo_ret(bl);
switch(bl->type){
case BL_PC:
- if (sd->vd.class_ != INVISIBLE_CLASS)
+ if (sd->vd.class != INVISIBLE_CLASS)
clif->clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
- if (sd->chatID) {
- struct chat_data *cd = map->id2cd(sd->chatID);
- if(cd->usersd[0]==sd)
+ if (sd->chat_id != 0) {
+ struct chat_data *cd = map->id2cd(sd->chat_id);
+ if (cd != NULL && cd->usersd[0] == sd)
clif->dispchat(cd,tsd->fd);
}
if( sd->state.vending )
@@ -4652,7 +4746,7 @@ int clif_outsight(struct block_list *bl,va_list ap)
clif->clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
break;
default:
- if ((vd=status->get_viewdata(bl)) && vd->class_ != INVISIBLE_CLASS)
+ if ((vd=status->get_viewdata(bl)) && vd->class != INVISIBLE_CLASS)
clif->clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
break;
}
@@ -4661,7 +4755,7 @@ int clif_outsight(struct block_list *bl,va_list ap)
nullpo_ret(tbl);
if (tbl->type == BL_SKILL) //Trap knocked out of sight
clif->clearchar_skillunit(BL_UCAST(BL_SKILL, tbl), sd->fd);
- else if ((vd = status->get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS
+ else if ((vd = status->get_viewdata(tbl)) != NULL && vd->class != INVISIBLE_CLASS
&& !(tbl->type == BL_NPC && (BL_UCAST(BL_NPC, tbl)->option&OPTION_INVISIBLE)))
clif->clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd);
}
@@ -4735,9 +4829,9 @@ 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;
+ WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill->tree_get_max(id, sd->status.class))? 1:0;
else
WFIFOB(fd,len+36) = 0;
len += 37;
@@ -4786,9 +4880,9 @@ 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;
+ WFIFOB(fd,38) = (skill_lv < skill->tree_get_max(id, sd->status.class))? 1:0;
else
WFIFOB(fd,38) = 0;
WFIFOSET(fd,packet_len(0x111));
@@ -4833,7 +4927,7 @@ void clif_skillup(struct map_session_data *sd, uint16 skill_id, int skill_lv, in
WFIFOW(fd, 6) = skill->get_sp(skill_id, skill_lv);
WFIFOW(fd, 8) = (flag)?skill->get_range2(&sd->bl, skill_id, skill_lv) : skill->get_range(skill_id, skill_lv);
if( flag )
- WFIFOB(fd,10) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class_)) ? 1 : 0;
+ WFIFOB(fd,10) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class)) ? 1 : 0;
else
WFIFOB(fd,10) = 1;
@@ -4866,7 +4960,7 @@ void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf)
WFIFOW(fd,12) = 0;
}
if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT)
- WFIFOB(fd,14) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class_))? 1:0;
+ WFIFOB(fd,14) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class))? 1:0;
else
WFIFOB(fd,14) = 0;
WFIFOSET(fd,packet_len(0x7e1));
@@ -4887,7 +4981,7 @@ void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf)
/// is disposable:
/// 0 = yellow chat text "[src name] will use skill [skill name]."
/// 1 = no text
-void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime)
+void clif_useskill(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, uint16 skill_lv, int casttime)
{
#if PACKETVER < 20091124
const int cmd = 0x13e;
@@ -4895,6 +4989,7 @@ void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x,
const int cmd = 0x7fb;
#endif
unsigned char buf[32];
+ int property = skill->get_ele(skill_id, skill_lv);
WBUFW(buf,0) = cmd;
WBUFL(buf,2) = src_id;
@@ -4908,12 +5003,13 @@ void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x,
WBUFB(buf,24) = 0; // isDisposable
#endif
- if (disguised(bl)) {
+ if (clif->isdisguised(bl)) {
clif->send(buf,packet_len(cmd), bl, AREA_WOS);
WBUFL(buf,2) = -src_id;
clif->send(buf,packet_len(cmd), bl, SELF);
- } else
+ } else {
clif->send(buf,packet_len(cmd), bl, AREA);
+ }
}
/// Notifies clients in area, that an object canceled casting (ZC_DISPEL).
@@ -5043,16 +5139,17 @@ int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick
WBUFW(buf, 26) = skill_lv;
WBUFW(buf, 28) = div;
WBUFB(buf, 30) = type;
- if (disguised(dst)) {
+ if (clif->isdisguised(dst)) {
clif->send(buf, packet_len(0x114), dst, AREA_WOS);
WBUFL(buf, 8) = -dst->id;
clif->send(buf, packet_len(0x114), dst, SELF);
- } else
+ } else {
clif->send(buf, packet_len(0x114), dst, AREA);
+ }
- if (disguised(src)) {
+ if (clif->isdisguised(src)) {
WBUFL(buf, 4) = -src->id;
- if (disguised(dst))
+ if (clif->isdisguised(dst))
WBUFL(buf, 8) = dst->id;
if (damage > 0)
WBUFW(buf, 24) = -1;
@@ -5082,16 +5179,17 @@ int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick
#else
WBUFB(buf, 32) = (type == BDT_SKILL) ? BDT_MULTIHIT : type;
#endif
- if (disguised(dst)) {
+ if (clif->isdisguised(dst)) {
clif->send(buf, packet_len(0x1de), dst, AREA_WOS);
WBUFL(buf,8)=-dst->id;
clif->send(buf, packet_len(0x1de), dst, SELF);
- } else
+ } else {
clif->send(buf, packet_len(0x1de), dst, AREA);
+ }
- if (disguised(src)) {
+ if (clif->isdisguised(src)) {
WBUFL(buf, 4) = -src->id;
- if (disguised(dst))
+ if (clif->isdisguised(dst))
WBUFL(buf, 8) = dst->id;
if (damage > 0)
WBUFL(buf, 24) = -1;
@@ -5140,15 +5238,15 @@ int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tic
WBUFW(buf,32)=div;
WBUFB(buf,34)=type;
clif->send(buf,packet_len(0x115),src,AREA);
- if(disguised(src)) {
+ if (clif->isdisguised(src)) {
WBUFL(buf,4)=-src->id;
if(damage > 0)
WBUFW(buf,28)=-1;
clif->send(buf,packet_len(0x115),src,SELF);
}
- if (disguised(dst)) {
+ if (clif->isdisguised(dst)) {
WBUFL(buf,8)=-dst->id;
- if (disguised(src))
+ if (clif->isdisguised(src))
WBUFL(buf,4)=src->id;
else if(damage > 0)
WBUFW(buf,28)=-1;
@@ -5160,33 +5258,46 @@ int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tic
}
#endif // 0
-/// Non-damaging skill effect (ZC_USE_SKILL).
-/// 011a <skill id>.W <skill lv>.W <dst id>.L <src id>.L <result>.B
-int clif_skill_nodamage(struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,int fail)
+/// Non-damaging skill effect.
+/// 011a <skill id>.W <skill lv>.W <dst id>.L <src id>.L <result>.B (ZC_USE_SKILL)
+/// 09cb <skill id>.W <skill lv>.L <dst id>.L <src id>.L <result>.B (ZC_USE_SKILL2)
+int clif_skill_nodamage(struct block_list *src, struct block_list *dst, uint16 skill_id, int heal, int fail)
{
unsigned char buf[32];
+ short offset = 0;
+#if PACKETVER < 20131223
+ short cmd = 0x11a;
+#else
+ short cmd = 0x9cb;
+#endif
+ int len = packet_len(cmd);
nullpo_ret(dst);
- WBUFW(buf,0)=0x11a;
- WBUFW(buf,2)=skill_id;
- WBUFW(buf,4)=min(heal, INT16_MAX);
- WBUFL(buf,6)=dst->id;
- WBUFL(buf,10)=src?src->id:0;
- WBUFB(buf,14)=fail;
-
- if (disguised(dst)) {
- clif->send(buf,packet_len(0x11a),dst,AREA_WOS);
- WBUFL(buf,6)=-dst->id;
- clif->send(buf,packet_len(0x11a),dst,SELF);
+ WBUFW(buf, 0) = cmd;
+ WBUFW(buf, 2) = skill_id;
+#if PACKETVER < 20131223
+ WBUFW(buf, 4) = min(heal, INT16_MAX);
+#else
+ WBUFL(buf, 4) = min(heal, INT_MAX);
+ offset += 2;
+#endif
+ WBUFL(buf, 6 + offset) = dst->id;
+ WBUFL(buf, 10 + offset) = src ? src->id : 0;
+ WBUFB(buf, 14 + offset) = fail;
+
+ if (clif->isdisguised(dst)) {
+ clif->send(buf, len, dst, AREA_WOS);
+ WBUFL(buf, 6 + offset) = -dst->id;
+ clif->send(buf, len, dst, SELF);
} else
- clif->send(buf,packet_len(0x11a),dst,AREA);
+ clif->send(buf, len, dst, AREA);
- if(src && disguised(src)) {
- WBUFL(buf,10)=-src->id;
- if (disguised(dst))
- WBUFL(buf,6)=dst->id;
- clif->send(buf,packet_len(0x11a),src,SELF);
+ if (src && clif->isdisguised(src)) {
+ WBUFL(buf, 10 + offset) = -src->id;
+ if (clif->isdisguised(dst))
+ WBUFL(buf, 6 + offset) = dst->id;
+ clif->send(buf, len, src, SELF);
}
return fail;
@@ -5206,12 +5317,13 @@ void clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, int
WBUFW(buf,10)=x;
WBUFW(buf,12)=y;
WBUFL(buf,14)=(uint32)tick;
- if(disguised(src)) {
+ if (clif->isdisguised(src)) {
clif->send(buf,packet_len(0x117),src,AREA_WOS);
WBUFL(buf,4)=-src->id;
clif->send(buf,packet_len(0x117),src,SELF);
- } else
+ } else {
clif->send(buf,packet_len(0x117),src,AREA);
+ }
}
/// Presents a list of available warp destinations (ZC_WARPLIST).
@@ -5227,12 +5339,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;
@@ -5491,24 +5603,25 @@ void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val
/// Send message (modified by [Yor]) (ZC_NOTIFY_PLAYERCHAT).
/// 008e <packet len>.W <message>.?B
-void clif_displaymessage(const int fd, const char* mes) {
+void clif_displaymessage(const int fd, const char *mes)
+{
nullpo_retv(mes);
- if( map->cpsd_active && fd == 0 ) {
+ if (map->cpsd_active && fd == 0) {
ShowInfo("HCP: %s\n",mes);
- } else if ( fd > 0 ) {
+ } else if (fd > 0) {
#if PACKETVER == 20141022
/** for some reason game client crashes depending on message pattern (only for this packet) **/
/** so we redirect to ZC_NPC_CHAT **/
clif->messagecolor_self(fd, COLOR_DEFAULT, mes);
#else
- size_t len;
+ int len = (int)strnlen(mes, 255);
- if ( ( len = strnlen(mes, 255) ) > 0 ) { // don't send a void message (it's not displaying on the client chat). @help can send void line.
+ if (len > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line.
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);
+ WFIFOW(fd,2) = 5 + len; // 4 + len + NUL terminate
+ safestrncpy(WFIFOP(fd,4), mes, len + 1);
WFIFOSET(fd, 5 + len);
}
#endif
@@ -5529,7 +5642,7 @@ void clif_displaymessage2(const int fd, const char* mes) {
line = strtok(message, "\n");
while(line != NULL) {
// Limit message to 255+1 characters (otherwise it causes a buffer overflow in the client)
- size_t len = strnlen(line, 255);
+ int len = (int)strnlen(line, 255);
if (len > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line.
if( map->cpsd_active && fd == 0 ) {
@@ -5538,7 +5651,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 +5680,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';
/* */
@@ -5583,7 +5696,7 @@ void clif_displaymessage_sprintf(const int fd, const char *mes, ...) {
}
/// Send broadcast message in yellow or blue without font formatting (ZC_BROADCAST).
/// 009a <packet len>.W <message>.?B
-void clif_broadcast(struct block_list *bl, const char *mes, size_t len, int type, enum send_target target)
+void clif_broadcast(struct block_list *bl, const char *mes, int len, int type, enum send_target target)
{
int lp = (type&BC_COLOR_MASK) ? 4 : 0;
unsigned char *buf = NULL;
@@ -5607,38 +5720,38 @@ void clif_broadcast(struct block_list *bl, const char *mes, size_t len, int type
* Displays a message on a 'bl' to all it's nearby clients
* Used by npc_globalmessage
*------------------------------------------*/
-void clif_GlobalMessage(struct block_list* bl, const char* message) {
+void clif_GlobalMessage(struct block_list *bl, const char *message)
+{
char buf[256];
- size_t len;
+ int len;
nullpo_retv(bl);
- if(!message)
+ if (message == NULL)
return;
- len = strlen(message)+1;
+ len = (int)strlen(message)+1;
- if (len > sizeof(buf)-8) {
- ShowWarning("clif_GlobalMessage: Truncating too long message '%s' (len=%"PRIuS").\n", message, len);
- len = sizeof(buf)-8;
+ if (len > (int)sizeof(buf)-8) {
+ ShowWarning("clif_GlobalMessage: Truncating too long message '%s' (len=%d).\n", message, len);
+ len = (int)sizeof(buf)-8;
}
- WBUFW(buf,0)=0x8d;
- WBUFW(buf,2)=len+8;
- WBUFL(buf,4)=bl->id;
- safestrncpy((char *) WBUFP(buf,8),message,len);
- clif->send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT);
-
+ WBUFW(buf,0) = 0x8d;
+ WBUFW(buf,2) = len+8;
+ WBUFL(buf,4) = bl->id;
+ safestrncpy(WBUFP(buf,8),message,len);
+ clif->send(buf,WBUFW(buf,2),bl,ALL_CLIENT);
}
/// Send broadcast message with font formatting (ZC_BROADCAST2).
/// 01c3 <packet len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?B
-void clif_broadcast2(struct block_list* bl, const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target)
+void clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target)
{
unsigned char *buf;
nullpo_retv(mes);
- buf = (unsigned char*)aMalloc((16 + len)*sizeof(unsigned char));
+ buf = aMalloc((16 + len)*sizeof(unsigned char));
WBUFW(buf,0) = 0x1c3;
WBUFW(buf,2) = len + 16;
WBUFL(buf,4) = fontColor;
@@ -5658,13 +5771,24 @@ void clif_broadcast2(struct block_list* bl, const char* mes, size_t len, unsigne
/// 5 = HP (SP_HP)
/// 7 = SP (SP_SP)
/// ? = ignored
-void clif_heal(int fd,int type,int val)
+void clif_heal(int fd, int type, int val)
{
- WFIFOHEAD(fd,packet_len(0x13d));
- WFIFOW(fd,0)=0x13d;
- WFIFOW(fd,2)=type;
- WFIFOW(fd,4)=cap_value(val,0,INT16_MAX);
- WFIFOSET(fd,packet_len(0x13d));
+#if PACKETVER < 20150513
+ short cmd = 0x13d;
+#else
+ short cmd = 0xa27;
+#endif
+ int len = packet_len(cmd);
+
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = cmd;
+ WFIFOW(fd, 2) = type;
+#if PACKETVER < 20150513
+ WFIFOW(fd, 4) = cap_value(val, 0, INT16_MAX);
+#else
+ WFIFOL(fd, 4) = cap_value(val, 0, INT_MAX);
+#endif
+ WFIFOSET(fd, len);
}
/// Displays resurrection effect (ZC_RESURRECTION).
@@ -5682,7 +5806,7 @@ void clif_resurrection(struct block_list *bl,int type)
WBUFW(buf,6)=0;
clif->send(buf,packet_len(0x148),bl, type == 1 ? AREA : AREA_WOS);
- if (disguised(bl)) {
+ if (clif->isdisguised(bl)) {
struct map_session_data *sd = BL_UCAST(BL_PC, bl);
if (sd->fontcolor) {
WBUFL(buf,2)=-bl->id;
@@ -5806,7 +5930,7 @@ void clif_upgrademessage(int fd, int result, int item_id)
/// Whisper is transmitted to the destination player (ZC_WHISPER).
/// 0097 <packet len>.W <nick>.24B <message>.?B
/// 0097 <packet len>.W <nick>.24B <isAdmin>.L <message>.?B (PACKETVER >= 20091104)
-void clif_wis_message(int fd, const char *nick, const char *mes, size_t mes_len)
+void clif_wis_message(int fd, const char *nick, const char *mes, int mes_len)
{
#if PACKETVER >= 20091104
struct map_session_data *ssd = NULL;
@@ -5815,21 +5939,21 @@ void clif_wis_message(int fd, const char *nick, const char *mes, size_t mes_len)
nullpo_retv(mes);
#if PACKETVER < 20091104
- WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4);
+ WFIFOHEAD(fd, mes_len + NAME_LENGTH + 5);
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);
+ WFIFOW(fd,2) = mes_len + NAME_LENGTH + 5;
+ safestrncpy(WFIFOP(fd,4), nick, NAME_LENGTH);
+ safestrncpy(WFIFOP(fd,28), mes, mes_len + 1);
WFIFOSET(fd,WFIFOW(fd,2));
#else
ssd = map->nick2sd(nick);
- WFIFOHEAD(fd, mes_len + NAME_LENGTH + 8);
+ WFIFOHEAD(fd, mes_len + NAME_LENGTH + 9);
WFIFOW(fd,0) = 0x97;
- WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8;
- safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH);
+ WFIFOW(fd,2) = mes_len + NAME_LENGTH + 9;
+ 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 + 1);
WFIFOSET(fd,WFIFOW(fd,2));
#endif
}
@@ -5865,7 +5989,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));
}
@@ -5979,7 +6103,7 @@ void clif_item_repair_list(struct map_session_data *sd,struct map_session_data *
WFIFOW(fd,0)=0x1fc;
for (i = c = 0; i < MAX_INVENTORY; i++) {
int nameid = dstsd->status.inventory[i].nameid;
- if (nameid > 0 && dstsd->status.inventory[i].attribute != 0) { // && skill_can_repair(sd,nameid)) {
+ if (nameid > 0 && (dstsd->status.inventory[i].attribute & ATTR_BROKEN) != 0) { // && skill_can_repair(sd,nameid)) {
WFIFOW(fd,c*13+4) = i;
WFIFOW(fd,c*13+6) = nameid;
WFIFOB(fd,c*13+8) = dstsd->status.inventory[i].refine;
@@ -6089,7 +6213,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));
}
@@ -6127,7 +6251,7 @@ void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail)
WBUFB(buf,12+offset)=sd->status.cart[n].refine;
clif->addcards(WBUFP(buf,13+offset), &sd->status.cart[n]);
#if PACKETVER >= 20150226
- clif->add_random_options(WBUFP(buf,21+offset), &sd->status.cart[n]);
+ clif->add_item_options(WBUFP(buf, 21 + offset), &sd->status.cart[n]);
#endif
WFIFOSET(fd,packet_len(cartaddType));
}
@@ -6176,7 +6300,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));
@@ -6255,7 +6379,7 @@ void clif_vendinglist(struct map_session_data* sd, unsigned int id, struct s_ven
WFIFOB(fd,offset+13+i*item_length) = vsd->status.cart[index].refine;
clif->addcards(WFIFOP(fd,offset+14+i*item_length), &vsd->status.cart[index]);
#if PACKETVER >= 20150226
- clif->add_random_options(WFIFOP(fd,offset+22+i*item_length), &vsd->status.cart[index]);
+ clif->add_item_options(WFIFOP(fd, offset + 22 + i * item_length), &vsd->status.cart[index]);
#endif
}
WFIFOSET(fd,WFIFOW(fd,2));
@@ -6321,34 +6445,46 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven
WFIFOB(fd,21+i*item_length) = sd->status.cart[index].refine;
clif->addcards(WFIFOP(fd,22+i*item_length), &sd->status.cart[index]);
#if PACKETVER >= 20150226
- clif->add_random_options(WFIFOP(fd,30+22+i*item_length), &sd->status.cart[index]);
+ clif->add_item_options(WFIFOP(fd, 30 + i * item_length), &sd->status.cart[index]);
#endif
}
WFIFOSET(fd,WFIFOW(fd,2));
-#if PACKETVER >= 20141022
+#if PACKETVER >= 20140625
/** should go elsewhere perhaps? it has to be bundled with this however. **/
- WFIFOHEAD(fd, 3);
+ WFIFOHEAD(fd, packet_len(0xa28));
WFIFOW(fd, 0) = 0xa28;
WFIFOB(fd, 2) = 0;/** 1 is failure. our current responses to failure are working so not yet implemented **/
- WFIFOSET(fd, 3);
+ WFIFOSET(fd, packet_len(0xa28));
#endif
}
-/// Inform merchant that someone has bought an item (ZC_DELETEITEM_FROM_MCSTORE).
-/// 0137 <index>.W <amount>.W
-void clif_vendingreport(struct map_session_data* sd, int index, int amount)
+/// Inform merchant that someone has bought an item.
+/// 0137 <index>.W <amount>.W (ZC_DELETEITEM_FROM_MCSTORE).
+/// 09e5 <index>.W <amount>.W <GID>.L <Date>.L <zeny>.L (ZC_DELETEITEM_FROM_MCSTORE2).
+void clif_vendingreport(struct map_session_data* sd, int index, int amount, uint32 char_id, int zeny)
{
int fd;
+#if PACKETVER < 20141016 // TODO : not sure for client date [Napster]
+ const int cmd = 0x137;
+#else
+ const int cmd = 0x9e5;
+#endif
+ const int len = packet_len(cmd);
nullpo_retv(sd);
fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x137));
- WFIFOW(fd,0) = 0x137;
- WFIFOW(fd,2) = index+2;
- WFIFOW(fd,4) = amount;
- WFIFOSET(fd,packet_len(0x137));
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = cmd;
+ WFIFOW(fd, 2) = index + 2;
+ WFIFOW(fd, 4) = amount;
+#if PACKETVER >= 20141016
+ WFIFOL(fd,6) = char_id; // GID
+ WFIFOL(fd,10) = (int)time(NULL); // Date
+ WFIFOL(fd,14) = zeny; // zeny
+#endif
+ WFIFOSET(fd, len);
}
/// Result of organizing a party (ZC_ACK_MAKE_GROUP).
@@ -6404,7 +6540,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 +6573,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++;
@@ -6517,7 +6653,7 @@ void clif_party_inviteack(struct map_session_data* sd, const char* nick, int res
#if PACKETVER < 20070904
if( result == 7 ) {
- clif->message(fd, msg_sd(sd,3));
+ clif->message(fd, msg_sd(sd,3)); // Character not found.
return;
}
#endif
@@ -6525,13 +6661,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
@@ -6615,7 +6751,7 @@ void clif_party_withdraw(struct party_data* p, struct map_session_data* sd, int
/// Party chat message (ZC_NOTIFY_CHAT_PARTY).
/// 0109 <packet len>.W <account id>.L <message>.?B
-void clif_party_message(struct party_data* p, int account_id, const char* mes, int len)
+void clif_party_message(struct party_data *p, int account_id, const char *mes, int len)
{
struct map_session_data *sd;
int i;
@@ -6623,22 +6759,24 @@ void clif_party_message(struct party_data* p, int account_id, const char* mes, i
nullpo_retv(p);
nullpo_retv(mes);
- for(i=0; i < MAX_PARTY && !p->data[i].sd;i++);
- if(i < MAX_PARTY){
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != NULL);
+
+ if (i < MAX_PARTY) {
unsigned char buf[1024];
+ int maxlen = (int)sizeof(buf) - 9;
- if (len > sizeof(buf)-8) {
- ShowWarning("clif_party_message: Truncated message '%s' (len=%d, max=%"PRIuS", party_id=%d).\n",
- mes, len, sizeof(buf)-8, p->party.party_id);
- len = sizeof(buf)-8;
+ if (len > maxlen) {
+ ShowWarning("clif_party_message: Truncated message '%s' (len=%d, max=%d, party_id=%d).\n",
+ mes, len, maxlen, p->party.party_id);
+ len = maxlen;
}
sd = p->data[i].sd;
- WBUFW(buf,0)=0x109;
- WBUFW(buf,2)=len+8;
- WBUFL(buf,4)=account_id;
- safestrncpy((char *)WBUFP(buf,8), mes, len);
- clif->send(buf,len+8,&sd->bl,PARTY);
+ WBUFW(buf,0) = 0x109;
+ WBUFW(buf,2) = len+9;
+ WBUFL(buf,4) = account_id;
+ safestrncpy(WBUFP(buf,8), mes, len+1);
+ clif->send(buf, len+9, &sd->bl, PARTY);
}
}
@@ -6998,21 +7136,31 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd)
if( src->type == BL_MER )
{
struct mercenary_data *md = BL_CAST(BL_MER,src);
+ int skill_lvl;
if( md && md->master && md->devotion_flag )
WBUFL(buf,6) = md->master->bl.id;
- WBUFW(buf,26) = skill->get_range2(src, ML_DEVOTION, mercenary->checkskill(md, ML_DEVOTION));
+ skill_lvl = mercenary->checkskill(md, ML_DEVOTION);
+ if (skill_lvl > 0)
+ WBUFW(buf, 26) = skill->get_range2(src, ML_DEVOTION, skill_lvl);
+ else
+ WBUFW(buf, 26) = 0;
}
else
{
int i;
struct map_session_data *sd = BL_CAST(BL_PC,src);
+ int skill_lvl;
if( sd == NULL )
return;
for( i = 0; i < MAX_PC_DEVOTION; i++ )
WBUFL(buf,6+4*i) = sd->devotion[i];
- WBUFW(buf,26) = skill->get_range2(src, CR_DEVOTION, pc->checkskill(sd, CR_DEVOTION));
+ skill_lvl = pc->checkskill(sd, CR_DEVOTION);
+ if (skill_lvl > 0)
+ WBUFW(buf, 26) = skill->get_range2(src, CR_DEVOTION, skill_lvl);
+ else
+ WBUFW(buf, 26) = 0;
}
if( tsd )
@@ -7112,6 +7260,13 @@ void clif_mvp_item(struct map_session_data *sd,int nameid)
/// 010b <exp>.L
void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
{
+#if PACKETVER >= 20131223 // Kro removed this packet [Napster]
+ if (battle_config.mvp_exp_reward_message) {
+ char e_msg[CHAT_SIZE_MAX];
+ sprintf(e_msg, msg_txt(855), exp);
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, e_msg); // Congratulations! You are the MVP! Your reward EXP Points are %u !!
+ }
+#else
int fd;
nullpo_retv(sd);
@@ -7121,6 +7276,7 @@ void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
WFIFOW(fd,0)=0x10b;
WFIFOL(fd,2)=cap_value(exp,0,INT32_MAX);
WFIFOSET(fd,packet_len(0x10b));
+#endif
}
/// Dropped MVP item reward message (ZC_THROW_MVPITEM).
@@ -7303,7 +7459,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));
@@ -7366,7 +7522,7 @@ void clif_guild_memberlist(struct map_session_data *sd)
WFIFOW(fd,c*104+12)=m->hair;
WFIFOW(fd,c*104+14)=m->hair_color;
WFIFOW(fd,c*104+16)=m->gender;
- WFIFOW(fd,c*104+18)=m->class_;
+ WFIFOW(fd,c*104+18)=m->class;
WFIFOW(fd,c*104+20)=m->lv;
WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT32_MAX);
WFIFOL(fd,c*104+26)=m->online;
@@ -7546,7 +7702,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 +7803,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 +7871,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 +8015,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 +8098,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));
}
*/
@@ -7950,24 +8106,26 @@ void clif_marriage_proposal(int fd, struct map_session_data *sd, struct map_sess
/*==========================================
* Displays a message using the guild-chat colors to the specified targets. [Skotlex]
*------------------------------------------*/
-void clif_disp_message(struct block_list* src, const char* mes, size_t len, enum send_target target)
+void clif_disp_message(struct block_list *src, const char *mes, enum send_target target)
{
unsigned char buf[256];
+ int len;
+
+ nullpo_retv(mes);
+ nullpo_retv(src);
+ len = (int)strlen(mes);
if (len == 0)
return;
- nullpo_retv(src);
- nullpo_retv(mes);
-
- if (len > sizeof(buf)-5) {
- ShowWarning("clif_disp_message: Truncated message '%s' (len=%"PRIuS", max=%"PRIuS", aid=%d).\n", mes, len, sizeof(buf)-5, src->id);
- len = sizeof(buf)-5;
+ if (len > (int)sizeof(buf)-5) {
+ ShowWarning("clif_disp_message: Truncated message '%s' (len=%d, max=%"PRIuS", aid=%d).\n", mes, len, sizeof(buf)-5, src->id);
+ len = (int)sizeof(buf)-5;
}
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 +8199,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 +8257,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 +8285,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 +8300,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;
@@ -8167,7 +8325,7 @@ void clif_specialeffect(struct block_list* bl, int type, enum send_target target
clif->send(buf, packet_len(0x1f3), bl, target);
- if (disguised(bl)) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2) = -bl->id;
clif->send(buf, packet_len(0x1f3), bl, SELF);
}
@@ -8199,8 +8357,7 @@ void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, sen
clif->send(buf, packet_len(0x284), bl, target);
- if( disguised(bl) )
- {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2) = -bl->id;
clif->send(buf, packet_len(0x284), bl, SELF);
}
@@ -8216,17 +8373,18 @@ void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, sen
*/
void clif_messagecolor_self(int fd, uint32 color, const char *msg)
{
- size_t msg_len;
+ int msg_len;
nullpo_retv(msg);
- msg_len = strlen(msg) + 1;
+ msg_len = (int)strlen(msg) + 1;
+ Assert_retv(msg_len <= INT16_MAX - 12);
WFIFOHEAD(fd,msg_len + 12);
WFIFOW(fd,0) = 0x2C1;
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);
}
@@ -8239,17 +8397,19 @@ void clif_messagecolor_self(int fd, uint32 color, const char *msg)
* @param color Message color (RGB format: 0xRRGGBB)
* @param msg Message text
*/
-void clif_messagecolor(struct block_list* bl, uint32 color, const char *msg)
+void clif_messagecolor(struct block_list *bl, uint32 color, const char *msg)
{
- size_t msg_len = strlen(msg) + 1;
+ int msg_len;
uint8 buf[256];
nullpo_retv(bl);
nullpo_retv(msg);
- if (msg_len > sizeof(buf)-12) {
- ShowWarning("clif_messagecolor: Truncating too long message '%s' (len=%"PRIuS").\n", msg, msg_len);
- msg_len = sizeof(buf)-12;
+ msg_len = (int)strlen(msg) + 1;
+
+ if (msg_len > (int)sizeof(buf)-12) {
+ ShowWarning("clif_messagecolor: Truncating too long message '%s' (len=%d).\n", msg, msg_len);
+ msg_len = (int)sizeof(buf)-12;
}
WBUFW(buf,0) = 0x2C1;
@@ -8272,9 +8432,11 @@ void clif_refresh_storagewindow(struct map_session_data *sd)
nullpo_retv(sd);
// Notify the client that the storage is open
if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
- storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ if (sd->storage.aggregate > 0) {
+ storage->sortitem(VECTOR_DATA(sd->storage.item), VECTOR_LENGTH(sd->storage.item));
+ clif->storagelist(sd, VECTOR_DATA(sd->storage.item), VECTOR_LENGTH(sd->storage.item));
+ }
+ clif->updatestorageamount(sd, sd->storage.aggregate, MAX_STORAGE);
}
// Notify the client that the gstorage is open otherwise it will
// remain locked forever and nobody will be able to access it
@@ -8329,7 +8491,7 @@ void clif_refresh(struct map_session_data *sd)
clif->elemental_info(sd);
map->foreachinrange(clif->getareachar,&sd->bl,AREA_SIZE,BL_ALL,sd);
clif->weather_check(sd);
- if( sd->chatID )
+ if (sd->chat_id != 0)
chat->leave(sd, false);
if( sd->state.vending )
clif->openvending(sd, sd->bl.id, sd->vending);
@@ -8345,7 +8507,7 @@ void clif_refresh(struct map_session_data *sd)
mail->clear(sd);
- if( disguised(&sd->bl) ) {/* refresh-da */
+ if (clif->isdisguised(&sd->bl)) {/* refresh-da */
short disguise = sd->disguise;
pc->disguise(sd, -1);
pc->disguise(sd, disguise);
@@ -8475,7 +8637,7 @@ void clif_charnameack (int fd, struct block_list *bl)
memcpy(WBUFP(buf,6), BL_UCCAST(BL_ELEM, bl)->db->name, NAME_LENGTH);
break;
default:
- ShowError("clif_charnameack: bad type %d(%d)\n", bl->type, bl->id);
+ ShowError("clif_charnameack: bad type %u(%d)\n", bl->type, bl->id);
return;
}
@@ -8560,8 +8722,7 @@ void clif_slide(struct block_list *bl, int x, int y)
WBUFW(buf, 8) = y;
clif->send(buf, packet_len(0x1ff), bl, AREA);
- if( disguised(bl) )
- {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2) = -bl->id;
clif->send(buf, packet_len(0x1ff), bl, SELF);
}
@@ -8569,34 +8730,33 @@ void clif_slide(struct block_list *bl, int x, int y)
/// Public chat message (ZC_NOTIFY_CHAT). lordalfa/Skotlex - used by @me as well
/// 008d <packet len>.W <id>.L <message>.?B
-void clif_disp_overhead(struct block_list *bl, const char* mes)
+void clif_disp_overhead(struct block_list *bl, const char *mes)
{
unsigned char buf[256]; //This should be more than sufficient, the theoretical max is CHAT_SIZE + 8 (pads and extra inserted crap)
- size_t len_mes;
+ int mes_len;
nullpo_retv(bl);
nullpo_retv(mes);
- len_mes = strlen(mes)+1; //Account for \0
+ mes_len = (int)strlen(mes)+1; //Account for \0
- if (len_mes > sizeof(buf)-8) {
- ShowError("clif_disp_overhead: Message too long (length %"PRIuS")\n", len_mes);
- len_mes = sizeof(buf)-8; //Trunk it to avoid problems.
+ if (mes_len > (int)sizeof(buf)-8) {
+ ShowError("clif_disp_overhead: Message too long (length %d)\n", mes_len);
+ mes_len = sizeof(buf)-8; //Trunk it to avoid problems.
}
// send message to others
WBUFW(buf,0) = 0x8d;
- WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id)
+ WBUFW(buf,2) = mes_len + 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, mes_len);
clif->send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
// send back message to the speaker
- if( bl->type == BL_PC ) {
+ if (bl->type == BL_PC) {
WBUFW(buf,0) = 0x8e;
- WBUFW(buf, 2) = len_mes + 4;
- safestrncpy((char*)WBUFP(buf,4), mes, len_mes);
+ WBUFW(buf, 2) = mes_len + 4;
+ safestrncpy(WBUFP(buf,4), mes, mes_len);
clif->send(buf, WBUFW(buf,2), bl, SELF);
}
-
}
/*==========================
@@ -8680,7 +8840,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;
@@ -8795,7 +8955,7 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts
safestrncpy(viewequip_list.characterName, tsd->status.name, NAME_LENGTH);
- viewequip_list.job = tsd->status.class_;
+ viewequip_list.job = tsd->status.class;
viewequip_list.head = tsd->vd.hair_style;
viewequip_list.accessory = tsd->vd.head_bottom;
viewequip_list.accessory2 = tsd->vd.head_mid;
@@ -8880,119 +9040,153 @@ void clif_msgtable_skill(struct map_session_data* sd, uint16 skill_id, int msg_i
WFIFOSET(fd, packet_len(0x7e6));
}
-/// Validates one global/guild/party/whisper message packet and tries to recognize its components.
-/// 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;
- unsigned int packetlen, textlen;
- size_t namelen, messagelen;
- int fd = sd->fd;
+/**
+ * Validates and processes a global/guild/party message packet.
+ *
+ * @param[in] sd The source character.
+ * @param[in] packet The packet data.
+ * @param[out] out_buf The output buffer (must be a valid buffer), that will
+ * be filled with "Name : Message".
+ * @param[in] out_buflen The size of out_buf (including the NUL terminator).
+ * @return a pointer to the "Message" part of out_buf.
+ * @retval NULL if the validation failed, the messages was a command or the
+ * character can't send chat messages. out_buf shan't be used.
+ */
+const char *clif_process_chat_message(struct map_session_data *sd, const struct packet_chat_message *packet, char *out_buf, int out_buflen)
+{
+ const char *srcname = NULL, *srcmessage = NULL, *message = NULL;
+ int textlen = 0, namelen = 0, messagelen = 0;
- nullpo_retr(false, sd);
- nullpo_retr(false, name_);
- nullpo_retr(false, namelen_);
- nullpo_retr(false, message_);
- nullpo_retr(false, messagelen_);
-
- *name_ = NULL;
- *namelen_ = 0;
- *message_ = NULL;
- *messagelen_ = 0;
-
- packetlen = RFIFOW(fd,2);
- // basic structure checks
- if (packetlen < 4 + 1) {
+ nullpo_ret(sd);
+ nullpo_ret(packet);
+ nullpo_ret(out_buf);
+
+ if (packet->packet_len < 4 + 1) {
// 4-byte header and at least an empty string is expected
- ShowWarning("clif_process_message: Received malformed packet from player '%s' (no message data)!\n", sd->status.name);
- return false;
+ ShowWarning("clif_process_chat_message: Received malformed packet from player '%s' (no message data)!\n", sd->status.name);
+ return NULL;
}
- text = (char*)RFIFOP(fd,4);
- textlen = packetlen - 4;
+#if PACKETVER >= 20151001
+ // Packet doesn't include a NUL terminator
+ textlen = packet->packet_len - 4;
+#else // PACKETVER < 20151001
+ // Packet includes a NUL terminator
+ textlen = packet->packet_len - 4 - 1;
+#endif // PACKETVER > 20151001
- // process <name> part of the packet
- if( format == 0 )
- {// name and message are separated by ' : '
- // validate name
- name = text;
- namelen = strnlen(sd->status.name, NAME_LENGTH-1); // name length (w/o zero byte)
+ // name and message are separated by ' : '
+ srcname = packet->message;
+ namelen = (int)strnlen(sd->status.name, NAME_LENGTH-1); // name length (w/o zero byte)
- if( strncmp(name, sd->status.name, namelen) || // the text must start with the speaker's name
- name[namelen] != ' ' || name[namelen+1] != ':' || name[namelen+2] != ' ' ) // followed by ' : '
- {
- //Hacked message, or infamous "client desynchronize" issue where they pick one char while loading another.
- ShowWarning("clif_process_message: Player '%s' sent a message using an incorrect name! Forcing a relog...\n", sd->status.name);
- sockt->eof(fd); // Just kick them out to correct it.
- return false;
- }
+ if (strncmp(srcname, sd->status.name, namelen) != 0 // the text must start with the speaker's name
+ || srcname[namelen] != ' ' || srcname[namelen+1] != ':' || srcname[namelen+2] != ' ' // followed by ' : '
+ ) {
+ //Hacked message, or infamous "client desynchronize" issue where they pick one char while loading another.
+ ShowWarning("clif_process_chat_message: Player '%s' sent a message using an incorrect name! Forcing a relog...\n", sd->status.name);
+ sockt->eof(sd->fd); // Just kick them out to correct it.
+ return NULL;
+ }
- message = name + namelen + 3;
- messagelen = textlen - namelen - 3; // this should be the message length (w/ zero byte included)
+ srcmessage = packet->message + namelen + 3; // <name> " : " <message>
+ messagelen = textlen - namelen - 3;
+
+ if (messagelen >= CHAT_SIZE_MAX || textlen >= out_buflen) {
+ // messages mustn't be too long
+ // Normally you can only enter CHATBOX_SIZE-1 letters into the chat box, but Frost Joke / Dazzler's text can be longer.
+ // Also, the physical size of strings that use multibyte encoding can go multiple times over the chatbox capacity.
+ // Neither the official client nor server place any restriction on the length of the data in the packet,
+ // but we'll only allow reasonably long strings here. This also makes sure that they fit into the `chatlog` table.
+ ShowWarning("clif_process_chat_message: Player '%s' sent a message too long ('%.*s')!\n", sd->status.name, CHATBOX_SIZE-1, srcmessage);
+ return NULL;
}
- else
- {// name has fixed width
- if( textlen < NAME_LENGTH + 1 )
- {
- ShowWarning("clif_process_message: Received malformed packet from player '%s' (packet length is incorrect)!\n", sd->status.name);
- return false;
- }
- // validate name
- name = text;
- namelen = strnlen(name, NAME_LENGTH-1); // name length (w/o zero byte)
+ safestrncpy(out_buf, packet->message, textlen+1); // [!] packet->message is not necessarily NUL terminated
+ message = out_buf + namelen + 3;
- if (name[namelen] != '\0') {
- // only restriction is that the name must be zero-terminated
- ShowWarning("clif_process_message: Player '%s' sent an unterminated name!\n", sd->status.name);
- return false;
- }
+ if (!pc->process_chat_message(sd, message))
+ return NULL;
+ return message;
+}
- message = name + NAME_LENGTH;
- messagelen = textlen - NAME_LENGTH; // this should be the message length (w/ zero byte included)
- }
+/**
+ * Validates and processes a whisper message packet.
+ *
+ * @param[in] sd The source character.
+ * @param[in] packet The packet data.
+ * @param[out] out_name The parsed target name buffer (must be a valid
+ * buffer of size NAME_LENGTH).
+ * @param[out] out_message The output message buffer (must be a valid buffer).
+ * @param[in] out_messagelen The size of out_message.
+ * @retval true if the validation succeeded and the message is a chat message.
+ * @retval false if the validation failed, the messages was a command or the
+ * character can't send chat messages. out_name and out_message
+ * shan't be used.
+ */
+bool clif_process_whisper_message(struct map_session_data *sd, const struct packet_whisper_message *packet, char *out_name, char *out_message, int out_messagelen)
+{
+ int namelen = 0, messagelen = 0;
- if (messagelen != strnlen(message, messagelen)+1) {
- // the declared length must match real length
- ShowWarning("clif_process_message: Received malformed packet from player '%s' (length is incorrect)!\n", sd->status.name);
+ nullpo_retr(false, sd);
+ nullpo_retr(false, packet);
+ nullpo_retr(false, out_name);
+ nullpo_retr(false, out_message);
+
+ if (packet->packet_len < NAME_LENGTH + 4 + 1) {
+ // 4-byte header and at least an empty string is expected
+ ShowWarning("clif_process_whisper_message: Received malformed packet from player '%s' (packet length is incorrect)!\n", sd->status.name);
return false;
}
- // verify <message> part of the packet
- if (message[messagelen-1] != '\0') {
- // message must be zero-terminated
- ShowWarning("clif_process_message: Player '%s' sent an unterminated message string!\n", sd->status.name);
+
+ // validate name
+ namelen = (int)strnlen(packet->name, NAME_LENGTH-1); // name length (w/o zero byte)
+
+ if (packet->name[namelen] != '\0') {
+ // only restriction is that the name must be zero-terminated
+ ShowWarning("clif_process_whisper_message: Player '%s' sent an unterminated name!\n", sd->status.name);
return false;
}
- if (messagelen > CHAT_SIZE_MAX-1) {
+
+#if PACKETVER >= 20151001
+ // Packet doesn't include a NUL terminator
+ messagelen = packet->packet_len - NAME_LENGTH - 4;
+#else // PACKETVER < 20151001
+ // Packet includes a NUL terminator
+ messagelen = packet->packet_len - NAME_LENGTH - 4 - 1;
+#endif // PACKETVER > 20151001
+
+ if (messagelen >= CHAT_SIZE_MAX || messagelen >= out_messagelen) {
// messages mustn't be too long
// Normally you can only enter CHATBOX_SIZE-1 letters into the chat box, but Frost Joke / Dazzler's text can be longer.
// Also, the physical size of strings that use multibyte encoding can go multiple times over the chatbox capacity.
// Neither the official client nor server place any restriction on the length of the data in the packet,
// but we'll only allow reasonably long strings here. This also makes sure that they fit into the `chatlog` table.
- ShowWarning("clif_process_message: Player '%s' sent a message too long ('%.*s')!\n", sd->status.name, CHAT_SIZE_MAX-1, message);
+ ShowWarning("clif_process_whisper_message: Player '%s' sent a message too long ('%.*s')!\n", sd->status.name, CHAT_SIZE_MAX-1, packet->message);
return false;
}
- *name_ = name;
- *namelen_ = namelen;
- *message_ = message;
- *messagelen_ = messagelen;
+ safestrncpy(out_name, packet->name, namelen+1); // [!] packet->name is not NUL terminated
+ safestrncpy(out_message, packet->message, messagelen+1); // [!] packet->message is not necessarily NUL terminated
+
+ if (!pc->process_chat_message(sd, out_message))
+ return false;
+
return true;
}
void clif_channel_msg(struct channel_data *chan, struct map_session_data *sd, char *msg)
{
- DBIterator *iter;
+ struct DBIterator *iter;
struct map_session_data *user;
- unsigned short msg_len;
+ int msg_len;
uint32 color;
nullpo_retv(chan);
nullpo_retv(sd);
nullpo_retv(msg);
iter = db_iterator(chan->users);
- msg_len = strlen(msg) + 1;
+ msg_len = (int)strlen(msg) + 1;
+ Assert_retv(msg_len <= INT16_MAX - 12);
color = channel->config->colors[chan->color];
WFIFOHEAD(sd->fd,msg_len + 12);
@@ -9000,7 +9194,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 )
@@ -9017,23 +9211,24 @@ void clif_channel_msg(struct channel_data *chan, struct map_session_data *sd, ch
void clif_channel_msg2(struct channel_data *chan, char *msg)
{
- DBIterator *iter;
+ struct DBIterator *iter;
struct map_session_data *user;
unsigned char buf[210];
- unsigned short msg_len;
+ int msg_len;
uint32 color;
nullpo_retv(chan);
nullpo_retv(msg);
iter = db_iterator(chan->users);
- msg_len = strlen(msg) + 1;
+ msg_len = (int)strlen(msg) + 1;
+ Assert_retv(msg_len <= INT16_MAX - 12);
color = channel->config->colors[chan->color];
WBUFW(buf,0) = 0x2C1;
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);
@@ -9148,7 +9343,7 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
sd->state.warping = 0;
sd->state.dialog = 0;/* reset when warping, client dialog will go missing */
- // look
+ // Character Looks
#if PACKETVER < 4
clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
@@ -9158,21 +9353,26 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
if(sd->vd.cloth_color)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
+
if (sd->vd.body_style)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_BODY2,sd->vd.body_style,SELF);
- // item
- clif->inventorylist(sd); // inventory list first, otherwise deleted items in pc->checkitem show up as 'unknown item'
- pc->checkitem(sd);
- // cart
+ // Send character inventory to the client.
+ // call this before pc->checkitem() so that the client isn't called to delete a non-existent item.
+ clif->inventorylist(sd);
+
+ // Send the cart inventory, counts & weight to the client.
if(pc_iscarton(sd)) {
clif->cartlist(sd);
- clif->updatestatus(sd,SP_CARTINFO);
+ clif->updatestatus(sd, SP_CARTINFO);
}
- // weight
- clif->updatestatus(sd,SP_WEIGHT);
- clif->updatestatus(sd,SP_MAXWEIGHT);
+ // Check for and delete unavailable/disabled items.
+ pc->checkitem(sd);
+
+ // Send the character's weight to the client.
+ clif->updatestatus(sd, SP_WEIGHT);
+ clif->updatestatus(sd, SP_MAXWEIGHT);
// guild
// (needs to go before clif_spawn() to show guild emblems correctly)
@@ -9392,7 +9592,7 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
if( map->list[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m) ) {
char output[128];
sprintf(output, "[ Kill Steal Protection Disabled. KS is allowed in this map ]");
- clif->broadcast(&sd->bl, output, strlen(output) + 1, BC_BLUE, SELF);
+ clif->broadcast(&sd->bl, output, (int)strlen(output) + 1, BC_BLUE, SELF);
}
map->iwall_get(sd); // Updates Walls Info on this Map to Client
@@ -9459,7 +9659,8 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
clif->clearunit_area(&sd->bl, CLR_DEAD);
else {
skill->usave_trigger(sd);
- sd->ud.dir = 0;/* enforce north-facing (not visually, virtually) */
+ if (battle_config.player_warp_keep_direction == 1)
+ clif->changed_dir(&sd->bl, SELF); // Visually updates player facing direction
}
// Trigger skill effects if you appear standing on them
@@ -9474,7 +9675,7 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started
if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class.
- if( sd->class_ == qi->job )
+ if (sd->status.class == qi->job)
clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
} else {
clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
@@ -9665,11 +9866,9 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd) __attribute__((non
void clif_parse_QuitGame(int fd, struct map_session_data *sd)
{
/* Rovert's prevent logout option fixed [Valaris] */
- if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] &&
- (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
- {
+ if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && !sd->sc.data[SC_SUHIDE] &&
+ (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout)) {
sockt->eof(fd);
-
clif->disconnect_ack(sd, 0);
} else {
clif->disconnect_ack(sd, 1);
@@ -9699,7 +9898,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
// 'see people in GM hide' cheat detection
#if 0 /* disabled due to false positives (network lag + request name of char that's about to hide = race condition) */
sc = status->get_sc(bl);
- if (sc && sc->option&OPTION_INVISIBLE && !disguised(bl) &&
+ if (sc && sc->option&OPTION_INVISIBLE && !clif->isdisguised(bl) &&
bl->type != BL_NPC && //Skip hidden NPCs which can be seen using Maya Purple
pc_get_group_level(sd) < battle_config.hack_info_GM_level
) {
@@ -9718,149 +9917,114 @@ int clif_undisguise_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data * sd;
if( (sd = map->id2sd(id)) ) {
sd->fontcolor_tid = INVALID_TIMER;
- if( sd->fontcolor && sd->disguise == sd->status.class_ )
+ if (sd->fontcolor && sd->disguise == sd->status.class)
pc->disguise(sd,-1);
}
return 0;
}
-void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
-/// Validates and processes global messages
-/// 008c <packet len>.W <text>.?B (<name> : <message>) 00 (CZ_REQUEST_CHAT)
-/// There are various variants of this packet.
-void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
+/**
+ * Validates and processed global messages.
+ *
+ * There are various variants of this packet.
+ *
+ * @code
+ * 008c <packet len>.W <text>.?B (<name> : <message>) 00 (CZ_REQUEST_CHAT)
+ * @endcode
+ *
+ * @param fd The incoming file descriptor.
+ * @param sd The related character.
+ */
+void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+void clif_parse_GlobalMessage(int fd, struct map_session_data *sd)
{
- const char* text = (char*)RFIFOP(fd,4);
- size_t textlen = RFIFOW(fd,2) - 4;
-
- char *name, *message, *fakename = NULL;
- size_t namelen, messagelen;
+ const struct packet_chat_message *packet = NULL;
+ char full_message[CHAT_SIZE_MAX + NAME_LENGTH + 3 + 1];
+ const char *message = NULL;
+ bool is_fakename = false;
+ int outlen = 0;
- bool is_fake;
-
- // validate packet and retrieve name and message
- if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) )
+ packet = RP2PTR(fd);
+ message = clif->process_chat_message(sd, packet, full_message, sizeof full_message);
+ if (message == NULL)
return;
- if( atcommand->exec(fd, sd, message, true) )
- return;
+ pc->check_supernovice_call(sd, message);
- if( !pc->can_talk(sd) )
+ if (sd->gcbind != NULL) {
+ channel->send(sd->gcbind, sd, message);
return;
-
- if( battle_config.min_chat_delay ) { //[Skotlex]
- if (DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0)
- return;
- sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
}
- if( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE ) {
- unsigned int next = pc->nextbaseexp(sd);
- if( next == 0 ) next = pc->thisbaseexp(sd);
- if( next ) { // 0%, 10%, 20%, ...
- int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. );
- if( (battle_config.snovice_call_type || percent) && ( percent%100 ) == 0 ) {// 10.0%, 20.0%, ..., 90.0%
- switch (sd->state.snovice_call_flag) {
- case 0:
- if( strstr(message, msg_txt(1479)) ) // "Dear angel, can you hear my voice?"
- sd->state.snovice_call_flag = 1;
- break;
- case 1: {
- char buf[256];
- snprintf(buf, 256, msg_txt(1480), sd->status.name);
- if( strstr(message, buf) ) // "I am %s Super Novice~"
- sd->state.snovice_call_flag = 2;
- }
- break;
- case 2:
- if( strstr(message, msg_txt(1481)) ) // "Help me out~ Please~ T_T"
- sd->state.snovice_call_flag = 3;
- break;
- case 3:
- sc_start(NULL,&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
- clif->skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions
- sd->state.snovice_call_flag = 0;
- break;
- }
- }
- }
+ if (sd->fakename[0] != '\0') {
+ is_fakename = true;
+ outlen = (int)strlen(sd->fakename) + (int)strlen(message) + 3 + 1;
+ } else {
+ outlen = (int)strlen(full_message) + 1;
}
- pc->update_idle_time(sd, BCIDLE_CHAT);
-
- if( sd->gcbind ) {
- channel->send(sd->gcbind,sd,message);
- return;
- } else if ( sd->fontcolor && !sd->chatID ) {
- char mout[200];
- unsigned char mylen = 1;
+ if (sd->fontcolor != 0 && sd->chat_id == 0) {
uint32 color = 0;
- if( sd->disguise == -1 ) {
+ if (sd->disguise == -1) {
sd->fontcolor_tid = timer->add(timer->gettick()+5000, clif->undisguise_timer, sd->bl.id, 0);
- pc->disguise(sd,sd->status.class_);
- if( pc_isdead(sd) )
+ pc->disguise(sd,sd->status.class);
+ if (pc_isdead(sd))
clif->clearunit_single(-sd->bl.id, CLR_DEAD, sd->fd);
- if( unit->is_walking(&sd->bl) )
+ if (unit->is_walking(&sd->bl))
clif->move(&sd->ud);
- } else if ( sd->disguise == sd->status.class_ && sd->fontcolor_tid != INVALID_TIMER ) {
+ } else if (sd->disguise == sd->status.class && sd->fontcolor_tid != INVALID_TIMER) {
const struct TimerData *td;
- if( (td = timer->get(sd->fontcolor_tid)) ) {
+ if ((td = timer->get(sd->fontcolor_tid)) != NULL)
timer->settick(sd->fontcolor_tid, td->tick+5000);
- }
}
- mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
-
color = channel->config->colors[sd->fontcolor - 1];
- WFIFOHEAD(fd,mylen + 12);
+ WFIFOHEAD(fd, outlen + 12);
WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = mylen + 12;
+ WFIFOW(fd,2) = outlen + 12;
WFIFOL(fd,4) = sd->bl.id;
WFIFOL(fd,8) = RGB2BGR(color);
- safestrncpy((char*)WFIFOP(fd,12), mout, mylen);
+ if (is_fakename)
+ safesnprintf(WFIFOP(fd, 12), outlen, "%s : %s", sd->fakename, message);
+ else
+ safestrncpy(WFIFOP(fd, 12), full_message, outlen);
clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS);
WFIFOL(fd,4) = -sd->bl.id;
- WFIFOSET(fd, mylen + 12);
+ WFIFOSET(fd, outlen + 12);
return;
}
- /**
- * Fake Name Design by FatalEror (bug report #9)
- **/
- if( ( is_fake = ( sd->fakename[0] ) ) ) {
- fakename = (char*) aMalloc(strlen(sd->fakename)+messagelen+3);
- strcpy(fakename, sd->fakename);
- strcat(fakename, " : ");
- strcat(fakename, message);
- textlen = strlen(fakename) + 1;
+ {
+ // send message to others
+ void *buf = aMalloc(8 + outlen);
+ WBUFW(buf, 0) = 0x8d;
+ WBUFW(buf, 2) = 8 + outlen;
+ WBUFL(buf, 4) = sd->bl.id;
+ if (is_fakename)
+ safesnprintf(WBUFP(buf, 8), outlen, "%s : %s", sd->fakename, message);
+ else
+ safestrncpy(WBUFP(buf, 8), full_message, outlen);
+ //FIXME: chat has range of 9 only
+ clif->send(buf, WBUFW(buf, 2), &sd->bl, sd->chat_id != 0 ? CHAT_WOS : AREA_CHAT_WOC);
+ aFree(buf);
}
- // send message to others (using the send buffer for temp. storage)
- WFIFOHEAD(fd, 8 + textlen);
- 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);
- //FIXME: chat has range of 9 only
- clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
// send back message to the speaker
- if( is_fake ) {
- WFIFOW(fd,0) = 0x8e;
- WFIFOW(fd,2) = textlen + 4;
- safestrncpy((char*)WFIFOP(fd,4), fakename, textlen);
- aFree(fakename);
- } else {
- memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
- WFIFOW(fd,0) = 0x8e;
- }
+ WFIFOHEAD(fd, 4 + outlen);
+ WFIFOW(fd, 0) = 0x8e;
+ WFIFOW(fd, 2) = 4 + outlen;
+ if (is_fakename)
+ safesnprintf(WFIFOP(fd, 4), outlen, "%s : %s", sd->fakename, message);
+ else
+ safestrncpy(WFIFOP(fd, 4), full_message, outlen);
WFIFOSET(fd, WFIFOW(fd,2));
// Chat logging type 'O' / Global Chat
logs->chat(LOG_CHAT_GLOBAL, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
// trigger listening npcs
- map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
+ map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, full_message, strlen(full_message), &sd->bl);
}
void clif_parse_MapMove(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -9870,10 +10034,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);
}
@@ -9905,7 +10068,7 @@ void clif_changed_dir(struct block_list *bl, enum send_target target)
clif->send(buf, packet_len(0x9c), bl, target);
- if (disguised(bl)) {
+ if (clif->isdisguised(bl)) {
WBUFL(buf,2) = -bl->id;
WBUFW(buf,6) = 0;
clif->send(buf, packet_len(0x9c), bl, SELF);
@@ -9937,7 +10100,7 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd)
{
int emoticon = RFIFOB(fd,packet_db[RFIFOW(fd,0)].pos[0]);
- if (battle_config.basic_skill_check == 0 || pc->checkskill(sd, NV_BASIC) >= 2) {
+ if (battle_config.basic_skill_check == 0 || pc->check_basicskill(sd, 2)) {
if (emoticon == E_MUTE) {// prevent use of the mute emote [Valaris]
clif->skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1);
return;
@@ -9997,7 +10160,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
sd->sc.data[SC_TRICKDEAD] ||
(sd->sc.data[SC_AUTOCOUNTER] && action_type != 0x07) ||
sd->sc.data[SC_BLADESTOP] ||
- sd->sc.data[SC_DEEP_SLEEP] )
+ sd->sc.data[SC_DEEP_SLEEP] ||
+ sd->sc.data[SC_SUHIDE] )
)
return;
@@ -10024,7 +10188,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
if( sd->sc.option&OPTION_COSTUME )
return;
- if (!battle_config.sdelay_attack_enable && pc->checkskill(sd, SA_FREECAST) <= 0) {
+ if (!battle_config.sdelay_attack_enable && pc->checkskill(sd, SA_FREECAST) <= 0 && (skill->get_inf2(sd->ud.skill_id) & (INF2_FREE_CAST_REDUCED | INF2_FREE_CAST_NORMAL)) == 0) {
if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
clif->skill_fail(sd, 1, USESKILL_FAIL_SKILLINTERVAL, 0);
return;
@@ -10037,7 +10201,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
}
break;
case 0x02: // sitdown
- if (battle_config.basic_skill_check && pc->checkskill(sd, NV_BASIC) < 3) {
+ if (battle_config.basic_skill_check && !pc->check_basicskill(sd, 3)) {
clif->skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 2);
break;
}
@@ -10122,7 +10286,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
case 0x01:
/* Rovert's Prevent logout option - Fixed [Valaris] */
if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK]
- && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY]
+ && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && !sd->sc.data[SC_SUHIDE]
&& (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout)
) {
//Send to char-server for character selection.
@@ -10134,37 +10298,28 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
}
}
-void clif_parse_WisMessage(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
-/// Validates and processes whispered messages (CZ_WHISPER).
-/// 0096 <packet len>.W <nick>.24B <message>.?B
+/**
+ * Validates and processes whispered messages (CZ_WHISPER).
+ *
+ * @code
+ * 0096 <packet len>.W <nick>.24B <message>.?B
+ * @endcode
+ *
+ * @param fd The incoming file descriptor.
+ * @param sd The related character.
+ */
+void clif_parse_WisMessage(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_WisMessage(int fd, struct map_session_data* sd)
{
struct map_session_data* dstsd;
int i;
- char *target, *message;
- size_t namelen, messagelen;
-
- // validate packet and retrieve name and message
- if( !clif->process_message(sd, 1, &target, &namelen, &message, &messagelen) )
- return;
-
- if ( atcommand->exec(fd, sd, message, true) )
- return;
+ char target[NAME_LENGTH], message[CHAT_SIZE_MAX + 1];
+ const struct packet_whisper_message *packet = RP2PTR(fd);
- // Statuses that prevent the player from whispering
- if( !pc->can_talk(sd) )
+ if (!clif->process_whisper_message(sd, packet, target, message, sizeof message))
return;
- if (battle_config.min_chat_delay) { //[Skotlex]
- if (DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0) {
- return;
- }
- sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
- }
-
- pc->update_idle_time(sd, BCIDLE_CHAT);
-
// Chat logging type 'W' / Whisper
logs->chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message);
@@ -10172,7 +10327,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 +10362,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) {
@@ -10216,7 +10371,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
if (k < sd->channel_count || channel->join(chan, sd, "", true) == HCS_STATUS_OK) {
channel->send(chan,sd,message);
} else {
- clif->message(fd, msg_fd(fd,1402));
+ clif->message(fd, msg_fd(fd,1402)); //You're not in that channel, type '@join <#channel_name>'
}
return;
} else if (strcmpi(&chname[1], channel->config->ally_name) == 0) {
@@ -10234,7 +10389,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
// if there are 'Test' player on an other map-server and 'test' player on this map-server,
// and if we ask for 'Test', we must not contact 'test' player
// so, we send information to inter-server, which is the only one which decide (and copy correct name).
- intif->wis_message(sd, target, message, messagelen);
+ intif->wis_message(sd, target, message, (int)strlen(message));
return;
}
@@ -10248,10 +10403,10 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
}
// if player is autotrading
- if( dstsd->state.autotrade ) {
+ if (dstsd->state.autotrade) {
char output[256];
sprintf(output, "%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name);
- clif->wis_message(fd, map->wisp_server_name, output, strlen(output) + 1);
+ clif->wis_message(fd, map->wisp_server_name, output, (int)strlen(output));
return;
}
@@ -10268,22 +10423,29 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
clif->wis_end(fd, 0); // 0: success to send wisper
// Normal message
- clif->wis_message(dstsd->fd, sd->status.name, message, messagelen);
+ clif->wis_message(dstsd->fd, sd->status.name, message, (int)strlen(message));
}
-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);
}
@@ -10312,6 +10474,7 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd)
sd->sc.data[SC_TRICKDEAD] ||
sd->sc.data[SC_BLADESTOP] ||
sd->sc.data[SC_CLOAKINGEXCEED] ||
+ sd->sc.data[SC_SUHIDE] ||
pc_ismuted(&sd->sc, MANNER_NOITEM)
) )
break;
@@ -10378,7 +10541,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
return;
}
- if ( (!sd->npc_id && pc_istrading(sd)) || sd->chatID )
+ if ((!sd->npc_id && pc_istrading(sd)) || sd->chat_id != 0)
return;
//Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex]
@@ -10395,16 +10558,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 +10580,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)));
@@ -10477,9 +10642,11 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
clif->clearunit_area(&sd->bl,CLR_DEAD);
return;
}
- if( sd->npc_id || sd->state.workinprogress&2 ){
-#ifdef RENEWAL
- clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
+ if (sd->npc_id || sd->state.workinprogress & 2) {
+#if PACKETVER >= 20110309
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
+#else
+ clif->messagecolor_self(fd, COLOR_WHITE, msg_fd(fd, 48));
#endif
return;
}
@@ -10492,9 +10659,11 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
clif->pActionRequest_sub(sd, 0x07, bl->id, timer->gettick());
break;
case BL_NPC:
- if( sd->ud.skill_id < RK_ENCHANTBLADE && sd->ud.skilltimer != INVALID_TIMER ) {// TODO: should only work with none 3rd job skills
-#ifdef RENEWAL
+ if (sd->ud.skill_id < RK_ENCHANTBLADE && sd->ud.skilltimer != INVALID_TIMER) { // TODO: should only work with none 3rd job skills
+#if PACKETVER >= 20110309
clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
+#else
+ clif->messagecolor_self(fd, COLOR_WHITE, msg_fd(fd, 48));
#endif
break;
}
@@ -10540,14 +10709,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 +10761,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,14 +10804,14 @@ 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];
if (pc_ismuted(&sd->sc, MANNER_NOROOM))
return;
- if(battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 4) {
+ if(battle_config.basic_skill_check && !pc->check_basicskill(sd, 4)) {
clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,3);
return;
}
@@ -10637,7 +10839,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 +10855,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 +10877,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 +10885,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)));
@@ -10703,10 +10905,10 @@ void clif_noask_sub(struct map_session_data *src, struct map_session_data *targe
nullpo_retv(src);
// Your request has been rejected by autoreject option.
msg = msg_sd(src,392);
- clif_disp_onlyself(src, msg, strlen(msg));
+ clif_disp_onlyself(src, msg);
//Notice that a request was rejected.
snprintf(output, 256, msg_sd(target,393+type), src->status.name, 256);
- clif_disp_onlyself(target, output, strlen(output));
+ clif_disp_onlyself(target, output);
}
void clif_parse_TradeRequest(int fd,struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -10717,7 +10919,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) {
t_sd = map->id2sd(RFIFOL(fd,2));
- if(!sd->chatID && pc_cant_act(sd))
+ if (sd->chat_id == 0 && pc_cant_act(sd))
return; //You can trade while in a chatroom.
// @noask [LuzZza]
@@ -10726,7 +10928,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) {
return;
}
- if( battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 1) {
+ if( battle_config.basic_skill_check && !pc->check_basicskill(sd, 1)) {
clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,0);
return;
}
@@ -10837,39 +11039,38 @@ void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
void clif_parse_ChangeCart(int fd,struct map_session_data *sd) __attribute__((nonnull (2)));
/// Request to change cart's visual look (CZ_REQ_CHANGECART).
/// 01af <num>.W
-void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
+void clif_parse_ChangeCart(int fd, struct map_session_data *sd)
{// TODO: State tracking?
int type;
- if( pc->checkskill(sd, MC_CHANGECART) < 1 )
+ if (pc->checkskill(sd, MC_CHANGECART) == 0)
return;
-#ifdef RENEWAL
- if( sd->npc_id || sd->state.workinprogress&1 ){
+ if (sd->npc_id || sd->state.workinprogress & 1) {
+#if PACKETVER >= 20110309
clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
+#else
+ clif->messagecolor_self(fd, COLOR_WHITE, msg_fd(fd, 48));
+#endif
return;
}
-#endif
- type = (int)RFIFOW(fd,2);
+ type = RFIFOW(fd, 2);
+
+ if (
#ifdef NEW_CARTS
- if( (type == 9 && sd->status.base_level > 131) ||
- (type == 8 && sd->status.base_level > 121) ||
- (type == 7 && sd->status.base_level > 111) ||
- (type == 6 && sd->status.base_level > 101) ||
+ (type == 9 && sd->status.base_level > 130) ||
+ (type == 8 && sd->status.base_level > 120) ||
+ (type == 7 && sd->status.base_level > 110) ||
+ (type == 6 && sd->status.base_level > 100) ||
+#endif
(type == 5 && sd->status.base_level > 90) ||
(type == 4 && sd->status.base_level > 80) ||
(type == 3 && sd->status.base_level > 65) ||
(type == 2 && sd->status.base_level > 40) ||
(type == 1))
-#else
- if( (type == 5 && sd->status.base_level > 90) ||
- (type == 4 && sd->status.base_level > 80) ||
- (type == 3 && sd->status.base_level > 65) ||
- (type == 2 && sd->status.base_level > 40) ||
- (type == 1))
-#endif
- pc->setcart(sd,type);
+
+ pc->setcart(sd, type);
}
/// Request to select cart's visual look for new cart design (CZ_SELECTCART).
@@ -10882,7 +11083,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;
@@ -11056,9 +11257,11 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
// Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
pc->update_idle_time(sd, BCIDLE_USESKILLTOID);
- if( sd->npc_id || sd->state.workinprogress&1 ){
-#ifdef RENEWAL
- clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
+ if (sd->npc_id || sd->state.workinprogress & 1) {
+#if PACKETVER >= 20110309
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
+#else
+ clif->messagecolor_self(fd, COLOR_WHITE, msg_fd(fd, 48));
#endif
return;
}
@@ -11115,7 +11318,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
sd->skillitem = sd->skillitemlv = 0;
- if( skill_id >= GD_SKILLBASE ) {
+ if (skill_id >= GD_SKILLBASE && skill_id < GD_MAX) {
if( sd->state.gmaster_flag )
skill_lv = guild->checkskill(sd->guild, skill_id);
else
@@ -11153,12 +11356,14 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski
return;
}
-#ifdef RENEWAL
- if( sd->state.workinprogress&1 ){
- clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
+ if (sd->state.workinprogress & 1) {
+#if PACKETVER >= 20110309
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
+#else
+ clif->messagecolor_self(fd, COLOR_WHITE, msg_fd(fd, 48));
+#endif
return;
}
-#endif
//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
pc->update_idle_time(sd, BCIDLE_USESKILLTOPOS);
@@ -11171,7 +11376,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 +11469,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 +11630,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;
@@ -11439,9 +11644,14 @@ void clif_parse_NpcStringInput(int fd, struct map_session_data* sd) __attribute_
/// 01d5 <packet len>.W <npc id>.L <string>.?B
void clif_parse_NpcStringInput(int fd, struct map_session_data* sd)
{
- int message_len = RFIFOW(fd,2)-8;
+// [4144] can't confirm exact client version. At least >= correct for 20150513
+#if PACKETVER >= 20151029
+ int message_len = RFIFOW(fd, 2) - 7;
+#else
+ int message_len = RFIFOW(fd, 2) - 8;
+#endif
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
@@ -11489,12 +11699,12 @@ void clif_parse_OneClick_ItemIdentify(int fd, struct map_session_data *sd)
int cmd = RFIFOW(fd,0);
short idx = RFIFOW(fd, packet_db[cmd].pos[0]) - 2;
int n;
-
+
if (idx < 0 || idx >= MAX_INVENTORY || sd->inventory_data[idx] == NULL || sd->status.inventory[idx].nameid <= 0)
return;
-
+
if ((n = pc->have_magnifier(sd) ) != INDEX_NOT_FOUND &&
- pc->delitem(sd, n, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER) == 0)
+ pc->delitem(sd, n, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME) == 0)
skill->identify(sd, idx);
}
@@ -11595,20 +11805,26 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd) {
atcommand->exec(fd, sd, cmd, true);
}
-void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
+void clif_parse_LocalBroadcast(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
/// /lb /nlb (CZ_LOCALBROADCAST).
/// Request to broadcast a message on current map.
/// 019c <packet len>.W <text>.?B
-void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd)
+void clif_parse_LocalBroadcast(int fd, struct map_session_data *sd)
{
- char command[CHAT_SIZE_MAX+16];
- char* msg = (char*)RFIFOP(fd,4);
- unsigned int len = RFIFOW(fd,2)-4;
+ const char commandname[] = "lkami";
+ char command[sizeof commandname + 2 + CHAT_SIZE_MAX] = ""; // '@' + command + ' ' + message + NUL
+ int len = (int)RFIFOW(fd,2) - 4;
- // as the length varies depending on the command used, just block unreasonably long strings
- mes_len_check(msg, len, CHAT_SIZE_MAX);
+ if (len < 0)
+ return;
+
+ sprintf(command, "%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,16 +11971,18 @@ 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.
- clif->message(fd, msg_fd(fd,227));
+ clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map.
return;
}
- if( battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 7 ) {
+ if (battle_config.basic_skill_check && !pc->check_basicskill(sd, 7)) {
clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,4);
return;
}
@@ -11773,18 +11991,20 @@ 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.
- clif->message(fd, msg_fd(fd,227));
+ clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map.
return;
}
- if( battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 7 ) {
+ if (battle_config.basic_skill_check && !pc->check_basicskill(sd, 7)) {
clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,4);
return;
}
@@ -11801,7 +12021,7 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) {
if(map->list[sd->bl.m].flag.partylock) {
// Party locked.
- clif->message(fd, msg_fd(fd,227));
+ clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map.
return;
}
@@ -11816,14 +12036,16 @@ 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.
- clif->message(fd, msg_fd(fd,227));
+ clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map.
return;
}
@@ -11861,7 +12083,7 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd) __attribute__((n
void clif_parse_LeaveParty(int fd, struct map_session_data *sd) {
if(map->list[sd->bl.m].flag.partylock) {
// Party locked.
- clif->message(fd, msg_fd(fd,227));
+ clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map.
return;
}
party->leave(sd);
@@ -11873,10 +12095,10 @@ void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) __attribu
void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) {
if(map->list[sd->bl.m].flag.partylock) {
// Party locked.
- clif->message(fd, msg_fd(fd,227));
+ clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map.
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)));
@@ -11910,36 +12132,26 @@ void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd)
#endif
}
-void clif_parse_PartyMessage(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
-/// Validates and processes party messages (CZ_REQUEST_CHAT_PARTY).
-/// 0108 <packet len>.W <text>.?B (<name> : <message>) 00
-void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
+/**
+ * Validates and processes party messages (CZ_REQUEST_CHAT_PARTY).
+ *
+ * @code
+ * 0108 <packet len>.W <text>.?B (<name> : <message>) 00
+ * @endcode
+ *
+ * @param fd The incoming file descriptor.
+ * @param sd The related character.
+ */
+void clif_parse_PartyMessage(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+void clif_parse_PartyMessage(int fd, struct map_session_data *sd)
{
- const char* text = (char*)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
+ const struct packet_chat_message *packet = RP2PTR(fd);
+ char message[CHAT_SIZE_MAX + NAME_LENGTH + 3 + 1];
- char *name, *message;
- size_t namelen, messagelen;
-
- // validate packet and retrieve name and message
- if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) )
- return;
-
- if( atcommand->exec(fd, sd, message, true) )
+ if (clif->process_chat_message(sd, packet, message, sizeof message) == NULL)
return;
- if( !pc->can_talk(sd) )
- return;
-
- if (battle_config.min_chat_delay) {
- if (DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0)
- return;
- sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
- }
-
- pc->update_idle_time(sd, BCIDLE_CHAT);
-
- party->send_message(sd, text, textlen);
+ party->send_message(sd, message);
}
void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -12173,7 +12385,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 +12508,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
@@ -12417,7 +12627,7 @@ void clif_PartyBookingVolunteerInfo(int index, struct map_session_data *sd)
nullpo_retv(sd);
WBUFW(buf, 0) = 0x8f2;
WBUFL(buf, 2) = sd->status.account_id;
- WBUFL(buf, 6) = sd->status.class_;
+ WBUFL(buf, 6) = sd->status.class;
WBUFW(buf, 10) = sd->status.base_level;
memcpy(WBUFP(buf, 12), sd->status.name, NAME_LENGTH);
@@ -12599,8 +12809,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 +12824,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 +12843,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,13 +12870,13 @@ 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.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
@@ -12717,7 +12927,7 @@ void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd)
clif->guild_expulsionlist(sd);
break;
default:
- ShowError("clif: guild request info: unknown type %d\n", RFIFOL(fd,2));
+ ShowError("clif: guild request info: unknown type %u\n", RFIFOL(fd,2));
break;
}
}
@@ -12733,7 +12943,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));
}
}
@@ -12782,7 +12992,7 @@ bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len) {
//uint8 b;
//uint8 g;
//uint8 r;
- unsigned int rgb:24;
+ uint32 rgb:24;
} __attribute__((packed));
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
@@ -12792,7 +13002,8 @@ bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len) {
int header = 0, bitmap = 0, offbits = 0, palettesize = 0;
nullpo_retr(false, emblem);
- if( decode_zip(buf, &buf_len, emblem, emblem_len) != 0 || buf_len < BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE
+ if (grfio->decode_zip(buf, &buf_len, emblem, emblem_len) != 0
+ || buf_len < BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE
|| RBUFW(buf,0) != 0x4d42 // BITMAPFILEHEADER.bfType (signature)
|| RBUFL(buf,2) != buf_len // BITMAPFILEHEADER.bfSize (file size)
|| RBUFL(buf,14) != BITMAPINFOHEADER_SIZE // BITMAPINFOHEADER.biSize (other headers are not supported)
@@ -12848,8 +13059,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 +13078,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 +13126,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
@@ -12937,8 +13152,7 @@ bool clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_sessi
nullpo_retr(false, sd);
nullpo_retr(false, t_sd);
if ( map->list[sd->bl.m].flag.guildlock ) {
- //Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return false;
}
@@ -12964,14 +13178,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)));
@@ -12990,8 +13205,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd) __attribute__((no
/// 0159 <guild id>.L <account id>.L <char id>.L <reason>.40B
void clif_parse_GuildLeave(int fd,struct map_session_data *sd) {
if(map->list[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
if( sd->bg_id ) {
@@ -12999,7 +13213,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)));
@@ -13007,46 +13221,35 @@ void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd) __attribute__
/// 015b <guild id>.L <account id>.L <char id>.L <reason>.40B
void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd) {
if( map->list[sd->bl.m].flag.guildlock || sd->bg_id ) {
- // Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
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)));
-/// Validates and processes guild messages (CZ_GUILD_CHAT).
-/// 017e <packet len>.W <text>.?B (<name> : <message>) 00
-void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
+/**
+ * Validates and processes guild messages (CZ_GUILD_CHAT).
+ *
+ * @code
+ * 017e <packet len>.W <text>.?B (<name> : <message>) 00
+ * @endcode
+ *
+ * @param fd The incoming file descriptor.
+ * @param sd The related character.
+ */
+void clif_parse_GuildMessage(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+void clif_parse_GuildMessage(int fd, struct map_session_data *sd)
{
- const char* text = (char*)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
+ const struct packet_chat_message *packet = RP2PTR(fd);
+ char message[CHAT_SIZE_MAX + NAME_LENGTH + 3 + 1];
- char *name, *message;
- size_t namelen, messagelen;
-
- // validate packet and retrieve name and message
- if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) )
- return;
-
- if( atcommand->exec(fd, sd, message, true) )
- return;
-
- if( !pc->can_talk(sd) )
+ if (clif->process_chat_message(sd, packet, message, sizeof message) == NULL)
return;
- if (battle_config.min_chat_delay) {
- if (DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0)
- return;
- sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
- }
-
- pc->update_idle_time(sd, BCIDLE_CHAT);
-
- if( sd->bg_id )
- bg->send_message(sd, text, textlen);
+ if (sd->bg_id)
+ bg->send_message(sd, message);
else
- guild->send_message(sd, text, textlen);
+ guild->send_message(sd, message);
}
void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -13059,8 +13262,7 @@ void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) {
return;
if(map->list[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
@@ -13097,8 +13299,7 @@ void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) {
return;
if(map->list[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
guild->delalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
@@ -13114,8 +13315,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) {
return;
if(map->list[sd->bl.m].flag.guildlock) {
- //Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
@@ -13138,11 +13338,10 @@ void clif_parse_GuildBreak(int fd, struct map_session_data *sd) __attribute__((n
/// field name and size is same as the one in CH_DELETE_CHAR.
void clif_parse_GuildBreak(int fd, struct map_session_data *sd) {
if( map->list[sd->bl.m].flag.guildlock ) {
- //Guild locked.
- clif->message(fd, msg_fd(fd,228));
+ clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
- guild->dobreak(sd,(char*)RFIFOP(fd,2));
+ guild->dobreak(sd, RFIFOP(fd,2));
}
/// Pet
@@ -13218,7 +13417,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)));
@@ -13241,7 +13440,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) {
case BL_PC:
{
char command[NAME_LENGTH+6];
- sprintf(command, "%ckick %s", atcommand->at_symbol, status->get_name(target));
+ sprintf(command, "%ckick %s", atcommand->at_symbol, clif->get_bl_name(target));
atcommand->exec(fd, sd, command, true);
}
break;
@@ -13256,7 +13455,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) {
clif->GM_kickack(sd, 0);
return;
}
- sprintf(command, "/kick %s (%d)", status->get_name(target), status->get_class(target));
+ sprintf(command, "/kick %s (%d)", clif->get_bl_name(target), status->get_class(target));
logs->atcommand(sd, command);
status_percent_damage(&sd->bl, target, 100, 0, true); // can invalidate 'target'
}
@@ -13299,12 +13498,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 +13534,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 +13575,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 +13705,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 +13723,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 +13767,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)
@@ -13682,12 +13883,13 @@ void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd)
{
if (sd->state.doridori) return;
- switch (sd->class_&MAPID_UPPERMASK) {
+ switch (sd->job & MAPID_UPPERMASK) {
case MAPID_SOUL_LINKER:
case MAPID_STAR_GLADIATOR:
case MAPID_TAEKWON:
if (!sd->state.rest)
break;
+ FALLTHROUGH
case MAPID_SUPER_NOVICE:
sd->state.doridori=1;
break;
@@ -13709,7 +13911,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
/* game client is currently broken on this (not sure the packetver range) */
/* it sends the request when the criteria doesn't match (and of course we let it fail) */
/* so restoring the old parse_globalmes method. */
- if( ( sd->class_&MAPID_UPPERMASK ) == MAPID_SUPER_NOVICE ) {
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
unsigned int next = pc->nextbaseexp(sd);
if( next == 0 ) next = pc->thisbaseexp(sd);
if( next ) {
@@ -13831,12 +14033,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
@@ -13849,7 +14053,7 @@ void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) {
// Friend doesn't exist (no player with this name)
if (f_sd == NULL) {
- clif->message(fd, msg_fd(fd,3));
+ clif->message(fd, msg_fd(fd,3)); // "Character not found."
return;
}
@@ -14055,46 +14259,43 @@ 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;
}
}
/// 097d <RankingType>.W {<CharName>.24B <point>L}*10 <mypoint>L (ZC_ACK_RANKING)
-void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) {
+void clif_ranklist(struct map_session_data *sd, enum fame_list_type type)
+{
+#if PACKETVER >= 20120502
int fd;
- int mypoint = 0;
- int upperMask;
+ int len = packet_len(0x97d);
nullpo_retv(sd);
fd = sd->fd;
- upperMask = sd->class_&MAPID_UPPERMASK;
- WFIFOHEAD(fd, 288);
+ WFIFOHEAD(fd, len);
WFIFOW(fd, 0) = 0x97d;
WFIFOW(fd, 2) = type;
clif_ranklist_sub(WFIFOP(fd,4), type);
- if( (upperMask == MAPID_BLACKSMITH && type == RANKTYPE_BLACKSMITH)
- || (upperMask == MAPID_ALCHEMIST && type == RANKTYPE_ALCHEMIST)
- || (upperMask == MAPID_TAEKWON && type == RANKTYPE_TAEKWON)
- ) {
- mypoint = sd->status.fame;
+ if (pc->famelist_type(sd->job) == type) {
+ WFIFOL(fd, 284) = sd->status.fame; //mypoint
} else {
- mypoint = 0;
+ WFIFOL(fd, 284) = 0; //mypoint
}
- WFIFOL(fd, 284) = mypoint; //mypoint
- WFIFOSET(fd, 288);
+ WFIFOSET(fd, len);
+#endif
}
void clif_parse_ranklist(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -14114,8 +14315,9 @@ void clif_parse_ranklist(int fd, struct map_session_data *sd) {
}
// 097e <RankingType>.W <point>.L <TotalPoint>.L (ZC_UPDATE_RANKING_POINT)
-void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list_type type, int points) {
-#if PACKETVER < 20130710
+void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list_type type, int points)
+{
+#if PACKETVER < 20120502
switch( type ) {
case RANKTYPE_BLACKSMITH: clif->fame_blacksmith(sd,points); break;
case RANKTYPE_ALCHEMIST: clif->fame_alchemist(sd,points); break;
@@ -14124,15 +14326,16 @@ void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list_type t
#else
int fd;
+ int len = packet_len(0x97e);
nullpo_retv(sd);
fd = sd->fd;
- WFIFOHEAD(fd, 12);
+ WFIFOHEAD(fd, len);
WFIFOW(fd, 0) = 0x97e;
WFIFOW(fd, 2) = type;
WFIFOL(fd, 4) = points;
WFIFOL(fd, 8) = sd->status.fame;
- WFIFOSET(fd, 12);
+ WFIFOSET(fd, len);
#endif
}
@@ -14248,7 +14451,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 +14511,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 +14680,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 +14771,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));
}
@@ -14623,7 +14827,7 @@ void clif_Mail_refreshinbox(struct map_session_data *sd)
if( md->full ) {// TODO: is this official?
char output[100];
sprintf(output, "Inbox is full (Max %d). Delete some mails.", MAIL_MAX_INBOX);
- clif_disp_onlyself(sd, output, strlen(output));
+ clif_disp_onlyself(sd, output);
}
}
@@ -14661,11 +14865,16 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
struct mail_message *msg = &sd->mail.inbox.msg[i];
struct item *item = &msg->item;
struct item_data *data;
- size_t msg_len = strlen(msg->body), len;
+ int msg_len = (int)strlen(msg->body), len;
- if( msg_len == 0 ) {
+ if (msg_len == 0) {
strcpy(msg->body, "(no message)");
- msg_len = strlen(msg->body);
+ msg_len = (int)strlen(msg->body);
+ }
+
+ if (msg_len > UINT8_MAX) {
+ Assert_report(msg_len > UINT8_MAX);
+ msg_len = UINT8_MAX;
}
len = 101 + msg_len;
@@ -14674,8 +14883,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;
@@ -14693,8 +14902,8 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
} else // no item, set all to zero
memset(WFIFOP(fd,80), 0x00, 19);
- WFIFOB(fd,99) = (unsigned char)msg_len;
- safestrncpy((char*)WFIFOP(fd,100), msg->body, msg_len + 1);
+ WFIFOB(fd,99) = (uint8)msg_len;
+ safestrncpy(WFIFOP(fd,100), msg->body, msg_len + 1);
WFIFOSET(fd,len);
if (msg->status == MAIL_UNREAD) {
@@ -14727,7 +14936,6 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
{
int mail_id = RFIFOL(fd,2);
int i;
- bool fail = false;
if( !chrif->isconnected() )
return;
@@ -14751,6 +14959,7 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
if( sd->mail.inbox.msg[i].item.nameid > 0 ) {
struct item_data *data;
unsigned int weight;
+ bool fail = false;
if ((data = itemdb->exists(sd->mail.inbox.msg[i].item.nameid)) == NULL)
return;
@@ -14919,15 +15128,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 +15176,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 +15195,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 +15213,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));
@@ -15111,10 +15320,10 @@ void clif_Auction_message(int fd, unsigned char flag)
/// 2 = Auction ID is incorrect
void clif_Auction_close(int fd, unsigned char flag)
{
- WFIFOHEAD(fd,packet_len(0x25e));
+ WFIFOHEAD(fd, 4);
WFIFOW(fd,0) = 0x25d; // BUG: The client identifies this packet as 0x25d (CZ_AUCTION_REQ_MY_SELL_STOP)
WFIFOW(fd,2) = flag;
- WFIFOSET(fd,packet_len(0x25e));
+ WFIFOSET(fd, 4);
}
void clif_parse_Auction_register(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -15188,7 +15397,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
// Auction checks...
if( sd->status.inventory[sd->auction.index].bound && !pc_can_give_bound_items(sd) ) {
- clif->message(sd->fd, msg_sd(sd,293));
+ clif->message(sd->fd, msg_sd(sd,293)); // This bound item cannot be traded to that character.
clif->auction_message(fd, 2); // The auction has been canceled
return;
}
@@ -15241,7 +15450,7 @@ void clif_parse_Auction_bid(int fd, struct map_session_data *sd)
int bid = RFIFOL(fd,6);
if( !pc_can_give_items(sd) ) { //They aren't supposed to give zeny [Inkfish]
- clif->message(sd->fd, msg_sd(sd,246));
+ clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action.
return;
}
@@ -15278,7 +15487,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 +15623,25 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
int len = RFIFOW(fd,2);
int points = RFIFOL(fd,4);
int count = RFIFOW(fd,8);
- unsigned short* item_list = (unsigned short*)RFIFOP(fd,10);
+ struct itemlist item_list = { 0 };
+ int i;
if( len < 10 || len != 10 + count * 4) {
- ShowWarning("Player %u sent incorrect cash shop buy packet (len %u:%u)!\n", sd->status.char_id, len, 10 + count * 4);
+ ShowWarning("Player %d sent incorrect cash shop buy packet (len %d:%d)!\n", sd->status.char_id, len, 10 + count * 4);
return;
}
- fail = npc->cashshop_buylist(sd,points,count,item_list);
+ VECTOR_INIT(item_list);
+ VECTOR_ENSURE(item_list, count, 1);
+ for (i = 0; i < count; i++) {
+ struct itemlist_entry entry = { 0 };
+
+ entry.amount = RFIFOW(fd, 10 + 4 * i);
+ entry.id = RFIFOW(fd, 10 + 4 * i + 2); // Nameid
+
+ VECTOR_PUSH(item_list, entry);
+ }
+ fail = npc->cashshop_buylist(sd, points, &item_list);
+ VECTOR_CLEAR(item_list);
#endif
}
@@ -15539,7 +15760,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 +15792,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 +15826,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 +16136,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 +16178,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;
}
@@ -16028,28 +16249,46 @@ void clif_readbook(int fd, int book_id, int page)
/// Battlegrounds
///
-/// Updates HP bar of a camp member (ZC_BATTLEFIELD_NOTIFY_HP).
-/// 02e0 <account id>.L <name>.24B <hp>.W <max hp>.W
+/// Updates HP bar of a camp member.
+/// 02e0 <account id>.L <name>.24B <hp>.W <max hp>.W (ZC_BATTLEFIELD_NOTIFY_HP).
+/// 0a0e <account id>.L <hp>.L <max hp>.L (ZC_BATTLEFIELD_NOTIFY_HP2)
void clif_bg_hp(struct map_session_data *sd)
{
unsigned char buf[34];
+
+// packet version can be wrong, because inconsistend data in other servers. From packets table it start from 20140312 [4144]
+#if PACKETVER < 20140613
const int cmd = 0x2e0;
nullpo_retv(sd);
- WBUFW(buf,0) = cmd;
- WBUFL(buf,2) = sd->status.account_id;
- memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH);
+ WBUFW(buf, 0) = cmd;
+ WBUFL(buf, 2) = sd->status.account_id;
+ memcpy(WBUFP(buf, 6), sd->status.name, NAME_LENGTH);
- if( sd->battle_status.max_hp > INT16_MAX )
+ if (sd->battle_status.max_hp > INT16_MAX)
{ // To correctly display the %hp bar. [Skotlex]
- WBUFW(buf,30) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
- WBUFW(buf,32) = 100;
+ WBUFW(buf, 30) = sd->battle_status.hp / (sd->battle_status.max_hp / 100);
+ WBUFW(buf, 32) = 100;
}
else
{
- WBUFW(buf,30) = sd->battle_status.hp;
- WBUFW(buf,32) = sd->battle_status.max_hp;
+ WBUFW(buf, 30) = sd->battle_status.hp;
+ WBUFW(buf, 32) = sd->battle_status.max_hp;
}
+#else
+ const int cmd = 0xa0e;
+ nullpo_retv(sd);
+
+ WBUFW(buf, 0) = cmd;
+ WBUFL(buf, 2) = sd->status.account_id;
+ if (sd->battle_status.max_hp > INT32_MAX) {
+ WBUFL(buf, 6) = sd->battle_status.hp / (sd->battle_status.max_hp / 100);
+ WBUFL(buf, 10) = 100;
+ } else {
+ WBUFL(buf, 6) = sd->battle_status.hp;
+ WBUFL(buf, 10) = sd->battle_status.max_hp;
+ }
+#endif
clif->send(buf, packet_len(cmd), &sd->bl, BG_AREA_WOS);
}
@@ -16064,7 +16303,7 @@ void clif_bg_xy(struct map_session_data *sd)
WBUFW(buf,0)=0x2df;
WBUFL(buf,2)=sd->status.account_id;
memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH);
- WBUFW(buf,30)=sd->status.class_;
+ WBUFW(buf,30)=sd->status.class;
WBUFW(buf,32)=sd->bl.x;
WBUFW(buf,34)=sd->bl.y;
@@ -16088,58 +16327,53 @@ void clif_bg_xy_remove(struct map_session_data *sd)
/// Notifies clients of a battleground message (ZC_BATTLEFIELD_CHAT).
/// 02dc <packet len>.W <account id>.L <name>.24B <message>.?B
-void clif_bg_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes, size_t len)
+void clif_bg_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes)
{
struct map_session_data *sd;
unsigned char *buf;
+ int len;
nullpo_retv(bgd);
nullpo_retv(name);
nullpo_retv(mes);
- if( !bgd->count || (sd = bg->getavailablesd(bgd)) == NULL )
+
+ if (!bgd->count || (sd = bg->getavailablesd(bgd)) == NULL)
return;
+ len = (int)strlen(mes);
+ Assert_retv(len <= INT16_MAX - NAME_LENGTH - 8);
buf = (unsigned char*)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char));
WBUFW(buf,0) = 0x2dc;
WBUFW(buf,2) = len + NAME_LENGTH + 8;
WBUFL(buf,4) = src_id;
memcpy(WBUFP(buf,8), name, NAME_LENGTH);
- memcpy(WBUFP(buf,32), mes, len);
+ memcpy(WBUFP(buf,32), mes, len); // [!] no NUL terminator
clif->send(buf,WBUFW(buf,2), &sd->bl, BG);
aFree(buf);
}
-void clif_parse_BattleChat(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
-/// Validates and processes battlechat messages [pakpil] (CZ_BATTLEFIELD_CHAT).
-/// 0x2db <packet len>.W <text>.?B (<name> : <message>) 00
-void clif_parse_BattleChat(int fd, struct map_session_data* sd)
+/**
+ * Validates and processes battlechat messages [pakpil] (CZ_BATTLEFIELD_CHAT).
+ *
+ * @code
+ * 0x2db <packet len>.W <text>.?B (<name> : <message>) 00
+ * @endcode
+ *
+ * @param fd The incoming file descriptor.
+ * @param sd The related character.
+ */
+void clif_parse_BattleChat(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+void clif_parse_BattleChat(int fd, struct map_session_data *sd)
{
- const char* text = (char*)RFIFOP(fd,4);
- int textlen = RFIFOW(fd,2) - 4;
+ const struct packet_chat_message *packet = RP2PTR(fd);
+ char message[CHAT_SIZE_MAX + NAME_LENGTH + 3 + 1];
- char *name, *message;
- size_t namelen, messagelen;
-
- if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) )
- return;
-
- if( atcommand->exec(fd, sd, message, true) )
+ if (clif->process_chat_message(sd, packet, message, sizeof message) == NULL)
return;
- if( !pc->can_talk(sd) )
- return;
-
- if( battle_config.min_chat_delay ) {
- if( DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0 )
- return;
- sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
- }
-
- pc->update_idle_time(sd, BCIDLE_CHAT);
-
- bg->send_message(sd, text, textlen);
+ bg->send_message(sd, message);
}
/// Notifies client of a battleground score change (ZC_BATTLEFIELD_NOTIFY_POINT).
@@ -16179,7 +16413,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 +16424,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 +16636,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;
@@ -16498,6 +16747,7 @@ void clif_elemental_info(struct map_session_data *sd) {
/// 0810 <slots>.B
void clif_buyingstore_open(struct map_session_data* sd)
{
+#if PACKETVER >= 20100303
int fd;
nullpo_retv(sd);
@@ -16506,6 +16756,7 @@ void clif_buyingstore_open(struct map_session_data* sd)
WFIFOW(fd,0) = 0x810;
WFIFOB(fd,2) = sd->buyingstore.slots;
WFIFOSET(fd,packet_len(0x810));
+#endif
}
void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -16516,7 +16767,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;
@@ -16528,13 +16779,13 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) {
// TODO: Make this check global for all variable length packets.
if( packet_len < 89 )
{// minimum packet length
- ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89, packet_len, sd->bl.id);
+ ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89U, packet_len, sd->bl.id);
return;
}
zenylimit = RFIFOL(fd,info->pos[1]);
result = RFIFOL(fd,info->pos[2]);
- safestrncpy(storename, (const char*)RFIFOP(fd,info->pos[3]), sizeof(storename));
+ safestrncpy(storename, RFIFOP(fd,info->pos[3]), sizeof(storename));
itemlist = RFIFOP(fd,info->pos[4]);
// so that buyingstore_create knows, how many elements it has access to
@@ -16559,6 +16810,7 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) {
/// ? = nothing
void clif_buyingstore_open_failed(struct map_session_data* sd, unsigned short result, unsigned int weight)
{
+#if PACKETVER >= 20100420
int fd;
nullpo_retv(sd);
@@ -16568,6 +16820,7 @@ void clif_buyingstore_open_failed(struct map_session_data* sd, unsigned short re
WFIFOW(fd,2) = result;
WFIFOL(fd,4) = weight;
WFIFOSET(fd,packet_len(0x812));
+#endif
}
/// Notification, that the requested buying store was created (ZC_MYITEMLIST_BUYING_STORE).
@@ -16600,6 +16853,7 @@ void clif_buyingstore_myitemlist(struct map_session_data* sd)
/// 0814 <account id>.L <store name>.80B
void clif_buyingstore_entry(struct map_session_data* sd)
{
+#if PACKETVER >= 20100420
uint8 buf[86];
nullpo_retv(sd);
@@ -16608,9 +16862,11 @@ void clif_buyingstore_entry(struct map_session_data* sd)
memcpy(WBUFP(buf,6), sd->message, MESSAGE_SIZE);
clif->send(buf, packet_len(0x814), &sd->bl, AREA_WOS);
+#endif
}
void clif_buyingstore_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd)
{
+#if PACKETVER >= 20100420
int fd;
nullpo_retv(sd);
@@ -16620,6 +16876,7 @@ void clif_buyingstore_entry_single(struct map_session_data* sd, struct map_sessi
WFIFOL(fd,2) = pl_sd->bl.id;
memcpy(WFIFOP(fd,6), pl_sd->message, MESSAGE_SIZE);
WFIFOSET(fd,packet_len(0x814));
+#endif
}
void clif_parse_ReqCloseBuyingStore(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -16633,6 +16890,7 @@ void clif_parse_ReqCloseBuyingStore(int fd, struct map_session_data* sd) {
/// 0816 <account id>.L
void clif_buyingstore_disappear_entry(struct map_session_data* sd)
{
+#if PACKETVER >= 20100309
uint8 buf[6];
nullpo_retv(sd);
@@ -16640,9 +16898,12 @@ void clif_buyingstore_disappear_entry(struct map_session_data* sd)
WBUFL(buf,2) = sd->bl.id;
clif->send(buf, packet_len(0x816), &sd->bl, AREA_WOS);
+#endif
}
+
void clif_buyingstore_disappear_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd)
{
+#if PACKETVER >= 20100309
int fd;
nullpo_retv(sd);
@@ -16652,6 +16913,7 @@ void clif_buyingstore_disappear_entry_single(struct map_session_data* sd, struct
WFIFOW(fd,0) = 0x816;
WFIFOL(fd,2) = pl_sd->bl.id;
WFIFOSET(fd,packet_len(0x816));
+#endif
}
/// Request to open someone else's buying store (CZ_REQ_CLICK_TO_BUYING_STORE).
@@ -16698,7 +16960,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)];
@@ -16707,7 +16969,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) {
if( packet_len < 12 )
{// minimum packet length
- ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12, packet_len, sd->bl.id);
+ ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12U, packet_len, sd->bl.id);
return;
}
@@ -16720,7 +16982,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) {
if( packet_len%blocksize )
{
- ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%u, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize);
+ ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%d, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize);
return;
}
count = packet_len/blocksize;
@@ -16736,6 +16998,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) {
/// ? = nothing
void clif_buyingstore_trade_failed_buyer(struct map_session_data* sd, short result)
{
+#if PACKETVER >= 20100420
int fd;
nullpo_retv(sd);
@@ -16744,22 +17007,36 @@ void clif_buyingstore_trade_failed_buyer(struct map_session_data* sd, short resu
WFIFOW(fd,0) = 0x81a;
WFIFOW(fd,2) = result;
WFIFOSET(fd,packet_len(0x81a));
+#endif
}
/// Updates the zeny limit and an item in the buying store item list (ZC_UPDATE_ITEM_FROM_BUYING_STORE).
/// 081b <name id>.W <amount>.W <limit zeny>.L
-void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short nameid, unsigned short amount)
+void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short nameid, unsigned short amount, uint32 char_id, int zeny)
{
int fd;
+#if PACKETVER < 20141016 // TODO : not sure for client date [Napster]
+ const int cmd = 0x81b;
+#else
+ const int cmd = 0x9e6;
+#endif
+ const int len = packet_len(cmd);
nullpo_retv(sd);
fd = sd->fd;
- WFIFOHEAD(fd,packet_len(0x81b));
- WFIFOW(fd,0) = 0x81b;
- WFIFOW(fd,2) = nameid;
- WFIFOW(fd,4) = amount; // amount of nameid received
- WFIFOL(fd,6) = sd->buyingstore.zenylimit;
- WFIFOSET(fd,packet_len(0x81b));
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = cmd;
+ WFIFOW(fd, 2) = nameid;
+ WFIFOW(fd, 4) = amount; // amount of nameid received
+#if PACKETVER < 20141016
+ WFIFOL(fd, 6) = sd->buyingstore.zenylimit;
+#else
+ WFIFOL(fd, 6) = zeny; // zeny
+ WFIFOL(fd, 10) = sd->buyingstore.zenylimit;
+ WFIFOL(fd, 14) = char_id; // GID
+ WFIFOL(fd, 18) = (int)time(NULL); // date
+#endif
+ WFIFOSET(fd, len);
}
/// Deletes item from inventory, that was sold to a buying store (ZC_ITEM_DELETE_BUYING_STORE).
@@ -16770,6 +17047,7 @@ void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short na
/// NOTE: This function has to be called _instead_ of clif_delitem/clif_dropitem.
void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsigned short amount, int price)
{
+#if PACKETVER >= 20100420
int fd;
nullpo_retv(sd);
@@ -16780,6 +17058,7 @@ void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsi
WFIFOW(fd,4) = amount;
WFIFOL(fd,6) = price; // price per item, client calculates total Zeny by itself
WFIFOSET(fd,packet_len(0x81c));
+#endif
}
/// Notifies the seller, that a buying store trade failed (ZC_FAILED_TRADE_BUYING_STORE_TO_SELLER).
@@ -16791,6 +17070,7 @@ void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsi
/// ? = nothing
void clif_buyingstore_trade_failed_seller(struct map_session_data* sd, short result, unsigned short nameid)
{
+#if PACKETVER >= 20100420
int fd;
nullpo_retv(sd);
@@ -16800,6 +17080,7 @@ void clif_buyingstore_trade_failed_seller(struct map_session_data* sd, short res
WFIFOW(fd,2) = result;
WFIFOW(fd,4) = nameid;
WFIFOSET(fd,packet_len(0x824));
+#endif
}
void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -16827,7 +17108,7 @@ void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd) {
if( packet_len < 15 )
{// minimum packet length
- ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15, packet_len, sd->bl.id);
+ ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15U, packet_len, sd->bl.id);
return;
}
@@ -16919,6 +17200,7 @@ void clif_search_store_info_ack(struct map_session_data* sd)
/// 4 = "No sale (purchase) information available." (0x705)
void clif_search_store_info_failed(struct map_session_data* sd, unsigned char reason)
{
+#if PACKETVER >= 20100601
int fd;
nullpo_retv(sd);
@@ -16927,6 +17209,7 @@ void clif_search_store_info_failed(struct map_session_data* sd, unsigned char re
WFIFOW(fd,0) = 0x837;
WFIFOB(fd,2) = reason;
WFIFOSET(fd,packet_len(0x837));
+#endif
}
void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -16944,6 +17227,7 @@ void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data* sd)
/// 1 = Search Stores (Cash), asks for confirmation, when clicking a store
void clif_open_search_store_info(struct map_session_data* sd)
{
+#if PACKETVER >= 20100608
int fd;
nullpo_retv(sd);
@@ -16955,6 +17239,7 @@ void clif_open_search_store_info(struct map_session_data* sd)
WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
#endif
WFIFOSET(fd,packet_len(0x83a));
+#endif
}
void clif_parse_CloseSearchStoreInfo(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -16985,6 +17270,7 @@ void clif_parse_SearchStoreInfoListItemClick(int fd, struct map_session_data* sd
/// 083d <xPos>.W <yPos>.W
void clif_search_store_info_click_ack(struct map_session_data* sd, short x, short y)
{
+#if PACKETVER >= 20100608
int fd;
nullpo_retv(sd);
@@ -16994,6 +17280,7 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
WFIFOW(fd,2) = x;
WFIFOW(fd,4) = y;
WFIFOSET(fd,packet_len(0x83d));
+#endif
}
/// Parse function for packet debugging.
@@ -17009,10 +17296,10 @@ void clif_parse_debug(int fd,struct map_session_data *sd) {
if( packet_len == -1 ) {// variable length
packet_len = RFIFOW(fd,2); // clif_parse ensures, that this amount of data is already received
}
- ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
+ ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", (unsigned int)cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id);
} else {
packet_len = (int)RFIFOREST(fd);
- ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", cmd, packet_len, fd);
+ ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", (unsigned int)cmd, packet_len, fd);
}
ShowDump(RFIFOP(fd,0), packet_len);
@@ -17262,6 +17549,7 @@ void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) {
*------------------------------------------*/
void clif_charm(struct map_session_data *sd)
{
+#if PACKETVER >= 20110809
unsigned char buf[10];
nullpo_retv(sd);
@@ -17271,6 +17559,7 @@ void clif_charm(struct map_session_data *sd)
WBUFW(buf,6) = sd->charm_type;
WBUFW(buf,8) = sd->charm_count;
clif->send(buf,packet_len(0x08cf),&sd->bl,AREA);
+#endif
}
void clif_parse_MoveItem(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -17308,8 +17597,8 @@ void clif_parse_MoveItem(int fd, struct map_session_data *sd) {
/* [Ind/Hercules] */
void clif_cashshop_db(void) {
- config_t cashshop_conf;
- config_setting_t *cashshop = NULL, *cats = NULL;
+ struct config_t cashshop_conf;
+ struct config_setting_t *cashshop = NULL, *cats = NULL;
const char *config_filename = "db/cashshop_db.conf"; // FIXME hardcoded name
int i, item_count_t = 0;
for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) {
@@ -17317,16 +17606,14 @@ void clif_cashshop_db(void) {
clif->cs.item_count[i] = 0;
}
- if (libconfig->read_file(&cashshop_conf, config_filename)) {
- ShowError("can't read %s\n", config_filename);
+ if (!libconfig->load_file(&cashshop_conf, config_filename))
return;
- }
cashshop = libconfig->lookup(&cashshop_conf, "cash_shop");
if( cashshop != NULL && (cats = libconfig->setting_get_elem(cashshop, 0)) != NULL ) {
for(i = 0; i < CASHSHOP_TAB_MAX; i++) {
- config_setting_t *cat;
+ struct config_setting_t *cat;
char entry_name[10];
sprintf(entry_name,"cat_%d",i);
@@ -17335,7 +17622,7 @@ void clif_cashshop_db(void) {
int k, item_count = libconfig->setting_length(cat);
for(k = 0; k < item_count; k++) {
- config_setting_t *entry = libconfig->setting_get_elem(cat,k);
+ struct config_setting_t *entry = libconfig->setting_get_elem(cat,k);
const char *name = config_setting_name(entry);
int price = libconfig->setting_get_int(entry);
struct item_data * data = NULL;
@@ -17374,6 +17661,7 @@ void clif_cashshop_db(void) {
/// Items that are in favorite tab of inventory (ZC_ITEM_FAVORITE).
/// 0900 <index>.W <favorite>.B
void clif_favorite_item(struct map_session_data* sd, unsigned short index) {
+#if PACKETVER >= 20120410
int fd;
nullpo_retv(sd);
@@ -17383,9 +17671,11 @@ void clif_favorite_item(struct map_session_data* sd, unsigned short index) {
WFIFOW(fd,2) = index+2;
WFIFOB(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1;
WFIFOSET(fd,packet_len(0x908));
+#endif
}
void clif_snap( struct block_list *bl, short x, short y ) {
+#if PACKETVER >= 20110809
unsigned char buf[10];
nullpo_retv(bl);
@@ -17395,9 +17685,12 @@ void clif_snap( struct block_list *bl, short x, short y ) {
WBUFW(buf,8) = y;
clif->send(buf,packet_len(0x8d2),bl,AREA);
+#endif
}
-void clif_monster_hp_bar( struct mob_data* md, struct map_session_data *sd ) {
+void clif_monster_hp_bar(struct mob_data *md, struct map_session_data *sd)
+{
+#if PACKETVER >= 20120228
struct packet_monster_hp p;
nullpo_retv(md);
@@ -17408,6 +17701,7 @@ void clif_monster_hp_bar( struct mob_data* md, struct map_session_data *sd ) {
p.MaxHP = md->status.max_hp;
clif->send(&p, sizeof(p), &sd->bl, SELF);
+#endif
}
/* [Ind/Hercules] placeholder for unsupported incoming packets (avoids server disconnecting client) */
@@ -17436,7 +17730,9 @@ void clif_parse_CashShopClose(int fd, struct map_session_data *sd) {
}
void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
-void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) {
+void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd)
+{
+#if PACKETVER >= 20110614
int i, j = 0;
for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) {
@@ -17456,6 +17752,7 @@ void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) {
WFIFOSET(fd, 8 + ( clif->cs.item_count[i] * 6 ));
}
+#endif
}
void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -17549,7 +17846,9 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) {
void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
/* [Ind/Hercules] */
-void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) {
+void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd)
+{
+#if PACKETVER >= 20110222
short tab = RFIFOW(fd, 2);
int j;
@@ -17568,9 +17867,12 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) {
}
WFIFOSET(fd, 10 + ( clif->cs.item_count[tab] * 6 ));
+#endif
}
+
/* [Ind/Hercules] */
-void clif_maptypeproperty2(struct block_list *bl,enum send_target t) {
+void clif_maptypeproperty2(struct block_list *bl,enum send_target t)
+{
#if PACKETVER >= 20121010
struct packet_maptypeproperty2 p;
struct map_session_data *sd = NULL;
@@ -17621,26 +17923,29 @@ void clif_partytickack(struct map_session_data* sd, bool flag) {
WFIFOSET(sd->fd, packet_len(0x2c9));
}
-void clif_ShowScript(struct block_list* bl, const char* message) {
+void clif_ShowScript(struct block_list *bl, const char *message)
+{
+#if PACKETVER >= 20110111
char buf[256];
- size_t len;
+ int len;
nullpo_retv(bl);
- if(!message)
+ if (message == NULL)
return;
- len = strlen(message)+1;
+ len = (int)strlen(message)+1;
- if (len > sizeof(buf)-8) {
- ShowWarning("clif_ShowScript: Truncating too long message '%s' (len=%"PRIuS").\n", message, len);
- len = sizeof(buf)-8;
+ if (len > (int)sizeof(buf)-8) {
+ ShowWarning("clif_ShowScript: Truncating too long message '%s' (len=%d).\n", message, len);
+ len = (int)sizeof(buf)-8;
}
- WBUFW(buf,0)=0x8b3;
- WBUFW(buf,2)=len+8;
- WBUFL(buf,4)=bl->id;
- safestrncpy((char *) WBUFP(buf,8),message,len);
- clif->send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT);
+ WBUFW(buf,0) = 0x8b3;
+ WBUFW(buf,2) = len+8;
+ WBUFL(buf,4) = bl->id;
+ safestrncpy(WBUFP(buf,8),message,len);
+ clif->send(buf,WBUFW(buf,2),bl,AREA);
+#endif
}
void clif_status_change_end(struct block_list *bl, int tid, enum send_target target, int type) {
@@ -17679,7 +17984,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);
@@ -17691,8 +17997,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 */
@@ -17729,19 +18036,21 @@ 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);
@@ -17750,8 +18059,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 */
@@ -17792,14 +18102,17 @@ void clif_bgqueue_battlebegins(struct map_session_data *sd, unsigned char arena_
clif->send(&p,sizeof(p), &sd->bl, target);
}
-void clif_scriptclear(struct map_session_data *sd, int npcid) {
+void clif_scriptclear(struct map_session_data *sd, int npcid)
+{
+#if PACKETVER >= 20110928
struct packet_script_clear p;
nullpo_retv(sd);
p.PacketType = script_clearType;
p.NpcID = npcid;
- clif->send(&p,sizeof(p), &sd->bl, SELF);
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
+#endif
}
/* Made Possible Thanks to Yommy! */
@@ -17887,10 +18200,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) {
@@ -17903,9 +18217,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) {
@@ -17919,7 +18234,9 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) {
}
void clif_parse_BankCheck(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
-void clif_parse_BankCheck(int fd, struct map_session_data* sd) {
+void clif_parse_BankCheck(int fd, struct map_session_data* sd)
+{
+#if PACKETVER >= 20130313
struct packet_banking_check p;
if (!battle_config.feature_banking) {
@@ -17932,6 +18249,7 @@ void clif_parse_BankCheck(int fd, struct map_session_data* sd) {
p.Reason = (short)0;
clif->send(&p,sizeof(p), &sd->bl, SELF);
+#endif
}
void clif_parse_BankOpen(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -17944,7 +18262,9 @@ void clif_parse_BankClose(int fd, struct map_session_data* sd) {
return;
}
-void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) {
+void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason)
+{
+#if PACKETVER >= 20130313
struct packet_banking_deposit_ack p;
nullpo_retv(sd);
@@ -17954,9 +18274,12 @@ void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK r
p.Reason = (short)reason;
clif->send(&p,sizeof(p), &sd->bl, SELF);
+#endif
}
-void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) {
+void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason)
+{
+#if PACKETVER >= 20130313
struct packet_banking_withdraw_ack p;
nullpo_retv(sd);
@@ -17966,6 +18289,7 @@ void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK
p.Reason = (short)reason;
clif->send(&p,sizeof(p), &sd->bl, SELF);
+#endif
}
/* TODO: official response packet (tried 0x8cb/0x97b but the display was quite screwed up.) */
@@ -17978,7 +18302,7 @@ void clif_show_modifiers (struct map_session_data *sd) {
snprintf(output,128,"Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%",
sd->status.mod_exp,sd->status.mod_drop,sd->status.mod_death);
- clif->broadcast2(&sd->bl,output, strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF);
+ clif->broadcast2(&sd->bl, output, (int)strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF);
}
}
@@ -18140,32 +18464,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;
@@ -18180,11 +18502,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
}
@@ -18203,10 +18546,11 @@ void clif_PartyLeaderChanged(struct map_session_data *sd, int prev_leader_aid, i
void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
/* Roulette System [Yommy/Hercules] */
void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) {
+#if PACKETVER >= 20140612
struct packet_roulette_open_ack p;
if( !battle_config.feature_roulette ) {
- clif->message(fd,"Roulette is disabled");
+ clif->message(fd, msg_fd(fd,82)); // Roulette is disabled
return;
}
@@ -18221,15 +18565,18 @@ void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) {
p.SilverPoint = pc_readglobalreg(sd, script->add_str("TmpRouletteSilver"));
clif->send(&p,sizeof(p), &sd->bl, SELF);
+#endif
}
void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
-void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) {
+void clif_parse_RouletteInfo(int fd, struct map_session_data* sd)
+{
+#if PACKETVER >= 20140612
struct packet_roulette_info_ack p;
unsigned short i, j, count = 0;
if( !battle_config.feature_roulette ) {
- clif->message(fd,"Roulette is disabled");
+ clif->message(fd, msg_fd(fd,82)); // Roulette is disabled
return;
}
@@ -18247,13 +18594,13 @@ void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) {
}
}
clif->send(&p,sizeof(p), &sd->bl, SELF);
- return;
+#endif
}
void clif_parse_RouletteClose(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
void clif_parse_RouletteClose(int fd, struct map_session_data* sd) {
if( !battle_config.feature_roulette ) {
- clif->message(fd,"Roulette is disabled");
+ clif->message(fd, msg_fd(fd,82)); // Roulette is disabled
return;
}
@@ -18269,7 +18616,7 @@ void clif_parse_RouletteGenerate(int fd, struct map_session_data* sd) {
short stage = sd->roulette.stage;
if( !battle_config.feature_roulette ) {
- clif->message(fd,"Roulette is disabled");
+ clif->message(fd, msg_fd(fd,82)); // Roulette is disabled
return;
}
@@ -18304,7 +18651,7 @@ void clif_parse_RouletteGenerate(int fd, struct map_session_data* sd) {
it.nameid = clif->rd.nameid[stage][0];
it.identify = 1;
- pc->additem(sd, &it, clif->rd.qty[stage][0], LOG_TYPE_OTHER);/** TODO maybe a new log type for roulette items? **/
+ pc->additem(sd, &it, clif->rd.qty[stage][0], LOG_TYPE_ROULETTE);/** TODO maybe a new log type for roulette items? **/
sd->roulette.stage = 0;
result = GENERATE_ROULETTE_LOSING;
@@ -18321,11 +18668,13 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) __attribut
/**
* Request to cash in!
**/
-void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) {
+void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd)
+{
+#if PACKETVER >= 20140612
struct packet_roulette_itemrecv_ack p;
if( !battle_config.feature_roulette ) {
- clif->message(fd,"Roulette is disabled");
+ clif->message(fd, msg_fd(fd,82)); // Roulette is disabled
return;
}
@@ -18339,7 +18688,7 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) {
it.nameid = clif->rd.nameid[sd->roulette.prizeStage][sd->roulette.prizeIdx];
it.identify = 1;
- switch (pc->additem(sd, &it, clif->rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_OTHER)) {
+ switch (pc->additem(sd, &it, clif->rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_ROULETTE)) {
case 0:
p.Result = RECV_ITEM_SUCCESS;
sd->roulette.claimPrize = false;
@@ -18364,12 +18713,12 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) {
p.Result = RECV_ITEM_FAILED;
clif->send(&p,sizeof(p), &sd->bl, SELF);
- return;
+#endif
}
bool clif_parse_roulette_db(void) {
- config_t roulette_conf;
- config_setting_t *roulette = NULL, *levels = NULL;
+ struct config_t roulette_conf;
+ struct config_setting_t *roulette = NULL, *levels = NULL;
const char *config_filename = "db/roulette_db.conf"; // FIXME hardcoded name
int i, j, item_count_t = 0;
@@ -18377,15 +18726,13 @@ bool clif_parse_roulette_db(void) {
clif->rd.items[i] = 0;
}
- if (libconfig->read_file(&roulette_conf, config_filename)) {
- ShowError("can't read %s\n", config_filename);
+ if (!libconfig->load_file(&roulette_conf, config_filename))
return false;
- }
roulette = libconfig->lookup(&roulette_conf, "roulette");
if( roulette != NULL && (levels = libconfig->setting_get_elem(roulette, 0)) != NULL ) {
for(i = 0; i < MAX_ROULETTE_LEVEL; i++) {
- config_setting_t *level;
+ struct config_setting_t *level;
char entry_name[10];
sprintf(entry_name,"level_%d",i+1);
@@ -18394,7 +18741,7 @@ bool clif_parse_roulette_db(void) {
int k, item_count = libconfig->setting_length(level);
for(k = 0; k < item_count; k++) {
- config_setting_t *entry = libconfig->setting_get_elem(level,k);
+ struct config_setting_t *entry = libconfig->setting_get_elem(level,k);
const char *name = config_setting_name(entry);
int qty = libconfig->setting_get_int(entry);
struct item_data * data = NULL;
@@ -18461,7 +18808,9 @@ bool clif_parse_roulette_db(void) {
/**
*
**/
-void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID) {
+void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID)
+{
+#if PACKETVER >= 20140612
struct packet_roulette_generate_ack p;
nullpo_retv(sd);
@@ -18475,6 +18824,7 @@ void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char resul
p.RemainSilver = pc_readglobalreg(sd, script->add_str("TmpRouletteSilver"));
clif->send(&p,sizeof(p), &sd->bl, SELF);
+#endif
}
/**
@@ -18482,6 +18832,7 @@ void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char resul
*/
void clif_openmergeitem(int fd, struct map_session_data *sd)
{
+#if PACKETVER > 20120228
int i = 0, n = 0, j = 0;
struct merge_item merge_items[MAX_INVENTORY];
struct merge_item *merge_items_[MAX_INVENTORY] = {0};
@@ -18524,6 +18875,7 @@ void clif_openmergeitem(int fd, struct map_session_data *sd)
for ( i = 0; i < j; i++ )
WFIFOW(fd,i*2+4) = merge_items_[i]->position;
WFIFOSET(fd,2*j+4);
+#endif
}
int clif_comparemergeitem(const void *a, const void *b)
@@ -18540,6 +18892,7 @@ int clif_comparemergeitem(const void *a, const void *b)
void clif_ackmergeitems(int fd, struct map_session_data *sd)
{
+#if PACKETVER > 20120228
int i = 0, n = 0, length = 0, count = 0;
int16 nameid = 0, indexes[MAX_INVENTORY] = {0}, amounts[MAX_INVENTORY] = {0};
struct item item_data;
@@ -18619,6 +18972,7 @@ void clif_ackmergeitems(int fd, struct map_session_data *sd)
WFIFOW(fd,4) = count;
WFIFOB(fd,6) = MERGEITEM_SUCCESS;
WFIFOSET(fd,7);
+#endif
}
void clif_cancelmergeitem (int fd, struct map_session_data *sd)
@@ -18629,6 +18983,7 @@ void clif_cancelmergeitem (int fd, struct map_session_data *sd)
void clif_dressroom_open(struct map_session_data *sd, int view)
{
+#if PACKETVER >= 20150513
int fd;
nullpo_retv(sd);
@@ -18638,6 +18993,7 @@ void clif_dressroom_open(struct map_session_data *sd, int view)
WFIFOW(fd,0)=0xa02;
WFIFOW(fd,2)=view;
WFIFOSET(fd,packet_len(0xa02));
+#endif
}
/// Request to select cart's visual look for new cart design (ZC_SELECTCART).
@@ -18662,6 +19018,64 @@ void clif_selectcart(struct map_session_data *sd)
#endif
}
+/// Starts navigation to the given target on client side
+void clif_navigate_to(struct map_session_data *sd, const char* mapname, uint16 x, uint16 y, uint8 flag, bool hideWindow, uint16 mob_id)
+{
+// probably this packet with other fields present in older packet versions
+#if PACKETVER >= 20120307
+ int fd;
+
+ nullpo_retv(sd);
+ nullpo_retv(mapname);
+ fd = sd->fd;
+ WFIFOHEAD(fd, packet_len(0x8e2));
+ WFIFOW(fd, 0) = 0x8e2;
+
+ // How detailed will our navigation be?
+ if (mob_id > 0) {
+ x = 0;
+ y = 0;
+ WFIFOB(fd, 2) = 3; // monster with destination field
+ } else if (x > 0 && y > 0) {
+ WFIFOB(fd, 2) = 0; // with coordinates
+ } else {
+ x = 0;
+ y = 0;
+ WFIFOB(fd, 2) = 1; // without coordinates(will fail if you are already on the map)
+ }
+
+ // Which services can be used for transportation?
+ WFIFOB(fd, 3) = flag;
+ // If this flag is set, the navigation window will not be opened up
+ WFIFOB(fd, 4) = hideWindow;
+ // Target map
+ safestrncpy((char*)WFIFOP(fd, 5), mapname, MAP_NAME_LENGTH_EXT);
+ // Target x
+ WFIFOW(fd, 21) = x;
+ // Target y
+ WFIFOW(fd, 23) = y;
+ // Target monster ID
+ WFIFOW(fd, 25) = mob_id;
+ WFIFOSET(fd, packet_len(0x8e2));
+#endif
+}
+
+/**
+ * Returns the name of the given bl, in a client-friendly format.
+ *
+ * @param bl The requested bl.
+ * @return The bl's name (guaranteed to be non-NULL).
+ */
+const char *clif_get_bl_name(const struct block_list *bl)
+{
+ const char *name = status->get_name(bl);
+
+ if (name == NULL)
+ return "Unknown";
+
+ return name;
+}
+
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
@@ -18761,7 +19175,7 @@ int clif_parse(int fd) {
// filter out invalid / unsupported packets
if (cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0) {
ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x (0x%04x), %"PRIuS" bytes received), disconnecting session #%d.\n",
- cmd, RFIFOW(fd,0), RFIFOREST(fd), fd);
+ (unsigned int)cmd, RFIFOW(fd,0), RFIFOREST(fd), fd);
#ifdef DUMP_INVALID_PACKET
ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
#endif
@@ -18777,7 +19191,7 @@ int clif_parse(int fd) {
packet_len = RFIFOW(fd,2);
if (packet_len < 4 || packet_len > 32768) {
- ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd);
+ ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", (unsigned int)cmd, packet_len, fd);
#ifdef DUMP_INVALID_PACKET
ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
#endif
@@ -18791,7 +19205,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
}
@@ -18865,12 +19283,12 @@ static void __attribute__ ((unused)) packetdb_addpacket(short cmd, int len, ...)
pFunc func;
if (cmd > MAX_PACKET_DB) {
- ShowError("Packet Error: packet 0x%x is greater than the maximum allowed (0x%x), skipping...\n", cmd, MAX_PACKET_DB);
+ ShowError("Packet Error: packet 0x%x is greater than the maximum allowed (0x%x), skipping...\n", (unsigned int)cmd, (unsigned int)MAX_PACKET_DB);
return;
}
if (cmd < MIN_PACKET_DB) {
- ShowError("Packet Error: packet 0x%x is lower than the minimum allowed (0x%x), skipping...\n", cmd, MIN_PACKET_DB);
+ ShowError("Packet Error: packet 0x%x is lower than the minimum allowed (0x%x), skipping...\n", (unsigned int)cmd, (unsigned int)MIN_PACKET_DB);
return;
}
@@ -19163,6 +19581,7 @@ void clif_defaults(void) {
clif->autoshadowspell_list = clif_autoshadowspell_list;
clif->skill_itemlistwindow = clif_skill_itemlistwindow;
clif->sc_load = clif_status_change2;
+ clif->sc_continue = clif_status_change2;
clif->sc_end = clif_status_change_end;
clif->initialstatus = clif_initialstatus;
clif->cooldown_list = clif_skill_cooldown_list;
@@ -19196,7 +19615,7 @@ void clif_defaults(void) {
clif->skill_poseffect = clif_skill_poseffect;
clif->skill_estimation = clif_skill_estimation;
clif->skill_warppoint = clif_skill_warppoint;
- clif->skillcasting = clif_skillcasting;
+ clif->useskill = clif_useskill;
clif->produce_effect = clif_produceeffect;
clif->devotion = clif_devotion;
clif->spiritball = clif_spiritball;
@@ -19244,7 +19663,8 @@ void clif_defaults(void) {
clif->message = clif_displaymessage;
clif->messageln = clif_displaymessage2;
clif->messages = clif_displaymessage_sprintf;
- clif->process_message = clif_process_message;
+ clif->process_chat_message = clif_process_chat_message;
+ clif->process_whisper_message = clif_process_whisper_message;
clif->wisexin = clif_wisexin;
clif->wisall = clif_wisall;
clif->PMIgnoreList = clif_PMIgnoreList;
@@ -19481,6 +19901,10 @@ void clif_defaults(void) {
clif->ackmergeitems = clif_ackmergeitems;
/* Cart Deco */
clif->selectcart = clif_selectcart;
+ /* */
+ clif->isdisguised = clif_isdisguised;
+ clif->navigate_to = clif_navigate_to;
+ clif->bl_type = clif_bl_type;
/*------------------------
*- Parse Incoming Packet
@@ -19723,8 +20147,9 @@ void clif_defaults(void) {
clif->pNPCMarketClosed = clif_parse_NPCMarketClosed;
clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase;
/* */
- clif->add_random_options = clif_add_random_options;
+ clif->add_item_options = clif_add_item_options;
clif->pHotkeyRowShift = clif_parse_HotkeyRowShift;
clif->dressroom_open = clif_dressroom_open;
clif->pOneClick_ItemIdentify = clif_parse_OneClick_ItemIdentify;
+ clif->get_bl_name = clif_get_bl_name;
}