[1.10+] Client & Server Packets

This forum is for discussions on how to edit what can not be edited through the txt files, needless to say this isn't about battle net hacking.

Moderators: Nefarius, Havvoric

Post Reply
User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

[1.10+] Client & Server Packets

Post by Necrolis » Tue Mar 29, 2016 3:13 pm

Rules
Please note, the only packets that we will allow discussion of related directly to gameplay. That means NOTHING related to BNet, BNChat, BNFtp. We will also not allow ANY discussion of anything related to Warden or exploitation/malicious use of packets.
Rule of thumb: if its not in the D2Game or D2Client packet callback table, you shouldn't post it. If you have a query, PM Kingpin or myself.


Posting Guidelines
  • Although 99% of packets remain the same from 1.09 and up, there have been slight changes and additions over the years. In light of this please post what version you captured the packet from.
  • When you post a packet, be clear as to the size of the packet (including the one byte header) and the packet number (the id stored in the one-byte header).
  • Clearly indicated if the packet is sent from the client to the server(C->S), or the server to the client (S->C). Rule of thumb: if its Processed in D2Game its C->S, if its processed in D2Client its S->C.
  • Be wary of packets that have unions, these can lead to a lot of confusion, clearly indicate the union'ed fields.
  • When describing a packet, include the offset of each member explicitly. This offset should include the one-byte header.
  • Be as descriptive as possible in field naming or provide a description and size if the field is of a fixed length.
  • Certain packets contain bit streams. If possible, include an additional description of the bit stream. Clearly mark optional bit stream members.
  • In the interests of neatness and manageability, Kingpin and myself will maintain this index. This post will serve as the table of contents and include miscellaneous data relating to packets, such as adding new packets. All submitted data will be uniformly formatted and placed into the 2nd and 3rd posts.
Server to Client Packets
  • Coming Soon
Client to Server Packets
  • Coming Soon
Miscellaneous
  • Coming Soon
This topic is currently a work in progress; I shall update it over the coming days. The current packets that will be added to the list are as following (Note: these are all pretty much fully documented, please avoid posting about these till I have added them to the listing. Packets not in the list do need posts to be made):

