From d38d2b6b71ee367ee7463aaf2914d197e7d9afb2 Mon Sep 17 00:00:00 2001 From: Jittapan Pluemsumran Date: Tue, 30 Jun 2020 15:57:03 +0700 Subject: [PATCH] Guild emblem implementation for late 2019 clients or later (#5144) Co-authored-by: valhein <35770095+attackjom@users.noreply.github.com> Co-authored-by: Lemongrass3110 Co-authored-by: Aleos --- src/char/int_guild.cpp | 29 +++++++++++++++++++++++ src/char/inter.cpp | 2 +- src/map/clif.cpp | 47 ++++++++++++++++++++++++++++++-------- src/map/clif_packetdb.hpp | 5 ++++ src/map/guild.cpp | 38 ++++++++++++++++++++++++++---- src/map/guild.hpp | 1 + src/map/intif.cpp | 24 ++++++++++++++++++- src/map/intif.hpp | 1 + src/map/packets_struct.hpp | 26 +++++++++++++++++++++ 9 files changed, 156 insertions(+), 17 deletions(-) diff --git a/src/char/int_guild.cpp b/src/char/int_guild.cpp index 5aeda89139..9f2335a8c8 100644 --- a/src/char/int_guild.cpp +++ b/src/char/int_guild.cpp @@ -1130,6 +1130,18 @@ int mapif_guild_emblem(struct guild *g) return 0; } +// Send the guild emblem_id (version) +int mapif_guild_emblem_version(guild* g) +{ + unsigned char buf[10]; + WBUFW(buf, 0) = 0x3841; + WBUFL(buf, 2) = g->guild_id; + WBUFL(buf, 6) = g->emblem_id; + chmapif_sendall(buf, 10); + + return 0; +} + int mapif_guild_master_changed(struct guild *g, int aid, int cid, time_t time) { unsigned char buf[18]; @@ -1884,6 +1896,22 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int le return mapif_guild_master_changed(g, g->member[0].account_id, g->member[0].char_id, g->last_leader_change); } +int mapif_parse_GuildEmblemVersion(int fd, int guild_id, int version) +{ + guild* g = inter_guild_fromsql(guild_id); + + if (g == nullptr) + return 0; + + g->emblem_len = 0; + g->emblem_id = version; + g->save_flag |= GS_EMBLEM; + + mapif_guild_emblem_version(g); + + return 1; +} + // Communication from the map server // - Can analyzed only one by one packet // Data packet length that you set to inter.cpp @@ -1912,6 +1940,7 @@ int inter_guild_parse_frommap(int fd) case 0x303F: mapif_parse_GuildEmblem(fd,RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOCP(fd,12)); break; case 0x3040: mapif_parse_GuildCastleDataLoad(fd,RFIFOW(fd,2),(int *)RFIFOP(fd,4)); break; case 0x3041: mapif_parse_GuildCastleDataSave(fd,RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); break; + case 0x3042: mapif_parse_GuildEmblemVersion(fd, RFIFOL(fd, 2), RFIFOL(fd, 6)); break; default: return 0; diff --git a/src/char/inter.cpp b/src/char/inter.cpp index b38e7bb8e9..00ccbd60da 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -58,7 +58,7 @@ int inter_recv_packet_length[] = { 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- -1,10,-1,14, 15+NAME_LENGTH,19, 6,-1, 14,14, 6, 0, 0, 0, 0, 0, // 3020- Party -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- - -1, 9, 0, 0, 0, 0, 0, 0, 8, 6,11,10, 10,-1,6+NAME_LENGTH, 0, // 3040- + -1, 9,10, 0, 0, 0, 0, 0, 8, 6,11,10, 10,-1,6+NAME_LENGTH, 0, // 3040- -1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] 6,-1, 6,-1, 16+NAME_LENGTH+ACHIEVEMENT_NAME_LENGTH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] / Achievements [Aleos] -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil] diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 84cf82671d..7518393b71 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -8765,19 +8765,24 @@ void clif_guild_emblem(struct map_session_data *sd,struct guild *g) /// Sends update of the guild id/emblem id to everyone in the area (ZC_CHANGE_GUILD). /// 01b4 .L .L .W +/// 0b47 .L .L .L void clif_guild_emblem_area(struct block_list* bl) { - uint8 buf[12]; - - nullpo_retv(bl); - // TODO this packet doesn't force the update of ui components that have the emblem visible // (emblem in the flag npcs and emblem over the head in agit maps) [FlavioJS] - WBUFW(buf,0) = 0x1b4; - WBUFL(buf,2) = bl->id; - WBUFL(buf,6) = status_get_guild_id(bl); - WBUFW(buf,10) = status_get_emblem_id(bl); - clif_send(buf, 12, bl, AREA_WOS); + PACKET_ZC_CHANGE_GUILD p{}; + + p.packetType = changeGuildEmblem; + p.guild_id = status_get_guild_id(bl); + p.emblem_id = status_get_emblem_id(bl); + +#if PACKETVER < 20190724 + p.aid = bl->id; +#else + p.unknown = 0; +#endif + + clif_send(&p, sizeof(p), bl, AREA_WOS); } @@ -13843,6 +13848,29 @@ void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd){ guild_change_emblem(sd, emblem_len, (const char*)emblem); } +/// Request to update the guild emblem id (version, according to Gravity) +/// 0b46 .L .L +void clif_parse_GuildChangeEmblem2(int fd, struct map_session_data* sd) { + nullpo_retv(sd); + +#if PACKETVER >= 20190724 + const PACKET_CZ_GUILD_EMBLEM_CHANGE2* p = (PACKET_CZ_GUILD_EMBLEM_CHANGE2*)RFIFOP(fd, 0); + guild* g = sd->guild; + + if (g == nullptr || g->guild_id != p->guild_id) + return; + + if (!sd->state.gmaster_flag) + return; + + if (!battle_config.emblem_woe_change && is_agit_start()) { + clif_messagecolor(&sd->bl, color_table[COLOR_RED], msg_txt(sd, 385), false, SELF); //"You not allowed to change emblem during woe" + return; + } + + guild_change_emblem_version(sd, p->version); +#endif +} /// Guild notice update request (CZ_GUILD_NOTICE). /// 016e .L .60B .120B @@ -21618,4 +21646,3 @@ void do_init_clif(void) { void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } - diff --git a/src/map/clif_packetdb.hpp b/src/map/clif_packetdb.hpp index cb8b44bcdc..5caffc8c08 100644 --- a/src/map/clif_packetdb.hpp +++ b/src/map/clif_packetdb.hpp @@ -2447,6 +2447,11 @@ parseable_packet( 0x0B1C, sizeof( struct PACKET_CZ_PING ), clif_parse_dull, 0 ); #endif +#if PACKETVER >= 20190724 + parseable_packet(HEADER_CZ_GUILD_EMBLEM_CHANGE2, sizeof( PACKET_CZ_GUILD_EMBLEM_CHANGE2 ), clif_parse_GuildChangeEmblem2, 0 ); + packet(HEADER_ZC_CHANGE_GUILD, sizeof(PACKET_ZC_CHANGE_GUILD)); +#endif + #if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605 parseable_packet( 0x0B21, sizeof( struct PACKET_CZ_SHORTCUT_KEY_CHANGE2 ), clif_parse_Hotkey, 0 ); parseable_packet( 0x0B22, sizeof( struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE2 ), clif_parse_HotkeyRowShift, 0 ); diff --git a/src/map/guild.cpp b/src/map/guild.cpp index 28d5a2c747..cd478eb167 100644 --- a/src/map/guild.cpp +++ b/src/map/guild.cpp @@ -1262,22 +1262,49 @@ int guild_notice_changed(int guild_id,const char *mes1,const char *mes2) { return 0; } +/*==================================================== + * Check condition for changing guild emblem + *---------------------------------------------------*/ +bool guild_check_emblem_change_condition(map_session_data *sd) +{ + nullpo_ret(sd); + guild* g = sd->guild; + + if (battle_config.require_glory_guild && g != nullptr && guild_checkskill(g, GD_GLORYGUILD) > 0) { + clif_skill_fail(sd, GD_GLORYGUILD, USESKILL_FAIL_LEVEL, 0); + return false; + } + + return true; +} + /*==================================================== * Change guild emblem *---------------------------------------------------*/ int guild_change_emblem(struct map_session_data *sd,int len,const char *data) { - struct guild *g; nullpo_ret(sd); - if (battle_config.require_glory_guild && - !((g = sd->guild) && guild_checkskill(g, GD_GLORYGUILD)>0)) { - clif_skill_fail(sd,GD_GLORYGUILD,USESKILL_FAIL_LEVEL,0); + if (!guild_check_emblem_change_condition(sd)) { return 0; } return intif_guild_emblem(sd->status.guild_id,len,data); } +/*==================================================== + * Change guild emblem version + *---------------------------------------------------*/ +int guild_change_emblem_version(map_session_data* sd, int version) +{ + nullpo_ret(sd); + + if (!guild_check_emblem_change_condition(sd)) { + return 0; + } + + return intif_guild_emblem_version(sd->status.guild_id, version); +} + /*==================================================== * Notification of guild emblem changed *---------------------------------------------------*/ @@ -1288,7 +1315,8 @@ int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data) { if(g==NULL) return 0; - memcpy(g->emblem_data,data,len); + if (data != nullptr) + memcpy(g->emblem_data,data,len); g->emblem_len=len; g->emblem_id=emblem_id; diff --git a/src/map/guild.hpp b/src/map/guild.hpp index 456c91afe9..37e4530f3c 100644 --- a/src/map/guild.hpp +++ b/src/map/guild.hpp @@ -82,6 +82,7 @@ int guild_position_changed(int guild_id,int idx,struct guild_position *p); int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2); int guild_notice_changed(int guild_id,const char *mes1,const char *mes2); int guild_change_emblem(struct map_session_data *sd,int len,const char *data); +int guild_change_emblem_version(map_session_data* sd, int version); int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data); int guild_send_message(struct map_session_data *sd,const char *mes,int len); int guild_recv_message(int guild_id,uint32 account_id,const char *mes,int len); diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 55b74712c9..65c54f145c 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -39,7 +39,7 @@ static const int packet_len_table[] = { 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 39,-1,15,15, 15+NAME_LENGTH,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 - -1, 0, 0,18, 0, 0, 0, 0, -1,75,-1,11, 11,-1, 38, 0, //0x3840 + -1,10, 0,18, 0, 0, 0, 0, -1,75,-1,11, 11,-1, 38, 0, //0x3840 -1,-1, 7, 7, 7,11, 8,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari] -1, 7,-1, 7, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish] / Achievements [Aleos] -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil] @@ -1132,6 +1132,21 @@ int intif_guild_emblem(int guild_id,int len,const char *data) return 1; } +int intif_guild_emblem_version(int guild_id, int emblem_id) +{ + if (CheckForCharServer()) + return 0; + if (guild_id <= 0) + return 0; + WFIFOHEAD(inter_fd, 10); + WFIFOW(inter_fd, 0) = 0x3042; + WFIFOL(inter_fd, 2) = guild_id; + WFIFOL(inter_fd, 6) = emblem_id; + WFIFOSET(inter_fd, 10); + + return 1; +} + /** * Requests guild castles data from char-server. * @param num Number of castles, size of castle_ids array. @@ -1818,6 +1833,12 @@ int intif_parse_GuildEmblem(int fd) return 1; } +int intif_parse_GuildEmblemVersionChanged(int fd) +{ + guild_emblem_changed(0, RFIFOL(fd, 2), RFIFOL(fd, 6), nullptr); // Doesn't need emblem length and data + return 1; +} + /** * ACK guild message * @param fd : char-serv link @@ -3762,6 +3783,7 @@ int intif_parse(int fd) case 0x383e: intif_parse_GuildNotice(fd); break; case 0x383f: intif_parse_GuildEmblem(fd); break; case 0x3840: intif_parse_GuildCastleDataLoad(fd); break; + case 0x3841: intif_parse_GuildEmblemVersionChanged(fd); break; case 0x3843: intif_parse_GuildMasterChanged(fd); break; // Mail System diff --git a/src/map/intif.hpp b/src/map/intif.hpp index 7bd164fa91..b3acb8b770 100644 --- a/src/map/intif.hpp +++ b/src/map/intif.hpp @@ -63,6 +63,7 @@ int intif_guild_skillup(int guild_id, uint16 skill_id, uint32 account_id, int ma int intif_guild_alliance(int guild_id1, int guild_id2, uint32 account_id1, uint32 account_id2, int flag); int intif_guild_notice(int guild_id, const char *mes1, const char *mes2); int intif_guild_emblem(int guild_id, int len, const char *data); +int intif_guild_emblem_version(int guild_id, int version); int intif_guild_castle_dataload(int num, int *castle_ids); int intif_guild_castle_datasave(int castle_id, int index, int value); #ifdef BOUND_ITEMS diff --git a/src/map/packets_struct.hpp b/src/map/packets_struct.hpp index f3ed2a73f9..e75000fa08 100644 --- a/src/map/packets_struct.hpp +++ b/src/map/packets_struct.hpp @@ -405,6 +405,11 @@ enum packet_headers { #else guildLeave = 0x15a, #endif +#if PACKETVER >= 20190724 + changeGuildEmblem = 0xb47, +#else + changeGuildEmblem = 0x1b4, +#endif }; #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute @@ -3870,6 +3875,27 @@ struct PACKET_ZC_AUTORUN_SKILL { } __attribute__((packed)); DEFINE_PACKET_HEADER(ZC_AUTORUN_SKILL, 0x0147); +struct PACKET_CZ_GUILD_EMBLEM_CHANGE2 { + int16 packetType; + uint32 guild_id; + uint32 version; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_GUILD_EMBLEM_CHANGE2, 0x0b46); + +struct PACKET_ZC_CHANGE_GUILD { + int16 packetType; +#if PACKETVER < 20190724 + uint32 aid; + uint32 guild_id; + uint16 emblem_id; +#else + uint32 guild_id; + uint32 emblem_id; + uint32 unknown; +#endif +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_CHANGE_GUILD, 0x0b47); + #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) #endif // not NetBSD < 6 / Solaris