Wiki
Clone wikiNetPro / config / Packets
Protocol/packet definitions
Location
All related configuration files are under ./config/packets/
.
Protocol definitions
Supported protocol configuration can be altered by modifying the all_known_protocols.xml
file.
Auth (login)
There isn't much to say about auth protocols, because they hardly change and the protocol revision number is just cosmetic. You shouldn't need to change them.
Game
Let's start with an example:
#!xml <protocol id="54" alias="Infinite Odyssey" category="IO"> <version date="2015-04-22">24</version> <primary> <constant>0x12</constant> <constant>0xB1</constant> <constant>0x11</constant> <constant>0xD0</constant> </primary> <secondary count="269"> <constant>0x70</constant> <constant>0x71</constant> </secondary> <definitions dir="infinite_odyssey" /> </protocol>
<protocol>
element attributes:
id
: currently unused. Designed to be used for programmatic protocol version comparisons instead of the hardcodedClientProtocolVersion
enum values.alias
: user-friendly protocol description string (yes, it will be displayed to the user).category
: user-friendly protocol category string. Used to build GUI submenus related to protocol display configuration.disabled
: boolean that controls whether to ignore a definition.
Subelements:
<version>
: protocol revision number, as known to the associated client. Attributedate
is used for version comparisons.<primary>
: CM opcode shuffling control. See below.<secondary>
: CM opcode shuffling control. See below.<definitions>
: Attributedir
specifies the relative directory for packet definitions.
CM opcode shuffling
Client packet opcode shuffling feature was first implemented in Hellbound (831). Shuffling happens on two occassions:
- Initial login (to the game server lobby)
- Each time a concrete character is logged in
Shuffle results depend on the total amount of opcodes to be shuffled (e.g., if there are 5 in total, opcode 6 will never be used after shuffling). Moreover, certain opcodes
may be deemed constant: they will not participate in the shuffle. <primary>
and <secondary>
elements allow these options to be configured.
count
attribute may be used to specify the total amount of opcodes (NetPro will log warnings if this is set too low). There is no sense in setting the count of primary opcodes,
because with introduction of 0xCF
(which changed to 0xD0
in C4 – years before shuffling was implemented), the amount of primary opcodes never changes.
<constant>
subelements may be used to specify which opcode values should not participate in the shuffling algorithm.
Packet definitions
Packet names are defined in all_known_packets.xml
. As you have found out while reading about protocol definitions, actual definitions are contained in named subdirectories of ./config/packets/
.
Each such subdirectory may contain up to 3 elements:
client/
: CM definition folderserver/
: SM definition folderopcode_mapping.xml
: a specification of what packets have which opcode values
Opcode mapping
The opcode mapping specification file is a critical component in incremental packet definition loading. Opcode mappings themselves are loaded incrementally as well.
The structure of this file is completely self-explanatory (see the associated XML schema for details). Packet IDs and visible names are defined in all_known_packets.xml
.
Known major opcode re-assignments are C2 (SMs) and Kamael (all).
client
and server
subfolders
Names of these subfolders are rather self-explanatory. They contain XML files with packet definitions, one definition per file. The recommended definition file naming scheme is
[name of the packet as found in the latest available client].xml, even though you may name them arbitrarily (keep the .xml
extension) if that helps you in any way.
It is not required to keep these folders if they are empty.
Packet definition file
A packet definition file is a sequence of fields, loops and branches associated with an ID defined in all_known_packets.xml
.
Field types
Numeric
<byte>
and<unsignedByte>
: 8-bit integer (byte
and no direct equivalent in Java)<word>
and<unsignedWord>
: 16-bit integer (short
andchar
)<dword>
: 32-bit integer (int
)<word>
: 64-bit integer (long
)<single>
: IEEE single-precision float (float
)<double>
: IEEE double-precision float (double
)
Text
<ntstring>
(or simply<string>
): nul-terminated UTF-16 (LE) string<sstring>
: sized UTF-16 (LE) string. The string itself is preceeded by a 16-bit integer specifying string length (in characters).
Field value presentation
More often than not, fields values do not have a direct meaning (e.g. PvP count is exactly what it says on the tin, while a world object ID merely points to some object; plus, there are different types of world objects).
A field may specify an interpreter class using the type
attribute to change the way field values are presented. While some of you may know the numeric equivalents of all character classes,
learning all skill level names and enchant routes may pose a notably harder challenge.
#!xml <byte alias="Mount type" type="MountType" /> <byte alias="Private store" type="PersonalStoreType" /> <dword alias="Mount" type="Npc" /> <dword alias="Class" type="CharacterClass" />
Loops
<loop>
element allows its subelements to be read an arbitrary amount of times. It is assumed that loop size is always dynamic, and the id
attribute controls which integer field's
[modified] value is used as iteration count. The associated integer field should have a matching id
attribute, e.g.
#!xml <dword alias="Available recipes" id="cnt" /> <loop id="cnt"> <dword alias="Recipe" type="Recipe" /> <dword alias="Can create" type="YesOrNo" /> </loop>
Branches
<branch>
element allows its subelements to be read conditionally. The id
attribute identifies the field to be tested (that field must have a matching id
attribute value) using logic
found in the conditional class identified by attribute condition
. Condition classes are found in the script condition
package (and its subpackages); in the class name, only specify
subpackages (if any; do not use FQCN).
#!xml <byte alias="Parameter" type="Parameter" id="param" /> <branch id="param" condition="param.StringValue"> <string alias="Value" /> </branch>
Updated