diff options
author | Haru <haru@dotalux.com> | 2019-05-05 23:23:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-05 23:23:05 +0200 |
commit | b1970eac663b641b93e30ec24f2b3d8ee02ce8f6 (patch) | |
tree | f363d01b6181e4cfcdad109dc6d56873a73eaa15 /src/map/clif.c | |
parent | aa79da0e801a536b22911d47fd12df351c36214e (diff) | |
parent | b8ce5e9e1352abc45b08f92eb50890f202b1b230 (diff) | |
download | hercules-b1970eac663b641b93e30ec24f2b3d8ee02ce8f6.tar.gz hercules-b1970eac663b641b93e30ec24f2b3d8ee02ce8f6.tar.bz2 hercules-b1970eac663b641b93e30ec24f2b3d8ee02ce8f6.tar.xz hercules-b1970eac663b641b93e30ec24f2b3d8ee02ce8f6.zip |
Merge pull request #2432 from 4144/updatepackets
Update packets up to 2019-05-02
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 724 |
1 files changed, 510 insertions, 214 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 38d0215d3..299c69a1c 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2943,7 +2943,7 @@ static void clif_inventoryStart(struct map_session_data *sd, enum inventory_type p->invType = type; #endif #if PACKETVER_RE_NUM >= 20180919 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 - int strLen = (int)safestrnlen(name, 24); + int strLen = (int)safestrnlen(name, 24) + 1; if (strLen > 24) strLen = 24; const int len = sizeof(struct ZC_INVENTORY_START) + strLen; @@ -4311,22 +4311,25 @@ static void clif_addchat(struct chat_data *cd, struct map_session_data *sd) /// role: /// 0 = owner (menu) /// 1 = normal -static void clif_changechatowner(struct chat_data *cd, struct map_session_data *sd) +static void clif_chatRoleChange(struct chat_data *cd, struct map_session_data *sd, struct block_list* bl, int isNotOwner) { - unsigned char buf[64]; - nullpo_retv(sd); - nullpo_retv(cd); + nullpo_retv(bl); + struct PACKET_ZC_ROLE_CHANGE p; - WBUFW(buf, 0) = 0xe1; - WBUFL(buf, 2) = 1; - memcpy(WBUFP(buf,6),cd->usersd[0]->status.name,NAME_LENGTH); + p.packetType = HEADER_ZC_ROLE_CHANGE; + p.flag = isNotOwner; + memcpy(&p.name, sd->status.name, NAME_LENGTH); + clif->send(&p, sizeof(struct PACKET_ZC_ROLE_CHANGE), bl, CHAT); +} - WBUFW(buf,30) = 0xe1; - WBUFL(buf,32) = 0; - memcpy(WBUFP(buf,36),sd->status.name,NAME_LENGTH); +static void clif_changechatowner(struct chat_data *cd, struct map_session_data *sd) +{ + nullpo_retv(sd); + nullpo_retv(cd); - clif->send(buf,packet_len(0xe1)*2,&sd->bl,CHAT); + clif->chatRoleChange(cd, cd->usersd[0], &sd->bl, 1); + clif->chatRoleChange(cd, sd, &sd->bl, 0); } /// Notify about user leaving the chatroom (ZC_MEMBER_EXIT). @@ -7134,14 +7137,17 @@ static void clif_party_job_and_level(struct map_session_data *sd) /// 1 = auto-deny party invites static void clif_partyinvitationstate(struct map_session_data *sd) { +#if PACKETVER_MAIN_NUM >= 20070911 || defined(PACKETVER_RE) || PACKETVER_AD_NUM >= 20070911 || PACKETVER_SAK_NUM >= 20070904 || defined(PACKETVER_ZERO) int fd; nullpo_retv(sd); fd = sd->fd; - WFIFOHEAD(fd, packet_len(0x2c9)); - WFIFOW(fd, 0) = 0x2c9; - WFIFOB(fd, 2) = sd->status.allow_party ? 0 : 1; - WFIFOSET(fd, packet_len(0x2c9)); + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_PARTY_CONFIG)); + struct PACKET_ZC_PARTY_CONFIG *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_PARTY_CONFIG; + p->denyPartyInvites = sd->status.allow_party ? 1 : 0; + WFIFOSET(fd, sizeof(struct PACKET_ZC_PARTY_CONFIG)); +#endif } /// Party invitation request. @@ -8399,6 +8405,7 @@ static void clif_guild_expulsion(struct map_session_data *sd, const char *name, #endif safestrncpy(&p.reason[0], mes, 40); +// version unconfirmed #if PACKETVER < 20100803 memset(&p.account_name, 0, NAME_LENGTH); // account name (not used for security reasons) #endif @@ -8410,42 +8417,44 @@ static void clif_guild_expulsion(struct map_session_data *sd, const char *name, /// 0163 <packet len>.W { <char name>.24B <reason>.40B }* (PACKETVER >= 20100803) static void clif_guild_expulsionlist(struct map_session_data *sd) { -#if PACKETVER < 20100803 - const int offset = NAME_LENGTH*2+40; -#else - const int offset = NAME_LENGTH+40; -#endif - int fd, i, c = 0; - struct guild* g; - nullpo_retv(sd); - if( (g = sd->guild) == NULL ) + int c = 0; + + struct guild* g; + if ((g = sd->guild) == NULL) return; - fd = sd->fd; + int fd = sd->fd; - WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * offset); - WFIFOW(fd,0) = 0x163; + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_BAN_LIST) + MAX_GUILDEXPULSION * sizeof(struct PACKET_ZC_BAN_LIST_sub)); + struct PACKET_ZC_BAN_LIST *packet = WFIFOP(fd, 0); + packet->packetType = HEADER_ZC_BAN_LIST; - for( i = 0; i < MAX_GUILDEXPULSION; i++ ) + for (int i = 0; i < MAX_GUILDEXPULSION; i++) { struct guild_expulsion* e = &g->expulsion[i]; - if( e->account_id > 0 ) + if (e->account_id > 0) { - memcpy(WFIFOP(fd,4 + c*offset), e->name, NAME_LENGTH); -#if PACKETVER < 20100803 - memset(WFIFOP(fd,4 + c*offset+24), 0, NAME_LENGTH); // account name (not used for security reasons) - memcpy(WFIFOP(fd,4 + c*offset+48), e->mes, 40); +#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO) + packet->chars[c].char_id = e->char_id; +// version unconfirmed +#elif PACKETVER >= 20100803 + memcpy(packet->chars[c].char_name, e->name, NAME_LENGTH); + #else - memcpy(WFIFOP(fd,4 + c*offset+24), e->mes, 40); + memcpy(packet->chars[c].char_name, e->name, NAME_LENGTH); + memset(packet->chars[c].account_name, 0, NAME_LENGTH); // account name (not used for security reasons) + #endif - c++; + memcpy(packet->chars[c].message, e->mes, 40); + + c ++; } } - WFIFOW(fd,2) = 4 + c*offset; - WFIFOSET(fd,WFIFOW(fd,2)); + packet->packetLen = sizeof(struct PACKET_ZC_BAN_LIST) + c * sizeof(struct PACKET_ZC_BAN_LIST_sub); + WFIFOSET(fd, packet->packetLen); } /// Guild chat message (ZC_GUILD_CHAT). @@ -9226,149 +9235,377 @@ static void clif_refresh(struct map_session_data *sd) clif->refresh_storagewindow(sd); } +static void clif_send_selforarea(int fd, struct block_list *bl, const void *buf, int len) +{ + // if no recipient specified just update nearby clients + // if no recipient specified just update nearby clients + if (fd == 0) { + clif->send(buf, len, bl, AREA); + } else { + struct map_session_data *sd = sockt->session_is_valid(fd) ? sockt->session[fd]->session_data : NULL; + if (sd != NULL) { + clif->send(buf, len, &sd->bl, SELF); + } else { + clif->send(buf, len, bl, SELF); + } + } +} + /// Updates the object's (bl) name on client. /// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) /// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) /// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) -static void clif_blname_ack(int fd, struct block_list *bl) +static void clif_pcname_ack(int fd, struct block_list *bl) { - struct packet_reqnameall_ack packet = { 0 }; - int len = sizeof(struct packet_reqnameall_ack); - nullpo_retv(bl); + Assert_retv(bl->type == BL_PC); - packet.packet_id = reqName; + struct PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; + int len = sizeof(struct PACKET_ZC_ACK_REQNAMEALL); packet.gid = bl->id; - switch(bl->type) { - case BL_PC: - { - 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; + 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->status.guild_id > 0 || ssd->status.party_id > 0 || ssd->status.title_id > 0) { - packet.packet_id = reqNameAllType; - } + if (ssd->fakename[0] != '\0' && ssd->disguise != -1) { + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; + len = sizeof(struct PACKET_ZC_ACK_REQNAMEALL); + } else { + packet.packet_id = reqName; + len = sizeof(struct packet_reqname_ack); + } - //Requesting your own "shadow" name. [Skotlex] - if (ssd->fd == fd && ssd->disguise != -1) { - packet.gid = -bl->id; - } + //Requesting your own "shadow" name. [Skotlex] + if (ssd->fd == fd && ssd->disguise != -1) { + packet.gid = -bl->id; + } - if (ssd->fakename[0] != '\0') { - memcpy(packet.name, ssd->fakename, NAME_LENGTH); - break; - } + if (ssd->fakename[0] != '\0' && ssd->disguise != -1) { + memcpy(packet.name, ssd->fakename, NAME_LENGTH); + } else { +#if PACKETVER_MAIN_NUM >= 20150225 || PACKETVER_RE_NUM >= 20141126 || defined(PACKETVER_ZERO) + // Title System [Dastgir/Hercules] + if (ssd->status.title_id > 0) { + packet.title_id = ssd->status.title_id; + } +#endif + memcpy(packet.name, ssd->status.name, NAME_LENGTH); -#if PACKETVER >= 20150503 - // Title System [Dastgir/Hercules] - if (ssd->status.title_id > 0) { - packet.title_id = ssd->status.title_id; + if (ssd->status.party_id != 0) { + p = party->search(ssd->status.party_id); + } + if (ssd->status.guild_id != 0) { + if ((g = ssd->guild) != NULL) { + int i; + ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id); + if (i < g->max_member) + ps = g->member[i].position; } + } + + if (!battle_config.display_party_name && g == NULL) { + // do not display party unless the player is also in a guild + p = NULL; + } + + if (p != NULL) { + memcpy(packet.party_name, p->party.name, NAME_LENGTH); + } + + if (g != NULL && ps >= 0 && ps < MAX_GUILDPOSITION) { + memcpy(packet.guild_name, g->name,NAME_LENGTH); + memcpy(packet.position_name, g->position[ps].name, NAME_LENGTH); + } + } + + clif->send_selforarea(fd, bl, &packet, len); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_homname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_HOM); + + 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_HOM, bl)->homunculus.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) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } #endif - memcpy(packet.name, ssd->status.name, NAME_LENGTH); + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} - if (ssd->status.party_id != 0) { - p = party->search(ssd->status.party_id); - } - if (ssd->status.guild_id != 0) { - if ((g = ssd->guild) != NULL) { - int i; - ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id); - if (i < g->max_member) - ps = g->member[i].position; - } - } +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_mername_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_MER); - if (!battle_config.display_party_name && g == NULL) { - // do not display party unless the player is also in a guild - p = NULL; - } + 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_MER, bl)->db->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) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } +#endif - if (p == NULL && g == NULL) - break; + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} - if (p != NULL) { - memcpy(packet.party_name, p->party.name, NAME_LENGTH); - } +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_petname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_PET); - if (g != NULL && ps >= 0 && ps < MAX_GUILDPOSITION) { - memcpy(packet.guild_name, g->name,NAME_LENGTH); - memcpy(packet.position_name, g->position[ps].name, NAME_LENGTH); - } - } + 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_PET, bl)->pet.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) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } +#endif + + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_npcname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_NPC); + + 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_NPC, bl)->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) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } +#endif + + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_mobname_guardian_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_MOB); + const struct mob_data *md = BL_UCCAST(BL_MOB, bl); + Assert_retv(md->guardian_data && md->guardian_data->g); + + struct PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; + packet.gid = bl->id; + memcpy(packet.name, md->name, NAME_LENGTH); + memcpy(packet.guild_name, md->guardian_data->g->name, NAME_LENGTH); + memcpy(packet.position_name, md->guardian_data->castle->castle_name, NAME_LENGTH); + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAMEALL)); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_mobname_normal_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_MOB); + + 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); +#if PACKETVER_MAIN_NUM >= 20180207 || PACKETVER_RE_NUM >= 20171129 || PACKETVER_ZERO_NUM >= 20171130 + struct unit_data *ud = unit->bl2ud(bl); + if (ud != NULL) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } +#endif + + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_mobname_additional_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_MOB); + + struct PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; + packet.gid = bl->id; + + const struct mob_data *md = BL_UCCAST(BL_MOB, bl); + + memcpy(packet.name, md->name, NAME_LENGTH); + char mobhp[100]; + char *str_p = mobhp; + if (battle_config.show_mob_info&4) + str_p += sprintf(str_p, "Lv. %d | ", md->level); + if (battle_config.show_mob_info&1) + str_p += sprintf(str_p, "HP: %u/%u | ", md->status.hp, md->status.max_hp); + if (battle_config.show_mob_info&2) + str_p += sprintf(str_p, "HP: %u%% | ", get_percentage(md->status.hp, md->status.max_hp)); + //Even thought mobhp ain't a name, we send it as one so the client + //can parse it. [Skotlex] + if (str_p != mobhp) { + *(str_p-3) = '\0'; //Remove trailing space + pipe. + memcpy(packet.party_name, mobhp, NAME_LENGTH); + } + + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAMEALL)); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_mobname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_MOB); + + const struct mob_data *md = BL_UCCAST(BL_MOB, bl); + + if (md->guardian_data && md->guardian_data->g) { + clif->mobname_guardian_ack(fd, bl); + } else if (battle_config.show_mob_info) { + clif->mobname_additional_ack(fd, bl); + } else { + clif->mobname_normal_ack(fd, bl); + } +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_chatname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_CHAT); + + struct PACKET_ZC_ACK_REQNAME_TITLE packet = { 0 }; + packet.packet_id = HEADER_ZC_ACK_REQNAME_TITLE; + packet.gid = bl->id; + +#if 0 // Clients DO request this... what should be done about it? The chat's title may not fit... [Skotlex] + memcpy(packet.name, BL_UCCAST(BL_CHAT, bl)->title, 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) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } +#endif +#endif + + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} + +/// Updates the object's (bl) name on client. +/// 0095 <id>.L <char name>.24B (ZC_ACK_REQNAME) +/// 0195 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B (ZC_ACK_REQNAMEALL) +/// 0A30 <id>.L <char name>.24B <party name>.24B <guild name>.24B <position name>.24B <title id>.L (ZC_ACK_REQNAMEALL2) +static void clif_elemname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + Assert_retv(bl->type == BL_ELEM); + + 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_ELEM, bl)->db->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) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->groupId; + } +#endif + + clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); +} + +static void clif_unknownname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + ShowError("clif_blname_ack: bad type %u(%d)\n", bl->type, bl->id); +} + +static void clif_blname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + + switch(bl->type) { + case BL_PC: + clif->pcname_ack(fd, bl); break; - //[blackhole89] case BL_HOM: - memcpy(packet.name, BL_UCCAST(BL_HOM, bl)->homunculus.name, NAME_LENGTH); + clif->homname_ack(fd, bl); break; case BL_MER: - memcpy(packet.name, BL_UCCAST(BL_MER, bl)->db->name, NAME_LENGTH); + clif->mername_ack(fd, bl); break; case BL_PET: - memcpy(packet.name, BL_UCCAST(BL_PET, bl)->pet.name, NAME_LENGTH); + clif->petname_ack(fd, bl); break; case BL_NPC: - memcpy(packet.name, BL_UCCAST(BL_NPC, bl)->name, NAME_LENGTH); + clif->npcname_ack(fd, bl); break; case BL_MOB: - { - const struct mob_data *md = BL_UCCAST(BL_MOB, bl); - - memcpy(packet.name, md->name, NAME_LENGTH); - if (md->guardian_data && md->guardian_data->g) { - packet.packet_id = reqNameAllType; - memcpy(packet.guild_name, md->guardian_data->g->name, NAME_LENGTH); - memcpy(packet.position_name, md->guardian_data->castle->castle_name, NAME_LENGTH); - } else if (battle_config.show_mob_info) { - char mobhp[50], *str_p = mobhp; - packet.packet_id = reqNameAllType; - if (battle_config.show_mob_info&4) - str_p += sprintf(str_p, "Lv. %d | ", md->level); - if (battle_config.show_mob_info&1) - str_p += sprintf(str_p, "HP: %u/%u | ", md->status.hp, md->status.max_hp); - if (battle_config.show_mob_info&2) - str_p += sprintf(str_p, "HP: %u%% | ", get_percentage(md->status.hp, md->status.max_hp)); - //Even thought mobhp ain't a name, we send it as one so the client - //can parse it. [Skotlex] - if (str_p != mobhp) { - *(str_p-3) = '\0'; //Remove trailing space + pipe. - memcpy(packet.party_name, mobhp, NAME_LENGTH); - } - } - } + clif->mobname_ack(fd, bl); break; case BL_CHAT: -#if 0 //FIXME: Clients DO request this... what should be done about it? The chat's title may not fit... [Skotlex] - memcpy(packet.name, BL_UCCAST(BL_CHAT, bl)->title, NAME_LENGTH); + clif->chatname_ack(fd, bl); break; -#endif - return; case BL_ELEM: - memcpy(packet.name, BL_UCCAST(BL_ELEM, bl)->db->name, NAME_LENGTH); + clif->elemname_ack(fd, bl); break; default: - ShowError("clif_blname_ack: bad type %u(%d)\n", bl->type, bl->id); - return; - } - - if (packet.packet_id == reqName) { - len = sizeof(struct packet_reqname_ack); - } - // if no recipient specified just update nearby clients - // if no recipient specified just update nearby clients - if (fd == 0) { - clif->send(&packet, len, bl, AREA); - } else { - struct map_session_data *sd = sockt->session_is_valid(fd) ? sockt->session[fd]->session_data : NULL; - if (sd != NULL) { - clif->send(&packet, len, &sd->bl, SELF); - } else { - clif->send(&packet, len, bl, SELF); - } + clif->unknownname_ack(fd, bl); + break; } } @@ -9379,14 +9616,14 @@ static void clif_charnameupdate(struct map_session_data *ssd) int ps = -1; struct party_data *p = NULL; struct guild *g = NULL; - struct packet_reqnameall_ack packet = { 0 }; + struct PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; nullpo_retv(ssd); if (ssd->fakename[0]) return; //No need to update as the party/guild was not displayed anyway. - packet.packet_id = reqNameAllType; + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; packet.gid = ssd->bl.id; memcpy(packet.name, ssd->status.name, NAME_LENGTH); @@ -9413,7 +9650,7 @@ static void clif_charnameupdate(struct map_session_data *ssd) memcpy(packet.position_name, g->position[ps].name, NAME_LENGTH); } -#if PACKETVER >= 20150503 +#if PACKETVER_MAIN_NUM >= 20150225 || PACKETVER_RE_NUM >= 20141126 || defined(PACKETVER_ZERO) // Achievement System [Dastgir/Hercules] if (ssd->status.title_id > 0) { packet.title_id = ssd->status.title_id; @@ -10742,8 +10979,10 @@ static void clif_parse_QuitGame(int fd, struct map_session_data *sd) /* Rovert's prevent logout option fixed [Valaris] */ if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && !sd->sc.data[SC_SUHIDE] && (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout)) { - sockt->eof(fd); clif->disconnect_ack(sd, 0); + sockt->flush(fd); + if (battle_config.drop_connection_on_quit) + sockt->eof(fd); } else { clif->disconnect_ack(sd, 1); } @@ -11535,7 +11774,7 @@ static void clif_parse_NpcClicked(int fd, struct map_session_data *sd) #endif return; } - if ( pc_cant_act2(sd) || !(bl = map->id2bl(RFIFOL(fd,2))) || sd->state.vending ) + if (pc_cant_act2(sd) || !(bl = map->id2bl(RFIFOL(fd,2))) || sd->state.vending || sd->state.prevend) return; switch (bl->type) { @@ -11907,7 +12146,7 @@ static void clif_parse_PutItemToCart(int fd, struct map_session_data *sd) __attr static void clif_parse_PutItemToCart(int fd, struct map_session_data *sd) { int flag = 0; - if (pc_istrading(sd)) + if (pc_istrading(sd) || sd->state.prevend) return; if (!pc_iscarton(sd)) return; @@ -11922,6 +12161,8 @@ static void clif_parse_GetItemFromCart(int fd, struct map_session_data *sd) __at /// 0127 <index>.W <amount>.L static void clif_parse_GetItemFromCart(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || sd->state.prevend) + return; if (!pc_iscarton(sd)) return; pc->getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4)); @@ -12796,7 +13037,7 @@ static void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) { int item_index, item_amount; - if (pc_istrading(sd)) + if (pc_istrading(sd) || sd->state.prevend) return; item_index = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-2; @@ -12817,6 +13058,9 @@ static void clif_parse_MoveFromKafra(int fd, struct map_session_data *sd) __attr /// There are various variants of this packet, some of them have padding between fields. static void clif_parse_MoveFromKafra(int fd, struct map_session_data *sd) { + if (pc_istrading(sd) || sd->state.prevend) + return; + int item_index, item_amount; item_index = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-1; @@ -12833,7 +13077,7 @@ static void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) /// 0129 <index>.W <amount>.L static void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) { - if( sd->state.vending ) + if (pc_istrading(sd) || sd->state.prevend) return; if (!pc_iscarton(sd)) return; @@ -12849,7 +13093,7 @@ static void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) /// 0128 <index>.W <amount>.L static void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) { - if( sd->state.vending ) + if (pc_istrading(sd) || sd->state.prevend) return; if (!pc_iscarton(sd)) return; @@ -16340,7 +16584,7 @@ static void clif_Auction_openwindow(struct map_session_data *sd) nullpo_retv(sd); fd = sd->fd; - if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->state.vending || sd->state.buyingstore || sd->state.trading) + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->state.vending || sd->state.prevend || sd->state.buyingstore || sd->state.trading) return; if( !battle_config.feature_auction ) @@ -17031,7 +17275,14 @@ static void clif_parse_PartyTick(int fd, struct map_session_data *sd) __attribut static void clif_parse_PartyTick(int fd, struct map_session_data *sd) { const struct PACKET_CZ_PARTY_CONFIG *const p = RFIFOP(fd, 0); - sd->status.allow_party = p->refuseInvite ? false : true; + const bool newAllowParty = p->refuseInvite ? true : false; + if (newAllowParty != sd->status.allow_party) { + sd->status.allow_party = newAllowParty; + if ((map->save_settings & 512) != 0) + chrif->save(sd, 0); // send to char server + } else { + sd->status.allow_party = newAllowParty; + } clif->partytickack(sd, sd->status.allow_party); } @@ -18923,7 +19174,7 @@ static void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) if( sd->menuskill_id != SC_AUTOSHADOWSPELL ) return; - if( pc_istrading(sd) ) { + if (pc_istrading(sd) || sd->state.prevend) { clif->skill_fail(sd, sd->ud.skill_id, 0, 0, 0); clif_menuskill_clear(sd); return; @@ -19272,18 +19523,24 @@ static void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) } else { result = CSBR_UNKONWN_ITEM; } - - WFIFOHEAD(fd, 16); - WFIFOW(fd, 0) = 0x849; - WFIFOL(fd, 2) = id; - WFIFOW(fd, 6) = result;/* result */ - WFIFOL(fd, 8) = sd->cashPoints;/* current cash point */ - WFIFOL(fd, 12) = sd->kafraPoints;// [Ryuuzaki] - WFIFOSET(fd, 16); + clif->cashShopBuyAck(fd, sd, id, result); } } +static void clif_cashShopBuyAck(int fd, struct map_session_data *sd, int itemId, enum CASH_SHOP_BUY_RESULT result) +{ + nullpo_retv(sd); + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT)); + struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT *p = WFIFOP(fd, 0); + p->packetType = 0x849; + p->itemId = itemId; + p->result = result; + p->cashPoints = sd->cashPoints; + p->kafraPoints = sd->kafraPoints; + WFIFOSET(fd, sizeof(struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT)); +} + static void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /* [Ind/Hercules] */ static void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) @@ -20309,20 +20566,34 @@ static void clif_roulette_generate_ack(struct map_session_data *sd, enum GENERAT #endif } +static void clif_roulette_close(struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20141008 || PACKETVER_RE_NUM >= 20140903 || defined(PACKETVER_ZERO) + nullpo_retv(sd); + + struct PACKET_ZC_ACK_CLOSE_ROULETTE p; + p.packetType = HEADER_ZC_ACK_CLOSE_ROULETTE; + p.result = 0; // close window + + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif +} + /** * Stackable items merger */ static void clif_openmergeitem(int fd, struct map_session_data *sd) { -#if PACKETVER > 20120228 - int i = 0, n = 0, j = 0; +#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO) + nullpo_retv(sd); + + int n = 0, j = 0; struct merge_item merge_items[MAX_INVENTORY]; struct merge_item *merge_items_[MAX_INVENTORY] = {0}; - nullpo_retv(sd); - memset(&merge_items,'\0',sizeof(merge_items)); + memset(&merge_items, '\0', sizeof(merge_items)); - for (i = 0; i < sd->status.inventorySize; i++) { + for (int i = 0; i < sd->status.inventorySize; i++) { struct item *item_data = &sd->status.inventory[i]; if (item_data->nameid == 0 || !itemdb->isstackable(item_data->nameid) || item_data->bound != IBT_NONE) @@ -20333,17 +20604,18 @@ static void clif_openmergeitem(int fd, struct map_session_data *sd) n++; } - qsort(merge_items,n,sizeof(struct merge_item),clif->comparemergeitem); + qsort(merge_items, n, sizeof(struct merge_item), clif->comparemergeitem); - for (i = 0, j = 0; i < n; i++) { - if (i > 0 && merge_items[i].nameid == merge_items[i-1].nameid) + j = 0; + for (int i = 0; i < n; i++) { + if (i > 0 && merge_items[i].nameid == merge_items[i - 1].nameid) { merge_items_[j] = &merge_items[i]; j++; continue; } - if (i < n - 1 && merge_items[i].nameid == merge_items[i+1].nameid) + if (i < n - 1 && merge_items[i].nameid == merge_items[i + 1].nameid) { merge_items_[j] = &merge_items[i]; j++; @@ -20351,12 +20623,14 @@ static void clif_openmergeitem(int fd, struct map_session_data *sd) } } - WFIFOHEAD(fd,2*j+4); - WFIFOW(fd,0) = 0x96d; - WFIFOW(fd,2) = 2*j+4; - for ( i = 0; i < j; i++ ) - WFIFOW(fd,i*2+4) = merge_items_[i]->position; - WFIFOSET(fd,2*j+4); + const int len = sizeof(struct PACKET_ZC_MERGE_ITEM_OPEN) + j * sizeof(struct PACKET_ZC_MERGE_ITEM_OPEN_sub); + WFIFOHEAD(fd, len); + struct PACKET_ZC_MERGE_ITEM_OPEN *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_MERGE_ITEM_OPEN; + p->packetLen = len; + for (int i = 0; i < j; i++) + p->items[i].index = merge_items_[i]->position; + WFIFOSET(fd, len); #endif } @@ -20372,35 +20646,42 @@ static int clif_comparemergeitem(const void *a, const void *b) return a_->nameid > b_->nameid ? -1 : 1; } +static void clif_mergeitems(int fd, struct map_session_data *sd, int index, int amount, enum mergeitem_reason reason) +{ +#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO) + WFIFOHEAD(fd, sizeof(struct PACKET_ZC_ACK_MERGE_ITEM)); + struct PACKET_ZC_ACK_MERGE_ITEM *p = WFIFOP(fd, 0); + p->packetType = HEADER_ZC_ACK_MERGE_ITEM; + p->index = index + 2; + p->amount = amount; + p->reason = reason; + WFIFOSET(fd, sizeof(struct PACKET_ZC_ACK_MERGE_ITEM)); +#endif +} + static void clif_ackmergeitems(int fd, struct map_session_data *sd) { -#if PACKETVER > 20120228 - int i = 0, n = 0, length = 0, count = 0; +#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO) + nullpo_retv(sd); + + int i = 0, n = 0, count = 0; int nameid = 0; int16 indexes[MAX_INVENTORY] = {0}, amounts[MAX_INVENTORY] = {0}; - struct item item_data; - nullpo_retv(sd); - length = (RFIFOW(fd,2) - 4)/2; + int length = (RFIFOW(fd, 2) - 4) / 2; if (length >= sd->status.inventorySize || length < 2) { - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x96f; - WFIFOW(fd,2) = 0; - WFIFOW(fd,4) = 0; - WFIFOB(fd,6) = MERGEITEM_FAILD; - WFIFOSET(fd,7); + clif->mergeitems(fd, sd, 0, 0, MERGEITEM_FAILD); return; } for (i = 0, n = 0; i < length; i++) { - int16 idx = RFIFOW(fd,i*2+4) - 2; - struct item *it = NULL; + int16 idx = RFIFOW(fd, i * 2 + 4) - 2; if (idx < 0 || idx >= sd->status.inventorySize) continue; - it = &sd->status.inventory[idx]; + struct item *it = &sd->status.inventory[idx]; if (it->nameid == 0 || !itemdb->isstackable(it->nameid) || it->bound != IBT_NONE) continue; @@ -20418,43 +20699,29 @@ static void clif_ackmergeitems(int fd, struct map_session_data *sd) } if (n < 2 || count == 0) { - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x96f; - WFIFOW(fd,2) = 0; - WFIFOW(fd,4) = 0; - WFIFOB(fd,6) = MERGEITEM_FAILD; - WFIFOSET(fd,7); + clif->mergeitems(fd, sd, 0, 0, MERGEITEM_FAILD); return; } if (count > MAX_AMOUNT) { - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x96f; - WFIFOW(fd,2) = 0; - WFIFOW(fd,4) = 0; - WFIFOB(fd,6) = MERGEITEM_MAXCOUNTFAILD; - WFIFOSET(fd,7); + clif->mergeitems(fd, sd, 0, 0, MERGEITEM_MAXCOUNTFAILD); return; } for (i = 0; i < n; i++) - pc->delitem(sd,indexes[i],amounts[i],0,DELITEM_NORMAL,LOG_TYPE_NPC); + pc->delitem(sd, indexes[i], amounts[i], 0, DELITEM_NORMAL, LOG_TYPE_NPC); - memset(&item_data,'\0',sizeof(item_data)); + struct item item_data; + memset(&item_data, '\0', sizeof(item_data)); item_data.nameid = nameid; item_data.identify = 1; item_data.unique_id = itemdb->unique_id(sd); - pc->additem(sd,&item_data,count,LOG_TYPE_NPC); + pc->additem(sd, &item_data, count, LOG_TYPE_NPC); ARR_FIND(0, sd->status.inventorySize, i, item_data.unique_id == sd->status.inventory[i].unique_id); - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x96f; - WFIFOW(fd,2) = i+2; - WFIFOW(fd,4) = count; - WFIFOB(fd,6) = MERGEITEM_SUCCESS; - WFIFOSET(fd,7); + clif->mergeitems(fd, sd, i, count, MERGEITEM_SUCCESS); #endif } @@ -21835,6 +22102,17 @@ static void clif_parse_attendance_reward_request(int fd, struct map_session_data static void clif_parse_cz_blocking_play_cancel(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_cz_blocking_play_cancel(int fd, struct map_session_data *sd) { + clif->loadConfirm(sd); +} + +static void clif_loadConfirm(struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190403 || PACKETVER_RE_NUM >= 20190320 || PACKETVER_ZERO_NUM >= 20190410 + nullpo_retv(sd); + struct PACKET_ZC_LOAD_CONFIRM p; + p.packetType = HEADER_ZC_LOAD_CONFIRM; + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif } static void clif_ui_action(struct map_session_data *sd, int32 UIType, int32 data) @@ -22699,6 +22977,18 @@ void clif_defaults(void) clif->mvp_noitem = clif_mvp_noitem; clif->changed_dir = clif_changed_dir; clif->blname_ack = clif_blname_ack; + clif->pcname_ack = clif_pcname_ack; + clif->homname_ack = clif_homname_ack; + clif->mername_ack = clif_mername_ack; + clif->petname_ack = clif_petname_ack; + clif->npcname_ack = clif_npcname_ack; + clif->mobname_ack = clif_mobname_ack; + clif->mobname_guardian_ack = clif_mobname_guardian_ack; + clif->mobname_additional_ack = clif_mobname_additional_ack; + clif->mobname_normal_ack = clif_mobname_normal_ack; + clif->chatname_ack = clif_chatname_ack; + clif->elemname_ack = clif_elemname_ack; + clif->unknownname_ack = clif_unknownname_ack; clif->monster_hp_bar = clif_monster_hp_bar; clif->hpmeter = clif_hpmeter; clif->hpmeter_single = clif_hpmeter_single; @@ -22796,6 +23086,7 @@ void clif_defaults(void) clif->joinchatok = clif_joinchatok; clif->addchat = clif_addchat; clif->changechatowner = clif_changechatowner; + clif->chatRoleChange = clif_chatRoleChange; clif->clearchat = clif_clearchat; clif->leavechat = clif_leavechat; clif->changechatstatus = clif_changechatstatus; @@ -23058,11 +23349,13 @@ void clif_defaults(void) /* */ clif->parse_roulette_db = clif_parse_roulette_db; clif->roulette_generate_ack = clif_roulette_generate_ack; + clif->roulette_close = clif_roulette_close; /* Merge Items */ clif->openmergeitem = clif_openmergeitem; clif->cancelmergeitem = clif_cancelmergeitem; clif->comparemergeitem = clif_comparemergeitem; clif->ackmergeitems = clif_ackmergeitems; + clif->mergeitems = clif_mergeitems; /* Cart Deco */ clif->selectcart = clif_selectcart; /* */ @@ -23298,6 +23591,7 @@ void clif_defaults(void) clif->pCashShopReqTab = clif_parse_CashShopReqTab; clif->pCashShopSchedule = clif_parse_CashShopSchedule; clif->pCashShopBuy = clif_parse_CashShopBuy; + clif->cashShopBuyAck = clif_cashShopBuyAck; /* */ clif->pPartyTick = clif_parse_PartyTick; clif->pGuildInvite2 = clif_parse_GuildInvite2; @@ -23409,4 +23703,6 @@ void clif_defaults(void) clif->pingTimer = clif_pingTimer; clif->pingTimerSub = clif_pingTimerSub; clif->pResetCooldown = clif_parse_ResetCooldown; + clif->loadConfirm = clif_loadConfirm; + clif->send_selforarea = clif_send_selforarea; } |