Wiki

Clone wiki

NetPro / 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:

  1. id: currently unused. Designed to be used for programmatic protocol version comparisons instead of the hardcoded ClientProtocolVersion enum values.
  2. alias: user-friendly protocol description string (yes, it will be displayed to the user).
  3. category: user-friendly protocol category string. Used to build GUI submenus related to protocol display configuration.
  4. disabled: boolean that controls whether to ignore a definition.

Subelements:

  1. <version>: protocol revision number, as known to the associated client. Attribute date is used for version comparisons.
  2. <primary>: CM opcode shuffling control. See below.
  3. <secondary>: CM opcode shuffling control. See below.
  4. <definitions>: Attribute dir 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:

  1. Initial login (to the game server lobby)
  2. 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:

  1. client/: CM definition folder
  2. server/: SM definition folder
  3. opcode_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
  1. <byte> and <unsignedByte>: 8-bit integer (byte and no direct equivalent in Java)
  2. <word> and <unsignedWord>: 16-bit integer (short and char)
  3. <dword>: 32-bit integer (int)
  4. <word>: 64-bit integer (long)
  5. <single>: IEEE single-precision float (float)
  6. <double>: IEEE double-precision float (double)
Text
  1. <ntstring> (or simply <string>): nul-terminated UTF-16 (LE) string
  2. <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