Skip to content

PropertyClass

The game client uses an abstract data type, known as a PropertyClass, to designate complex types capable of undergoing binary serialization. Internally, this is an assembly reflection. Each PropertyClass must be labeled with a property hash.

The property class hash is a string ID of the PropertyClass name, prefixed with it's internal representation, such as class or struct.

Property

Each property of the PropertyClass is simply labeled as Property, and serves as specific field elaboration to the binary encoding process.

Each Property element denotes two important attributes: Hash, and Flags.

Property Hash

Each property may be prefixed with an attribute detailing it's property hash. This is an expansion of a string ID.

csharp
public static uint HashPropertyName(string name, string type)
{
    uint typeHash = HashString(type);
    var propHash = DJB2(name) & 0x7FFF_FFFF;

    // Dropping the most-significant byte.
    return (typeHash + propHash) & 0xFFFF_FFFF;
}

public static uint DJB2(string str)
{
    uint hash = 5381;

    foreach (char c in str)
    {
        hash = ((hash << 5) + hash) + c;
    }

    return hash;
}
public static uint HashPropertyName(string name, string type)
{
    uint typeHash = HashString(type);
    var propHash = DJB2(name) & 0x7FFF_FFFF;

    // Dropping the most-significant byte.
    return (typeHash + propHash) & 0xFFFF_FFFF;
}

public static uint DJB2(string str)
{
    uint hash = 5381;

    foreach (char c in str)
    {
        hash = ((hash << 5) + hash) + c;
    }

    return hash;
}

Figure A.I - Imlight's cryptography for hashing a property.

Property Flags

Each property may also be prefixed with a bitflag operator attribute detailing how it should be processed through a serializer.

csharp
[Flags]
public enum PropertyFlags
{
    Save = 1              << 0,
    Copy = 1              << 1,
    Public = 1            << 2,
    Transmit = 1          << 3,
    AuthorityTransmit = 1 << 4,
    Persistent = 1        << 5,
    Deprecated = 1        << 6,
    NoScript = 1          << 7,
    Encode = 1            << 8,
    Blob = 1              << 9,

    Immutable = 1         << 16,
    FileName = 1          << 17,
    Color = 1             << 18,

    Bits = 1              << 20,
    Enum = 1              << 21,
    Localized = 1         << 22,
    StringKey = 1         << 23,
    ObjectID = 1          << 24,
    ReferenceID = 1       << 25,
                                  
    ObjectName = 1        << 27,
    HasBaseClass = 1      << 28,
}
[Flags]
public enum PropertyFlags
{
    Save = 1              << 0,
    Copy = 1              << 1,
    Public = 1            << 2,
    Transmit = 1          << 3,
    AuthorityTransmit = 1 << 4,
    Persistent = 1        << 5,
    Deprecated = 1        << 6,
    NoScript = 1          << 7,
    Encode = 1            << 8,
    Blob = 1              << 9,

    Immutable = 1         << 16,
    FileName = 1          << 17,
    Color = 1             << 18,

    Bits = 1              << 20,
    Enum = 1              << 21,
    Localized = 1         << 22,
    StringKey = 1         << 23,
    ObjectID = 1          << 24,
    ReferenceID = 1       << 25,
                                  
    ObjectName = 1        << 27,
    HasBaseClass = 1      << 28,
}

Figure B.I - An enum of all possible property bit flags.

Finding each PropertyClass

Third-party tools such as WizWalker or WizType may suffice in dumping the in-game types.