Bläddra i källkod

Initial support for newer packet versions (#4944)

Basic support for packets up to April 2020
Changing the default packet version to 2020-04-01

Thanks to everyone involved!
Lemongrass3110 5 år sedan
förälder
incheckning
45cd5808b7

+ 7 - 0
conf/battle/client.conf

@@ -138,3 +138,10 @@ spawn_direction: no
 // kRO removed the packet and this re-enables the message.
 // Official: Disabled.
 mvp_exp_reward_message: no
+
+// Send ping timer
+// Interval in seconds for each timer invoke.
+ping_timer_inverval: 30
+
+// Send packets timeout in seconds before ping packet can be sent.
+ping_time: 20

+ 1 - 0
sql-files/main.sql

@@ -254,6 +254,7 @@ CREATE TABLE IF NOT EXISTS `char` (
   `uniqueitem_counter` int(11) unsigned NOT NULL default '0',
   `sex` ENUM('M','F','U') NOT NULL default 'U',
   `hotkey_rowshift` tinyint(3) unsigned NOT NULL default '0',
+  `hotkey_rowshift2` tinyint(3) unsigned NOT NULL default '0',
   `clan_id` int(11) unsigned NOT NULL default '0',
   `last_login` datetime DEFAULT NULL,
   `title_id` INT(11) unsigned NOT NULL default '0',

+ 1 - 0
sql-files/upgrades/upgrade_20200603.sql

@@ -0,0 +1 @@
+ALTER TABLE  `char` ADD COLUMN `hotkey_rowshift2` TINYINT(3) UNSIGNED NOT NULL DEFAULT  '0' AFTER `hotkey_rowshift`;

+ 11 - 7
src/char/char.cpp

@@ -299,7 +299,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
 		(p->rename != cp->rename) || (p->robe != cp->robe) || (p->character_moves != cp->character_moves) ||
 		(p->unban_time != cp->unban_time) || (p->font != cp->font) || (p->uniqueitem_counter != cp->uniqueitem_counter) ||
 		(p->hotkey_rowshift != cp->hotkey_rowshift) || (p->clan_id != cp->clan_id ) || (p->title_id != cp->title_id) ||
-		(p->show_equip != cp->show_equip)
+		(p->show_equip != cp->show_equip) || (p->hotkey_rowshift2 != cp->hotkey_rowshift2)
 	)
 	{	//Save status
 		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `base_level`='%d', `job_level`='%d',"
@@ -310,7 +310,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
 			"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
 			"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
 			"`delete_date`='%lu',`robe`='%d',`moves`='%d',`font`='%u',`uniqueitem_counter`='%u',"
-			"`hotkey_rowshift`='%d', `clan_id`='%d', `title_id`='%lu', `show_equip`='%d'"
+			"`hotkey_rowshift`='%d', `clan_id`='%d', `title_id`='%lu', `show_equip`='%d', `hotkey_rowshift2`='%d'"
 			" WHERE `account_id`='%d' AND `char_id` = '%d'",
 			schema_config.char_db, p->base_level, p->job_level,
 			p->base_exp, p->job_exp, p->zeny,
@@ -322,7 +322,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
 			mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
 			(unsigned long)p->delete_date, // FIXME: platform-dependent size
 			p->robe, p->character_moves, p->font, p->uniqueitem_counter,
-			p->hotkey_rowshift, p->clan_id, p->title_id, p->show_equip,
+			p->hotkey_rowshift, p->clan_id, p->title_id, p->show_equip, p->hotkey_rowshift2,
 			p->account_id, p->char_id) )
 		{
 			Sql_ShowDebug(sql_handle);
@@ -924,7 +924,8 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
 		"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
 		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
 		"`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
-		"`robe`,`moves`,`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`title_id`,`show_equip`"
+		"`robe`,`moves`,`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`title_id`,`show_equip`,"
+		"`hotkey_rowshift2`"
 		" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", schema_config.char_db, sd->account_id, MAX_CHARS)
 	||	SQL_ERROR == SqlStmt_Execute(stmt)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0,  SQLDT_INT,    &p.char_id, 0, NULL, NULL)
@@ -972,6 +973,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_UCHAR,  &p.hotkey_rowshift, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_ULONG,  &p.title_id, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_UINT16, &p.show_equip, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UCHAR,  &p.hotkey_rowshift2, 0, NULL, NULL)
 	)
 	{
 		SqlStmt_ShowDebug(stmt);
@@ -1039,7 +1041,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
 		"`hair_color`,`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
 		"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`, `moves`,"
-		"`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`title_id`,`show_equip`"
+		"`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`title_id`,`show_equip`,`hotkey_rowshift2`"
 		" FROM `%s` WHERE `char_id`=? LIMIT 1", schema_config.char_db)
 	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
 	||	SQL_ERROR == SqlStmt_Execute(stmt)
@@ -1105,6 +1107,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 59, SQLDT_INT,    &p->clan_id, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 60, SQLDT_ULONG,  &p->title_id, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 61, SQLDT_UINT16, &p->show_equip, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 62, SQLDT_UCHAR,  &p->hotkey_rowshift2, 0, NULL, NULL)
 	)
 	{
 		SqlStmt_ShowDebug(stmt);
@@ -1211,7 +1214,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 
 	while( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
 	{
-		if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS )
+		if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS_DB )
 			memcpy(&p->hotkeys[hotkey_num], &tmp_hotkey, sizeof(tmp_hotkey));
 		else
 			ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
@@ -2318,7 +2321,8 @@ bool char_checkdb(void){
 		"`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,`hair_color`,`clothes_color`,`weapon`,"
 		"`shield`,`head_top`,`head_mid`,`head_bottom`,`robe`,`last_map`,`last_x`,`last_y`,`save_map`,"
 		"`save_x`,`save_y`,`partner_id`,`online`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,"
-		"`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`,`title_id`,`show_equip`"
+		"`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`,`title_id`,`show_equip`,"
+		"`hotkey_rowshift2`"
 		" FROM `%s` LIMIT 1;", schema_config.char_db) ){
 		Sql_ShowDebug(sql_handle);
 		return false;

+ 8 - 1
src/common/mmo.hpp

@@ -33,6 +33,12 @@
 	#define MAX_HOTKEYS 38
 #endif
 
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+	#define MAX_HOTKEYS_DB ((MAX_HOTKEYS) * 2)
+#else
+	#define MAX_HOTKEYS_DB MAX_HOTKEYS
+#endif
+
 #define MAX_MAP_PER_SERVER 1500 /// Maximum amount of maps available on a server
 #define MAX_INVENTORY 100 ///Maximum items in player inventory
 /** Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
@@ -518,7 +524,7 @@ struct mmo_charstatus {
 
 	struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
 #ifdef HOTKEY_SAVING
-	struct hotkey hotkeys[MAX_HOTKEYS];
+	struct hotkey hotkeys[MAX_HOTKEYS_DB];
 #endif
 	bool show_equip,allow_party;
 	short rename;
@@ -536,6 +542,7 @@ struct mmo_charstatus {
 	uint32 uniqueitem_counter;
 
 	unsigned char hotkey_rowshift;
+	unsigned char hotkey_rowshift2;
 	unsigned long title_id;
 };
 

+ 4 - 0
src/common/socket.cpp

@@ -428,6 +428,8 @@ int send_from_fifo(int fd)
 
 	if( len > 0 )
 	{
+		session[fd]->wdata_tick = last_tick;
+
 		// some data could not be transferred?
 		// shift unsent data to the beginning of the queue
 		if( (size_t)len < session[fd]->wdata_size )
@@ -587,6 +589,7 @@ int make_listen_bind(uint32 ip, uint16 port)
 	create_session(fd, connect_client, null_send, null_parse);
 	session[fd]->client_addr = 0; // just listens
 	session[fd]->rdata_tick = 0; // disable timeouts on this socket
+	session[fd]->wdata_tick = 0;
 
 	return fd;
 }
@@ -727,6 +730,7 @@ static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseF
 	session[fd]->func_send  = func_send;
 	session[fd]->func_parse = func_parse;
 	session[fd]->rdata_tick = last_tick;
+	session[fd]->wdata_tick = last_tick;
 	return 0;
 }
 

+ 1 - 0
src/common/socket.hpp

@@ -98,6 +98,7 @@ struct socket_data
 	size_t rdata_size, wdata_size;
 	size_t rdata_pos;
 	time_t rdata_tick; // time of last recv (for detecting timeouts); zero when timeout is disabled
+	time_t wdata_tick; // time of last send (for detecting timeouts);
 
 	RecvFunc func_recv;
 	SendFunc func_send;

+ 18 - 1
src/config/packets.hpp

@@ -13,7 +13,7 @@
 	/// Do NOT edit this line! To set your client version, please do this instead:
 	/// In Windows: Add this line in your src\custom\defines_pre.hpp file: #define PACKETVER YYYYMMDD
 	/// In Linux: The same as above or run the following command: ./configure --enable-packetver=YYYYMMDD
-	#define PACKETVER 20180620
+	#define PACKETVER 20200401
 #endif
 
 #ifndef PACKETVER_RE
@@ -24,6 +24,23 @@
 	#endif
 #endif
 
+#ifndef PACKETVER_RE
+	#define PACKETVER_MAIN_NUM PACKETVER
+
+	// Undefine all sakray server definitions
+	#undef PACKETVER_RE
+	#undef PACKETVER_RE_NUM
+#else
+	// Undefine existing definition
+	#undef PACKETVER_RE
+
+	#define PACKETVER_RE PACKETVER
+	#define PACKETVER_RE_NUM PACKETVER
+
+	// Undefine all main server definitions
+	#undef PACKETVER_MAIN_NUM
+#endif
+
 #if PACKETVER >= 20110817
 	/// Comment to disable the official packet obfuscation support.
 	/// This requires PACKETVER 2011-08-17 or newer.

+ 18 - 0
src/login/loginclif.cpp

@@ -457,6 +457,20 @@ static int logclif_parse_reqcharconnec(int fd, struct login_session_data *sd, ch
 	return 1;
 }
 
+int logclif_parse_otp_login( int fd, struct login_session_data* sd ){
+	RFIFOSKIP( fd, 68 );
+
+	WFIFOHEAD( fd, 34 );
+	WFIFOW( fd, 0 ) = 0xae3;
+	WFIFOW( fd, 2 ) = 34;
+	WFIFOL( fd, 4 ) = 0; // normal login
+	safestrncpy( WFIFOCP( fd, 8 ), "S1000", 6 );
+	safestrncpy( WFIFOCP( fd, 28 ), "token", 6 );
+	WFIFOSET( fd, 34 );
+
+	return 1;
+}
+
 /**
  * Entry point from client to log-server.
  * Function that checks incoming command, then splits it to the correct handler.
@@ -521,6 +535,10 @@ int logclif_parse(int fd) {
 			break;
 		// Sending request of the coding key
 		case 0x01db: next = logclif_parse_reqkey(fd, sd); break;
+		// OTP token login
+		case 0x0acf:
+			next = logclif_parse_otp_login( fd, sd );
+			break;
 		// Connection request of a char-server
 		case 0x2710: logclif_parse_reqcharconnec(fd,sd, ip); return 0; // processing will continue elsewhere
 		default:

+ 2 - 0
src/map/battle.cpp

@@ -8954,6 +8954,8 @@ static const struct _battle_data {
 	{ "bgqueue_nowarp_mapflag",             &battle_config.bgqueue_nowarp_mapflag,          0,      0,      1,              },
 	{ "homunculus_exp_gain",                &battle_config.homunculus_exp_gain,             10,     0,      100,            },
 	{ "rental_item_novalue",                &battle_config.rental_item_novalue,             1,      0,      1,              },
+	{ "ping_timer_inverval",                &battle_config.ping_timer_interval,             30,     0,      99999999,       },
+	{ "ping_time",                          &battle_config.ping_time,                       20,     0,      99999999,       },
 
 #include "../custom/battle_config_init.inc"
 };

+ 2 - 0
src/map/battle.hpp

@@ -678,6 +678,8 @@ struct Battle_Config
 	int bgqueue_nowarp_mapflag;
 	int homunculus_exp_gain;
 	int rental_item_novalue;
+	int ping_timer_interval;
+	int ping_time;
 
 #include "../custom/battle_config_struct.inc"
 };

+ 97 - 107
src/map/buyingstore.cpp

@@ -113,8 +113,7 @@ int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){
 * @param at Autotrader info, or NULL if requetsed not from autotrade persistance
 * @return 0 If success, 1 - Cannot open, 2 - Manner penalty, 3 - Mapflag restiction, 4 - Cell restriction, 5 - Invalid count/result, 6 - Cannot give item, 7 - Will be overweight
 */
-int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count, struct s_autotrader *at)
-{
+int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub* itemlist, unsigned int count, struct s_autotrader *at ){
 	unsigned int i, weight, listidx;
 	char message_sql[MESSAGE_SIZE*2];
 	StringBuf buf;
@@ -161,50 +160,53 @@ int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
 	weight = sd->weight;
 
 	// check item list
-	for( i = 0; i < count; i++ )
-	{// itemlist: <name id>.W <amount>.W <price>.L
-		unsigned short nameid, amount;
-		int price, idx;
-		struct item_data* id;
-
-		nameid = RBUFW(itemlist,i*8+0);
-		amount = RBUFW(itemlist,i*8+2);
-		price  = RBUFL(itemlist,i*8+4);
-
-		if( ( id = itemdb_exists(nameid) ) == NULL || amount == 0 )
-		{// invalid input
+	for( i = 0; i < count; i++ ){
+		const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub *item = &itemlist[i];
+
+		struct item_data* id = itemdb_exists( item->itemId );
+
+		// invalid input
+		if( id == NULL || item->amount == 0 ){	
+			break;
+		}
+
+		// invalid price: unlike vending, items cannot be bought at 0 Zeny
+		if( item->price <= 0 || item->price > BUYINGSTORE_MAX_PRICE ){
 			break;
 		}
 
-		if( price <= 0 || price > BUYINGSTORE_MAX_PRICE )
-		{// invalid price: unlike vending, items cannot be bought at 0 Zeny
+		// restrictions: allowed and no character-bound items
+		if( !id->flag.buyingstore || !itemdb_cantrade_sub( id, pc_get_group_level( sd ), pc_get_group_level( sd ) ) ){ 
 			break;
 		}
 
-		if( !id->flag.buyingstore || !itemdb_cantrade_sub(id, pc_get_group_level(sd), pc_get_group_level(sd)) || ( idx = pc_search_inventory(sd, nameid) ) == -1 )
-		{// restrictions: allowed, no character-bound items and at least one must be owned
+		int idx = pc_search_inventory( sd, item->itemId );
+
+		// At least one must be owned
+		if( idx < 0 ){
 			break;
 		}
 
-		if( sd->inventory.u.items_inventory[idx].amount + amount > BUYINGSTORE_MAX_AMOUNT )
-		{// too many items of same kind
+		// too many items of same kind
+		if( sd->inventory.u.items_inventory[idx].amount + item->amount > BUYINGSTORE_MAX_AMOUNT ){
 			break;
 		}
 
-		if( i )
-		{// duplicate check. as the client does this too, only malicious intent should be caught here
-			ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
-			if( listidx != i )
-			{// duplicate
-				ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
+		// duplicate check. as the client does this too, only malicious intent should be caught here
+		if( i ){
+			ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == item->itemId );
+
+			// duplicate
+			if( listidx != i ){
+				ShowWarning( "buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", item->itemId, item->amount, sd->status.account_id, sd->status.char_id );
 				break;
 			}
 		}
 
-		weight+= id->weight*amount;
-		sd->buyingstore.items[i].nameid = nameid;
-		sd->buyingstore.items[i].amount = amount;
-		sd->buyingstore.items[i].price  = price;
+		weight+= id->weight*item->amount;
+		sd->buyingstore.items[i].nameid = item->itemId;
+		sd->buyingstore.items[i].amount = item->amount;
+		sd->buyingstore.items[i].price  = item->price;
 	}
 
 	if( i != count )
@@ -322,10 +324,9 @@ void buyingstore_open(struct map_session_data* sd, uint32 account_id)
 * @param *itemlist List of sold items { <index>.W, <nameid>.W, <amount>.W }*
 * @param count Number of item on the itemlist
 */
-void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count)
-{
+void buyingstore_trade( struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* itemlist, unsigned int count ){
 	int zeny = 0;
-	unsigned int i, weight, listidx, k;
+	unsigned int weight;
 	struct map_session_data* pl_sd;
 
 	nullpo_retv(sd);
@@ -362,98 +363,94 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned
 
 	searchstore_clearremote(sd);
 
-	if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit )
-	{// buyer lost zeny in the mean time? fix the limit
+	// buyer lost zeny in the mean time? fix the limit
+	if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit ){
 		pl_sd->buyingstore.zenylimit = pl_sd->status.zeny;
 	}
 	weight = pl_sd->weight;
 
 	// check item list
-	for( i = 0; i < count; i++ )
-	{// itemlist: <index>.W <name id>.W <amount>.W
-		unsigned short nameid, amount;
-		int index;
-
-		index  = RBUFW(itemlist,i*6+0)-2;
-		nameid = RBUFW(itemlist,i*6+2);
-		amount = RBUFW(itemlist,i*6+4);
-
-		if( i )
-		{// duplicate check. as the client does this too, only malicious intent should be caught here
-			ARR_FIND( 0, i, k, RBUFW(itemlist,k*6+0)-2 == index );
-			if( k != i )
-			{// duplicate
-				ShowWarning("buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n",
-					RBUFW(itemlist,k*6+2), RBUFW(itemlist,k*6+4), nameid, amount, sd->status.account_id, sd->status.char_id);
-				clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+	for( int i = 0; i < count; i++ ){
+		const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* item = &itemlist[i];
+
+		// duplicate check. as the client does this too, only malicious intent should be caught here
+		for( int k = 0; k < i; k++ ){
+			// duplicate
+			if( itemlist[k].index == item->index && k != i ){
+				ShowWarning( "buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", itemlist[k].itemId, itemlist[k].amount, item->itemId, item->amount, sd->status.account_id, sd->status.char_id );
+				clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
 				return;
 			}
 		}
 
-		if( index < 0 || index >= ARRAYLENGTH(sd->inventory.u.items_inventory) || sd->inventory_data[index] == NULL || sd->inventory.u.items_inventory[index].nameid != nameid || sd->inventory.u.items_inventory[index].amount < amount )
-		{// invalid input
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+		int index = item->index - 2; // TODO: clif::server_index
+
+		// invalid input
+		if( index < 0 || index >= ARRAYLENGTH( sd->inventory.u.items_inventory ) || sd->inventory_data[index] == NULL || sd->inventory.u.items_inventory[index].nameid != item->itemId || sd->inventory.u.items_inventory[index].amount < item->amount ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
 			return;
 		}
 
-		if( sd->inventory.u.items_inventory[index].expire_time || (sd->inventory.u.items_inventory[index].bound && !pc_can_give_bounded_items(sd)) || !itemdb_cantrade(&sd->inventory.u.items_inventory[index], pc_get_group_level(sd), pc_get_group_level(pl_sd)) || memcmp(sd->inventory.u.items_inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots)) )
-		{// non-tradable item
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+		// non-tradable item
+		if( sd->inventory.u.items_inventory[index].expire_time || ( sd->inventory.u.items_inventory[index].bound && !pc_can_give_bounded_items( sd ) ) || !itemdb_cantrade( &sd->inventory.u.items_inventory[index], pc_get_group_level( sd ), pc_get_group_level( pl_sd ) ) || memcmp( sd->inventory.u.items_inventory[index].card, buyingstore_blankslots, sizeof( buyingstore_blankslots ) ) ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
 			return;
 		}
 
-		ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
-		if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 )
-		{// there is no such item or the buyer has already bought all of them
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+		int listidx;
+
+		ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == item->itemId );
+
+		// there is no such item or the buyer has already bought all of them
+		if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
 			return;
 		}
 
-		if( pl_sd->buyingstore.items[listidx].amount < amount )
-		{// buyer does not need that much of the item
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_COUNT, nameid);
+		// buyer does not need that much of the item
+		if( pl_sd->buyingstore.items[listidx].amount < item->amount ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_COUNT, item->itemId );
 			return;
 		}
 
-		if( pc_checkadditem(pl_sd, nameid, amount) == CHKADDITEM_OVERAMOUNT )
-		{// buyer does not have enough space for this item
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+		// buyer does not have enough space for this item
+		if( pc_checkadditem( pl_sd, item->itemId, item->amount ) == CHKADDITEM_OVERAMOUNT ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
 			return;
 		}
 
-		if( amount*(unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight-weight )
-		{// normally this is not supposed to happen, as the total weight is
-		 // checked upon creation, but the buyer could have gained items
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
+		// normally this is not supposed to happen, as the total weight is
+		// checked upon creation, but the buyer could have gained items
+		if( item->amount * (unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight - weight ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
 			return;
 		}
-		weight+= amount*sd->inventory_data[index]->weight;
 
-		if( amount*pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit-zeny )
-		{// buyer does not have enough zeny
-			clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_ZENY, nameid);
+		weight += item->amount * sd->inventory_data[index]->weight;
+
+		// buyer does not have enough zeny
+		if( item->amount * pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit - zeny ){
+			clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_ZENY, item->itemId );
 			return;
 		}
-		zeny+= amount*pl_sd->buyingstore.items[listidx].price;
+
+		zeny += item->amount * pl_sd->buyingstore.items[listidx].price;
 	}
 
 	// process item list
-	for( i = 0; i < count; i++ )
-	{// itemlist: <index>.W <name id>.W <amount>.W
-		unsigned short nameid, amount;
-		int index;
+	for( int i = 0; i < count; i++ ){
+		const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* item = &itemlist[i];
+		int listidx;
 
-		index  = RBUFW(itemlist,i*6+0)-2;
-		nameid = RBUFW(itemlist,i*6+2);
-		amount = RBUFW(itemlist,i*6+4);
+		ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == item->itemId );
+		zeny = item->amount * pl_sd->buyingstore.items[listidx].price;
 
-		ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
-		zeny = amount*pl_sd->buyingstore.items[listidx].price;
+		int index = item->index - 2; // TODO: clif::server_index
 
 		// move item
-		pc_additem(pl_sd, &sd->inventory.u.items_inventory[index], amount, LOG_TYPE_BUYING_STORE);
-		pc_delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE);
-		pl_sd->buyingstore.items[listidx].amount-= amount;
+		pc_additem(pl_sd, &sd->inventory.u.items_inventory[index], item->amount, LOG_TYPE_BUYING_STORE);
+		pc_delitem(sd, index, item->amount, 1, 0, LOG_TYPE_BUYING_STORE);
+		pl_sd->buyingstore.items[listidx].amount -= item->amount;
 
 		if( pl_sd->buyingstore.items[listidx].amount > 0 ){
 			if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `amount` = %d WHERE `buyingstore_id` = %d AND `index` = %d;", buyingstore_items_table, pl_sd->buyingstore.items[listidx].amount, pl_sd->buyer_id, listidx ) != SQL_SUCCESS ){
@@ -471,8 +468,8 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned
 		pl_sd->buyingstore.zenylimit-= zeny;
 
 		// notify clients
-		clif_buyingstore_delete_item(sd, index, amount, pl_sd->buyingstore.items[listidx].price);
-		clif_buyingstore_update_item(pl_sd, nameid, amount, sd->status.char_id, zeny);
+		clif_buyingstore_delete_item(sd, index, item->amount, pl_sd->buyingstore.items[listidx].price);
+		clif_buyingstore_update_item(pl_sd, item->itemId, item->amount, sd->status.char_id, zeny);
 	}
 
 	if( save_settings&CHARSAVE_VENDING ) {
@@ -481,6 +478,7 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned
 	}
 	
 	// check whether or not there is still something to buy
+	int i;
 	ARR_FIND( 0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0 );
 	if( i == pl_sd->buyingstore.slots )
 	{// everything was bought
@@ -548,7 +546,7 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st
 
 	for( idx = 0; idx < s->item_count; idx++ )
 	{
-		ARR_FIND( 0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == s->itemlist[idx] && sd->buyingstore.items[i].amount );
+		ARR_FIND( 0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == s->itemlist[idx].itemId && sd->buyingstore.items[i].amount );
 		if( i == sd->buyingstore.slots )
 		{// not found
 			continue;
@@ -591,23 +589,15 @@ void buyingstore_reopen( struct map_session_data* sd ){
 
 	// Ready to open buyingstore for this char
 	if ((at = (struct s_autotrader *)uidb_get(buyingstore_autotrader_db, sd->status.char_id)) && at->count && at->entries) {
-		uint8 *data, *p;
-		uint16 j, count;
+		struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub* data;
 
 		// Init buyingstore data for autotrader
-		CREATE(data, uint8, at->count * 8);
-
-		for (j = 0, p = data, count = at->count; j < at->count; j++) {
-			struct s_autotrade_entry *entry = at->entries[j];
-			unsigned short *item_id = (uint16*)(p + 0);
-			uint16 *amount = (uint16*)(p + 2);
-			uint32 *price = (uint32*)(p + 4);
-
-			*item_id = entry->item_id;
-			*amount = entry->amount;
-			*price = entry->price;
+		CREATE(data, struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub, at->count );
 
-			p += 8;
+		for( int j = 0; j < at->count; j++) {
+			data[j].itemId = at->entries[j]->item_id;
+			data[j].amount = at->entries[j]->amount;
+			data[j].price = at->entries[j]->price;
 		}
 
 		sd->state.autotrade = 1;
@@ -633,7 +623,7 @@ void buyingstore_reopen( struct map_session_data* sd ){
 			chrif_save(sd, CSAVE_AUTOTRADE);
 
 			ShowInfo("Buyingstore loaded for '" CL_WHITE "%s" CL_RESET "' with '" CL_WHITE "%d" CL_RESET "' items at " CL_WHITE "%s (%d,%d)" CL_RESET "\n",
-				sd->status.name, count, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y);
+				sd->status.name, at->count, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y);
 		}
 		aFree(data);
 	}

+ 2 - 2
src/map/buyingstore.hpp

@@ -56,10 +56,10 @@ struct s_autotrader {
 };
 
 int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots);
-int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count, struct s_autotrader *at);
+int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub* itemlist, unsigned int count, struct s_autotrader *at);
 void buyingstore_close(struct map_session_data* sd);
 void buyingstore_open(struct map_session_data* sd, uint32 account_id);
-void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count);
+void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* itemlist, unsigned int count);
 bool buyingstore_search(struct map_session_data* sd, unsigned short nameid);
 bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_store_search* s);
 DBMap *buyingstore_getdb(void);

+ 12 - 11
src/map/cashshop.cpp

@@ -467,7 +467,7 @@ static void cashshop_read_db( void ){
  * @param item_list Array of item ID
  * @return true: success, false: fail
  */
-bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list ){
+bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub* item_list ){
 	uint32 totalcash = 0;
 	uint32 totalweight = 0;
 	int i,new_;
@@ -487,9 +487,9 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
 	new_ = 0;
 
 	for( i = 0; i < n; ++i ){
-		unsigned short nameid = *( item_list + i * 5 );
-		uint32 quantity = *( item_list + i * 5 + 2 );
-		uint8 tab = (uint8)*( item_list + i * 5 + 4 );
+		unsigned short nameid = item_list[i].itemId;
+		uint32 quantity = item_list[i].amount;
+		uint16 tab = item_list[i].tab;
 		int j;
 
 		if( tab >= CASHSHOP_TAB_MAX ){
@@ -504,7 +504,7 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
 			return false;
 		}
 
-		nameid = *( item_list + i * 5 ) = cash_shop_items[tab].item[j]->nameid; //item_avail replacement
+		nameid = item_list[i].itemId = cash_shop_items[tab].item[j]->nameid; //item_avail replacement
 		id = itemdb_exists(nameid);
 
 		if( !id ){
@@ -569,10 +569,10 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
 	}
 
 	for( i = 0; i < n; ++i ){
-		unsigned short nameid = *( item_list + i * 5 );
-		uint32 quantity = *( item_list + i * 5 + 2 );
+		unsigned short nameid = item_list[i].itemId;
+		uint32 quantity = item_list[i].amount;
 #if PACKETVER_SUPPORTS_SALES
-		uint16 tab = *(item_list + i * 5 + 4);
+		uint16 tab = item_list[i].tab;
 #endif
 		struct item_data *id = itemdb_search(nameid);
 
@@ -580,12 +580,12 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
 			continue;
 
 		if (!pet_create_egg(sd, nameid)) {
-			unsigned short get_amt = quantity, j;
+			unsigned short get_amt = quantity;
 
 			if (id->flag.guid || !itemdb_isstackable2(id))
 				get_amt = 1;
 
-			for (j = 0; j < quantity; j += get_amt) {
+			for (uint32 j = 0; j < quantity; j += get_amt) {
 				struct item item_tmp = { 0 };
 
 				item_tmp.nameid = nameid;
@@ -606,6 +606,8 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
 						return false;
 				}
 
+				clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_SUCCESS );
+
 #if PACKETVER_SUPPORTS_SALES
 				if( tab == CASHSHOP_TAB_SALE ){
 					uint32 new_amount = sale->amount - get_amt;
@@ -627,7 +629,6 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
 		}
 	}
 
-	clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS ); //Doesn't show any message?
 	return true;
 }
 

+ 1 - 1
src/map/cashshop.hpp

@@ -13,7 +13,7 @@ struct map_session_data;
 void do_init_cashshop( void );
 void do_final_cashshop( void );
 void cashshop_reloaddb( void );
-bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list );
+bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub* item_list );
 
 // Taken from AEGIS
 enum CASH_SHOP_TAB_CODE

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 466 - 390
src/map/clif.cpp


+ 20 - 15
src/map/clif.hpp

@@ -13,6 +13,7 @@
 #include "../common/mmo.hpp"
 #include "../common/timer.hpp" // t_tick
 
+#include "packets.hpp"
 #include "script.hpp"
 
 struct Channel;
@@ -47,8 +48,10 @@ enum e_instance_notify : uint8;
 
 enum e_PacketDBVersion { // packet DB
 	MIN_PACKET_DB  = 0x064,
-	MAX_PACKET_DB  = 0xAFF,
+	MAX_PACKET_DB  = 0xBFF,
+#if !defined(MAX_PACKET_POS)
 	MAX_PACKET_POS = 20,
+#endif
 };
 
 enum e_packet_ack : uint8_t{
@@ -659,7 +662,7 @@ void clif_soundeffect(struct map_session_data* sd, struct block_list* bl, const
 void clif_soundeffectall(struct block_list* bl, const char* name, int type, enum send_target coverage);
 void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, t_tick tick);
 void clif_parse_LoadEndAck(int fd,struct map_session_data *sd);
-void clif_hotkeys_send(struct map_session_data *sd);
+void clif_hotkeys_send(struct map_session_data *sd, int tab);
 
 // trade
 void clif_traderequest(struct map_session_data* sd, const char* name);
@@ -693,7 +696,7 @@ void clif_deleteskill(struct map_session_data *sd, int skill_id);
 
 void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime);
 void clif_skillcastcancel(struct block_list* bl);
-void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype);
+void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype, int itemId = 0);
 void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, t_tick tick);
 int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int64 sdamage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type);
 //int clif_skill_damage2(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type);
@@ -739,7 +742,7 @@ void clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int
 void clif_inventorylist(struct map_session_data *sd);
 void clif_equiplist(struct map_session_data *sd);
 
-void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail);
+void clif_cart_additem(struct map_session_data *sd,int n,int amount);
 void clif_cart_additem_ack(struct map_session_data *sd, uint8 flag);
 void clif_cart_delitem(struct map_session_data *sd,int n,int amount);
 void clif_cartlist(struct map_session_data *sd);
@@ -766,7 +769,7 @@ void clif_changed_dir(struct block_list *bl, enum send_target target);
 void clif_openvendingreq(struct map_session_data* sd, int num);
 void clif_showvendingboard(struct block_list* bl, const char* message, int fd);
 void clif_closevendingboard(struct block_list* bl, int fd);
-void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* vending);
+void clif_vendinglist( struct map_session_data* sd, struct map_session_data* vsd );
 void clif_buyvending(struct map_session_data* sd, int index, int amount, int fail);
 void clif_openvending(struct map_session_data* sd, int id, struct s_vending* vending);
 void clif_vendingreport(struct map_session_data* sd, int index, int amount, uint32 char_id, int zeny);
@@ -855,7 +858,7 @@ void clif_map_property(struct block_list *bl, enum map_property property, enum s
 void clif_pvpset(struct map_session_data *sd, int pvprank, int pvpnum,int type);
 void clif_map_property_mapall(int map, enum map_property property);
 void clif_refine(int fd, int fail, int index, int val);
-void clif_upgrademessage(int fd, int result, unsigned short item_id);
+void clif_upgrademessage( struct map_session_data* sd, int result, unsigned short item_id );
 
 //petsystem
 void clif_catch_process(struct map_session_data *sd);
@@ -904,7 +907,7 @@ void clif_feel_hate_reset(struct map_session_data *sd);
 void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag);
 int clif_homskillinfoblock(struct map_session_data *sd);
 void clif_homskillup(struct map_session_data *sd, uint16 skill_id);	//[orn]
-int clif_hom_food(struct map_session_data *sd,int foodid,int fail);	//[orn]
+void clif_hom_food(struct map_session_data *sd,int foodid,int fail);	//[orn]
 void clif_send_homdata(struct map_session_data *sd, int state, int param);	//[orn]
 
 void clif_configuration( struct map_session_data* sd, enum e_config_type type, bool enabled );
@@ -926,7 +929,7 @@ void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd
 void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, e_questinfo_types effect, e_questinfo_markcolor color);
 void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest, bool lost);
 