Code: Select all

	PACKET_CLIENTJOIN		= 0x00,
	PACKET_GAMEDATA			= 0x01,		//S -> C
	PACKET_GAMEREADY		= 0x02,
	PACKET_PLAYERMOVE		= 0x03,		//C -> S
	PACKET_GAMEINIT			= 0x03,		//S -> C
	PACKET_CLIENTSTATUS		= 0x04,
	PACKET_GAMEEND			= 0x05,		//S -> C
	PACKET_DEATHMESSAGE		= 0x06,		//S -> C
	PACKET_INFERNOSTATEOFF	= 0x06,		//C -> S
	PACKET_INITROOM			= 0x07,
	PACKET_REVEALROOM		= 0x08,
	PACKET_DELETEUNIT		= 0x0A,		//S -> C
	PACKET_SETPLAYERLOAD	= 0x0B,
	PACKET_UNUSED_C			= 0x0C,
	PACKET_CASTSKILL		= 0x0C,
	PACKET_UNUSED_E			= 0x0E,
	PACKET_OBJECTSTATE		= 0x0E,
	PACKET_SYSTEMMSG		= 0x0D,
	PACKET_SERVER_CHAT		= 0x0F,
	PACKET_UNUSED_10		= 0x10,		//S -> C
	PACKET_TOGGLESTATEOFF	= 0x11,		//S -> C
	PACKET_UNUSED_12		= 0x12,		//S -> C
	PACKET_MELEEATTACK		= 0x12,		//C -> S
	PACKET_UNITINTERACT		= 0x13,		//C -> S
	PACKET_UNUSED_13		= 0x13,		//S -> C
	PACKET_EMOTE			= 0x14,		//C -> S
	PACKET_UNUSED_14		= 0x14,		//S -> C
	PACKET_CHAT				= 0x15,		//C -> S
	PACKET_UNK_15			= 0x15,		//S -> C
	PACKET_UNK_16			= 0x16,		//S -> C
	PACKET_PICKUPINVITEM	= 0x16,		//C -> S
	PACKET_DROPITEM		= 0x17,		//C -> S
    PACKET_GOLD_8			= 0x19,
    PACKET_EXP_8			= 0x1A,
    PACKET_EXP_16			= 0x1B,
    PACKET_EXP_32			= 0x1C,
    PACKET_STAT_8			= 0x1D,
    PACKET_STAT_16			= 0x1E,
    PACKET_STAT_32			= 0x1F,
    PACKET_STAT_32_PLAY		= 0x20,
	PACKET_USEITEM			= 0x20,
	PACKET_SKILLUPDATE		= 0x21,		//S -> C
	PACKET_SCROLL			= 0x22,		//S -> C
	PACKET_SETACTIVESKILL	= 0x23,		//S -> C
	PACKET_CHAT_RELAY		= 0x26,
	PACKET_USE_BELT_ITEM	= 0x26,
	PACKET_PSPELLTARGET		= 0x27,		//C -> S
	PACKET_SCROLLMESSAGE	= 0x27,		//S -> C
	PACKET_SOCKETITEM		= 0x28,		//C -> S
	PACKET_PLAYERQUESTS		= 0x28,		//S -> C
	PACKET_PLAYERQUESTSEX	= 0x29,
	PACKET_ADD_ITEM_STACK	= 0x29,
	PACKET_FAILDIALOG		= 0x2A,
	PACKET_CLIENTUPDATE		= 0x2C,
	PACKET_NPCUPDATE		= 0x30,
	PACKET_CLOSE_ANVIL		= 0x30,
	PACKET_NPCMESSAGE		= 0x31,		//C -> S
	PACKET_BUY				= 0x32,
	PACKET_SELL				= 0x33,
	PACKET_IDENTIFY			= 0x34,
	PACKET_REPAIRALL		= 0x35,
    PACKET_NPCMSG			= 0x38,		//C -> S
	PACKET_BUYLIFE			= 0x39,
    PACKET_ADDSTAT			= 0x3A,
    PACKET_ADDSKILL			= 0x3B,
	PACKET_SKILLSELECT		= 0x3C,
	PACKET_BARKSCROLL		= 0x3E,		//C -> S
	PACKET_ITEMUPDATE		= 0x3E,		//S -> C
	PACKET_CURSOR			= 0x3F,		//S -> C
	PACKET_RESPAWN			= 0x41,
	PACKET_DELETECURSORITEM = 0x42,		//S -> C
	PACKET_CLOSE_ANVIL_EX	= 0x44,
	PACKET_UPDATEUNIT		= 0x47,
	PACKET_UPDATEEQUIPMENT	= 0x48,		//S -> C
	PACKET_WAYPOINT_CLOSE	= 0x49,
	PACKET_USETMOGITEM		= 0x4C,		//C -> S
	PACKET_UNUSED_4D		= 0x4D,
	PACKET_NPC_SOUND		= 0x4D,
    PACKET_MERCLIST			= 0x4E,		//S -> C
    PACKET_MERCINIT			= 0x4F,		//S -> C
	PACKET_UIDISABLE		= 0x4F,		//C - > S
	PACKET_QUESTLOGEXTRA	= 0x50,
	PACKET_SETHOTKEY		= 0x51,		//C -> S
	PACKET_NEWOBJECT		= 0x51,		//S -> C
	PACKET_QUESTSTATUS		= 0x52,
	PACKET_GAMETIME			= 0x53,		//S -> C
	PACKET_NPCITEMEVENT		= 0x58,
	PACKET_NEWPLAYER		= 0x59,
	PACKET_SERVER_MESSAGE	= 0x5A,
	PACKET_PLAYERJOIN		= 0x5B,
	PACKET_QUESTLOG			= 0x5D,		//S -> C
	PACKET_HOSTILE			= 0x5D,		//C -> S
	PACKET_INIT_QUESTS		= 0x5E,
	PACKET_WAYPOINTSMASK	= 0x5F,		//S -> C
	PACKET_PORTAL			= 0x60,
	PACKET_ACTCHANGE		= 0x61,
	PACKET_REMOVEINTERACT	= 0x62,
	PACKET_WAYPOINT_OPEN	= 0x63,
	PACKET_ARENASCORE		= 0x65,
	PACKET_CREATEGAME		= 0x66,		//C -> S
	PACKET_JOINGAME			= 0x67,		//C -> S
	PACKET_ENDGAME			= 0x68,		//C -> S
	PACKET_UNUSED_69		= 0x69,
	PACKET_JOINLIST			= 0x69,		//C -> S
	PACKET_JOINACT			= 0x6A,		//C -> S
	PACKET_OPENCHAR			= 0x6B,		//C -> S
	PACKET_UNUSED_6D		= 0x6D,
	PACKET_FORCEDISCONNECT	= 0x6D,		//C -> S
	PACKET_CREATEMISSILE	= 0x73,		//S -> C
	PACKET_PLAYERINFO		= 0x75,
	PACKET_FREEHOVER		= 0x76,
	PACKET_PETUPDATE		= 0x7A,		//S -> C
	PACKET_UITOGGLE			= 0x77,
	PACKET_HOTKEY			= 0x7B,		//S -> C
	PACKET_PSPELLFAIL		= 0x7C,		//S -> C
	PACKET_PETADDEXTRA		= 0x81,		//S -> C
	PACKET_TRIGGERFX		= 0x89,
	PACKET_SPEECHBALLOON	= 0x8A,
	PACKET_PARTYLEAVE		= 0x8D,		//S -> C
	PACKET_CORPSE			= 0x8E,		//S -> C
	PACKET_NPCINTRO			= 0x91,
	PACKET_SKILLINFO		= 0x94,
	PACKET_ATTACK			= 0x95,
	PACKET_WEAPONSWAP		= 0x97,		//S -> C
	PACKET_SKILLVSTARGET	= 0x99,		//S -> C
	PACKET_SKILLVSPOS		= 0x9A,		//S -> C
	PACKET_MERCCOST			= 0x9B,		//S -> C
	PACKET_NEWITEM			= 0x9C,
	PACKET_ITEMACTION		= 0x9D,
    PACKET_STAT_8_MON		= 0x9E,
    PACKET_STAT_16_MON		= 0x9F,
    PACKET_STAT_32_MON		= 0xA0,
    PACKET_STAT_8_MON_ADD	= 0xA1,
    PACKET_STAT_16_MON_ADD	= 0xA2,
	PACKET_GFXLOAD			= 0xA4,		//S -> C
	PACKET_ITEMTABLES		= 0xA6,
	PACKET_STATEON			= 0xA7,		//S -> C
	PACKET_STATEUPDATE		= 0xA8,		//S -> C
	PACKET_STATEOFF			= 0xA9,		//S -> C
	PACKET_STATEADD			= 0xAA,		//S -> C
	PACKET_HP_PERCENT		= 0xAB,		//S -> C
	PACKET_NEWMONSTER		= 0xAC,
    PACKET_GAMEOPEN			= 0xAE,
    PACKET_GAMECLOSE		= 0xAF,
	PACKET_JOINLISTITEM		= 0xB1,		//S -> C
    PACKET_SAVEFILE			= 0xB2,
    PACKET_SAVEFILESTATUS	= 0xB3,		//S -> C
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: [1.10+] Client & Server Packets

