Initial support for 2021-11-03RagexeRE (#6431)

Fixes #6415
This commit is contained in:
Lemongrass3110 2022-01-09 14:03:17 +01:00 committed by GitHub
parent a251c3743c
commit 4bc9e24b4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 476 additions and 114 deletions

View File

@ -177,6 +177,7 @@
<ClInclude Include="int_pet.hpp" />
<ClInclude Include="int_quest.hpp" />
<ClInclude Include="int_storage.hpp" />
<ClInclude Include="packets.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="char.cpp" />

View File

@ -65,6 +65,9 @@
<ClInclude Include="int_clan.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="packets.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="char.cpp">

View File

@ -35,6 +35,7 @@
#include "int_mercenary.hpp"
#include "int_party.hpp"
#include "int_storage.hpp"
#include "packets.hpp"
//definition of exported var declared in header
int login_fd=-1; //login file descriptor
@ -1789,113 +1790,91 @@ int char_count_users(void)
// Writes char data to the buffer in the format used by the client.
// Used in packets 0x6b (chars info) and 0x6d (new char info)
// Returns the size
int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
{
unsigned short offset = 0;
uint8* buf;
int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p){
if( buffer == NULL || p == NULL )
return 0;
buf = WBUFP(buffer,0);
WBUFL(buf,0) = p->char_id;
#if PACKETVER >= 20170830
WBUFQ(buf,4) = u64min(p->base_exp, MAX_EXP);
offset += 4;
buf = WBUFP(buffer, offset);
#else
WBUFL(buf,4) = (int32)u64min(p->base_exp, MAX_EXP);
#endif
WBUFL(buf,8) = p->zeny;
#if PACKETVER >= 20170830
WBUFQ(buf,12) = u64min(p->job_exp, MAX_EXP);
offset += 4;
buf = WBUFP(buffer, offset);
#else
WBUFL(buf,12) = (int32)u64min(p->job_exp, MAX_EXP);
#endif
WBUFL(buf,16) = p->job_level;
WBUFL(buf,20) = 0; // probably opt1
WBUFL(buf,24) = 0; // probably opt2
WBUFL(buf,28) = p->option;
WBUFL(buf,32) = p->karma;
WBUFL(buf,36) = p->manner;
WBUFW(buf,40) = umin(p->status_point, INT16_MAX);
WBUFL(buf,42) = p->hp;
WBUFL(buf,46) = p->max_hp;
offset+=4;
buf = WBUFP(buffer,offset);
WBUFW(buf,46) = min(p->sp, INT16_MAX);
WBUFW(buf,48) = min(p->max_sp, INT16_MAX);
WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed;
WBUFW(buf,52) = p->class_;
WBUFW(buf,54) = p->hair;
struct CHARACTER_INFO* info = (struct CHARACTER_INFO*)buffer;
info->GID = p->char_id;
#if PACKETVER >= 20170830
info->exp = u64min( p->base_exp, MAX_EXP );
#else
info->exp = (int32)u64min( p->base_exp, MAX_EXP );
#endif
info->money = p->zeny;
#if PACKETVER >= 20170830
info->jobexp = u64min( p->job_exp, MAX_EXP );
#else
info->jobexp = (int32)u64min( p->job_exp, MAX_EXP );
#endif
info->joblevel = p->job_level;
info->bodystate = 0; // probably opt1
info->healthstate = 0; // probably opt2
info->effectstate = p->option;
info->virtue = p->karma;
info->honor = p->manner;
info->jobpoint = umin( p->status_point, INT16_MAX );
info->hp = p->hp;
info->maxhp = p->max_hp;
info->sp = min( p->sp, INT16_MAX );
info->maxsp = min( p->max_sp, INT16_MAX );
info->speed = DEFAULT_WALK_SPEED; // p->speed;
info->job = p->class_;
info->head = p->hair;
#if PACKETVER >= 20141022
WBUFW(buf,56) = p->body;
offset+=2;
buf = WBUFP(buffer,offset);
info->body = p->body;
#endif
//When the weapon is sent and your option is riding, the client crashes on login!?
WBUFW(buf,56) = p->option&(0x20|0x80000|0x100000|0x200000|0x400000|0x800000|0x1000000|0x2000000|0x4000000|0x8000000) ? 0 : p->weapon;
WBUFW(buf,58) = p->base_level;
WBUFW(buf,60) = umin(p->skill_point, INT16_MAX);
WBUFW(buf,62) = p->head_bottom;
WBUFW(buf,64) = p->shield;
WBUFW(buf,66) = p->head_top;
WBUFW(buf,68) = p->head_mid;
WBUFW(buf,70) = p->hair_color;
WBUFW(buf,72) = p->clothes_color;
memcpy(WBUFP(buf,74), p->name, NAME_LENGTH);
WBUFB(buf,98) = (unsigned char)u16min(p->str, UINT8_MAX);
WBUFB(buf,99) = (unsigned char)u16min(p->agi, UINT8_MAX);
WBUFB(buf,100) = (unsigned char)u16min(p->vit, UINT8_MAX);
WBUFB(buf,101) = (unsigned char)u16min(p->int_, UINT8_MAX);
WBUFB(buf,102) = (unsigned char)u16min(p->dex, UINT8_MAX);
WBUFB(buf,103) = (unsigned char)u16min(p->luk, UINT8_MAX);
WBUFW(buf,104) = p->slot;
WBUFW(buf,106) = ( p->rename > 0 ) ? 0 : 1;
offset += 2;
info->weapon = p->option&(0x20|0x80000|0x100000|0x200000|0x400000|0x800000|0x1000000|0x2000000|0x4000000|0x8000000) ? 0 : p->weapon;
info->level = p->base_level;
info->sppoint = umin( p->skill_point, INT16_MAX );
info->accessory = p->head_bottom;
info->shield = p->shield;
info->accessory2 = p->head_top;
info->accessory3 = p->head_mid;
info->headpalette = p->hair_color;
info->bodypalette = p->clothes_color;
safestrncpy( info->name, p->name, NAME_LENGTH );
info->Str = (uint8)u16min( p->str, UINT8_MAX );
info->Agi = (uint8)u16min( p->agi, UINT8_MAX );
info->Vit = (uint8)u16min( p->vit, UINT8_MAX );
info->Int = (uint8)u16min( p->int_, UINT8_MAX );
info->Dex = (uint8)u16min( p->dex, UINT8_MAX );
info->Luk = (uint8)u16min( p->luk, UINT8_MAX );
info->CharNum = p->slot;
info->hairColor = (uint8)u16min( p->hair_color, UINT8_MAX );
info->bIsChangedCharName = ( p->rename > 0 ) ? 0 : 1;
#if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803
mapindex_getmapname_ext(mapindex_id2name(p->last_point.map), WBUFCP(buf,108));
offset += MAP_NAME_LENGTH_EXT;
mapindex_getmapname_ext( mapindex_id2name( p->last_point.map ), info->mapName );
#endif
#if PACKETVER >= 20100803
#if PACKETVER_CHAR_DELETEDATE
WBUFL(buf,124) = (p->delete_date?TOL(p->delete_date-time(NULL)):0);
info->DelRevDate = ( p->delete_date ? TOL( p->delete_date - time( NULL ) ) : 0 );
#else
WBUFL(buf,124) = TOL(p->delete_date);
info->DelRevDate = TOL( p->delete_date );
#endif
offset += 4;
#endif
#if PACKETVER >= 20110111
WBUFL(buf,128) = p->robe;
offset += 4;
info->robePalette = p->robe;
#endif
#if PACKETVER != 20111116 //2011-11-16 wants 136, ask gravity.
#if PACKETVER >= 20110928
// change slot feature (0 = disabled, otherwise enabled)
if( (charserv_config.charmove_config.char_move_enabled)==0 )
WBUFL(buf,132) = 0;
else if( charserv_config.charmove_config.char_moves_unlimited )
WBUFL(buf,132) = 1;
else
WBUFL(buf,132) = max( 0, (int)p->character_moves );
offset += 4;
#endif
#if PACKETVER >= 20111025
WBUFL(buf,136) = ( p->rename > 0 ) ? 1 : 0; // (0 = disabled, otherwise displays "Add-Ons" sidebar)
offset += 4;
#endif
#if PACKETVER >= 20141016
WBUFB(buf,140) = p->sex;// sex - (0 = female, 1 = male, 99 = logindefined)
offset += 1;
#endif
#if PACKETVER >= 20110928
// change slot feature (0 = disabled, otherwise enabled)
if( charserv_config.charmove_config.char_move_enabled == 0 )
info->chr_slot_changeCnt = 0;
else if( charserv_config.charmove_config.char_moves_unlimited )
info->chr_slot_changeCnt = 1;
else
info->chr_slot_changeCnt = max( 0, (int)p->character_moves );
#endif
#if PACKETVER >= 20111025
info->chr_name_changeCnt = ( p->rename > 0 ) ? 1 : 0; // (0 = disabled, otherwise displays "Add-Ons" sidebar)
#endif
#if PACKETVER >= 20141016
info->sex = p->sex; // sex - (0 = female, 1 = male, 99 = logindefined)
#endif
return 106+offset;
return sizeof( struct CHARACTER_INFO );
}

View File

@ -12,6 +12,8 @@
#include "../common/timer.hpp"
#include "../config/core.hpp"
#include "packets.hpp"
extern int login_fd; //login file descriptor
extern int char_fd; //char file descriptor
@ -270,7 +272,7 @@ extern struct fame_list chemist_fame_list[MAX_FAME_LIST];
extern struct fame_list taekwon_fame_list[MAX_FAME_LIST];
#define DEFAULT_AUTOSAVE_INTERVAL 300*1000
#define MAX_CHAR_BUF 150 //Max size (for WFIFOHEAD calls)
#define MAX_CHAR_BUF sizeof( struct CHARACTER_INFO ) //Max size (for WFIFOHEAD calls)
int char_search_mapserver(unsigned short map, uint32 ip, uint16 port);
int char_lan_subnetcheck(uint32 ip);

View File

@ -21,6 +21,7 @@
#include "char_logif.hpp"
#include "char_mapif.hpp"
#include "inter.hpp"
#include "packets.hpp"
#if PACKETVER_SUPPORTS_PINCODE
bool pincode_allowed( char* pincode );
@ -34,7 +35,7 @@ bool pincode_allowed( char* pincode );
// 1: failed
void chclif_moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason ){
WFIFOHEAD(fd,8);
WFIFOW(fd,0) = 0x8d5;
WFIFOW(fd,0) = HEADER_HC_ACK_CHANGE_CHARACTER_SLOT;
WFIFOW(fd,2) = 8;
WFIFOW(fd,4) = reason;
WFIFOW(fd,6) = sd->char_moves[index];
@ -374,7 +375,7 @@ void chclif_mmo_send099d(int fd, struct char_session_data *sd) {
uint8 count = 0;
WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF));
WFIFOW(fd,0) = 0x99d;
WFIFOW(fd,0) = HEADER_HC_ACK_CHARINFO_PER_PAGE;
WFIFOW(fd,2) = char_mmo_chars_fromsql(sd, WFIFOP(fd,4), &count) + 4;
WFIFOSET(fd,WFIFOW(fd,2));
@ -382,7 +383,7 @@ void chclif_mmo_send099d(int fd, struct char_session_data *sd) {
// The client triggers some finalization code only if count is != 3.
if( count == 3 ){
WFIFOHEAD(fd,4);
WFIFOW(fd,0) = 0x99d;
WFIFOW(fd,0) = HEADER_HC_ACK_CHARINFO_PER_PAGE;
WFIFOW(fd,2) = 4;
WFIFOSET(fd,4);
}
@ -1050,7 +1051,7 @@ int chclif_parse_createnewchar(int fd, struct char_session_data* sd,int cmd){
// send to player
WFIFOHEAD(fd,2+MAX_CHAR_BUF);
WFIFOW(fd,0) = 0x6d;
WFIFOW(fd,0) = HEADER_HC_ACCEPT_MAKECHAR;
len = 2 + char_mmo_char_tobuf(WFIFOP(fd,2), &char_dat);
WFIFOSET(fd,len);

120
src/char/packets.hpp Normal file
View File

@ -0,0 +1,120 @@
// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#ifndef PACKETS_HPP
#define PACKETS_HPP
#include "../common/mmo.hpp"
#pragma warning( push )
#pragma warning( disable : 4200 )
// 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 CHARACTER_INFO{
uint32 GID;
#if PACKETVER >= 20170830
int64 exp;
#else
int32 exp;
#endif
int32 money;
#if PACKETVER >= 20170830
int64 jobexp;
#else
int32 jobexp;
#endif
int32 joblevel;
int32 bodystate;
int32 healthstate;
int32 effectstate;
int32 virtue;
int32 honor;
int16 jobpoint;
#if PACKETVER_RE_NUM >= 20211103
int64 hp;
int64 maxhp;
int64 sp;
int64 maxsp;
#else
int32 hp;
int32 maxhp;
int16 sp;
int16 maxsp;
#endif
int16 speed;
int16 job;
int16 head;
#if PACKETVER >= 20141022
int16 body;
#endif
int16 weapon;
int16 level;
int16 sppoint;
int16 accessory;
int16 shield;
int16 accessory2;
int16 accessory3;
int16 headpalette;
int16 bodypalette;
char name[24];
uint8 Str;
uint8 Agi;
uint8 Vit;
uint8 Int;
uint8 Dex;
uint8 Luk;
uint8 CharNum;
uint8 hairColor;
int16 bIsChangedCharName;
#if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803
char mapName[16];
#endif
#if PACKETVER >= 20100803
int32 DelRevDate;
#endif
#if PACKETVER >= 20110111
int32 robePalette;
#endif
#if PACKETVER >= 20110928
int32 chr_slot_changeCnt;
#endif
#if PACKETVER >= 20111025
int32 chr_name_changeCnt;
#endif
#if PACKETVER >= 20141016
uint8 sex;
#endif
} __attribute__((packed));
#define DEFINE_PACKET_HEADER(name, id) const int16 HEADER_##name = id;
#if PACKETVER_MAIN_NUM >= 20201007 || PACKETVER_RE_NUM >= 20211103
DEFINE_PACKET_HEADER( HC_ACK_CHANGE_CHARACTER_SLOT, 0xb70 )
#else
DEFINE_PACKET_HEADER( HC_ACK_CHANGE_CHARACTER_SLOT, 0x8d5 )
#endif
#if PACKETVER_MAIN_NUM >= 20201007 || PACKETVER_RE_NUM >= 20211103
DEFINE_PACKET_HEADER( HC_ACK_CHARINFO_PER_PAGE, 0xb72 )
#else
DEFINE_PACKET_HEADER( HC_ACK_CHARINFO_PER_PAGE, 0x99d )
#endif
#if PACKETVER_MAIN_NUM >= 20201007 || PACKETVER_RE_NUM >= 20211103
DEFINE_PACKET_HEADER( HC_ACCEPT_MAKECHAR, 0xb6f )
#else
DEFINE_PACKET_HEADER( HC_ACCEPT_MAKECHAR, 0x6d )
#endif
#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( pop )
#endif
#pragma warning( pop )
#endif /* PACKETS_HPP */

View File

@ -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 20200902
#define PACKETVER 20211103
#endif
#ifndef PACKETVER_RE

View File

@ -1799,8 +1799,13 @@ void clif_hominfo( struct map_session_data *sd, struct homun_data *hd, int flag
p.sp = status->sp;
p.maxSp = status->max_sp;
}
#if PACKETVER_MAIN_NUM >= 20210303 || PACKETVER_RE_NUM >= 20211103
p.exp = hd->homunculus.exp;
p.expNext = hd->exp_next;
#else
p.exp = (uint32)hd->homunculus.exp;
p.expNext = (uint32)hd->exp_next;
#endif
switch( hom_class2type( hd->homunculus.class_ ) ){
case HT_REG:
case HT_EVO:
@ -2175,7 +2180,7 @@ void clif_buylist( struct map_session_data *sd, struct npc_data *nd ){
uint16 len = sizeof( struct PACKET_ZC_PC_PURCHASE_ITEMLIST ) + nd->u.shop.count * sizeof( struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub );
WFIFOHEAD( fd, len );
struct PACKET_ZC_PC_PURCHASE_ITEMLIST *p = (struct PACKET_ZC_PC_PURCHASE_ITEMLIST *)WFIFOP( fd, 0 );
p->packetType = 0xc6;
p->packetType = HEADER_ZC_PC_PURCHASE_ITEMLIST;
int count = 0;
for( int i = 0, discount = npc_shop_discount( nd ); i < nd->u.shop.count; i++ ){
@ -2185,6 +2190,12 @@ void clif_buylist( struct map_session_data *sd, struct npc_data *nd ){
p->items[count].discountPrice = ( discount ) ? pc_modifybuyvalue( sd, val ) : val;
p->items[count].itemType = itemtype( nd->u.shop.shop_item[i].nameid );
p->items[count].itemId = client_nameid( nd->u.shop.shop_item[i].nameid );
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
struct item_data* id = itemdb_exists( nd->u.shop.shop_item[i].nameid );
p->items[count].viewSprite = id->look;
p->items[count].location = pc_equippoint_sub( sd, id );
#endif
count++;
}
@ -2277,6 +2288,9 @@ void clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) {
p->list[count].price = item->value;
p->list[count].qty = item->qty;
p->list[count].weight = id->weight;
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
p->list[count].location = pc_equippoint_sub( sd, id );
#endif
count++;
}
@ -16352,15 +16366,22 @@ void clif_Mail_Receiver_Ack( struct map_session_data* sd, uint32 char_id, short
/// Request information about the recipient
/// 0a13 <name>.24B (CZ_CHECK_RECEIVE_CHARACTER_NAME)
void clif_parse_Mail_Receiver_Check(int fd, struct map_session_data *sd) {
#if PACKETVER >= 20140423
#if PACKETVER_MAIN_NUM >= 20201104 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20201118
struct PACKET_CZ_CHECKNAME2* p = (struct PACKET_CZ_CHECKNAME2*)RFIFOP( fd, 0 );
#else
struct PACKET_CZ_CHECKNAME1* p = (struct PACKET_CZ_CHECKNAME1*)RFIFOP( fd, 0 );
#endif
static char name[NAME_LENGTH];
if( mail_invalid_operation( sd ) ){
return;
}
safestrncpy(name, RFIFOCP(fd, 2), NAME_LENGTH);
safestrncpy(name, p->Name, NAME_LENGTH);
intif_mail_checkreceiver(sd, name);
#endif
}
/// Request to receive mail's attachment.
@ -16518,7 +16539,18 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd){
/// Request to return a mail (CZ_REQ_MAIL_RETURN).
/// 0273 <mail id>.L <receive name>.24B
void clif_parse_Mail_return(int fd, struct map_session_data *sd){
#if PACKETVER_MAIN_NUM >= 20201104 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20201118
struct PACKET_CZ_UNCONFIRMED_RODEX_RETURN* p = (struct PACKET_CZ_UNCONFIRMED_RODEX_RETURN*)RFIFOP( fd, 0 );
//ShowDump( p, sizeof( p ) );
int mail_id = p->msgId;
// not supported for now
return;
#else
int mail_id = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]);
#endif
//char *rec_name = RFIFOP(fd,packet_db[RFIFOW(fd,0)].pos[1]);
int i;
@ -22304,6 +22336,34 @@ void clif_parse_refineui_refine( int fd, struct map_session_data* sd ){
#endif
}
void clif_unequipall_reply( struct map_session_data* sd, bool failed ){
#if PACKETVER_MAIN_NUM >= 20210818 || PACKETVER_RE_NUM >= 20211103
struct PACKET_ZC_TAKEOFF_EQUIP_ALL_ACK p = {};
p.PacketType = HEADER_ZC_TAKEOFF_EQUIP_ALL_ACK;
p.result = failed;
clif_send( &p, sizeof( struct PACKET_ZC_TAKEOFF_EQUIP_ALL_ACK ), &sd->bl, SELF );
#endif // PACKETVER_MAIN_NUM >= 20210818 || PACKETVER_RE_NUM >= 20211103
}
void clif_parse_unequipall( int fd, struct map_session_data* sd ){
#if PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20210818
if( pc_cant_act( sd ) ){
clif_unequipall_reply( sd, true );
return;
}
for( int i = 0; i < EQI_COSTUME_HEAD_TOP; i++ ){
if( sd->equip_index[i] >= 0 ){
pc_unequipitem( sd, sd->equip_index[i], 1 );
}
}
clif_unequipall_reply( sd, false );
#endif
}
/*==========================================
* Main client packet processing function
*------------------------------------------*/

View File

@ -2435,4 +2435,11 @@
parseable_packet( HEADER_CZ_UNCONFIRMED_TSTATUS_UP, sizeof( PACKET_CZ_UNCONFIRMED_TSTATUS_UP ), clif_parse_traitstatus_up, 0 );
#endif
#if PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20210818
parseable_packet( HEADER_CZ_CHECKNAME2, sizeof( struct PACKET_CZ_CHECKNAME2 ), clif_parse_Mail_Receiver_Check, 0 );
parseable_packet( HEADER_CZ_UNCONFIRMED_RODEX_RETURN, sizeof( struct PACKET_CZ_UNCONFIRMED_RODEX_RETURN ), clif_parse_Mail_return, 0 );
parseable_packet( HEADER_CZ_REQ_TAKEOFF_EQUIP_ALL, sizeof( struct PACKET_CZ_REQ_TAKEOFF_EQUIP_ALL ), clif_parse_unequipall, 0 );
parseable_packet( 0xb93, 12, clif_parse_dull, 0 );
#endif
#endif /* CLIF_PACKETDB_HPP */

View File

@ -4741,7 +4741,11 @@
#endif
parseable_packet(0x0368,6,clif_parse_GetCharNameRequest,2);
parseable_packet(0x0369,6,clif_parse_SolveCharName,2);
parseable_packet(0x0436,19,clif_parse_WantToConnection,2,6,10,14,18);
#if PACKETVER_RE_NUM >= 20211103
parseable_packet( 0x0436, 23, clif_parse_WantToConnection, 2, 6, 10, 14, 22 );
#else
parseable_packet( 0x0436, 19, clif_parse_WantToConnection, 2, 6, 10, 14, 18 );
#endif
parseable_packet(0x0437,7,clif_parse_ActionRequest,2,6);
parseable_packet(0x0438,10,clif_parse_UseSkillToId,2,4,6);
parseable_packet(0x07E4,-1,clif_parse_ItemListWindowSelected,2,4,8,12);

View File

@ -217,6 +217,11 @@ struct PACKET_ZC_ENTRY_QUEUE_INIT {
int16 packetType;
} __attribute__((packed));
struct PACKET_CZ_UNCONFIRMED_RODEX_RETURN{
int16 packetType;
uint32 msgId;
} __attribute__((packed));
// 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 )
@ -274,6 +279,7 @@ DEFINE_PACKET_HEADER(ZC_REMOVE_EFFECT, 0x0b0d)
DEFINE_PACKET_HEADER(CZ_UNCONFIRMED_TSTATUS_UP, 0x0b24)
DEFINE_PACKET_HEADER(CZ_GUILD_EMBLEM_CHANGE2, 0x0b46)
DEFINE_PACKET_HEADER(ZC_UNCONFIRMED_SPIRITS3, 0xb73)
DEFINE_PACKET_HEADER(CZ_UNCONFIRMED_RODEX_RETURN, 0xb98)
const int16 MAX_INVENTORY_ITEM_PACKET_NORMAL = ( ( INT16_MAX - ( sizeof( struct packet_itemlist_normal ) - ( sizeof( struct NORMALITEM_INFO ) * MAX_ITEMLIST) ) ) / sizeof( struct NORMALITEM_INFO ) );
const int16 MAX_INVENTORY_ITEM_PACKET_EQUIP = ( ( INT16_MAX - ( sizeof( struct packet_itemlist_equip ) - ( sizeof( struct EQUIPITEM_INFO ) * MAX_ITEMLIST ) ) ) / sizeof( struct EQUIPITEM_INFO ) );

View File

@ -1389,7 +1389,26 @@ struct packet_npc_market_purchase {
struct packet_npc_market_purchase_sub list[];
} __attribute__((packed));
#if PACKETVER_MAIN_NUM >= 20131120 || PACKETVER_RE_NUM >= 20131106 || defined(PACKETVER_ZERO)
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
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;
uint32 location;
} __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, 0x0b7a);
#elif 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
@ -1402,13 +1421,11 @@ struct PACKET_ZC_NPC_MARKET_OPEN_sub {
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
@ -1681,10 +1698,22 @@ struct PACKET_ZC_WRITE_MAIL_RESULT {
int8 result;
} __attribute__((packed));
struct PACKET_CZ_CHECKNAME {
#if PACKETVER >= 20140423
struct PACKET_CZ_CHECKNAME1 {
int16 PacketType;
char Name[24];
} __attribute__((packed));
DEFINE_PACKET_HEADER(CZ_CHECKNAME1, 0x0a13)
#endif // PACKETVER >= 20140423
#if PACKETVER_MAIN_NUM >= 20201104 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20201118
struct PACKET_CZ_CHECKNAME2 {
int16 PacketType;
char Name[24];
char own_char;
} __attribute__((packed));
DEFINE_PACKET_HEADER(CZ_CHECKNAME2, 0x0b97)
#endif // PACKETVER_MAIN_NUM >= 20201104 || PACKETVER_ZERO_NUM >= 20201118
struct PACKET_ZC_CHECKNAME {
int16 PacketType;
@ -2375,7 +2404,63 @@ struct PACKET_ZC_ACK_WEAPONREFINE {
#endif
} __attribute__((packed));
#if PACKETVER_MAIN_NUM >= 20190619 || PACKETVER_RE_NUM >= 20190605 || PACKETVER_ZERO_NUM >= 20190626
#if PACKETVER_MAIN_NUM >= 20210303 || PACKETVER_RE_NUM >= 20211103
// PACKET_ZC_PROPERTY_HOMUN4
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;
uint32 sp;
uint32 maxSp;
int64 exp;
int64 expNext;
uint16 skillPoints;
uint16 range;
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_PROPERTY_HOMUN, 0x0ba4);
#elif PACKETVER_MAIN_NUM >= 20200819 || PACKETVER_RE_NUM >= 20200723
// 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;
uint32 sp;
uint32 maxSp;
uint32 exp;
uint32 expNext;
uint16 skillPoints;
uint16 range;
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_PROPERTY_HOMUN, 0x0b76);
#elif PACKETVER_MAIN_NUM >= 20190619 || PACKETVER_RE_NUM >= 20190605 || PACKETVER_ZERO_NUM >= 20190626
// PACKET_ZC_PROPERTY_HOMUN3
struct PACKET_ZC_PROPERTY_HOMUN {
int16 packetType;
@ -2573,6 +2658,26 @@ struct PACKET_ZC_PC_PURCHASE_MYITEMLIST {
struct PACKET_ZC_PC_PURCHASE_MYITEMLIST_sub items[];
} __attribute__((packed));
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub {
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
uint32 itemId;
#else
uint16 itemId;
#endif
uint32 price;
uint32 discountPrice;
uint8 itemType;
uint16 viewSprite;
uint32 location;
} __attribute__((packed));
struct PACKET_ZC_PC_PURCHASE_ITEMLIST {
int16 packetType;
int16 packetLength;
struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub items[];
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_PC_PURCHASE_ITEMLIST, 0x0b77)
#else // PACKETVER_MAIN_NUM >= 20210203
struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub {
uint32 price;
uint32 discountPrice;
@ -2583,12 +2688,13 @@ struct PACKET_ZC_PC_PURCHASE_ITEMLIST_sub {
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));
DEFINE_PACKET_HEADER(ZC_PC_PURCHASE_ITEMLIST, 0x00c6)
#endif
struct PACKET_CZ_PC_PURCHASE_ITEMLIST_sub {
uint16 amount;
@ -3245,7 +3351,33 @@ struct PACKET_CZ_PARTY_CONFIG {
} __attribute__((packed));
DEFINE_PACKET_HEADER(CZ_PARTY_CONFIG, 0x02c8);
#if PACKETVER_MAIN_NUM >= 20190116 || PACKETVER_RE_NUM >= 20190116 || PACKETVER_ZERO_NUM >= 20181226
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
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;
uint16 viewSprite;
uint32 location;
} __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, 0x0b78);
#elif 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;
@ -3263,13 +3395,11 @@ struct PACKET_ZC_NPC_BARTER_OPEN_sub {
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
@ -3883,7 +4013,45 @@ struct PACKET_CZ_NPC_EXPANDED_BARTER_CLOSE {
DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_CLOSE, 0x0b58);
#endif
#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
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;
uint16 viewSprite;
uint32 location;
uint32 currency_count;
// Workaround: this should be currencies[], but compilers do not support multiple layers of incomplete types. See error C2233
struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 currencies[1];
} __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, 0x0b79);
#elif 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;
@ -3907,12 +4075,8 @@ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub {
uint32 index;
uint32 zeny;
uint32 currency_count;
#if defined(_MSC_VER)
// Workaround for fix Visual Studio bug (error C2233). Here should be currencies[]
// Workaround: this should be currencies[], but compilers do not support multiple layers of incomplete types. See error C2233
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 {
@ -3923,7 +4087,7 @@ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN {
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_NPC_EXPANDED_BARTER_OPEN, 0x0b56);
#endif
#endif // PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127
#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub {
@ -4130,6 +4294,21 @@ struct PACKET_ZC_NOTIFY_SKILL_POSITION {
};
DEFINE_PACKET_HEADER(ZC_NOTIFY_SKILL_POSITION, 0x0115);
#if PACKETVER_MAIN_NUM >= 20210818 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20210818
struct PACKET_CZ_REQ_TAKEOFF_EQUIP_ALL {
int16 PacketType;
} __attribute__((packed));
DEFINE_PACKET_HEADER(CZ_REQ_TAKEOFF_EQUIP_ALL, 0x0bad);
#endif // PACKETVER_MAIN_NUM >= 20210818 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20210818
#if PACKETVER_MAIN_NUM >= 20210818 || PACKETVER_RE_NUM >= 20211103
struct PACKET_ZC_TAKEOFF_EQUIP_ALL_ACK {
int16 PacketType;
uint8 result;
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_TAKEOFF_EQUIP_ALL_ACK, 0x0bae);
#endif // PACKETVER_MAIN_NUM >= 20210818 || PACKETVER_RE_NUM >= 20211103
#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