diff options
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 1481 |
1 files changed, 1126 insertions, 355 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 4e8653783..5c6bc39d3 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -92,9 +92,6 @@ static struct packet_itemlist_equip itemlist_equip; static struct ZC_STORE_ITEMLIST_NORMAL storelist_normal; static struct ZC_STORE_ITEMLIST_EQUIP storelist_equip; static struct packet_viewequip_ack viewequip_list; -#if PACKETVER >= 20131223 -static struct packet_npc_market_result_ack npcmarket_result; -#endif // temporart buffer for send big packets char packet_buf[0xffff]; //#define DUMP_UNKNOWN_PACKET @@ -1649,7 +1646,9 @@ static void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int p.level = hd->homunculus.level; p.hunger = hd->homunculus.hunger; p.intimacy = hd->homunculus.intimacy / 100; +#if !(PACKETVER_MAIN_NUM >= 20190619 || PACKETVER_RE_NUM >= 20190605 || PACKETVER_ZERO_NUM >= 20190626) p.itemId = 0; // equip id +#endif #ifdef RENEWAL p.atk2 = cap_value(hstatus->rhw.atk2, 0, INT16_MAX); #else @@ -3909,20 +3908,16 @@ static void clif_arrow_fail(struct map_session_data *sd, int type) /// 01ad <packet len>.W { <name id>.W }* static void clif_arrow_create_list(struct map_session_data *sd) { - int i, c; - int fd; - int len; - struct PACKET_ZC_MAKINGARROW_LIST *p; - nullpo_retv(sd); - fd = sd->fd; - len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + int fd = sd->fd; + int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); WFIFOHEAD(fd, len); - p = WFIFOP(fd, 0); - p->packetType = 0x1ad; + struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_MAKINGARROW_LIST; - for (i = 0, c = 0; i < MAX_SKILL_ARROW_DB; i++) { + int c = 0; + for (int i = 0; i < MAX_SKILL_ARROW_DB; i++) { int j; if (skill->dbs->arrow_db[i].nameid > 0 && (j = pc->search_inventory(sd, skill->dbs->arrow_db[i].nameid)) != INDEX_NOT_FOUND @@ -3953,17 +3948,16 @@ static void clif_arrow_create_list(struct map_session_data *sd) /// 1 = success static void clif_statusupack(struct map_session_data *sd, int type, int ok, int val) { - int fd; - nullpo_retv(sd); + int fd = sd->fd; - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0xbc)); - WFIFOW(fd,0)=0xbc; - WFIFOW(fd,2)=type; - WFIFOB(fd,4)=ok; - WFIFOB(fd,5)=cap_value(val,0,UINT8_MAX); - WFIFOSET(fd,packet_len(0xbc)); + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_STATUS_CHANGE_ACK)); + struct PACKET_ZC_STATUS_CHANGE_ACK *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_STATUS_CHANGE_ACK; + p->sp = type; + p->ok = ok; + p->value = cap_value(val, 0, UINT8_MAX); + WFIFOSET(fd, sizeof(struct PACKET_ZC_STATUS_CHANGE_ACK)); } /// Notifies the client about the result of a request to equip an item (ZC_REQ_WEAR_EQUIP_ACK). @@ -4795,9 +4789,9 @@ static void clif_getareachar_unit(struct map_session_data *sd, struct block_list //Modifies the type of damage according to status changes [Skotlex] //Aegis data specifies that: 4 endure against single hit sources, 9 against multi-hit. -static inline int clif_calc_delay(int type, int div, int damage, int delay) +static inline enum battle_dmg_type clif_calc_delay(enum battle_dmg_type type, int div, int damage, int delay) { - return ( delay == 0 && damage > 0 ) ? ( div > 1 ? 9 : 4 ) : type; + return ( delay == 0 && damage > 0 ) ? ( div > 1 ? BDT_MULTIENDURE : BDT_ENDURE ) : type; } /*========================================== @@ -4828,7 +4822,7 @@ static int clif_calc_walkdelay(struct block_list *bl, int delay, int type, int d /// 08c8 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <IsSPDamage>.B <div>.W <type>.B <damage2>.L (ZC_NOTIFY_ACT2) /// type: @see enum battle_dmg_type /// for BDT_NORMAL: [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ] -static int clif_damage(struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) +static int clif_damage(struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, enum battle_dmg_type type, int64 in_damage2) { struct packet_damage p; struct status_change *sc; @@ -5257,58 +5251,79 @@ static int clif_insight(struct block_list *bl, va_list ap) return 0; } +static void clif_playerSkillToPacket(struct map_session_data *sd, struct SKILLDATA *skillData, int skillId, int idx, bool newSkill) +{ + nullpo_retv(sd); + nullpo_retv(skillData); + Assert_retv(idx >= 0 && idx < MAX_SKILL_DB); + + int skill_lv = sd->status.skill[idx].lv; + skillData->id = skillId; + skillData->inf = skill->get_inf(skillId); + skillData->level = skill_lv; + if (skill_lv > 0) { + skillData->sp = skill->get_sp(skillId, skill_lv); + skillData->range2 = skill->get_range2(&sd->bl, skillId, skill_lv); + } else { + skillData->sp = 0; + skillData->range2 = 0; + } +#if PACKETVER_RE_NUM >= 20190807 + if (newSkill) + skillData->level2 = 0; + else + skillData->level2 = skill_lv; +#else + safestrncpy(skillData->name, skill->get_name(skillId), NAME_LENGTH); +#endif + if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) + skillData->upFlag = (skill_lv < skill->tree_get_max(skillId, sd->status.class)) ? 1 : 0; + else + skillData->upFlag = 0; +} + /// Updates whole skill tree (ZC_SKILLINFO_LIST). /// 010f <packet len>.W { <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B }* static void clif_skillinfoblock(struct map_session_data *sd) { - int fd; - int i,len,id; - nullpo_retv(sd); - fd=sd->fd; - if (!fd) return; + int fd = sd->fd; + if (!fd) + return; - WFIFOHEAD(fd, MAX_SKILL_DB * 37 + 4); - WFIFOW(fd,0) = 0x10f; - for ( i = 0, len = 4; i < MAX_SKILL_DB; i++) { - if( (id = sd->status.skill[i].id) != 0 ) { - int level; + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_SKILLINFO_LIST) + MAX_SKILL_DB * sizeof(struct SKILLDATA)); + struct PACKET_ZC_SKILLINFO_LIST *p = WFIFOP(fd, 0); + + p->packetType = HEADER_ZC_SKILLINFO_LIST; + int skillIndex = 0; + int len = sizeof(struct PACKET_ZC_SKILLINFO_LIST); + int i; + for (i = 0; i < MAX_SKILL_DB; i++) { + int id = sd->status.skill[i].id; + if (id != 0) { // workaround for bugreport:5348 - if (len + 37 > 8192) + if (len + sizeof(struct SKILLDATA) > 8192) break; - WFIFOW(fd, len) = id; - WFIFOL(fd, len + 2) = skill->get_inf(id); - level = sd->status.skill[i].lv; - WFIFOW(fd, len + 6) = level; - if (level) { - WFIFOW(fd, len + 8) = skill->get_sp(id, level); - WFIFOW(fd, len + 10)= skill->get_range2(&sd->bl, id, level); - } - else { - WFIFOW(fd, len + 8) = 0; - WFIFOW(fd, len + 10)= 0; - } - safestrncpy(WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH); - if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) - WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill->tree_get_max(id, sd->status.class))? 1:0; - else - WFIFOB(fd,len+36) = 0; - len += 37; + clif->playerSkillToPacket(sd, &p->skills[skillIndex], id, i, false); + len += sizeof(struct SKILLDATA); + skillIndex++; } } - WFIFOW(fd,2)=len; - WFIFOSET(fd,len); + p->packetLength = len; + WFIFOSET(fd, len); // workaround for bugreport:5348; send the remaining skills one by one to bypass packet size limit - for ( ; i < MAX_SKILL_DB; i++) { - if( (id = sd->status.skill[i].id) != 0 ) { + for (; i < MAX_SKILL_DB; i++) { + int id = sd->status.skill[i].id; + if (id != 0) { clif->addskill(sd, id); clif->skillinfo(sd, id, 0); } } } + /** * Server tells client 'sd' to add skill of id 'id' to it's skill tree (e.g. with Ice Falcion item) **/ @@ -5317,36 +5332,21 @@ static void clif_skillinfoblock(struct map_session_data *sd) /// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B static void clif_addskill(struct map_session_data *sd, int id) { - int fd, skill_lv, idx = skill->get_index(id); - nullpo_retv(sd); - fd = sd->fd; - if (!fd) return; + int fd = sd->fd; + if (!fd) + return; + int idx = skill->get_index(id); if (sd->status.skill[idx].id <= 0) return; - skill_lv = sd->status.skill[idx].lv; - - WFIFOHEAD(fd, packet_len(0x111)); - WFIFOW(fd,0) = 0x111; - WFIFOW(fd,2) = id; - WFIFOL(fd,4) = skill->get_inf(id); - WFIFOW(fd,8) = skill_lv; - if (skill_lv > 0) { - WFIFOW(fd,10) = skill->get_sp(id, skill_lv); - WFIFOW(fd,12) = skill->get_range2(&sd->bl, id, skill_lv); - } else { - WFIFOW(fd,10) = 0; - WFIFOW(fd,12) = 0; - } - safestrncpy(WFIFOP(fd,14), skill->get_name(id), NAME_LENGTH); - if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) - WFIFOB(fd,38) = (skill_lv < skill->tree_get_max(id, sd->status.class))? 1:0; - else - WFIFOB(fd,38) = 0; - WFIFOSET(fd,packet_len(0x111)); + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_ADD_SKILL)); + struct PACKET_ZC_ADD_SKILL *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_ADD_SKILL; + clif->playerSkillToPacket(sd, &p->skill, id, idx, true); + WFIFOSET(fd, sizeof(struct PACKET_ZC_ADD_SKILL)); } /// Deletes a skill from the skill tree (ZC_SKILLINFO_DELETE). @@ -5399,32 +5399,34 @@ static void clif_skillup(struct map_session_data *sd, uint16 skill_id, int skill /// 07e1 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <upgradable>.B static void clif_skillinfo(struct map_session_data *sd, int skill_id, int inf) { + nullpo_retv(sd); + const int fd = sd->fd; int idx = skill->get_index(skill_id); - int skill_lv; - - nullpo_retv(sd); Assert_retv(idx >= 0 && idx < MAX_SKILL_DB); - skill_lv = sd->status.skill[idx].lv; - - WFIFOHEAD(fd,packet_len(0x7e1)); - WFIFOW(fd,0) = 0x7e1; - WFIFOW(fd,2) = skill_id; - WFIFOL(fd,4) = inf?inf:skill->get_inf(skill_id); - WFIFOW(fd,8) = skill_lv; + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_SKILLINFO_UPDATE2)); + struct PACKET_ZC_SKILLINFO_UPDATE2 *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_SKILLINFO_UPDATE2; + int skill_lv = sd->status.skill[idx].lv; + p->id = skill_id; + p->inf = skill->get_inf(skill_id); + p->level = skill_lv; if (skill_lv > 0) { - WFIFOW(fd,10) = skill->get_sp(skill_id, skill_lv); - WFIFOW(fd,12) = skill->get_range2(&sd->bl, skill_id, skill_lv); + p->sp = skill->get_sp(skill_id, skill_lv); + p->range2 = skill->get_range2(&sd->bl, skill_id, skill_lv); } else { - WFIFOW(fd,10) = 0; - WFIFOW(fd,12) = 0; + p->sp = 0; + p->range2 = 0; } +#if PACKETVER_RE_NUM >= 20190807 + p->level2 = skill_lv; +#endif 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; + p->upFlag = (skill_lv < skill->tree_get_max(skill_id, sd->status.class)) ? 1 : 0; else - WFIFOB(fd,14) = 0; - WFIFOSET(fd,packet_len(0x7e1)); + p->upFlag = 0; + WFIFOSET(fd, sizeof(struct PACKET_ZC_SKILLINFO_UPDATE2)); } /// Notifies clients in area, that an object is about to use a skill. @@ -5571,7 +5573,7 @@ static void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, un /// Skill attack effect and damage. /// 0114 <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.W <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL) /// 01de <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.L <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL2) -static int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, uint16 skill_id, uint16 skill_lv, int type) +static int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, uint16 skill_id, uint16 skill_lv, enum battle_dmg_type type) { unsigned char buf[64]; struct status_change *sc; @@ -5673,7 +5675,7 @@ static int clif_skill_damage(struct block_list *src, struct block_list *dst, int /// Ground skill attack effect and damage (ZC_NOTIFY_SKILL_POSITION). /// 0115 <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <x>.W <y>.W <damage>.W <level>.W <div>.W <type>.B #if 0 -static int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int damage, int div, uint16 skill_id, uint16 skill_lv, int type) +static int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int damage, int div, uint16 skill_id, uint16 skill_lv, enum battle_dmg_type type) { unsigned char buf[64]; struct status_change *sc; @@ -5996,7 +5998,7 @@ static void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 s len = sizeof(struct PACKET_ZC_MAKINGITEM_LIST) + MAX_SKILL_PRODUCE_DB * sizeof(struct PACKET_ZC_MAKINGITEM_LIST_sub); WFIFOHEAD(fd, len); p = WFIFOP(fd, 0); - p->packetType = 0x25a; + p->packetType = HEADER_ZC_MAKINGITEM_LIST; p->makeItem = list_type; // list type c = 0; @@ -6456,7 +6458,7 @@ static void clif_wis_message(int fd, const char *nick, const char *mes, int mes_ safestrncpy(WFIFOP(fd,28), mes, mes_len + 1); WFIFOSET(fd,WFIFOW(fd,2)); #else - ssd = map->nick2sd(nick); + ssd = map->nick2sd(nick, false); WFIFOHEAD(fd, mes_len + NAME_LENGTH + 9); WFIFOW(fd,0) = 0x97; @@ -8104,6 +8106,54 @@ static void clif_guild_allianceinfo(struct map_session_data *sd) WFIFOSET(fd,WFIFOW(fd,2)); } +static void clif_guild_castlelist(struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 + nullpo_retv(sd); + + struct guild *g = sd->guild; + if (g == NULL) + return; + + int castle_count = guild->checkcastles(g); + if (castle_count > 0) { + int len = sizeof(struct PACKET_ZC_GUILD_CASTLE_LIST) + castle_count; + struct PACKET_ZC_GUILD_CASTLE_LIST *p = aMalloc(len); + p->packetType = HEADER_ZC_GUILD_CASTLE_LIST; + p->packetLength = len; + + int i = 0; + struct DBIterator *iter = db_iterator(guild->castle_db); + for (struct guild_castle *gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) { + if (gc->guild_id == g->guild_id) { + p->castle_list[i] = gc->castle_id; + ++i; + } + } + dbi_destroy(iter); + + clif->send(p, len, &sd->bl, SELF); + aFree(p); + } +#endif +} + +static void clif_guild_castleinfo(struct map_session_data *sd, struct guild_castle *gc) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 + + nullpo_retv(sd); + nullpo_retv(gc); + + struct PACKET_ZC_CASTLE_INFO p = { 0 }; + p.packetType = HEADER_ZC_CASTLE_INFO; + p.castle_id = gc->castle_id; + p.economy = gc->economy; + p.defense = gc->defense; + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif +} + /// Guild member manager information (ZC_MEMBERMGR_INFO). /// 0154 <packet len>.W { <account>.L <char id>.L <hair style>.W <hair color>.W <gender>.W <class>.W <level>.W <contrib exp>.L <state>.L <position>.L <memo>.50B <name>.24B }* /// state: @@ -8687,14 +8737,14 @@ static void clif_emotion(struct block_list *bl, int type) /// 0191 <id>.L <contents>.80B static void clif_talkiebox(struct block_list *bl, const char *talkie) { - unsigned char buf[MESSAGE_SIZE+6]; nullpo_retv(bl); nullpo_retv(talkie); + struct PACKET_ZC_TALKBOX_CHATCONTENTS p; - WBUFW(buf,0) = 0x191; - WBUFL(buf,2) = bl->id; - safestrncpy(WBUFP(buf,6),talkie,MESSAGE_SIZE); - clif->send(buf,packet_len(0x191),bl,AREA); + p.PacketType = HEADER_ZC_TALKBOX_CHATCONTENTS; + p.aid = bl->id; + safestrncpy(&p.message[0], talkie, TALKBOX_MESSAGE_SIZE); + clif->send(&p, sizeof(struct PACKET_ZC_TALKBOX_CHATCONTENTS), bl, AREA); } /// Displays wedding effect centered on an object (ZC_CONGRATULATION). @@ -9296,9 +9346,6 @@ static void clif_pcname_ack(int fd, struct block_list *bl) packet.gid = bl->id; const struct map_session_data *ssd = BL_UCCAST(BL_PC, bl); - const struct party_data *p = NULL; - const struct guild *g = NULL; - int ps = -1; if (ssd->fakename[0] != '\0' && ssd->disguise != -1) { packet.packet_id = reqName; @@ -9324,9 +9371,12 @@ static void clif_pcname_ack(int fd, struct block_list *bl) #endif memcpy(packet.name, ssd->status.name, NAME_LENGTH); + const struct party_data *p = NULL; + int ps = -1; if (ssd->status.party_id != 0) { p = party->search(ssd->status.party_id); } + const struct guild *g = NULL; if (ssd->status.guild_id != 0) { if ((g = ssd->guild) != NULL) { int i; @@ -9349,6 +9399,12 @@ static void clif_pcname_ack(int fd, struct block_list *bl) memcpy(packet.guild_name, g->name,NAME_LENGTH); memcpy(packet.position_name, g->position[ps].name, NAME_LENGTH); } + else if (ssd->status.clan_id != 0) { + struct clan *c = clan->search(ssd->status.clan_id); + if (c != 0) { + memcpy(packet.position_name, c->name, NAME_LENGTH); + } + } } clif->send_selforarea(fd, bl, &packet, len); @@ -9482,7 +9538,8 @@ static void clif_mobname_normal_ack(int fd, struct block_list *bl) struct PACKET_ZC_ACK_REQNAME_TITLE packet = { 0 }; packet.packet_id = HEADER_ZC_ACK_REQNAME_TITLE; packet.gid = bl->id; - memcpy(packet.name, BL_UCCAST(BL_MOB, bl)->db->name, NAME_LENGTH); + const struct mob_data *md = BL_UCCAST(BL_MOB, bl); + memcpy(packet.name, md->name, NAME_LENGTH); #if PACKETVER_MAIN_NUM >= 20180207 || PACKETVER_RE_NUM >= 20171129 || PACKETVER_ZERO_NUM >= 20171130 struct unit_data *ud = unit->bl2ud(bl); if (ud != NULL) { @@ -10712,7 +10769,7 @@ static 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 ]"); + sprintf(output, "%s", msg_sd(sd, 893)); // [ Kill Steal Protection Disabled. KS is allowed in this map ] clif->broadcast(&sd->bl, output, (int)strlen(output) + 1, BC_BLUE, SELF); } @@ -10825,7 +10882,7 @@ static void clif_hotkeysAll_send(struct map_session_data *sd) { #ifdef HOTKEY_SAVING clif->hotkeys(sd, 0); -#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605 // send second tab only if data exists for (int i = MAX_HOTKEYS; i < MAX_HOTKEYS * 2; i++) { if (sd->status.hotkeys[i].type != 0 || sd->status.hotkeys[i].id != 0 || sd->status.hotkeys[i].lv != 0) { @@ -10854,7 +10911,7 @@ static void clif_hotkeys_send(struct map_session_data *sd, int tab) else p.rotate = sd->status.hotkey_rowshift2; #endif -#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605 p.tab = tab; #endif const int offset = tab * MAX_HOTKEYS; @@ -10879,7 +10936,7 @@ static void clif_parse_HotkeyRowShift1(int fd, struct map_session_data *sd) static void clif_parse_HotkeyRowShift2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_HotkeyRowShift2(int fd, struct map_session_data *sd) { -#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605 const struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE2 *p = RFIFOP(fd, 0); if (p->tab == 0) sd->status.hotkey_rowshift = p->rowshift; @@ -10911,7 +10968,7 @@ static void clif_parse_Hotkey2(int fd, struct map_session_data *sd) __attribute_ static void clif_parse_Hotkey2(int fd, struct map_session_data *sd) { #ifdef HOTKEY_SAVING -#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605 const struct PACKET_CZ_SHORTCUT_KEY_CHANGE2 *p = RFIFOP(fd, 0); const unsigned short idx = p->index + p->tab * MAX_HOTKEYS; Assert_retv(idx < MAX_HOTKEYS_DB); @@ -10982,9 +11039,13 @@ static void clif_parse_progressbar(int fd, struct map_session_data *sd) __attrib /// 02f1 static void clif_parse_progressbar(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int npc_id = sd->progressbar.npc_id; + Assert_retv(npc_id != 0); - if( timer->gettick() < sd->progressbar.timeout && sd->st ) + if (timer->gettick() < sd->progressbar.timeout && sd->st) sd->st->state = END; sd->progressbar.timeout = sd->state.workinprogress = sd->progressbar.npc_id = 0; @@ -11009,7 +11070,7 @@ static void clif_parse_WalkToXY(int fd, struct map_session_data *sd) ; //You CAN walk on this OPT1 value. /*else if( sd->progressbar.npc_id ) clif->progressbar_abort(sd);*/ - else if (pc_cant_act(sd)) + else if (pc_cant_act(sd) || pc_isvending(sd)) return; if(sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH]) @@ -11089,13 +11150,13 @@ static void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) sc = status->get_sc(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 + !pc_has_permission(sd, PC_PERM_RECEIVE_HACK_INFO) ) { char gm_msg[256]; sprintf(gm_msg, "Hack on NameRequest: character '%s' (account: %d) requested the name of an invisible target (id: %d).\n", sd->status.name, sd->status.account_id, id); ShowWarning(gm_msg); // information is sent to all online GMs - intif->wis_message_to_gm(map->wisp_server_name, battle_config.hack_info_GM_level, gm_msg); + pc->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, gm_msg); return; } #endif // 0 @@ -11169,7 +11230,10 @@ static void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) timer->settick(sd->fontcolor_tid, td->tick+5000); } - color = channel->config->colors[sd->fontcolor - 1]; + int fontColor = sd->fontcolor - 1; + if (fontColor < 0 || fontColor >= channel->config->colors_count) + fontColor = 0; + color = channel->config->colors[fontColor]; WFIFOHEAD(fd, outlen + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = outlen + 12; @@ -11374,10 +11438,10 @@ static void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action return; } - if( pc_cant_act(sd) || pc_issit(sd) || sd->sc.option&OPTION_HIDE ) + if (pc_cant_act(sd) || pc_issit(sd) || sd->sc.option&OPTION_HIDE || pc_isvending(sd)) return; - if( sd->sc.option&OPTION_COSTUME ) + if (sd->sc.option & OPTION_COSTUME) return; 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) { @@ -11555,8 +11619,8 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd) script->set_var(sd,output,(char *) split_data[i]); } - sprintf(output, "%s::OnWhisperGlobal", nd->exname); - npc->event(sd,output,0); // Calls the NPC label + safesnprintf(output, 255, "%s::OnWhisperGlobal", nd->exname); + npc->event(sd,output, 0); // Calls the NPC label return; } @@ -11580,15 +11644,11 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd) } // searching destination character - dstsd = map->nick2sd(target); + dstsd = map->nick2sd(target, false); - if (dstsd == NULL || strcmp(dstsd->status.name, target) != 0) { - // player is not on this map-server - // At this point, don't send wisp/page if it's not exactly the same name, because (example) - // if there are 'Test' player on an other map-server and 'test' player on this map-server, - // and if we ask for 'Test', we must not contact 'test' player - // so, we send information to inter-server, which is the only one which decide (and copy correct name). - intif->wis_message(sd, target, message, (int)strlen(message)); + if (dstsd == NULL) { + // Character not found (or found through partial match). + clif->wis_end(sd->fd, 1); return; } @@ -11604,7 +11664,7 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd) // if player is autotrading if (dstsd->state.autotrade) { char output[256]; - sprintf(output, "%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name); + sprintf(output, msg_fd(fd, 894), dstsd->status.name); // %s is in autotrade mode and cannot receive whispered messages. clif->wis_message(fd, map->wisp_server_name, output, (int)strlen(output)); return; } @@ -11635,7 +11695,7 @@ static void clif_parse_Broadcast(int fd, struct map_session_data *sd) char command[sizeof commandname + 2 + CHAT_SIZE_MAX] = ""; // '@' command + ' ' + message + NUL int len = (int)RFIFOW(fd,2) - 4; - if (len < 0) + if (len <= 0) return; sprintf(command, "%c%s ", atcommand->at_symbol, commandname); @@ -11735,6 +11795,9 @@ static void clif_parse_UseItem(int fd, struct map_session_data *sd) { int n; + if (pc_isvending(sd)) + return; + if (pc_isdead(sd)) { clif->clearunit_area(&sd->bl, CLR_DEAD); return; @@ -11760,15 +11823,17 @@ static void clif_parse_EquipItem(int fd, struct map_session_data *sd) __attribut static 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)) { + if (pc_isvending(sd)) + return; + + if (pc_isdead(sd)) { clif->clearunit_area(&sd->bl,CLR_DEAD); return; } - index = p->index - 2; - if (index >= sd->status.inventorySize) + int index = p->index - 2; + if (index < 0 || index >= sd->status.inventorySize) return; //Out of bounds check. if( sd->npc_id ) { @@ -11779,15 +11844,15 @@ static 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[index].identify) { - clif->equipitemack(sd, index, 0, EIA_FAIL);// fail + if (!sd->status.inventory[index].identify) { + clif->equipitemack(sd, index, 0, EIA_FAIL); // fail return; } - if(!sd->inventory_data[index]) + if (!sd->inventory_data[index]) return; - if(sd->inventory_data[index]->type == IT_PETARMOR){ + if (sd->inventory_data[index]->type == IT_PETARMOR) { pet->equipitem(sd, index); return; } @@ -11795,7 +11860,7 @@ static void clif_parse_EquipItem(int fd, struct map_session_data *sd) pc->update_idle_time(sd, BCIDLE_USEITEM); //Client doesn't send the position for ammo. - if(sd->inventory_data[index]->type == IT_AMMO) + if (sd->inventory_data[index]->type == IT_AMMO) pc->equipitem(sd, index, EQP_AMMO); else pc->equipitem(sd, index, p->wearLocation); @@ -11808,6 +11873,9 @@ static void clif_parse_UnequipItem(int fd, struct map_session_data *sd) { int index; + if (pc_isvending(sd)) + return; + if(pc_isdead(sd)) { clif->clearunit_area(&sd->bl,CLR_DEAD); return; @@ -11880,7 +11948,7 @@ static void clif_parse_NpcBuySellSelected(int fd, struct map_session_data *sd) _ /// 1 = sell static void clif_parse_NpcBuySellSelected(int fd, struct map_session_data *sd) { - if (sd->state.trading) + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) return; npc->buysellsel(sd, RFIFOL(fd,2), RFIFOB(fd,6)); } @@ -11916,9 +11984,12 @@ static void clif_parse_NpcBuyListSend(int fd, struct map_session_data *sd) __att /// 00c8 <packet len>.W { <amount>.W <name id>.W }* static void clif_parse_NpcBuyListSend(int fd, struct map_session_data *sd) { - int n = ((int)RFIFOW(fd, 2) - sizeof(struct PACKET_CZ_PC_PURCHASE_ITEMLIST)) / sizeof(struct PACKET_CZ_PC_PURCHASE_ITEMLIST_sub); - int result; + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_PC_PURCHASE_ITEMLIST *p = RFIFOP(fd, 0); + int n = ((int)p->packetLength - sizeof(struct PACKET_CZ_PC_PURCHASE_ITEMLIST)) / sizeof(struct PACKET_CZ_PC_PURCHASE_ITEMLIST_sub); + int result; Assert_retv(n >= 0); @@ -11976,7 +12047,7 @@ static void clif_parse_NpcSellListSend(int fd, struct map_session_data *sd) Assert_retv(n >= 0); - if (sd->state.trading || !sd->npc_shopid) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd) || !sd->npc_shopid) { fail = 1; } else { struct itemlist item_list = { 0 }; @@ -12011,6 +12082,9 @@ static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd) __att /// 1 = public static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int len = (int)RFIFOW(fd, 2) - 15; int limit; bool pub; @@ -12027,6 +12101,9 @@ static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd) password = RFIFOP(fd, 7); //not zero-terminated title = RFIFOP(fd, 15); // not zero-terminated + if (limit < 0) + return; + if (pc_ismuted(&sd->sc, MANNER_NOROOM)) return; if(battle_config.basic_skill_check && !pc->check_basicskill(sd, 4)) { @@ -12053,6 +12130,9 @@ static void clif_parse_ChatAddMember(int fd, struct map_session_data *sd) __attr /// 00d9 <chat ID>.L <passwd>.8B static void clif_parse_ChatAddMember(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int chatid = RFIFOL(fd,2); const char *password = RFIFOP(fd,6); // not zero-terminated @@ -12067,6 +12147,9 @@ static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd) /// 1 = public static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int len = (int)RFIFOW(fd, 2) - 15; int limit; bool pub; @@ -12079,6 +12162,8 @@ static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd) return; limit = RFIFOW(fd, 4); + if (limit < 0) + return; pub = (RFIFOB(fd, 6) != 0); password = RFIFOP(fd, 7); // not zero-terminated title = RFIFOP(fd, 15); // not zero-terminated @@ -12097,6 +12182,9 @@ static void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd) __at /// 1 = normal static void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + chat->change_owner(sd, RFIFOP(fd,6)); // non null terminated } @@ -12105,6 +12193,9 @@ static void clif_parse_KickFromChat(int fd, struct map_session_data *sd) __attri /// 00e2 <name>.24B static void clif_parse_KickFromChat(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + chat->kick(sd, RFIFOP(fd,2)); // non null terminated } @@ -12113,6 +12204,9 @@ static void clif_parse_ChatLeave(int fd, struct map_session_data *sd) __attribut /// 00e3 static void clif_parse_ChatLeave(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + chat->leave(sd, false); } @@ -12137,9 +12231,10 @@ static void clif_parse_TradeRequest(int fd, struct map_session_data *sd) __attri /// 00e4 <account id>.L static void clif_parse_TradeRequest(int fd, struct map_session_data *sd) { - struct map_session_data *t_sd; + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; - t_sd = map->id2sd(RFIFOL(fd,2)); + struct map_session_data *t_sd = map->id2sd(RFIFOL(fd, 2)); if (sd->chat_id == 0 && pc_cant_act(sd)) return; //You can trade while in a chatroom. @@ -12166,6 +12261,9 @@ static void clif_parse_TradeAck(int fd, struct map_session_data *sd) __attribute /// 4 = rejected static void clif_parse_TradeAck(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + trade->ack(sd,RFIFOB(fd,2)); } @@ -12174,6 +12272,9 @@ static void clif_parse_TradeAddItem(int fd, struct map_session_data *sd) __attri /// 00e8 <index>.W <amount>.L static void clif_parse_TradeAddItem(int fd, struct map_session_data *sd) { + if (!sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + short index = RFIFOW(fd,2); int amount = RFIFOL(fd,4); @@ -12188,6 +12289,8 @@ static void clif_parse_TradeOk(int fd, struct map_session_data *sd) __attribute_ /// 00eb static void clif_parse_TradeOk(int fd, struct map_session_data *sd) { + if (pc_isdead(sd) || pc_isvending(sd)) + return; trade->ok(sd); } @@ -12196,6 +12299,9 @@ static void clif_parse_TradeCancel(int fd, struct map_session_data *sd) __attrib /// 00ed static void clif_parse_TradeCancel(int fd, struct map_session_data *sd) { + if (pc_isdead(sd) || pc_isvending(sd)) + return; + trade->cancel(sd); } @@ -12204,6 +12310,9 @@ static void clif_parse_TradeCommit(int fd, struct map_session_data *sd) __attrib /// 00ef static void clif_parse_TradeCommit(int fd, struct map_session_data *sd) { + if (pc_isdead(sd) || pc_isvending(sd)) + return; + trade->commit(sd); } @@ -12632,7 +12741,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin return; } //You can't use Graffiti/TalkieBox AND have a vending open, so this is safe. - safestrncpy(sd->message, RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE); + safestrncpy(sd->message, RFIFOP(fd, skillmoreinfo), TALKBOX_MESSAGE_SIZE); } if( sd->ud.skilltimer != INVALID_TIMER ) @@ -12766,7 +12875,7 @@ static void clif_parse_ProduceMix(int fd, struct map_session_data *sd) default: return; } - if (pc_istrading(sd)) { + if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) { //Make it fail to avoid shop exploits where you sell something different than you see. clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0); clif_menuskill_clear(sd); @@ -12797,7 +12906,7 @@ static void clif_parse_Cooking(int fd, struct map_session_data *sd) if (type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY) return; - if (pc_istrading(sd)) { + if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) { //Make it fail to avoid shop exploits where you sell something different than you see. clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0); clif_menuskill_clear(sd); @@ -12817,7 +12926,7 @@ static void clif_parse_RepairItem(int fd, struct map_session_data *sd) if (sd->menuskill_id != BS_REPAIRWEAPON) return; - if (pc_istrading(sd)) { + if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) { //Make it fail to avoid shop exploits where you sell something different than you see. clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0); clif_menuskill_clear(sd); @@ -12832,19 +12941,17 @@ static void clif_parse_WeaponRefine(int fd, struct map_session_data *sd) __attri /// 0222 <index>.L static void clif_parse_WeaponRefine(int fd, struct map_session_data *sd) { - int idx; - sd->state.prerefining = 0; if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit? return; - if (pc_istrading(sd)) { + if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) { //Make it fail to avoid shop exploits where you sell something different than you see. clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0); clif_menuskill_clear(sd); return; } - idx = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]); + int idx = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]); skill->weaponrefine(sd, idx-2); clif_menuskill_clear(sd); } @@ -12859,6 +12966,9 @@ static void clif_parse_NpcSelectMenu(int fd, struct map_session_data *sd) __attr /// overflows to choice%256. static void clif_parse_NpcSelectMenu(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int npc_id = RFIFOL(fd,2); uint8 select = RFIFOB(fd,6); @@ -12884,6 +12994,9 @@ static void clif_parse_NpcNextClicked(int fd, struct map_session_data *sd) __att /// 00b9 <npc id>.L static void clif_parse_NpcNextClicked(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + npc->scriptcont(sd,RFIFOL(fd,2), false); } @@ -12892,6 +13005,9 @@ static void clif_parse_NpcAmountInput(int fd, struct map_session_data *sd) __att /// 0143 <npc id>.L <value>.L static void clif_parse_NpcAmountInput(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int npcid = RFIFOL(fd,2); int amount = RFIFOL(fd,6); @@ -12916,6 +13032,9 @@ static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd) __att /// 01d5 <packet len>.W <npc id>.L <string>.?B static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int len = RFIFOW(fd, 2); // [4144] can't confirm exact client version. At least >= correct for 20150513 #if PACKETVER >= 20151029 @@ -12943,6 +13062,8 @@ static void clif_parse_NpcCloseClicked(int fd, struct map_session_data *sd) { if (!sd->npc_id) //Avoid parsing anything when the script was done with. [Skotlex] return; + if (sd->state.trading || pc_isvending(sd)) + return; sd->state.dialog = 0; npc->scriptcont(sd, RFIFOL(fd,2), true); } @@ -12954,6 +13075,9 @@ static void clif_parse_ItemIdentify(int fd, struct map_session_data *sd) __attri /// -1 = cancel static void clif_parse_ItemIdentify(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + short idx = RFIFOW(fd,2); if (sd->menuskill_id != MC_IDENTIFY) @@ -12972,6 +13096,9 @@ static void clif_parse_ItemIdentify(int fd, struct map_session_data *sd) /// 0A35 <index>.W static void clif_parse_OneClick_ItemIdentify(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int cmd = RFIFOW(fd,0); short idx = RFIFOW(fd, packet_db[cmd].pos[0]) - 2; int n; @@ -12979,7 +13106,7 @@ static void clif_parse_OneClick_ItemIdentify(int fd, struct map_session_data *sd if (idx < 0 || idx >= sd->status.inventorySize || sd->inventory_data[idx] == NULL || sd->status.inventory[idx].nameid <= 0) return; - if ((n = pc->have_magnifier(sd) ) != INDEX_NOT_FOUND && + if ((n = pc->have_magnifier(sd)) != INDEX_NOT_FOUND && pc->delitem(sd, n, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME) == 0) skill->identify(sd, idx); } @@ -12990,7 +13117,7 @@ static void clif_parse_SelectArrow(int fd, struct map_session_data *sd) __attrib static void clif_parse_SelectArrow(int fd, struct map_session_data *sd) { int itemId; - if (pc_istrading(sd)) { + if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) { //Make it fail to avoid shop exploits where you sell something different than you see. clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0); clif_menuskill_clear(sd); @@ -13027,6 +13154,9 @@ static void clif_parse_AutoSpell(int fd, struct map_session_data *sd) __attribut /// 01ce <skill id>.L static void clif_parse_AutoSpell(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + uint16 skill_id = RFIFOL(fd,2); sd->state.workinprogress = 0; @@ -13046,6 +13176,9 @@ static void clif_parse_UseCard(int fd, struct map_session_data *sd) __attribute_ /// 017a <card index>.W static void clif_parse_UseCard(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + clif->use_card(sd,RFIFOW(fd,2)-2); } @@ -13054,6 +13187,9 @@ static void clif_parse_InsertCard(int fd, struct map_session_data *sd) __attribu /// 017c <card index>.W <equip index>.W static void clif_parse_InsertCard(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + pc->insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2); } @@ -13079,6 +13215,9 @@ static void clif_parse_ResetChar(int fd, struct map_session_data *sd) __attribut /// 1 = skill static void clif_parse_ResetChar(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + char cmd[15]; if( RFIFOW(fd,2) ) @@ -13264,6 +13403,9 @@ static void clif_parse_CreateParty(int fd, struct map_session_data *sd) __attrib /// 01e8 <party name>.24B <item pickup rule>.B <item share rule>.B (CZ_MAKE_GROUP2) static void clif_parse_CreateParty(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + char name[NAME_LENGTH]; safestrncpy(name, RFIFOP(fd,2), NAME_LENGTH); @@ -13284,6 +13426,9 @@ static void clif_parse_CreateParty(int fd, struct map_session_data *sd) static void clif_parse_CreateParty2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_CreateParty2(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + char name[NAME_LENGTH]; int item1 = RFIFOB(fd,26); int item2 = RFIFOB(fd,27); @@ -13309,6 +13454,9 @@ static void clif_parse_PartyInvite(int fd, struct map_session_data *sd) __attrib /// 02c4 <char name>.24B (CZ_PARTY_JOIN_REQ) static void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + struct map_session_data *t_sd; if(map->list[sd->bl.m].flag.partylock) { @@ -13330,6 +13478,9 @@ static void clif_parse_PartyInvite(int fd, struct map_session_data *sd) static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + struct map_session_data *t_sd; char name[NAME_LENGTH]; @@ -13341,7 +13492,7 @@ static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) return; } - t_sd = map->nick2sd(name); + t_sd = map->nick2sd(name, true); if(t_sd && t_sd->state.noask) { // @noask [LuzZza] clif->noask_sub(sd, t_sd, 1); @@ -13360,13 +13511,23 @@ static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd) __a /// 1 = accept static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd) { - party->reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6)); + if (pc_istrading(sd) || pc_isvending(sd)) { + party->reply_invite(sd, RFIFOL(fd, 2), 0); + return; + } + + party->reply_invite(sd, RFIFOL(fd, 2), RFIFOL(fd, 6)); } static void clif_parse_ReplyPartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_ReplyPartyInvite2(int fd, struct map_session_data *sd) { - party->reply_invite(sd,RFIFOL(fd,2),RFIFOB(fd,6)); + if (pc_istrading(sd) || pc_isvending(sd)) { + party->reply_invite(sd, RFIFOL(fd, 2), 0); + return; + } + + party->reply_invite(sd, RFIFOL(fd, 2), RFIFOB(fd, 6)); } static void clif_parse_LeaveParty(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -13374,7 +13535,10 @@ static void clif_parse_LeaveParty(int fd, struct map_session_data *sd) __attribu /// 0100 static void clif_parse_LeaveParty(int fd, struct map_session_data *sd) { - if(map->list[sd->bl.m].flag.partylock) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + + if (map->list[sd->bl.m].flag.partylock) { // Party locked. clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map. return; @@ -13387,12 +13551,15 @@ static void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) __ /// 0103 <account id>.L <char name>.24B static void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) { - if(map->list[sd->bl.m].flag.partylock) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + + if (map->list[sd->bl.m].flag.partylock) { // Party locked. clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map. return; } - party->removemember(sd, RFIFOL(fd,2), RFIFOP(fd,6)); + party->removemember(sd, RFIFOL(fd, 2), RFIFOP(fd, 6)); } static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -13401,6 +13568,9 @@ static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) __ /// 07d7 <exp share rule>.L <item pickup rule>.B <item share rule>.B (CZ_GROUPINFO_CHANGE_V2) static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + struct party_data *p; int i; @@ -13453,6 +13623,9 @@ static void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd) __ /// 07da <account id>.L static void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + party->changeleader(sd, map->id2sd(RFIFOL(fd,2))); } @@ -13465,6 +13638,9 @@ static void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data * static void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *sd) { #ifndef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + short level = RFIFOW(fd,2); short mapid = RFIFOW(fd,4); short job[PARTY_BOOKING_JOBS]; @@ -13507,6 +13683,9 @@ static void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd static void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd) { #ifndef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + short level = RFIFOW(fd,2); short mapid = RFIFOW(fd,4); short job = RFIFOW(fd,6); @@ -13558,7 +13737,10 @@ static void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd static void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd) { #ifndef PARTY_RECRUIT - if(party->booking_delete(sd)) + if (pc_istrading(sd) || pc_isvending(sd)) + return; + + if (party->booking_delete(sd)) clif->PartyBookingDeleteAck(sd, 0); #else return; @@ -13594,11 +13776,13 @@ static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd) { #ifndef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + short job[PARTY_BOOKING_JOBS]; - int i; - for(i=0; i<PARTY_BOOKING_JOBS; i++) - job[i] = RFIFOW(fd,2+i*2); + for (int i = 0; i < PARTY_BOOKING_JOBS; i++) + job[i] = RFIFOW(fd, 2 + i * 2); party->booking_update(sd, job); #else @@ -13611,8 +13795,11 @@ static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd static void clif_PartyBookingInsertNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad) { #ifndef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + int i; - uint8 buf[38+PARTY_BOOKING_JOBS*2]; + uint8 buf[38 + PARTY_BOOKING_JOBS * 2]; nullpo_retv(sd); if(pb_ad == NULL) return; @@ -13679,7 +13866,10 @@ static void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data * static void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT - short level = RFIFOW(fd,2); + if (pc_istrading(sd) || pc_isvending(sd)) + return; + + short level = RFIFOW(fd, 2); const char *notice = RFIFOP(fd, 4); party->recruit_register(sd, level, notice); @@ -13750,6 +13940,9 @@ static void clif_parse_PartyRecruitSearchReq(int fd, struct map_session_data *sd static void clif_parse_PartyRecruitSearchReq(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + short level = RFIFOW(fd, 2); short mapid = RFIFOW(fd, 4); unsigned long lastindex = RFIFOL(fd, 6); @@ -13767,7 +13960,10 @@ static void clif_parse_PartyRecruitDeleteReq(int fd, struct map_session_data *sd static void clif_parse_PartyRecruitDeleteReq(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT - if(party->booking_delete(sd)) + if (pc_istrading(sd) || pc_isvending(sd)) + return; + + if (party->booking_delete(sd)) clif->PartyRecruitDeleteAck(sd, 0); #else return; @@ -13803,6 +13999,9 @@ static void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd static void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + const char *notice = RFIFOP(fd, 2); party->recruit_update(sd, notice); @@ -13876,6 +14075,9 @@ static void clif_parse_PartyBookingAddFilteringList(int fd, struct map_session_d static void clif_parse_PartyBookingAddFilteringList(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + int index = RFIFOL(fd, 2); clif->PartyBookingAddFilteringList(index, sd); @@ -13890,6 +14092,9 @@ static void clif_parse_PartyBookingSubFilteringList(int fd, struct map_session_d static void clif_parse_PartyBookingSubFilteringList(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + int gid = RFIFOL(fd, 2); clif->PartyBookingSubFilteringList(gid, sd); @@ -13904,6 +14109,9 @@ static void clif_parse_PartyBookingReqVolunteer(int fd, struct map_session_data static void clif_parse_PartyBookingReqVolunteer(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + int index = RFIFOL(fd, 2); clif->PartyBookingVolunteerInfo(index, sd); @@ -13980,6 +14188,9 @@ static void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_da static void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + unsigned int aid = RFIFOL(fd, 2); clif->PartyBookingRefuseVolunteer(aid, sd); @@ -14009,6 +14220,9 @@ static void clif_parse_PartyBookingCancelVolunteer(int fd, struct map_session_da static void clif_parse_PartyBookingCancelVolunteer(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT + if (pc_istrading(sd) || pc_isvending(sd)) + return; + int index = RFIFOL(fd, 2); clif->PartyBookingCancelVolunteer(index, sd); @@ -14084,6 +14298,9 @@ static void clif_parse_CloseVending(int fd, struct map_session_data *sd) __attri /// 012e static void clif_parse_CloseVending(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isdead(sd)) + return; + vending->close(sd); } @@ -14092,6 +14309,9 @@ static void clif_parse_VendingListReq(int fd, struct map_session_data *sd) __att /// 0130 <account id>.L static void clif_parse_VendingListReq(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isdead(sd)) + return; + if( sd->npc_id ) {// using an NPC return; } @@ -14103,6 +14323,9 @@ static void clif_parse_PurchaseReq(int fd, struct map_session_data *sd) __attrib /// 0134 <packet len>.W <account id>.L { <amount>.W <index>.W }* static void clif_parse_PurchaseReq(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int len = (int)RFIFOW(fd, 2) - 8; int id; const uint8 *data; @@ -14124,6 +14347,9 @@ static void clif_parse_PurchaseReq2(int fd, struct map_session_data *sd) __attri /// 0801 <packet len>.W <account id>.L <unique id>.L { <amount>.W <index>.W }* static void clif_parse_PurchaseReq2(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int len = (int)RFIFOW(fd, 2) - 12; int aid; int uid; @@ -14150,25 +14376,25 @@ static void clif_parse_OpenVending(int fd, struct map_session_data *sd) __attrib /// 1 = open static void clif_parse_OpenVending(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isdead(sd) || sd->state.vending || sd->state.buyingstore) + return; + int len = (int)RFIFOW(fd, 2) - 85; - const char *message; - bool flag; - const uint8 *data; if (len < 0) return; - message = RFIFOP(fd,4); - flag = (RFIFOB(fd,84) != 0) ? true : false; - data = 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 ) + if (!flag) sd->state.prevend = sd->state.workinprogress = 0; - if(pc_ismuted(&sd->sc, MANNER_NOROOM)) + if (pc_ismuted(&sd->sc, MANNER_NOROOM)) return; - if( map->list[sd->bl.m].flag.novending ) { - clif->message (sd->fd, msg_sd(sd,276)); // "You can't open a shop on this map" + if (map->list[sd->bl.m].flag.novending) { + clif->message (sd->fd, msg_sd(sd, 276)); // "You can't open a shop on this map" return; } if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING)) { @@ -14187,11 +14413,14 @@ static void clif_parse_CreateGuild(int fd, struct map_session_data *sd) __attrib /// 0165 <char id>.L <guild name>.24B static void clif_parse_CreateGuild(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + char name[NAME_LENGTH]; safestrncpy(name, RFIFOP(fd,6), NAME_LENGTH); - if(map->list[sd->bl.m].flag.guildlock) { - clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map. + if (map->list[sd->bl.m].flag.guildlock) { + clif->message(fd, msg_fd(fd, 228)); // Guild modification is disabled in this map. return; } @@ -14226,6 +14455,7 @@ static void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) case 0: // Basic Information Guild, hostile alliance information clif->guild_basicinfo(sd); clif->guild_allianceinfo(sd); + clif->guild_castlelist(sd); break; case 1: // Members list, list job title clif->guild_positionnamelist(sd); @@ -14252,6 +14482,9 @@ static void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data * /// 0161 <packet len>.W { <position id>.L <mode>.L <ranking>.L <pay rate>.L <name>.24B }* static void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int i; int count = (RFIFOW(fd, 2) - 4) / 40; @@ -14269,6 +14502,9 @@ static void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data /// 0155 <packet len>.W { <account id>.L <char id>.L <position id>.L }* static void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int i; int len = RFIFOW(fd, 2); int count = (len - 4) / 12; @@ -14434,10 +14670,13 @@ static void clif_parse_GuildChangeEmblem(int fd, struct map_session_data *sd) __ /// 0153 <packet len>.W <emblem data>.?B static void clif_parse_GuildChangeEmblem(int fd, struct map_session_data *sd) { - unsigned int emblem_len = RFIFOW(fd,2)-4; - const uint8* emblem = RFIFOP(fd,4); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; - if( !emblem_len || !sd->state.gmaster_flag ) + unsigned int emblem_len = RFIFOW(fd, 2) - 4; + const uint8* emblem = RFIFOP(fd, 4); + + if (!emblem_len || !sd->state.gmaster_flag) return; if (!clif->validate_emblem(emblem, emblem_len)) { @@ -14454,7 +14693,10 @@ static void clif_parse_GuildChangeNotice(int fd, struct map_session_data *sd) __ /// 016e <guild id>.L <msg1>.60B <msg2>.120B static void clif_parse_GuildChangeNotice(int fd, struct map_session_data *sd) { - int guild_id = RFIFOL(fd,2); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + int guild_id = RFIFOL(fd, 2); char *msg1 = NULL, *msg2 = NULL; if (!sd->state.gmaster_flag) @@ -14506,6 +14748,9 @@ static void clif_parse_GuildInvite(int fd, struct map_session_data *sd) __attrib /// 0168 <account id>.L <inviter account id>.L <inviter char id>.L static void clif_parse_GuildInvite(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct map_session_data *t_sd = map->id2sd(RFIFOL(fd,2)); if (!clif_sub_guild_invite(fd, sd, t_sd)) @@ -14521,7 +14766,7 @@ static void clif_parse_GuildInvite2(int fd, struct map_session_data *sd) struct map_session_data *t_sd = NULL; safestrncpy(nick, RFIFOP(fd, 2), NAME_LENGTH); - t_sd = map->nick2sd(nick); + t_sd = map->nick2sd(nick, true); clif_sub_guild_invite(fd, sd, t_sd); } @@ -14534,7 +14779,7 @@ static void clif_parse_GuildReplyInvite(int fd, struct map_session_data *sd) __a /// 1 = accept static void clif_parse_GuildReplyInvite(int fd, struct map_session_data *sd) { - guild->reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6)); + guild->reply_invite(sd, RFIFOL(fd, 2), RFIFOL(fd, 6)); } static void clif_parse_GuildLeave(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -14542,16 +14787,19 @@ static void clif_parse_GuildLeave(int fd, struct map_session_data *sd) __attribu /// 0159 <guild id>.L <account id>.L <char id>.L <reason>.40B static void clif_parse_GuildLeave(int fd, struct map_session_data *sd) { - if(map->list[sd->bl.m].flag.guildlock) { - clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map. + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + if (map->list[sd->bl.m].flag.guildlock) { + clif->message(fd, msg_fd(fd, 228)); // Guild modification is disabled in this map. return; } - if( sd->bg_id ) { - clif->message(fd, msg_fd(fd,870)); //"You can't leave battleground guilds." + if (sd->bg_id) { + clif->message(fd, msg_fd(fd, 870)); //"You can't leave battleground guilds." return; } - guild->leave(sd,RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOP(fd,14)); + guild->leave(sd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10), RFIFOP(fd, 14)); } static void clif_parse_GuildExpulsion(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -14559,11 +14807,14 @@ static void clif_parse_GuildExpulsion(int fd, struct map_session_data *sd) __att /// 015b <guild id>.L <account id>.L <char id>.L <reason>.40B static void clif_parse_GuildExpulsion(int fd, struct map_session_data *sd) { - if( map->list[sd->bl.m].flag.guildlock || sd->bg_id ) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + if (map->list[sd->bl.m].flag.guildlock || sd->bg_id) { 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), RFIFOP(fd,14)); + guild->expulsion(sd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10), RFIFOP(fd, 14)); } /** @@ -14596,6 +14847,9 @@ static void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) /// 0170 <account id>.L <inviter account id>.L <inviter char id>.L static void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct map_session_data *t_sd; if(!sd->state.gmaster_flag) @@ -14636,6 +14890,9 @@ static void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) __a /// 1 = Enemy static void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + if(!sd->state.gmaster_flag) return; @@ -14651,6 +14908,9 @@ static void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) __at /// 0180 <account id>.L static void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct map_session_data *t_sd; if(!sd->state.gmaster_flag) @@ -14680,6 +14940,9 @@ static void clif_parse_GuildBreak(int fd, struct map_session_data *sd) __attribu /// field name and size is same as the one in CH_DELETE_CHAR. static void clif_parse_GuildBreak(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + char key[40]; if( map->list[sd->bl.m].flag.guildlock ) { clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map. @@ -14703,7 +14966,10 @@ static void clif_parse_PetMenu(int fd, struct map_session_data *sd) __attribute_ /// 4 = unequip accessory static void clif_parse_PetMenu(int fd, struct map_session_data *sd) { - pet->menu(sd,RFIFOB(fd,2)); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + pet->menu(sd, RFIFOB(fd, 2)); } static void clif_parse_CatchPet(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -14711,7 +14977,10 @@ static void clif_parse_CatchPet(int fd, struct map_session_data *sd) __attribute /// 019f <id>.L static void clif_parse_CatchPet(int fd, struct map_session_data *sd) { - pet->catch_process2(sd,RFIFOL(fd,2)); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + pet->catch_process2(sd, RFIFOL(fd, 2)); } static void clif_parse_SelectEgg(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -14719,10 +14988,13 @@ static void clif_parse_SelectEgg(int fd, struct map_session_data *sd) __attribut /// 01a7 <index>.W static void clif_parse_SelectEgg(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1) { return; } - pet->select_egg(sd,RFIFOW(fd,2)-2); + pet->select_egg(sd, RFIFOW(fd, 2) - 2); clif_menuskill_clear(sd); } @@ -14762,6 +15034,9 @@ static void clif_parse_ChangePetName(int fd, struct map_session_data *sd) __attr /// 01a5 <name>.24B static void clif_parse_ChangePetName(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + pet->change_name(sd, RFIFOP(fd,2)); } @@ -14770,6 +15045,9 @@ static void clif_parse_pet_evolution(int fd, struct map_session_data *sd) __attr /// 09fb <Length>.W <EvolvedPetEggID>.W {<index>.W <amount>.W}*items static void clif_parse_pet_evolution(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_PET_EVOLUTION *p = RP2PTR(fd); int i = 0, idx, petIndex; @@ -14958,7 +15236,7 @@ static 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[NAME_LENGTH]; - char command[NAME_LENGTH+8]; + char command[NAME_LENGTH + 20]; safestrncpy(player_name, RFIFOP(fd,2), NAME_LENGTH); @@ -14977,7 +15255,7 @@ static void clif_parse_GMRemove2(int fd, struct map_session_data *sd) account_id = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]); if( (pl_sd = map->id2sd(account_id)) != NULL ) { - char command[NAME_LENGTH+8]; + char command[NAME_LENGTH + 20]; sprintf(command, "%cjumpto %s", atcommand->at_symbol, pl_sd->status.name); atcommand->exec(fd, sd, command, true); } @@ -15014,7 +15292,7 @@ static void clif_parse_GMRecall2(int fd, struct map_session_data *sd) account_id = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]); if( (pl_sd = map->id2sd(account_id)) != NULL ) { - char command[NAME_LENGTH+8]; + char command[NAME_LENGTH + 20]; sprintf(command, "%crecall %s", atcommand->at_symbol, pl_sd->status.name); atcommand->exec(fd, sd, command, true); } @@ -15045,7 +15323,7 @@ static void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) safestrncpy(item_monster_name, p->str, sizeof(item_monster_name)); - if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ) { + if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, IT_SEARCH_NAME_EXACT)) > 0 ) { for(i = 0; i < count; i++) { if( !item_array[i] ) continue; @@ -15345,6 +15623,9 @@ static void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) __att /// 01e7 static void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + if (sd->state.doridori) return; switch (sd->job & MAPID_UPPERMASK) { @@ -15371,6 +15652,9 @@ static void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *s /// "Help me out~ Please~ T_T" static void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + /* [Ind/Hercules] */ /* 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) */ @@ -15514,13 +15798,16 @@ static void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) __att /// 0202 <name>.24B static void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct map_session_data *f_sd; int i; char nick[NAME_LENGTH]; safestrncpy(nick, RFIFOP(fd,2), NAME_LENGTH); - f_sd = map->nick2sd(nick); + f_sd = map->nick2sd(nick, true); // ensure that the request player's friend list is not full ARR_FIND(0, MAX_FRIENDS, i, sd->status.friends[i].char_id == 0); @@ -15635,6 +15922,9 @@ static void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd) __ /// 0203 <account id>.L <char id>.L static void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct map_session_data *f_sd = NULL; int account_id, char_id; int i, j; @@ -15724,60 +16014,95 @@ static void clif_parse_PVPInfo(int fd, struct map_session_data *sd) /// Ranking list /// ranking pointlist { <name>.24B <point>.L }*10 -static void clif_ranklist_sub(unsigned char *buf, enum fame_list_type type) +static void clif_ranklist_sub(struct PACKET_ZC_ACK_RANKING_sub *ranks, enum fame_list_type type) { - const char* name; - struct fame_list* list; - int i; +#if !(PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724) + nullpo_retv(ranks); - nullpo_retv(buf); - switch( type ) { + struct fame_list* list; + switch (type) { case RANKTYPE_BLACKSMITH: list = pc->smith_fame_list; break; case RANKTYPE_ALCHEMIST: list = pc->chemist_fame_list; break; case RANKTYPE_TAEKWON: list = pc->taekwon_fame_list; break; default: return; // Unsupported } + int i; // Packet size limits this list to 10 elements. [Skotlex] - 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(WBUFP(buf, 24 * i), name, NAME_LENGTH); + for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) { + if (list[i].id > 0) { + const char* name; + if (strcmp(list[i].name, "-") == 0 && (name = map->charid2nick(list[i].id)) != NULL) { + strncpy(ranks->names[i].name, name, NAME_LENGTH); } else { - strncpy(WBUFP(buf, 24 * i), list[i].name, NAME_LENGTH); + strncpy(ranks->names[i].name, list[i].name, NAME_LENGTH); } } else { - strncpy(WBUFP(buf, 24 * i), "None", 5); + strncpy(ranks->names[i].name, "None", 5); + } + ranks->points[i].points = list[i].fame; //points + } + for (;i < 10; i++) { // In case the MAX is less than 10. + strncpy(ranks->names[i].name, "Unavailable", 12); + ranks->points[i].points = 0; + } +#endif +} + +static void clif_ranklist_sub2(uint32 *chars, uint32 *points, enum fame_list_type type) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724 + nullpo_retv(chars); + nullpo_retv(points); + + struct fame_list* list; + switch (type) { + case RANKTYPE_BLACKSMITH: list = pc->smith_fame_list; break; + case RANKTYPE_ALCHEMIST: list = pc->chemist_fame_list; break; + case RANKTYPE_TAEKWON: list = pc->taekwon_fame_list; break; + default: return; // Unsupported + } + + int i; + // Packet size limits this list to 10 elements. [Skotlex] + for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) { + if (list[i].id > 0) { + chars[i] = list[i].id; + } else { + chars[i] = 0; } - WBUFL(buf, 24 * 10 + i * 4) = list[i].fame; //points + points[i] = list[i].fame; //points } - for( ;i < 10; i++ ) { // In case the MAX is less than 10. - strncpy(WBUFP(buf, 24 * i), "Unavailable", 12); - WBUFL(buf, 24 * 10 + i * 4) = 0; + for (;i < 10; i++) { // In case the MAX is less than 10. + chars[i] = 0; + points[i] = 0; } +#endif } /// 097d <RankingType>.W {<CharName>.24B <point>L}*10 <mypoint>L (ZC_ACK_RANKING) static void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) { -#if PACKETVER >= 20120502 - int fd; - int len = packet_len(0x97d); - +#if PACKETVER_MAIN_NUM >= 20130605 || PACKETVER_RE_NUM >= 20130529 || defined(PACKETVER_ZERO) nullpo_retv(sd); - fd = sd->fd; - WFIFOHEAD(fd, len); - WFIFOW(fd, 0) = 0x97d; - WFIFOW(fd, 2) = type; - clif_ranklist_sub(WFIFOP(fd,4), type); + int fd = sd->fd; + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_ACK_RANKING)); + struct PACKET_ZC_ACK_RANKING *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_ACK_RANKING; + p->rankType = type; +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724 + clif->ranklist_sub2(p->chars, p->points, type); +#else + clif->ranklist_sub(&p->ranks, type); +#endif if (pc->famelist_type(sd->job) == type) { - WFIFOL(fd, 284) = sd->status.fame; //mypoint + p->myPoints = sd->status.fame; //mypoint } else { - WFIFOL(fd, 284) = 0; //mypoint + p->myPoints = 0; //mypoint } - WFIFOSET(fd, len); + WFIFOSET(fd, sizeof(struct PACKET_ZC_ACK_RANKING)); #endif } @@ -15827,14 +16152,16 @@ static void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list /// 0219 { <name>.24B }*10 { <point>.L }*10 static void clif_blacksmith(struct map_session_data *sd) { +#if !(PACKETVER_MAIN_NUM >= 20130605 || PACKETVER_RE_NUM >= 20130529 || defined(PACKETVER_ZERO)) int fd; nullpo_retv(sd); fd = sd->fd; WFIFOHEAD(fd,packet_len(0x219)); WFIFOW(fd,0) = 0x219; - clif_ranklist_sub(WFIFOP(fd, 2), RANKTYPE_BLACKSMITH); + clif->ranklist_sub(WFIFOP(fd, 2), RANKTYPE_BLACKSMITH); WFIFOSET(fd, packet_len(0x219)); +#endif } static void clif_parse_Blacksmith(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -15864,14 +16191,16 @@ static void clif_fame_blacksmith(struct map_session_data *sd, int points) /// 021a { <name>.24B }*10 { <point>.L }*10 static void clif_alchemist(struct map_session_data *sd) { +#if !(PACKETVER_MAIN_NUM >= 20130605 || PACKETVER_RE_NUM >= 20130529 || defined(PACKETVER_ZERO)) int fd; nullpo_retv(sd); fd = sd->fd; WFIFOHEAD(fd,packet_len(0x21a)); WFIFOW(fd,0) = 0x21a; - clif_ranklist_sub(WFIFOP(fd,2), RANKTYPE_ALCHEMIST); + clif->ranklist_sub(WFIFOP(fd,2), RANKTYPE_ALCHEMIST); WFIFOSET(fd, packet_len(0x21a)); +#endif } static void clif_parse_Alchemist(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -15901,14 +16230,16 @@ static void clif_fame_alchemist(struct map_session_data *sd, int points) /// 0226 { <name>.24B }*10 { <point>.L }*10 static void clif_taekwon(struct map_session_data *sd) { +#if !(PACKETVER_MAIN_NUM >= 20130605 || PACKETVER_RE_NUM >= 20130529 || defined(PACKETVER_ZERO)) int fd; nullpo_retv(sd); fd = sd->fd; WFIFOHEAD(fd,packet_len(0x226)); WFIFOW(fd,0) = 0x226; - clif_ranklist_sub(WFIFOP(fd,2), RANKTYPE_TAEKWON); + clif->ranklist_sub(WFIFOP(fd,2), RANKTYPE_TAEKWON); WFIFOSET(fd, packet_len(0x226)); +#endif } static void clif_parse_Taekwon(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -15968,6 +16299,9 @@ static void clif_parse_FeelSaveOk(int fd, struct map_session_data *sd) __attribu /// 2 = star static void clif_parse_FeelSaveOk(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int i; if (sd->menuskill_id != SG_FEEL) return; @@ -16009,6 +16343,9 @@ static void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) /// 0231 <name>.24B static void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + homun->change_name(sd, RFIFOP(fd,2)); } @@ -16017,6 +16354,9 @@ static void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) __at /// 0234 <id>.L static void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int id = RFIFOL(fd,2); // Mercenary or Homunculus struct block_list *bl = NULL; struct unit_data *ud = NULL; @@ -16038,6 +16378,9 @@ static void clif_parse_HomMoveTo(int fd, struct map_session_data *sd) __attribut /// 0232 <id>.L <position data>.3B static void clif_parse_HomMoveTo(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int id = RFIFOL(fd,2); // Mercenary or Homunculus struct block_list *bl = NULL; short x, y; @@ -16061,6 +16404,9 @@ static void clif_parse_HomAttack(int fd, struct map_session_data *sd) __attribut /// always 0 static void clif_parse_HomAttack(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct block_list *bl = NULL; int id = RFIFOL(fd,2), target_id = RFIFOL(fd,6), @@ -16087,6 +16433,9 @@ static void clif_parse_HomMenu(int fd, struct map_session_data *sd) __attribute_ /// 2 = delete static void clif_parse_HomMenu(int fd, struct map_session_data *sd) { //[orn] + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int cmd; cmd = RFIFOW(fd,0); @@ -16102,7 +16451,16 @@ static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) __attribu /// 0292 static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) { - int item_position = pc->search_inventory(sd, ITEMID_TOKEN_OF_SIEGFRIED); + if (pc_istrading(sd) || pc_isvending(sd)) + return; + + if (!pc_isdead(sd)) + return; + + if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER. + return; + + int item_position = pc->have_item_chain(sd, ECC_SIEGFRIED); int hpsp = 100; if (item_position == INDEX_NOT_FOUND) { @@ -16112,18 +16470,15 @@ static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) return; } - if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER. - return; - if (!status->revive(&sd->bl, hpsp, hpsp)) return; if (item_position == INDEX_NOT_FOUND) - status_change_end(&sd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER); + status_change_end(&sd->bl, SC_LIGHT_OF_REGENE, INVALID_TIMER); else pc->delitem(sd, item_position, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); - clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); + clif->skill_nodamage(&sd->bl, &sd->bl, ALL_RESURRECTION, 4, 1); } /// Information about character's status values (ZC_ACK_STATUS_GM). @@ -16173,6 +16528,9 @@ static void clif_parse_Check(int fd, struct map_session_data *sd) __attribute__( /// 0213 <char name>.24B static void clif_parse_Check(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isvending(sd)) + return; + char charname[NAME_LENGTH]; struct map_session_data* pl_sd; @@ -16181,7 +16539,7 @@ static void clif_parse_Check(int fd, struct map_session_data *sd) 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) ) { + if ((pl_sd = map->nick2sd(charname, true)) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd)) { return; } @@ -16325,7 +16683,7 @@ static 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); + sprintf(output, msg_sd(sd, 511), MAIL_MAX_INBOX); // Inbox is full (Max %d). Delete some mails. clif_disp_onlyself(sd, output); } } @@ -16335,6 +16693,9 @@ static void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd) __ /// 023f static void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct mail_data* md = &sd->mail.inbox; if( md->amount < MAIL_MAX_INBOX && (md->full || sd->mail.changed) ) @@ -16418,6 +16779,9 @@ static void clif_parse_Mail_read(int fd, struct map_session_data *sd) __attribut /// 0241 <mail id>.L static void clif_parse_Mail_read(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int mail_id = RFIFOL(fd,2); if( mail_id <= 0 ) @@ -16433,6 +16797,9 @@ static void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) __att /// 0244 <mail id>.L static void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int mail_id = RFIFOL(fd,2); int i; @@ -16501,6 +16868,9 @@ static void clif_parse_Mail_delete(int fd, struct map_session_data *sd) __attrib /// 0243 <mail id>.L static void clif_parse_Mail_delete(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int mail_id = RFIFOL(fd,2); int i; @@ -16532,6 +16902,9 @@ static void clif_parse_Mail_return(int fd, struct map_session_data *sd) __attrib /// 0273 <mail id>.L <receive name>.24B static void clif_parse_Mail_return(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int mail_id = RFIFOL(fd,2); int i; @@ -16556,6 +16929,9 @@ static void clif_parse_Mail_setattach(int fd, struct map_session_data *sd) __att /// 0247 <index>.W <amount>.L static void clif_parse_Mail_setattach(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int idx = RFIFOW(fd,2); int amount = RFIFOL(fd,4); unsigned char flag; @@ -16578,6 +16954,9 @@ static void clif_parse_Mail_winopen(int fd, struct map_session_data *sd) __attri /// 2 = remove zeny static void clif_parse_Mail_winopen(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int flag = RFIFOW(fd,2); if (flag == 0 || flag == 1) @@ -16592,6 +16971,9 @@ static void clif_parse_Mail_send(int fd, struct map_session_data *sd) __attribut static void clif_parse_Mail_send(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct mail_message msg; int body_len; int len = RFIFOW(fd, 2); @@ -16748,7 +17130,10 @@ static void clif_parse_Auction_cancelreg(int fd, struct map_session_data *sd) __ /// ? = junk, uninitialized value (ex. when switching between list filters) static void clif_parse_Auction_cancelreg(int fd, struct map_session_data *sd) { - if( sd->auction.amount > 0 ) + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + if (sd->auction.amount > 0) clif->additem(sd, sd->auction.index, sd->auction.amount, 0); sd->auction.amount = 0; @@ -16759,8 +17144,11 @@ static void clif_parse_Auction_setitem(int fd, struct map_session_data *sd) __at /// 024c <index>.W <count>.L static void clif_parse_Auction_setitem(int fd, struct map_session_data *sd) { - int idx = RFIFOW(fd,2) - 2; - int amount = RFIFOL(fd,4); // Always 1 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + int idx = RFIFOW(fd, 2) - 2; + int amount = RFIFOL(fd, 4); // Always 1 struct item_data *item; if( !battle_config.feature_auction ) @@ -16838,6 +17226,9 @@ static void clif_parse_Auction_register(int fd, struct map_session_data *sd) __a /// 024d <now money>.L <max money>.L <delete hour>.W static void clif_parse_Auction_register(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct auction_data auction; struct item_data *item; @@ -16933,7 +17324,10 @@ static void clif_parse_Auction_cancel(int fd, struct map_session_data *sd) __att /// 024e <auction id>.L static void clif_parse_Auction_cancel(int fd, struct map_session_data *sd) { - unsigned int auction_id = RFIFOL(fd,2); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + unsigned int auction_id = RFIFOL(fd, 2); intif->Auction_cancel(sd->status.char_id, auction_id); } @@ -16943,6 +17337,9 @@ static void clif_parse_Auction_close(int fd, struct map_session_data *sd) __attr /// 025d <auction id>.L static void clif_parse_Auction_close(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + unsigned int auction_id = RFIFOL(fd,2); intif->Auction_close(sd->status.char_id, auction_id); @@ -16953,8 +17350,11 @@ static void clif_parse_Auction_bid(int fd, struct map_session_data *sd) __attrib /// 024f <auction id>.L <money>.L static void clif_parse_Auction_bid(int fd, struct map_session_data *sd) { - unsigned int auction_id = RFIFOL(fd,2); - int bid = RFIFOL(fd,6); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + unsigned int auction_id = RFIFOL(fd, 2); + 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)); // Your GM level doesn't authorize you to perform this action. @@ -16985,9 +17385,12 @@ static void clif_parse_Auction_search(int fd, struct map_session_data *sd) __att /// 5 = auction id search static void clif_parse_Auction_search(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + char search_text[NAME_LENGTH]; - short type = RFIFOW(fd,2), page = RFIFOW(fd,32); - int price = RFIFOL(fd,4); // FIXME: bug #5071 + short type = RFIFOW(fd, 2), page = RFIFOW(fd, 32); + int price = RFIFOL(fd, 4); // FIXME: bug #5071 if( !battle_config.feature_auction ) return; @@ -17006,7 +17409,10 @@ static void clif_parse_Auction_buysell(int fd, struct map_session_data *sd) __at /// 1 = buy (own bids) static void clif_parse_Auction_buysell(int fd, struct map_session_data *sd) { - short type = RFIFOW(fd,2) + 6; + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + short type = RFIFOW(fd, 2) + 6; if( !battle_config.feature_auction ) return; @@ -17116,6 +17522,9 @@ static void clif_parse_cashshop_buy(int fd, struct map_session_data *sd) __attri /// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803) static void clif_parse_cashshop_buy(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int fail = 0; const struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM *p = RFIFOP(fd, 0); @@ -17208,6 +17617,9 @@ static void clif_parse_Adopt_request(int fd, struct map_session_data *sd) __attr /// 01f9 <account id>.L static void clif_parse_Adopt_request(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct map_session_data *tsd = map->id2sd(RFIFOL(fd,2)), *p_sd = map->charid2sd(sd->status.partner_id); if( pc->can_Adopt(sd, p_sd, tsd) ) { @@ -17224,6 +17636,9 @@ static void clif_parse_Adopt_reply(int fd, struct map_session_data *sd) __attrib /// 1 = accepted static void clif_parse_Adopt_reply(int fd, struct map_session_data *sd) { + if (pc_isdead(sd)) + return; + int p1_id = RFIFOL(fd,2); int p2_id = RFIFOL(fd,6); int result = RFIFOL(fd,10); @@ -17291,6 +17706,9 @@ static void clif_parse_ViewPlayerEquip(int fd, struct map_session_data *sd) __at /// 02d6 <account id>.L static void clif_parse_ViewPlayerEquip(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int charid = RFIFOL(fd, 2); struct map_session_data* tsd = map->id2sd(charid); @@ -17318,6 +17736,9 @@ static void clif_parse_cz_config(int fd, struct map_session_data *sd) __attribut /// 1 = enabled static void clif_parse_cz_config(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + enum CZ_CONFIG type = RFIFOL(fd, 2); int flag = RFIFOL(fd, 6); @@ -17633,6 +18054,9 @@ static void clif_parse_questStateAck(int fd, struct map_session_data *sd) __attr /// 02b6 <quest id>.L <active>.B static void clif_parse_questStateAck(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + quest->update_status(sd, RFIFOL(fd,2), RFIFOB(fd,6)?Q_ACTIVE:Q_INACTIVE); } @@ -17852,6 +18276,9 @@ static void clif_parse_mercenary_action(int fd, struct map_session_data *sd) __a /// 2 = delete static void clif_parse_mercenary_action(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int option = RFIFOB(fd,2); if (sd->md == NULL) return; @@ -18320,6 +18747,9 @@ static void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *s /// S 07e4 <length>.w <option>.l <val>.l {<index>.w <amount>.w).4b* static void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int n = ((int)RFIFOW(fd, 2) - 12) / 4; int type = RFIFOL(fd,4); int flag = RFIFOL(fd,8); // Button clicked: 0 = Cancel, 1 = OK @@ -18449,6 +18879,9 @@ static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd) _ /// 1 = open static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || pc_isdead(sd)) + return; + const unsigned int blocksize = sizeof(struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub); const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub *itemlist; char storename[MESSAGE_SIZE]; @@ -18612,6 +19045,9 @@ static void clif_buyingstore_disappear_entry_single(struct map_session_data *sd, /// 0817 <account id>.L static void clif_parse_ReqClickBuyingStore(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int account_id; account_id = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]); @@ -18656,6 +19092,9 @@ static void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data *sd) /// 0819 <packet len>.W <account id>.L <store id>.L { <index>.W <name id>.W <amount>.W }* static void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const unsigned int blocksize = sizeof(struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub); const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub *itemlist; int account_id; @@ -18794,6 +19233,9 @@ static void clif_parse_SearchStoreInfo(int fd, struct map_session_data *sd) __at /// cannot be searched. static void clif_parse_SearchStoreInfo(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const unsigned int blocksize = sizeof(struct PACKET_CZ_SEARCH_STORE_INFO_item); const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist; const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist; @@ -18942,6 +19384,9 @@ static void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data * /// 0838 static void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + searchstore->next(sd); } @@ -18980,6 +19425,9 @@ static void clif_parse_SearchStoreInfoListItemClick(int fd, struct map_session_d /// 083c <account id>.L <store id>.L <nameid>.W static void clif_parse_SearchStoreInfoListItemClick(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_SSILIST_ITEM_CLICK *p = RFIFOP(fd, 0); searchstore->click(sd, p->AID, p->storeId, p->itemId); } @@ -19029,27 +19477,30 @@ static void clif_parse_debug(int fd, struct map_session_data *sd) *------------------------------------------*/ static int clif_elementalconverter_list(struct map_session_data *sd) { - int i,c,view,fd; - nullpo_ret(sd); /// Main client packet processing function - fd=sd->fd; - WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB *2+4); - WFIFOW(fd, 0)=0x1ad; + int fd = sd->fd; + int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + WFIFOHEAD(fd, len); + struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_MAKINGARROW_LIST; - for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){ - if( skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid,23, 1) ){ - if((view = itemdb_viewid(skill->dbs->produce_db[i].nameid)) > 0) - WFIFOW(fd,c*2+ 4)= view; + int c = 0; + for (int i = 0; i < MAX_SKILL_PRODUCE_DB; i++) { + if (skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid,23, 1) ) { + int view = itemdb_viewid(skill->dbs->produce_db[i].nameid); + if (view > 0) + p->items[c].itemId = view; else - WFIFOW(fd,c*2+ 4)= skill->dbs->produce_db[i].nameid; + p->items[c].itemId = skill->dbs->produce_db[i].nameid; c++; } } - WFIFOW(fd,2) = c*2+4; - WFIFOSET(fd, WFIFOW(fd,2)); if (c > 0) { + len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + p->packetLength = len; + WFIFOSET(fd, len); sd->menuskill_id = SA_CREATECON; sd->menuskill_val = c; } @@ -19080,33 +19531,33 @@ static void clif_millenniumshield(struct block_list *bl, short shields) *------------------------------------------*/ static int clif_spellbook_list(struct map_session_data *sd) { - int i, c; - int fd; - nullpo_ret(sd); - fd = sd->fd; - WFIFOHEAD(fd, 8 * 8 + 8); - WFIFOW(fd,0) = 0x1ad; + int fd = sd->fd; + int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + WFIFOHEAD(fd, len); + struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_MAKINGARROW_LIST; - for (i = 0, c = 0; i < sd->status.inventorySize; i ++ ) + int c = 0; + for (int i = 0; i < sd->status.inventorySize; i ++ ) { - if( itemdb_is_spellbook(sd->status.inventory[i].nameid) ) + if (itemdb_is_spellbook(sd->status.inventory[i].nameid)) { - WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid; + p->items[c].itemId = sd->status.inventory[i].nameid; c++; } } - if( c > 0 ) + if (c > 0) { - WFIFOW(fd,2) = c * 2 + 4; - WFIFOSET(fd, WFIFOW(fd, 2)); + len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + p->packetLength = len; + WFIFOSET(fd, len); sd->menuskill_id = WL_READING_SB; sd->menuskill_val = c; - } - else{ - status_change_end(&sd->bl,SC_STOP,INVALID_TIMER); + } else { + status_change_end(&sd->bl, SC_STOP, INVALID_TIMER); clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK, 0, 0); } @@ -19121,17 +19572,18 @@ static int clif_spellbook_list(struct map_session_data *sd) static int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, short y) { int i, c; - int fd; nullpo_ret(sd); - fd = sd->fd; - WFIFOHEAD(fd, 8 * 8 + 8); - WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil] + int fd = sd->fd; + int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + WFIFOHEAD(fd, len); + struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_MAKINGARROW_LIST; for (i = 0, c = 0; i < sd->status.inventorySize; i ++) { - if( itemdb_is_element(sd->status.inventory[i].nameid) ) { - WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid; + if (itemdb_is_element(sd->status.inventory[i].nameid)) { + p->items[c].itemId = sd->status.inventory[i].nameid; c ++; } } @@ -19140,8 +19592,10 @@ static int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, sh sd->menuskill_val = skill_lv; sd->sc.comet_x = x; sd->sc.comet_y = y; - WFIFOW(fd,2) = c * 2 + 4; - WFIFOSET(fd, WFIFOW(fd, 2)); + + len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + p->packetLength = len; + WFIFOSET(fd, len); } else { clif->skill_fail(sd, NC_MAGICDECOY, USESKILL_FAIL_LEVEL, 0, 0); return 0; @@ -19158,25 +19612,28 @@ static int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, sh static int clif_poison_list(struct map_session_data *sd, uint16 skill_lv) { int i, c; - int fd; nullpo_ret(sd); - fd = sd->fd; - WFIFOHEAD(fd, 8 * 8 + 8); - WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil] + int fd = sd->fd; + int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + WFIFOHEAD(fd, len); + struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_MAKINGARROW_LIST; for (i = 0, c = 0; i < sd->status.inventorySize; i ++) { if( itemdb_is_poison(sd->status.inventory[i].nameid) ) { - WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid; + p->items[c].itemId = sd->status.inventory[i].nameid; c ++; } } - if( c > 0 ) { + if (c > 0) { sd->menuskill_id = GC_POISONINGWEAPON; sd->menuskill_val = skill_lv; - WFIFOW(fd,2) = c * 2 + 4; - WFIFOSET(fd, WFIFOW(fd, 2)); + + len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST); + p->packetLength = len; + WFIFOSET(fd, len); } else { clif->skill_fail(sd, GC_POISONINGWEAPON, USESKILL_FAIL_GUILLONTINE_POISON, 0, 0); return 0; @@ -19254,8 +19711,10 @@ static void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) __at *------------------------------------------*/ static void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; - if( sd->menuskill_id != SC_AUTOSHADOWSPELL ) + if (sd->menuskill_id != SC_AUTOSHADOWSPELL) return; if (pc_istrading(sd) || sd->state.prevend) { @@ -19301,9 +19760,8 @@ static void clif_parse_MoveItem(int fd, struct map_session_data *sd) int index; /* can't move while dead. */ - if(pc_isdead(sd)) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) return; - } index = RFIFOW(fd,2)-2; @@ -19454,6 +19912,8 @@ static void clif_parse_dull(int fd, struct map_session_data *sd) static void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; if (map->list[sd->bl.m].flag.nocashshop) { clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1489)); //Cash Shop is disabled in this map @@ -19476,6 +19936,9 @@ static void clif_parse_CashShopClose(int fd, struct map_session_data *sd) static void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + clif->cashShopSchedule(fd, sd); } @@ -19513,6 +19976,9 @@ void clif_cashShopSchedule(int fd, struct map_session_data *sd) static void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int len = RFIFOW(fd, 2); unsigned short limit, i, j; unsigned int kafra_pay; @@ -19633,6 +20099,9 @@ static void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) { // [4144] packet exists only in 2011 and was dropped after #if PACKETVER >= 20110222 && PACKETVER < 20120000 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + short tab = RFIFOW(fd, 2); int j; @@ -19787,6 +20256,9 @@ static void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEG static void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct packet_bgqueue_register *p = RP2PTR(fd); struct bg_arena *arena = NULL; if( !bg->queue_on ) return; /* temp, until feature is complete */ @@ -19827,6 +20299,9 @@ static void clif_bgqueue_update_info(struct map_session_data *sd, unsigned char static void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct packet_bgqueue_checkstate *p = RP2PTR(fd); if (sd->bg_queue.arena && sd->bg_queue.type) { @@ -19839,6 +20314,9 @@ static void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) static void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct packet_bgqueue_revoke_req *p = RP2PTR(fd); if( sd->bg_queue.arena ) @@ -19850,6 +20328,9 @@ static void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) static void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct packet_bgqueue_battlebegin_ack *p = RP2PTR(fd); struct bg_arena *arena; @@ -19914,7 +20395,11 @@ static void clif_package_item_announce(struct map_session_data *sd, int nameid, nullpo_retv(sd); p.PacketType = package_item_announceType; - p.PacketLength = 11 + NAME_LENGTH; +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + p.PacketLength = 7 + 4 + 4 + NAME_LENGTH; +#else + p.PacketLength = 7 + 2 + 2 + NAME_LENGTH; +#endif p.type = 0x0; p.ItemID = nameid; p.len = NAME_LENGTH; @@ -19922,7 +20407,7 @@ static void clif_package_item_announce(struct map_session_data *sd, int nameid, p.unknown = 0x2; // some strange byte, IDA shows.. BYTE3(BoxItemIDLength) = 2; p.BoxItemID = containerid; - clif->send(&p,sizeof(p), &sd->bl, ALL_CLIENT); + clif->send(&p, p.PacketLength, &sd->bl, ALL_CLIENT); } /* Made Possible Thanks to Yommy! */ @@ -19940,12 +20425,13 @@ static void clif_item_drop_announce(struct map_session_data *sd, int nameid, cha if (monsterName == NULL) { // message: MSG_BROADCASTING_SPECIAL_ITEM_OBTAIN2 p.type = 0x2; + p.PacketLength -= NAME_LENGTH; } else { // message: MSG_BROADCASTING_SPECIAL_ITEM_OBTAIN p.type = 0x1; safestrncpy(p.monsterName, monsterName, sizeof(p.monsterName)); } - clif->send(&p, sizeof(p), &sd->bl, ALL_CLIENT); + clif->send(&p, p.PacketLength, &sd->bl, ALL_CLIENT); } /* [Ind/Hercules] special thanks to Yommy~! */ @@ -20005,6 +20491,9 @@ static void clif_cart_additem_ack(struct map_session_data *sd, int flag) static void clif_parse_BankDeposit(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_BankDeposit(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct packet_banking_deposit_req *p = RP2PTR(fd); int money; @@ -20021,6 +20510,9 @@ static void clif_parse_BankDeposit(int fd, struct map_session_data *sd) static void clif_parse_BankWithdraw(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_BankWithdraw(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct packet_banking_withdraw_req *p = RP2PTR(fd); int money; @@ -20038,6 +20530,9 @@ static void clif_parse_BankCheck(int fd, struct map_session_data *sd) __attribut static void clif_parse_BankCheck(int fd, struct map_session_data *sd) { #if PACKETVER >= 20130320 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct packet_banking_check p; p.PacketType = banking_checkType; @@ -20104,7 +20599,7 @@ static void clif_show_modifiers(struct map_session_data *sd) if( sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100 ) { char output[128]; - snprintf(output,128,"Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%", + snprintf(output,128, msg_sd(sd, 896), // 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, (int)strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF); } @@ -20169,7 +20664,7 @@ static int clif_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) * * @return clif->calc_walkdelay used in further processing **/ -static int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type) +static int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, enum battle_dmg_type type) { struct cdelayed_damage *dd; struct status_change *sc; @@ -20281,40 +20776,43 @@ static void clif_parse_NPCBarterClosed(int fd, struct map_session_data *sd) sd->npc_shopid = 0; } -static void clif_npc_market_purchase_ack(struct map_session_data *sd, const struct itemlist *item_list, unsigned char response) +static void clif_npc_market_purchase_ack(struct map_session_data *sd, const struct itemlist *item_list, enum market_buy_result response) { -#if PACKETVER >= 20131223 - unsigned short c = 0; - +#if PACKETVER_MAIN_NUM >= 20131120 || PACKETVER_RE_NUM >= 20130911 || defined(PACKETVER_ZERO) nullpo_retv(sd); nullpo_retv(item_list); - npcmarket_result.PacketType = npcmarketresultackType; - npcmarket_result.result = response == 0 ? 1 : 0;/* find other values */ + struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT *p = (struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT *)packet_buf; + p->PacketType = HEADER_ZC_NPC_MARKET_PURCHASE_RESULT; + p->result = response; - if (npcmarket_result.result) { + unsigned short c = 0; + if (response == MARKET_BUY_RESULT_SUCCESS) { + int vectorLen = VECTOR_LENGTH(*item_list); + int maxCount = (sizeof(packet_buf) - sizeof(struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT)) / sizeof(struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT_sub); + if (maxCount > vectorLen) + maxCount = vectorLen; 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 < VECTOR_LENGTH(*item_list); i++) { + for (int i = 0; i < maxCount; i++) { const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); int j; - npcmarket_result.list[i].ITID = entry->id; - npcmarket_result.list[i].qty = entry->amount; + p->list[i].ITID = entry->id; + p->list[i].qty = entry->amount; - ARR_FIND( 0, shop_size, j, entry->id == 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; + p->list[i].price = (j != shop_size) ? shop[j].value : 0; c++; } } - npcmarket_result.PacketLength = 5 + ( sizeof(npcmarket_result.list[0]) * c );; + p->PacketLength = sizeof(struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT) + (sizeof(struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT_sub) * c); - clif->send(&npcmarket_result,npcmarket_result.PacketLength,&sd->bl,SELF); + clif->send(p, p->PacketLength, &sd->bl, SELF); #endif } @@ -20322,8 +20820,10 @@ static void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) __ static void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) { #if PACKETVER >= 20131223 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + 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; @@ -20332,7 +20832,7 @@ static void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) VECTOR_INIT(item_list); VECTOR_ENSURE(item_list, count, 1); - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { struct itemlist_entry entry = { 0 }; entry.id = p->list[i].ITID; @@ -20341,7 +20841,7 @@ static void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) VECTOR_PUSH(item_list, entry); } - response = npc->market_buylist(sd, &item_list); + enum market_buy_result response = npc->market_buylist(sd, &item_list); clif->npc_market_purchase_ack(sd, &item_list, response); VECTOR_CLEAR(item_list); @@ -20366,6 +20866,9 @@ static void clif_parse_RouletteOpen(int fd, struct map_session_data *sd) __attri static void clif_parse_RouletteOpen(int fd, struct map_session_data *sd) { #if PACKETVER >= 20140612 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct packet_roulette_open_ack p; if( !battle_config.feature_roulette ) { @@ -20391,6 +20894,9 @@ static void clif_parse_RouletteInfo(int fd, struct map_session_data *sd) __attri static void clif_parse_RouletteInfo(int fd, struct map_session_data *sd) { #if PACKETVER >= 20140612 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + struct packet_roulette_info_ack p; unsigned short i, j, count = 0; @@ -20436,6 +20942,9 @@ static void clif_parse_RouletteClose(int fd, struct map_session_data *sd) static void clif_parse_RouletteGenerate(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_RouletteGenerate(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + unsigned char result = GENERATE_ROULETTE_SUCCESS; short stage = sd->roulette.stage; @@ -20495,6 +21004,8 @@ static void clif_parse_RouletteRecvItem(int fd, struct map_session_data *sd) __a static void clif_parse_RouletteRecvItem(int fd, struct map_session_data *sd) { #if PACKETVER >= 20140612 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; struct packet_roulette_itemrecv_ack p; if( !battle_config.feature_roulette ) { @@ -21232,6 +21743,9 @@ static void clif_achievement_send_update(int fd, struct map_session_data *sd, co static void clif_parse_achievement_get_reward(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_achievement_get_reward(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int ach_id = RFIFOL(fd, 2); const struct achievement_data *ad = NULL; struct achievement *ach = NULL; @@ -21274,6 +21788,9 @@ static void clif_achievement_reward_ack(int fd, struct map_session_data *sd, con static void clif_parse_change_title(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_change_title(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + int title_id = RFIFOL(fd, 2); if (title_id == sd->status.title_id) { // Same Title @@ -21321,6 +21838,9 @@ static void clif_change_title_ack(int fd, struct map_session_data *sd, int title static void clif_parse_rodex_open_write_mail(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_open_write_mail(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_OPEN_WRITE_MAIL *rPacket = RFIFOP(fd, 0); int8 result = (rodex->isenabled() == true && sd->npc_id == 0) ? 1 : 0; @@ -21346,6 +21866,9 @@ static void clif_rodex_open_write_mail(int fd, const char *receiver_name, int8 r static void clif_parse_rodex_add_item(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_add_item(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_ADD_ITEM_TO_MAIL *rPacket = RFIFOP(fd, 0); int16 idx = rPacket->index - 2; @@ -21399,6 +21922,9 @@ static void clif_rodex_add_item_result(struct map_session_data *sd, int16 idx, i static void clif_parse_rodex_remove_item(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_remove_item(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_REMOVE_ITEM_MAIL *rPacket = RFIFOP(fd, 0); int16 idx = rPacket->index - 2; @@ -21471,6 +21997,9 @@ static void clif_rodex_checkname_result(struct map_session_data *sd, int char_id static void clif_parse_rodex_send_mail(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_send_mail(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_SEND_MAIL *rPacket = RFIFOP(fd, 0); int8 result; @@ -21701,6 +22230,9 @@ static void clif_rodex_send_refresh(int fd, struct map_session_data *sd, int8 op static void clif_parse_rodex_next_maillist(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_next_maillist(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_NEXT_MAIL_LIST *packet = RFIFOP(fd, 0); rodex->next_page(sd, packet->opentype, packet->Lower_MailID); @@ -21709,6 +22241,9 @@ static void clif_parse_rodex_next_maillist(int fd, struct map_session_data *sd) static void clif_parse_rodex_read_mail(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_read_mail(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_READ_MAIL *rPacket = RFIFOP(fd, 0); rodex->read_mail(sd, rPacket->MailID); @@ -21778,6 +22313,9 @@ static void clif_rodex_read_mail(struct map_session_data *sd, int8 opentype, str static void clif_parse_rodex_delete_mail(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_delete_mail(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_DELETE_MAIL *rPacket = RFIFOP(fd, 0); rodex->delete_mail(sd, rPacket->MailID); @@ -21805,6 +22343,9 @@ static void clif_rodex_delete_mail(struct map_session_data *sd, int8 opentype, i static void clif_parse_rodex_request_zeny(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_request_zeny(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_ZENY_FROM_MAIL *rPacket = RFIFOP(fd, 0); rodex->get_zeny(sd, rPacket->opentype, rPacket->MailID); @@ -21833,6 +22374,9 @@ static void clif_rodex_request_zeny(struct map_session_data *sd, int8 opentype, static void clif_parse_rodex_request_items(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_request_items(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_ITEM_FROM_MAIL *rPacket = RFIFOP(fd, 0); rodex->get_items(sd, rPacket->opentype, rPacket->MailID); @@ -21872,6 +22416,9 @@ static void clif_rodex_icon(int fd, bool show) static void clif_parse_rodex_refresh_maillist(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_refresh_maillist(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_REFRESH_MAIL_LIST *packet = RFIFOP(fd, 0); #if PACKETVER >= 20170419 rodex->refresh(sd, RODEX_OPENTYPE_UNSET, packet->Upper_MailID); @@ -21883,6 +22430,9 @@ static void clif_parse_rodex_refresh_maillist(int fd, struct map_session_data *s static void clif_parse_rodex_open_mailbox(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_open_mailbox(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_OPEN_MAIL *packet = RFIFOP(fd, 0); #if PACKETVER >= 20170419 rodex->open(sd, RODEX_OPENTYPE_UNSET, packet->char_Upper_MailID); @@ -21895,6 +22445,9 @@ static void clif_parse_rodex_open_mailbox(int fd, struct map_session_data *sd) static void clif_parse_rodex_close_mailbox(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_close_mailbox(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + rodex->clean(sd, 0); intif->rodex_checkhasnew(sd); } @@ -21902,6 +22455,9 @@ static void clif_parse_rodex_close_mailbox(int fd, struct map_session_data *sd) static void clif_parse_rodex_cancel_write_mail(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_rodex_cancel_write_mail(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + rodex->clean(sd, 1); } @@ -21935,53 +22491,47 @@ static void clif_skill_scale(struct block_list *bl, int src_id, int x, int y, ui /// 0A3B <Length>.W <AID>.L <Status>.B { <HatEffectId>.W } static void clif_hat_effect(struct block_list *bl, struct block_list *tbl, enum send_target target) { -#if PACKETVER >= 20150422 - unsigned char *buf; - int len, i; - struct map_session_data *sd; - +#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) nullpo_retv(bl); - - sd = BL_CAST(BL_PC, bl); - + struct map_session_data *sd = BL_CAST(BL_PC, bl); nullpo_retv(sd); - len = 9 + VECTOR_LENGTH(sd->hatEffectId) * 2; - - buf = (unsigned char*)aMalloc(len); + const int len = sizeof(struct PACKET_ZC_HAT_EFFECT) + VECTOR_LENGTH(sd->hatEffectId) * 2; + struct PACKET_ZC_HAT_EFFECT *p = aMalloc(len); - WBUFW(buf, 0) = 0xa3b; - WBUFW(buf, 2) = len; - WBUFL(buf, 4) = bl->id; - WBUFB(buf, 8) = 1; + p->packetType = HEADER_ZC_HAT_EFFECT; + p->packetLength = len; + p->aid = bl->id; + p->status = 1; - for( i = 0; i < VECTOR_LENGTH(sd->hatEffectId); i++ ){ - WBUFW(buf, 9 + i * 2) = VECTOR_INDEX(sd->hatEffectId, i); + for (int i = 0; i < VECTOR_LENGTH(sd->hatEffectId); i++) { + p->effects[i] = VECTOR_INDEX(sd->hatEffectId, i); } if (tbl != NULL) { - clif->send(buf, len, tbl, target); + clif->send(p, len, tbl, target); } else { - clif->send(buf, len, bl, target); + clif->send(p, len, bl, target); } - - aFree(buf); + aFree(p); #endif } static void clif_hat_effect_single(struct block_list *bl, uint16 effectId, bool enable){ -#if PACKETVER >= 20150422 - unsigned char buf[13]; - +#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) nullpo_retv(bl); - WBUFW(buf,0) = 0xa3b; - WBUFW(buf,2) = 13; - WBUFL(buf,4) = bl->id; - WBUFB(buf,8) = enable; - WBUFL(buf,9) = effectId; + const int len = sizeof(struct PACKET_ZC_HAT_EFFECT) + 2; + struct PACKET_ZC_HAT_EFFECT *p = aMalloc(len); - clif->send(buf, 13, bl, AREA); + p->packetType = HEADER_ZC_HAT_EFFECT; + p->packetLength = len; + p->aid = bl->id; + p->status = enable; + p->effects[0] = effectId; + + clif->send(p, len, bl, AREA); + aFree(p); #endif } @@ -22066,8 +22616,10 @@ static time_t clif_attendance_getendtime(void) static void clif_parse_open_ui_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_open_ui_request(int fd, struct map_session_data *sd) { - const struct PACKET_CZ_OPEN_UI *p = RP2PTR(fd); + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_OPEN_UI *p = RP2PTR(fd); clif->open_ui(sd, p->UIType); } @@ -22138,6 +22690,8 @@ static void clif_parse_attendance_reward_request(int fd, struct map_session_data static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) { #if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; struct rodex_message msg = { 0 }; struct attendance_entry *entry; @@ -22219,6 +22773,9 @@ static void clif_parse_private_airship_request(int fd, struct map_session_data * static void clif_parse_private_airship_request(int fd, struct map_session_data *sd) { #if PACKETVER_RE_NUM >= 20180321 || PACKETVER_MAIN_NUM >= 20180620 || defined(PACKETVER_ZERO) + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + char evname[EVENT_NAME_LENGTH]; struct event_data *ev = NULL; const struct PACKET_CZ_PRIVATE_AIRSHIP_REQUEST *p = RP2PTR(fd); @@ -22260,6 +22817,9 @@ static void clif_private_airship_response(struct map_session_data *sd, uint32 fl static void clif_parse_cz_req_style_change(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_cz_req_style_change(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_STYLE_CHANGE *p = RP2PTR(fd); if (p->HeadStyle > 0) @@ -22281,6 +22841,9 @@ static void clif_parse_cz_req_style_change(int fd, struct map_session_data *sd) static void clif_parse_cz_req_style_change2(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_cz_req_style_change2(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_REQ_STYLE_CHANGE2 *p = RP2PTR(fd); if (p->HeadStyle > 0) @@ -22343,6 +22906,9 @@ static void clif_parse_changeDress(int fd, struct map_session_data *sd) __attrib /// 0ae8 <packet len>.W static void clif_parse_changeDress(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const char commandname[] = "changedress"; char command[sizeof commandname + 3] = ""; // '@' command + ' ' + NUL @@ -22367,6 +22933,9 @@ static void clif_party_dead_notification(struct map_session_data *sd) static void clif_parse_memorial_dungeon_command(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_memorial_dungeon_command(int fd, struct map_session_data *sd) { + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_MEMORIALDUNGEON_COMMAND *p = RP2PTR(fd); switch (p->command) { @@ -22407,6 +22976,9 @@ static void clif_parse_cameraInfo(int fd, struct map_session_data *sd) __attribu static void clif_parse_cameraInfo(int fd, struct map_session_data *sd) { #if PACKETVER >= 20160525 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_CAMERA_INFO *const p = RFIFOP(fd, 0); char command[100]; if (p->action == 1) { @@ -22495,6 +23067,9 @@ static void clif_parse_NPCBarterPurchase(int fd, struct map_session_data *sd) __ static void clif_parse_NPCBarterPurchase(int fd, struct map_session_data *sd) { #if PACKETVER_MAIN_NUM >= 20190116 || PACKETVER_RE_NUM >= 20190116 || PACKETVER_ZERO_NUM >= 20181226 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + const struct PACKET_CZ_NPC_BARTER_PURCHASE *p = RP2PTR(fd); int count = (p->packetLength - sizeof(struct PACKET_CZ_NPC_BARTER_PURCHASE)) / sizeof p->list[0]; struct barteritemlist item_list; @@ -22598,6 +23173,9 @@ static void clif_parse_AddItemRefineryUI(int fd, struct map_session_data *sd) __ static void clif_parse_AddItemRefineryUI(int fd, struct map_session_data *sd) { #if PACKETVER_MAIN_NUM >= 20161005 || PACKETVER_RE_NUM >= 20161005 || defined(PACKETVER_ZERO) + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + if (battle_config.enable_refinery_ui == 0) return; @@ -22639,6 +23217,9 @@ static void clif_parse_RefineryUIRefine(int fd, struct map_session_data *sd) __a static void clif_parse_RefineryUIRefine(int fd, struct map_session_data *sd) { #if PACKETVER_MAIN_NUM >= 20161005 || PACKETVER_RE_NUM >= 20161005 || defined(PACKETVER_ZERO) + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + if (battle_config.enable_refinery_ui == 0) return; @@ -22651,6 +23232,9 @@ static void clif_parse_RefineryUIClose(int fd, struct map_session_data *sd) __at static void clif_parse_RefineryUIClose(int fd, struct map_session_data *sd) { #if PACKETVER_MAIN_NUM >= 20161130 || PACKETVER_RE_NUM >= 20161109 || defined(PACKETVER_ZERO) + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + if (battle_config.enable_refinery_ui == 0) return; @@ -22676,6 +23260,181 @@ static void clif_announce_refine_status(struct map_session_data *sd, int item_id #endif } +static void clif_parse_GuildCastleTeleportRequest(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); +static void clif_parse_GuildCastleTeleportRequest(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 + const struct PACKET_CZ_CASTLE_TELEPORT_REQUEST *p = RFIFO2PTR(fd); + struct guild *g = sd->guild; + + if (g == NULL) + return; + + struct guild_castle *gc = guild->castle_search(p->castle_id); + if (gc == NULL) + return; + if (gc->enable_client_warp == false) + return; + if (gc->guild_id != g->guild_id) + return; + + if (map->list[sd->bl.m].flag.gvg_castle == 1) + return; + + int zeny = gc->client_warp.zeny; + if (gc->siege_type == SIEGE_TYPE_FE && map->agit_flag == 1) { + zeny = gc->client_warp.zeny_siege; + } else if (gc->siege_type == SIEGE_TYPE_SE && map->agit2_flag == 1) { + zeny = gc->client_warp.zeny_siege; + } else if (gc->siege_type == SIEGE_TYPE_TE) { + clif->guild_castleteleport_res(sd, SIEGE_TP_INVALID_MODE); + return; + } + + if (sd->status.zeny < zeny) { + clif->guild_castleteleport_res(sd, SIEGE_TP_NOT_ENOUGH_ZENY); + return; + } + sd->status.zeny -= zeny; + clif->updatestatus(sd, SP_ZENY); + pc->setpos(sd, gc->mapindex, gc->client_warp.x, gc->client_warp.y, CLR_OUTSIGHT); +#endif +} + +static void clif_guild_castleteleport_res(struct map_session_data *sd, enum siege_teleport_result result) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 + + nullpo_retv(sd); + + struct PACKET_ZC_CASTLE_TELEPORT_RESPONSE p = { 0 }; + p.packetType = HEADER_ZC_CASTLE_TELEPORT_RESPONSE; + p.result = (int16)result; + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif +} +static void clif_parse_GuildCastleInfoRequest(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); +static void clif_parse_GuildCastleInfoRequest(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 + const struct PACKET_CZ_CASTLE_INFO_REQUEST *p = RFIFO2PTR(fd); + struct guild *g = sd->guild; + + if (g == NULL) + return; + + struct guild_castle *gc = guild->castle_search(p->castle_id); + if (gc == NULL) + return; + if (gc->guild_id != g->guild_id) + return; + clif->guild_castleinfo(sd, gc); +#endif +} + +static bool clif_lapineDdukDdak_open(struct map_session_data *sd, int item_id) +{ +#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) + nullpo_retr(false, sd); + nullpo_retr(false, itemdb->exists(item_id)); + struct PACKET_ZC_LAPINEDDUKDDAK_OPEN p; + + p.packetType = HEADER_ZC_LAPINEDDUKDDAK_OPEN; + p.itemId = item_id; + clif->send(&p, sizeof(p), &sd->bl, SELF); + + sd->state.lapine_ui = 1; + return true; +#else + return false; +#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) +} + +static bool clif_lapineDdukDdak_result(struct map_session_data *sd, enum lapineddukddak_result result) +{ +#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) + nullpo_retr(false, sd); + struct PACKET_ZC_LAPINEDDUKDDAK_RESULT p; + + p.packetType = HEADER_ZC_LAPINEDDUKDDAK_RESULT; + p.result = result; + clif->send(&p, sizeof(p), &sd->bl, SELF); + return true; +#else + return false; +#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) +} + +static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20160302 + const struct PACKET_CZ_LAPINEDDUKDDAK_ACK *p = RP2PTR(fd); + struct item_data *it = itemdb->exists(p->itemId); + + if (it == NULL || it->lapineddukddak == NULL) + return; + if (pc_cant_act(sd)) + return; + if (pc->search_inventory(sd, it->nameid) == INDEX_NOT_FOUND) + return; + + if (((p->packetLength - sizeof(struct PACKET_CZ_LAPINEDDUKDDAK_ACK)) / sizeof(struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub)) != it->lapineddukddak->NeedCount) + return; + + for (int i = 0; i < it->lapineddukddak->NeedCount; ++i) { + int16 idx = p->items[i].index - 2; + Assert_retv(idx >= 0 && idx < sd->status.inventorySize); + + struct item itr = sd->status.inventory[idx]; + int j = 0; + for (j = 0; j < VECTOR_LENGTH(it->lapineddukddak->SourceItems); ++j) { + if (itr.nameid == VECTOR_INDEX(it->lapineddukddak->SourceItems, j).id) { + // Validate that the amount sent in the packet is matching the database + if (p->items[i].count != VECTOR_INDEX(it->lapineddukddak->SourceItems, j).amount) { + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT); + return; + } + + // Validate that the player have enough of the item + if (itr.amount < VECTOR_INDEX(it->lapineddukddak->SourceItems, j).amount) { + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT); + return; + } + + // Validate refine rate requirement + if ((itemdb_type(itr.nameid) == IT_ARMOR || itemdb_type(itr.nameid) == IT_WEAPON) + && (itr.refine < it->lapineddukddak->NeedRefineMin || itr.refine > it->lapineddukddak->NeedRefineMax)) + return; + + // All requirements are met, move to the next one + break; + } + } + // The item is not in sources list + if (j == VECTOR_LENGTH(it->lapineddukddak->SourceItems)) { + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INVALID_ITEM); + return; + } + } + + for (int i = 0; i < it->lapineddukddak->NeedCount; ++i) + pc->delitem(sd, p->items[i].index - 2, p->items[i].count, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT); + if (it->lapineddukddak->script != NULL) + script->run_item_lapineddukddak_script(sd, it, npc->fake_nd->bl.id); + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_SUCCESS); + return; +#endif // PACKETVER >= 20160302 +} + +static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20160504 + sd->state.lapine_ui = 0; +#endif // PACKETVER >= 20160504 +} + /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -23119,6 +23878,8 @@ void clif_defaults(void) clif->fame_alchemist = clif_fame_alchemist; clif->fame_taekwon = clif_fame_taekwon; clif->ranklist = clif_ranklist; + clif->ranklist_sub = clif_ranklist_sub; + clif->ranklist_sub2 = clif_ranklist_sub2; clif->pRanklist = clif_parse_ranklist; clif->update_rankingpoint = clif_update_rankingpoint; clif->hotkeys = clif_hotkeys_send; @@ -23334,6 +24095,7 @@ void clif_defaults(void) clif->skillinfo = clif_skillinfo; clif->addskill = clif_addskill; clif->deleteskill = clif_deleteskill; + clif->playerSkillToPacket = clif_playerSkillToPacket; /* party-specific */ clif->party_created = clif_party_created; clif->party_member_info = clif_party_member_info; @@ -23357,6 +24119,8 @@ void clif_defaults(void) clif->guild_masterormember = clif_guild_masterormember; clif->guild_basicinfo = clif_guild_basicinfo; clif->guild_allianceinfo = clif_guild_allianceinfo; + clif->guild_castlelist = clif_guild_castlelist; + clif->guild_castleinfo = clif_guild_castleinfo; clif->guild_memberlist = clif_guild_memberlist; clif->guild_skillinfo = clif_guild_skillinfo; clif->guild_send_onlineinfo = clif_guild_send_onlineinfo; @@ -23898,4 +24662,11 @@ void clif_defaults(void) clif->pRefineryUIClose = clif_parse_RefineryUIClose; clif->pRefineryUIRefine = clif_parse_RefineryUIRefine; clif->announce_refine_status = clif_announce_refine_status; + clif->pGuildCastleTeleportRequest = clif_parse_GuildCastleTeleportRequest; + clif->pGuildCastleInfoRequest = clif_parse_GuildCastleInfoRequest; + clif->guild_castleteleport_res = clif_guild_castleteleport_res; + clif->lapineDdukDdak_open = clif_lapineDdukDdak_open; + clif->lapineDdukDdak_result = clif_lapineDdukDdak_result; + clif->plapineDdukDdak_ack = clif_parse_lapineDdukDdak_ack; + clif->plapineDdukDdak_close = clif_parse_lapineDdukDdak_close; } |