-int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type);
+int clif_send(const void* buf, int len, struct block_list* bl, enum send_target type);
 void do_init_clif(void);
 void do_final_clif(void);
 
@@ -971,8 +974,8 @@ void clif_mercenary_message(struct map_session_data* sd, int message);
 void clif_mercenary_updatestatus(struct map_session_data *sd, int type);
 
 // RENTAL SYSTEM
-void clif_rental_time(int fd, unsigned short nameid, int seconds);
-void clif_rental_expired(int fd, int index, unsigned short nameid);
+void clif_rental_time( struct map_session_data* sd, unsigned short nameid, int seconds );
+void clif_rental_expired( struct map_session_data* sd, int index, unsigned short nameid );
 
 // BOOK READING
 void clif_readbook(int fd, int book_id, int page);
@@ -1026,7 +1029,7 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
 
 /// Cash Shop
 void clif_cashshop_result( struct map_session_data* sd, unsigned short item_id, uint16 result );
-void clif_cashshop_open( struct map_session_data* sd );
+void clif_cashshop_open( struct map_session_data* sd, int tab );
 
 void clif_display_pinfo(struct map_session_data *sd, int type);
 
@@ -1038,15 +1041,15 @@ void clif_parse_roulette_close(int fd, struct map_session_data *sd);
 void clif_parse_roulette_generate(int fd, struct map_session_data *sd);
 void clif_parse_roulette_item(int fd, struct map_session_data *sd);
 
-int clif_elementalconverter_list(struct map_session_data *sd);
+void clif_elementalconverter_list(struct map_session_data *sd);
 
 void clif_millenniumshield(struct block_list *bl, short shields);
 
-int clif_spellbook_list(struct map_session_data *sd);
+void clif_spellbook_list(struct map_session_data *sd);
 
-int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, short y);
+void clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, short y);
 
-int clif_poison_list(struct map_session_data *sd, uint16 skill_lv);
+void clif_poison_list(struct map_session_data *sd, uint16 skill_lv);
 
 int clif_autoshadowspell_list(struct map_session_data *sd);
 
@@ -1140,4 +1143,6 @@ void clif_equipswitch_reply( struct map_session_data* sd, bool failed );
 /// Pet evolution
 void clif_pet_evolution_result( struct map_session_data* sd, e_pet_evolution_result result );
 
+void clif_parse_skill_toid( struct map_session_data* sd, uint16 skill_id, uint16 skill_lv, int target_id );
+
 #endif /* CLIF_HPP */

+ 59 - 17
src/map/clif_packetdb.hpp

@@ -311,7 +311,7 @@
 	parseable_packet(0x018e,10,clif_parse_ProduceMix,2,4,6,8);
 	packet(0x018f,6);
 	parseable_packet(0x0190,90,clif_parse_UseSkillToPosMoreInfo,2,4,6,8,10);
-	packet(0x0191,86);
+	packet( HEADER_ZC_TALKBOX_CHATCONTENTS, sizeof( struct PACKET_ZC_TALKBOX_CHATCONTENTS ) );
 	packet(0x0192,24);
 	parseable_packet(0x0193,6,clif_parse_SolveCharName,2);
 	packet(0x0194,30);
@@ -419,7 +419,7 @@
 	packet(0x01fa,48);
 	packet(0x01fb,56);
 	packet(0x01fc,-1);
-	parseable_packet(0x01fd,4,clif_parse_RepairItem,2);
+	parseable_packet(0x01fd,4,clif_parse_RepairItem,0);
 	packet(0x01fe,5);
 	packet(0x01ff,10);
 	packet(0x0200,26);
@@ -1074,12 +1074,12 @@
 
 // 2007-05-07aSakexe
 #if PACKETVER >= 20070507
-	parseable_packet(0x01fd,15,clif_parse_RepairItem,2,4,6,7,9,11,13);
+	parseable_packet(0x01fd,15,clif_parse_RepairItem,0);
 #endif
 
 // 2007-02-27aSakexe to 2007-10-02aSakexe
 #if PACKETVER >= 20070227
-	parseable_packet(0x0288,10,clif_parse_cashshop_buy,2,4,6);
+	parseable_packet(0x0288,10,clif_parse_npccashshop_buy,2,4,6);
 	packet(0x0289,12);
 	packet(0x02a6,22);
 	packet(0x02a7,22);
@@ -1505,7 +1505,7 @@
 	//packet(0x07d4,4);
 	//packet(0x07d5,4);
 	//packet(0x07d6,4);
-	//packet(0x0447,2);
+	parseable_packet( 0x0447, 2, clif_parse_blocking_playcancel, 0 );
 #endif
 
 // 2009-06-03aRagexeRE
@@ -1815,7 +1815,7 @@
 
 // 2010-11-24aRagexeRE
 #if PACKETVER >= 20101124
-	parseable_packet(0x0288,-1,clif_parse_cashshop_buy,2,4,8,10);
+	parseable_packet(0x0288,-1,clif_parse_npccashshop_buy,2,4,8,10);
 	parseable_packet(0x0436,19,clif_parse_WantToConnection,2,6,10,14,18);
 	parseable_packet(0x035f,5,clif_parse_WalkToXY,2);
 	parseable_packet(0x0360,6,clif_parse_TickSend,2);
@@ -1915,11 +1915,11 @@
 
 // 2012-04-10aRagexeRE
 #if PACKETVER >= 20120410
-	parseable_packet(0x01fd,15,clif_parse_RepairItem,2,4,6,7,9,11,13);
+	parseable_packet(0x01fd,15,clif_parse_RepairItem,0);
 	parseable_packet(0x089c,26,clif_parse_FriendsListAdd,2);
 	parseable_packet(0x0885,5,clif_parse_HomMenu,2,4);
 	parseable_packet(0x0961,36,clif_parse_StoragePassword,2,4,20);
-	parseable_packet(0x0288,-1,clif_parse_cashshop_buy,2,4,8,10);
+	parseable_packet(0x0288,-1,clif_parse_npccashshop_buy,2,4,8,10);
 	parseable_packet(0x091c,26,clif_parse_PartyInvite2,2);
 	parseable_packet(0x094b,19,clif_parse_WantToConnection,2,6,10,14,18);
 	parseable_packet(0x0369,7,clif_parse_ActionRequest,2,6);
@@ -2049,7 +2049,7 @@
 // 2013-03-20Ragexe (Judas)
 #if PACKETVER >= 20130320
 	parseable_packet(0x014f,6,clif_parse_GuildRequestInfo,2);
-	parseable_packet(0x01fd,15,clif_parse_RepairItem,2,4,6,7,9,11,13);
+	parseable_packet(0x01fd,15,clif_parse_RepairItem,0);
 	//parseable_packet(0x0281,-1,clif_parse_ItemListWindowSelected,2,4,8,12);
 	parseable_packet(0x035f,6,clif_parse_ReqClickBuyingStore,2);
 	parseable_packet(0x0363,6,clif_parse_TickSend,2);
@@ -2180,18 +2180,18 @@
 	parseable_packet(0x098D,-1,clif_parse_clan_chat,2,4);
 	packet(0x098E,-1);
 	// Sale
-	parseable_packet(0x09AC,-1,clif_parse_sale_search,2,4,8);
-	packet(0x09AD,8);
-	parseable_packet(0x09AE,17,clif_parse_sale_add,2,6,8,12,16);
+	parseable_packet( HEADER_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO, -1, clif_parse_sale_search, 0 );
+	packet( HEADER_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO, sizeof( PACKET_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO ) );
+	parseable_packet( HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM, sizeof( PACKET_CZ_REQ_APPLY_BARGAIN_SALE_ITEM ), clif_parse_sale_add, 0 );
 	packet(0x09AF,4);
-	parseable_packet(0x09B0,8,clif_parse_sale_remove,2,6);
+	parseable_packet( HEADER_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM, sizeof( PACKET_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM ), clif_parse_sale_remove, 0 );
 	packet(0x09B1,4);
