فهرست منبع

Guild emblem implementation for late 2019 clients or later (#5144)

Co-authored-by: valhein <35770095+attackjom@users.noreply.github.com>
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Co-authored-by: Aleos <aleos89@users.noreply.github.com>
Jittapan Pluemsumran 4 سال پیش
والد
کامیت
d38d2b6b71
9فایلهای تغییر یافته به همراه156 افزوده شده و 17 حذف شده
  1. 29 0
      src/char/int_guild.cpp
  2. 1 1
      src/char/inter.cpp
  3. 37 10
      src/map/clif.cpp
  4. 5 0
      src/map/clif_packetdb.hpp
  5. 33 5
      src/map/guild.cpp
  6. 1 0
      src/map/guild.hpp
  7. 23 1
      src/map/intif.cpp
  8. 1 0
      src/map/intif.hpp
  9. 26 0
      src/map/packets_struct.hpp

+ 29 - 0
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;

+ 1 - 1
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]

+ 37 - 10
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 <id>.L <guild id>.L <emblem id>.W
+/// 0b47 <guild id>.L <version>.L <unknown>.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 <guild id>.L <version>.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 <guild id>.L <msg1>.60B <msg2>.120B
@@ -21618,4 +21646,3 @@ void do_init_clif(void) {
 void do_final_clif(void) {
 	ers_destroy(delay_clearunit_ers);
 }
-

+ 5 - 0
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 );

+ 33 - 5
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;
 

+ 1 - 0
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);

+ 23 - 1
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

+ 1 - 0
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

+ 26 - 0
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