Post by Necrolis » Tue Mar 29, 2016 3:14 pm

Server to Client Packets
  • Coming Soon
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: [1.10+] Client & Server Packets

Post by Necrolis » Tue Mar 29, 2016 3:24 pm

Client to Server Packets
  • Coming Soon
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: [1.10+] Client & Server Packets

Post by kidpaddle94 » Fri Apr 01, 2016 10:08 pm

1.13c

S>C 0x26 - Received Chat Message

Code: Select all

struct D2GSPacketSrv26		//variable size
{
	BYTE nHeader;			//0x00
	BYTE nMessageType;		//0x01
	BYTE nLang;				//0x02
	BYTE nUnitType;			//0x03
	DWORD dwUnitGUID;		//0x04
	BYTE nMessageColor;		//0x08
	BYTE nNameColor;		//0x09
	char szStrings[502];	//0x0A
};

/*
	Function:		D2GSSRV2CLTPACKET_ChatMessage
	Type:			D2GS
	Header:			Server -> Client 0x26
	Address:		D2Client.0xAF9F0
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_ChatMessage(D2GSPacketSrv26* pPacket)
It usually has one or two strings, one for the name, one for the message. Note that the name string is omitted in some cases. You can retrieve the strings (and check if they exist using strlen), by doing this:

Code: Select all

char* szName = pPacket->szStrings;
char* szMessage = (szName + (strlen(szName) + 1));

Code: Select all

enum D2C_ChatMessageTypes
{
	CHAT_NONE,
	CHAT_PLAYERMESSAGE,
	CHAT_RECEIVEDWHISPER,
	CHAT_UNUSED,
	CHAT_MESSAGE,
	CHAT_EMOTE,
	CHAT_SENTWHISPER,
	CHAT_CLUESCROLL,
};
-------------------------------------------------------------------------------------------------------------

S>C 0x59 - Create Client Player

Code: Select all

struct D2GSPacketSrv59	//size of 0x1A
{
	BYTE nHeader;		//0x00
	DWORD dwGUID;		//0x01
	BYTE nClass;		//0x05
	char szName[16];	//0x06
	WORD nPosX;			//0x16
	WORD nPosY;			//0x18
};

/*
	Function:		D2GSSRV2CLTPACKET_CreateClientPlayer
	Type:			D2GS
	Header:			Server -> Client 0x59
	Address:		D2Client.0xADF20
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_CreateClientPlayer(D2GSPacketSrv59* pPacket)
-------------------------------------------------------------------------------------------------------------

S>C 0x5A - Events

Code: Select all

struct D2GSPacketSrv5A			//size of 0x28
{
	BYTE nHeader;				//0x00
	BYTE nType;					//0x01
	BYTE nColor;				//0x02
	DWORD dwParam;				//0x03
	BYTE nParam;				//0x07
	char szTextData[2][16];		//0x08
};

/*
	Function:		D2GSSRV2CLTPACKET_Events
	Type:			D2GS
	Header:			Server -> Client 0x5A
	Address:		D2Client.0xAD6B0
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_Events(D2GSPacketSrv5A* pPacket)

Code: Select all

enum D2C_5AEventTypes
{
	EVENTTYPE_DROPTIMEOUT,
	EVENTTYPE_DROPERROR,
	EVENTTYPE_PLAYERJOIN,
	EVENTTYPE_PLAYERLEFT,
	EVENTTYPE_NOTINGAME,
	EVENTTYPE_NOTLOGGEDIN,
	EVENTTYPE_SLAIN,
	EVENTTYPE_PVPSTATUS,
	EVENTTYPE_PLAYERISBUSY,
	EVENTTYPE_PLEASEWAIT,
	EVENTTYPE_HASITEMSINBOX,
	EVENTTYPE_UNUSED1,
	EVENTTYPE_UNUSED2,
	EVENTTYPE_NOTLISTENINGTOYOU,
	EVENTTYPE_UNUSED3,
	EVENTTYPE_REALMGOINGDOWN,
	EVENTTYPE_PLEASEWAITHOSTILE,
	EVENTTYPE_JORDANSTONES,
	EVENTTYPE_DIABLOCLONE
};
-------------------------------------------------------------------------------------------------------------

S>C 0x5B - Create Roster Unit

Code: Select all

struct D2GSPacketSrv5B		//variable size
{
	BYTE nHeader;				//0x00
	WORD nPacketLen;			//0x01
	DWORD dwGUID;				//0x03
	BYTE nClass;				//0x07
	char szName[16];			//0x08
	WORD nLevel;				//0x18
	WORD nPartyId;				//0x1A
	WORD __01C;					//0x1C
	WORD nPartyFlags;			//0x1E
	WORD __020;					//0x20
	char szStrings[475];		//0x22
};

/*
	Function:		D2GSSRV2CLTPACKET_CreateRosterUnit
	Type:			D2GS
	Header:			Server -> Client 0x5B
	Address:		D2Client.0xAD8F0
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_CreateRosterUnit(D2GSPacketSrv5B* pPacket)
The strings part of the packet were meant to contain the user's clan tag & clan name, however they're not used by the original game. The server always sends empty strings. Still, the clan tag code is used on the client, so you can use it if you change the server code that sends this packet.

Code: Select all

char* szClanTag = pPacket->szStrings;
char* szClanName = (szClanTag + (strlen(szClanTag) + 1));
-------------------------------------------------------------------------------------------------------------

S>C 0xA7 - State On (expand this to get rid of the state limit)

Code: Select all

struct D2GSPacketSrvA7	//size of 0x07
{
	BYTE nHeader;		//0x00
	BYTE nUnitType;		//0x01
	DWORD dwUnitGUID;	//0x02
	BYTE nState;		//0x06
};

/*
	Function:		D2GSSRV2CLTPACKET_StateOn
	Type:			D2GS
	Header:			Server -> Client 0xA7
	Address:		D2Client.0xADEB0
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_StateOn(D2GSPacketSrvA7* pPacket)
-------------------------------------------------------------------------------------------------------------

S>C 0xA8 - State Update (expand this to get rid of the state limit)

Code: Select all

struct D2GSPacketSrvA8	//Variable Size
{
	BYTE nHeader;			//0x00
	BYTE nUnitType;			//0x01
	DWORD dwUnitGUID;		//0x02
	BYTE nPacketLength;		//0x06
	BYTE nState;			//0x07
	BYTE Stream[500];		//0x08
};

/*
	Function:		D2GSSRV2CLTPACKET_StateUpdate
	Type:			D2GS
	Header:			Server -> Client 0xA8
	Address:		D2Client.0xADD70
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_StateUpdate(D2GSPacketSrvA8* pPacket)
The stream is an array with the following structure. You should read through the array until the stat Id is 0x1FF (terminator)

Code: Select all

[9 bits] Stat Id
[x bits] Stat Layer
[y bits] Stat Value

x = ItemStatCost.txt SendParamBits
y = ItemStatCost.txt SendBits
-------------------------------------------------------------------------------------------------------------

S>C 0xA9 - State Off (expand this to get rid of the state limit)

Code: Select all

struct D2GSPacketSrvA9	//size of 0x07
{
	BYTE nHeader;		//0x00
	BYTE nUnitType;		//0x01
	DWORD dwUnitGUID;	//0x02
	BYTE nState;		//0x06
};

/*
	Function:		D2GSSRV2CLTPACKET_StateOff
	Type:			D2GS
	Header:			Server -> Client 0xA9
	Address:		D2Client.0xADD30
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_StateOff(D2GSPacketSrvA9* pPacket)
-------------------------------------------------------------------------------------------------------------

S>C 0xAA - New Unit States (expand this to get rid of the state limit)

Code: Select all

struct D2GSPacketSrvAA	//variable size
{
	BYTE nHeader;			//0x00
	BYTE nUnitType;			//0x01
	DWORD dwUnitGUID;		//0x02
	BYTE nPacketLength;		//0x06
	BYTE Stream[500];		//0x07
};

/*
	Function:		D2GSSRV2CLTPACKET_StateUpdateAll
	Type:			D2GS
	Header:			Server -> Client 0xAA
	Address:		D2Client.0xADB90
	Notes:			
*/
void __fastcall D2GSSRV2CLTPACKET_StateUpdateAll(D2GSPacketSrvAA* pPacket)
The stream is an array of states and the stats attached to it. Basically, this is a state array, and in every state array, there is a stat array. When reading states array, you should read until you read a state Id of 0xFF (terminator), and when reading stats array, you should read until you read a stat Id of 0x1FF (terminator).