-	packet(0x09B2,8);
-	packet(0x09B3,4);
+	packet( HEADER_ZC_NOTIFY_BARGAIN_SALE_SELLING, sizeof( PACKET_ZC_NOTIFY_BARGAIN_SALE_SELLING ) );
+	packet( HEADER_ZC_NOTIFY_BARGAIN_SALE_CLOSE, sizeof( PACKET_ZC_NOTIFY_BARGAIN_SALE_CLOSE ) );
 	parseable_packet(0x09B4,6,clif_parse_sale_open,2);
 	parseable_packet(0x09BC,6,clif_parse_sale_close,2);
 	parseable_packet(0x09C3,8,clif_parse_sale_refresh,2,6);
-	packet(0x09C4,8);
+	packet( HEADER_ZC_ACK_COUNT_BARGAIN_SALE_ITEM, sizeof( PACKET_ZC_ACK_COUNT_BARGAIN_SALE_ITEM ) );
 	// New Packet
 	packet(0x097A,-1); // ZC_ALL_QUEST_LIST2
 	packet(0x09DB,-1); // ZC_NOTIFY_MOVEENTRY10
@@ -2312,7 +2312,7 @@
 
 // 2015-05-20aRagexe
 #if PACKETVER >= 20150520
-	parseable_packet(0x0A3D,18,clif_parse_sale_add,2,6,8,12,16);
+	parseable_packet( HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM2, sizeof( PACKET_CZ_REQ_APPLY_BARGAIN_SALE_ITEM ), clif_parse_sale_add, 0 );
 #endif
 
 // 2015-09-16Ragexe
@@ -2439,4 +2439,46 @@
 	packet(0x0ADD, 22);
 #endif
 
+#if PACKETVER >= 20180704
+	parseable_packet( 0x018e, sizeof( struct PACKET_CZ_REQMAKINGITEM ), clif_parse_ProduceMix, 0 );
+	parseable_packet( 0x01ae, 6, clif_parse_SelectArrow, 0 );
+	parseable_packet( 0x01fd, sizeof( struct PACKET_CZ_REQ_ITEMREPAIR ), clif_parse_RepairItem, 0 );
+	parseable_packet( 0x025b, sizeof( struct PACKET_CZ_REQ_MAKINGITEM ), clif_parse_Cooking, 0 );
+	// this is done in clif_shuffle
+	//parseable_packet( 0x083C, sizeof( struct PACKET_CZ_SSILIST_ITEM_CLICK ), clif_parse_SearchStoreInfoListItemClick, 0 );
+	parseable_packet( 0x0A49, sizeof( struct PACKET_CZ_PRIVATE_AIRSHIP_REQUEST ), clif_parse_private_airship_request, 0 );
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 || PACKETVER_ZERO_NUM >= 20181010
+	parseable_packet( 0x0B10, sizeof( struct PACKET_CZ_START_USE_SKILL ), clif_parse_StartUseSkillToId, 0 );
+	parseable_packet( 0x0B11, sizeof( struct PACKET_CZ_STOP_USE_SKILL ), clif_parse_StopUseSkillToId, 0 );
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
+	parseable_packet( 0x0B14, sizeof( struct PACKET_CZ_INVENTORY_EXPAND ), clif_parse_dull, 0 );
+	parseable_packet( 0x0B16, sizeof( struct PACKET_CZ_INVENTORY_EXPAND_CONFIRMED ), clif_parse_dull, 0 );
+	parseable_packet( 0x0B19, sizeof( struct PACKET_CZ_INVENTORY_EXPAND_REJECTED ), clif_parse_dull, 0 );
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190227 || PACKETVER_RE_NUM >= 20190220 || PACKETVER_ZERO_NUM >= 20190220
+	parseable_packet( 0x0B1C, sizeof( struct PACKET_CZ_PING ), clif_parse_dull, 0 );
+#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 );
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190703 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190709
+	parseable_packet( HEADER_CZ_REQ_MOUNTOFF, sizeof( PACKET_CZ_REQ_MOUNTOFF ), clif_parse_RemoveOption, 0 );
+#endif
+
+#if PACKETVER >= 20190724
+	parseable_packet( 0x0b4c, 2, clif_parse_dull, 0 );
+#endif
+
+#if PACKETVER >= 20191224
+	parseable_packet( HEADER_CZ_SE_CASHSHOP_OPEN2, sizeof( struct PACKET_CZ_SE_CASHSHOP_OPEN2 ), clif_parse_cashshop_open_request, 0 );
+#endif
+
 #endif /* CLIF_PACKETDB_HPP */

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 112 - 112
src/map/clif_shuffle.hpp


+ 4 - 2
src/map/map-server.vcxproj

@@ -95,7 +95,8 @@
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4018</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4018;4200</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -192,6 +193,8 @@
     <ClInclude Include="mercenary.hpp" />
     <ClInclude Include="mob.hpp" />
     <ClInclude Include="npc.hpp" />
+    <ClInclude Include="packets.hpp" />
+    <ClInclude Include="packets_struct.hpp" />
     <ClInclude Include="party.hpp" />
     <ClInclude Include="path.hpp" />
     <ClInclude Include="pc.hpp" />
@@ -369,4 +372,3 @@
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\status_disabled.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\status_disabled.txt')" />
   </Target>
 </Project>
-

+ 6 - 0
src/map/map-server.vcxproj.filters

@@ -98,6 +98,12 @@
     <ClInclude Include="npc.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="packets.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="packets_struct.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="party.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>

+ 6 - 0
src/map/map.hpp

