Create View Serialisation

We will explain on an easy example how this works.
In our Example we use a NPC Packet from the Logs and explain its Data.
 


The RAW Packet Data

02 03 01 00 0c 57 02 38 cd ab 13 ae 43 6f 72 72 75 70 74 65 64 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 22 00 00 10 00 d0 30 23 00 c6 01 a0 01 c1 15 00 
00 4e 00 00 00 31 61 b7 f0 c0 00 00 00 00 00 c0 57 40 00 00 00 60 07 cd d2 40 d0 0c 01 82 02 a8 
45 66 0a b2 09 66 0a 06 08 00 00 81 3d b9 00 00 02 11 08 00 00 00 00 
.  .  .  .  .  W  .  8  .  .  .  .  C  o  r  r  u  p  t  e  d  .  .  .  .  .  .  .  .  .  .  .  
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  "  .  .  .  .  .  0  #  .  .  .  .  .  .  .  .  
.  N  .  .  .  1  a  .  .  .  .  .  .  .  .  .  W  @  .  .  .  `  .  .  .  @  .  .  .  .  .  .  
E  f  .  .  .  f  .  .  .  .  .  .  =  .  .  .  .  .  .  .  .  .  . 

So thats how the Packet is in the Logs.

As we know we have GoID 599 (57 02). So we take our Attribute List for Object Creation.

The Attribute Lists for all Objects was parsed by Morpheus and Rajko so Credits goes to mxoemu and HD in this Case.

The Raw Attribute List look like this :
 

#VALUES FOR GOID: 599, NPC_BASE


#USING 3827, Binary-Present(1): offset 254
104,EvadeShieldHealth,uint8,1
12,CharacterName,GOString32,32
1768,TitleAbility,AbilityID,4
49,CombatantMode,uint8,1
255,JumpFlags,int16,2
50,ConditionStateFlags,AbilityConditionFlags,4
261,Jumping,bool,1
91,EffectCounter,uint8,1
1773,UseRSIDescription,bool,1
1782,Yaw Interval,int8,1
263,MasterCharacterID,uint32,4
292,MoreInfoID,LTSTRINGID,4
1660,StealthLevel,uint8,1
1661,StopFollowActiveTracker,bool,1
219,IsDead,bool,1
80,DissemblingType,uint16,2
251,JumpEndTime,uint32,4
194,HalfExtents,LTVector3f,12
1778,WanderRange,int32,4
1569,ScriptCounter,uint8,1
100,EvadeShieldDamageScale,float,4
74,Description,REZ_ID,4
92,EffectID,uint32,4
157,FactionID,LTFactionID,4
82,DontAttack,bool,1
335,NoiseLevel,uint8,1
122,ExclusiveLocator,LTGenericLoc,18
393,Position,LTVector3d,24
417,ProneState,uint32,4
7,CancelAbility,AbilityID,4
1772,UseCount,uint8,1
269,MissionKey,MissionKey,4
1582,Stance,Movement::Stance,1
369,OrganizationID,Organization::MissionOrg,1
221,IsEnemy,bool,1
0,Action,Movement::Action,1
324,NPCRank,uint8,1
223,IsFriendly,bool,1
73,Demeanor,uint8,1
320,MovementScale,float,4
11,CancelAbilityCounter,uint8,1
257,JumpPeakHeight,float,4
161,FollowActiveTracker,bool,1
193,GuardType,uint8,1
140,ExclusiveType,uint8,1
262,Level,uint8,1
183,GiverActiveTracker,bool,1
206,Health,uint16,2
87,EffectCommand,uint32,4
227,JumpDestination,LTVector3d,24
70,DebuffState,uint8,1
1675,TakerActiveTracker,bool,1
435,RSIDescription,RSI::RSIPackedBytesWrapper,15
267,MaxHealth,uint16,2
58,CurrentState,EventID,4
222,IsEscortable,bool,1
96,EquippedItemID,uint32,4
1574,SpawnFX,EffectID,4
83,DuelID,uint32,4
1698,TalkDefaultable,bool,1
389,OwnerCharacterID,uint32,4
421,PutActiveTracker,bool,1
463,RelevancyFlags,uint8,1
1693,TalkActiveTracker,bool,1
1659,StealthAwareness,uint8,1
62,CurrentStateContainer,EventID,4

But before we can parse we need to split it into Groups . Each Groups can contain max. 7 Attributes. We just goes top down and split them in Groups.

So after that our List look similiar like this : 

Attribute List 

Group 1
Attrib 1: 104,EvadeShieldHealth,uint8,1
Attrib 2: 12,CharacterName,GOString32,32
Attrib 3: 1768,TitleAbility,AbilityID,4
Attrib 4: 49,CombatantMode,uint8,1
Attrib 5: 255,JumpFlags,int16,2
Attrib 6: 50,ConditionStateFlags,AbilityConditionFlags,4
Attrib 7: 261,Jumping,bool,1

Group 2
Attrib 1: 91,EffectCounter,uint8,1
Attrib 2: 1773,UseRSIDescription,bool,1
Attrib 3: 1782,Yaw Interval,int8,1
Attrib 4: 263,MasterCharacterID,uint32,4
Attrib 5: 292,MoreInfoID,LTSTRINGID,4
Attrib 6: 1660,StealthLevel,uint8,1
Attrib 7: 1661,StopFollowActiveTracker,bool,1

Group 3 
Attrib 1: 219,IsDead,bool,1
Attrib 2: 80,DissemblingType,uint16,2
Attrib 3: 251,JumpEndTime,uint32,4
Attrib 4: 194,HalfExtents,LTVector3f,12
Attrib 5: 1778,WanderRange,int32,4
Attrib 6: 1569,ScriptCounter,uint8,1
Attrib 7: 100,EvadeShieldDamageScale,float,4

Group 4
Attrib 1: 74,Description,REZ_ID,4
Attrib 2: 92,EffectID,uint32,4
Attrib 3: 157,FactionID,LTFactionID,4
Attrib 4: 82,DontAttack,bool,1
Attrib 5: 335,NoiseLevel,uint8,1
Attrib 6: 122,ExclusiveLocator,LTGenericLoc,18
Attrib 7: 393,Position,LTVector3d,24

Group 5
Attrib 1: 417,ProneState,uint32,4
Attrib 2: 7,CancelAbility,AbilityID,4
Attrib 3: 1772,UseCount,uint8,1
Attrib 4: 269,MissionKey,MissionKey,4
Attrib 5: 1582,Stance,Movement::Stance,1
Attrib 6: 369,OrganizationID,Organization::MissionOrg,1
Attrib 7: 221,IsEnemy,bool,1

Group 6
Attrib 1: 0,Action,Movement::Action,1
Attrib 2: 324,NPCRank,uint8,1
Attrib 3: 223,IsFriendly,bool,1
Attrib 4: 73,Demeanor,uint8,1
Attrib 5: 320,MovementScale,float,4
Attrib 6: 11,CancelAbilityCounter,uint8,1
Attrib 7: 257,JumpPeakHeight,float,4

Group 7
Attrib 1: 161,FollowActiveTracker,bool,1
Attrib 2: 193,GuardType,uint8,1
Attrib 3: 140,ExclusiveType,uint8,1
Attrib 4: 262,Level,uint8,1
Attrib 5: 183,GiverActiveTracker,bool,1
Attrib 6: 206,Health,uint16,2
Attrib 7: 87,EffectCommand,uint32,4

Group 8
Attrib 1: 227,JumpDestination,LTVector3d,24
Attrib 2: 70,DebuffState,uint8,1
Attrib 3: 1675,TakerActiveTracker,bool,1
Attrib 4: 435,RSIDescription,RSI::RSIPackedBytesWrapper,15
Attrib 5: 267,MaxHealth,uint16,2
Attrib 6: 58,CurrentState,EventID,4
Attrib 7: 222,IsEscortable,bool,1

Group 9
Attrib 1: 96,EquippedItemID,uint32,4
Attrib 2: 1574,SpawnFX,EffectID,4
Attrib 3: 83,DuelID,uint32,4
Attrib 4: 1698,TalkDefaultable,bool,1
Attrib 5: 389,OwnerCharacterID,uint32,4
Attrib 6: 421,PutActiveTracker,bool,1
Attrib 7: 463,RelevancyFlags,uint8,1

Group 10
Attrib 1: 1693,TalkActiveTracker,bool,1
Attrib 2: 1659,StealthAwareness,uint8,1
Attrib 3: 62,CurrentStateContainer,EventID,4


 

Unserialize the Packet

I will just copy and paste it here.



02 (ack)
03 (Protocol)
01 00 (Admin View Manager)
0c <- Flags (1100) . Format is ndcc (cc is the operation - cc can be 0= Create, 1=delete, 2=PendingCreateUpdate, 3= RelevanceNotices (S2S only) . d = isFullyDynamicFlag)
57 02(goId)
38 <- spawn counter (dont resend it until it was acked)
cd ab <- seperator for Protocol and Object Serializer
13 <- Num Attributes (19 )
ae <- 10101110 ( Group1 with 4 Attribs - Attributes 2,3,4,6 ON, MORE GROUPS ON) (AttributeList: 12,CharacterName,GOString32,32; 1768,TitleAbility,AbilityID,4; 49,CombatantMode,uint8,1;50,ConditionStateFlags,AbilityConditionFlags,4)
43 6f 72 72 75 70 74 65 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <- 12,CharacterName,GOString32,32
00 10 00 00 <- 1768,TitleAbility,AbilityID,4
22 <- 49,CombatantMode,uint8,1
00 00 10 00 <- 50,ConditionStateFlags,AbilityConditionFlags,4

d0 <- 11010000 ( Group 2 with 2 Attribs - Attributes 5,7 ON, MORE GROUPS ON) (AttributeList:292,MoreInfoID,LTSTRINGID,4; 1661,StopFollowActiveTracker,bool,1)
30 23 00 c6 <- 292,MoreInfoID,LTSTRINGID,4
01 <- 1661,StopFollowActiveTracker,bool,1

a0 <- 10100000 ( Group 3 with 1 Attribs - Attributes 6 ON, MORE GROUPS ON) (AttributeList:1569,ScriptCounter,uint8,1)
01 <- 1569,ScriptCounter,uint8,1

c1 <- 11000001 ( Group 4 with 2 Attribs - Attributes 1,7 ON, MORE GROUPS ON) (AttributeList:74,Description,REZ_ID,4; 393,Position,LTVector3d,24)
15 00 00 4e <- 74,Description,REZ_ID,4
00 00 00 31 61 b7 f0 c0 00 00 00 00 00 c0 57 40 00 00 00 60 07 cd d2 40 <- 393,Position,LTVector3d,24

d0 <- 11010000 ( Group 5 with 2 Attribs - Attributes 5,7 ON, MORE GROUPS ON) (AttributeList:1582,Stance,Movement::Stance,1; 221,IsEnemy,bool,1)
0c <- 1582,Stance,Movement::Stance,1
01 <- 221,IsEnemy,bool,1

82 <- 10000010 ( Group 6 with 1 Attribs - Attributes 2 ON, MORE GROUPS ON) (AttributeList:324,NPCRank,uint8,1)
02 <- 324,NPCRank,uint8,1

a8 <- 10101000 ( Group 7 with 2 Attribs - Attributes 4,6 ON, MORE GROUPS ON) (AttributeList: 262,Level,uint8,1; 206,Health,uint16,2)
45 <- 262,Level,uint8,1
66 0a <- 206,Health,uint16,2

b2 <- 10110010 ( Group 8 with 3 Attribs - Attributes 2,5,6 ON, MORE GROUPS ON) (AttributeList: 70,DebuffState,uint8,1;  267,MaxHealth,uint16,2; 58,CurrentState,EventID,4)
09 <- 70,DebuffState,uint8,1
66 0a <- 267,MaxHealth,uint16,2
06 08 00 00 <- 58,CurrentState,EventID,4

81 <- 10000001 (Group 9 with 1 Attribs - Attributes 1 ON, MORE GROUPS ON ) (AttributeList: Attrib 1: 96,EquippedItemID,uint32,4 )
3d b9 00 00 <- 96,EquippedItemID,uint32,4

02 <- 0010 ( Group 10 with 1 Attrib - Attributes 2 ON, MORE GROUPS OFF) (AttributeList: 1659,StealthAwareness,uint8,1)
11 <- 1659,StealthAwareness,uint8,1

08 00 <- new View Id (8)
00 00 <- no more views (View Id 0)
00 <- end (0)

So whats happened here ? 
Lets take a look where Num Attributes Starts.
We have 19 Attributes that needs to parse according to the Attribute List.
Each Group starts with a Byte which has the Bits set for which Attributes should been parsed from this list and if we moove forward to the next Group (More Groups ON flag).
 

How do we do this ? 

In our first group 0xae = 10101110 as bit vector.

10101110 <- you need to read this from right to left. So right is 1 until 7 . The 8th bit is the "Group ON" Flag. If it is set, it means there are more groups to parse.
 

More Info about it can be find at : wiki.mxoemu.info/index.php



THE MATRIX ONLINE, characters, names and all related indicia are trademarks of and © Warner Bros. Entertainment Inc.
Webdesign and Programming by Hardline Dreams
HD Server Emulator Development by Hardline Dreams
All other trademarks or tradenames are properties of their respective owners.