Code: Select all

[8 bits] State Id
[1 bit] boolean that determines if the following stat array exists or not
{
	[9 bits] Stat Id
	[x bits] Stat Layer
	[y bits] Stat Value
}[n];

x = ItemStatCost.txt SendParamBits
y = ItemStatCost.txt SendBits
n = number of stats for this state
Last edited by kidpaddle94 on Thu Aug 31, 2017 9:22 pm, edited 1 time in total.

User avatar
weapon-x
Forum Legend
Arch-Angel
Posts: 1047
Joined: Wed Mar 18, 2009 4:52 am
Location: Mindanao, Philippines
Contact:
Philippines

Re: [1.10+] Client & Server Packets

Post by weapon-x » Fri Apr 22, 2016 8:58 am

i can already see a number of applications for this one :mrgreen:

for example, a slot-machine mini-game ;)

I still haven't grasp the full concept of packets... perhaps there is a packet listener somewhere, :-|

will stay tuned for updates :)
" It's not the size of the dog in the fight, it's the size of the fight in the dog. "

~Mark Twain

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: [1.10+] Client & Server Packets

Post by kidpaddle94 » Fri Apr 22, 2016 7:45 pm

weapon-x" wrote:i can already see a number of applications for this one :mrgreen:
for example, a slot-machine mini-game ;)
I still haven't grasp the full concept of packets... perhaps there is a packet listener somewhere, :-|
will stay tuned for updates :)
on 1.13c