@@ -223,6 +223,12 @@ enum e_mapid {
 
 //Max size for inputs to Graffiti, Talkie Box and Vending text prompts
 #define MESSAGE_SIZE (79 + 1)
+// Max size for inputs to Graffiti, Talkie Box text prompts
+#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
+#define TALKBOX_MESSAGE_SIZE 21
+#else
+#define TALKBOX_MESSAGE_SIZE (79 + 1)
+#endif
 //String length you can write in the 'talking box'
 #define CHATBOX_SIZE (70 + 1)
 //Chatroom-related string sizes

+ 8 - 8
src/map/npc.cpp

@@ -1682,7 +1682,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
  * @param item_list: List of items to purchase
  * @return clif_cashshop_ack value to display
  */
-int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list)
+int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub* item_list)
 {
 	int i, j, amount, new_, w, vt;
 	unsigned short nameid;
@@ -1702,8 +1702,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
 	// Validating Process ----------------------------------------------------
 	for( i = 0; i < count; i++ )
 	{
-		nameid = item_list[i*2+1];
-		amount = item_list[i*2+0];
+		nameid = item_list[i].itemId;
+		amount = item_list[i].amount;
 		id = itemdb_exists(nameid);
 
 		if( !id || amount <= 0 )
@@ -1713,12 +1713,12 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
 		if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 )
 			return ERROR_TYPE_ITEM_ID;
 
-		nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
+		nameid = item_list[i].itemId = nd->u.shop.shop_item[j].nameid; //item_avail replacement
 
 		if( !itemdb_isstackable2(id) && amount > 1 )
 		{
 			ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %hu!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
-			amount = item_list[i*2+0] = 1;
+			amount = item_list[i].amount = 1;
 		}
 
 		switch( pc_checkadditem(sd,nameid,amount) )
@@ -1745,8 +1745,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
 
 	// Delivery Process ----------------------------------------------------
 	for( i = 0; i < count; i++ ) {
-		nameid = item_list[i*2+1];
-		amount = item_list[i*2+0];
+		nameid = item_list[i].itemId;
+		amount = item_list[i].amount;
 
 		if( !pet_create_egg(sd,nameid) ) {
 			struct item item_tmp;
@@ -3040,7 +3040,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 		nd->u.shop.shop_item[nd->u.shop.count].value = value;
 #if PACKETVER >= 20131223
 		nd->u.shop.shop_item[nd->u.shop.count].flag = 0;
-		if (type == NPCTYPE_MARKETSHOP)
+		if (type == NPCTYPE_MARKETSHOP )
 			nd->u.shop.shop_item[nd->u.shop.count].qty = qty;
 #endif
 		nd->u.shop.count++;

+ 15 - 3
src/map/npc.hpp

@@ -33,11 +33,23 @@ struct npc_item_list {
 #endif
 };
 
+#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#pragma pack(push, 1)
+#endif // not NetBSD < 6 / Solaris
+
 /// List of bought/sold item for NPC shops
 struct s_npc_buy_list {
 	unsigned short qty;		///< Amount of item will be bought
-	unsigned short nameid;	///< ID of item will be bought
-};
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 nameid;	///< ID of item will be bought
+#else
+	uint16 nameid;	///< ID of item will be bought
+#endif
+} __attribute__((packed));
+
+#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#pragma pack(pop)
+#endif // not NetBSD < 6 / Solaris
 
 struct npc_data {
 	struct block_list bl;
@@ -1266,7 +1278,7 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in
 
 extern struct npc_data* fake_nd;
 
-int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
+int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub* item_list);
 bool npc_shop_discount(struct npc_data* nd);
 
 #if PACKETVER >= 20131223

+ 178 - 0
src/map/packets.hpp

@@ -0,0 +1,178 @@
+// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef PACKETS_HPP
+#define PACKETS_HPP
+
+#pragma warning( push )
+#pragma warning( disable : 4200 )
+
+// Required for MESSAGE_SIZE, TALKBOX_MESSAGE_SIZE
+#include "map.hpp"
+
+#define MAX_ITEM_OPTIONS MAX_ITEM_RDM_OPT
+#define UNAVAILABLE_STRUCT int8 _____unavailable
+/* packet size constant for itemlist */
+#if MAX_INVENTORY > MAX_STORAGE && MAX_INVENTORY > MAX_CART
+	#define MAX_ITEMLIST MAX_INVENTORY
+#elif MAX_CART > MAX_INVENTORY && MAX_CART > MAX_STORAGE
+	#define MAX_ITEMLIST MAX_CART
+#else
+	#define MAX_ITEMLIST MAX_STORAGE
+#endif
+#define MAX_ACHIEVEMENT_DB MAX_ACHIEVEMENT_OBJECTIVES
+
+#define DEFINE_PACKET_HEADER(name, id) const uint16 HEADER_##name = id;
+
+#include "packets_struct.hpp"
+
+#undef MAX_ITEM_OPTIONS
+#undef UNAVAILABLE_STRUCT
+#undef MAX_ITEMLIST
+#undef MAX_ACHIEVEMENT_DB
+#undef MAX_PACKET_POS
+
+#undef DEFINE_PACKET_HEADER
+
+// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
+	#pragma pack( push, 1 )
+#endif
+
+struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub{
+	uint32 itemId;
+	uint32 amount;
+	uint16 tab;
+} __attribute__((packed));
+
+struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST{
+	int16 packetType;
+	int16 packetLength;
+	uint16 count;
+	uint32 kafraPoints;
+	struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO{
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+};
+
+struct PACKET_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO{
+	int16 packetType;
+	uint16 result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 price;
+};
+
+struct PACKET_CZ_REQ_APPLY_BARGAIN_SALE_ITEM{
+	int16 packetType;
+	uint32 AID;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 amount;
+	uint32 startTime;
+#if PACKETVER >= 20150520
+	uint16 hours;
+#else
+	uint8 hours;
+#endif
+};
+
+struct PACKET_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM{
+	int16 packetType;
+	uint32 AID;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+};
+
+struct PACKET_ZC_NOTIFY_BARGAIN_SALE_SELLING{
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 remainingTime;
+};
+
+struct PACKET_ZC_NOTIFY_BARGAIN_SALE_CLOSE{
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+};
+
+struct PACKET_ZC_ACK_COUNT_BARGAIN_SALE_ITEM{
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 amount;
+};
+
+struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub{
+	uint32 id;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	int32 amount;
+	uint8 action;
+	int32 refine;
+	int64 uniqueId;
+	uint8 IsIdentified;
+	uint16 itemType;
+	struct EQUIPSLOTINFO slot;
+	char name[NAME_LENGTH];
+	char time[NAME_LENGTH];
+	uint8 attribute;
+};
+
+struct PACKET_ZC_ACK_GUILDSTORAGE_LOG{
+	int16 packetType;
+	int16 PacketLength;
+	uint16 result;
+	uint16 amount;
+	struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub items[];
+};
+
+// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
+	#pragma pack( pop )
+#endif
+
+const uint16 HEADER_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO = 0x9ac;
+const uint16 HEADER_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO = 0x9ad;
+const uint16 HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM = 0x9ae;
+const uint16 HEADER_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM = 0x9b0;
+const uint16 HEADER_ZC_NOTIFY_BARGAIN_SALE_SELLING = 0x9b2;
+const uint16 HEADER_ZC_NOTIFY_BARGAIN_SALE_CLOSE = 0x9b3;
+const uint16 HEADER_ZC_ACK_COUNT_BARGAIN_SALE_ITEM = 0x9c4;
+const uint16 HEADER_PACKET_ZC_ACK_GUILDSTORAGE_LOG = 0x9da;
+const uint16 HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM2 = 0xa3d;
+
+#pragma warning( pop )
+
+#endif /* PACKETS_HPP */

+ 3877 - 0
src/map/packets_struct.hpp

@@ -0,0 +1,3877 @@
+// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
+// Copyright (c) Hercules Dev Team - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef MAP_PACKETS_STRUCT_HPP
+#define MAP_PACKETS_STRUCT_HPP
+
+#include "../common/cbasetypes.hpp"
+#include "../common/mmo.hpp"
+
+/**
+ *
+ **/
+enum packet_headers {
+	banking_withdraw_ackType = 0x9aa,
+	banking_deposit_ackType = 0x9a8,
+	banking_checkType = 0x9a6,
+	cart_additem_ackType = 0x12c,
+	sc_notickType = 0x196,
+#if PACKETVER >= 20150226
+	cartaddType = 0xa0b,
+#elif PACKETVER >= 5
+	cartaddType = 0x1c5,
+#else
+	cartaddType = 0x124,
+#endif
+#if PACKETVER >= 20150226
+	storageaddType = 0xa0a,
+#elif PACKETVER >= 5
+	storageaddType = 0x1c4,
+#else
+	storageaddType = 0xf4,
+#endif
+#if PACKETVER >= 20150226
+	tradeaddType = 0xa09,
+#elif PACKETVER >= 20100223
+	tradeaddType = 0x80f,
+#else
+	tradeaddType = 0x0e9,
+#endif
+#if PACKETVER < 20061218
+	additemType = 0x0a0,
+#elif PACKETVER < 20071002
+	additemType = 0x29a,
+#elif PACKETVER < 20120925
+	additemType = 0x2d4,
+#elif PACKETVER < 20150226
+	additemType = 0x990,
+#elif PACKETVER < 20160921
+	additemType = 0xa0c,
+#else
+	additemType = 0xa37,
+#endif
+#if PACKETVER < 4
+	idle_unitType = 0x78,
+#elif PACKETVER < 7
+	idle_unitType = 0x1d8,
+#elif PACKETVER < 20080102
+	idle_unitType = 0x22a,
+#elif PACKETVER < 20091103
+	idle_unitType = 0x2ee,
+#elif PACKETVER < 20101124
+	idle_unitType = 0x7f9,
+#elif PACKETVER < 20120221
+	idle_unitType = 0x857,
+#elif PACKETVER < 20131223
+	idle_unitType = 0x915,
+#elif PACKETVER < 20150513
+	idle_unitType = 0x9dd,
+#else
+	idle_unitType = 0x9ff,
+#endif
+#if PACKETVER >= 20120618
+	status_changeType = 0x983,
+#elif PACKETVER >= 20090121
+	status_changeType = 0x43f,
+#else
+	status_changeType = sc_notickType,/* 0x196 */
+#endif
+	status_change2Type = 0x43f,
+	status_change_endType = 0x196,
+#if PACKETVER < 20091103
+	spawn_unit2Type = 0x7c,
+	idle_unit2Type = 0x78,
+#endif
+#if PACKETVER < 20071113
+	damageType = 0x8a,
+#elif PACKETVER < 20131223
+	damageType = 0x2e1,
+#else
+	damageType = 0x8c8,
+#endif
+#if PACKETVER < 4
+	spawn_unitType = 0x79,
+#elif PACKETVER < 7
+	spawn_unitType = 0x1d9,
+#elif PACKETVER < 20080102
+	spawn_unitType = 0x22b,
+#elif PACKETVER < 20091103
+	spawn_unitType = 0x2ed,
+#elif PACKETVER < 20101124
+	spawn_unitType = 0x7f8,
+#elif PACKETVER < 20120221
+	spawn_unitType = 0x858,
+#elif PACKETVER < 20131223
+	spawn_unitType = 0x90f,
+#elif PACKETVER < 20150513
+	spawn_unitType = 0x9dc,
+#else
+	spawn_unitType = 0x9fe,
+#endif
+#if PACKETVER < 20080102
+	authokType = 0x73,
+#elif PACKETVER < 20141022
+	authokType = 0x2eb,
+// Some clients smaller than 20160330 cant be tested [4144]
+#elif PACKETVER < 20160330
+	authokType = 0xa18,
+#else
+	authokType = 0x2eb,
+#endif
+	script_clearType = 0x8d6,
+	package_item_announceType = 0x7fd,
+	item_drop_announceType = 0x7fd,
+#if PACKETVER < 4
+	unit_walkingType = 0x7b,
+#elif PACKETVER < 7
+	unit_walkingType = 0x1da,
+#elif PACKETVER < 20080102
+	unit_walkingType = 0x22c,
+#elif PACKETVER < 20091103
+	unit_walkingType = 0x2ec,
+#elif PACKETVER < 20101124
+	unit_walkingType = 0x7f7,
+#elif PACKETVER < 20120221
+	unit_walkingType = 0x856,
+#elif PACKETVER < 20131223
+	unit_walkingType = 0x914,
+#elif PACKETVER < 20150513
+	unit_walkingType = 0x9db,
+#else
+	unit_walkingType = 0x9fd,
+#endif
+	bgqueue_ackType = 0x8d8,
+	bgqueue_notice_deleteType = 0x8db,
+	bgqueue_registerType = 0x8d7,
+	bgqueue_updateinfoType = 0x8d9,
+	bgqueue_checkstateType = 0x90a,
+	bgqueue_revokereqType = 0x8da,
+	bgqueue_battlebeginackType = 0x8e0,
+	bgqueue_notify_entryType = 0x8d9,
+	bgqueue_battlebeginsType = 0x8df,
+	notify_bounditemType = 0x2d3,
+#if PACKETVER < 20110718
+	skill_entryType = 0x11f,
+#elif PACKETVER < 20121212
+	skill_entryType = 0x8c7,
+#elif PACKETVER < 20130731
+	skill_entryType = 0x99f,
+#else
+	skill_entryType = 0x9ca,
+#endif
+	graffiti_entryType = 0x1c9,
+#if defined(PACKETVER_ZERO) || PACKETVER >= 20180418
+	dropflooritemType = 0xadd,
+#elif PACKETVER > 20130000 /* not sure date */
+	dropflooritemType = 0x84b,
+#else
+	dropflooritemType = 0x9e,
+#endif
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	inventorylistnormalType = 0xb09,
+#elif PACKETVER >= 20120925
+	inventorylistnormalType = 0x991,
+#elif PACKETVER >= 20080102
+	inventorylistnormalType = 0x2e8,
+#elif PACKETVER >= 20071002
+	inventorylistnormalType = 0x1ee,
+#else
+	inventorylistnormalType = 0xa3,
+#endif
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	inventorylistequipType = 0xb0a,
+#elif PACKETVER >= 20150226
+	inventorylistequipType = 0xa0d,
+#elif PACKETVER >= 20120925
+	inventorylistequipType = 0x992,
+#elif PACKETVER >= 20080102
+	inventorylistequipType = 0x2d0,
+#elif PACKETVER >= 20071002
+	inventorylistequipType = 0x295,
+#else
+	inventorylistequipType = 0xa4,
+#endif
+#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	storageListNormalType = 0xb09,
+#elif PACKETVER >= 20120925
+	storageListNormalType = 0x995,
+#elif PACKETVER >= 20080102
+	storageListNormalType = 0x2ea,
+#elif PACKETVER >= 20071002
+	storageListNormalType = 0x295,
+#else
+	storageListNormalType = 0xa5,
+#endif
+#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	storageListEquipType = 0xb0a,
+#elif PACKETVER >= 20150226
+	storageListEquipType = 0xa10,
+#elif PACKETVER >= 20120925
+	storageListEquipType = 0x996,
+#elif PACKETVER >= 20080102
+	storageListEquipType = 0x2d1,
+#elif PACKETVER >= 20071002
+	storageListEquipType = 0x296,
+#else
+	storageListEquipType = 0xa6,
+#endif
+#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	cartlistnormalType = 0xb09,
+#elif PACKETVER >= 20120925
+	cartlistnormalType = 0x993,
+#elif PACKETVER >= 20080102
+	cartlistnormalType = 0x2e9,
+#elif PACKETVER >= 20071002
+	cartlistnormalType = 0x1ef,
+#else
+	cartlistnormalType = 0x123,
+#endif
+#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	cartlistequipType = 0xb0a,
+#elif PACKETVER >= 20150226
+	cartlistequipType = 0xa0f,
+#elif PACKETVER >= 20120925
+	cartlistequipType = 0x994,
+#elif PACKETVER >= 20080102
+	cartlistequipType = 0x2d2,
+#elif PACKETVER >= 20071002
+	cartlistequipType = 0x297,
+#else
+	cartlistequipType = 0x122,
+#endif
+#if PACKETVER < 20100105
+	vendinglistType = 0x133,
+#else
+	vendinglistType = 0x800,
+#endif
+	openvendingType = 0x136,
+#if PACKETVER >= 20120925
+	equipitemType = 0x998,
+#else
+	equipitemType = 0xa9,
+#endif
+#if PACKETVER >= 20120925
+	equipitemackType = 0x999,
+#else
+	equipitemackType = 0xaa,
+#endif
+#if PACKETVER >= 20120925
+	unequipitemackType = 0x99a,
+#else
+	unequipitemackType = 0xac,
+#endif
+#if PACKETVER_MAIN_NUM >= 20180801 || PACKETVER_RE_NUM >= 20180801 || PACKETVER_ZERO_NUM >= 20180808
+	viewequipackType = 0xb03,
+#elif PACKETVER >= 20150226
+	viewequipackType = 0xa2d,
+#elif PACKETVER >= 20120925
+	viewequipackType = 0x997,
+// [4144] not supported due other packets/structs not updated
+//#elif (PACKETVER_MAIN_NUM >= 20111207) || (PACKETVER_RE_NUM >= 20111122)
+//	viewequipackType = 0x906,
+#elif PACKETVER >= 20101124
+	viewequipackType = 0x859,
+#else
+	viewequipackType = 0x2d7,
+#endif
+	notifybindonequip = 0x2d3,
+	monsterhpType = 0x977,
+	maptypeproperty2Type = 0x99b,
+#if PACKETVER >= 20131223  // version probably can be 20131030 [4144]
+	wisendType = 0x9df,
+#else
+	wisendType = 0x98,
+#endif
+	partyleaderchangedType = 0x7fc,
+	rouletteinfoackType = 0xa1c,
+	roulettgenerateackType = 0xa20,
+	roulettercvitemackType = 0xa22,
+#if PACKETVER >= 20141016
+	achievementListType = 0xa23,
+	achievementUpdateType = 0xa24,
+	achievementRewardAckType = 0xa26,
+#endif // PACKETVER >= 20141016
+#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017
+	questListType = 0xaff, ///< ZC_ALL_QUEST_LIST4
+#elif PACKETVER >= 20150513  // [4144] 0x09f8 handling in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE
+	questListType = 0x9f8, ///< ZC_ALL_QUEST_LIST3
+#elif PACKETVER >= 20141022
+	questListType = 0x97a, ///< ZC_ALL_QUEST_LIST2
+#else // PACKETVER < 20141022
+	questListType = 0x2b1, ///< ZC_ALL_QUEST_LIST
+#endif // PACKETVER >= 20141022
+	/* Rodex */
+	rodexicon = 0x09E7,
+	rodexread = 0x09EB,
+	rodexwriteresult = 0x09ED,
+	rodexnextpage = 0x09F0,
+	rodexgetzeny = 0x09F2,
+	rodexgetitem = 0x09F4,
+	rodexdelete = 0x09F6,
+	rodexadditem = 0x0A05,
+	rodexremoveitem = 0x0A07,
+	rodexopenwrite = 0x0A12,
+#if PACKETVER < 20160601
+	rodexmailList = 0x09F0,
+#elif PACKETVER < 20170419
+	rodexmailList = 0x0A7D,
+#else // PACKETVER >= 20170419
+	rodexmailList = 0x0Ac2,
+#endif
+#if PACKETVER < 20160316
+	rodexcheckplayer = 0x0A14,
+#else // PACKETVER >= 20160316
+	rodexcheckplayer = 0x0A51,
+#endif
+#if PACKETVER >= 20151223
+	skillscale = 0xA41,
+#endif
+#if PACKETVER >= 20130821
+	progressbarunit = 0x09D1,
+#endif
+#if PACKETVER >= 20171207
+	partymemberinfo = 0x0ae4,
+	partyinfo = 0x0ae5,
+#elif PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO)
+	partymemberinfo = 0x0a43,
+	partyinfo = 0x0a44,
+#else
+	partymemberinfo = 0x01e9,
+	partyinfo = 0x00fb,
+#endif
+#if PACKETVER >= 20120716
+	clanOnlineCount = 0x0988, ///< ZC_NOTIFY_CLAN_CONNECTINFO
+	clanLeave = 0x0989, ///< ZC_ACK_CLAN_LEAVE
+	clanMessage = 0x098E, ///< ZC_NOTIFY_CLAN_CHAT
+#endif
+#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017
+	questAddType = 0xb0c,
+#elif PACKETVER >= 20150513 // [4144] 0x09f9 handled in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE
+	questAddType = 0x9f9,
+#else
+	questAddType = 0x2b3,
+#endif // PACKETVER < 20150513
+#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017
+	questUpdateType = 0xafe,
+#elif PACKETVER >= 20150513
+	questUpdateType = 0x9fa,
+#else
+	questUpdateType = 0x2b5,
+#endif // PACKETVER < 20150513
+	questUpdateType2 = 0x8fe,
+#if PACKETVER >= 20171122
+	openUiType = 0xAE2,
+#elif PACKETVER >= 20150128
+	openUiType = 0xA38,
+#endif
+#if PACKETVER >= 20180627
+	authError = 0xb02,
+#elif PACKETVER >= 20101123
+	authError = 0x83e,
+#else
+	authError = 0x6a,
+#endif
+#if PACKETVER >= 3
+	useItemAckType = 0x1c8,
+#else
+	useItemAckType = 0xa8,
+#endif
+#if PACKETVER >= 4
+	sendLookType = 0x1d7,
+#else
+	sendLookType = 0xc3,
+#endif
+#if PACKETVER >= 20141016
+	buyingStoreUpdateItemType = 0x9e6,
+#else
+	buyingStoreUpdateItemType = 0x81b,
+#endif
+	reqName = 0x95,
+#if PACKETVER_MAIN_NUM >= 20170502 || PACKETVER_RE_NUM >= 20170419 || defined(PACKETVER_ZERO)
+	skilWarpPointType = 0xabe,
+#else
+	skilWarpPointType = 0x11c,
+#endif
+#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO)
+	guildExpulsion = 0xa82,
+#elif PACKETVER >= 20100803
+	guildExpulsion = 0x839,
+#else
+	guildExpulsion = 0x15c,
+#endif
+#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO)
+	guildLeave = 0xa83,
+#else
+	guildLeave = 0x15a,
+#endif
+};
+
+#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#pragma pack(push, 1)
+#endif // not NetBSD < 6 / Solaris
+
+/**
+ * structs for data
+ */
+struct EQUIPSLOTINFO {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 card[4];
+#else
+	uint16 card[4];
+#endif
+} __attribute__((packed));
+
+struct NORMALITEM_INFO {
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ITID;
+#else
+	uint16 ITID;
+#endif
+	uint8 type;
+#if PACKETVER < 20120925
+	uint8 IsIdentified;
+#endif
+	int16 count;
+#if PACKETVER >= 20120925
+	uint32 WearState;
+#else
+	uint16 WearState;
+#endif
+#if PACKETVER >= 5
+	struct EQUIPSLOTINFO slot;
+#endif
+#if PACKETVER >= 20080102
+	int32 HireExpireDate;
+#endif
+#if PACKETVER >= 20120925
+	struct {
+		uint8 IsIdentified : 1;
+		uint8 PlaceETCTab : 1;
+		uint8 SpareBits : 6;
+	} Flag;
+#endif
+} __attribute__((packed));
+
+struct ItemOptions {
+	int16 index;
+	int16 value;
+	uint8 param;
+} __attribute__((packed));
+
+struct EQUIPITEM_INFO {
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ITID;
+#else
+	uint16 ITID;
+#endif
+	uint8 type;
+#if PACKETVER < 20120925
+	uint8 IsIdentified;
+#endif
+#if PACKETVER >= 20120925
+	uint32 location;
+	uint32 WearState;
+#else
+	uint16 location;
+	uint16 WearState;
+#endif
+#if PACKETVER < 20120925
+	uint8 IsDamaged;
+#endif
+	uint8 RefiningLevel;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20071002
+	int32 HireExpireDate;
+#endif
+#if PACKETVER >= 20080102
+	uint16 bindOnEquipType;
+#endif
+#if PACKETVER >= 20100629
+	uint16 wItemSpriteNumber;
+#endif
+#if PACKETVER >= 20150226
+	uint8 option_count;
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+#if PACKETVER >= 20120925
+	struct {
+		uint8 IsIdentified : 1;
+		uint8 IsDamaged : 1;
+		uint8 PlaceETCTab : 1;
+		uint8 SpareBits : 5;
+	} Flag;
+#endif
+} __attribute__((packed));
+
+struct packet_authok {
+	int16 PacketType;
+	uint32 startTime;
+	uint8 PosDir[3];
+	uint8 xSize;
+	uint8 ySize;
+#if PACKETVER >= 20080102
+	int16 font;
+#endif
+// Some clients smaller than 20160330 cant be tested [4144]
+#if PACKETVER >= 20141022 && PACKETVER < 20160330
+	uint8 sex;
+#endif
+} __attribute__((packed));
+
+struct packet_monster_hp {
+	int16 PacketType;
+	uint32 GID;
+	int32 HP;
+	int32 MaxHP;
+} __attribute__((packed));
+
+struct packet_sc_notick {
+	int16 PacketType;
+	int16 index;
+	uint32 AID;
+	uint8 state;
+} __attribute__((packed));
+
+struct packet_additem {
+	int16 PacketType;
+	uint16 Index;
+	uint16 count;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 nameid;
+#else
+	uint16 nameid;
+#endif
+	uint8 IsIdentified;
+	uint8 IsDamaged;
+	uint8 refiningLevel;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20120925
+	uint32 location;
+#else
+	uint16 location;
+#endif
+	uint8 type;
+	uint8 result;
+#if PACKETVER >= 20061218
+	int32 HireExpireDate;
+#endif
+#if PACKETVER >= 20071002
+	uint16 bindOnEquipType;
+#endif
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+#if PACKETVER >= 20160921
+	uint8 favorite;
+	uint16 look;
+#endif
+} __attribute__((packed));
+
+struct packet_dropflooritem {
+	int16 PacketType;
+	uint32 ITAID;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ITID;
+#else
+	uint16 ITID;
+#endif
+#if PACKETVER >= 20130000 /* not sure date */
+	uint16 type;
+#endif
+	uint8 IsIdentified;
+	int16 xPos;
+	int16 yPos;
+	uint8 subX;
+	uint8 subY;
+	int16 count;
+#if defined(PACKETVER_ZERO) || PACKETVER >= 20180418
+	int8 showdropeffect;
+	int16 dropeffectmode;
+#endif
+} __attribute__((packed));
+struct packet_idle_unit2 {
+#if PACKETVER < 20091103
+	int16 PacketType;
+#if PACKETVER >= 20071106
+	uint8 objecttype;
+#endif
+	uint32 GID;
+	int16 speed;
+	int16 bodyState;
+	int16 healthState;
+	int16 effectState;
+	int16 job;
+	uint16 head;
+	uint16 weapon;
+	uint16 accessory;
+	uint16 shield;
+	uint16 accessory2;
+	uint16 accessory3;
+	int16 headpalette;
+	int16 bodypalette;
+	int16 headDir;
+	uint32 GUID;
+	int16 GEmblemVer;
+	int16 honor;
+	int16 virtue;
+	uint8 isPKModeON;
+	uint8 sex;
+	uint8 PosDir[3];
+	uint8 xSize;
+	uint8 ySize;
+	uint8 state;
+	int16 clevel;
+#else // ! PACKETVER < 20091103
+	UNAVAILABLE_STRUCT;
+#endif // PACKETVER < 20091103
+} __attribute__((packed));
+
+struct packet_spawn_unit2 {
+#if PACKETVER < 20091103
+	int16 PacketType;
+#if PACKETVER >= 20071106
+	uint8 objecttype;
+#endif
+	uint32 GID;
+	int16 speed;
+	int16 bodyState;
+	int16 healthState;
+	int16 effectState;
+	uint16 head;
+	uint16 weapon;
+	uint16 accessory;
+	int16 job;
+	uint16 shield;
+	uint16 accessory2;
+	uint16 accessory3;
+	int16 headpalette;
+	int16 bodypalette;
+	int16 headDir;
+	uint8 isPKModeON;
+	uint8 sex;
+	uint8 PosDir[3];
+	uint8 xSize;
+	uint8 ySize;
+#else // ! PACKETVER < 20091103
+	UNAVAILABLE_STRUCT;
+#endif // PACKETVER < 20091103
+} __attribute__((packed));
+
+struct packet_spawn_unit {
+	int16 PacketType;
+#if PACKETVER >= 20091103
+	int16 PacketLength;
+	uint8 objecttype;
+#endif
+#if PACKETVER >= 20131223
+	uint32 AID;
+#endif
+	uint32 GID;
+	int16 speed;
+	int16 bodyState;
+	int16 healthState;
+#if PACKETVER < 20080102
+	int16 effectState;
+#else
+	int32 effectState;
+#endif
+	int16 job;
+	uint16 head;
+#if PACKETVER < 7
+	uint16 weapon;
+#else
+	uint32 weapon;
+#endif
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 shield;
+#endif
+	uint16 accessory;
+#if PACKETVER < 7
+	uint16 shield;
+#endif
+	uint16 accessory2;
+	uint16 accessory3;
+	int16 headpalette;
+	int16 bodypalette;
+	int16 headDir;
+#if PACKETVER >= 20101124
+	uint16 robe;
+#endif
+	uint32 GUID;
+	int16 GEmblemVer;
+	int16 honor;
+#if PACKETVER > 7
+	int32 virtue;
+#else
+	int16 virtue;
+#endif
+	uint8 isPKModeON;
+	uint8 sex;
+	uint8 PosDir[3];
+	uint8 xSize;
+	uint8 ySize;
+	int16 clevel;
+#if PACKETVER >= 20080102
+	int16 font;
+#endif
+#if PACKETVER >= 20120221
+	int32 maxHP;
+	int32 HP;
+	uint8 isBoss;
+#endif
+#if PACKETVER >= 20150513
+	int16 body;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
+	char name[NAME_LENGTH];
+#endif
+} __attribute__((packed));
+
+struct packet_unit_walking {
+	int16 PacketType;
+#if PACKETVER >= 20091103
+	int16 PacketLength;
+#endif
+#if PACKETVER >= 20071106
+	uint8 objecttype;
+#endif
+#if PACKETVER >= 20131223
+	uint32 AID;
+#endif
+	uint32 GID;
+	int16 speed;
+	int16 bodyState;
+	int16 healthState;
+#if PACKETVER < 7
+	int16 effectState;
+#else
+	int32 effectState;
+#endif
+	int16 job;
+	uint16 head;
+#if PACKETVER < 7
+	uint16 weapon;
+#else
+	uint32 weapon;
+#endif
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 shield;
+#endif
+	uint16 accessory;
+	uint32 moveStartTime;
+#if PACKETVER < 7
+	uint16 shield;
+#endif
+	uint16 accessory2;
+	uint16 accessory3;
+	int16 headpalette;
+	int16 bodypalette;
+	int16 headDir;
+#if PACKETVER >= 20101124
+	uint16 robe;
+#endif
+	uint32 GUID;
+	int16 GEmblemVer;
+	int16 honor;
+#if PACKETVER > 7
+	int32 virtue;
+#else
+	int16 virtue;
+#endif
+	uint8 isPKModeON;
+	uint8 sex;
+	uint8 MoveData[6];
+	uint8 xSize;
+	uint8 ySize;
+	int16 clevel;
+#if PACKETVER >= 20080102
+	int16 font;
+#endif
+#if PACKETVER >= 20120221
+	int32 maxHP;
+	int32 HP;
+	uint8 isBoss;
+#endif
+#if PACKETVER >= 20150513
+	uint16 body;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
+	char name[NAME_LENGTH];
+#endif
+} __attribute__((packed));
+
+struct packet_idle_unit {
+	int16 PacketType;
+#if PACKETVER >= 20091103
+	int16 PacketLength;
+	uint8 objecttype;
+#endif
+#if PACKETVER >= 20131223
+	uint32 AID;
+#endif
+	uint32 GID;
+	int16 speed;
+	int16 bodyState;
+	int16 healthState;
+#if PACKETVER < 20080102
+	int16 effectState;
+#else
+	int32 effectState;
+#endif
+	int16 job;
+	uint16 head;
+#if PACKETVER < 7
+	uint16 weapon;
+#else
+	uint32 weapon;
+#endif
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 shield;
+#endif
+	uint16 accessory;
+#if PACKETVER < 7
+	uint16 shield;
+#endif
+	uint16 accessory2;
+	uint16 accessory3;
+	int16 headpalette;
+	int16 bodypalette;
+	int16 headDir;
+#if PACKETVER >= 20101124
+	uint16 robe;
+#endif
+	uint32 GUID;
+	int16 GEmblemVer;
+	int16 honor;
+#if PACKETVER > 7
+	int32 virtue;
+#else
+	int16 virtue;
+#endif
+	uint8 isPKModeON;
+	uint8 sex;
+	uint8 PosDir[3];
+	uint8 xSize;
+	uint8 ySize;
+	uint8 state;
+	int16 clevel;
+#if PACKETVER >= 20080102
+	int16 font;
+#endif
+#if PACKETVER >= 20120221
+	int32 maxHP;
+	int32 HP;
+	uint8 isBoss;
+#endif
+#if PACKETVER >= 20150513
+	uint16 body;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
+	char name[NAME_LENGTH];
+#endif
+} __attribute__((packed));
+
+struct packet_status_change {
+	int16 PacketType;
+	int16 index;
+	uint32 AID;
+	uint8 state;
+#if PACKETVER >= 20120618
+	uint32 Total;
+#endif
+#if PACKETVER >= 20090121
+	uint32 Left;
+	int32 val1;
+	int32 val2;
+	int32 val3;
+#endif
+} __attribute__((packed));
+
+struct packet_status_change_end {
+	int16 PacketType;
+	int16 index;
+	uint32 AID;
+	uint8 state;
+} __attribute__((packed));
+
+struct packet_status_change2 {
+	int16 PacketType;
+	int16 index;
+	uint32 AID;
+	uint8 state;
+	uint32 Left;
+	int32 val1;
+	int32 val2;
+	int32 val3;
+} __attribute__((packed));
+
+struct packet_maptypeproperty2 {
+	int16 PacketType;
+	int16 type;
+	struct {
+		uint32 party             : 1;  // Show attack cursor on non-party members (PvP)
+		uint32 guild             : 1;  // Show attack cursor on non-guild members (GvG)
+		uint32 siege             : 1;  // Show emblem over characters' heads when in GvG (WoE castle)
+		uint32 mineffect         : 1;  // Automatically enable /mineffect
+		uint32 nolockon          : 1;  // TODO: What does this do? (shows attack cursor on non-party members)
+		uint32 countpk           : 1;  /// Show the PvP counter
+		uint32 nopartyformation  : 1;  /// Prevent party creation/modification
+		uint32 bg                : 1;  // TODO: What does this do? Probably related to Battlegrounds, but I'm not sure on the effect
+		uint32 nocostume         : 1;  /// Does not show costume sprite.
+		uint32 usecart           : 1;  /// Allow opening cart inventory
+		uint32 summonstarmiracle : 1;  // TODO: What does this do? Related to Taekwon Masters, but I have no idea.
+		uint32 SpareBits         : 21; /// Currently ignored, reserved for future updates
+	} flag;
+} __attribute__((packed));
+
+struct packet_bgqueue_ack {
+	int16 PacketType;
+	uint8 type;
+	char bg_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_bgqueue_notice_delete {
+	int16 PacketType;
+	uint8 type;
+	char bg_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_bgqueue_register {
+	int16 PacketType;
+	int16 type;
+	char bg_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_bgqueue_update_info {
+	int16 PacketType;
+	char bg_name[NAME_LENGTH];
+	int32 position;
+} __attribute__((packed));
+
+struct packet_bgqueue_checkstate {
+	int16 PacketType;
+	char bg_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_bgqueue_revoke_req {
+	int16 PacketType;
+	char bg_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_bgqueue_battlebegin_ack {
+	int16 PacketType;
+	uint8 result;
+	char bg_name[NAME_LENGTH];
+	char game_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_bgqueue_notify_entry {
+	int16 PacketType;
+	char name[NAME_LENGTH];
+	int32 position;
+} __attribute__((packed));
+
+struct packet_bgqueue_battlebegins {
+	int16 PacketType;
+	char bg_name[NAME_LENGTH];
+	char game_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_script_clear {
+	int16 PacketType;
+	uint32 NpcID;
+} __attribute__((packed));
+
+/* made possible thanks to Yommy!! */
+struct packet_package_item_announce {
+	int16 PacketType;
+	int16 PacketLength;
+	uint8 type;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ItemID;
+#else
+	uint16 ItemID;
+#endif
+	int8 len;
+	char Name[NAME_LENGTH];
+	int8 unknown;  // probably unused
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 BoxItemID;
+#else
+	uint16 BoxItemID;
+#endif
+} __attribute__((packed));
+
+/* made possible thanks to Yommy!! */
+struct packet_item_drop_announce {
+	int16 PacketType;
+	int16 PacketLength;
+	uint8 type;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ItemID;
+#else
+	uint16 ItemID;
+#endif
+	int8 len;
+	char Name[NAME_LENGTH];
+	char monsterNameLen;
+	char monsterName[NAME_LENGTH];
+} __attribute__((packed));
+
+struct packet_cart_additem_ack {
+	int16 PacketType;
+	int8 result;
+} __attribute__((packed));
+
+struct packet_banking_check {
+	int16 PacketType;
+	int64 Money;
+	int16 Reason;
+} __attribute__((packed));
+
+struct packet_banking_deposit_req {
+	int16 PacketType;
+	uint32 AID;
+	int32 Money;
+} __attribute__((packed));
+
+struct packet_banking_withdraw_req {
+	int16 PacketType;
+	uint32 AID;
+	int32 Money;
+} __attribute__((packed));
+
+struct packet_banking_deposit_ack {
+	int16 PacketType;
+	int16 Reason;
+	int64 Money;
+	int32 Balance;
+} __attribute__((packed));
+
+struct packet_banking_withdraw_ack {
+	int16 PacketType;
+	int16 Reason;
+	int64 Money;
+	int32 Balance;
+} __attribute__((packed));
+
+/* Roulette System [Yommy/Hercules] */
+struct packet_roulette_open_ack {
+	int16 PacketType;
+	int8 Result;
+	int32 Serial;
+	int8 Step;
+	int8 Idx;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 AdditionItemID;
+#else
+	uint16 AdditionItemID;
+#endif
+	int32 GoldPoint;
+	int32 SilverPoint;
+	int32 BronzePoint;
+} __attribute__((packed));
+
+struct packet_roulette_info_ack {
+	int16 PacketType;
+	int16 PacketLength;
+	uint32 RouletteSerial;
+	struct {
+		uint16 Row;
+		uint16 Position;
+#if PACKETVER >= 20180511
+		uint32 ItemId;
+		uint16 Count;
+		uint16 unused;
+#else
+		uint16 ItemId;
+		uint16 Count;
+#endif
+	} ItemInfo[42];
+} __attribute__((packed));
+
+struct packet_roulette_close_ack {
+	int16 PacketType;
+	uint8 Result;
+} __attribute__((packed));
+
+struct packet_roulette_generate_ack {
+	int16 PacketType;
+	uint8 Result;
+	uint16 Step;
+	uint16 Idx;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 AdditionItemID;
+#else
+	uint16 AdditionItemID;
+#endif
+	int32 RemainGold;
+	int32 RemainSilver;
+	int32 RemainBronze;
+} __attribute__((packed));
+
+struct packet_roulette_itemrecv_req {
+	int16 PacketType;
+	uint8 Condition;
+} __attribute__((packed));
+
+struct packet_roulette_itemrecv_ack {
+	int16 PacketType;
+	uint8 Result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 AdditionItemID;
+#else
+	uint16 AdditionItemID;
+#endif
+} __attribute__((packed));
+
+struct packet_itemlist_normal {
+	int16 PacketType;
+	int16 PacketLength;
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	uint8 invType;
+#endif
+	struct NORMALITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_itemlist_equip {
+	int16 PacketType;
+	int16 PacketLength;
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	uint8 invType;
+#endif
+	struct EQUIPITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct ZC_STORE_ITEMLIST_NORMAL {
+	int16 PacketType;
+	int16 PacketLength;
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	uint8 invType;
+#endif
+#if PACKETVER >= 20120925 && PACKETVER_RE_NUM < 20180829 && PACKETVER_ZERO_NUM < 20180919 && PACKETVER_MAIN_NUM < 20181002
+	char name[NAME_LENGTH];
+#endif
+	struct NORMALITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+struct PACKET_ZC_INVENTORY_START {
+	int16 packetType;
+#if PACKETVER_RE_NUM >= 20180919 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	int16 packetLength;
+#endif
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	uint8 invType;
+#endif
+#if PACKETVER_RE_NUM >= 20180919 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	char name[];
+#else
+	char name[NAME_LENGTH];
+#endif
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_INVENTORY_START, 0x0b08);
+#endif  // PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+
+#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+struct PACKET_ZC_INVENTORY_END {
+	int16 packetType;
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	uint8 invType;
+#endif
+	char flag;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_INVENTORY_END, 0x0b0b);
+#endif  // PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+
+struct ZC_STORE_ITEMLIST_EQUIP {
+	int16 PacketType;
+	int16 PacketLength;
+#if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002
+	uint8 invType;
+#endif
+#if PACKETVER >= 20120925 && PACKETVER_RE_NUM < 20180829 && PACKETVER_ZERO_NUM < 20180919 && PACKETVER_MAIN_NUM < 20181002
+	char name[NAME_LENGTH];
+#endif
+	struct EQUIPITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_equip_item {
+	int16 PacketType;
+	uint16 index;
+#if PACKETVER >= 20120925
+	uint32 wearLocation;
+#else
+	uint16 wearLocation;
+#endif
+} __attribute__((packed));
+
+struct packet_equipitem_ack {
+	int16 PacketType;
+	uint16 index;
+#if PACKETVER >= 20120925
+	uint32 wearLocation;
+#else
+	uint16 wearLocation;
+#endif
+#if PACKETVER >= 20100629
+	uint16 wItemSpriteNumber;
+#endif
+	uint8 result;
+} __attribute__((packed));
+
+struct packet_unequipitem_ack {
+	int16 PacketType;
+	uint16 index;
+#if PACKETVER >= 20120925
+	uint32 wearLocation;
+#else
+	uint16 wearLocation;
+#endif
+	uint8 result;
+} __attribute__((packed));
+
+struct packet_viewequip_ack {
+	int16 PacketType;
+	int16 PacketLength;
+	char characterName[NAME_LENGTH];
+	int16 job;
+	int16 head;
+	int16 accessory;
+	int16 accessory2;
+	int16 accessory3;
+#if PACKETVER >= 20101124
+	int16 robe;
+#endif
+	int16 headpalette;
+	int16 bodypalette;
+#if PACKETVER_MAIN_NUM >= 20180801 || PACKETVER_RE_NUM >= 20180801 || PACKETVER_ZERO_NUM >= 20180808
+	int16 body2;
+#endif
+	uint8 sex;
+	// [4144] need remove MAX_INVENTORY from here
+	struct EQUIPITEM_INFO list[MAX_INVENTORY];
+} __attribute__((packed));
+
+struct packet_notify_bounditem {
+	int16 PacketType;
+	uint16 index;
+} __attribute__((packed));
+
+struct packet_skill_entry {
+	int16 PacketType;
+#if PACKETVER >= 20110718
+	int16 PacketLength;
+#endif
+	uint32 AID;
+	uint32 creatorAID;
+	int16 xPos;
+	int16 yPos;
+#if PACKETVER >= 20121212
+	int32 job;
+#else
+	uint8 job;
+#endif
+#if PACKETVER >= 20110718
+	int8 RadiusRange;
+#endif
+	uint8 isVisible;
+#if PACKETVER >= 20130731
+	uint8 level;
+#endif
+} __attribute__((packed));
+
+struct packet_graffiti_entry {
+	int16 PacketType;
+	uint32 AID;
+	uint32 creatorAID;
+	int16 xPos;
+	int16 yPos;
+	uint8 job;
+	uint8 isVisible;
+	uint8 isContens;
+	char msg[80];
+} __attribute__((packed));
+
+struct packet_damage {
+	int16 PacketType;
+	uint32 GID;
+	uint32 targetGID;
+	uint32 startTime;
+	int32 attackMT;
+	int32 attackedMT;
+#if PACKETVER < 20071113
+	int16 damage;
+#else
+	int32 damage;
+#endif
+#if PACKETVER >= 20131223
+	uint8 is_sp_damaged;
+#endif
+	int16 count;
+	uint8 action;
+#if PACKETVER < 20071113
+	int16 leftDamage;
+#else
+	int32 leftDamage;
+#endif
+} __attribute__((packed));
+
+struct packet_gm_monster_item {
+	int16 PacketType;
+#if PACKETVER >= 20131218
+	char str[100];
+#else
+	char str[24];
+#endif
+} __attribute__((packed));
+
+struct packet_npc_market_purchase_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ITID;
+#else
+	uint16 ITID;
+#endif
+	int32 qty;
+} __attribute__((packed));
+
+struct packet_npc_market_purchase {
+	int16 PacketType;
+	int16 PacketLength;
+	struct packet_npc_market_purchase_sub list[];
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20131120 || PACKETVER_RE_NUM >= 20131106 || defined(PACKETVER_ZERO)
+/* inner struct figured by Ind after some annoying hour of debugging (data Thanks to Yommy) */
+struct PACKET_ZC_NPC_MARKET_OPEN_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 nameid;
+#else
+	uint16 nameid;
+#endif
+	uint8 type;
+	uint32 price;
+	uint32 qty;
+	uint16 weight;
+} __attribute__((packed));
+
+struct PACKET_ZC_NPC_MARKET_OPEN {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_NPC_MARKET_OPEN_sub list[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_NPC_MARKET_OPEN, 0x09d5);
+#endif
+
+struct packet_wis_end {
+	int16 PacketType;
+	int8 result;
+#if PACKETVER >= 20131223
+	uint32 AID;
+#endif
+} __attribute__((packed));
+
+
+struct packet_party_leader_changed {
+	int16 PacketType;
+	uint32 prev_leader_aid;
+	uint32 new_leader_aid;
+} __attribute__((packed));
+
+#ifdef HOTKEY_SAVING
+struct hotkey_data {
+	int8 isSkill; // 0: Item, 1:Skill
+	uint32 id;    // Item/Skill ID
+	int16 count;  // Item Quantity/Skill Level
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+#define MAX_HOTKEYS_PACKET 38
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+	int16 packetType;
+	int8 rotate;
+	int16 tab;
+	struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x0b20);
+#elif PACKETVER_MAIN_NUM >= 20141022 || PACKETVER_RE_NUM >= 20141015 || defined(PACKETVER_ZERO)
+#define MAX_HOTKEYS_PACKET 38
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+	int16 packetType;
+	int8 rotate;
+	struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x0a00);
+#elif PACKETVER_MAIN_NUM >= 20090617 || PACKETVER_RE_NUM >= 20090617 || PACKETVER_SAK_NUM >= 20090617
+#define MAX_HOTKEYS_PACKET 38
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+	int16 packetType;
+	struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x07d9);
+#elif PACKETVER_MAIN_NUM >= 20090603 || PACKETVER_RE_NUM >= 20090603 || PACKETVER_SAK_NUM >= 20090603
+#define MAX_HOTKEYS_PACKET 36
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+	int16 packetType;
+	struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x07d9);
+#elif PACKETVER_MAIN_NUM >= 20070711 || PACKETVER_RE_NUM >= 20080827 || PACKETVER_AD_NUM >= 20070711 || PACKETVER_SAK_NUM >= 20070628
+#define MAX_HOTKEYS_PACKET 27
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+	int16 packetType;
+	struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x02b9);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20070618 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO) || PACKETVER_AD_NUM >= 20070618 || PACKETVER_SAK_NUM >= 20070618
+struct PACKET_CZ_SHORTCUT_KEY_CHANGE1 {
+	int16 packetType;
+	uint16 index;
+	struct hotkey_data hotkey;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUT_KEY_CHANGE1, 0x02ba);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+struct PACKET_CZ_SHORTCUT_KEY_CHANGE2 {
+	int16 packetType;
+	uint16 tab;
+	uint16 index;
+	struct hotkey_data hotkey;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUT_KEY_CHANGE2, 0x0b21);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20140129 || PACKETVER_RE_NUM >= 20140129 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE1 {
+	int16 packetType;
+	uint8 rowshift;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUTKEYBAR_ROTATE1, 0x0a01);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE2 {
+	int16 packetType;
+	uint16 tab;
+	uint8 rowshift;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUTKEYBAR_ROTATE2, 0x0b22);
+#endif
+
+#endif // HOTKEY_SAVING
+
+/**
+ * MISSION_HUNT_INFO (PACKETVER >= 20141022)
+ * MISSION_HUNT_INFO_EX (PACKETVER >= 20150513)
+ */
+struct packet_mission_info_sub {
+#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017
+	uint32 huntIdent;
+	uint32 huntIdent2;
+	uint32 mobType;
+#elif PACKETVER >= 20150513
+	uint32 huntIdent;
+	uint32 mobType;
+#endif
+	uint32 mob_id;
+#if PACKETVER >= 20150513
+	int16 levelMin;
+	int16 levelMax;
+#endif
+	int16 huntCount;
+	int16 maxCount;
+	char mobName[NAME_LENGTH];
+} __attribute__((packed));
+
+/**
+ * PACKET_ZC_ALL_QUEST_LIST2_INFO (PACKETVER >= 20141022)
+ * PACKET_ZC_ALL_QUEST_LIST3_INFO (PACKETVER >= 20150513)
+ */
+struct packet_quest_list_info {
+	int32 questID;
+	int8 active;
+#if PACKETVER >= 20141022
+	int32 quest_svrTime;
+	int32 quest_endTime;
+	int16 hunting_count;
+	struct packet_mission_info_sub objectives[]; // Note: This will be < MAX_QUEST_OBJECTIVES
+#endif // PACKETVER >= 20141022
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_ZC_ALL_QUEST_LIST (PACKETVER < 20141022)
+ * PACKET_ZC_ALL_QUEST_LIST2 (PACKETVER >= 20141022)
+ * PACKET_ZC_ALL_QUEST_LIST3 (PACKETVER >= 20150513)
+ *
+ * @remark
+ *     Contains (is followed by) a variable-length array of packet_quest_list_info
+ */
+struct packet_quest_list_header {
+	uint16 PacketType;
+	uint16 PacketLength;
+	int32 questCount;
+	//struct packet_quest_list_info list[]; // Variable-length
+} __attribute__((packed));
+
+struct packet_chat_message {
+	uint16 packet_id;
+	int16 packet_len;
+	char message[];
+} __attribute__((packed));
+
+struct packet_whisper_message {
+	uint16 packet_id;
+	int16 packet_len;
+	char name[NAME_LENGTH];
+	char message[];
+} __attribute__((packed));
+
+/* RoDEX */
+struct PACKET_CZ_ADD_ITEM_TO_MAIL {
+	int16 PacketType;
+	int16 index;
+	int16 count;
+} __attribute__((packed));
+
+struct PACKET_ZC_ADD_ITEM_TO_MAIL {
+	int16 PacketType;
+	int8 result;
+	int16 index;
+	int16 count;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	int8 type;
+	int8 IsIdentified;
+	int8 IsDamaged;
+	int8 refiningLevel;
+	struct EQUIPSLOTINFO slot;
+	struct ItemOptions optionData[MAX_ITEM_OPTIONS];
+	int16 weight;
+	uint8 favorite;
+	uint32 location;
+} __attribute__((packed));
+
+struct mail_item {
+	int16 count;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ITID;
+#else
+	uint16 ITID;
+#endif
+	int8 IsIdentified;
+	int8 IsDamaged;
+	int8 refiningLevel;
+	struct EQUIPSLOTINFO slot;
+	uint32 location;
+	uint8 type;
+	uint16 viewSprite;
+	uint16 bindOnEquip;
+	struct ItemOptions optionData[MAX_ITEM_OPTIONS];
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_OPEN_WRITE_MAIL {
+	int16 PacketType;
+	char receiveName[NAME_LENGTH];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_OPEN_WRITE_MAIL {
+	int16 PacketType;
+	char receiveName[NAME_LENGTH];
+	int8 result;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_REMOVE_ITEM_MAIL {
+	int16 PacketType;
+	int16 index;
+	uint16 cnt;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_REMOVE_ITEM_MAIL {
+	int16 PacketType;
+	int8 result;
+	int16 index;
+	uint16 cnt;
+	int16 weight;
+} __attribute__((packed));
+
+struct PACKET_CZ_SEND_MAIL {
+	int16 PacketType;
+	int16 PacketLength;
+	char receiveName[24];
+	char senderName[24];
+	int64 zeny;
+	int16 Titlelength;
+	int16 TextcontentsLength;
+#if PACKETVER > 20160600
+	int32 receiver_char_id;
+#endif // PACKETVER > 20160600
+	char string[];
+} __attribute__((packed));
+
+struct PACKET_ZC_WRITE_MAIL_RESULT {
+	int16 PacketType;
+	int8 result;
+} __attribute__((packed));
+
+struct PACKET_CZ_CHECKNAME {
+	int16 PacketType;
+	char Name[24];
+} __attribute__((packed));
+
+struct PACKET_ZC_CHECKNAME {
+	int16 PacketType;
+	int32 CharId;
+	int16 Class;
+	int16 BaseLevel;
+#if PACKETVER >= 20160316
+	char Name[24];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_NOTIFY_UNREADMAIL {
+	int16 PacketType;
+	char result;
+} __attribute__((packed));
+
+struct maillistinfo {
+#if PACKETVER >= 20170419
+	uint8 openType;
+#endif
+	int64 MailID;
+	int8 Isread;
+	uint8 type;
+	char SenderName[24];
+#if PACKETVER < 20170419
+	int32 regDateTime;
+#endif
+	int32 expireDateTime;
+	int16 Titlelength;
+	char title[];
+} __attribute__((packed));
+
+struct PACKET_ZC_MAIL_LIST {
+	int16 PacketType;
+	int16 PacketLength;
+#if PACKETVER < 20170419
+	int8 opentype;
+	int8 cnt;
+#endif
+	int8 IsEnd;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_NEXT_MAIL_LIST {
+	int16 PacketType;
+	int8 opentype;
+	int64 Lower_MailID;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_OPEN_MAIL {
+	int16 PacketType;
+#if PACKETVER >= 20170419
+	int64 char_Upper_MailID;
+	int64 return_Upper_MailID;
+	int64 account_Upper_MailID;
+#else
+	int8 opentype;
+	int64 Upper_MailID;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_READ_MAIL {
+	int16 PacketType;
+	int8 opentype;
+	int64 MailID;
+} __attribute__((packed));
+
+struct PACKET_ZC_READ_MAIL {
+	int16 PacketType;
+	int16 PacketLength;
+	int8 opentype;
+	int64 MailID;
+	int16 TextcontentsLength;
+	int64 zeny;
+	int8 ItemCnt;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_DELETE_MAIL {
+	int16 PacketType;
+	int8 opentype;
+	int64 MailID;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_DELETE_MAIL {
+	int16 PacketType;
+	int8 opentype;
+	int64 MailID;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_REFRESH_MAIL_LIST {
+	int16 PacketType;
+#if PACKETVER >= 20170419
+	int64 Upper_MailID;
+	int8 unknown[16];
+#else
+	int8 opentype;
+	int64 Upper_MailID;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_ZENY_FROM_MAIL {
+	int16 PacketType;
+	int64 MailID;
+	int8 opentype;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_ZENY_FROM_MAIL {
+	int16 PacketType;
+	int64 MailID;
+	int8 opentype;
+	int8 result;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_ITEM_FROM_MAIL {
+	int16 PacketType;
+	int64 MailID;
+	int8 opentype;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_ITEM_FROM_MAIL {
+	int16 PacketType;
+	int64 MailID;
+	int8 opentype;
+	int8 result;
+} __attribute__((packed));
+
+struct PACKET_ZC_SKILL_SCALE {
+	int16 PacketType;
+	uint32 AID;
+	int16 skill_id;
+	int16 skill_lv;
+	int16 x;
+	int16 y;
+	uint32 casttime;
+} __attribute__((packed));
+
+struct ZC_PROGRESS_ACTOR {
+	int16 PacketType;
+	int32 GID;
+	int32 color;
+	uint32 time;
+} __attribute__((packed));
+
+struct PACKET_ZC_ADD_MEMBER_TO_GROUP {
+	int16 packetType;
+	uint32 AID;
+#if PACKETVER >= 20171207
+	uint32 GID;
+#endif
+	uint32 leader;
+#if PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO)
+	int16 class_;
+	int16 baseLevel;
+#endif
+	int16 x;
+	int16 y;
+	uint8 offline;
+	char partyName[NAME_LENGTH];
+	char playerName[NAME_LENGTH];
+	char mapName[MAP_NAME_LENGTH_EXT];
+	int8 sharePickup;
+	int8 shareLoot;
+} __attribute__((packed));
+
+struct PACKET_ZC_GROUP_LIST_SUB {
+	uint32 AID;
+#if PACKETVER >= 20171207
+	uint32 GID;
+#endif
+	char playerName[NAME_LENGTH];
+	char mapName[MAP_NAME_LENGTH_EXT];
+	uint8 leader;
+	uint8 offline;
+#if PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO)
+	int16 class_;
+	int16 baseLevel;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_GROUP_LIST {
+	int16 packetType;
+	int16 packetLen;
+	char partyName[NAME_LENGTH];
+	struct PACKET_ZC_GROUP_LIST_SUB members[];
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20130626 || PACKETVER_RE_NUM >= 20130605 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_CLANINFO {
+	int16 PacketType;
+	int16 PacketLength;
+	uint32 ClanID;
+	char ClanName[NAME_LENGTH];
+	char MasterName[NAME_LENGTH];
+	char Map[MAP_NAME_LENGTH_EXT];
+	uint8 AllyCount;
+	uint8 AntagonistCount;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_CLANINFO, 0x098a);
+#endif
+
+struct PACKET_ZC_NOTIFY_CLAN_CONNECTINFO {
+	int16 PacketType;
+	int16 NumConnect;
+	int16 NumTotal;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_CLAN_LEAVE {
+	int16 PacketType;
+} __attribute__((packed));
+
+struct PACKET_ZC_NOTIFY_CLAN_CHAT {
+	int16 PacketType;
+	int16 PacketLength;
+	char MemberName[NAME_LENGTH];
+	char Message[];
+} __attribute__((packed));
+
+/**
+ * PACKET_ZC_MISSION_HUNT (PACKETVER < 20150513)
+ * PACKET_ZC_MISSION_HUNT_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_hunt_sub {
+#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017
+	uint32 huntIdent;
+	uint32 huntIdent2;
+	uint32 mobType;
+#elif PACKETVER >= 20150513
+	uint32 huntIdent;
+	uint32 mobType;
+#endif
+	uint32 mob_id;
+#if PACKETVER >= 20150513
+	int16 levelMin;
+	int16 levelMax;
+#endif
+	int16 huntCount;
+	char mobName[NAME_LENGTH];
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_ZC_ADD_QUEST (PACKETVER < 20150513)
+ * PACKET_ZC_ADD_QUEST_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_add_header {
+	uint16 PacketType;
+	uint32 questID;
+	uint8 active;
+	int32 quest_svrTime;
+	int32 quest_endTime;
+	int16 count;
+	struct packet_quest_hunt_sub objectives[];
+} __attribute__((packed));
+
+/**
+ * PACKET_MOB_HUNTING (PACKETVER < 20150513)
+ * PACKET_MOB_HUNTING_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_update_hunt {
+	uint32 questID;
+#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017
+	uint32 huntIdent;
+	uint32 huntIdent2;
+#elif PACKETVER >= 20150513
+	uint32 huntIdent;
+#else
+	uint32 mob_id;
+#endif // PACKETVER < 20150513
+	int16 maxCount;
+	int16 count;
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_ZC_UPDATE_MISSION_HUNT (PACKETVER < 20150513)
+ * PACKET_ZC_UPDATE_MISSION_HUNT_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_update_header {
+	uint16 PacketType;
+	uint16 PacketLength;
+	int16 count;
+	struct packet_quest_update_hunt objectives[];
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_MOB_HUNTING (PACKETVER >= 20150513)
+ */
+struct packet_quest_hunt_info_sub {
+	uint32 questID;
+	uint32 mob_id;
+	int16 maxCount;
+	int16 count;
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * ZC_HUNTING_QUEST_INFO (PACKETVER >= 20150513)
+ */
+struct packet_quest_hunt_info {
+	uint16 PacketType;
+	uint16 PacketLength;
+	struct packet_quest_hunt_info_sub info[];
+} __attribute__((packed));
+
+struct PACKET_ZC_FORMATSTRING_MSG {
+	uint16 PacketType;
+	uint16 PacketLength;
+	uint16 MessageId;
+	char MessageString[];
+} __attribute__((packed));
+
+struct PACKET_ZC_FORMATSTRING_MSG_COLOR {
+	uint16 PacketType;
+	uint16 PacketLength;
+	uint16 messageId;
+#if PACKETVER >= 20160406
+	uint32 color;
+#endif
+	char messageString[];
+} __attribute__((packed));
+
+struct PACKET_ZC_MSG_COLOR {
+	uint16 PacketType;
+	uint16 MessageId;
+	uint32 MessageColor;
+} __attribute__((packed));
+
+struct PACKET_CZ_OPEN_UI {
+	int16 PacketType;
+	int8 UIType;
+} __attribute__((packed));
+
+struct PACKET_ZC_OPEN_UI {
+	int16 PacketType;
+	int8 UIType;
+#if PACKETVER >= 20171122
+	int32 data;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_UI_ACTION {
+	int16 PacketType;
+	int32 UIType;
+	int32 data;
+} __attribute__((packed));
+
+struct PACKET_CZ_PRIVATE_AIRSHIP_REQUEST {
+	int16 PacketType;
+	char mapName[MAP_NAME_LENGTH_EXT];
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ItemID;
+#else
+	uint16 ItemID;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_PRIVATE_AIRSHIP_RESPONSE {
+	int16 PacketType;
+	uint32 flag;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_STYLE_CHANGE {
+	int16 PacketType;
+	int16 HeadPalette;
+	int16 HeadStyle;
+	int16 BodyPalette;
+	int16 TopAccessory;
+	int16 MidAccessory;
+	int16 BottomAccessory;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_STYLE_CHANGE2 {
+	int16 PacketType;
+	int16 HeadPalette;
+	int16 HeadStyle;
+	int16 BodyPalette;
+	int16 TopAccessory;
+	int16 MidAccessory;
+	int16 BottomAccessory;
+	int16 BodyStyle;
+} __attribute__((packed));
+
+struct PACKET_ZC_STYLE_CHANGE_RES {
+	int16 PacketType;
+	int8 flag;
+} __attribute__((packed));
+
+struct pet_evolution_items {
+	int16 index;
+	int16 amount;
+} __attribute__((packed));
+
+struct PACKET_CZ_PET_EVOLUTION {
+	int16 PacketType;
+	uint16 PacketLength;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 EvolvedPetEggID;
+#else
+	uint16 EvolvedPetEggID;
+#endif
+	// struct pet_evolution_items items[];
+} __attribute__((packed));
+
+struct packet_ZC_REFUSE_LOGIN {
+	int16 PacketType;
+#if PACKETVER >= 20101123
+	uint32 error_code;
+#else
+	uint8 error_code;
+#endif
+	char block_date[20];
+} __attribute__((packed));
+
+struct PACKET_ZC_NOTIFY_CHAT {
+	int16 PacketType;
+	int16 PacketLength;
+	uint32 GID;
+	char Message[];
+} __attribute__((packed));
+
+struct PACKET_ZC_NOTIFY_PLAYERCHAT {
+	int16 PacketType;
+	int16 PacketLength;
+	char Message[];
+} __attribute__((packed));
+
+struct PACKET_ZC_ITEM_ENTRY {
+	int16 packetType;
+	uint32 AID;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 identify;
+	uint16 x;
+	uint16 y;
+	uint16 amount;
+	uint8 subX;
+	uint8 subY;
+} __attribute__((packed));
+
+struct PACKET_ZC_ADD_ITEM_TO_STORE {
+	int16 packetType;
+	int16 index;
+	int32 amount;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+#if PACKETVER >= 5
+	uint8 itemType;
+#endif
+	uint8 identified;
+	uint8 damaged;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_MVP_GETTING_ITEM {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_TOUSESKILL {
+	int16 packetType;
+	uint16 skillId;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	int32 btype;
+	uint32 itemId;
+#else
+	int16 btype;
+	uint16 itemId;
+#endif
+	uint8 flag;
+	uint8 cause;
+} __attribute__((packed));
+
+struct PACKET_ZC_ADD_ITEM_TO_CART {
+	int16 packetType;
+	int16 index;
+	int32 amount;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+#if PACKETVER >= 5
+	uint8 itemType;
+#endif
+	uint8 identified;
+	uint8 damaged;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_REQMAKINGITEM {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+	uint32 material[3];
+#else
+	uint16 itemId;
+	uint16 material[3];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_REQMAKINGITEM {
+	int16 packetType;
+	int16 result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_FEED_PET {
+	int16 packetType;
+	uint8 result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_FEED_MER {
+	int16 packetType;
+	uint8 result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_USE_ITEM_ACK {
+	int16 packetType;
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+	uint32 AID;
+#elif PACKETVER >= 3
+	uint16 itemId;
+	uint32 AID;
+#endif
+	int16 amount;
+	uint8 result;
+} __attribute__((packed));
+
+struct PACKET_ZC_SPRITE_CHANGE {
+	int16 packetType;
+	uint32 AID;
+	uint8 type;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 val;
+	uint32 val2;
+#elif PACKETVER >= 4
+	uint16 val;
+	uint16 val2;
+#else
+	uint8 val;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ADD_EXCHANGE_ITEM {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+	uint8 itemType;
+	int32 amount;
+#elif PACKETVER >= 20100223
+	uint16 itemId;
+	uint8 itemType;
+	int32 amount;
+#else
+	int32 amount;
+	uint16 itemId;
+#endif
+	uint8 identified;
+	uint8 damaged;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_CASH_TIME_COUNTER {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 seconds;
+} __attribute__((packed));
+
+struct PACKET_ZC_CASH_ITEM_DELETE {
+	int16 packetType;
+	uint16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ITEM_PICKUP_PARTY {
+	int16 packetType;
+	uint32 AID;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 identified;
+	uint8 damaged;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+	uint16 location;
+	uint8 itemType;
+} __attribute__((packed));
+
+struct PACKET_ZC_UPDATE_ITEM_FROM_BUYING_STORE {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint16 amount;
+#if PACKETVER >= 20141016
+	uint32 zeny;
+	uint32 zenyLimit;
+	uint32 charId;
+	uint32 updateTime;
+#else
+	uint32 zenyLimit;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_WEAPONREFINE {
+	int16 packetType;
+	int32 result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20190619 || PACKETVER_RE_NUM >= 20190605 || PACKETVER_ZERO_NUM >= 20190626
+// PACKET_ZC_PROPERTY_HOMUN3
+struct PACKET_ZC_PROPERTY_HOMUN {
+	int16 packetType;
+	char name[NAME_LENGTH];
+	// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
+	uint8 flags;
+	uint16 level;
+	uint16 hunger;
+	uint16 intimacy;
+	uint16 atk2;
+	uint16 matk;
+	uint16 hit;
+	uint16 crit;
+	uint16 def;
+	uint16 mdef;
+	uint16 flee;
+	uint16 amotion;
+	uint32 hp;
+	uint32 maxHp;
+	uint16 sp;
+	uint16 maxSp;
+	uint32 exp;
+	uint32 expNext;
+	uint16 skillPoints;
+	uint16 range;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PROPERTY_HOMUN, 0x0b2f);
+#elif PACKETVER_MAIN_NUM >= 20131230 || PACKETVER_RE_NUM >= 20131230 || defined(PACKETVER_ZERO)
+// PACKET_ZC_PROPERTY_HOMUN2
+struct PACKET_ZC_PROPERTY_HOMUN {
+	int16 packetType;
+	char name[NAME_LENGTH];
+	// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
+	uint8 flags;
+	uint16 level;
+	uint16 hunger;
+	uint16 intimacy;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint16 atk2;
+	uint16 matk;
+	uint16 hit;
+	uint16 crit;
+	uint16 def;
+	uint16 mdef;
+	uint16 flee;
+	uint16 amotion;
+	uint32 hp;
+	uint32 maxHp;
+	uint16 sp;
+	uint16 maxSp;
+	uint32 exp;
+	uint32 expNext;
+	uint16 skillPoints;
+	uint16 range;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PROPERTY_HOMUN, 0x09f7);
+#elif PACKETVER_MAIN_NUM >= 20101005 || PACKETVER_RE_NUM >= 20080827 || defined(PACKETVER_ZERO)
+// PACKET_ZC_PROPERTY_HOMUN1
+struct PACKET_ZC_PROPERTY_HOMUN {
+	int16 packetType;
+	char name[NAME_LENGTH];
+	// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
+	uint8 flags;
+	uint16 level;
+	uint16 hunger;
+	uint16 intimacy;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint16 atk2;
+	uint16 matk;
+	uint16 hit;
+	uint16 crit;
+	uint16 def;
+	uint16 mdef;
+	uint16 flee;
+	uint16 amotion;
+	uint16 hp;
+	uint16 maxHp;
+	uint16 sp;
+	uint16 maxSp;
+	uint32 exp;
+	uint32 expNext;
+	uint16 skillPoints;
+	uint16 range;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PROPERTY_HOMUN, 0x022e);
+#endif
+
+struct PACKET_ZC_FAILED_TRADE_BUYING_STORE_TO_SELLER {
+	int16 packetType;
+	uint16 result;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_ITEMREPAIR {
+	int16 packetType;
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_MAKINGITEM {
+	int16 packetType;
+	int16 type;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_SSILIST_ITEM_CLICK {
+	int16 packetType;
+	uint32 AID;
+	uint32 storeId;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_SCHEDULER_CASHITEM_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 price;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_SCHEDULER_CASHITEM {
+	int16 packetType;
+	int16 packetLength;
+	int16 count;
+	int16 tabNum;
+	struct PACKET_ZC_ACK_SCHEDULER_CASHITEM_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_PURCHASE_MYITEMLIST_sub {
+	uint32 price;
+	int16 index;
+	int16 amount;
+	uint8 itemType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 identified;
+	uint8 damaged;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_PURCHASE_MYITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+	struct PACKET_ZC_PC_PURCHASE_MYITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub {
+	uint32 price;
+	uint32 discountPrice;
+	uint8 itemType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_PURCHASE_ITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_CZ_PC_PURCHASE_ITEMLIST_sub {
+	uint16 amount;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_PC_PURCHASE_ITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_CZ_PC_PURCHASE_ITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint16 amount;
+	uint32 price;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_OPEN_BUYING_STORE {
+	int16 packetType;
+	int16 packetLength;
+	uint32 zenyLimit;
+	uint8 result;
+	char storeName[MESSAGE_SIZE];
+	struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_MYITEMLIST_BUYING_STORE_sub {
+	uint32 price;
+	uint16 amount;
+	uint8 itemType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_MYITEMLIST_BUYING_STORE {
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+	uint32 zenyLimit;
+	struct PACKET_ZC_MYITEMLIST_BUYING_STORE_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_PURCHASE_ITEMLIST_FROMMC_sub {
+	uint32 price;
+	uint16 amount;
+	int16 index;
+	uint8 itemType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 identified;
+	uint8 damaged;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+// [4144] date 20160921 not confirmed. Can be bigger or smaller
+#if PACKETVER >= 20160921
+	uint32 location;
+	uint16 viewSprite;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_PURCHASE_ITEMLIST_FROMMC {
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+#if PACKETVER >= 20100105
+	uint32 venderId;
+#endif
+	struct PACKET_ZC_PC_PURCHASE_ITEMLIST_FROMMC_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_ITEMLIST_BUYING_STORE_sub {
+	uint32 price;
+	uint16 amount;
+	uint8 itemType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_ITEMLIST_BUYING_STORE {
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+	uint32 storeId;
+	uint32 zenyLimit;
+	struct PACKET_ZC_ACK_ITEMLIST_BUYING_STORE_sub items[];
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub {
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint16 amount;
+} __attribute__((packed));
+
+struct PACKET_CZ_REQ_TRADE_BUYING_STORE {
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+	uint32 storeId;
+	struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_MAKABLEITEMLIST_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+	uint32 material[3];
+#else
+	uint16 itemId;
+	uint16 material[3];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_MAKABLEITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_MAKABLEITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_MAKINGARROW_LIST_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_MAKINGARROW_LIST {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_MAKINGARROW_LIST_sub items[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_MAKINGARROW_LIST, 0x01ad);
+
+struct PACKET_ZC_REPAIRITEMLIST_sub {
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 refine;  // unused?
+	struct EQUIPSLOTINFO slot;  // unused?
+} __attribute__((packed));
+
+struct PACKET_ZC_REPAIRITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_REPAIRITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_NOTIFY_WEAPONITEMLIST_sub {
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 refine;  // unused?
+	struct EQUIPSLOTINFO slot;  // unused?
+} __attribute__((packed));
+
+struct PACKET_ZC_NOTIFY_WEAPONITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_NOTIFY_WEAPONITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_ZC_MAKINGITEM_LIST_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_MAKINGITEM_LIST {
+	int16 packetType;
+	int16 packetLength;
+	uint16 makeItem;
+	struct PACKET_ZC_MAKINGITEM_LIST_sub items[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_MAKINGITEM_LIST, 0x025a);
+
+struct PACKET_ZC_PC_CASH_POINT_ITEMLIST_sub {
+	uint32 price;
+	uint32 discountPrice;
+	uint8 itemType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_PC_CASH_POINT_ITEMLIST {
+	int16 packetType;
+	int16 packetLength;
+	uint32 cashPoints;
+#if PACKETVER >= 20070711
+	uint32 kafraPoints;
+#endif
+	struct PACKET_ZC_PC_CASH_POINT_ITEMLIST_sub items[];
+} __attribute__((packed));
+
+struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub {
+	uint16 amount;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM {
+	int16 packetType;
+#if PACKETVER >= 20101116
+	int16 packetLength;
+	uint32 kafraPoints;
+	uint16 count;
+	struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub items[];
+#else
+	uint16 itemId;
+	uint16 amount;
+#if PACKETVER >= 20070711
+	uint32 kafraPoints;
+#endif
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_SEARCH_STORE_INFO_item {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+} __attribute__((packed));
+
+struct PACKET_CZ_SEARCH_STORE_INFO {
+	int16 packetType;
+	int16 packetLength;
+	uint8 searchType;
+	uint32 maxPrice;
+	uint32 minPrice;
+	uint8 itemsCount;
+	uint8 cardsCount;
+	struct PACKET_CZ_SEARCH_STORE_INFO_item items[];  // items[itemCount]
+/*
+	struct PACKET_CZ_SEARCH_STORE_INFO_item cards[cardCount];
+*/
+} __attribute__((packed));
+
+struct PACKET_ZC_SEARCH_STORE_INFO_ACK_sub {
+	uint32 storeId;
+	uint32 AID;
+	char shopName[MESSAGE_SIZE];
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint8 itemType;
+	uint32 price;
+	uint16 amount;
+	uint8 refine;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20150226
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_SEARCH_STORE_INFO_ACK {
+	int16 packetType;
+	int16 packetLength;
+	uint8 firstPage;
+	uint8 nextPage;
+	uint8 usesCount;
+	struct PACKET_ZC_SEARCH_STORE_INFO_ACK_sub items[];
+} __attribute__((packed));
+
+/* Achievement System */
+struct ach_list_info {
+	uint32 ach_id;
+	uint8 completed;
+	uint32 objective[MAX_ACHIEVEMENT_OBJECTIVES];
+	uint32 completed_at;
+	uint8 reward;
+} __attribute__((packed));
+
+struct packet_achievement_list {
+	uint16 packet_id;
+	uint16 packet_len;
+	uint32 total_achievements;
+	uint32 total_points;
+	uint16 rank;
+	uint32 current_rank_points;
+	uint32 next_rank_points;
+	struct ach_list_info ach[MAX_ACHIEVEMENT_DB];
+} __attribute__((packed));
+
+struct packet_achievement_update {
+	uint16 packet_id;
+	uint32 total_points;
+	uint16 rank;
+	uint32 current_rank_points;
+	uint32 next_rank_points;
+	struct ach_list_info ach;
+} __attribute__((packed));
+
+struct packet_achievement_reward_ack {
+	uint16 packet_id;
+	uint8 failed;
+	uint32 ach_id;
+} __attribute__((packed));
+
+// Name Packet ZC_ACK_REQNAME
+struct packet_reqname_ack {
+	uint16 packet_id;
+	int32 gid;
+	char name[NAME_LENGTH];
+} __attribute__((packed));
+
+// ZC_ACK_REQNAMEALL / ZC_ACK_REQNAMEALL2
+#if PACKETVER_MAIN_NUM >= 20150225 || PACKETVER_RE_NUM >= 20141126 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_ACK_REQNAMEALL {
+	uint16 packet_id;
+	int32 gid;
+	char name[NAME_LENGTH];
+	char party_name[NAME_LENGTH];
+	char guild_name[NAME_LENGTH];
+	char position_name[NAME_LENGTH];
+	int32 title_id;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_REQNAMEALL, 0x0a30);
+#else
+struct PACKET_ZC_ACK_REQNAMEALL {
+	uint16 packet_id;
+	int32 gid;
+	char name[NAME_LENGTH];
+	char party_name[NAME_LENGTH];
+	char guild_name[NAME_LENGTH];
+	char position_name[NAME_LENGTH];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_REQNAMEALL, 0x0195);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20180207 || PACKETVER_RE_NUM >= 20171129 || PACKETVER_ZERO_NUM >= 20171130
+struct PACKET_ZC_ACK_REQNAME_TITLE {
+	uint16 packet_id;
+	int32 gid;
+	int32 groupId;
+	char name[NAME_LENGTH];
+	char title[NAME_LENGTH];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_REQNAME_TITLE, 0x0adf);
+#else
+struct PACKET_ZC_ACK_REQNAME_TITLE {
+	uint16 packet_id;
+	int32 gid;
+	char name[NAME_LENGTH];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_REQNAME_TITLE, 0x0095);
+#endif
+
+struct PACKET_ZC_OVERWEIGHT_PERCENT {
+	int16 packetType;
+	uint32 percent;
+} __attribute__((packed));
+
+struct PACKET_ZC_WARPLIST_sub {
+	char map[MAP_NAME_LENGTH_EXT];
+} __attribute__((packed));
+
+struct PACKET_ZC_WARPLIST {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20170502 || PACKETVER_RE_NUM >= 20170419 || defined(PACKETVER_ZERO)
+	int16 packetLength;
+	uint16 skillId;
+	struct PACKET_ZC_WARPLIST_sub maps[];
+#else
+	uint16 skillId;
+	struct PACKET_ZC_WARPLIST_sub maps[4];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_GROUP_ISALIVE {
+	int16 packetType;
+	uint32 AID;
+	uint8 isDead;
+} __attribute__((packed));
+
+struct PACKET_ZC_GUILD_POSITION {
+	int16 packetType;
+	int16 packetLength;
+	uint32 AID;
+	char position[];
+} __attribute__((packed));
+
+struct PACKET_ZC_INVENTORY_MOVE_FAILED {
+	int16 packetType;
+	int16 index;
+	int16 unknown;
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO)
+#define PACKET_ZC_ACK_BAN_GUILD PACKET_ZC_ACK_BAN_GUILD3
+#elif PACKETVER >= 20100803
+#define PACKET_ZC_ACK_BAN_GUILD PACKET_ZC_ACK_BAN_GUILD2
+#else
+#define PACKET_ZC_ACK_BAN_GUILD PACKET_ZC_ACK_BAN_GUILD1
+#endif
+
+struct PACKET_ZC_ACK_BAN_GUILD1 {
+	int16 packetType;
+	char name[NAME_LENGTH];
+	char reason[40];
+	char account_name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_BAN_GUILD2 {
+	int16 packetType;
+	char name[NAME_LENGTH];
+	char reason[40];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_BAN_GUILD3 {
+	int16 packetType;
+	char reason[40];
+	uint32 GID;
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO)
+#define PACKET_ZC_ACK_LEAVE_GUILD PACKET_ZC_ACK_LEAVE_GUILD2
+#else
+#define PACKET_ZC_ACK_LEAVE_GUILD PACKET_ZC_ACK_LEAVE_GUILD1
+#endif
+
+struct PACKET_ZC_ACK_LEAVE_GUILD1 {
+	int16 packetType;
+	char name[NAME_LENGTH];
+	char reason[40];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_LEAVE_GUILD2 {
+	int16 packetType;
+	uint32 GID;
+	char reason[40];
+} __attribute__((packed));
+
+struct PACKET_CZ_MEMORIALDUNGEON_COMMAND {
+	int16 packetType;
+	int32 command;
+} __attribute__((packed));
+
+struct PACKET_ZC_REMOVE_EFFECT {
+	int16 packetType;
+	uint32 aid;
+	uint32 effectId;
+} __attribute__((packed));
+
+#if PACKETVER >= 20160525
+struct PACKET_ZC_CAMERA_INFO {
+	int16 packetType;
+	int8 action;
+	float range;
+	float rotation;
+	float latitude;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_CAMERA_INFO, 0x0a78);
+#endif
+
+#if PACKETVER >= 20160525
+struct PACKET_CZ_CAMERA_INFO {
+	int16 packetType;
+	int8 action;
+	float range;
+	float rotation;
+	float latitude;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_CAMERA_INFO, 0x0a77);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181128 || PACKETVER_RE_NUM >= 20181031
+// PACKET_ZC_AUTOSPELLLIST2
+struct PACKET_ZC_AUTOSPELLLIST {
+	int16 packetType;
+	int16 packetLength;
+	int skills[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_AUTOSPELLLIST, 0x0afb);
+#elif PACKETVER_MAIN_NUM >= 20090406 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO) || PACKETVER_SAK_NUM >= 20080618
+// PACKET_ZC_AUTOSPELLLIST1
+struct PACKET_ZC_AUTOSPELLLIST {
+	int16 packetType;
+	int skills[7];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_AUTOSPELLLIST, 0x01cd);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+#if 0 && (PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 || PACKETVER_ZERO_NUM >= 20181024 )
+struct PACKET_ZC_ITEM_PREVIEW {
+	int16 packetType;
+	int16 index;
+	int8 isDamaged;
+	int16 refiningLevel;
+	struct EQUIPSLOTINFO slot;
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ITEM_PREVIEW, 0x0b13);
+#else  // PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 || PACKETVER_ZERO_NUM >= 20181024
+
+struct PACKET_ZC_ITEM_PREVIEW {
+	int16 packetType;
+	int16 index;
+	int16 refiningLevel;
+	struct EQUIPSLOTINFO slot;
+	struct ItemOptions option_data[MAX_ITEM_OPTIONS];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ITEM_PREVIEW, 0x0ab9);
+#endif  // PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 || PACKETVER_ZERO_NUM >= 20181024
+#endif  // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+
+#if PACKETVER_MAIN_NUM >= 20160831 || PACKETVER_RE_NUM >= 20151118 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_ENCHANT_EQUIPMENT {
+	int16 packetType;
+	int16 wearState;
+	int16 cardSlot;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	int32 itemId;
+#else
+	int16 itemId;
+#endif
+	int8 equipFlag;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ENCHANT_EQUIPMENT, 0x0a3f);
+#endif  // PACKETVER_MAIN_NUM >= 20160831 || PACKETVER_RE_NUM >= 20151118 || defined(PACKETVER_ZERO)
+
+#if PACKETVER_MAIN_NUM >= 20170830 || PACKETVER_RE_NUM >= 20170830 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_SERVICE_MESSAGE_COLOR {
+	int16 packetType;
+	int16 packetLength;
+	int32 color;
+	char message[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SERVICE_MESSAGE_COLOR, 0x0adb);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 || PACKETVER_ZERO_NUM >= 20181010
+struct PACKET_CZ_START_USE_SKILL {
+	int16 packetType;
+	int16 skillId;
+	int16 skillLv;
+	uint32 targetId;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_START_USE_SKILL, 0x0b10);
+
+struct PACKET_CZ_STOP_USE_SKILL {
+	int16 packetType;
+	int16 skillId;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_STOP_USE_SKILL, 0x0b11);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
+struct PACKET_ZC_INVENTORY_EXPANSION_INFO {
+	int16 packetType;
+	int16 expansionSize;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_INVENTORY_EXPANSION_INFO, 0x0b18);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
+struct PACKET_ZC_ACK_INVENTORY_EXPAND {
+	int16 packetType;
+	uint8 result;
+	uint32 itemId;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_INVENTORY_EXPAND, 0x0b15);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
+struct PACKET_ZC_ACK_INVENTORY_EXPAND_RESULT {
+	int16 packetType;
+	uint8 result;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_INVENTORY_EXPAND_RESULT, 0x0b17);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
+struct PACKET_CZ_INVENTORY_EXPAND {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_INVENTORY_EXPAND, 0x0b14);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
+struct PACKET_CZ_INVENTORY_EXPAND_CONFIRMED {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_INVENTORY_EXPAND_CONFIRMED, 0x0b16);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
+struct PACKET_CZ_INVENTORY_EXPAND_REJECTED {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_INVENTORY_EXPAND_REJECTED, 0x0b19);
+#endif
+
+struct PACKET_CZ_REQ_REMAINTIME {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_REQ_REMAINTIME, 0x01c0);
+
+struct PACKET_CZ_PARTY_CONFIG {
+	int16 packetType;
+	uint8 refuseInvite;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_PARTY_CONFIG, 0x02c8);
+
+#if PACKETVER_MAIN_NUM >= 20190116 || PACKETVER_RE_NUM >= 20190116 || PACKETVER_ZERO_NUM >= 20181226
+struct PACKET_ZC_NPC_BARTER_OPEN_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 nameid;
+#else
+	uint16 nameid;
+#endif
+	uint8 type;
+	uint32 amount;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 currencyNameid;
+#else
+	uint16 currencyNameid;
+#endif
+	uint32 currencyAmount;
+	uint32 weight;
+	uint32 index;
+} __attribute__((packed));
+
+struct PACKET_ZC_NPC_BARTER_OPEN {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_ZC_NPC_BARTER_OPEN_sub list[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_NPC_BARTER_OPEN, 0x0b0e);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190116 || PACKETVER_RE_NUM >= 20190116 || PACKETVER_ZERO_NUM >= 20181226
+struct PACKET_CZ_NPC_BARTER_CLOSE {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_NPC_BARTER_CLOSE, 0x0b12);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190116 || PACKETVER_RE_NUM >= 20190116 || PACKETVER_ZERO_NUM >= 20181226
+struct PACKET_CZ_NPC_BARTER_PURCHASE_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 amount;
+	uint16 invIndex;
+	uint32 shopIndex;
+} __attribute__((packed));
+
+struct PACKET_CZ_NPC_BARTER_PURCHASE {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_CZ_NPC_BARTER_PURCHASE_sub list[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_NPC_BARTER_PURCHASE, 0x0b0f);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20181212 || PACKETVER_RE_NUM >= 20181212 ||  PACKETVER_ZERO_NUM >= 20190130
+struct PACKET_ZC_USESKILL_ACK {
+	int16 packetType;
+	uint32 srcId;
+	uint32 dstId;
+	uint16 x;
+	uint16 y;
+	uint16 skillId;
+	uint32 element;
+	uint32 delayTime;
+	uint8 disposable;
+	uint32 unknown;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_USESKILL_ACK, 0x0b1a);
+#elif PACKETVER_MAIN_NUM >= 20091124 || PACKETVER_RE_NUM >= 20091124 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_USESKILL_ACK {
+	int16 packetType;
+	uint32 srcId;
+	uint32 dstId;
+	uint16 x;
+	uint16 y;
+	uint16 skillId;
+	uint32 element;
+	uint32 delayTime;
+	uint8 disposable;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_USESKILL_ACK, 0x07fb);
+#elif PACKETVER_MAIN_NUM >= 20090406 || PACKETVER_SAK_NUM >= 20080618 || PACKETVER_RE_NUM >= 20080827 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_USESKILL_ACK {
+	int16 packetType;
+	uint32 srcId;
+	uint32 dstId;
+	uint16 x;
+	uint16 y;
+	uint16 skillId;
+	uint32 element;
+	uint32 delayTime;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_USESKILL_ACK, 0x013e);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20090406 || PACKETVER_RE_NUM >= 20090408 || PACKETVER_SAK_NUM >= 20090408 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_CLIENT_VERSION {
+	int16 packetType;
+	uint32 clientVersion;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_CLIENT_VERSION, 0x044a);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190227 || PACKETVER_RE_NUM >= 20190220 || PACKETVER_ZERO_NUM >= 20190220
+struct PACKET_CZ_PING {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_PING, 0x0b1c);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190227 || PACKETVER_RE_NUM >= 20190220 || PACKETVER_ZERO_NUM >= 20190220
+struct PACKET_ZC_PING {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PING, 0x0b1d);
+#endif
+
+#if PACKETVER >= 20160622
+struct PACKET_CZ_COOLDOWN_RESET {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_COOLDOWN_RESET, 0x0a88);
+#endif
+
+#if PACKETVER >= 20151104
+struct PACKET_CZ_STYLE_CLOSE {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_STYLE_CLOSE, 0x0a48);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190403 || PACKETVER_RE_NUM >= 20190320 || PACKETVER_ZERO_NUM >= 20190410
+struct PACKET_ZC_LOAD_CONFIRM {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_LOAD_CONFIRM, 0x0b1b);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20070911 || defined(PACKETVER_RE) || PACKETVER_AD_NUM >= 20070911 || PACKETVER_SAK_NUM >= 20070904 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_PARTY_CONFIG {
+	int16 packetType;
+	uint8 denyPartyInvites;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PARTY_CONFIG, 0x02c9);
+#endif
+
+struct PACKET_ZC_ROLE_CHANGE {
+	int16 packetType;
+	int32 flag;
+	char name[NAME_LENGTH];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ROLE_CHANGE, 0x00e1);
+
+#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_BAN_LIST_sub {
+	int char_id;
+	char message[40];
+} __attribute__((packed));
+
+struct PACKET_ZC_BAN_LIST {
+	int16 packetType;
+	uint16 packetLen;
+	struct PACKET_ZC_BAN_LIST_sub chars[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_BAN_LIST, 0x0a87);
+// version unconfirmed
+#elif PACKETVER >= 20100803
+struct PACKET_ZC_BAN_LIST_sub {
+	char char_name[NAME_LENGTH];
+	char message[40];
+} __attribute__((packed));
+
+struct PACKET_ZC_BAN_LIST {
+	int16 packetType;
+	uint16 packetLen;
+	struct PACKET_ZC_BAN_LIST_sub chars[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_BAN_LIST, 0x0163);
+#else
+struct PACKET_ZC_BAN_LIST_sub {
+	char char_name[NAME_LENGTH];
+	char account_name[NAME_LENGTH];
+	char message[40];
+} __attribute__((packed));
+
+struct PACKET_ZC_BAN_LIST {
+	int16 packetType;
+	uint16 packetLen;
+	struct PACKET_ZC_BAN_LIST_sub chars[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_BAN_LIST, 0x0163);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20141008 || PACKETVER_RE_NUM >= 20140903 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_ACK_CLOSE_ROULETTE {
+	int16 packetType;
+	uint8 result;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_CLOSE_ROULETTE, 0x0a1e);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_ACK_MERGE_ITEM {
+	int16 packetType;
+	int16 index;
+	int16 amount;
+	uint8 reason;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_MERGE_ITEM, 0x096f);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_MERGE_ITEM_OPEN_sub {
+	int16 index;
+} __attribute__((packed));
+
+struct PACKET_ZC_MERGE_ITEM_OPEN {
+	int16 packetType;
+	uint16 packetLen;
+	struct PACKET_ZC_MERGE_ITEM_OPEN_sub items[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_MERGE_ITEM_OPEN, 0x096d);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20101123 || PACKETVER_RE_NUM >= 20120328 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT {
+	int16 packetType;
+	uint32 itemId;  // unused
+	uint16 result;
+	uint32 cashPoints;
+	uint32 kafraPoints;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SE_PC_BUY_CASHITEM_RESULT, 0x0849);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20161130 || PACKETVER_RE_NUM >= 20161109 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_REFINE_OPEN_WINDOW {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_REFINE_OPEN_WINDOW, 0x0aa0);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20161005 || PACKETVER_RE_NUM >= 20161005 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_REFINE_ADD_ITEM {
+	int16 packetType;
+	int16 index;
+};
+DEFINE_PACKET_HEADER(CZ_REFINE_ADD_ITEM, 0x0aa1);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20161130 || PACKETVER_RE_NUM >= 20161109 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_REFINE_ADD_ITEM_SUB {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	int8 chance;
+	int32 zeny;
+} __attribute__((packed));
+
+struct PACKET_ZC_REFINE_ADD_ITEM {
+	int16 packetType;
+	int16 packtLength;
+	int16 itemIndex;
+	int8 blacksmithBlessing;
+	struct PACKET_ZC_REFINE_ADD_ITEM_SUB req[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_REFINE_ADD_ITEM, 0x0aa2);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20161005 || PACKETVER_RE_NUM >= 20161005 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_REFINE_ITEM_REQUEST {
+	int16 packetType;
+	int16 index;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	int8 blacksmithBlessing;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_REFINE_ITEM_REQUEST, 0x0aa3);
+
+struct PACKET_CZ_REFINE_WINDOW_CLOSE {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_REFINE_WINDOW_CLOSE, 0x0aa4);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20170906 || PACKETVER_RE_NUM >= 20170830 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_REFINE_STATUS {
+	int16 packetType;
+	char name[NAME_LENGTH];
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	int8 refine_level;
+	int8 status;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_REFINE_STATUS, 0x0ada);
+#endif
+
+struct PACKET_ZC_ACK_RANKING_name {
+	char name[NAME_LENGTH];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_RANKING_points {
+	uint32 points;
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724
+struct PACKET_ZC_ACK_RANKING_sub {
+	char name[NAME_LENGTH];
+	uint32 points;
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_RANKING {
+	int16 packetType;
+	int16 rankType;
+	uint32 chars[10];
+	uint32 points[10];
+	uint32 myPoints;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_ACK_RANKING, 0x0af6);
+#elif PACKETVER_MAIN_NUM >= 20130605 || PACKETVER_RE_NUM >= 20130529 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_ACK_RANKING_sub {
+	struct PACKET_ZC_ACK_RANKING_name names[10];
+	struct PACKET_ZC_ACK_RANKING_points points[10];
+} __attribute__((packed));
+
+struct PACKET_ZC_ACK_RANKING {
+	int16 packetType;
+	int16 rankType;
+	struct PACKET_ZC_ACK_RANKING_sub ranks;
+	uint32 myPoints;
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_ACK_RANKING, 0x097d);
+#else
+struct PACKET_ZC_ACK_RANKING_sub {
+	struct PACKET_ZC_ACK_RANKING_name names[10];
+	struct PACKET_ZC_ACK_RANKING_points points[10];
+} __attribute__((packed));
+#endif
+
+struct PACKET_ZC_STATUS_CHANGE_ACK {
+	int16 packetType;
+	uint16 sp;
+	uint8 ok;
+	uint8 value;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_STATUS_CHANGE_ACK, 0x00bc);
+
+#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_HAT_EFFECT {
+	int16 packetType;
+	int16 packetLength;
+	uint32 aid;
+	int8 status;
+	uint16 effects[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_HAT_EFFECT, 0x0a3b);
+#endif
+
+// [4144] this struct updated not in all packets in client
+#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918
+struct SKILLDATA {
+	uint16 id;
+	int inf;
+	uint16 level;
+	uint16 sp;
+	uint16 range2;
+	uint8 upFlag;
+	uint16 level2;
+} __attribute__((packed));
+#else
+struct SKILLDATA {
+	uint16 id;
+	int inf;
+	uint16 level;
+	uint16 sp;
+	uint16 range2;
+	char name[NAME_LENGTH];
+	uint8 upFlag;
+} __attribute__((packed));
+#endif
+
+struct PACKET_ZC_ADD_SKILL {
+	int16 packetType;
+	struct SKILLDATA skill;
+} __attribute__((packed));
+#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918
+DEFINE_PACKET_HEADER(ZC_ADD_SKILL, 0x0b31);
+#else
+DEFINE_PACKET_HEADER(ZC_ADD_SKILL, 0x0111);
+#endif
+
+struct PACKET_ZC_SKILLINFO_LIST {
+	int16 packetType;
+	int16 packetLength;
+	struct SKILLDATA skills[];
+} __attribute__((packed));
+#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918
+DEFINE_PACKET_HEADER(ZC_SKILLINFO_LIST, 0x0b32);
+#else
+DEFINE_PACKET_HEADER(ZC_SKILLINFO_LIST, 0x010f);
+#endif
+
+#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918
+struct PACKET_ZC_SKILLINFO_UPDATE2 {
+	int16 packetType;
+	uint16 id;
+	int inf;
+	uint16 level;
+	uint16 sp;
+	uint16 range2;
+	uint8 upFlag;
+	uint16 level2;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SKILLINFO_UPDATE2, 0x0b33);
+#else
+struct PACKET_ZC_SKILLINFO_UPDATE2 {
+	int16 packetType;
+	uint16 id;
+	int inf;
+	uint16 level;
+	uint16 sp;
+	uint16 range2;
+	uint8 upFlag;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SKILLINFO_UPDATE2, 0x07e1);
+#endif
+
+struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 ITID;
+#else
+	uint16 ITID;
+#endif
+	uint16 qty;
+	uint32 price;
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20190807 || PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814
+struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT {
+	int16 PacketType;
+	int16 PacketLength;
+	uint16 result;
+	struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT_sub list[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_NPC_MARKET_PURCHASE_RESULT, 0x0b4e);
+#elif PACKETVER_MAIN_NUM >= 20131120 || PACKETVER_RE_NUM >= 20130911 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT {
+	int16 PacketType;
+	int16 PacketLength;
+	uint8 result;
+	struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT_sub list[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_NPC_MARKET_PURCHASE_RESULT, 0x09d7);
+#endif
+
+struct PACKET_ZC_TALKBOX_CHATCONTENTS {
+	int16 PacketType;
+	uint32 aid;
+	char message[TALKBOX_MESSAGE_SIZE];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_TALKBOX_CHATCONTENTS, 0x0191);
+
+#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814
+struct PACKET_ZC_GUILD_CASTLE_LIST {
+	int16 packetType;
+	int16 packetLength;
+	int8 castle_list[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_GUILD_CASTLE_LIST, 0x0b27);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515
+struct PACKET_CZ_CASTLE_TELEPORT_REQUEST {
+	int16 packetType;
+	int8 castle_id;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_CASTLE_TELEPORT_REQUEST, 0x0b28);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814
+struct PACKET_ZC_CASTLE_TELEPORT_RESPONSE {
+	int16 packetType;
+	int16 result;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_CASTLE_TELEPORT_RESPONSE, 0x0b2e);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814
+struct PACKET_ZC_CASTLE_INFO {
+	int16 packetType;
+	int8 castle_id;
+	int32 economy;
+	int32 defense;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_CASTLE_INFO, 0x0b2d);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515
+struct PACKET_CZ_CASTLE_INFO_REQUEST {
+	int16 packetType;
+	int8 castle_id;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_CASTLE_INFO_REQUEST, 0x0b2c);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_LAPINEDDUKDDAK_OPEN {
+	int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	int32 itemId;
+#else
+	int16 itemId;
+#endif
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_LAPINEDDUKDDAK_OPEN, 0x0a4e);
+#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
+
+#if PACKETVER_MAIN_NUM >= 20160504 || PACKETVER_RE_NUM >= 20160504 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_LAPINEDDUKDDAK_CLOSE {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_LAPINEDDUKDDAK_CLOSE, 0x0a70);
+#endif // PACKETVER_MAIN_NUM >= 20160504 || PACKETVER_RE_NUM >= 20160504 || defined(PACKETVER_ZERO)
+
+#if PACKETVER >= 20160302
+struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub {
+	int16 index;
+	int16 count;
+} __attribute__((packed));
+
+struct PACKET_CZ_LAPINEDDUKDDAK_ACK {
+	int16 packetType;
+	int16 packetLength;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	int32 itemId;
+#else
+	int16 itemId;
+#endif
+	struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub items[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_LAPINEDDUKDDAK_ACK, 0x0a4f);
+#endif // PACKETVER >= 20160302
+
+#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_LAPINEDDUKDDAK_RESULT {
+	int16 packetType;
+	int16 result;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_LAPINEDDUKDDAK_RESULT, 0x0a50);
+#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
+
+#if PACKETVER_MAIN_NUM >= 20190703 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190709
+struct PACKET_CZ_REQ_MOUNTOFF {
+	int16 packetType;
+	uint8 action;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_REQ_MOUNTOFF, 0x0b35);
+#endif
+
+// in 3 clients from same version
+#if PACKETVER >= 20191127
+struct PACKET_ZC_NOTIFY_EFFECT3 {
+	int16 packetType;
+	uint32 aid;
+	uint32 effectId;
+	uint64 num;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_NOTIFY_EFFECT3, 0x0b69);
+#elif PACKETVER_MAIN_NUM >= 20060911 || PACKETVER_AD_NUM >= 20060911 || PACKETVER_SAK_NUM >= 20060911 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO)
+struct PACKET_ZC_NOTIFY_EFFECT3 {
+	int16 packetType;
+	uint32 aid;
+	uint32 effectId;
+	uint32 num;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_NOTIFY_EFFECT3, 0x0284);
+#endif
+
+#if PACKETVER >= 20100824
+struct PACKET_CZ_SE_CASHSHOP_OPEN1 {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SE_CASHSHOP_OPEN1, 0x0844);
+#endif
+
+#if PACKETVER >= 20191224
+struct PACKET_CZ_SE_CASHSHOP_OPEN2 {
+	int16 packetType;
+	uint32 tab;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SE_CASHSHOP_OPEN2, 0x0b6d);
+#endif
+
+#if PACKETVER >= 20190724
+struct PACKET_CZ_SE_CASHSHOP_LIMITED_REQ {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SE_CASHSHOP_LIMITED_REQ, 0x0b4c);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20200129 || PACKETVER_RE_NUM >= 20200205 || PACKETVER_ZERO_NUM >= 20191224
+struct PACKET_ZC_SE_CASHSHOP_OPEN {
+	int16 packetType;
+	uint32 cashPoints;
+	uint32 kafraPoints;
+	uint32 tab;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SE_CASHSHOP_OPEN, 0x0b6e);
+// for ragexeRE in some version this packet unused [4144]
+#elif PACKETVER_MAIN_NUM >= 20101123 || PACKETVER_RE_NUM >= 20120328 || PACKETVER_ZERO_NUM >= defined(PACKETVER_ZERO)
+struct PACKET_ZC_SE_CASHSHOP_OPEN {
+	int16 packetType;
+	uint32 cashPoints;
+	uint32 kafraPoints;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SE_CASHSHOP_OPEN, 0x0845);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
+struct PACKET_CZ_NPC_EXPANDED_BARTER_CLOSE {
+	int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_CLOSE, 0x0b58);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127
+struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 nameid;
+#else
+	uint16 nameid;
+#endif
+	uint16 refine_level;
+	uint32 amount;
+	uint16 type;
+} __attribute__((packed));
+
+struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 nameid;
+#else
+	uint16 nameid;
+#endif
+	uint16 type;
+	uint32 amount;
+	uint32 weight;
+	uint32 index;
+	uint32 zeny;
+	uint32 currency_count;
+#if defined(_MSC_VER)
+	// Workaround for fix Visual Studio bug (error C2233). Here should be currencies[]
+	struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 currencies[1];
+#else
+	struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 currencies[];
+#endif
+} __attribute__((packed));
+
+struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN {
+	int16 packetType;
+	int16 packetLength;
+	int32 items_count;
+	struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub items[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_NPC_EXPANDED_BARTER_OPEN, 0x0b56);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
+struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+	uint32 itemId;
+#else
+	uint16 itemId;
+#endif
+	uint32 shopIndex;
+	uint32 amount;
+} __attribute__((packed));
+
+struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE {
+	int16 packetType;
+	int16 packetLength;
+	struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub list[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_PURCHASE, 0x0b57);
+#endif
+
+#if PACKETVER >= 7
+struct PACKET_ZC_STATE_CHANGE {
+	int16 packetType;
+	uint32 AID;
+	int16 bodyState;
+	int16 healthState;
+	int32 effectState;
+	int8 isPKModeON;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_STATE_CHANGE, 0x0229);
+#else
+struct PACKET_ZC_STATE_CHANGE {
+	int16 PacketType;
+	uint32 AID;
+	int16 bodyState;
+	int16 healthState;
+	int16 effectState;
+	int8 isPKModeON;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_STATE_CHANGE, 0x0119);
+#endif
+
+struct PACKET_ZC_AUTORUN_SKILL {
+	int16 packetType;
+	uint16 skill_id;
+	uint32 skill_type;
+	uint16 skill_lv;
+	uint16 skill_sp;
+	uint16 skill_range;
+	char skill_name[NAME_LENGTH];
+	char up_flag;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_AUTORUN_SKILL, 0x0147);
+
+#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
+
+#endif /* MAP_PACKETS_STRUCT_HPP */

+ 20 - 7
src/map/pc.cpp

@@ -800,12 +800,12 @@ void pc_inventory_rentals(struct map_session_data *sd)
 		if( sd->inventory.u.items_inventory[i].expire_time <= time(NULL) ) {
 			if (sd->inventory_data[i]->unequip_script)
 				run_script(sd->inventory_data[i]->unequip_script, 0, sd->bl.id, fake_nd->bl.id);
-			clif_rental_expired(sd->fd, i, sd->inventory.u.items_inventory[i].nameid);
+			clif_rental_expired(sd, i, sd->inventory.u.items_inventory[i].nameid);
 			pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
 		} else {
 			unsigned int expire_tick = (unsigned int)(sd->inventory.u.items_inventory[i].expire_time - time(NULL));
 
-			clif_rental_time(sd->fd, sd->inventory.u.items_inventory[i].nameid, (int)expire_tick);
+			clif_rental_time(sd, sd->inventory.u.items_inventory[i].nameid, (int)expire_tick);
 			next_tick = umin(expire_tick * 1000U, next_tick);
 			c++;
 		}
@@ -1539,6 +1539,11 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
 	sd->respawn_tid = INVALID_TIMER;
 	sd->tid_queue_active = INVALID_TIMER;
 
+	sd->skill_keep_using.tid = INVALID_TIMER;
+	sd->skill_keep_using.skill_id = 0;
+	sd->skill_keep_using.level = 0;
+	sd->skill_keep_using.target = 0;
+
 #ifdef SECURE_NPCTIMEOUT
 	// Initialize to defaults/expected
 	sd->npc_idle_timer = INVALID_TIMER;
@@ -5055,11 +5060,11 @@ enum e_additem_result pc_additem(struct map_session_data *sd,struct item *item,i
 	/* rental item check */
 	if( item->expire_time ) {
 		if( time(NULL) > item->expire_time ) {
-			clif_rental_expired(sd->fd, i, sd->inventory.u.items_inventory[i].nameid);
+			clif_rental_expired(sd, i, sd->inventory.u.items_inventory[i].nameid);
 			pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 1, 0, LOG_TYPE_OTHER);
 		} else {
 			unsigned int seconds = (unsigned int)( item->expire_time - time(NULL) );
-			clif_rental_time(sd->fd, sd->inventory.u.items_inventory[i].nameid, seconds);
+			clif_rental_time(sd, sd->inventory.u.items_inventory[i].nameid, seconds);
 			pc_inventory_rental_add(sd, seconds);
 		}
 	}
@@ -5567,7 +5572,7 @@ enum e_additem_result pc_cart_additem(struct map_session_data *sd,struct item *i
 			return ADDITEM_OVERAMOUNT; // no slot
 
 		sd->cart.u.items_cart[i].amount += amount;
-		clif_cart_additem(sd,i,amount,0);
+		clif_cart_additem(sd,i,amount);
 	}
 	else
 	{// item not stackable or not present, add it
@@ -5579,7 +5584,7 @@ enum e_additem_result pc_cart_additem(struct map_session_data *sd,struct item *i
 		sd->cart.u.items_cart[i].id = 0;
 		sd->cart.u.items_cart[i].amount = amount;
 		sd->cart_num++;
-		clif_cart_additem(sd,i,amount,0);
+		clif_cart_additem(sd,i,amount);
 	}
 	sd->cart.u.items_cart[i].favorite = 0; // clear
 	sd->cart.u.items_cart[i].equipSwitch = 0;
@@ -5688,7 +5693,7 @@ void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
 	else {
 		clif_cart_delitem(sd, idx, amount);
 		clif_additem(sd, idx, amount, flag);
-		clif_cart_additem(sd, idx, amount, 0);
+		clif_cart_additem(sd, idx, amount);
 	}
 }
 
@@ -9509,6 +9514,10 @@ void pc_setoption(struct map_session_data *sd,int type)
 					status_change_end(&sd->bl,statuses[i],INVALID_TIMER);
 			}
 			pc_bonus_script_clear(sd,BSF_REM_ON_MADOGEAR);
+
+#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106
+			clif_status_load( &sd->bl, EFST_MADOGEAR, 1 );
+#endif
 		} else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) {
 			status_calc_pc(sd,SCO_NONE);
 			status_change_end(&sd->bl,SC_SHAPESHIFT,INVALID_TIMER);
@@ -9520,6 +9529,10 @@ void pc_setoption(struct map_session_data *sd,int type)
 			status_change_end(&sd->bl,SC_NEUTRALBARRIER_MASTER,INVALID_TIMER);
 			status_change_end(&sd->bl,SC_STEALTHFIELD_MASTER,INVALID_TIMER);
 			pc_bonus_script_clear(sd,BSF_REM_ON_MADOGEAR);
+
+#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106
+			clif_status_load( &sd->bl, EFST_MADOGEAR, 0 );
+#endif
 		}
 	}
 

+ 7 - 0
src/map/pc.hpp

@@ -769,6 +769,13 @@ struct map_session_data {
 	uint32* hatEffectIDs;
 	uint8 hatEffectCount;
 #endif
+
+	struct{
+		int tid;
+		uint16 skill_id;
+		uint16 level;
+		int target;
+	} skill_keep_using;
 };
 
 extern struct eri *pc_sc_display_ers; /// Player's SC display table

+ 5 - 5
src/map/searchstore.cpp

@@ -138,7 +138,7 @@ bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned s
  * @param cardlist : list with stored cards (cards attached to items)
  * @param card_count : amount of items in cardlist
  */
-void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count)
+void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist, unsigned int item_count, const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist, unsigned int card_count)
 {
 	unsigned int i;
 	struct map_session_data* pl_sd;
@@ -172,15 +172,15 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 
 	// validate lists
 	for( i = 0; i < item_count; i++ ) {
-		if( !itemdb_exists(itemlist[i]) ) {
-			ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
+		if( !itemdb_exists(itemlist[i].itemId) ) {
+			ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i].itemId);
 			clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
 			return;
 		}
 	}
 	for( i = 0; i < card_count; i++ ) {
-		if( !itemdb_exists(cardlist[i]) ) {
-			ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
+		if( !itemdb_exists(cardlist[i].itemId) ) {
+			ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i].itemId);
 			clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
 			return;
 		}

+ 4 - 3
src/map/searchstore.hpp

@@ -7,6 +7,7 @@
 #include "../common/cbasetypes.hpp"
 #include "../common/mmo.hpp"
 
+#include "clif.hpp"
 #include "map.hpp"
 
 #define SEARCHSTORE_RESULTS_PER_PAGE 10
@@ -14,8 +15,8 @@
 /// information about the search being performed
 struct s_search_store_search {
 	struct map_session_data* search_sd;  // sd of the searching player
-	const unsigned short* itemlist;
-	const unsigned short* cardlist;
+	const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist;
+	const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist;
 	unsigned int item_count;
 	unsigned int card_count;
 	unsigned int min_price;
@@ -46,7 +47,7 @@ struct s_search_store_info {
 };
 
 bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect);
-void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count);
+void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist, unsigned int item_count, const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist, unsigned int card_count);
 bool searchstore_querynext(struct map_session_data* sd);
 void searchstore_next(struct map_session_data* sd);
 void searchstore_clear(struct map_session_data* sd);

+ 20 - 6
src/map/skill.cpp

@@ -11733,6 +11733,16 @@ static int8 skill_castend_id_check(struct block_list *src, struct block_list *ta
 	return -1;
 }
 
+TIMER_FUNC( skill_keep_using ){
+	struct map_session_data* sd = map_id2sd( id );
+
+	if( sd && sd->skill_keep_using.skill_id ){
+		clif_parse_skill_toid( sd, sd->skill_keep_using.skill_id, sd->skill_keep_using.level, sd->skill_keep_using.target );
+	}
+
+	return 0;
+}
+
 /**
  * Check & process skill to target on castend. Determines if skill is 'damage' or 'nodamage'
  * @param tid
@@ -11959,6 +11969,10 @@ TIMER_FUNC(skill_castend_id){
 		else
 			skill_castend_damage_id(src,target,ud->skill_id,ud->skill_lv,tick,flag);
 
+		if( sd && sd->skill_keep_using.skill_id == ud->skill_id ){
+			sd->skill_keep_using.tid = add_timer( sd->ud.canact_tick + 100, skill_keep_using, sd->bl.id, 0 );
+		}
+
 		sc = status_get_sc(src);
 		if(sc && sc->count) {
 			if (ud->skill_id != RA_CAMOUFLAGE)
@@ -12034,7 +12048,7 @@ TIMER_FUNC(skill_castend_id){
 	//sent in ALL cases, even cases where skill_check_condition fails
 	//which would lead to double 'skill failed' messages u.u [Skotlex]
 	if(sd)
-		sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0;
+		sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = sd->skill_keep_using.skill_id = 0;
 	else if(md)
 		md->skill_idx = -1;
 	return 0;
@@ -16637,7 +16651,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
 			else if( require.itemid[i] == ITEMID_ANCILLA )
 				clif_skill_fail(sd,skill_id,USESKILL_FAIL_ANCILLA,0); //Ancilla is required.
 			else
-				clif_skill_fail( sd, skill_id, USESKILL_FAIL_NEED_ITEM, ( require.itemid[i] << 16 ) | require.amount[i] ); // [%s] required '%d' amount.
+				clif_skill_fail( sd, skill_id, USESKILL_FAIL_NEED_ITEM, require.amount[i], require.itemid[i] ); // [%s] required '%d' amount.
 			return false;
 		}
 	}
@@ -17572,11 +17586,11 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
 				return;
 			}
 			if( item->refine >= sd->menuskill_val || item->refine >= 10 ) {
-				clif_upgrademessage(sd->fd, 2, item->nameid);
+				clif_upgrademessage(sd, 2, item->nameid);
 				return;
 			}
 			if( (i = pc_search_inventory(sd, material [ditem->wlv])) < 0 ) {
-				clif_upgrademessage(sd->fd, 3, material[ditem->wlv]);
+				clif_upgrademessage(sd, 3, material[ditem->wlv]);
 				return;
 			}
 			per = status_get_refine_chance(static_cast<refine_type>(ditem->wlv), (int)item->refine, false);
@@ -17596,7 +17610,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
 					pc_unequipitem(sd,idx,3);
 				}
 				clif_delitem(sd,idx,1,3);
-				clif_upgrademessage(sd->fd, 0, item->nameid);
+				clif_upgrademessage(sd, 0, item->nameid);
 				clif_inventorylist(sd);
 				clif_refine(sd->fd,0,idx,item->refine);
 				achievement_update_objective(sd, AG_REFINE_SUCCESS, 2, ditem->wlv, item->refine);
@@ -17623,7 +17637,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
 				item->refine = 0;
 				if(item->equip)
 					pc_unequipitem(sd,idx,3);
-				clif_upgrademessage(sd->fd, 1, item->nameid);
+				clif_upgrademessage(sd, 1, item->nameid);
 				clif_refine(sd->fd,1,idx,item->refine);
 				achievement_update_objective(sd, AG_REFINE_FAIL, 1, 1);
 				pc_delitem(sd,idx,1,0,2, LOG_TYPE_OTHER);

+ 1 - 0
src/map/skill.hpp

@@ -530,6 +530,7 @@ uint16 SKILL_MAX_DB(void);
 int skill_isammotype(struct map_session_data *sd, unsigned short skill_id);
 TIMER_FUNC(skill_castend_id);
 TIMER_FUNC(skill_castend_pos);
+TIMER_FUNC( skill_keep_using );
 int skill_castend_map( struct map_session_data *sd,uint16 skill_id, const char *map);
 
 int skill_cleartimerskill(struct block_list *src);

+ 3 - 2
src/map/storage.cpp

@@ -22,6 +22,7 @@
 #include "itemdb.hpp"
 #include "log.hpp"
 #include "map.hpp" // struct map_session_data
+#include "packets.hpp"
 #include "pc.hpp"
 #include "pc_groups.hpp"
 
@@ -741,8 +742,8 @@ enum e_guild_storage_log storage_guild_log_read_sub( struct map_session_data* sd
 enum e_guild_storage_log storage_guild_log_read( struct map_session_data* sd ){
 	std::vector<struct guild_log_entry> log;
 
-	// ( 65535(maximum packet size) - 8(header) ) / 83 (entry size) = 789 (-1 for safety)
-	enum e_guild_storage_log ret = storage_guild_log_read_sub( sd, log, 788 );
+	// ( maximum packet size - header size ) / entry size ) - 1 (for safety)
+	enum e_guild_storage_log ret = storage_guild_log_read_sub( sd, log, ( ( UINT16_MAX - sizeof( struct PACKET_ZC_ACK_GUILDSTORAGE_LOG ) ) / sizeof( struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub ) ) - 1 );
 
 	clif_guild_storage_log( sd, log, ret );
 

+ 3 - 3
src/map/vending.cpp

@@ -94,7 +94,7 @@ void vending_vendinglistreq(struct map_session_data* sd, int id)
 
 	sd->vended_id = vsd->vender_id;  // register vending uid
 
-	clif_vendinglist(sd, id, vsd->vending);
+	clif_vendinglist( sd, vsd );
 }
 
 /**
@@ -433,7 +433,7 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
 		return true;
 
 	for( idx = 0; idx < s->item_count; idx++ ) {
-		ARR_FIND( 0, sd->vend_num, i, sd->cart.u.items_cart[sd->vending[i].index].nameid == s->itemlist[idx] );
+		ARR_FIND( 0, sd->vend_num, i, sd->cart.u.items_cart[sd->vending[i].index].nameid == s->itemlist[idx].itemId );
 		if( i == sd->vend_num ) { // not found
 			continue;
 		}
@@ -454,7 +454,7 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
 			slot = itemdb_slot(it->nameid);
 
 			for( c = 0; c < slot && it->card[c]; c ++ ) {
-				ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx] == it->card[c] );
+				ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx].itemId == it->card[c] );
 				if( cidx != s->card_count ) { // found
 					break;
 				}

Vissa filer visades inte eftersom för många filer har ändrats