Replica Packets
Note
This is a read-the-docs port of the original google docs lu_replica_packets, written by humanoid, lcdr and others, ported by @Xiphoseer. This is currently a proof of concept and is not guaranteed to reflect the latest changes.
Note
most structures can be omitted if they are optional, so you do not have to implement everything
grey colored structs didn’t occur in a packet yet
for investigations in raw replica packets, an advanced hex editor that can do bit operations on the data is very much recommended since there tend to be a lot of bit shifts in one packet
a sample packet viewer is provided at https://bitbucket.org/lcdr/utils/src captureviewer.pyw (needs the client database converted as per fdb_to_sqlite.py)
the original server seems to have used the first iteration of RakNet’s Replica(Manager) class instead of the second one (as evidenced by the structure of the Construction header), so the Replica2 and ReplicaManager2 classes should not be used to emulate the original traffic
Packet composition
[0x24] - Replica Manager Construction
[0x27] - Replica Manager Serialization
[0x25] - Replica Manager Destruction
Base Data ($+731C30)
seems to be included for every object
- contains LDF with the following keys and data formats:
blueprintid: 9
componentWhitelist: 1
modelBehaviors: 5
modelType: 1
propertyObjectID: 7
userModelID: 9
Note: this also can contain a script, like for example on pets, to whitelist specific components.
Component serialization
Introduction
Every object consists of components, which define its behavior (e.g. RenderComponent means that the object should be rendered and is visible in the game).
Like the general object data, components have data that needs to be broadcast to every player (e.g. health value for DestructibleComponent) which is serialized.
Components consist of indices (inofficial name) which allow structures to be broken up further and to be reused (e.g. DestructibleComponent consists of the general destructible index and the stats index, which handles object stats like health, armor and imagination. This stats index is also used by the Collectible and Rebuild components.)
If an object has for example both Destructible and Collectible indices, the stats index is “shared”, that is, the second occurrence is removed and both Destructible and Collectible take their information from this single remaining stats index. This prevents redundancy and saves network bandwidth.
As with game messages, not all components are used in network traffic but internally within the client. The non-networked ones are of no use in this documentation but for completeness sake we’ll list the ones that we could identify so far as well (ids only)
Component List (networked)
In the following the components and the indices they use are listed, in the format
[cdclient id] <Component name>: Index names
.
The order in which they are listed are the order they are serialized. Make sure to write the components in this order (omitting components that are not listed for the according object in the cdclient database of course), otherwise the client will not be able to read them.
[108] ???: Component 108
[61] ModuleAssembly: ModuleAssembly
[1] ControllablePhysics: ControllablePhysics
[3] SimplePhysics: SimplePhysics
[20] RigidBodyPhantomPhysics: RigidBodyPhantomPhysics
[30] VehiclePhysics: VehiclePhysics
[40] PhantomPhysics: PhantomPhysics
[7] Destructible: Destructible, Stats
[23] Collectible: Stats, Collectible
[26] Pet: Pet
[4] Character: Character (Part 1-4)
[17] Inventory: Inventory
[5] Script: Script
[9] Skill: Skill
[60] BaseCombatAI: BaseCombatAI
[48] Rebuild: Stats, Rebuild
[25] Moving Platform: Moving Platform
[49] Switch: Switch
[16] Vendor: Vendor
[6] Bouncer: Bouncer
[39] ScriptedActivity: ScriptedActivity
[71] RacingControl: RacingControl
[75] Exhibit: Exhibit
[42] Model: Model
[2] Render: Render
[107] ???: Component 107
[69] Trigger: Trigger
Example
An object with ControllablePhysics and Destructible components has the following indices in this order:
ControllablePhysics
Destructible
Stats
Component List (non-networked)
12, 31, 35, 36, 45, 55, 56, 64, 65, 68, 73, 104, 113, 114
61 = AssemblyComponent
Index serialization data
Collectible (todo: address)
Bouncer ($+7D6620)
Component 107 ($+7D6690)
RigidBodyPhantomPhysics ($+7D90C0)
Character
Part 1 ($+7DBCE0)
Part 2 ($+863BD0)
Part 3 ($+7DC480)
Part 4 ($+8A3A40)
Component 108 ($+7DC1F0)
(something vehicle related)
Vendor ($+7E1CB0)
SimplePhysics ($+7E4B00)
VehiclePhysics ($+7FD4D0)
Skill ($+806270)
Switch ($+80EBF0)
BaseCombatAI ($+824290)
PhantomPhysics ($+834DB0)
Render ($+840310)
ControllablePhysics ($+845770)
Exhibit ($+863790)
Script ($+87CDF0)
Pet ($+8D1270)
ScriptedActivity ($+9002B0)
Rebuild ($+90AE10)
ModuleAssembly ($+913F30)
Stats ($+92BBD0)
Destructible ($+939820)
Moving Platform
Racing Control ($+949620)
Inventory ($+952860)
Trigger Component
Seems like this component is append when there is a trigger_id entry in the luz-lvl See also documentation for lvl files See also documentation for .lutriggers files