Code: Select all

/*
	Function:		D2GSPACKETS_SendPacketToClient
	Address:		D2Game.0x8A3E0
	Notes:
*/
void __fastcall D2GSPACKETS_SendPacketToClient(D2ClientStrc* pClient, void* pPacket, size_t nSize)

/*
	Function:		D2GSPACKETS_SendPacketToServer
	Address:		D2Client.0x143E0
	Notes:
*/
void __fastcall D2GSPACKETS_SendPacketToServer(void* pPacket, size_t nSize)
As for the actual packet, it really just is structured data sent over a network socket. The process of building up the data to send is quite simple and straightforward in most cases. Some packets have a little more complex build-up and reception process (those that contain variable data in variable sizes, or bunch of different union cases). Here's a simple example of a static packet.

Code: Select all

struct D2GSPacketClt5D		//size of 0x07
{
	BYTE nHeader;			//0x00
	BYTE nType;				//0x01
	BYTE nToggle;			//0x02
	DWORD dwPlayerGUID;		//0x03
};

D2GSPacketClt5D Packet = {};

Packet.nHeader = 0x5D;
Packet.nType = RELATIONSHIP_TYPE_MUTE;
Packet.nToggle = FALSE;
Packet.dwPlayerGUID = ptPlayer->dwGUID;

D2GSPACKETS_SendPacketToServer(&Packet, sizeof(D2GSPacketClt5D));

Emjayen
Posts: 7
Joined: Sun Jun 30, 2013 2:07 pm

Re: [1.10+] Client & Server Packets

Post by Emjayen » Wed Sep 14, 2016 11:23 pm

0xAA's format is slightly different to what's documented: There's a one bit flag after each state-id that determines whether or not a statlist follows (1=statlist exists, 0=no statlist).

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: [1.10+] Client & Server Packets

Post by kidpaddle94 » Wed Sep 14, 2016 11:59 pm

Emjayen" wrote:0xAA's format is slightly different to what's documented: There's a one bit flag after each state-id that determines whether or not a statlist follows (1=statlist exists, 0=no statlist).
Thank you for that, you may just have told me what's causing these synching problems I'm getting since I expanded states limit. Will look into it & update post

User avatar
misiek1294
Junior Member
Paladin
Posts: 168
Joined: Mon Dec 29, 2014 3:58 pm
Poland

Re: [1.10+] Client & Server Packets

Post by misiek1294 » Sun Feb 05, 2017 5:02 pm

Hey guys, some one can share me some info about packet 0x95 and 0x96 ?
Thanks !

User avatar
devurandom
Forum Regular
Angel
Posts: 897
Joined: Sat Mar 07, 2015 9:07 pm
United States of America

Re: [1.10+] Client & Server Packets

Post by devurandom » Sat Oct 14, 2017 3:40 am

misiek1294" wrote:Hey guys, some one can share me some info about packet 0x95 and 0x96 ?
Thanks !
I ran across packet 0x96 trying to track down another packet.
C->S Packet 0x96 is triggered every time you click the screen to move the character, but I haven't looked into it much further than that.

[1.13c]

PacketData

Code: Select all

struct PacketData         //size of 0x208 
{
  int nPacketSize;        //0x00
  BYTE aPacket[512];      //0x04
  PacketData* pNext;      //0x204
};

S>C 0x21 - UpdateSkill

Code: Select all

struct PacketS2C_21       //size 0x0C  - PACKET_SKILLUPDATE
{
   BYTE nHeader;           //0x00
   BYTE nUnitType;         //0x01
   BYTE bDeleteSkill;      //0x02
   int nUnitGUID;          //0x03
   WORD nSkill;            //0x07
   BYTE nSkillLevel;       //0x09
   BYTE nEvalSkill;        //0x0A
   BYTE bIncSkillLvl;      //0x0B
};
S>C 0x2A - FailDialog

Code: Select all

struct PacketS2C_2A       //size of 0x0F  PACKET_FAILDIALOG
{
  BYTE nHeader;           //0x00
  BYTE nTransType;        //0x01
  BYTE nMsgType;          //0x02
  DWORD _03;              //0x03 Doesn't init
  int nItemGUID;          //0x07
  int nStat;              //0x0B
};

S>C 0x5D - Quest Log Button (credits Necrolis)

Code: Select all

struct D2QuestStatusPacketStrc     //sizeof 0x6
{
    BYTE nType;                    //+00
    BYTE nQuest;                   //+01
    BYTE fAlertFlags;              //+02
    BYTE nFilterStatus;            //+03
    WORD nExtra;                   //+04 - quest specific
};
S>C 0x58 - Opens User Interface on Client - UnitInteract

Code: Select all

struct PacketS2C_58       //sizeof 0x07 - UnitInteract 
{
  BYTE nHeader;           //0x00
  int nUnitGUID;          //0x01
  BYTE nUIType;           //0x05
  BYTE _006;              //0x06
};

C>S 0x68 - Join Game Request (credits Lolet)

Code: Select all

struct	PacketC2S_68         // JoinGameRequest 
{
    BYTE nHeader;            // 0x00
    DWORD ServerHash;        // 0x01 also SessionKey - 
    WORD ServerToken;        // 0x05 TicketNo - increases each join.
    BYTE ClassId;            // 0x07
    DWORD VerByte;           // 0x08 (11 for 1.11) etc  0x0D for 1.13
    DWORD Unk1;              // 0x0C FOG_isExpansion_10227() != 0 ? 0xED5DCC50u : 0x2185EDD6u; (const)
    DWORD Unk2;              // 0x10 0x91A519B6 (const)
    BYTE LocaleId;           // 0x14 language
    char szCharName[16];     // 0x15
};
S>C 0xB0 - Game Close

Code: Select all

struct PacketS2C_B0       //size of 0x01  PACKET_GAMECLOSE
{
  BYTE nHeader;           //0x00
};
Last edited by devurandom on Thu Aug 16, 2018 5:51 pm, edited 3 times in total.
Assembly Reference | 1.13d Code Edits | UVLoD | BaseMod Plugin

Fiat paper money is the most elaborate and well devised form of slavery the world has ever seen..

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: [1.10+] Client & Server Packets

Post by kidpaddle94 » Sat Oct 14, 2017 4:46 am

devurandom" wrote:C>S 0x68 - Join Game Request (credits Lolet)

Code: Select all

struct	PacketC2S_68	// JoinGameRequest 
{
	BYTE nHeader;			// 0x00
	DWORD ServerHash;		// 0x01 also SessionKey - 
	WORD ServerToken;		// 0x05 TicketNo - increases each join.
	BYTE ClassId;			// 0x07
	DWORD VerByte;			// 0x08 (11 for 1.11) etc  0x0D for 1.13
	DWORD Unk1;				// 0x0C FOG_isExpansion_10227() != 0 ? 0xED5DCC50u : 0x2185EDD6u; (const)
	DWORD Unk2;				// 0x10 0x91A519B6 (const)
	BYTE LocaleId;			// 0x14 language
	char szCharName[16];	// 0x15
};

There's technically two "join game request" packets. 0x68 is used when creating a closed bnet game only, as far as I know. This is probably really on the grey area line to post this one, but I guess it's no big harm to have it here (not my decision though, let's see what Nec says if he sees it). For SP, TCP/IP and Open Bnet, 0x67 is used:

C>S 0x67 - Join Game Request

Code: Select all

struct D2GSPacketClt67      //size of 0x2E
{
    BYTE nHeader;           //0x00
    char szGameName[16];    //0x01
    BYTE nGameType;         //0x11
    BYTE nClass;            //0x12
    BYTE nTemplate;         //0x13
    BYTE nDifficulty;       //0x14
    char szCharName[16];    //0x15
    WORD __025;             //0x25
    DWORD dwArenaFlags;     //0x27
    BYTE __02B;             //0x2B
    BYTE __02C;             //0x2C
    BYTE nLang;             //0x2D
};
Some of the members I marked as padding are actually being filled by the sending code in D2Client, but as far as I can tell it's never used.

User avatar
devurandom
Forum Regular
Angel
Posts: 897
Joined: Sat Mar 07, 2015 9:07 pm
United States of America

Re: [1.10+] Client & Server Packets

Post by devurandom » Mon Oct 16, 2017 10:42 am

kidpaddle94" wrote: For SP, TCP/IP and Open Bnet, 0x67 is used:
EDIT:
I never verified SP. I assumed it was the same as TCP/IP.
With Breakpoints I hit 0x68 for TCP/IP MP Games, and 0x67 for SP Games.
Cant verify the other 2, because I never use BNET.
;)
Assembly Reference | 1.13d Code Edits | UVLoD | BaseMod Plugin

Fiat paper money is the most elaborate and well devised form of slavery the world has ever seen..

User avatar
cla$$ics
Moderator
Arch-Angel
Posts: 1320
Joined: Wed Aug 15, 2007 3:48 pm
United States of America

Hand-picked

Re: [1.10+] Client & Server Packets

Post by cla$$ics » Thu Mar 01, 2018 1:10 am

All of these are for 1.10, not 1.11+ which is different.

Packet 0x6C C->S
PING packet. Every 5 seconds, the client will send a PING packet to make sure the connection is alive.
The two parameters can be used by the server to estimate client FPS and latency.
To the best of my knowledge, this packet is not sent on singleplayer games.

Structure:
Sizeof = 9
BYTE - 0x6C
DWORD - current ticks (milliseconds)
DWORD - time last PING packet received from server

-------------------------------------

Packet 0x67 C->S
Join a remote game (D2CLTSYS_JOINGAME)

Structure:
sizeof = 28
BYTE - 0x67
DWORD - unknown (usually 0)
WORD - unknown (always 1, otherwise game fails with error code 6, "Unable to join game")
BYTE - unknown (usually 0)
DWORD - version (10 / 0xA0 in 1.10)
BYTE - language (0 = English)
char[16] - character name

-------------------------------------

Packet 0xB3 S->C
Indicate that the chunk of savegame was invalid.

Structure:
sizeof = 2
BYTE - 0xB3
BYTE - error code (see below)

The error code maps to an enum...

Code: Select all

// D2SPACKET_SAVESTATUS return codes
enum D2SaveStatus
{	// default to 9
	SAVESTATUS_0,	// not used?
	SAVESTATUS_1,	// maps to 0
	SAVESTATUS_2,	// maps to 1
	SAVESTATUS_3,	// maps to 2
	SAVESTATUS_4,	// maps to 3
	SAVESTATUS_5,	// maps to 4
	SAVESTATUS_6,	// maps to 5
	SAVESTATUS_7,	// maps to 10
	SAVESTATUS_8,	// maps to 11
	SAVESTATUS_9,	// maps to 12
	SAVESTATUS_10,	// maps to 13
	SAVESTATUS_11,	// maps to 14
	SAVESTATUS_12,	// maps to 15
	SAVESTATUS_13,	// maps to 16
	SAVESTATUS_14,	// maps to 17
	SAVESTATUS_15,	// maps to 18
	SAVESTATUS_16,	// maps to 19
	SAVESTATUS_17,	// maps to 20
	SAVESTATUS_18,	// maps to 21
	SAVESTATUS_19,	// maps to 22
	SAVESTATUS_20,	// maps to 23
	SAVESTATUS_21,	// maps to 24
	SAVESTATUS_22,	// not used?
	SAVESTATUS_23,	// maps to 25
	SAVESTATUS_24,	// maps to 26
	SAVESTATUS_25,	// maps to 27
	SAVESTATUS_26,	// maps to 28
};
...which maps to a table of TBL entries...

Code: Select all

WORD gwaTBLErrorEntries[] = {
		0x14F5,	// Unable to enter game. Bad character version
		0x14F6,	// Unable to enter game. Bad character quest data
		0x14F7,	// Unable to enter game. Bad character waypoint data
		0x14F8,	// Unable to enter game. Bad character stats data
		0x14F9,	// Unable to enter game. Bad character skills data
		0x14FB,	// Unable to enter game
		0x14FA,	// failed to join game
		0x14ED,	// Your connection has been interrupted
		0x14EE,	// The Host of this game has left
		0x14FC,	// unknown failure
		0x14FD,	// Unable to enter game, Bad inventory data
		0x14FE,	// Unable to enter game, bad dead bodies
		0x14FF,	// Unable to enter game, bad header
		0x1500,	// Unable to enter game, bad hireables
		0x1501,	// Unable to enter game, bad intro data
		0x1502,	// Unable to enter game, bad item
		0x1503,	// Unable to enter game, bad dead body item
		0x1504,	// Unable to enter game, generic bad file
		0x1505,	// Game is full
		0x14F0,	// Versions do not match. Please log onto battle.net or go to http://www.blizzard.com/support/Diablo2 to get a patch
		0x14F4,	// Unable to enter game. Your character must kill Diablo to play in a Nightmare game.
		0x14F3,	// Unable to enter game. Your character must kill Diablo in Nightmare difficulty to play in a Hell game.
		0x14F2,	// Unable to enter game. A normal character cannot join a game created by a hardcore character.
		0x14F1,	// Unable to enter game. A hardcore character cannot join a game created by a normal character.
		0x14EF,	// A dead hardcore character cannot join or create any games.
		0x2775,	// Unable to enter game. A Diablo II character cannot join a game created by a Diablo II Expansion character.
		0x2776,	// Unable to enter game. A Diablo II Expansion character cannot join a game created by a Diablo II character.
		0x14FA,	// failed to join game
		0x14FB,	// Unable to enter game
		0x0000,
	};
-------------------------------------

Packet 0xAE S->C
Indicate whether the initial connection is valid. This is always the very first packet that the server sends, and it is always uncompressed. Afterwards, all subsequent packets sent by the server are compressed. (Packets sent by the client are *never* compressed.)

Structure:
sizeof = 2
BYTE - 0xAE
BYTE - status: 0 if no connection allowed, 1 if connection allowed
Last edited by cla$$ics on Sun Mar 04, 2018 2:21 am, edited 3 times in total.
Although done for our needs, mod-makers should like these changes, too.
11/1/08 - COTL; 5/10/09 - Angel; 11/11/09 - Archangel

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: [1.10+] Client & Server Packets

Post by kidpaddle94 » Thu Mar 01, 2018 3:03 am

Here's the def for C->S 0x67

Code: Select all

struct D2GSPacketClt67      // size of 0x2E
{
    BYTE nHeader;           //0x00
    char szGameName[16];    //0x01
    BYTE nGameType;         //0x11
    BYTE nClass;            //0x12
    BYTE nTemplate;         //0x13
    BYTE nDifficulty;       //0x14
    char szCharName[16];    //0x15
    WORD __025;             //0x25
    DWORD dwArenaFlags;     //0x27
    BYTE __02B;             //0x2B
    BYTE __02C;             //0x2C
    BYTE nLang;             //0x2D
};
I call S->C 0xB3 ConnectionEvent, it's really not just about savefiles. In many cases it's the response to a validation when joining a game, and other cases are to inform the client of something that happened to the server, such as connection interrupted, or the host has left this game.

User avatar
cla$$ics
Moderator
Arch-Angel
Posts: 1320
Joined: Wed Aug 15, 2007 3:48 pm
United States of America

Hand-picked

Re: [1.10+] Client & Server Packets

Post by cla$$ics » Thu Mar 01, 2018 3:50 am

kidpaddle94 wrote:
Thu Mar 01, 2018 3:03 am
Here's the def for C->S 0x67

Code: Select all

struct D2GSPacketClt67      // size of 0x2E
{
    BYTE nHeader;           //0x00
    char szGameName[16];    //0x01
    BYTE nGameType;         //0x11
    BYTE nClass;            //0x12
    BYTE nTemplate;         //0x13
    BYTE nDifficulty;       //0x14
    char szCharName[16];    //0x15
    WORD __025;             //0x25
    DWORD dwArenaFlags;     //0x27
    BYTE __02B;             //0x2B
    BYTE __02C;             //0x2C
    BYTE nLang;             //0x2D
};
I call S->C 0xB3 ConnectionEvent, it's really not just about savefiles. In many cases it's the response to a validation when joining a game, and other cases are to inform the client of something that happened to the server, such as connection interrupted, or the host has left this game.
Your 0x67 packet is right - for 1.11 and up. On 1.10 and below the packet structure is different.
You might have a good point there with 0xB3 - it's just mostly seen with validating the savegame.
Although done for our needs, mod-makers should like these changes, too.
11/1/08 - COTL; 5/10/09 - Angel; 11/11/09 - Archangel

User avatar
cla$$ics
Moderator
Arch-Angel
Posts: 1320
Joined: Wed Aug 15, 2007 3:48 pm
United States of America

Hand-picked

Re: [1.10+] Client & Server Packets

Post by cla$$ics » Sun Mar 04, 2018 2:49 am

Double post, and I'm documenting a packet here, which I hope @Necrolis doesn't mind as he mentioned in the OP not to document these.

But here is another set of packets - the last part required to be sent by the client for the handshake in 1.10!

Packet 0x6B C->S
Send a savegame chunk across the network.

This packet takes on two distinct forms.

Whole Chunk
BYTE: 0x6B
BYTE: 0xFF
DWORD: total size of the savegame, in bytes
BYTE[255]: the bytes associated with this chunk
BYTE: 0xF6 to terminate the chunk
sizeof = 262

Partial/Final Chunk
BYTE: 0x6B
BYTE: size of this last chunk (not including the last null terminator)
DWORD: total size of the savegame, in bytes
BYTE*: the bytes associated with this chunk
BYTE: extra null terminator ('\0')
sizeof = size indicated in byte +01, plus 7

Explanation
The game divides the size of the savegame by 255 to get the total number of full chunks. Then it multiplies this again by 255, and subtracts this from the total size to get the remainder at the end. Then it sends each chunk sequentially, first the whole chunks and then the partial/final chunk at the end.

NOTE: It is possible for other packets to get received on the server in between save transmissions, like ping packets and so on.

After all of the savegame packets have been sent, the next packet to get sent is:


Packet 0x6A C->S
Indicates that the save file has been completely sent and is ready to be parsed on the server.

Structure:
BYTE: 0x6A
sizeof = 1
Last edited by cla$$ics on Sun Mar 04, 2018 9:58 pm, edited 1 time in total.
Although done for our needs, mod-makers should like these changes, too.
11/1/08 - COTL; 5/10/09 - Angel; 11/11/09 - Archangel

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: [1.10+] Client & Server Packets

Post by kidpaddle94 » Sun Mar 04, 2018 5:27 am

cla$$ics wrote:
Sun Mar 04, 2018 2:49 am
which I hope @Necrolis doesn't mind as he mentioned in the OP not to document these.
My understanding is D2GS packets is OK, D2CS/D2BS/MCP and other realm-only related packets are prohibited.
Rule of thumb: if its not in the D2Game or D2Client packet callback table, you shouldn't post it.
The packet you documented is in D2Game

User avatar
misiek1294
Junior Member
Paladin
Posts: 168
Joined: Mon Dec 29, 2014 3:58 pm
Poland

Re: [1.10+] Client & Server Packets

Post by misiek1294 » Fri Dec 28, 2018 1:50 pm

Code: Select all

 
struct SRV2CLTPACKET18
{
  BYTE bHeader;
  WORD wLife;
  WORD wMana;
  WORD wStamina;
  BYTE bHpRecovery;
  BYTE bManaRecovery;
  WORD wOffsetX;
  WORD wOffsetY;
  BYTE bTargetXOffset;
  BYTE bTargetYOffset;
};

Code: Select all

 
struct SRV2CLTPACKET95
{
  BYTE bHeader; 
  WORD wLife; 
  WORD wMana; 
  WORD wStamina; 
  WORD wOffsetX;
  WORD wOffsetY;
  BYTE bTargetXOffset;
  BYTE bTargetYOffset;
};

Code: Select all

 
struct SRV2CLTPACKET96
{
  BYTE bHeader;
  DWORD wStamina;
  WORD wOffsetX;
  WORD wOffsetY;
  BYTE bTargetXOffset;
  BYTE bTargetYOffset;
};

Post Reply

Return to “Code Editing”