rattletrap 9.3.1 → 9.3.2
raw patch · 484 files changed
+7076/−7079 lines, 484 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
This diff is very large; some files are shown as “too large to diff”. Download the raw patch for the complete diff.
Files
- README.markdown +2/−8
- rattletrap.cabal +4/−4
- source/executable/Main.hs +0/−6
- source/library/Rattletrap.hs +0/−162
- source/library/Rattletrap/Console/Main.hs +0/−238
- source/library/Rattletrap/Data.hs +0/−665
- source/library/Rattletrap/Decode/AppliedDamageAttribute.hs +0/−19
- source/library/Rattletrap/Decode/Attribute.hs +0/−73
- source/library/Rattletrap/Decode/AttributeMapping.hs +0/−12
- source/library/Rattletrap/Decode/AttributeValue.hs +0/−131
- source/library/Rattletrap/Decode/BooleanAttribute.hs +0/−10
- source/library/Rattletrap/Decode/ByteAttribute.hs +0/−11
- source/library/Rattletrap/Decode/Cache.hs +0/−18
- source/library/Rattletrap/Decode/CamSettingsAttribute.hs +0/−20
- source/library/Rattletrap/Decode/ClassMapping.hs +0/−12
- source/library/Rattletrap/Decode/ClubColorsAttribute.hs +0/−16
- source/library/Rattletrap/Decode/Common.hs +0/−70
- source/library/Rattletrap/Decode/CompressedWord.hs +0/−30
- source/library/Rattletrap/Decode/CompressedWordVector.hs +0/−18
- source/library/Rattletrap/Decode/Content.hs +0/−71
- source/library/Rattletrap/Decode/CustomDemolishAttribute.hs +0/−16
- source/library/Rattletrap/Decode/DamageStateAttribute.hs +0/−21
- source/library/Rattletrap/Decode/DemolishAttribute.hs +0/−19
- source/library/Rattletrap/Decode/DestroyedReplication.hs +0/−10
- source/library/Rattletrap/Decode/Dictionary.hs +0/−17
- source/library/Rattletrap/Decode/EnumAttribute.hs +0/−10
- source/library/Rattletrap/Decode/ExplosionAttribute.hs +0/−17
- source/library/Rattletrap/Decode/ExtendedExplosionAttribute.hs +0/−16
- source/library/Rattletrap/Decode/FlaggedByteAttribute.hs +0/−13
- source/library/Rattletrap/Decode/FlaggedIntAttribute.hs +0/−12
- source/library/Rattletrap/Decode/Float32le.hs +0/−14
- source/library/Rattletrap/Decode/FloatAttribute.hs +0/−11
- source/library/Rattletrap/Decode/Frame.hs +0/−43
- source/library/Rattletrap/Decode/GameModeAttribute.hs +0/−15
- source/library/Rattletrap/Decode/Header.hs +0/−22
- source/library/Rattletrap/Decode/Initialization.hs +0/−16
- source/library/Rattletrap/Decode/Int32le.hs +0/−14
- source/library/Rattletrap/Decode/Int64Attribute.hs +0/−11
- source/library/Rattletrap/Decode/Int64le.hs +0/−13
- source/library/Rattletrap/Decode/Int8Vector.hs +0/−18
- source/library/Rattletrap/Decode/Int8le.hs +0/−13
- source/library/Rattletrap/Decode/IntAttribute.hs +0/−11
- source/library/Rattletrap/Decode/KeyFrame.hs +0/−13
- source/library/Rattletrap/Decode/List.hs +0/−16
- source/library/Rattletrap/Decode/LoadoutAttribute.hs +0/−31
- source/library/Rattletrap/Decode/LoadoutOnlineAttribute.hs +0/−25
- source/library/Rattletrap/Decode/LoadoutsAttribute.hs +0/−14
- source/library/Rattletrap/Decode/LoadoutsOnlineAttribute.hs +0/−23
- source/library/Rattletrap/Decode/LocationAttribute.hs +0/−12
- source/library/Rattletrap/Decode/Mark.hs +0/−12
- source/library/Rattletrap/Decode/Message.hs +0/−12
- source/library/Rattletrap/Decode/MusicStingerAttribute.hs +0/−16
- source/library/Rattletrap/Decode/PartyLeaderAttribute.hs +0/−18
- source/library/Rattletrap/Decode/PickupAttribute.hs +0/−13
- source/library/Rattletrap/Decode/PickupAttributeNew.hs +0/−16
- source/library/Rattletrap/Decode/PlayerHistoryKeyAttribute.hs +0/−11
- source/library/Rattletrap/Decode/PrivateMatchSettingsAttribute.hs +0/−20
- source/library/Rattletrap/Decode/ProductAttribute.hs +0/−70
- source/library/Rattletrap/Decode/Property.hs +0/−15
- source/library/Rattletrap/Decode/PropertyValue.hs +0/−31
- source/library/Rattletrap/Decode/QWordAttribute.hs +0/−11
- source/library/Rattletrap/Decode/Quaternion.hs +0/−26
- source/library/Rattletrap/Decode/RemoteId.hs +0/−49
- source/library/Rattletrap/Decode/Replay.hs +0/−66
- source/library/Rattletrap/Decode/Replication.hs +0/−45
- source/library/Rattletrap/Decode/ReplicationValue.hs +0/−45
- source/library/Rattletrap/Decode/ReservationAttribute.hs +0/−25
- source/library/Rattletrap/Decode/RigidBodyStateAttribute.hs +0/−19
- source/library/Rattletrap/Decode/Rotation.hs +0/−14
- source/library/Rattletrap/Decode/Section.hs +0/−30
- source/library/Rattletrap/Decode/SpawnedReplication.hs +0/−72
- source/library/Rattletrap/Decode/StatEventAttribute.hs +0/−12
- source/library/Rattletrap/Decode/Str.hs +0/−47
- source/library/Rattletrap/Decode/StringAttribute.hs +0/−11
- source/library/Rattletrap/Decode/TeamPaintAttribute.hs +0/−18
- source/library/Rattletrap/Decode/TitleAttribute.hs +0/−20
- source/library/Rattletrap/Decode/UniqueIdAttribute.hs +0/−16
- source/library/Rattletrap/Decode/UpdatedReplication.hs +0/−22
- source/library/Rattletrap/Decode/Vector.hs +0/−29
- source/library/Rattletrap/Decode/WeldedInfoAttribute.hs +0/−21
- source/library/Rattletrap/Decode/Word32le.hs +0/−14
- source/library/Rattletrap/Decode/Word64le.hs +0/−14
- source/library/Rattletrap/Decode/Word8le.hs +0/−14
- source/library/Rattletrap/Encode/AppliedDamageAttribute.hs +0/−18
- source/library/Rattletrap/Encode/Attribute.hs +0/−26
- source/library/Rattletrap/Encode/AttributeMapping.hs +0/−14
- source/library/Rattletrap/Encode/AttributeValue.hs +0/−85
- source/library/Rattletrap/Encode/BooleanAttribute.hs +0/−12
- source/library/Rattletrap/Encode/ByteAttribute.hs +0/−13
- source/library/Rattletrap/Encode/Cache.hs +0/−18
- source/library/Rattletrap/Encode/CamSettingsAttribute.hs +0/−21
- source/library/Rattletrap/Encode/ClassMapping.hs +0/−15
- source/library/Rattletrap/Encode/ClubColorsAttribute.hs +0/−16
- source/library/Rattletrap/Encode/Common.hs +0/−10
- source/library/Rattletrap/Encode/CompressedWord.hs +0/−44
- source/library/Rattletrap/Encode/CompressedWordVector.hs +0/−15
- source/library/Rattletrap/Encode/Content.hs +0/−43
- source/library/Rattletrap/Encode/CustomDemolishAttribute.hs +0/−16
- source/library/Rattletrap/Encode/DamageStateAttribute.hs +0/−20
- source/library/Rattletrap/Encode/DemolishAttribute.hs +0/−19
- source/library/Rattletrap/Encode/DestroyedReplication.hs +0/−11
- source/library/Rattletrap/Encode/Dictionary.hs +0/−17
- source/library/Rattletrap/Encode/EnumAttribute.hs +0/−13
- source/library/Rattletrap/Encode/ExplosionAttribute.hs +0/−16
- source/library/Rattletrap/Encode/ExtendedExplosionAttribute.hs +0/−16
- source/library/Rattletrap/Encode/FlaggedByteAttribute.hs +0/−14
- source/library/Rattletrap/Encode/FlaggedIntAttribute.hs +0/−14
- source/library/Rattletrap/Encode/Float32le.hs +0/−21
- source/library/Rattletrap/Encode/FloatAttribute.hs +0/−13
- source/library/Rattletrap/Encode/Frame.hs +0/−24
- source/library/Rattletrap/Encode/GameModeAttribute.hs +0/−14
- source/library/Rattletrap/Encode/Header.hs +0/−22
- source/library/Rattletrap/Encode/Initialization.hs +0/−19
- source/library/Rattletrap/Encode/Int32le.hs +0/−21
- source/library/Rattletrap/Encode/Int64Attribute.hs +0/−13
- source/library/Rattletrap/Encode/Int64le.hs +0/−20
- source/library/Rattletrap/Encode/Int8Vector.hs +0/−23
- source/library/Rattletrap/Encode/Int8le.hs +0/−19
- source/library/Rattletrap/Encode/IntAttribute.hs +0/−12
- source/library/Rattletrap/Encode/KeyFrame.hs +0/−16
- source/library/Rattletrap/Encode/List.hs +0/−16
- source/library/Rattletrap/Encode/LoadoutAttribute.hs +0/−35
- source/library/Rattletrap/Encode/LoadoutOnlineAttribute.hs +0/−17
- source/library/Rattletrap/Encode/LoadoutsAttribute.hs +0/−14
- source/library/Rattletrap/Encode/LoadoutsOnlineAttribute.hs +0/−18
- source/library/Rattletrap/Encode/LocationAttribute.hs +0/−13
- source/library/Rattletrap/Encode/Mark.hs +0/−15
- source/library/Rattletrap/Encode/Message.hs +0/−16
- source/library/Rattletrap/Encode/MusicStingerAttribute.hs +0/−16
- source/library/Rattletrap/Encode/PartyLeaderAttribute.hs +0/−19
- source/library/Rattletrap/Encode/PickupAttribute.hs +0/−18
- source/library/Rattletrap/Encode/PickupAttributeNew.hs +0/−19
- source/library/Rattletrap/Encode/PlayerHistoryKeyAttribute.hs +0/−13
- source/library/Rattletrap/Encode/PrivateMatchSettingsAttribute.hs +0/−26
- source/library/Rattletrap/Encode/ProductAttribute.hs +0/−37
- source/library/Rattletrap/Encode/Property.hs +0/−17
- source/library/Rattletrap/Encode/PropertyValue.hs +0/−30
- source/library/Rattletrap/Encode/QWordAttribute.hs +0/−13
- source/library/Rattletrap/Encode/Quaternion.hs +0/−41
- source/library/Rattletrap/Encode/RemoteId.hs +0/−37
- source/library/Rattletrap/Encode/Replay.hs +0/−21
- source/library/Rattletrap/Encode/Replication.hs +0/−26
- source/library/Rattletrap/Encode/ReplicationValue.hs +0/−25
- source/library/Rattletrap/Encode/ReservationAttribute.hs +0/−24
- source/library/Rattletrap/Encode/RigidBodyStateAttribute.hs +0/−22
- source/library/Rattletrap/Encode/Rotation.hs +0/−15
- source/library/Rattletrap/Encode/Section.hs +0/−31
- source/library/Rattletrap/Encode/SpawnedReplication.hs +0/−19
- source/library/Rattletrap/Encode/StatEventAttribute.hs +0/−14
- source/library/Rattletrap/Encode/Str.hs +0/−53
- source/library/Rattletrap/Encode/StringAttribute.hs +0/−13
- source/library/Rattletrap/Encode/TeamPaintAttribute.hs +0/−18
- source/library/Rattletrap/Encode/TitleAttribute.hs +0/−20
- source/library/Rattletrap/Encode/UniqueIdAttribute.hs +0/−16
- source/library/Rattletrap/Encode/UpdatedReplication.hs +0/−13
- source/library/Rattletrap/Encode/Vector.hs +0/−27
- source/library/Rattletrap/Encode/WeldedInfoAttribute.hs +0/−20
- source/library/Rattletrap/Encode/Word32le.hs +0/−21
- source/library/Rattletrap/Encode/Word64le.hs +0/−21
- source/library/Rattletrap/Encode/Word8le.hs +0/−21
- source/library/Rattletrap/Type/AppliedDamageAttribute.hs +0/−20
- source/library/Rattletrap/Type/Attribute.hs +0/−21
- source/library/Rattletrap/Type/AttributeMapping.hs +0/−16
- source/library/Rattletrap/Type/AttributeType.hs +0/−50
- source/library/Rattletrap/Type/AttributeValue.hs +0/−87
- source/library/Rattletrap/Type/BooleanAttribute.hs +0/−14
- source/library/Rattletrap/Type/ByteAttribute.hs +0/−15
- source/library/Rattletrap/Type/Cache.hs +0/−20
- source/library/Rattletrap/Type/CamSettingsAttribute.hs +0/−21
- source/library/Rattletrap/Type/ClassAttributeMap.hs +0/−324
- source/library/Rattletrap/Type/ClassMapping.hs +0/−17
- source/library/Rattletrap/Type/ClubColorsAttribute.hs +0/−18
- source/library/Rattletrap/Type/Common.hs +0/−56
- source/library/Rattletrap/Type/CompressedWord.hs +0/−17
- source/library/Rattletrap/Type/CompressedWordVector.hs +0/−17
- source/library/Rattletrap/Type/Content.hs +0/−71
- source/library/Rattletrap/Type/CustomDemolishAttribute.hs +0/−18
- source/library/Rattletrap/Type/DamageStateAttribute.hs +0/−22
- source/library/Rattletrap/Type/DemolishAttribute.hs +0/−21
- source/library/Rattletrap/Type/DestroyedReplication.hs +0/−16
- source/library/Rattletrap/Type/Dictionary.hs +0/−69
- source/library/Rattletrap/Type/EnumAttribute.hs +0/−14
- source/library/Rattletrap/Type/ExplosionAttribute.hs +0/−18
- source/library/Rattletrap/Type/ExtendedExplosionAttribute.hs +0/−17
- source/library/Rattletrap/Type/FlaggedByteAttribute.hs +0/−16
- source/library/Rattletrap/Type/FlaggedIntAttribute.hs +0/−16
- source/library/Rattletrap/Type/Float32le.hs +0/−14
- source/library/Rattletrap/Type/FloatAttribute.hs +0/−15
- source/library/Rattletrap/Type/Frame.hs +0/−21
- source/library/Rattletrap/Type/GameModeAttribute.hs +0/−19
- source/library/Rattletrap/Type/Header.hs +0/−61
- source/library/Rattletrap/Type/Initialization.hs +0/−21
- source/library/Rattletrap/Type/Int32le.hs +0/−14
- source/library/Rattletrap/Type/Int64Attribute.hs +0/−15
- source/library/Rattletrap/Type/Int64le.hs +0/−28
- source/library/Rattletrap/Type/Int8Vector.hs +0/−17
- source/library/Rattletrap/Type/Int8le.hs +0/−14
- source/library/Rattletrap/Type/IntAttribute.hs +0/−15
- source/library/Rattletrap/Type/KeyFrame.hs +0/−21
- source/library/Rattletrap/Type/List.hs +0/−14
- source/library/Rattletrap/Type/LoadoutAttribute.hs +0/−33
- source/library/Rattletrap/Type/LoadoutOnlineAttribute.hs +0/−15
- source/library/Rattletrap/Type/LoadoutsAttribute.hs +0/−16
- source/library/Rattletrap/Type/LoadoutsOnlineAttribute.hs +0/−18
- source/library/Rattletrap/Type/LocationAttribute.hs +0/−15
- source/library/Rattletrap/Type/Mark.hs +0/−19
- source/library/Rattletrap/Type/Message.hs +0/−21
- source/library/Rattletrap/Type/MusicStingerAttribute.hs +0/−18
- source/library/Rattletrap/Type/PartyLeaderAttribute.hs +0/−17
- source/library/Rattletrap/Type/PickupAttribute.hs +0/−16
- source/library/Rattletrap/Type/PickupAttributeNew.hs +0/−17
- source/library/Rattletrap/Type/PlayerHistoryKeyAttribute.hs +0/−14
- source/library/Rattletrap/Type/PrivateMatchSettingsAttribute.hs +0/−21
- source/library/Rattletrap/Type/ProductAttribute.hs +0/−35
- source/library/Rattletrap/Type/Property.hs +0/−20
- source/library/Rattletrap/Type/PropertyValue.hs +0/−32
- source/library/Rattletrap/Type/QWordAttribute.hs +0/−15
- source/library/Rattletrap/Type/Quaternion.hs +0/−98
- source/library/Rattletrap/Type/RemoteId.hs +0/−23
- source/library/Rattletrap/Type/Replay.hs +0/−21
- source/library/Rattletrap/Type/Replication.hs +0/−17
- source/library/Rattletrap/Type/ReplicationValue.hs +0/−22
- source/library/Rattletrap/Type/ReservationAttribute.hs +0/−22
- source/library/Rattletrap/Type/RigidBodyStateAttribute.hs +0/−20
- source/library/Rattletrap/Type/Rotation.hs +0/−17
- source/library/Rattletrap/Type/Section.hs +0/−41
- source/library/Rattletrap/Type/SpawnedReplication.hs +0/−30
- source/library/Rattletrap/Type/StatEventAttribute.hs +0/−16
- source/library/Rattletrap/Type/Str.hs +0/−24
- source/library/Rattletrap/Type/StringAttribute.hs +0/−15
- source/library/Rattletrap/Type/TeamPaintAttribute.hs +0/−20
- source/library/Rattletrap/Type/TitleAttribute.hs +0/−22
- source/library/Rattletrap/Type/UniqueIdAttribute.hs +0/−18
- source/library/Rattletrap/Type/UpdatedReplication.hs +0/−15
- source/library/Rattletrap/Type/Vector.hs +0/−26
- source/library/Rattletrap/Type/WeldedInfoAttribute.hs +0/−22
- source/library/Rattletrap/Type/Word32le.hs +0/−14
- source/library/Rattletrap/Type/Word64le.hs +0/−28
- source/library/Rattletrap/Type/Word8le.hs +0/−14
- source/library/Rattletrap/Utility/Bytes.hs +0/−33
- source/library/Rattletrap/Utility/Crc.hs +0/−47
- source/library/Rattletrap/Utility/Helper.hs +0/−46
- source/test-suite/Main.hs +0/−199
- src/exe/Main.hs +6/−0
- src/lib/Rattletrap.hs +162/−0
- src/lib/Rattletrap/Console/Main.hs +238/−0
- src/lib/Rattletrap/Data.hs +665/−0
- src/lib/Rattletrap/Decode/AppliedDamageAttribute.hs +19/−0
- src/lib/Rattletrap/Decode/Attribute.hs +73/−0
- src/lib/Rattletrap/Decode/AttributeMapping.hs +12/−0
- src/lib/Rattletrap/Decode/AttributeValue.hs +131/−0
- src/lib/Rattletrap/Decode/BooleanAttribute.hs +10/−0
- src/lib/Rattletrap/Decode/ByteAttribute.hs +11/−0
- src/lib/Rattletrap/Decode/Cache.hs +18/−0
- src/lib/Rattletrap/Decode/CamSettingsAttribute.hs +20/−0
- src/lib/Rattletrap/Decode/ClassMapping.hs +12/−0
- src/lib/Rattletrap/Decode/ClubColorsAttribute.hs +16/−0
- src/lib/Rattletrap/Decode/Common.hs +70/−0
- src/lib/Rattletrap/Decode/CompressedWord.hs +30/−0
- src/lib/Rattletrap/Decode/CompressedWordVector.hs +18/−0
- src/lib/Rattletrap/Decode/Content.hs +71/−0
- src/lib/Rattletrap/Decode/CustomDemolishAttribute.hs +16/−0
- src/lib/Rattletrap/Decode/DamageStateAttribute.hs +21/−0
- src/lib/Rattletrap/Decode/DemolishAttribute.hs +19/−0
- src/lib/Rattletrap/Decode/DestroyedReplication.hs +10/−0
- src/lib/Rattletrap/Decode/Dictionary.hs +17/−0
- src/lib/Rattletrap/Decode/EnumAttribute.hs +10/−0
- src/lib/Rattletrap/Decode/ExplosionAttribute.hs +17/−0
- src/lib/Rattletrap/Decode/ExtendedExplosionAttribute.hs +16/−0
- src/lib/Rattletrap/Decode/FlaggedByteAttribute.hs +13/−0
- src/lib/Rattletrap/Decode/FlaggedIntAttribute.hs +12/−0
- src/lib/Rattletrap/Decode/Float32le.hs +14/−0
- src/lib/Rattletrap/Decode/FloatAttribute.hs +11/−0
- src/lib/Rattletrap/Decode/Frame.hs +43/−0
- src/lib/Rattletrap/Decode/GameModeAttribute.hs +15/−0
- src/lib/Rattletrap/Decode/Header.hs +22/−0
- src/lib/Rattletrap/Decode/Initialization.hs +16/−0
- src/lib/Rattletrap/Decode/Int32le.hs +14/−0
- src/lib/Rattletrap/Decode/Int64Attribute.hs +11/−0
- src/lib/Rattletrap/Decode/Int64le.hs +13/−0
- src/lib/Rattletrap/Decode/Int8Vector.hs +18/−0
- src/lib/Rattletrap/Decode/Int8le.hs +13/−0
- src/lib/Rattletrap/Decode/IntAttribute.hs +11/−0
- src/lib/Rattletrap/Decode/KeyFrame.hs +13/−0
- src/lib/Rattletrap/Decode/List.hs +16/−0
- src/lib/Rattletrap/Decode/LoadoutAttribute.hs +31/−0
- src/lib/Rattletrap/Decode/LoadoutOnlineAttribute.hs +25/−0
- src/lib/Rattletrap/Decode/LoadoutsAttribute.hs +14/−0
- src/lib/Rattletrap/Decode/LoadoutsOnlineAttribute.hs +23/−0
- src/lib/Rattletrap/Decode/LocationAttribute.hs +12/−0
- src/lib/Rattletrap/Decode/Mark.hs +12/−0
- src/lib/Rattletrap/Decode/Message.hs +12/−0
- src/lib/Rattletrap/Decode/MusicStingerAttribute.hs +16/−0
- src/lib/Rattletrap/Decode/PartyLeaderAttribute.hs +18/−0
- src/lib/Rattletrap/Decode/PickupAttribute.hs +13/−0
- src/lib/Rattletrap/Decode/PickupAttributeNew.hs +16/−0
- src/lib/Rattletrap/Decode/PlayerHistoryKeyAttribute.hs +11/−0
- src/lib/Rattletrap/Decode/PrivateMatchSettingsAttribute.hs +20/−0
- src/lib/Rattletrap/Decode/ProductAttribute.hs +70/−0
- src/lib/Rattletrap/Decode/Property.hs +15/−0
- src/lib/Rattletrap/Decode/PropertyValue.hs +31/−0
- src/lib/Rattletrap/Decode/QWordAttribute.hs +11/−0
- src/lib/Rattletrap/Decode/Quaternion.hs +26/−0
- src/lib/Rattletrap/Decode/RemoteId.hs +49/−0
- src/lib/Rattletrap/Decode/Replay.hs +66/−0
- src/lib/Rattletrap/Decode/Replication.hs +45/−0
- src/lib/Rattletrap/Decode/ReplicationValue.hs +45/−0
- src/lib/Rattletrap/Decode/ReservationAttribute.hs +25/−0
- src/lib/Rattletrap/Decode/RigidBodyStateAttribute.hs +19/−0
- src/lib/Rattletrap/Decode/Rotation.hs +14/−0
- src/lib/Rattletrap/Decode/Section.hs +30/−0
- src/lib/Rattletrap/Decode/SpawnedReplication.hs +72/−0
- src/lib/Rattletrap/Decode/StatEventAttribute.hs +12/−0
- src/lib/Rattletrap/Decode/Str.hs +47/−0
- src/lib/Rattletrap/Decode/StringAttribute.hs +11/−0
- src/lib/Rattletrap/Decode/TeamPaintAttribute.hs +18/−0
- src/lib/Rattletrap/Decode/TitleAttribute.hs +20/−0
- src/lib/Rattletrap/Decode/UniqueIdAttribute.hs +16/−0
- src/lib/Rattletrap/Decode/UpdatedReplication.hs +22/−0
- src/lib/Rattletrap/Decode/Vector.hs +29/−0
- src/lib/Rattletrap/Decode/WeldedInfoAttribute.hs +21/−0
- src/lib/Rattletrap/Decode/Word32le.hs +14/−0
- src/lib/Rattletrap/Decode/Word64le.hs +14/−0
- src/lib/Rattletrap/Decode/Word8le.hs +14/−0
- src/lib/Rattletrap/Encode/AppliedDamageAttribute.hs +18/−0
- src/lib/Rattletrap/Encode/Attribute.hs +26/−0
- src/lib/Rattletrap/Encode/AttributeMapping.hs +14/−0
- src/lib/Rattletrap/Encode/AttributeValue.hs +85/−0
- src/lib/Rattletrap/Encode/BooleanAttribute.hs +12/−0
- src/lib/Rattletrap/Encode/ByteAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/Cache.hs +18/−0
- src/lib/Rattletrap/Encode/CamSettingsAttribute.hs +21/−0
- src/lib/Rattletrap/Encode/ClassMapping.hs +15/−0
- src/lib/Rattletrap/Encode/ClubColorsAttribute.hs +16/−0
- src/lib/Rattletrap/Encode/Common.hs +10/−0
- src/lib/Rattletrap/Encode/CompressedWord.hs +44/−0
- src/lib/Rattletrap/Encode/CompressedWordVector.hs +15/−0
- src/lib/Rattletrap/Encode/Content.hs +43/−0
- src/lib/Rattletrap/Encode/CustomDemolishAttribute.hs +16/−0
- src/lib/Rattletrap/Encode/DamageStateAttribute.hs +20/−0
- src/lib/Rattletrap/Encode/DemolishAttribute.hs +19/−0
- src/lib/Rattletrap/Encode/DestroyedReplication.hs +11/−0
- src/lib/Rattletrap/Encode/Dictionary.hs +17/−0
- src/lib/Rattletrap/Encode/EnumAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/ExplosionAttribute.hs +16/−0
- src/lib/Rattletrap/Encode/ExtendedExplosionAttribute.hs +16/−0
- src/lib/Rattletrap/Encode/FlaggedByteAttribute.hs +14/−0
- src/lib/Rattletrap/Encode/FlaggedIntAttribute.hs +14/−0
- src/lib/Rattletrap/Encode/Float32le.hs +21/−0
- src/lib/Rattletrap/Encode/FloatAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/Frame.hs +24/−0
- src/lib/Rattletrap/Encode/GameModeAttribute.hs +14/−0
- src/lib/Rattletrap/Encode/Header.hs +22/−0
- src/lib/Rattletrap/Encode/Initialization.hs +19/−0
- src/lib/Rattletrap/Encode/Int32le.hs +21/−0
- src/lib/Rattletrap/Encode/Int64Attribute.hs +13/−0
- src/lib/Rattletrap/Encode/Int64le.hs +20/−0
- src/lib/Rattletrap/Encode/Int8Vector.hs +23/−0
- src/lib/Rattletrap/Encode/Int8le.hs +19/−0
- src/lib/Rattletrap/Encode/IntAttribute.hs +12/−0
- src/lib/Rattletrap/Encode/KeyFrame.hs +16/−0
- src/lib/Rattletrap/Encode/List.hs +16/−0
- src/lib/Rattletrap/Encode/LoadoutAttribute.hs +35/−0
- src/lib/Rattletrap/Encode/LoadoutOnlineAttribute.hs +17/−0
- src/lib/Rattletrap/Encode/LoadoutsAttribute.hs +14/−0
- src/lib/Rattletrap/Encode/LoadoutsOnlineAttribute.hs +18/−0
- src/lib/Rattletrap/Encode/LocationAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/Mark.hs +15/−0
- src/lib/Rattletrap/Encode/Message.hs +16/−0
- src/lib/Rattletrap/Encode/MusicStingerAttribute.hs +16/−0
- src/lib/Rattletrap/Encode/PartyLeaderAttribute.hs +19/−0
- src/lib/Rattletrap/Encode/PickupAttribute.hs +18/−0
- src/lib/Rattletrap/Encode/PickupAttributeNew.hs +19/−0
- src/lib/Rattletrap/Encode/PlayerHistoryKeyAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/PrivateMatchSettingsAttribute.hs +26/−0
- src/lib/Rattletrap/Encode/ProductAttribute.hs +37/−0
- src/lib/Rattletrap/Encode/Property.hs +17/−0
- src/lib/Rattletrap/Encode/PropertyValue.hs +30/−0
- src/lib/Rattletrap/Encode/QWordAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/Quaternion.hs +41/−0
- src/lib/Rattletrap/Encode/RemoteId.hs +37/−0
- src/lib/Rattletrap/Encode/Replay.hs +21/−0
- src/lib/Rattletrap/Encode/Replication.hs +26/−0
- src/lib/Rattletrap/Encode/ReplicationValue.hs +25/−0
- src/lib/Rattletrap/Encode/ReservationAttribute.hs +24/−0
- src/lib/Rattletrap/Encode/RigidBodyStateAttribute.hs +22/−0
- src/lib/Rattletrap/Encode/Rotation.hs +15/−0
- src/lib/Rattletrap/Encode/Section.hs +31/−0
- src/lib/Rattletrap/Encode/SpawnedReplication.hs +19/−0
- src/lib/Rattletrap/Encode/StatEventAttribute.hs +14/−0
- src/lib/Rattletrap/Encode/Str.hs +53/−0
- src/lib/Rattletrap/Encode/StringAttribute.hs +13/−0
- src/lib/Rattletrap/Encode/TeamPaintAttribute.hs +18/−0
- src/lib/Rattletrap/Encode/TitleAttribute.hs +20/−0
- src/lib/Rattletrap/Encode/UniqueIdAttribute.hs +16/−0
- src/lib/Rattletrap/Encode/UpdatedReplication.hs +13/−0
- src/lib/Rattletrap/Encode/Vector.hs +27/−0
- src/lib/Rattletrap/Encode/WeldedInfoAttribute.hs +20/−0
- src/lib/Rattletrap/Encode/Word32le.hs +21/−0
- src/lib/Rattletrap/Encode/Word64le.hs +21/−0
- src/lib/Rattletrap/Encode/Word8le.hs too large to diff
- src/lib/Rattletrap/Type/AppliedDamageAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Attribute.hs too large to diff
- src/lib/Rattletrap/Type/AttributeMapping.hs too large to diff
- src/lib/Rattletrap/Type/AttributeType.hs too large to diff
- src/lib/Rattletrap/Type/AttributeValue.hs too large to diff
- src/lib/Rattletrap/Type/BooleanAttribute.hs too large to diff
- src/lib/Rattletrap/Type/ByteAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Cache.hs too large to diff
- src/lib/Rattletrap/Type/CamSettingsAttribute.hs too large to diff
- src/lib/Rattletrap/Type/ClassAttributeMap.hs too large to diff
- src/lib/Rattletrap/Type/ClassMapping.hs too large to diff
- src/lib/Rattletrap/Type/ClubColorsAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Common.hs too large to diff
- src/lib/Rattletrap/Type/CompressedWord.hs too large to diff
- src/lib/Rattletrap/Type/CompressedWordVector.hs too large to diff
- src/lib/Rattletrap/Type/Content.hs too large to diff
- src/lib/Rattletrap/Type/CustomDemolishAttribute.hs too large to diff
- src/lib/Rattletrap/Type/DamageStateAttribute.hs too large to diff
- src/lib/Rattletrap/Type/DemolishAttribute.hs too large to diff
- src/lib/Rattletrap/Type/DestroyedReplication.hs too large to diff
- src/lib/Rattletrap/Type/Dictionary.hs too large to diff
- src/lib/Rattletrap/Type/EnumAttribute.hs too large to diff
- src/lib/Rattletrap/Type/ExplosionAttribute.hs too large to diff
- src/lib/Rattletrap/Type/ExtendedExplosionAttribute.hs too large to diff
- src/lib/Rattletrap/Type/FlaggedByteAttribute.hs too large to diff
- src/lib/Rattletrap/Type/FlaggedIntAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Float32le.hs too large to diff
- src/lib/Rattletrap/Type/FloatAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Frame.hs too large to diff
- src/lib/Rattletrap/Type/GameModeAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Header.hs too large to diff
- src/lib/Rattletrap/Type/Initialization.hs too large to diff
- src/lib/Rattletrap/Type/Int32le.hs too large to diff
- src/lib/Rattletrap/Type/Int64Attribute.hs too large to diff
- src/lib/Rattletrap/Type/Int64le.hs too large to diff
- src/lib/Rattletrap/Type/Int8Vector.hs too large to diff
- src/lib/Rattletrap/Type/Int8le.hs too large to diff
- src/lib/Rattletrap/Type/IntAttribute.hs too large to diff
- src/lib/Rattletrap/Type/KeyFrame.hs too large to diff
- src/lib/Rattletrap/Type/List.hs too large to diff
- src/lib/Rattletrap/Type/LoadoutAttribute.hs too large to diff
- src/lib/Rattletrap/Type/LoadoutOnlineAttribute.hs too large to diff
- src/lib/Rattletrap/Type/LoadoutsAttribute.hs too large to diff
- src/lib/Rattletrap/Type/LoadoutsOnlineAttribute.hs too large to diff
- src/lib/Rattletrap/Type/LocationAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Mark.hs too large to diff
- src/lib/Rattletrap/Type/Message.hs too large to diff
- src/lib/Rattletrap/Type/MusicStingerAttribute.hs too large to diff
- src/lib/Rattletrap/Type/PartyLeaderAttribute.hs too large to diff
- src/lib/Rattletrap/Type/PickupAttribute.hs too large to diff
- src/lib/Rattletrap/Type/PickupAttributeNew.hs too large to diff
- src/lib/Rattletrap/Type/PlayerHistoryKeyAttribute.hs too large to diff
- src/lib/Rattletrap/Type/PrivateMatchSettingsAttribute.hs too large to diff
- src/lib/Rattletrap/Type/ProductAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Property.hs too large to diff
- src/lib/Rattletrap/Type/PropertyValue.hs too large to diff
- src/lib/Rattletrap/Type/QWordAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Quaternion.hs too large to diff
- src/lib/Rattletrap/Type/RemoteId.hs too large to diff
- src/lib/Rattletrap/Type/Replay.hs too large to diff
- src/lib/Rattletrap/Type/Replication.hs too large to diff
- src/lib/Rattletrap/Type/ReplicationValue.hs too large to diff
- src/lib/Rattletrap/Type/ReservationAttribute.hs too large to diff
- src/lib/Rattletrap/Type/RigidBodyStateAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Rotation.hs too large to diff
- src/lib/Rattletrap/Type/Section.hs too large to diff
- src/lib/Rattletrap/Type/SpawnedReplication.hs too large to diff
- src/lib/Rattletrap/Type/StatEventAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Str.hs too large to diff
- src/lib/Rattletrap/Type/StringAttribute.hs too large to diff
- src/lib/Rattletrap/Type/TeamPaintAttribute.hs too large to diff
- src/lib/Rattletrap/Type/TitleAttribute.hs too large to diff
- src/lib/Rattletrap/Type/UniqueIdAttribute.hs too large to diff
- src/lib/Rattletrap/Type/UpdatedReplication.hs too large to diff
- src/lib/Rattletrap/Type/Vector.hs too large to diff
- src/lib/Rattletrap/Type/WeldedInfoAttribute.hs too large to diff
- src/lib/Rattletrap/Type/Word32le.hs too large to diff
- src/lib/Rattletrap/Type/Word64le.hs too large to diff
- src/lib/Rattletrap/Type/Word8le.hs too large to diff
- src/lib/Rattletrap/Utility/Bytes.hs too large to diff
- src/lib/Rattletrap/Utility/Crc.hs too large to diff
- src/lib/Rattletrap/Utility/Helper.hs too large to diff
- src/test/Main.hs too large to diff
@@ -1,9 +1,7 @@ # [Rattletrap][] [![Version badge][]][version]-[![Windows build badge][]][windows build] [![Build badge][]][build]-[![Docker build badge][]][docker build] Rattletrap parses and generates [Rocket League][] replays. Parsing replays can be used to analyze data in order to collect high-level statistics like players@@ -127,12 +125,8 @@ [Rattletrap]: https://github.com/tfausak/rattletrap [Version badge]: https://img.shields.io/hackage/v/rattletrap.svg?logo=haskell&label=version&color=brightgreen [version]: https://hackage.haskell.org/package/rattletrap-[Windows build badge]: https://img.shields.io/appveyor/ci/taylorfausak/rattletrap/master.svg?logo=appveyor&logoColor=white-[windows build]: https://ci.appveyor.com/project/taylorfausak/rattletrap-[Build badge]: https://img.shields.io/travis/tfausak/rattletrap/master.svg?logo=travis-ci&logoColor=white-[build]: https://travis-ci.org/tfausak/rattletrap-[Docker build badge]: https://img.shields.io/docker/build/taylorfausak/rattletrap.svg?label=docker&logo=docker&logoColor=white-[docker build]: https://hub.docker.com/r/taylorfausak/rattletrap+[Build badge]: https://github.com/tfausak/rattletrap/workflows/CI/badge.svg+[build]: https://github.com/tfausak/rattletrap/actions [Rocket League]: https://www.rocketleague.com [1.88]: https://www.rocketleague.com/news/patch-notes--december-update/ [Ball Chasing]: https://ballchasing.com
@@ -1,7 +1,7 @@ cabal-version: >= 1.10 name: rattletrap-version: 9.3.1+version: 9.3.2 synopsis: Parse and generate Rocket League replays. description: Rattletrap parses and generates Rocket League replays. @@ -47,7 +47,7 @@ -Wno-missing-import-lists -Wno-safe -Wno-unsafe- hs-source-dirs: source/library+ hs-source-dirs: src/lib other-modules: Paths_rattletrap Rattletrap.Console.Main@@ -304,7 +304,7 @@ , rattletrap -any default-language: Haskell2010 ghc-options: -rtsopts -threaded- hs-source-dirs: source/executable+ hs-source-dirs: src/exe main-is: Main.hs if flag(static)@@ -320,6 +320,6 @@ , temporary >= 1.3 && < 1.4 default-language: Haskell2010 ghc-options: -rtsopts -threaded- hs-source-dirs: source/test-suite+ hs-source-dirs: src/test main-is: Main.hs type: exitcode-stdio-1.0
@@ -1,6 +0,0 @@-module Main- ( main- )-where--import Rattletrap (main)
@@ -1,162 +0,0 @@-module Rattletrap- ( Rattletrap.Console.Main.main- , Rattletrap.Console.Main.rattletrap- , Rattletrap.Utility.Helper.decodeReplayFile- , Rattletrap.Utility.Helper.encodeReplayJson- , Rattletrap.Utility.Helper.decodeReplayJson- , Rattletrap.Utility.Helper.encodeReplayFile- , Rattletrap.Type.AppliedDamageAttribute.AppliedDamageAttribute(..)- , Rattletrap.Type.Attribute.Attribute(..)- , Rattletrap.Type.AttributeMapping.AttributeMapping(..)- , Rattletrap.Type.AttributeType.AttributeType(..)- , Rattletrap.Type.AttributeValue.AttributeValue(..)- , Rattletrap.Type.BooleanAttribute.BooleanAttribute(..)- , Rattletrap.Type.ByteAttribute.ByteAttribute(..)- , Rattletrap.Type.Cache.Cache(..)- , Rattletrap.Type.CamSettingsAttribute.CamSettingsAttribute(..)- , Rattletrap.Type.ClassAttributeMap.ClassAttributeMap(..)- , Rattletrap.Type.ClassMapping.ClassMapping(..)- , Rattletrap.Type.ClubColorsAttribute.ClubColorsAttribute(..)- , Rattletrap.Type.CompressedWord.CompressedWord(..)- , Rattletrap.Type.CompressedWordVector.CompressedWordVector(..)- , Rattletrap.Type.Content.Content(..)- , Rattletrap.Type.DamageStateAttribute.DamageStateAttribute(..)- , Rattletrap.Type.DemolishAttribute.DemolishAttribute(..)- , Rattletrap.Type.DestroyedReplication.DestroyedReplication(..)- , Rattletrap.Type.Dictionary.Dictionary(..)- , Rattletrap.Type.EnumAttribute.EnumAttribute(..)- , Rattletrap.Type.ExplosionAttribute.ExplosionAttribute(..)- , Rattletrap.Type.ExtendedExplosionAttribute.ExtendedExplosionAttribute(..)- , Rattletrap.Type.FlaggedIntAttribute.FlaggedIntAttribute(..)- , Rattletrap.Type.Float32le.Float32le(..)- , Rattletrap.Type.FloatAttribute.FloatAttribute(..)- , Rattletrap.Type.Frame.Frame(..)- , Rattletrap.Type.GameModeAttribute.GameModeAttribute(..)- , Rattletrap.Type.Header.Header(..)- , Rattletrap.Type.Initialization.Initialization(..)- , Rattletrap.Type.Int32le.Int32le(..)- , Rattletrap.Type.Int64Attribute.Int64Attribute(..)- , Rattletrap.Type.Int64le.Int64le(..)- , Rattletrap.Type.Int8le.Int8le(..)- , Rattletrap.Type.Int8Vector.Int8Vector(..)- , Rattletrap.Type.IntAttribute.IntAttribute(..)- , Rattletrap.Type.KeyFrame.KeyFrame(..)- , Rattletrap.Type.List.List(..)- , Rattletrap.Type.LoadoutAttribute.LoadoutAttribute(..)- , Rattletrap.Type.LoadoutOnlineAttribute.LoadoutOnlineAttribute(..)- , Rattletrap.Type.LoadoutsAttribute.LoadoutsAttribute(..)- , Rattletrap.Type.LoadoutsOnlineAttribute.LoadoutsOnlineAttribute(..)- , Rattletrap.Type.LocationAttribute.LocationAttribute(..)- , Rattletrap.Type.Mark.Mark(..)- , Rattletrap.Type.Message.Message(..)- , Rattletrap.Type.MusicStingerAttribute.MusicStingerAttribute(..)- , Rattletrap.Type.PartyLeaderAttribute.PartyLeaderAttribute(..)- , Rattletrap.Type.PickupAttribute.PickupAttribute(..)- , Rattletrap.Type.PlayerHistoryKeyAttribute.PlayerHistoryKeyAttribute(..)- , Rattletrap.Type.PrivateMatchSettingsAttribute.PrivateMatchSettingsAttribute(..)- , Rattletrap.Type.ProductAttribute.ProductAttribute(..)- , Rattletrap.Type.Property.Property(..)- , Rattletrap.Type.PropertyValue.PropertyValue(..)- , Rattletrap.Type.Quaternion.Quaternion(..)- , Rattletrap.Type.QWordAttribute.QWordAttribute(..)- , Rattletrap.Type.RemoteId.RemoteId(..)- , Rattletrap.Type.Replay.Replay(..)- , Rattletrap.Type.Replication.Replication(..)- , Rattletrap.Type.ReplicationValue.ReplicationValue(..)- , Rattletrap.Type.ReservationAttribute.ReservationAttribute(..)- , Rattletrap.Type.RigidBodyStateAttribute.RigidBodyStateAttribute(..)- , Rattletrap.Type.Rotation.Rotation(..)- , Rattletrap.Type.Section.Section(..)- , Rattletrap.Type.SpawnedReplication.SpawnedReplication(..)- , Rattletrap.Type.StatEventAttribute.StatEventAttribute(..)- , Rattletrap.Type.Str.Str(..)- , Rattletrap.Type.StringAttribute.StringAttribute(..)- , Rattletrap.Type.TeamPaintAttribute.TeamPaintAttribute(..)- , Rattletrap.Type.TitleAttribute.TitleAttribute(..)- , Rattletrap.Type.UniqueIdAttribute.UniqueIdAttribute(..)- , Rattletrap.Type.UpdatedReplication.UpdatedReplication(..)- , Rattletrap.Type.Vector.Vector(..)- , Rattletrap.Type.WeldedInfoAttribute.WeldedInfoAttribute(..)- , Rattletrap.Type.Word32le.Word32le(..)- , Rattletrap.Type.Word64le.Word64le(..)- , Rattletrap.Type.Word8le.Word8le(..)- )-where--import qualified Rattletrap.Console.Main-import qualified Rattletrap.Type.AppliedDamageAttribute-import qualified Rattletrap.Type.Attribute-import qualified Rattletrap.Type.AttributeMapping-import qualified Rattletrap.Type.AttributeType-import qualified Rattletrap.Type.AttributeValue-import qualified Rattletrap.Type.BooleanAttribute-import qualified Rattletrap.Type.ByteAttribute-import qualified Rattletrap.Type.Cache-import qualified Rattletrap.Type.CamSettingsAttribute-import qualified Rattletrap.Type.ClassAttributeMap-import qualified Rattletrap.Type.ClassMapping-import qualified Rattletrap.Type.ClubColorsAttribute-import qualified Rattletrap.Type.CompressedWord-import qualified Rattletrap.Type.CompressedWordVector-import qualified Rattletrap.Type.Content-import qualified Rattletrap.Type.DamageStateAttribute-import qualified Rattletrap.Type.DemolishAttribute-import qualified Rattletrap.Type.DestroyedReplication-import qualified Rattletrap.Type.Dictionary-import qualified Rattletrap.Type.EnumAttribute-import qualified Rattletrap.Type.ExplosionAttribute-import qualified Rattletrap.Type.ExtendedExplosionAttribute-import qualified Rattletrap.Type.FlaggedIntAttribute-import qualified Rattletrap.Type.Float32le-import qualified Rattletrap.Type.FloatAttribute-import qualified Rattletrap.Type.Frame-import qualified Rattletrap.Type.GameModeAttribute-import qualified Rattletrap.Type.Header-import qualified Rattletrap.Type.Initialization-import qualified Rattletrap.Type.Int32le-import qualified Rattletrap.Type.Int64Attribute-import qualified Rattletrap.Type.Int64le-import qualified Rattletrap.Type.Int8le-import qualified Rattletrap.Type.Int8Vector-import qualified Rattletrap.Type.IntAttribute-import qualified Rattletrap.Type.KeyFrame-import qualified Rattletrap.Type.List-import qualified Rattletrap.Type.LoadoutAttribute-import qualified Rattletrap.Type.LoadoutOnlineAttribute-import qualified Rattletrap.Type.LoadoutsAttribute-import qualified Rattletrap.Type.LoadoutsOnlineAttribute-import qualified Rattletrap.Type.LocationAttribute-import qualified Rattletrap.Type.Mark-import qualified Rattletrap.Type.Message-import qualified Rattletrap.Type.MusicStingerAttribute-import qualified Rattletrap.Type.PartyLeaderAttribute-import qualified Rattletrap.Type.PickupAttribute-import qualified Rattletrap.Type.PlayerHistoryKeyAttribute-import qualified Rattletrap.Type.PrivateMatchSettingsAttribute-import qualified Rattletrap.Type.ProductAttribute-import qualified Rattletrap.Type.Property-import qualified Rattletrap.Type.PropertyValue-import qualified Rattletrap.Type.Quaternion-import qualified Rattletrap.Type.QWordAttribute-import qualified Rattletrap.Type.RemoteId-import qualified Rattletrap.Type.Replay-import qualified Rattletrap.Type.Replication-import qualified Rattletrap.Type.ReplicationValue-import qualified Rattletrap.Type.ReservationAttribute-import qualified Rattletrap.Type.RigidBodyStateAttribute-import qualified Rattletrap.Type.Rotation-import qualified Rattletrap.Type.Section-import qualified Rattletrap.Type.SpawnedReplication-import qualified Rattletrap.Type.StatEventAttribute-import qualified Rattletrap.Type.Str-import qualified Rattletrap.Type.StringAttribute-import qualified Rattletrap.Type.TeamPaintAttribute-import qualified Rattletrap.Type.TitleAttribute-import qualified Rattletrap.Type.UniqueIdAttribute-import qualified Rattletrap.Type.UpdatedReplication-import qualified Rattletrap.Type.Vector-import qualified Rattletrap.Type.WeldedInfoAttribute-import qualified Rattletrap.Type.Word32le-import qualified Rattletrap.Type.Word64le-import qualified Rattletrap.Type.Word8le-import qualified Rattletrap.Utility.Helper
@@ -1,238 +0,0 @@-module Rattletrap.Console.Main- ( main- , rattletrap- )-where--import qualified Control.Monad as Monad-import qualified Data.Aeson as Json-import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Lazy as LazyBytes-import qualified Data.Version as Version-import qualified Network.HTTP.Client as Client-import qualified Network.HTTP.Client.TLS as Client-import qualified Paths_rattletrap as This-import qualified Rattletrap.Type.Replay as Rattletrap-import qualified Rattletrap.Utility.Helper as Rattletrap-import qualified System.Console.GetOpt as Console-import qualified System.Environment as Environment-import qualified System.Exit as Exit-import qualified System.FilePath as Path-import qualified System.IO as IO-import qualified Text.Printf as Printf--main :: IO ()-main = do- name <- Environment.getProgName- arguments <- Environment.getArgs- rattletrap name arguments--rattletrap :: String -> [String] -> IO ()-rattletrap name arguments = do- config <- getConfig arguments- Monad.when (configHelp config) (printHelp name *> Exit.exitFailure)- Monad.when (configVersion config) (printVersion *> Exit.exitFailure)- input <- getInput config- let decode = getDecoder config- replay <- either fail pure (decode input)- let encode = getEncoder config- putOutput config (encode replay)--getDecoder :: Config -> Bytes.ByteString -> Either String Rattletrap.Replay-getDecoder config = case getMode config of- ModeDecode -> Rattletrap.decodeReplayFile $ configFast config- ModeEncode -> Rattletrap.decodeReplayJson--getEncoder :: Config -> Rattletrap.Replay -> Bytes.ByteString-getEncoder config = case getMode config of- ModeDecode -> if configCompact config- then LazyBytes.toStrict . Json.encode- else Rattletrap.encodeReplayJson- ModeEncode -> Rattletrap.encodeReplayFile $ configFast config--getInput :: Config -> IO Bytes.ByteString-getInput config = case configInput config of- Nothing -> Bytes.getContents- Just fileOrUrl -> case Client.parseUrlThrow fileOrUrl of- Nothing -> Bytes.readFile fileOrUrl- Just request -> do- manager <- Client.newTlsManager- response <- Client.httpLbs request manager- pure (LazyBytes.toStrict (Client.responseBody response))--putOutput :: Config -> Bytes.ByteString -> IO ()-putOutput = maybe Bytes.putStr Bytes.writeFile . configOutput--getConfig :: [String] -> IO Config-getConfig arguments = do- let- (updates, unexpectedArguments, unknownOptions, problems) =- Console.getOpt' Console.Permute options arguments- printUnexpectedArguments unexpectedArguments- printUnknownOptions unknownOptions- printProblems problems- Monad.unless (null problems) Exit.exitFailure- either fail pure (Monad.foldM applyUpdate defaultConfig updates)--type Option = Console.OptDescr Update--type Update = Config -> Either String Config--options :: [Option]-options =- [ compactOption- , fastOption- , helpOption- , inputOption- , modeOption- , outputOption- , versionOption- ]--compactOption :: Option-compactOption = Console.Option- ['c']- ["compact"]- (Console.NoArg (\config -> pure config { configCompact = True }))- "minify JSON output"--fastOption :: Option-fastOption = Console.Option- ['f']- ["fast"]- (Console.NoArg (\config -> pure config { configFast = True }))- "only encode or decode the header"--helpOption :: Option-helpOption = Console.Option- ['h']- ["help"]- (Console.NoArg (\config -> pure config { configHelp = True }))- "show the help"--inputOption :: Option-inputOption = Console.Option- ['i']- ["input"]- (Console.ReqArg- (\input config -> pure config { configInput = Just input })- "FILE|URL"- )- "input file or URL"--modeOption :: Option-modeOption = Console.Option- ['m']- ["mode"]- (Console.ReqArg- (\rawMode config -> do- mode <- parseMode rawMode- pure config { configMode = Just mode }- )- "MODE"- )- "decode or encode"--outputOption :: Option-outputOption = Console.Option- ['o']- ["output"]- (Console.ReqArg- (\output config -> pure config { configOutput = Just output })- "FILE"- )- "output file"--versionOption :: Option-versionOption = Console.Option- ['v']- ["version"]- (Console.NoArg (\config -> pure config { configVersion = True }))- "show the version"--applyUpdate :: Config -> Update -> Either String Config-applyUpdate config update = update config--data Config = Config- { configCompact :: Bool- , configFast :: Bool- , configHelp :: Bool- , configInput :: Maybe String- , configMode :: Maybe Mode- , configOutput :: Maybe String- , configVersion :: Bool- } deriving (Show)--defaultConfig :: Config-defaultConfig = Config- { configCompact = False- , configFast = False- , configHelp = False- , configInput = Nothing- , configMode = Nothing- , configOutput = Nothing- , configVersion = False- }--getMode :: Config -> Mode-getMode config = case getExtension (configInput config) of- ".json" -> ModeEncode- ".replay" -> ModeDecode- _ -> case getExtension (configOutput config) of- ".json" -> ModeDecode- ".replay" -> ModeEncode- _ -> ModeDecode--getExtension :: Maybe String -> String-getExtension = maybe "" Path.takeExtension--data Mode- = ModeDecode- | ModeEncode- deriving (Show)--parseMode :: String -> Either String Mode-parseMode mode = case mode of- "decode" -> Right ModeDecode- "encode" -> Right ModeEncode- _ -> Left (Printf.printf "invalid mode: %s" (show mode))--printUnexpectedArguments :: [String] -> IO ()-printUnexpectedArguments = mapM_ printUnexpectedArgument--printUnexpectedArgument :: String -> IO ()-printUnexpectedArgument =- warnLn . Printf.printf "WARNING: unexpected argument `%s'"--printUnknownOptions :: [String] -> IO ()-printUnknownOptions = mapM_ printUnknownOption--printUnknownOption :: String -> IO ()-printUnknownOption = warnLn . Printf.printf "WARNING: unknown option `%s'"--printProblems :: [String] -> IO ()-printProblems = mapM_ printProblem--printProblem :: String -> IO ()-printProblem = warn . Printf.printf "ERROR: %s"--printHelp :: String -> IO ()-printHelp = warn . help--help :: String -> String-help name = Console.usageInfo (header name) options--header :: String -> String-header name = unwords [name, "version", version]--version :: String-version = Version.showVersion This.version--printVersion :: IO ()-printVersion = warnLn version--warn :: String -> IO ()-warn = IO.hPutStr IO.stderr--warnLn :: String -> IO ()-warnLn = IO.hPutStrLn IO.stderr
@@ -1,665 +0,0 @@--- brittany --columns 120-module Rattletrap.Data- ( rawParentClasses- , rawClassesWithLocation- , rawClassesWithRotation- , rawObjectClasses- , rawAttributeTypes- , rawCrc32Table- )-where--import Rattletrap.Type.AttributeType--rawParentClasses :: [(String, String)]-rawParentClasses =- [ ("Engine.Actor", "Core.Object")- , ("Engine.GameReplicationInfo", "Engine.ReplicationInfo")- , ("Engine.Info", "Engine.Actor")- , ("Engine.Pawn", "Engine.Actor")- , ("Engine.PlayerReplicationInfo", "Engine.ReplicationInfo")- , ("Engine.ReplicationInfo", "Engine.Info")- , ("Engine.TeamInfo", "Engine.ReplicationInfo")- , ("ProjectX.GRI_X", "Engine.GameReplicationInfo")- , ("ProjectX.Pawn_X", "Engine.Pawn")- , ("ProjectX.PRI_X", "Engine.PlayerReplicationInfo")- , ("TAGame.Ball_God_TA", "TAGame.Ball_TA")- , ("TAGame.Ball_Haunted_TA", "TAGame.Ball_TA")- , ("TAGame.Ball_TA", "TAGame.RBActor_TA")- , ("TAGame.CameraSettingsActor_TA", "Engine.ReplicationInfo")- , ("TAGame.Car_Season_TA", "TAGame.PRI_TA")- , ("TAGame.Car_TA", "TAGame.Vehicle_TA")- , ("TAGame.CarComponent_Boost_TA", "TAGame.CarComponent_TA")- , ("TAGame.CarComponent_Dodge_TA", "TAGame.CarComponent_TA")- , ("TAGame.CarComponent_DoubleJump_TA", "TAGame.CarComponent_TA")- , ("TAGame.CarComponent_FlipCar_TA", "TAGame.CarComponent_TA")- , ("TAGame.CarComponent_Jump_TA", "TAGame.CarComponent_TA")- , ("TAGame.CarComponent_TA", "Engine.ReplicationInfo")- , ("TAGame.CrowdActor_TA", "Engine.ReplicationInfo")- , ("TAGame.CrowdManager_TA", "Engine.ReplicationInfo")- , ("TAGame.GameEvent_GodBall_TA", "TAGame.GameEvent_Soccar_TA")- , ("TAGame.GameEvent_Season_TA", "TAGame.GameEvent_Soccar_TA")- , ("TAGame.GameEvent_Soccar_TA", "TAGame.GameEvent_Team_TA")- , ("TAGame.GameEvent_SoccarPrivate_TA", "TAGame.GameEvent_Soccar_TA")- , ("TAGame.GameEvent_SoccarSplitscreen_TA", "TAGame.GameEvent_SoccarPrivate_TA")- , ("TAGame.GameEvent_TA", "Engine.ReplicationInfo")- , ("TAGame.GameEvent_Team_TA", "TAGame.GameEvent_TA")- , ("TAGame.GRI_TA", "ProjectX.GRI_X")- , ("TAGame.HauntedBallTrapTrigger_TA", "Engine.Actor")- , ("TAGame.InMapScoreboard_TA", "Engine.Actor")- , ("TAGame.PRI_TA", "ProjectX.PRI_X")- , ("TAGame.RBActor_TA", "ProjectX.Pawn_X")- , ("TAGame.SpecialPickup_BallCarSpring_TA", "TAGame.SpecialPickup_Spring_TA")- , ("TAGame.SpecialPickup_BallFreeze_TA", "TAGame.SpecialPickup_Targeted_TA")- , ("TAGame.SpecialPickup_BallGravity_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.SpecialPickup_BallLasso_TA", "TAGame.SpecialPickup_GrapplingHook_TA")- , ("TAGame.SpecialPickup_BallVelcro_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.SpecialPickup_Batarang_TA", "TAGame.SpecialPickup_BallLasso_TA")- , ("TAGame.SpecialPickup_BoostOverride_TA", "TAGame.SpecialPickup_Targeted_TA")- , ("TAGame.SpecialPickup_GrapplingHook_TA", "TAGame.SpecialPickup_Targeted_TA")- , ("TAGame.SpecialPickup_HauntedBallBeam_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.SpecialPickup_HitForce_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.SpecialPickup_Rugby_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.SpecialPickup_Spring_TA", "TAGame.SpecialPickup_Targeted_TA")- , ("TAGame.SpecialPickup_Swapper_TA", "TAGame.SpecialPickup_Targeted_TA")- , ("TAGame.SpecialPickup_TA", "TAGame.CarComponent_TA")- , ("TAGame.SpecialPickup_Targeted_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.SpecialPickup_Tornado_TA", "TAGame.SpecialPickup_TA")- , ("TAGame.Team_Soccar_TA", "TAGame.Team_TA")- , ("TAGame.Team_TA", "Engine.TeamInfo")- , ("TAGame.Vehicle_TA", "TAGame.RBActor_TA")- , ("TAGame.VehiclePickup_Boost_TA", "TAGame.VehiclePickup_TA")- , ("TAGame.VehiclePickup_TA", "Engine.ReplicationInfo")- ]--rawClassesWithLocation :: [String]-rawClassesWithLocation =- [ "Archetypes.Ball.Ball_BasketBall_Mutator"- , "Archetypes.Ball.Ball_Basketball"- , "Archetypes.Ball.Ball_BasketBall"- , "Archetypes.Ball.Ball_Breakout"- , "Archetypes.Ball.Ball_Default"- , "Archetypes.Ball.Ball_Puck"- , "Archetypes.Ball.CubeBall"- , "Archetypes.Car.Car_Default"- , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"- , "Archetypes.SpecialPickups.SpecialPickup_Rugby"- , "ProjectX.NetModeReplicator"- , "TAGame.Ball_Breakout_TA"- , "TAGame.Ball_God_TA"- , "TAGame.Ball_Haunted_TA"- , "TAGame.Ball_TA"- , "TAGame.CameraSettingsActor_TA"- , "TAGame.Car_Season_TA"- , "TAGame.Car_TA"- , "TAGame.CarComponent_Boost_TA"- , "TAGame.CarComponent_Dodge_TA"- , "TAGame.CarComponent_DoubleJump_TA"- , "TAGame.CarComponent_FlipCar_TA"- , "TAGame.CarComponent_Jump_TA"- , "TAGame.Default__CameraSettingsActor_TA"- , "TAGame.Default__PRI_TA"- , "TAGame.GameEvent_GodBall_TA"- , "TAGame.GameEvent_Season_TA"- , "TAGame.GameEvent_Soccar_TA"- , "TAGame.GameEvent_SoccarPrivate_TA"- , "TAGame.GameEvent_SoccarSplitscreen_TA"- , "TAGame.GRI_TA"- , "TAGame.MaxTimeWarningData_TA"- , "TAGame.RumblePickups_TA"- , "TAGame.PRI_TA"- , "TAGame.SpecialPickup_BallCarSpring_TA"- , "TAGame.SpecialPickup_BallFreeze_TA"- , "TAGame.SpecialPickup_BallGravity_TA"- , "TAGame.SpecialPickup_BallLasso_TA"- , "TAGame.SpecialPickup_BallVelcro_TA"- , "TAGame.SpecialPickup_Batarang_TA"- , "TAGame.SpecialPickup_BoostOverride_TA"- , "TAGame.SpecialPickup_GrapplingHook_TA"- , "TAGame.SpecialPickup_HauntedBallBeam_TA"- , "TAGame.SpecialPickup_HitForce_TA"- , "TAGame.SpecialPickup_Rugby_TA"- , "TAGame.SpecialPickup_Swapper_TA"- , "TAGame.SpecialPickup_Tornado_TA"- , "TAGame.Team_Soccar_TA"- , "TheWorld:PersistentLevel.BreakOutActor_Platform_TA"- , "TheWorld:PersistentLevel.CrowdActor_TA"- , "TheWorld:PersistentLevel.CrowdManager_TA"- , "TheWorld:PersistentLevel.InMapScoreboard_TA"- , "TheWorld:PersistentLevel.VehiclePickup_Boost_TA"- ]--rawClassesWithRotation :: [String]-rawClassesWithRotation =- [ "Archetypes.Ball.Ball_BasketBall_Mutator"- , "Archetypes.Ball.Ball_Basketball"- , "Archetypes.Ball.Ball_BasketBall"- , "Archetypes.Ball.Ball_Breakout"- , "Archetypes.Ball.Ball_Default"- , "Archetypes.Ball.Ball_Puck"- , "Archetypes.Ball.CubeBall"- , "Archetypes.Car.Car_Default"- , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"- , "Archetypes.SpecialPickups.SpecialPickup_Rugby"- , "TAGame.Ball_Breakout_TA"- , "TAGame.Ball_God_TA"- , "TAGame.Ball_Haunted_TA"- , "TAGame.Ball_TA"- , "TAGame.Car_Season_TA"- , "TAGame.Car_TA"- ]--rawObjectClasses :: [(String, String)]-rawObjectClasses =- [ ("Archetypes.Ball.Ball_Anniversary", "TAGame.Ball_TA")- , ("Archetypes.Ball.Ball_BasketBall_Mutator", "TAGame.Ball_TA")- , ("Archetypes.Ball.Ball_Basketball", "TAGame.Ball_TA")- , ("Archetypes.Ball.Ball_BasketBall", "TAGame.Ball_TA")- , ("Archetypes.Ball.Ball_Beachball", "TAGame.Ball_TA")- , ("Archetypes.Ball.Ball_Breakout", "TAGame.Ball_Breakout_TA")- , ("Archetypes.Ball.Ball_Default", "TAGame.Ball_TA")- , ("Archetypes.Ball.Ball_God", "TAGame.Ball_God_TA")- , ("Archetypes.Ball.Ball_Haunted", "TAGame.Ball_Haunted_TA")- , ("Archetypes.Ball.Ball_Puck", "TAGame.Ball_TA")- , ("Archetypes.Ball.CubeBall", "TAGame.Ball_TA")- , ("Archetypes.Car.Car_Default", "TAGame.Car_TA")- , ("Archetypes.CarComponents.CarComponent_Boost", "TAGame.CarComponent_Boost_TA")- , ("Archetypes.CarComponents.CarComponent_Dodge", "TAGame.CarComponent_Dodge_TA")- , ("Archetypes.CarComponents.CarComponent_DoubleJump", "TAGame.CarComponent_DoubleJump_TA")- , ("Archetypes.CarComponents.CarComponent_FlipCar", "TAGame.CarComponent_FlipCar_TA")- , ("Archetypes.CarComponents.CarComponent_Jump", "TAGame.CarComponent_Jump_TA")- , ("Archetypes.GameEvent.GameEvent_Basketball", "TAGame.GameEvent_Soccar_TA")- , ("Archetypes.GameEvent.GameEvent_BasketballPrivate", "TAGame.GameEvent_SoccarPrivate_TA")- , ("Archetypes.GameEvent.GameEvent_BasketballSplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")- , ("Archetypes.GameEvent.GameEvent_Breakout", "TAGame.GameEvent_Soccar_TA")- , ("Archetypes.GameEvent.GameEvent_Hockey", "TAGame.GameEvent_Soccar_TA")- , ("Archetypes.GameEvent.GameEvent_HockeyPrivate", "TAGame.GameEvent_SoccarPrivate_TA")- , ("Archetypes.GameEvent.GameEvent_HockeySplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")- , ("Archetypes.GameEvent.GameEvent_Items", "TAGame.GameEvent_Soccar_TA")- , ("Archetypes.GameEvent.GameEvent_Season:CarArchetype", "TAGame.Car_TA")- , ("Archetypes.GameEvent.GameEvent_Season", "TAGame.GameEvent_Season_TA")- , ("Archetypes.GameEvent.GameEvent_Soccar", "TAGame.GameEvent_Soccar_TA")- , ("Archetypes.GameEvent.GameEvent_SoccarLan", "TAGame.GameEvent_Soccar_TA")- , ("Archetypes.GameEvent.GameEvent_SoccarPrivate", "TAGame.GameEvent_SoccarPrivate_TA")- , ("Archetypes.GameEvent.GameEvent_SoccarSplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_BallFreeze", "TAGame.SpecialPickup_BallFreeze_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_BallGrapplingHook", "TAGame.SpecialPickup_GrapplingHook_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_BallLasso", "TAGame.SpecialPickup_BallLasso_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_BallSpring", "TAGame.SpecialPickup_BallCarSpring_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_BallVelcro", "TAGame.SpecialPickup_BallVelcro_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_Batarang", "TAGame.SpecialPickup_Batarang_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_BoostOverride", "TAGame.SpecialPickup_BoostOverride_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_CarSpring", "TAGame.SpecialPickup_BallCarSpring_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_GravityWell", "TAGame.SpecialPickup_BallGravity_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_HauntedBallBeam", "TAGame.SpecialPickup_HauntedBallBeam_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_Rugby", "TAGame.SpecialPickup_Rugby_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_StrongHit", "TAGame.SpecialPickup_HitForce_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_Swapper", "TAGame.SpecialPickup_Swapper_TA")- , ("Archetypes.SpecialPickups.SpecialPickup_Tornado", "TAGame.SpecialPickup_Tornado_TA")- , ("Archetypes.Teams.Team0", "TAGame.Team_Soccar_TA")- , ("Archetypes.Teams.Team1", "TAGame.Team_Soccar_TA")- , ("GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("GameInfo_Breakout.GameInfo.GameInfo_Breakout:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("gameinfo_godball.GameInfo.gameinfo_godball:Archetype", "TAGame.GameEvent_GodBall_TA")- , ("gameinfo_godball.GameInfo.gameinfo_godball:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("GameInfo_Items.GameInfo.GameInfo_Items:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("GameInfo_Season.GameInfo.GameInfo_Season:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype", "TAGame.GRI_TA")- , ("Haunted_TrainStation_P.TheWorld:PersistentLevel.HauntedBallTrapTrigger_TA_0", "TAGame.HauntedBallTrapTrigger_TA")- , ("Haunted_TrainStation_P.TheWorld:PersistentLevel.HauntedBallTrapTrigger_TA_1", "TAGame.HauntedBallTrapTrigger_TA")- , ("ProjectX.Default__NetModeReplicator_X", "ProjectX.NetModeReplicator")- , ("TAGame.Default__CameraSettingsActor_TA", "TAGame.CameraSettingsActor_TA")- , ("TAGame.Default__MaxTimeWarningData_TA", "TAGame.MaxTimeWarningData_TA")- , ("TAGame.Default__RumblePickups_TA", "TAGame.RumblePickups_TA")- , ("TAGame.Default__PRI_TA", "TAGame.PRI_TA")- , ("TheWorld:PersistentLevel.BreakOutActor_Platform_TA", "TAGame.BreakOutActor_Platform_TA")- , ("TheWorld:PersistentLevel.CrowdActor_TA", "TAGame.CrowdActor_TA")- , ("TheWorld:PersistentLevel.CrowdManager_TA", "TAGame.CrowdManager_TA")- , ("TheWorld:PersistentLevel.InMapScoreboard_TA", "TAGame.InMapScoreboard_TA")- , ("TheWorld:PersistentLevel.VehiclePickup_Boost_TA", "TAGame.VehiclePickup_Boost_TA")- ]--rawAttributeTypes :: [(String, AttributeType)]-rawAttributeTypes =- [ ("Engine.Actor:bBlockActors", AttributeTypeBoolean)- , ("Engine.Actor:bCollideActors", AttributeTypeBoolean)- , ("Engine.Actor:bHidden", AttributeTypeBoolean)- , ("Engine.Actor:DrawScale", AttributeTypeFloat)- , ("Engine.Actor:RemoteRole", AttributeTypeEnum)- , ("Engine.Actor:Role", AttributeTypeEnum)- , ("Engine.GameReplicationInfo:bMatchIsOver", AttributeTypeBoolean)- , ("Engine.GameReplicationInfo:GameClass", AttributeTypeFlaggedInt)- , ("TAGame.Car_TA:RumblePickups", AttributeTypeFlaggedInt)- , ("Engine.GameReplicationInfo:ServerName", AttributeTypeString)- , ("Engine.Pawn:PlayerReplicationInfo", AttributeTypeFlaggedInt)- , ("Engine.PlayerReplicationInfo:bBot", AttributeTypeBoolean)- , ("Engine.PlayerReplicationInfo:bIsSpectator", AttributeTypeBoolean)- , ("Engine.PlayerReplicationInfo:bReadyToPlay", AttributeTypeBoolean)- , ("Engine.PlayerReplicationInfo:bTimedOut", AttributeTypeBoolean)- , ("Engine.PlayerReplicationInfo:bWaitingPlayer", AttributeTypeBoolean)- , ("Engine.PlayerReplicationInfo:Ping", AttributeTypeByte)- , ("Engine.PlayerReplicationInfo:PlayerID", AttributeTypeInt)- , ("Engine.PlayerReplicationInfo:PlayerName", AttributeTypeString)- , ("Engine.PlayerReplicationInfo:RemoteUserData", AttributeTypeString)- , ("Engine.PlayerReplicationInfo:Score", AttributeTypeInt)- , ("Engine.PlayerReplicationInfo:Team", AttributeTypeFlaggedInt)- , ("Engine.PlayerReplicationInfo:UniqueId", AttributeTypeUniqueId)- , ("Engine.ReplicatedActor_ORS:ReplicatedOwner", AttributeTypeFlaggedInt)- , ("Engine.TeamInfo:Score", AttributeTypeInt)- , ("ProjectX.GRI_X:bGameStarted", AttributeTypeBoolean)- , ("ProjectX.GRI_X:GameServerID", AttributeTypeQWord)- , ("ProjectX.GRI_X:MatchGUID", AttributeTypeString)- , ("ProjectX.GRI_X:ReplicatedGameMutatorIndex", AttributeTypeInt)- , ("ProjectX.GRI_X:ReplicatedGamePlaylist", AttributeTypeInt)- , ("ProjectX.GRI_X:Reservations", AttributeTypeReservation)- , ("TAGame.Ball_Breakout_TA:AppliedDamage", AttributeTypeAppliedDamage)- , ("TAGame.Ball_Breakout_TA:DamageIndex", AttributeTypeInt)- , ("TAGame.Ball_Breakout_TA:LastTeamTouch", AttributeTypeByte)- , ("TAGame.Ball_God_TA:TargetSpeed", AttributeTypeFloat)- , ("TAGame.Ball_Haunted_TA:bIsBallBeamed", AttributeTypeBoolean)- , ("TAGame.Ball_Haunted_TA:DeactivatedGoalIndex", AttributeTypeByte)- , ("TAGame.Ball_Haunted_TA:LastTeamTouch", AttributeTypeByte)- , ("TAGame.Ball_Haunted_TA:ReplicatedBeamBrokenValue", AttributeTypeByte)- , ("TAGame.Ball_Haunted_TA:TotalActiveBeams", AttributeTypeByte)- , ("TAGame.Ball_TA:GameEvent", AttributeTypeFlaggedInt)- , ("TAGame.Ball_TA:HitTeamNum", AttributeTypeByte)- , ("TAGame.Ball_TA:ReplicatedAddedCarBounceScale", AttributeTypeFloat)- , ("TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale", AttributeTypeFloat)- , ("TAGame.Ball_TA:ReplicatedBallScale", AttributeTypeFloat)- , ("TAGame.Ball_TA:ReplicatedExplosionData", AttributeTypeExplosion)- , ("TAGame.Ball_TA:ReplicatedExplosionDataExtended", AttributeTypeExtendedExplosion)- , ("TAGame.Ball_TA:ReplicatedPhysMatOverride", AttributeTypeFlaggedInt)- , ("TAGame.Ball_TA:ReplicatedWorldBounceScale", AttributeTypeFloat)- , ("TAGame.BreakOutActor_Platform_TA:DamageState", AttributeTypeDamageState)- , ("TAGame.CameraSettingsActor_TA:bMouseCameraToggleEnabled", AttributeTypeBoolean)- , ("TAGame.CameraSettingsActor_TA:bUsingBehindView", AttributeTypeBoolean)- , ("TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera", AttributeTypeBoolean)- , ("TAGame.CameraSettingsActor_TA:bUsingSwivel", AttributeTypeBoolean)- , ("TAGame.CameraSettingsActor_TA:CameraPitch", AttributeTypeByte)- , ("TAGame.CameraSettingsActor_TA:CameraYaw", AttributeTypeByte)- , ("TAGame.CameraSettingsActor_TA:PRI", AttributeTypeFlaggedInt)- , ("TAGame.CameraSettingsActor_TA:ProfileSettings", AttributeTypeCamSettings)- , ("TAGame.Car_TA:AddedBallForceMultiplier", AttributeTypeFloat)- , ("TAGame.Car_TA:AddedCarForceMultiplier", AttributeTypeFloat)- , ("TAGame.Car_TA:AttachedPickup", AttributeTypeFlaggedInt)- , ("TAGame.Car_TA:ClubColors", AttributeTypeClubColors)- , ("TAGame.Car_TA:ReplicatedDemolish_CustomFX", AttributeTypeCustomDemolish)- , ("TAGame.Car_TA:ReplicatedDemolish", AttributeTypeDemolish)- , ("TAGame.Car_TA:TeamPaint", AttributeTypeTeamPaint)- , ("TAGame.CarComponent_Boost_TA:bNoBoost", AttributeTypeBoolean)- , ("TAGame.CarComponent_Boost_TA:BoostModifier", AttributeTypeFloat)- , ("TAGame.CarComponent_Boost_TA:bUnlimitedBoost", AttributeTypeBoolean)- , ("TAGame.CarComponent_Boost_TA:RechargeDelay", AttributeTypeFloat)- , ("TAGame.CarComponent_Boost_TA:RechargeRate", AttributeTypeFloat)- , ("TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount", AttributeTypeByte)- , ("TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount", AttributeTypeInt)- , ("TAGame.CarComponent_Dodge_TA:DodgeTorque", AttributeTypeLocation)- , ("TAGame.CarComponent_FlipCar_TA:bFlipRight", AttributeTypeBoolean)- , ("TAGame.CarComponent_FlipCar_TA:FlipCarTime", AttributeTypeFloat)- , ("TAGame.CarComponent_TA:ReplicatedActive", AttributeTypeByte)- , ("TAGame.CarComponent_TA:ReplicatedActivityTime", AttributeTypeFloat)- , ("TAGame.CarComponent_TA:Vehicle", AttributeTypeFlaggedInt)- , ("TAGame.CrowdActor_TA:GameEvent", AttributeTypeFlaggedInt)- , ("TAGame.CrowdActor_TA:ModifiedNoise", AttributeTypeFloat)- , ("TAGame.CrowdActor_TA:ReplicatedCountDownNumber", AttributeTypeInt)- , ("TAGame.CrowdActor_TA:ReplicatedOneShotSound", AttributeTypeFlaggedInt)- , ("TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber", AttributeTypeInt)- , ("TAGame.CrowdManager_TA:GameEvent", AttributeTypeFlaggedInt)- , ("TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound", AttributeTypeFlaggedInt)- , ("TAGame.GameEvent_Soccar_TA:bBallHasBeenHit", AttributeTypeBoolean)- , ("TAGame.GameEvent_Soccar_TA:bClubMatch", AttributeTypeBoolean)- , ("TAGame.GameEvent_Soccar_TA:bOverTime", AttributeTypeBoolean)- , ("TAGame.GameEvent_Soccar_TA:bUnlimitedTime", AttributeTypeBoolean)- , ("TAGame.GameEvent_Soccar_TA:GameTime", AttributeTypeInt)- , ("TAGame.GameEvent_Soccar_TA:MaxScore", AttributeTypeInt)- , ("TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger", AttributeTypeMusicStinger)- , ("TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam", AttributeTypeByte)- , ("TAGame.GameEvent_Soccar_TA:ReplicatedServerPerformanceState", AttributeTypeByte)- , ("TAGame.GameEvent_Soccar_TA:ReplicatedStatEvent", AttributeTypeStatEvent)- , ("TAGame.GameEvent_Soccar_TA:RoundNum", AttributeTypeInt)- , ("TAGame.GameEvent_Soccar_TA:SecondsRemaining", AttributeTypeInt)- , ("TAGame.GameEvent_Soccar_TA:SeriesLength", AttributeTypeInt)- , ("TAGame.GameEvent_Soccar_TA:SubRulesArchetype", AttributeTypeFlaggedInt)- , ("TAGame.GameEvent_SoccarPrivate_TA:MatchSettings", AttributeTypePrivateMatchSettings)- , ("TAGame.GameEvent_TA:bCanVoteToForfeit", AttributeTypeBoolean)- , ("TAGame.GameEvent_TA:bHasLeaveMatchPenalty", AttributeTypeBoolean)- , ("TAGame.GameEvent_TA:BotSkill", AttributeTypeInt)- , ("TAGame.GameEvent_TA:GameMode", AttributeTypeGameMode)- , ("TAGame.GameEvent_TA:MatchTypeClass", AttributeTypeFlaggedInt)- , ("TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining", AttributeTypeInt)- , ("TAGame.GameEvent_TA:ReplicatedRoundCountDownNumber", AttributeTypeInt)- , ("TAGame.GameEvent_TA:ReplicatedStateIndex", AttributeTypeByte)- , ("TAGame.GameEvent_TA:ReplicatedStateName", AttributeTypeInt)- , ("TAGame.GameEvent_Team_TA:bForfeit", AttributeTypeBoolean)- , ("TAGame.GameEvent_Team_TA:MaxTeamSize", AttributeTypeInt)- , ("TAGame.GRI_TA:NewDedicatedServerIP", AttributeTypeString)- , ("TAGame.MaxTimeWarningData_TA:EndGameEpochTime", AttributeTypeInt64)- , ("TAGame.MaxTimeWarningData_TA:EndGameWarningEpochTime", AttributeTypeInt64)- , ("TAGame.PRI_TA:bIsDistracted", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bIsInSplitScreen", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bMatchMVP", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bOnlineLoadoutSet", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bOnlineLoadoutsSet", AttributeTypeBoolean)- , ("TAGame.PRI_TA:BotProductName", AttributeTypeInt)- , ("TAGame.PRI_TA:bReady", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bUsingBehindView", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bUsingItems", AttributeTypeBoolean)- , ("TAGame.PRI_TA:bUsingSecondaryCamera", AttributeTypeBoolean)- , ("TAGame.PRI_TA:CameraPitch", AttributeTypeByte)- , ("TAGame.PRI_TA:CameraSettings", AttributeTypeCamSettings)- , ("TAGame.PRI_TA:CameraYaw", AttributeTypeByte)- , ("TAGame.PRI_TA:ClientLoadout", AttributeTypeLoadout)- , ("TAGame.PRI_TA:ClientLoadoutOnline", AttributeTypeLoadoutOnline)- , ("TAGame.PRI_TA:ClientLoadouts", AttributeTypeLoadouts)- , ("TAGame.PRI_TA:ClientLoadoutsOnline", AttributeTypeLoadoutsOnline)- , ("TAGame.PRI_TA:ClubID", AttributeTypeInt64)- , ("TAGame.PRI_TA:MatchAssists", AttributeTypeInt)- , ("TAGame.PRI_TA:MatchBreakoutDamage", AttributeTypeInt)- , ("TAGame.PRI_TA:MatchGoals", AttributeTypeInt)- , ("TAGame.PRI_TA:MatchSaves", AttributeTypeInt)- , ("TAGame.PRI_TA:MatchScore", AttributeTypeInt)- , ("TAGame.PRI_TA:MatchShots", AttributeTypeInt)- , ("TAGame.PRI_TA:MaxTimeTillItem", AttributeTypeInt)- , ("TAGame.PRI_TA:PartyLeader", AttributeTypePartyLeader)- , ("TAGame.PRI_TA:PawnType", AttributeTypeByte)- , ("TAGame.PRI_TA:PersistentCamera", AttributeTypeFlaggedInt)- , ("TAGame.PRI_TA:PlayerHistoryKey", AttributeTypePlayerHistoryKey)- , ("TAGame.PRI_TA:PlayerHistoryValid", AttributeTypeBoolean)- , ("TAGame.PRI_TA:PrimaryTitle", AttributeTypeTitle)- , ("TAGame.PRI_TA:ReplicatedGameEvent", AttributeTypeFlaggedInt)- , ("TAGame.PRI_TA:ReplicatedWorstNetQualityBeyondLatency", AttributeTypeByte)- , ("TAGame.PRI_TA:SecondaryTitle", AttributeTypeTitle)- , ("TAGame.PRI_TA:SkillTier", AttributeTypeFlaggedByte)- , ("TAGame.PRI_TA:SpectatorShortcut", AttributeTypeInt)- , ("TAGame.PRI_TA:SteeringSensitivity", AttributeTypeFloat)- , ("TAGame.PRI_TA:TimeTillItem", AttributeTypeInt)- , ("TAGame.PRI_TA:Title", AttributeTypeInt)- , ("TAGame.PRI_TA:TotalXP", AttributeTypeInt)- , ("TAGame.RBActor_TA:bFrozen", AttributeTypeBoolean)- , ("TAGame.RBActor_TA:bIgnoreSyncing", AttributeTypeBoolean)- , ("TAGame.RBActor_TA:bReplayActor", AttributeTypeBoolean)- , ("TAGame.RBActor_TA:ReplicatedRBState", AttributeTypeRigidBodyState)- , ("TAGame.RBActor_TA:WeldedInfo", AttributeTypeWeldedInfo)- , ("TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed", AttributeTypeFloat)- , ("TAGame.SpecialPickup_BallVelcro_TA:AttachTime", AttributeTypeFloat)- , ("TAGame.SpecialPickup_BallVelcro_TA:bBroken", AttributeTypeBoolean)- , ("TAGame.SpecialPickup_BallVelcro_TA:bHit", AttributeTypeBoolean)- , ("TAGame.SpecialPickup_BallVelcro_TA:BreakTime", AttributeTypeFloat)- , ("TAGame.SpecialPickup_Rugby_TA:bBallWelded", AttributeTypeBoolean)- , ("TAGame.SpecialPickup_Targeted_TA:Targeted", AttributeTypeFlaggedInt)- , ("TAGame.Team_Soccar_TA:GameScore", AttributeTypeInt)- , ("TAGame.Team_TA:ClubColors", AttributeTypeClubColors)- , ("TAGame.Team_TA:ClubID", AttributeTypeInt64)- , ("TAGame.Team_TA:CustomTeamName", AttributeTypeString)- , ("TAGame.Team_TA:Difficulty", AttributeTypeInt)- , ("TAGame.Team_TA:GameEvent", AttributeTypeFlaggedInt)- , ("TAGame.Team_TA:LogoData", AttributeTypeFlaggedInt)- , ("TAGame.Vehicle_TA:bDriving", AttributeTypeBoolean)- , ("TAGame.Vehicle_TA:bReplicatedHandbrake", AttributeTypeBoolean)- , ("TAGame.Vehicle_TA:ReplicatedSteer", AttributeTypeByte)- , ("TAGame.Vehicle_TA:ReplicatedThrottle", AttributeTypeByte)- , ("TAGame.VehiclePickup_TA:bNoPickup", AttributeTypeBoolean)- , ("TAGame.VehiclePickup_TA:NewReplicatedPickupData", AttributeTypePickupNew)- , ("TAGame.VehiclePickup_TA:ReplicatedPickupData", AttributeTypePickup)- ]--rawCrc32Table :: Integral a => [a]-rawCrc32Table =- [ 0x00000000- , 0x04c11db7- , 0x09823b6e- , 0x0d4326d9- , 0x130476dc- , 0x17c56b6b- , 0x1a864db2- , 0x1e475005- , 0x2608edb8- , 0x22c9f00f- , 0x2f8ad6d6- , 0x2b4bcb61- , 0x350c9b64- , 0x31cd86d3- , 0x3c8ea00a- , 0x384fbdbd- , 0x4c11db70- , 0x48d0c6c7- , 0x4593e01e- , 0x4152fda9- , 0x5f15adac- , 0x5bd4b01b- , 0x569796c2- , 0x52568b75- , 0x6a1936c8- , 0x6ed82b7f- , 0x639b0da6- , 0x675a1011- , 0x791d4014- , 0x7ddc5da3- , 0x709f7b7a- , 0x745e66cd- , 0x9823b6e0- , 0x9ce2ab57- , 0x91a18d8e- , 0x95609039- , 0x8b27c03c- , 0x8fe6dd8b- , 0x82a5fb52- , 0x8664e6e5- , 0xbe2b5b58- , 0xbaea46ef- , 0xb7a96036- , 0xb3687d81- , 0xad2f2d84- , 0xa9ee3033- , 0xa4ad16ea- , 0xa06c0b5d- , 0xd4326d90- , 0xd0f37027- , 0xddb056fe- , 0xd9714b49- , 0xc7361b4c- , 0xc3f706fb- , 0xceb42022- , 0xca753d95- , 0xf23a8028- , 0xf6fb9d9f- , 0xfbb8bb46- , 0xff79a6f1- , 0xe13ef6f4- , 0xe5ffeb43- , 0xe8bccd9a- , 0xec7dd02d- , 0x34867077- , 0x30476dc0- , 0x3d044b19- , 0x39c556ae- , 0x278206ab- , 0x23431b1c- , 0x2e003dc5- , 0x2ac12072- , 0x128e9dcf- , 0x164f8078- , 0x1b0ca6a1- , 0x1fcdbb16- , 0x018aeb13- , 0x054bf6a4- , 0x0808d07d- , 0x0cc9cdca- , 0x7897ab07- , 0x7c56b6b0- , 0x71159069- , 0x75d48dde- , 0x6b93dddb- , 0x6f52c06c- , 0x6211e6b5- , 0x66d0fb02- , 0x5e9f46bf- , 0x5a5e5b08- , 0x571d7dd1- , 0x53dc6066- , 0x4d9b3063- , 0x495a2dd4- , 0x44190b0d- , 0x40d816ba- , 0xaca5c697- , 0xa864db20- , 0xa527fdf9- , 0xa1e6e04e- , 0xbfa1b04b- , 0xbb60adfc- , 0xb6238b25- , 0xb2e29692- , 0x8aad2b2f- , 0x8e6c3698- , 0x832f1041- , 0x87ee0df6- , 0x99a95df3- , 0x9d684044- , 0x902b669d- , 0x94ea7b2a- , 0xe0b41de7- , 0xe4750050- , 0xe9362689- , 0xedf73b3e- , 0xf3b06b3b- , 0xf771768c- , 0xfa325055- , 0xfef34de2- , 0xc6bcf05f- , 0xc27dede8- , 0xcf3ecb31- , 0xcbffd686- , 0xd5b88683- , 0xd1799b34- , 0xdc3abded- , 0xd8fba05a- , 0x690ce0ee- , 0x6dcdfd59- , 0x608edb80- , 0x644fc637- , 0x7a089632- , 0x7ec98b85- , 0x738aad5c- , 0x774bb0eb- , 0x4f040d56- , 0x4bc510e1- , 0x46863638- , 0x42472b8f- , 0x5c007b8a- , 0x58c1663d- , 0x558240e4- , 0x51435d53- , 0x251d3b9e- , 0x21dc2629- , 0x2c9f00f0- , 0x285e1d47- , 0x36194d42- , 0x32d850f5- , 0x3f9b762c- , 0x3b5a6b9b- , 0x0315d626- , 0x07d4cb91- , 0x0a97ed48- , 0x0e56f0ff- , 0x1011a0fa- , 0x14d0bd4d- , 0x19939b94- , 0x1d528623- , 0xf12f560e- , 0xf5ee4bb9- , 0xf8ad6d60- , 0xfc6c70d7- , 0xe22b20d2- , 0xe6ea3d65- , 0xeba91bbc- , 0xef68060b- , 0xd727bbb6- , 0xd3e6a601- , 0xdea580d8- , 0xda649d6f- , 0xc423cd6a- , 0xc0e2d0dd- , 0xcda1f604- , 0xc960ebb3- , 0xbd3e8d7e- , 0xb9ff90c9- , 0xb4bcb610- , 0xb07daba7- , 0xae3afba2- , 0xaafbe615- , 0xa7b8c0cc- , 0xa379dd7b- , 0x9b3660c6- , 0x9ff77d71- , 0x92b45ba8- , 0x9675461f- , 0x8832161a- , 0x8cf30bad- , 0x81b02d74- , 0x857130c3- , 0x5d8a9099- , 0x594b8d2e- , 0x5408abf7- , 0x50c9b640- , 0x4e8ee645- , 0x4a4ffbf2- , 0x470cdd2b- , 0x43cdc09c- , 0x7b827d21- , 0x7f436096- , 0x7200464f- , 0x76c15bf8- , 0x68860bfd- , 0x6c47164a- , 0x61043093- , 0x65c52d24- , 0x119b4be9- , 0x155a565e- , 0x18197087- , 0x1cd86d30- , 0x029f3d35- , 0x065e2082- , 0x0b1d065b- , 0x0fdc1bec- , 0x3793a651- , 0x3352bbe6- , 0x3e119d3f- , 0x3ad08088- , 0x2497d08d- , 0x2056cd3a- , 0x2d15ebe3- , 0x29d4f654- , 0xc5a92679- , 0xc1683bce- , 0xcc2b1d17- , 0xc8ea00a0- , 0xd6ad50a5- , 0xd26c4d12- , 0xdf2f6bcb- , 0xdbee767c- , 0xe3a1cbc1- , 0xe760d676- , 0xea23f0af- , 0xeee2ed18- , 0xf0a5bd1d- , 0xf464a0aa- , 0xf9278673- , 0xfde69bc4- , 0x89b8fd09- , 0x8d79e0be- , 0x803ac667- , 0x84fbdbd0- , 0x9abc8bd5- , 0x9e7d9662- , 0x933eb0bb- , 0x97ffad0c- , 0xafb010b1- , 0xab710d06- , 0xa6322bdf- , 0xa2f33668- , 0xbcb4666d- , 0xb8757bda- , 0xb5365d03- , 0xb1f740b4- ]
@@ -1,19 +0,0 @@-module Rattletrap.Decode.AppliedDamageAttribute- ( decodeAppliedDamageAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Decode.Vector-import Rattletrap.Decode.Word8le-import Rattletrap.Type.AppliedDamageAttribute--decodeAppliedDamageAttributeBits- :: (Int, Int, Int) -> DecodeBits AppliedDamageAttribute-decodeAppliedDamageAttributeBits version =- AppliedDamageAttribute- <$> decodeWord8leBits- <*> decodeVectorBits version- <*> decodeInt32leBits- <*> decodeInt32leBits
@@ -1,73 +0,0 @@-module Rattletrap.Decode.Attribute- ( decodeAttributesBits- )-where--import Rattletrap.Decode.AttributeValue-import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Type.Attribute-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--decodeAttributesBits- :: (Int, Int, Int)- -> ClassAttributeMap- -> Map CompressedWord Word32le- -> CompressedWord- -> DecodeBits [Attribute]-decodeAttributesBits version classes actors actor = do- hasAttribute <- getBool- if hasAttribute- then- (:)- <$> decodeAttributeBits version classes actors actor- <*> decodeAttributesBits version classes actors actor- else pure []--decodeAttributeBits- :: (Int, Int, Int)- -> ClassAttributeMap- -> Map CompressedWord Word32le- -> CompressedWord- -> DecodeBits Attribute-decodeAttributeBits version classes actors actor = do- attributes <- lookupAttributeMap classes actors actor- limit <- lookupAttributeIdLimit attributes actor- attribute <- decodeCompressedWordBits limit- name <- lookupAttributeName classes attributes attribute- Attribute attribute name- <$> decodeAttributeValueBits- version- (classAttributeMapObjectMap classes)- name--lookupAttributeMap- :: ClassAttributeMap- -> Map CompressedWord Word32le- -> CompressedWord- -> DecodeBits (Map Word32le Word32le)-lookupAttributeMap classes actors actor = fromMaybe- ("[RT01] could not get attribute map for " <> show actor)- (getAttributeMap classes actors actor)--lookupAttributeIdLimit- :: Map Word32le Word32le -> CompressedWord -> DecodeBits Word-lookupAttributeIdLimit attributes actor = fromMaybe- ("[RT02] could not get attribute ID limit for " <> show actor)- (getAttributeIdLimit attributes)--lookupAttributeName- :: ClassAttributeMap- -> Map Word32le Word32le- -> CompressedWord- -> DecodeBits Str-lookupAttributeName classes attributes attribute = fromMaybe- ("[RT03] could not get attribute name for " <> show attribute)- (getAttributeName classes attributes attribute)--fromMaybe :: String -> Maybe a -> DecodeBits a-fromMaybe message = maybe (fail message) pure
@@ -1,12 +0,0 @@-module Rattletrap.Decode.AttributeMapping- ( decodeAttributeMapping- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Type.AttributeMapping--decodeAttributeMapping :: Decode AttributeMapping-decodeAttributeMapping =- AttributeMapping <$> decodeWord32le <*> decodeWord32le
@@ -1,131 +0,0 @@-module Rattletrap.Decode.AttributeValue- ( decodeAttributeValueBits- )-where--import Rattletrap.Data-import Rattletrap.Decode.AppliedDamageAttribute-import Rattletrap.Decode.BooleanAttribute-import Rattletrap.Decode.ByteAttribute-import Rattletrap.Decode.CamSettingsAttribute-import Rattletrap.Decode.ClubColorsAttribute-import Rattletrap.Decode.Common-import Rattletrap.Decode.CustomDemolishAttribute-import Rattletrap.Decode.DamageStateAttribute-import Rattletrap.Decode.DemolishAttribute-import Rattletrap.Decode.EnumAttribute-import Rattletrap.Decode.ExplosionAttribute-import Rattletrap.Decode.ExtendedExplosionAttribute-import Rattletrap.Decode.FlaggedIntAttribute-import Rattletrap.Decode.FlaggedByteAttribute-import Rattletrap.Decode.FloatAttribute-import Rattletrap.Decode.GameModeAttribute-import Rattletrap.Decode.Int64Attribute-import Rattletrap.Decode.IntAttribute-import Rattletrap.Decode.LoadoutAttribute-import Rattletrap.Decode.LoadoutOnlineAttribute-import Rattletrap.Decode.LoadoutsAttribute-import Rattletrap.Decode.LoadoutsOnlineAttribute-import Rattletrap.Decode.LocationAttribute-import Rattletrap.Decode.MusicStingerAttribute-import Rattletrap.Decode.PartyLeaderAttribute-import Rattletrap.Decode.PickupAttribute-import Rattletrap.Decode.PickupAttributeNew-import Rattletrap.Decode.PlayerHistoryKeyAttribute-import Rattletrap.Decode.PrivateMatchSettingsAttribute-import Rattletrap.Decode.QWordAttribute-import Rattletrap.Decode.ReservationAttribute-import Rattletrap.Decode.RigidBodyStateAttribute-import Rattletrap.Decode.StatEventAttribute-import Rattletrap.Decode.StringAttribute-import Rattletrap.Decode.TeamPaintAttribute-import Rattletrap.Decode.TitleAttribute-import Rattletrap.Decode.UniqueIdAttribute-import Rattletrap.Decode.WeldedInfoAttribute-import Rattletrap.Type.AttributeType-import Rattletrap.Type.AttributeValue-import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--import qualified Data.Map as Map--decodeAttributeValueBits- :: (Int, Int, Int) -> Map Word32le Str -> Str -> DecodeBits AttributeValue-decodeAttributeValueBits version objectMap name = do- constructor <- maybe- (fail ("[RT04] don't know how to get attribute value " <> show name))- pure- (Map.lookup name attributeTypes)- case constructor of- AttributeTypeAppliedDamage ->- AttributeValueAppliedDamage <$> decodeAppliedDamageAttributeBits version- AttributeTypeBoolean ->- AttributeValueBoolean <$> decodeBooleanAttributeBits- AttributeTypeByte -> AttributeValueByte <$> decodeByteAttributeBits- AttributeTypeCamSettings ->- AttributeValueCamSettings <$> decodeCamSettingsAttributeBits version- AttributeTypeClubColors ->- AttributeValueClubColors <$> decodeClubColorsAttributeBits- AttributeTypeCustomDemolish ->- AttributeValueCustomDemolish <$> decodeCustomDemolishAttributeBits version- AttributeTypeDamageState ->- AttributeValueDamageState <$> decodeDamageStateAttributeBits version- AttributeTypeDemolish ->- AttributeValueDemolish <$> decodeDemolishAttributeBits version- AttributeTypeEnum -> AttributeValueEnum <$> decodeEnumAttributeBits- AttributeTypeExplosion ->- AttributeValueExplosion <$> decodeExplosionAttributeBits version- AttributeTypeExtendedExplosion -> AttributeValueExtendedExplosion- <$> decodeExtendedExplosionAttributeBits version- AttributeTypeFlaggedInt ->- AttributeValueFlaggedInt <$> decodeFlaggedIntAttributeBits- AttributeTypeFlaggedByte ->- AttributeValueFlaggedByte <$> decodeFlaggedByteAttributeBits- AttributeTypeFloat -> AttributeValueFloat <$> decodeFloatAttributeBits- AttributeTypeGameMode ->- AttributeValueGameMode <$> decodeGameModeAttributeBits version- AttributeTypeInt -> AttributeValueInt <$> decodeIntAttributeBits- AttributeTypeInt64 -> AttributeValueInt64 <$> decodeInt64AttributeBits- AttributeTypeLoadout ->- AttributeValueLoadout <$> decodeLoadoutAttributeBits- AttributeTypeLoadoutOnline ->- AttributeValueLoadoutOnline- <$> decodeLoadoutOnlineAttributeBits version objectMap- AttributeTypeLoadouts ->- AttributeValueLoadouts <$> decodeLoadoutsAttributeBits- AttributeTypeLoadoutsOnline ->- AttributeValueLoadoutsOnline- <$> decodeLoadoutsOnlineAttributeBits version objectMap- AttributeTypeLocation ->- AttributeValueLocation <$> decodeLocationAttributeBits version- AttributeTypeMusicStinger ->- AttributeValueMusicStinger <$> decodeMusicStingerAttributeBits- AttributeTypePartyLeader ->- AttributeValuePartyLeader <$> decodePartyLeaderAttributeBits version- AttributeTypePickup -> AttributeValuePickup <$> decodePickupAttributeBits- AttributeTypePickupNew ->- AttributeValuePickupNew <$> decodePickupAttributeNewBits- AttributeTypePlayerHistoryKey ->- AttributeValuePlayerHistoryKey <$> decodePlayerHistoryKeyAttributeBits- AttributeTypePrivateMatchSettings ->- AttributeValuePrivateMatchSettings- <$> decodePrivateMatchSettingsAttributeBits- AttributeTypeQWord -> AttributeValueQWord <$> decodeQWordAttributeBits- AttributeTypeReservation ->- AttributeValueReservation <$> decodeReservationAttributeBits version- AttributeTypeRigidBodyState -> AttributeValueRigidBodyState- <$> decodeRigidBodyStateAttributeBits version- AttributeTypeStatEvent ->- AttributeValueStatEvent <$> decodeStatEventAttributeBits- AttributeTypeString -> AttributeValueString <$> decodeStringAttributeBits- AttributeTypeTeamPaint ->- AttributeValueTeamPaint <$> decodeTeamPaintAttributeBits- AttributeTypeTitle -> AttributeValueTitle <$> decodeTitleAttributeBits- AttributeTypeUniqueId ->- AttributeValueUniqueId <$> decodeUniqueIdAttributeBits version- AttributeTypeWeldedInfo ->- AttributeValueWeldedInfo <$> decodeWeldedInfoAttributeBits version--attributeTypes :: Map Str AttributeType-attributeTypes = Map.mapKeys toStr (Map.fromList rawAttributeTypes)
@@ -1,10 +0,0 @@-module Rattletrap.Decode.BooleanAttribute- ( decodeBooleanAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.BooleanAttribute--decodeBooleanAttributeBits :: DecodeBits BooleanAttribute-decodeBooleanAttributeBits = BooleanAttribute <$> getBool
@@ -1,11 +0,0 @@-module Rattletrap.Decode.ByteAttribute- ( decodeByteAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word8le-import Rattletrap.Type.ByteAttribute--decodeByteAttributeBits :: DecodeBits ByteAttribute-decodeByteAttributeBits = ByteAttribute <$> decodeWord8leBits
@@ -1,18 +0,0 @@-module Rattletrap.Decode.Cache- ( decodeCache- )-where--import Rattletrap.Decode.AttributeMapping-import Rattletrap.Decode.Common-import Rattletrap.Decode.List-import Rattletrap.Decode.Word32le-import Rattletrap.Type.Cache--decodeCache :: Decode Cache-decodeCache =- Cache- <$> decodeWord32le- <*> decodeWord32le- <*> decodeWord32le- <*> decodeList decodeAttributeMapping
@@ -1,20 +0,0 @@-module Rattletrap.Decode.CamSettingsAttribute- ( decodeCamSettingsAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Float32le-import Rattletrap.Type.CamSettingsAttribute--decodeCamSettingsAttributeBits- :: (Int, Int, Int) -> DecodeBits CamSettingsAttribute-decodeCamSettingsAttributeBits version =- CamSettingsAttribute- <$> decodeFloat32leBits- <*> decodeFloat32leBits- <*> decodeFloat32leBits- <*> decodeFloat32leBits- <*> decodeFloat32leBits- <*> decodeFloat32leBits- <*> decodeWhen (version >= (868, 20, 0)) decodeFloat32leBits
@@ -1,12 +0,0 @@-module Rattletrap.Decode.ClassMapping- ( decodeClassMapping- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word32le-import Rattletrap.Type.ClassMapping--decodeClassMapping :: Decode ClassMapping-decodeClassMapping = ClassMapping <$> decodeStr <*> decodeWord32le
@@ -1,16 +0,0 @@-module Rattletrap.Decode.ClubColorsAttribute- ( decodeClubColorsAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word8le-import Rattletrap.Type.ClubColorsAttribute--decodeClubColorsAttributeBits :: DecodeBits ClubColorsAttribute-decodeClubColorsAttributeBits =- ClubColorsAttribute- <$> getBool- <*> decodeWord8leBits- <*> getBool- <*> decodeWord8leBits
@@ -1,70 +0,0 @@-module Rattletrap.Decode.Common- ( Decode- , DecodeBits- , decodeWhen- , getBitsLE- , getByteStringBits- , getWord8Bits- , runDecode- , runDecodeBits- , toBits- , Binary.getFloatle- , Binary.getByteString- , Binary.getInt8- , Binary.getInt32le- , Binary.getInt64le- , Binary.getWord8- , Binary.getWord32le- , Binary.getWord64le- , BinaryBits.getBool- )-where--import qualified Control.Applicative as Applicative-import qualified Control.Monad as Monad-import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Get as BinaryBits-import qualified Data.Binary.Get as Binary-import qualified Data.Bits as Bits-import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Lazy as LazyBytes-import qualified Data.Word as Word-import qualified Rattletrap.Utility.Bytes as Utility--type Decode = Binary.Get--type DecodeBits = BinaryBits.BitGet--decodeWhen- :: (Applicative m, Applicative.Alternative f) => Bool -> m a -> m (f a)-decodeWhen p f = if p then fmap pure f else pure Applicative.empty--getByteStringBits :: Int -> DecodeBits Bytes.ByteString-getByteStringBits = BinaryBits.getByteString--getWord8Bits :: Int -> DecodeBits Word.Word8-getWord8Bits = BinaryBits.getWord8--runDecode :: Decode a -> Bytes.ByteString -> Either String a-runDecode decode bytes =- case Binary.runGetOrFail decode (LazyBytes.fromStrict bytes) of- Left (_, _, x) -> Left x- Right (_, _, x) -> Right x--runDecodeBits :: DecodeBits a -> Bytes.ByteString -> Either String a-runDecodeBits = runDecode . BinaryBits.runBitGet--toBits :: Decode a -> Int -> DecodeBits a-toBits decode size = do- bytes <- BinaryBits.getByteString size- case runDecode decode (Utility.reverseBytes bytes) of- Left problem -> fail problem- Right result -> pure result--getBitsLE :: Bits.Bits a => Int -> BinaryBits.BitGet a-getBitsLE size = do- bits <- Monad.replicateM size BinaryBits.getBool- pure $ foldr- (\bit x -> let y = Bits.shiftL x 1 in if bit then Bits.setBit y 0 else y)- Bits.zeroBits- bits
@@ -1,30 +0,0 @@-module Rattletrap.Decode.CompressedWord- ( decodeCompressedWordBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.CompressedWord--import qualified Data.Bits as Bits--decodeCompressedWordBits :: Word -> DecodeBits CompressedWord-decodeCompressedWordBits limit =- CompressedWord limit <$> step limit (getMaxBits limit) 0 0--getMaxBits :: Word -> Word-getMaxBits x = do- let- n :: Word- n = max 1 (ceiling (logBase (2 :: Double) (fromIntegral (max 1 x))))- if x < 1024 && x == 2 ^ n then n + 1 else n--step :: Word -> Word -> Word -> Word -> DecodeBits Word-step limit maxBits position value = do- let x = Bits.shiftL 1 (fromIntegral position) :: Word- if position < maxBits && value + x <= limit- then do- bit <- getBool- let newValue = if bit then value + x else value- step limit maxBits (position + 1) newValue- else pure value
@@ -1,18 +0,0 @@-module Rattletrap.Decode.CompressedWordVector- ( decodeCompressedWordVectorBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Type.CompressedWordVector--decodeCompressedWordVectorBits :: DecodeBits CompressedWordVector-decodeCompressedWordVectorBits =- CompressedWordVector- <$> decodeCompressedWordBits limit- <*> decodeCompressedWordBits limit- <*> decodeCompressedWordBits limit--limit :: Word-limit = 65536
@@ -1,71 +0,0 @@-module Rattletrap.Decode.Content- ( decodeContent- )-where--import Rattletrap.Decode.Cache-import Rattletrap.Decode.ClassMapping-import Rattletrap.Decode.Common-import Rattletrap.Decode.Frame-import Rattletrap.Decode.KeyFrame-import Rattletrap.Decode.List-import Rattletrap.Decode.Mark-import Rattletrap.Decode.Message-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word32le-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.Content-import Rattletrap.Type.Word32le-import Rattletrap.Utility.Bytes--import qualified Control.Monad.Trans.State as State-import qualified Data.Binary.Get as Binary-import qualified Data.ByteString.Lazy as LazyBytes--decodeContent- :: (Int, Int, Int)- -- ^ Version numbers, usually from 'Rattletrap.Header.getVersion'.- -> Int- -- ^ The number of frames in the stream, usually from- -- 'Rattletrap.Header.getNumFrames'.- -> Word- -- ^ The maximum number of channels in the stream, usually from- -- 'Rattletrap.Header.getMaxChannels'.- -> Decode Content-decodeContent version numFrames maxChannels = do- (levels, keyFrames, streamSize) <-- (,,)- <$> decodeList decodeStr- <*> decodeList decodeKeyFrame- <*> decodeWord32le- (stream, messages, marks, packages, objects, names, classMappings, caches) <-- (,,,,,,,)- <$> getByteString (fromIntegral (word32leValue streamSize))- <*> decodeList decodeMessage- <*> decodeList decodeMark- <*> decodeList decodeStr- <*> decodeList decodeStr- <*> decodeList decodeStr- <*> decodeList decodeClassMapping- <*> decodeList decodeCache- let- classAttributeMap =- makeClassAttributeMap objects classMappings caches names- bitGet = State.evalStateT- (decodeFramesBits version numFrames maxChannels classAttributeMap)- mempty- frames <- either fail pure (runDecodeBits bitGet (reverseBytes stream))- Content- levels- keyFrames- streamSize- frames- messages- marks- packages- objects- names- classMappings- caches- . LazyBytes.unpack- <$> Binary.getRemainingLazyByteString
@@ -1,16 +0,0 @@-module Rattletrap.Decode.CustomDemolishAttribute- ( decodeCustomDemolishAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.DemolishAttribute-import Rattletrap.Decode.Int32le-import Rattletrap.Type.CustomDemolishAttribute--decodeCustomDemolishAttributeBits :: (Int, Int, Int) -> DecodeBits CustomDemolishAttribute-decodeCustomDemolishAttributeBits version =- CustomDemolishAttribute- <$> getBool- <*> decodeInt32leBits- <*> decodeDemolishAttributeBits version
@@ -1,21 +0,0 @@-module Rattletrap.Decode.DamageStateAttribute- ( decodeDamageStateAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Decode.Vector-import Rattletrap.Decode.Word8le-import Rattletrap.Type.DamageStateAttribute--decodeDamageStateAttributeBits- :: (Int, Int, Int) -> DecodeBits DamageStateAttribute-decodeDamageStateAttributeBits version =- DamageStateAttribute- <$> decodeWord8leBits- <*> getBool- <*> decodeInt32leBits- <*> decodeVectorBits version- <*> getBool- <*> getBool
@@ -1,19 +0,0 @@-module Rattletrap.Decode.DemolishAttribute- ( decodeDemolishAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Vector-import Rattletrap.Decode.Word32le-import Rattletrap.Type.DemolishAttribute--decodeDemolishAttributeBits :: (Int, Int, Int) -> DecodeBits DemolishAttribute-decodeDemolishAttributeBits version =- DemolishAttribute- <$> getBool- <*> decodeWord32leBits- <*> getBool- <*> decodeWord32leBits- <*> decodeVectorBits version- <*> decodeVectorBits version
@@ -1,10 +0,0 @@-module Rattletrap.Decode.DestroyedReplication- ( decodeDestroyedReplicationBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.DestroyedReplication--decodeDestroyedReplicationBits :: DecodeBits DestroyedReplication-decodeDestroyedReplicationBits = pure DestroyedReplication
@@ -1,17 +0,0 @@-module Rattletrap.Decode.Dictionary- ( decodeDictionary- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Type.Dictionary-import Rattletrap.Type.Str--decodeDictionary :: Decode a -> Decode (Dictionary a)-decodeDictionary decodeValue = do- key <- decodeStr- case filter (/= '\x00') (fromStr key) of- "None" -> pure (DictionaryEnd key)- _ ->- DictionaryElement key <$> decodeValue <*> decodeDictionary decodeValue
@@ -1,10 +0,0 @@-module Rattletrap.Decode.EnumAttribute- ( decodeEnumAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.EnumAttribute--decodeEnumAttributeBits :: DecodeBits EnumAttribute-decodeEnumAttributeBits = EnumAttribute <$> getBitsLE 11
@@ -1,17 +0,0 @@-module Rattletrap.Decode.ExplosionAttribute- ( decodeExplosionAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Decode.Vector-import Rattletrap.Type.ExplosionAttribute--decodeExplosionAttributeBits- :: (Int, Int, Int) -> DecodeBits ExplosionAttribute-decodeExplosionAttributeBits version =- ExplosionAttribute- <$> getBool- <*> decodeInt32leBits- <*> decodeVectorBits version
@@ -1,16 +0,0 @@-module Rattletrap.Decode.ExtendedExplosionAttribute- ( decodeExtendedExplosionAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.ExplosionAttribute-import Rattletrap.Decode.FlaggedIntAttribute-import Rattletrap.Type.ExtendedExplosionAttribute--decodeExtendedExplosionAttributeBits- :: (Int, Int, Int) -> DecodeBits ExtendedExplosionAttribute-decodeExtendedExplosionAttributeBits version =- ExtendedExplosionAttribute- <$> decodeExplosionAttributeBits version- <*> decodeFlaggedIntAttributeBits
@@ -1,13 +0,0 @@-module Rattletrap.Decode.FlaggedByteAttribute- ( decodeFlaggedByteAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word8le-import Rattletrap.Type.FlaggedByteAttribute---decodeFlaggedByteAttributeBits :: DecodeBits FlaggedByteAttribute-decodeFlaggedByteAttributeBits =- FlaggedByteAttribute <$> getBool <*> decodeWord8leBits
@@ -1,12 +0,0 @@-module Rattletrap.Decode.FlaggedIntAttribute- ( decodeFlaggedIntAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Type.FlaggedIntAttribute--decodeFlaggedIntAttributeBits :: DecodeBits FlaggedIntAttribute-decodeFlaggedIntAttributeBits =- FlaggedIntAttribute <$> getBool <*> decodeInt32leBits
@@ -1,14 +0,0 @@-module Rattletrap.Decode.Float32le- ( decodeFloat32le- , decodeFloat32leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Float32le--decodeFloat32le :: Decode Float32le-decodeFloat32le = Float32le <$> getFloatle--decodeFloat32leBits :: DecodeBits Float32le-decodeFloat32leBits = toBits decodeFloat32le 4
@@ -1,11 +0,0 @@-module Rattletrap.Decode.FloatAttribute- ( decodeFloatAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Float32le-import Rattletrap.Type.FloatAttribute--decodeFloatAttributeBits :: DecodeBits FloatAttribute-decodeFloatAttributeBits = FloatAttribute <$> decodeFloat32leBits
@@ -1,43 +0,0 @@-module Rattletrap.Decode.Frame- ( decodeFramesBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Float32le-import Rattletrap.Decode.Replication-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Frame-import Rattletrap.Type.Word32le--import qualified Control.Monad.Trans.Class as Trans-import qualified Control.Monad.Trans.State as State-import qualified Data.Map as Map--decodeFramesBits- :: (Int, Int, Int)- -> Int- -> Word- -> ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord Word32le)- DecodeBits- [Frame]-decodeFramesBits version count limit classes = if count <= 0- then pure []- else- (:)- <$> decodeFrameBits version limit classes- <*> decodeFramesBits version (count - 1) limit classes--decodeFrameBits- :: (Int, Int, Int)- -> Word- -> ClassAttributeMap- -> State.StateT (Map.Map CompressedWord Word32le) DecodeBits Frame-decodeFrameBits version limit classes =- Frame- <$> Trans.lift decodeFloat32leBits- <*> Trans.lift decodeFloat32leBits- <*> decodeReplicationsBits version limit classes
@@ -1,15 +0,0 @@-module Rattletrap.Decode.GameModeAttribute- ( decodeGameModeAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.GameModeAttribute--decodeGameModeAttributeBits :: (Int, Int, Int) -> DecodeBits GameModeAttribute-decodeGameModeAttributeBits version =- GameModeAttribute <$> pure (numBits version) <*> getWord8Bits- (numBits version)--numBits :: (Int, Int, Int) -> Int-numBits version = if version >= (868, 12, 0) then 8 else 2
@@ -1,22 +0,0 @@-module Rattletrap.Decode.Header- ( decodeHeader- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Dictionary-import Rattletrap.Decode.Property-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word32le-import Rattletrap.Type.Header-import Rattletrap.Type.Word32le--decodeHeader :: Decode Header-decodeHeader = do- (major, minor) <- (,) <$> decodeWord32le <*> decodeWord32le- Header major minor- <$> decodeWhen- (major >= Word32le 868 && minor >= Word32le 18)- decodeWord32le- <*> decodeStr- <*> decodeDictionary decodeProperty
@@ -1,16 +0,0 @@-module Rattletrap.Decode.Initialization- ( decodeInitializationBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int8Vector-import Rattletrap.Decode.Vector-import Rattletrap.Type.Initialization--decodeInitializationBits- :: (Int, Int, Int) -> Bool -> Bool -> DecodeBits Initialization-decodeInitializationBits version hasLocation hasRotation =- Initialization- <$> decodeWhen hasLocation (decodeVectorBits version)- <*> decodeWhen hasRotation decodeInt8VectorBits
@@ -1,14 +0,0 @@-module Rattletrap.Decode.Int32le- ( decodeInt32le- , decodeInt32leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Int32le--decodeInt32le :: Decode Int32le-decodeInt32le = Int32le <$> getInt32le--decodeInt32leBits :: DecodeBits Int32le-decodeInt32leBits = toBits decodeInt32le 4
@@ -1,11 +0,0 @@-module Rattletrap.Decode.Int64Attribute- ( decodeInt64AttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int64le-import Rattletrap.Type.Int64Attribute--decodeInt64AttributeBits :: DecodeBits Int64Attribute-decodeInt64AttributeBits = Int64Attribute <$> decodeInt64leBits
@@ -1,13 +0,0 @@-module Rattletrap.Decode.Int64le- ( decodeInt64leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Int64le--decodeInt64le :: Decode Int64le-decodeInt64le = Int64le <$> getInt64le--decodeInt64leBits :: DecodeBits Int64le-decodeInt64leBits = toBits decodeInt64le 8
@@ -1,18 +0,0 @@-module Rattletrap.Decode.Int8Vector- ( decodeInt8VectorBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int8le-import Rattletrap.Type.Int8Vector-import Rattletrap.Type.Int8le--decodeInt8VectorBits :: DecodeBits Int8Vector-decodeInt8VectorBits =- Int8Vector <$> decodeFieldBits <*> decodeFieldBits <*> decodeFieldBits--decodeFieldBits :: DecodeBits (Maybe Int8le)-decodeFieldBits = do- hasField <- getBool- decodeWhen hasField decodeInt8leBits
@@ -1,13 +0,0 @@-module Rattletrap.Decode.Int8le- ( decodeInt8leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Int8le--decodeInt8le :: Decode Int8le-decodeInt8le = Int8le <$> getInt8--decodeInt8leBits :: DecodeBits Int8le-decodeInt8leBits = toBits decodeInt8le 1
@@ -1,11 +0,0 @@-module Rattletrap.Decode.IntAttribute- ( decodeIntAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Type.IntAttribute--decodeIntAttributeBits :: DecodeBits IntAttribute-decodeIntAttributeBits = IntAttribute <$> decodeInt32leBits
@@ -1,13 +0,0 @@-module Rattletrap.Decode.KeyFrame- ( decodeKeyFrame- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Float32le-import Rattletrap.Decode.Word32le-import Rattletrap.Type.KeyFrame--decodeKeyFrame :: Decode KeyFrame-decodeKeyFrame =- KeyFrame <$> decodeFloat32le <*> decodeWord32le <*> decodeWord32le
@@ -1,16 +0,0 @@-module Rattletrap.Decode.List- ( decodeList- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Type.List-import Rattletrap.Type.Word32le--import qualified Control.Monad as Monad--decodeList :: Decode a -> Decode (List a)-decodeList decodeElement = do- size <- decodeWord32le- List <$> Monad.replicateM (fromIntegral (word32leValue size)) decodeElement
@@ -1,31 +0,0 @@-module Rattletrap.Decode.LoadoutAttribute- ( decodeLoadoutAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Decode.Word8le-import Rattletrap.Type.LoadoutAttribute-import Rattletrap.Type.Word8le--decodeLoadoutAttributeBits :: DecodeBits LoadoutAttribute-decodeLoadoutAttributeBits = do- version <- decodeWord8leBits- LoadoutAttribute version- <$> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWhen (version >= Word8le 11) decodeWord32leBits- <*> decodeWhen (version >= Word8le 16) decodeWord32leBits- <*> decodeWhen (version >= Word8le 16) decodeWord32leBits- <*> decodeWhen (version >= Word8le 16) decodeWord32leBits- <*> decodeWhen (version >= Word8le 17) decodeWord32leBits- <*> decodeWhen (version >= Word8le 19) decodeWord32leBits- <*> decodeWhen (version >= Word8le 22) decodeWord32leBits- <*> decodeWhen (version >= Word8le 22) decodeWord32leBits- <*> decodeWhen (version >= Word8le 22) decodeWord32leBits
@@ -1,25 +0,0 @@-module Rattletrap.Decode.LoadoutOnlineAttribute- ( decodeLoadoutOnlineAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.ProductAttribute-import Rattletrap.Decode.Word8le-import Rattletrap.Type.LoadoutOnlineAttribute-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le-import Rattletrap.Type.Word8le--import qualified Control.Monad as Monad-import qualified Data.Map as Map--decodeLoadoutOnlineAttributeBits- :: (Int, Int, Int)- -> Map.Map Word32le Str- -> DecodeBits LoadoutOnlineAttribute-decodeLoadoutOnlineAttributeBits version objectMap = do- size <- decodeWord8leBits- LoadoutOnlineAttribute <$> Monad.replicateM- (fromIntegral (word8leValue size))- (decodeProductAttributesBits version objectMap)
@@ -1,14 +0,0 @@-module Rattletrap.Decode.LoadoutsAttribute- ( decodeLoadoutsAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.LoadoutAttribute-import Rattletrap.Type.LoadoutsAttribute--decodeLoadoutsAttributeBits :: DecodeBits LoadoutsAttribute-decodeLoadoutsAttributeBits =- LoadoutsAttribute- <$> decodeLoadoutAttributeBits- <*> decodeLoadoutAttributeBits
@@ -1,23 +0,0 @@-module Rattletrap.Decode.LoadoutsOnlineAttribute- ( decodeLoadoutsOnlineAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.LoadoutOnlineAttribute-import Rattletrap.Type.LoadoutsOnlineAttribute-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--import qualified Data.Map as Map--decodeLoadoutsOnlineAttributeBits- :: (Int, Int, Int)- -> Map.Map Word32le Str- -> DecodeBits LoadoutsOnlineAttribute-decodeLoadoutsOnlineAttributeBits version objectMap =- LoadoutsOnlineAttribute- <$> decodeLoadoutOnlineAttributeBits version objectMap- <*> decodeLoadoutOnlineAttributeBits version objectMap- <*> getBool- <*> getBool
@@ -1,12 +0,0 @@-module Rattletrap.Decode.LocationAttribute- ( decodeLocationAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Vector-import Rattletrap.Type.LocationAttribute--decodeLocationAttributeBits :: (Int, Int, Int) -> DecodeBits LocationAttribute-decodeLocationAttributeBits version =- LocationAttribute <$> decodeVectorBits version
@@ -1,12 +0,0 @@-module Rattletrap.Decode.Mark- ( decodeMark- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word32le-import Rattletrap.Type.Mark--decodeMark :: Decode Mark-decodeMark = Mark <$> decodeStr <*> decodeWord32le
@@ -1,12 +0,0 @@-module Rattletrap.Decode.Message- ( decodeMessage- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word32le-import Rattletrap.Type.Message--decodeMessage :: Decode Message-decodeMessage = Message <$> decodeWord32le <*> decodeStr <*> decodeStr
@@ -1,16 +0,0 @@-module Rattletrap.Decode.MusicStingerAttribute- ( decodeMusicStingerAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Decode.Word8le-import Rattletrap.Type.MusicStingerAttribute--decodeMusicStingerAttributeBits :: DecodeBits MusicStingerAttribute-decodeMusicStingerAttributeBits =- MusicStingerAttribute- <$> getBool- <*> decodeWord32leBits- <*> decodeWord8leBits
@@ -1,18 +0,0 @@-module Rattletrap.Decode.PartyLeaderAttribute- ( decodePartyLeaderAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.RemoteId-import Rattletrap.Decode.Word8le-import Rattletrap.Type.PartyLeaderAttribute-import Rattletrap.Type.Word8le--decodePartyLeaderAttributeBits- :: (Int, Int, Int) -> DecodeBits PartyLeaderAttribute-decodePartyLeaderAttributeBits version = do- systemId <- decodeWord8leBits- PartyLeaderAttribute systemId <$> decodeWhen- (systemId /= Word8le 0)- ((,) <$> decodeRemoteIdBits version systemId <*> decodeWord8leBits)
@@ -1,13 +0,0 @@-module Rattletrap.Decode.PickupAttribute- ( decodePickupAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Type.PickupAttribute--decodePickupAttributeBits :: DecodeBits PickupAttribute-decodePickupAttributeBits = do- instigator <- getBool- PickupAttribute <$> decodeWhen instigator decodeWord32leBits <*> getBool
@@ -1,16 +0,0 @@-module Rattletrap.Decode.PickupAttributeNew- ( decodePickupAttributeNewBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word8le-import Rattletrap.Decode.Word32le-import Rattletrap.Type.PickupAttributeNew--decodePickupAttributeNewBits :: DecodeBits PickupAttributeNew-decodePickupAttributeNewBits = do- instigator <- getBool- PickupAttributeNew- <$> decodeWhen instigator decodeWord32leBits- <*> decodeWord8leBits
@@ -1,11 +0,0 @@-module Rattletrap.Decode.PlayerHistoryKeyAttribute- ( decodePlayerHistoryKeyAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.PlayerHistoryKeyAttribute--decodePlayerHistoryKeyAttributeBits :: DecodeBits PlayerHistoryKeyAttribute-decodePlayerHistoryKeyAttributeBits =- PlayerHistoryKeyAttribute <$> getBitsLE 14
@@ -1,20 +0,0 @@-module Rattletrap.Decode.PrivateMatchSettingsAttribute- ( decodePrivateMatchSettingsAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word32le-import Rattletrap.Type.PrivateMatchSettingsAttribute--decodePrivateMatchSettingsAttributeBits- :: DecodeBits PrivateMatchSettingsAttribute-decodePrivateMatchSettingsAttributeBits =- PrivateMatchSettingsAttribute- <$> decodeStrBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeStrBits- <*> decodeStrBits- <*> getBool
@@ -1,70 +0,0 @@-module Rattletrap.Decode.ProductAttribute- ( decodeProductAttributesBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Decode.Word32le-import Rattletrap.Decode.Word8le-import Rattletrap.Decode.Str-import Rattletrap.Type.Common-import Rattletrap.Type.ProductAttribute-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le-import Rattletrap.Type.Word8le--import qualified Control.Monad as Monad-import qualified Data.Map as Map--decodeProductAttributesBits- :: (Int, Int, Int) -> Map Word32le Str -> DecodeBits [ProductAttribute]-decodeProductAttributesBits version objectMap = do- size <- decodeWord8leBits- Monad.replicateM- (fromIntegral (word8leValue size))- (decodeProductAttributeBits version objectMap)--decodeProductAttributeBits- :: (Int, Int, Int) -> Map Word32le Str -> DecodeBits ProductAttribute-decodeProductAttributeBits version objectMap = do- flag <- getBool- objectId <- decodeWord32leBits- let maybeObjectName = Map.lookup objectId objectMap- value <- case fromStr <$> maybeObjectName of- Just "TAGame.ProductAttribute_Painted_TA" -> decodePainted version- Just "TAGame.ProductAttribute_SpecialEdition_TA" -> decodeSpecialEdition- Just "TAGame.ProductAttribute_TeamEdition_TA" -> decodeTeamEdition version- Just "TAGame.ProductAttribute_TitleID_TA" -> decodeTitle- Just "TAGame.ProductAttribute_UserColor_TA" -> decodeColor version- Just objectName -> fail- ("[RT05] unknown object name "- <> show objectName- <> " for ID "- <> show objectId- )- Nothing -> fail ("[RT06] missing object name for ID " <> show objectId)- pure (ProductAttribute flag objectId maybeObjectName value)--decodeSpecialEdition :: DecodeBits ProductAttributeValue-decodeSpecialEdition = ProductAttributeValueSpecialEdition <$> getBitsLE 31--decodePainted :: (Int, Int, Int) -> DecodeBits ProductAttributeValue-decodePainted version = if version >= (868, 18, 0)- then ProductAttributeValuePaintedNew <$> getBitsLE 31- else ProductAttributeValuePaintedOld <$> decodeCompressedWordBits 13--decodeTeamEdition :: (Int, Int, Int) -> DecodeBits ProductAttributeValue-decodeTeamEdition version = if version >= (868, 18, 0)- then ProductAttributeValueTeamEditionNew <$> getBitsLE 31- else ProductAttributeValueTeamEditionOld <$> decodeCompressedWordBits 13--decodeColor :: (Int, Int, Int) -> DecodeBits ProductAttributeValue-decodeColor version = if version >= (868, 23, 8)- then ProductAttributeValueUserColorNew <$> decodeWord32leBits- else do- hasValue <- getBool- ProductAttributeValueUserColorOld <$> decodeWhen hasValue (getBitsLE 31)--decodeTitle :: DecodeBits ProductAttributeValue-decodeTitle = ProductAttributeValueTitleId <$> decodeStrBits
@@ -1,15 +0,0 @@-module Rattletrap.Decode.Property- ( decodeProperty- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.PropertyValue-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word64le-import Rattletrap.Type.Property--decodeProperty :: Decode Property-decodeProperty = do- kind <- decodeStr- Property kind <$> decodeWord64le <*> decodePropertyValue decodeProperty kind
@@ -1,31 +0,0 @@-module Rattletrap.Decode.PropertyValue- ( decodePropertyValue- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Dictionary-import Rattletrap.Decode.Float32le-import Rattletrap.Decode.Int32le-import Rattletrap.Decode.List-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word64le-import Rattletrap.Decode.Word8le-import Rattletrap.Type.PropertyValue-import Rattletrap.Type.Str--decodePropertyValue :: Decode a -> Str -> Decode (PropertyValue a)-decodePropertyValue getProperty kind = case fromStr kind of- "ArrayProperty" ->- PropertyValueArray <$> decodeList (decodeDictionary getProperty)- "BoolProperty" -> PropertyValueBool <$> decodeWord8le- "ByteProperty" -> do- k <- decodeStr- PropertyValueByte k- <$> decodeWhen (fromStr k /= "OnlinePlatform_Steam") decodeStr- "FloatProperty" -> PropertyValueFloat <$> decodeFloat32le- "IntProperty" -> PropertyValueInt <$> decodeInt32le- "NameProperty" -> PropertyValueName <$> decodeStr- "QWordProperty" -> PropertyValueQWord <$> decodeWord64le- "StrProperty" -> PropertyValueStr <$> decodeStr- _ -> fail ("[RT07] don't know how to read property value " <> show kind)
@@ -1,11 +0,0 @@-module Rattletrap.Decode.QWordAttribute- ( decodeQWordAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word64le-import Rattletrap.Type.QWordAttribute--decodeQWordAttributeBits :: DecodeBits QWordAttribute-decodeQWordAttributeBits = QWordAttribute <$> decodeWord64leBits
@@ -1,26 +0,0 @@-module Rattletrap.Decode.Quaternion- ( decodeQuaternionBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Quaternion--decodeQuaternionBits :: DecodeBits Quaternion-decodeQuaternionBits =- toQuaternion <$> decodeComponent <*> decodePart <*> decodePart <*> decodePart--decodeComponent :: DecodeBits Component-decodeComponent = do- x <- decodeCompressedWordBits 3- case compressedWordValue x of- 0 -> pure ComponentX- 1 -> pure ComponentY- 2 -> pure ComponentZ- 3 -> pure ComponentW- y -> fail ("[RT08] invalid component: " <> show y)--decodePart :: DecodeBits Double-decodePart = decompressPart <$> decodeCompressedWordBits maxCompressedValue
@@ -1,49 +0,0 @@-module Rattletrap.Decode.RemoteId- ( decodeRemoteIdBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Decode.Word64le-import Rattletrap.Type.RemoteId-import Rattletrap.Type.Word64le-import Rattletrap.Type.Word8le-import Rattletrap.Utility.Bytes--import qualified Data.ByteString as Bytes-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import qualified Data.Word as Word--decodeRemoteIdBits :: (Int, Int, Int) -> Word8le -> DecodeBits RemoteId-decodeRemoteIdBits version systemId = case word8leValue systemId of- 0 -> RemoteIdSplitscreen <$> getBitsLE 24- 1 -> RemoteIdSteam <$> decodeWord64leBits- 2 -> RemoteIdPlayStation <$> decodePsName <*> decodePsBytes version- 4 -> RemoteIdXbox <$> decodeWord64leBits- 6 -> do- (a, b, c, d) <- getWord256- pure $ RemoteIdSwitch a b c d- 7 -> if version >= (868, 24, 10)- then RemoteIdPsyNet . Left <$> decodeWord64leBits- else RemoteIdPsyNet . Right <$> getWord256- 11 -> RemoteIdEpic <$> decodeStrBits- _ -> fail ("[RT09] unknown system id " <> show systemId)--decodePsName :: DecodeBits Text.Text-decodePsName = fmap- (Text.dropWhileEnd (== '\x00') . Text.decodeLatin1 . reverseBytes)- (getByteStringBits 16)--decodePsBytes :: (Int, Int, Int) -> DecodeBits [Word.Word8]-decodePsBytes version = Bytes.unpack- <$> getByteStringBits (if version >= (868, 20, 1) then 24 else 16)--getWord256 :: DecodeBits (Word64le, Word64le, Word64le, Word64le)-getWord256 = do- a <- decodeWord64leBits- b <- decodeWord64leBits- c <- decodeWord64leBits- d <- decodeWord64leBits- pure (a, b, c, d)
@@ -1,66 +0,0 @@-module Rattletrap.Decode.Replay- ( decodeReplay- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Content-import Rattletrap.Decode.Header-import Rattletrap.Decode.Section-import Rattletrap.Encode.Content-import Rattletrap.Type.Content-import Rattletrap.Type.Dictionary-import Rattletrap.Type.Header-import Rattletrap.Type.Int32le-import Rattletrap.Type.Property-import Rattletrap.Type.PropertyValue-import Rattletrap.Type.Replay-import Rattletrap.Type.Section-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--decodeReplay :: Bool -> Decode Replay-decodeReplay fast = do- header <- decodeSection decodeHeader- content <- if fast- then pure $ toSection putContent defaultContent- else- let body = sectionBody header- in- decodeSection $ decodeContent- (getVersion body)- (getNumFrames body)- (getMaxChannels body)- pure $ Replay header content--getVersion :: Header -> (Int, Int, Int)-getVersion header =- ( fromIntegral (word32leValue (headerEngineVersion header))- , fromIntegral (word32leValue (headerLicenseeVersion header))- , getPatchVersion header- )--getPatchVersion :: Header -> Int-getPatchVersion header = case headerPatchVersion header of- Just version -> fromIntegral (word32leValue version)- Nothing ->- case dictionaryLookup (toStr "MatchType") (headerProperties header) of- -- This is an ugly, ugly hack to handle replays from season 2 of RLCS.- -- See `decodeSpawnedReplicationBits` and #85.- Just Property { propertyValue = PropertyValueName str }- | fromStr str == "Lan" -> -1- _ -> 0--getNumFrames :: Header -> Int-getNumFrames header =- case dictionaryLookup (toStr "NumFrames") (headerProperties header) of- Just (Property _ _ (PropertyValueInt numFrames)) ->- fromIntegral (int32leValue numFrames)- _ -> 0--getMaxChannels :: Header -> Word-getMaxChannels header =- case dictionaryLookup (toStr "MaxChannels") (headerProperties header) of- Just (Property _ _ (PropertyValueInt numFrames)) ->- fromIntegral (int32leValue numFrames)- _ -> 1023
@@ -1,45 +0,0 @@-module Rattletrap.Decode.Replication- ( decodeReplicationsBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Decode.ReplicationValue-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Replication-import Rattletrap.Type.Word32le--import qualified Control.Monad.Trans.Class as Trans-import qualified Control.Monad.Trans.State as State-import qualified Data.Map as Map--decodeReplicationsBits- :: (Int, Int, Int)- -> Word- -> ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord Word32le)- DecodeBits- [Replication]-decodeReplicationsBits version limit classes = do- hasReplication <- Trans.lift getBool- if hasReplication- then- (:)- <$> decodeReplicationBits version limit classes- <*> decodeReplicationsBits version limit classes- else pure []--decodeReplicationBits- :: (Int, Int, Int)- -> Word- -> ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord Word32le)- DecodeBits- Replication-decodeReplicationBits version limit classes = do- actor <- Trans.lift (decodeCompressedWordBits limit)- Replication actor <$> decodeReplicationValueBits version classes actor
@@ -1,45 +0,0 @@-module Rattletrap.Decode.ReplicationValue- ( decodeReplicationValueBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.DestroyedReplication-import Rattletrap.Decode.SpawnedReplication-import Rattletrap.Decode.UpdatedReplication-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.ReplicationValue-import Rattletrap.Type.Word32le--import qualified Control.Monad.Trans.Class as Trans-import qualified Control.Monad.Trans.State as State-import qualified Data.Map as Map--decodeReplicationValueBits- :: (Int, Int, Int)- -> ClassAttributeMap- -> CompressedWord- -> State.StateT- (Map.Map CompressedWord Word32le)- DecodeBits- ReplicationValue-decodeReplicationValueBits version classAttributeMap actorId = do- actorMap <- State.get- isOpen <- Trans.lift getBool- if isOpen- then do- isNew <- Trans.lift getBool- if isNew- then- ReplicationValueSpawned- <$> decodeSpawnedReplicationBits version classAttributeMap actorId- else ReplicationValueUpdated <$> Trans.lift- (decodeUpdatedReplicationBits- version- classAttributeMap- actorMap- actorId- )- else ReplicationValueDestroyed- <$> Trans.lift decodeDestroyedReplicationBits
@@ -1,25 +0,0 @@-module Rattletrap.Decode.ReservationAttribute- ( decodeReservationAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Decode.Str-import Rattletrap.Decode.UniqueIdAttribute-import Rattletrap.Type.ReservationAttribute-import Rattletrap.Type.UniqueIdAttribute-import Rattletrap.Type.Word8le--decodeReservationAttributeBits- :: (Int, Int, Int) -> DecodeBits ReservationAttribute-decodeReservationAttributeBits version = do- number <- decodeCompressedWordBits 7- uniqueId <- decodeUniqueIdAttributeBits version- ReservationAttribute number uniqueId- <$> decodeWhen- (uniqueIdAttributeSystemId uniqueId /= Word8le 0)- decodeStrBits- <*> getBool- <*> getBool- <*> decodeWhen (version >= (868, 12, 0)) (getWord8Bits 6)
@@ -1,19 +0,0 @@-module Rattletrap.Decode.RigidBodyStateAttribute- ( decodeRigidBodyStateAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Rotation-import Rattletrap.Decode.Vector-import Rattletrap.Type.RigidBodyStateAttribute--decodeRigidBodyStateAttributeBits- :: (Int, Int, Int) -> DecodeBits RigidBodyStateAttribute-decodeRigidBodyStateAttributeBits version = do- sleeping <- getBool- RigidBodyStateAttribute sleeping- <$> decodeVectorBits version- <*> decodeRotationBits version- <*> decodeWhen (not sleeping) (decodeVectorBits version)- <*> decodeWhen (not sleeping) (decodeVectorBits version)
@@ -1,14 +0,0 @@-module Rattletrap.Decode.Rotation- ( decodeRotationBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWordVector-import Rattletrap.Decode.Quaternion-import Rattletrap.Type.Rotation--decodeRotationBits :: (Int, Int, Int) -> DecodeBits Rotation-decodeRotationBits version = if version >= (868, 22, 7)- then RotationQuaternion <$> decodeQuaternionBits- else RotationCompressedWordVector <$> decodeCompressedWordVectorBits
@@ -1,30 +0,0 @@-module Rattletrap.Decode.Section- ( decodeSection- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Type.Section-import Rattletrap.Type.Word32le-import Rattletrap.Utility.Crc--import qualified Control.Monad as Monad--decodeSection :: Decode a -> Decode (Section a)-decodeSection getBody = do- size <- decodeWord32le- crc <- decodeWord32le- rawBody <- getByteString (fromIntegral (word32leValue size))- let actualCrc = Word32le (getCrc32 rawBody)- Monad.when (actualCrc /= crc) (fail (crcMessage actualCrc crc))- body <- either fail pure (runDecode getBody rawBody)- pure (Section size crc body)--crcMessage :: Word32le -> Word32le -> String-crcMessage actual expected = unwords- [ "[RT10] actual CRC"- , show actual- , "does not match expected CRC"- , show expected- ]
@@ -1,72 +0,0 @@-module Rattletrap.Decode.SpawnedReplication- ( decodeSpawnedReplicationBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Initialization-import Rattletrap.Decode.Word32le-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.SpawnedReplication-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--import qualified Control.Monad.Trans.Class as Trans-import qualified Control.Monad.Trans.State as State-import qualified Data.Map as Map--decodeSpawnedReplicationBits- :: (Int, Int, Int)- -> ClassAttributeMap- -> CompressedWord- -> State.StateT- (Map.Map CompressedWord Word32le)- DecodeBits- SpawnedReplication-decodeSpawnedReplicationBits version classAttributeMap actorId = do- flag <- Trans.lift getBool- nameIndex <- decodeWhen- (version >= (868, 14, 0))- (Trans.lift decodeWord32leBits)- name <- either fail pure (lookupName classAttributeMap nameIndex)- objectId <- Trans.lift decodeWord32leBits- State.modify (Map.insert actorId objectId)- objectName <- either fail pure (lookupObjectName classAttributeMap objectId)- className <- either fail pure (lookupClassName objectName)- let hasLocation = classHasLocation className- let hasRotation = classHasRotation className- initialization <- Trans.lift- (decodeInitializationBits version hasLocation hasRotation)- pure- (SpawnedReplication- flag- nameIndex- name- objectId- objectName- className- initialization- )--lookupName :: ClassAttributeMap -> Maybe Word32le -> Either String (Maybe Str)-lookupName classAttributeMap maybeNameIndex = case maybeNameIndex of- Nothing -> Right Nothing- Just nameIndex ->- case getName (classAttributeMapNameMap classAttributeMap) nameIndex of- Nothing ->- Left ("[RT11] could not get name for index " <> show nameIndex)- Just name -> Right (Just name)--lookupObjectName :: ClassAttributeMap -> Word32le -> Either String Str-lookupObjectName classAttributeMap objectId =- case getObjectName (classAttributeMapObjectMap classAttributeMap) objectId of- Nothing ->- Left ("[RT12] could not get object name for id " <> show objectId)- Just objectName -> Right objectName--lookupClassName :: Str -> Either String Str-lookupClassName objectName = case getClassName objectName of- Nothing ->- Left ("[RT13] could not get class name for object " <> show objectName)- Just className -> Right className
@@ -1,12 +0,0 @@-module Rattletrap.Decode.StatEventAttribute- ( decodeStatEventAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Type.StatEventAttribute--decodeStatEventAttributeBits :: DecodeBits StatEventAttribute-decodeStatEventAttributeBits =- StatEventAttribute <$> getBool <*> decodeInt32leBits
@@ -1,47 +0,0 @@-module Rattletrap.Decode.Str- ( decodeStr- , decodeStrBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Int32le-import Rattletrap.Type.Int32le-import Rattletrap.Type.Str-import Rattletrap.Utility.Bytes--import qualified Data.ByteString as Bytes-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import qualified Data.Text.Encoding.Error as Text-import qualified Debug.Trace as Debug--decodeStr :: Decode Str-decodeStr = do- rawSize <- decodeInt32le- bytes <- getByteString (normalizeTextSize rawSize)- pure (Str (dropNull (getTextDecoder rawSize bytes)))--decodeStrBits :: DecodeBits Str-decodeStrBits = do- rawSize <- decodeInt32leBits- bytes <- getByteStringBits (normalizeTextSize rawSize)- pure (Str (dropNull (getTextDecoder rawSize (reverseBytes bytes))))--normalizeTextSize :: Integral a => Int32le -> a-normalizeTextSize size = case int32leValue size of- 0x05000000 -> 8- x -> if x < 0 then (-2 * fromIntegral x) else fromIntegral x--getTextDecoder :: Int32le -> Bytes.ByteString -> Text.Text-getTextDecoder size bytes =- let- decode = if size < Int32le 0- then Text.decodeUtf16LEWith $ \message input -> do- Debug.traceM $ "WARNING: " <> show (Text.DecodeError message input)- Text.lenientDecode message input- else Text.decodeLatin1- in decode bytes--dropNull :: Text.Text -> Text.Text-dropNull = Text.dropWhileEnd (== '\x00')
@@ -1,11 +0,0 @@-module Rattletrap.Decode.StringAttribute- ( decodeStringAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Str-import Rattletrap.Type.StringAttribute--decodeStringAttributeBits :: DecodeBits StringAttribute-decodeStringAttributeBits = StringAttribute <$> decodeStrBits
@@ -1,18 +0,0 @@-module Rattletrap.Decode.TeamPaintAttribute- ( decodeTeamPaintAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Decode.Word8le-import Rattletrap.Type.TeamPaintAttribute--decodeTeamPaintAttributeBits :: DecodeBits TeamPaintAttribute-decodeTeamPaintAttributeBits =- TeamPaintAttribute- <$> decodeWord8leBits- <*> decodeWord8leBits- <*> decodeWord8leBits- <*> decodeWord32leBits- <*> decodeWord32leBits
@@ -1,20 +0,0 @@-module Rattletrap.Decode.TitleAttribute- ( decodeTitleAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Word32le-import Rattletrap.Type.TitleAttribute--decodeTitleAttributeBits :: DecodeBits TitleAttribute-decodeTitleAttributeBits =- TitleAttribute- <$> getBool- <*> getBool- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> decodeWord32leBits- <*> getBool
@@ -1,16 +0,0 @@-module Rattletrap.Decode.UniqueIdAttribute- ( decodeUniqueIdAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.RemoteId-import Rattletrap.Decode.Word8le-import Rattletrap.Type.UniqueIdAttribute--decodeUniqueIdAttributeBits :: (Int, Int, Int) -> DecodeBits UniqueIdAttribute-decodeUniqueIdAttributeBits version = do- systemId <- decodeWord8leBits- UniqueIdAttribute systemId- <$> decodeRemoteIdBits version systemId- <*> decodeWord8leBits
@@ -1,22 +0,0 @@-module Rattletrap.Decode.UpdatedReplication- ( decodeUpdatedReplicationBits- )-where--import Rattletrap.Decode.Attribute-import Rattletrap.Decode.Common-import Rattletrap.Type.ClassAttributeMap-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.UpdatedReplication-import Rattletrap.Type.Word32le--import qualified Data.Map as Map--decodeUpdatedReplicationBits- :: (Int, Int, Int)- -> ClassAttributeMap- -> Map.Map CompressedWord Word32le- -> CompressedWord- -> DecodeBits UpdatedReplication-decodeUpdatedReplicationBits version classes actors actor =- UpdatedReplication <$> decodeAttributesBits version classes actors actor
@@ -1,29 +0,0 @@-module Rattletrap.Decode.Vector- ( decodeVectorBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.CompressedWord-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Vector--decodeVectorBits :: (Int, Int, Int) -> DecodeBits Vector-decodeVectorBits version = do- size <- decodeCompressedWordBits (if version >= (868, 22, 7) then 21 else 19)- let- limit = getLimit size- bias = getBias size- Vector size bias- <$> fmap (fromDelta bias) (decodeCompressedWordBits limit)- <*> fmap (fromDelta bias) (decodeCompressedWordBits limit)- <*> fmap (fromDelta bias) (decodeCompressedWordBits limit)--getLimit :: CompressedWord -> Word-getLimit = (2 ^) . (+ 2) . compressedWordValue--getBias :: CompressedWord -> Word-getBias = (2 ^) . (+ 1) . compressedWordValue--fromDelta :: Word -> CompressedWord -> Int-fromDelta bias x = fromIntegral (compressedWordValue x) - fromIntegral bias
@@ -1,21 +0,0 @@-module Rattletrap.Decode.WeldedInfoAttribute- ( decodeWeldedInfoAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Decode.Float32le-import Rattletrap.Decode.Int32le-import Rattletrap.Decode.Int8Vector-import Rattletrap.Decode.Vector-import Rattletrap.Type.WeldedInfoAttribute--decodeWeldedInfoAttributeBits- :: (Int, Int, Int) -> DecodeBits WeldedInfoAttribute-decodeWeldedInfoAttributeBits version =- WeldedInfoAttribute- <$> getBool- <*> decodeInt32leBits- <*> decodeVectorBits version- <*> decodeFloat32leBits- <*> decodeInt8VectorBits
@@ -1,14 +0,0 @@-module Rattletrap.Decode.Word32le- ( decodeWord32le- , decodeWord32leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Word32le--decodeWord32le :: Decode Word32le-decodeWord32le = Word32le <$> getWord32le--decodeWord32leBits :: DecodeBits Word32le-decodeWord32leBits = toBits decodeWord32le 4
@@ -1,14 +0,0 @@-module Rattletrap.Decode.Word64le- ( decodeWord64le- , decodeWord64leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Word64le--decodeWord64le :: Decode Word64le-decodeWord64le = Word64le <$> getWord64le--decodeWord64leBits :: DecodeBits Word64le-decodeWord64leBits = toBits decodeWord64le 8
@@ -1,14 +0,0 @@-module Rattletrap.Decode.Word8le- ( decodeWord8le- , decodeWord8leBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.Word8le--decodeWord8le :: Decode Word8le-decodeWord8le = Word8le <$> getWord8--decodeWord8leBits :: DecodeBits Word8le-decodeWord8leBits = toBits decodeWord8le 1
@@ -1,18 +0,0 @@-module Rattletrap.Encode.AppliedDamageAttribute- ( putAppliedDamageAttribute- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Encode.Vector-import Rattletrap.Encode.Word8le-import Rattletrap.Type.AppliedDamageAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putAppliedDamageAttribute :: AppliedDamageAttribute -> BinaryBits.BitPut ()-putAppliedDamageAttribute appliedDamageAttribute = do- putWord8Bits (appliedDamageAttributeUnknown1 appliedDamageAttribute)- putVector (appliedDamageAttributeLocation appliedDamageAttribute)- putInt32Bits (appliedDamageAttributeUnknown3 appliedDamageAttribute)- putInt32Bits (appliedDamageAttributeUnknown4 appliedDamageAttribute)
@@ -1,26 +0,0 @@-module Rattletrap.Encode.Attribute- ( putAttributes- )-where--import Rattletrap.Encode.AttributeValue-import Rattletrap.Encode.CompressedWord-import Rattletrap.Type.Attribute--import qualified Data.Binary.Bits.Put as BinaryBits--putAttributes :: [Attribute] -> BinaryBits.BitPut ()-putAttributes attributes = case attributes of- [] -> BinaryBits.putBool False- [attribute] -> do- putAttribute attribute- BinaryBits.putBool False- first : rest -> do- putAttribute first- putAttributes rest--putAttribute :: Attribute -> BinaryBits.BitPut ()-putAttribute attribute = do- BinaryBits.putBool True- putCompressedWord (attributeId attribute)- putAttributeValue (attributeValue attribute)
@@ -1,14 +0,0 @@-module Rattletrap.Encode.AttributeMapping- ( putAttributeMapping- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Type.AttributeMapping--import qualified Data.Binary as Binary--putAttributeMapping :: AttributeMapping -> Binary.Put-putAttributeMapping attributeMapping = do- putWord32 (attributeMappingObjectId attributeMapping)- putWord32 (attributeMappingStreamId attributeMapping)
@@ -1,85 +0,0 @@-module Rattletrap.Encode.AttributeValue- ( putAttributeValue- )-where--import Rattletrap.Encode.AppliedDamageAttribute-import Rattletrap.Encode.BooleanAttribute-import Rattletrap.Encode.ByteAttribute-import Rattletrap.Encode.CamSettingsAttribute-import Rattletrap.Encode.ClubColorsAttribute-import Rattletrap.Encode.CustomDemolishAttribute-import Rattletrap.Encode.DamageStateAttribute-import Rattletrap.Encode.DemolishAttribute-import Rattletrap.Encode.EnumAttribute-import Rattletrap.Encode.ExplosionAttribute-import Rattletrap.Encode.ExtendedExplosionAttribute-import Rattletrap.Encode.FlaggedIntAttribute-import Rattletrap.Encode.FlaggedByteAttribute-import Rattletrap.Encode.FloatAttribute-import Rattletrap.Encode.GameModeAttribute-import Rattletrap.Encode.Int64Attribute-import Rattletrap.Encode.IntAttribute-import Rattletrap.Encode.LoadoutAttribute-import Rattletrap.Encode.LoadoutOnlineAttribute-import Rattletrap.Encode.LoadoutsAttribute-import Rattletrap.Encode.LoadoutsOnlineAttribute-import Rattletrap.Encode.LocationAttribute-import Rattletrap.Encode.MusicStingerAttribute-import Rattletrap.Encode.PartyLeaderAttribute-import Rattletrap.Encode.PickupAttribute-import Rattletrap.Encode.PickupAttributeNew-import Rattletrap.Encode.PlayerHistoryKeyAttribute-import Rattletrap.Encode.PrivateMatchSettingsAttribute-import Rattletrap.Encode.QWordAttribute-import Rattletrap.Encode.ReservationAttribute-import Rattletrap.Encode.RigidBodyStateAttribute-import Rattletrap.Encode.StatEventAttribute-import Rattletrap.Encode.StringAttribute-import Rattletrap.Encode.TeamPaintAttribute-import Rattletrap.Encode.TitleAttribute-import Rattletrap.Encode.UniqueIdAttribute-import Rattletrap.Encode.WeldedInfoAttribute-import Rattletrap.Type.AttributeValue--import qualified Data.Binary.Bits.Put as BinaryBits--putAttributeValue :: AttributeValue -> BinaryBits.BitPut ()-putAttributeValue value = case value of- AttributeValueAppliedDamage x -> putAppliedDamageAttribute x- AttributeValueBoolean x -> putBooleanAttribute x- AttributeValueByte x -> putByteAttribute x- AttributeValueCamSettings x -> putCamSettingsAttribute x- AttributeValueClubColors x -> putClubColorsAttribute x- AttributeValueCustomDemolish x -> putCustomDemolishAttribute x- AttributeValueDamageState x -> putDamageStateAttribute x- AttributeValueDemolish x -> putDemolishAttribute x- AttributeValueEnum x -> putEnumAttribute x- AttributeValueExplosion x -> putExplosionAttribute x- AttributeValueExtendedExplosion x -> putExtendedExplosionAttribute x- AttributeValueFlaggedInt x -> putFlaggedIntAttribute x- AttributeValueFlaggedByte x -> putFlaggedByteAttribute x- AttributeValueFloat x -> putFloatAttribute x- AttributeValueGameMode x -> putGameModeAttribute x- AttributeValueInt x -> putIntAttribute x- AttributeValueInt64 x -> putInt64Attribute x- AttributeValueLoadout x -> putLoadoutAttribute x- AttributeValueLoadoutOnline x -> putLoadoutOnlineAttribute x- AttributeValueLoadouts x -> putLoadoutsAttribute x- AttributeValueLoadoutsOnline x -> putLoadoutsOnlineAttribute x- AttributeValueLocation x -> putLocationAttribute x- AttributeValueMusicStinger x -> putMusicStingerAttribute x- AttributeValuePartyLeader x -> putPartyLeaderAttribute x- AttributeValuePickup x -> putPickupAttribute x- AttributeValuePickupNew x -> putPickupAttributeNew x- AttributeValuePlayerHistoryKey x -> putPlayerHistoryKeyAttribute x- AttributeValuePrivateMatchSettings x -> putPrivateMatchSettingsAttribute x- AttributeValueQWord x -> putQWordAttribute x- AttributeValueReservation x -> putReservationAttribute x- AttributeValueRigidBodyState x -> putRigidBodyStateAttribute x- AttributeValueStatEvent x -> putStatEventAttribute x- AttributeValueString x -> putStringAttribute x- AttributeValueTeamPaint x -> putTeamPaintAttribute x- AttributeValueTitle x -> putTitleAttribute x- AttributeValueUniqueId x -> putUniqueIdAttribute x- AttributeValueWeldedInfo x -> putWeldedInfoAttribute x
@@ -1,12 +0,0 @@-module Rattletrap.Encode.BooleanAttribute- ( putBooleanAttribute- )-where--import Rattletrap.Type.BooleanAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putBooleanAttribute :: BooleanAttribute -> BinaryBits.BitPut ()-putBooleanAttribute booleanAttribute =- BinaryBits.putBool (booleanAttributeValue booleanAttribute)
@@ -1,13 +0,0 @@-module Rattletrap.Encode.ByteAttribute- ( putByteAttribute- )-where--import Rattletrap.Encode.Word8le-import Rattletrap.Type.ByteAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putByteAttribute :: ByteAttribute -> BinaryBits.BitPut ()-putByteAttribute byteAttribute =- putWord8Bits (byteAttributeValue byteAttribute)
@@ -1,18 +0,0 @@-module Rattletrap.Encode.Cache- ( putCache- )-where--import Rattletrap.Encode.AttributeMapping-import Rattletrap.Encode.List-import Rattletrap.Encode.Word32le-import Rattletrap.Type.Cache--import qualified Data.Binary as Binary--putCache :: Cache -> Binary.Put-putCache cache = do- putWord32 (cacheClassId cache)- putWord32 (cacheParentCacheId cache)- putWord32 (cacheCacheId cache)- putList putAttributeMapping (cacheAttributeMappings cache)
@@ -1,21 +0,0 @@-module Rattletrap.Encode.CamSettingsAttribute- ( putCamSettingsAttribute- )-where--import Rattletrap.Encode.Float32le-import Rattletrap.Type.CamSettingsAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putCamSettingsAttribute :: CamSettingsAttribute -> BinaryBits.BitPut ()-putCamSettingsAttribute camSettingsAttribute = do- putFloat32Bits (camSettingsAttributeFov camSettingsAttribute)- putFloat32Bits (camSettingsAttributeHeight camSettingsAttribute)- putFloat32Bits (camSettingsAttributeAngle camSettingsAttribute)- putFloat32Bits (camSettingsAttributeDistance camSettingsAttribute)- putFloat32Bits (camSettingsAttributeStiffness camSettingsAttribute)- putFloat32Bits (camSettingsAttributeSwivelSpeed camSettingsAttribute)- case camSettingsAttributeTransitionSpeed camSettingsAttribute of- Nothing -> pure ()- Just transitionSpeed -> putFloat32Bits transitionSpeed
@@ -1,15 +0,0 @@-module Rattletrap.Encode.ClassMapping- ( putClassMapping- )-where--import Rattletrap.Encode.Str-import Rattletrap.Encode.Word32le-import Rattletrap.Type.ClassMapping--import qualified Data.Binary as Binary--putClassMapping :: ClassMapping -> Binary.Put-putClassMapping classMapping = do- putText (classMappingName classMapping)- putWord32 (classMappingStreamId classMapping)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.ClubColorsAttribute- ( putClubColorsAttribute- )-where--import Rattletrap.Encode.Word8le-import Rattletrap.Type.ClubColorsAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putClubColorsAttribute :: ClubColorsAttribute -> BinaryBits.BitPut ()-putClubColorsAttribute clubColorsAttribute = do- BinaryBits.putBool (clubColorsAttributeBlueFlag clubColorsAttribute)- putWord8Bits (clubColorsAttributeBlueColor clubColorsAttribute)- BinaryBits.putBool (clubColorsAttributeOrangeFlag clubColorsAttribute)- putWord8Bits (clubColorsAttributeOrangeColor clubColorsAttribute)
@@ -1,10 +0,0 @@-module Rattletrap.Encode.Common- ( putBitsLE- )-where--import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Bits as Bits--putBitsLE :: Bits.Bits a => Int -> a -> BinaryBits.BitPut ()-putBitsLE size x = mapM_ (BinaryBits.putBool . Bits.testBit x) [0 .. size - 1]
@@ -1,44 +0,0 @@-module Rattletrap.Encode.CompressedWord- ( putCompressedWord- )-where--import Rattletrap.Type.CompressedWord--import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Bits as Bits--putCompressedWord :: CompressedWord -> BinaryBits.BitPut ()-putCompressedWord compressedWord =- let- limit = compressedWordLimit compressedWord- value = compressedWordValue compressedWord- maxBits = getMaxBits limit- in putCompressedWordStep limit value maxBits 0 0--putCompressedWordStep- :: Word -> Word -> Int -> Int -> Word -> BinaryBits.BitPut ()-putCompressedWordStep limit value maxBits position soFar =- if position < maxBits- then do- let x = Bits.shiftL 1 position :: Word- if maxBits > 1 && position == maxBits - 1 && soFar + x > limit- then pure ()- else do- let bit = Bits.testBit value position- BinaryBits.putBool bit- let delta = if bit then x else 0- putCompressedWordStep- limit- value- maxBits- (position + 1)- (soFar + delta)- else pure ()--getMaxBits :: Word -> Int-getMaxBits x =- let- n :: Int- n = max 1 (ceiling (logBase (2 :: Double) (fromIntegral (max 1 x))))- in if x < 1024 && x == 2 ^ n then n + 1 else n
@@ -1,15 +0,0 @@-module Rattletrap.Encode.CompressedWordVector- ( putCompressedWordVector- )-where--import Rattletrap.Encode.CompressedWord-import Rattletrap.Type.CompressedWordVector--import qualified Data.Binary.Bits.Put as BinaryBits--putCompressedWordVector :: CompressedWordVector -> BinaryBits.BitPut ()-putCompressedWordVector compressedWordVector = do- putCompressedWord (compressedWordVectorX compressedWordVector)- putCompressedWord (compressedWordVectorY compressedWordVector)- putCompressedWord (compressedWordVectorZ compressedWordVector)
@@ -1,43 +0,0 @@-module Rattletrap.Encode.Content- ( putContent- )-where--import Rattletrap.Encode.Cache-import Rattletrap.Encode.ClassMapping-import Rattletrap.Encode.Frame-import Rattletrap.Encode.KeyFrame-import Rattletrap.Encode.List-import Rattletrap.Encode.Mark-import Rattletrap.Encode.Message-import Rattletrap.Encode.Str-import Rattletrap.Encode.Word32le-import Rattletrap.Type.Content-import Rattletrap.Type.Word32le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putContent :: Content -> Binary.Put-putContent content = do- putList putText (contentLevels content)- putList putKeyFrame (contentKeyFrames content)- let streamSize = contentStreamSize content- putWord32 streamSize- let- stream = LazyBytes.toStrict- (Binary.runPut (BinaryBits.runBitPut (putFrames (contentFrames content)))- )- Binary.putByteString- (reverseBytes (padBytes (word32leValue streamSize) stream))- putList putMessage (contentMessages content)- putList putMark (contentMarks content)- putList putText (contentPackages content)- putList putText (contentObjects content)- putList putText (contentNames content)- putList putClassMapping (contentClassMappings content)- putList putCache (contentCaches content)- mapM_ Binary.putWord8 (contentUnknown content)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.CustomDemolishAttribute- ( putCustomDemolishAttribute- )-where--import Rattletrap.Encode.DemolishAttribute-import Rattletrap.Encode.Int32le-import Rattletrap.Type.CustomDemolishAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putCustomDemolishAttribute :: CustomDemolishAttribute -> BinaryBits.BitPut ()-putCustomDemolishAttribute x = do- BinaryBits.putBool (customDemolishAttributeFlag x)- putInt32Bits (customDemolishAttributeId x)- putDemolishAttribute (customDemolishAttributeDemolish x)
@@ -1,20 +0,0 @@-module Rattletrap.Encode.DamageStateAttribute- ( putDamageStateAttribute- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Encode.Vector-import Rattletrap.Encode.Word8le-import Rattletrap.Type.DamageStateAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putDamageStateAttribute :: DamageStateAttribute -> BinaryBits.BitPut ()-putDamageStateAttribute damageStateAttribute = do- putWord8Bits (damageStateAttributeUnknown1 damageStateAttribute)- BinaryBits.putBool (damageStateAttributeUnknown2 damageStateAttribute)- putInt32Bits (damageStateAttributeUnknown3 damageStateAttribute)- putVector (damageStateAttributeUnknown4 damageStateAttribute)- BinaryBits.putBool (damageStateAttributeUnknown5 damageStateAttribute)- BinaryBits.putBool (damageStateAttributeUnknown6 damageStateAttribute)
@@ -1,19 +0,0 @@-module Rattletrap.Encode.DemolishAttribute- ( putDemolishAttribute- )-where--import Rattletrap.Encode.Vector-import Rattletrap.Encode.Word32le-import Rattletrap.Type.DemolishAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putDemolishAttribute :: DemolishAttribute -> BinaryBits.BitPut ()-putDemolishAttribute demolishAttribute = do- BinaryBits.putBool (demolishAttributeAttackerFlag demolishAttribute)- putWord32Bits (demolishAttributeAttackerActorId demolishAttribute)- BinaryBits.putBool (demolishAttributeVictimFlag demolishAttribute)- putWord32Bits (demolishAttributeVictimActorId demolishAttribute)- putVector (demolishAttributeAttackerVelocity demolishAttribute)- putVector (demolishAttributeVictimVelocity demolishAttribute)
@@ -1,11 +0,0 @@-module Rattletrap.Encode.DestroyedReplication- ( putDestroyedReplication- )-where--import Rattletrap.Type.DestroyedReplication--import qualified Data.Binary.Bits.Put as BinaryBits--putDestroyedReplication :: DestroyedReplication -> BinaryBits.BitPut ()-putDestroyedReplication _ = pure ()
@@ -1,17 +0,0 @@-module Rattletrap.Encode.Dictionary- ( putDictionary- )-where--import Rattletrap.Encode.Str-import Rattletrap.Type.Dictionary--import qualified Data.Binary as Binary--putDictionary :: (a -> Binary.Put) -> Dictionary a -> Binary.Put-putDictionary f x = case x of- DictionaryElement k v y -> do- putText k- f v- putDictionary f y- DictionaryEnd y -> putText y
@@ -1,13 +0,0 @@-module Rattletrap.Encode.EnumAttribute- ( putEnumAttribute- )-where--import Rattletrap.Encode.Common-import Rattletrap.Type.EnumAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putEnumAttribute :: EnumAttribute -> BinaryBits.BitPut ()-putEnumAttribute enumAttribute =- putBitsLE 11 (enumAttributeValue enumAttribute)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.ExplosionAttribute- ( putExplosionAttribute- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Encode.Vector-import Rattletrap.Type.ExplosionAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putExplosionAttribute :: ExplosionAttribute -> BinaryBits.BitPut ()-putExplosionAttribute explosionAttribute = do- BinaryBits.putBool False- putInt32Bits (explosionAttributeActorId explosionAttribute)- putVector (explosionAttributeLocation explosionAttribute)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.ExtendedExplosionAttribute- ( putExtendedExplosionAttribute- )-where--import Rattletrap.Encode.ExplosionAttribute-import Rattletrap.Encode.FlaggedIntAttribute-import Rattletrap.Type.ExtendedExplosionAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putExtendedExplosionAttribute- :: ExtendedExplosionAttribute -> BinaryBits.BitPut ()-putExtendedExplosionAttribute x = do- putExplosionAttribute (extendedExplosionAttributeExplosion x)- putFlaggedIntAttribute (extendedExplosionAttributeUnknown x)
@@ -1,14 +0,0 @@-module Rattletrap.Encode.FlaggedByteAttribute- ( putFlaggedByteAttribute- )-where--import Rattletrap.Encode.Word8le-import Rattletrap.Type.FlaggedByteAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putFlaggedByteAttribute :: FlaggedByteAttribute -> BinaryBits.BitPut ()-putFlaggedByteAttribute flaggedByteAttribute = do- BinaryBits.putBool (flaggedByteAttributeFlag flaggedByteAttribute)- putWord8Bits (flaggedByteAttributeByte flaggedByteAttribute)
@@ -1,14 +0,0 @@-module Rattletrap.Encode.FlaggedIntAttribute- ( putFlaggedIntAttribute- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Type.FlaggedIntAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putFlaggedIntAttribute :: FlaggedIntAttribute -> BinaryBits.BitPut ()-putFlaggedIntAttribute flaggedIntAttribute = do- BinaryBits.putBool (flaggedIntAttributeFlag flaggedIntAttribute)- putInt32Bits (flaggedIntAttributeInt flaggedIntAttribute)
@@ -1,21 +0,0 @@-module Rattletrap.Encode.Float32le- ( putFloat32- , putFloat32Bits- )-where--import Rattletrap.Type.Float32le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putFloat32 :: Float32le -> Binary.Put-putFloat32 = Binary.putFloatle . float32leValue--putFloat32Bits :: Float32le -> BinaryBits.BitPut ()-putFloat32Bits float32 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putFloat32 float32))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,13 +0,0 @@-module Rattletrap.Encode.FloatAttribute- ( putFloatAttribute- )-where--import Rattletrap.Encode.Float32le-import Rattletrap.Type.FloatAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putFloatAttribute :: FloatAttribute -> BinaryBits.BitPut ()-putFloatAttribute floatAttribute =- putFloat32Bits (floatAttributeValue floatAttribute)
@@ -1,24 +0,0 @@-module Rattletrap.Encode.Frame- ( putFrames- )-where--import Rattletrap.Encode.Float32le-import Rattletrap.Encode.Replication-import Rattletrap.Type.Frame--import qualified Data.Binary.Bits.Put as BinaryBits--putFrames :: [Frame] -> BinaryBits.BitPut ()-putFrames frames = case frames of- [] -> pure ()- [frame] -> putFrame frame- first : rest -> do- putFrame first- putFrames rest--putFrame :: Frame -> BinaryBits.BitPut ()-putFrame frame = do- putFloat32Bits (frameTime frame)- putFloat32Bits (frameDelta frame)- putReplications (frameReplications frame)
@@ -1,14 +0,0 @@-module Rattletrap.Encode.GameModeAttribute- ( putGameModeAttribute- )-where--import Rattletrap.Type.GameModeAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putGameModeAttribute :: GameModeAttribute -> BinaryBits.BitPut ()-putGameModeAttribute gameModeAttribute = do- let numBits = gameModeAttributeNumBits gameModeAttribute- let word = gameModeAttributeWord gameModeAttribute- BinaryBits.putWord8 numBits word
@@ -1,22 +0,0 @@-module Rattletrap.Encode.Header- ( putHeader- )-where--import Rattletrap.Encode.Dictionary-import Rattletrap.Encode.Property-import Rattletrap.Encode.Str-import Rattletrap.Encode.Word32le-import Rattletrap.Type.Header--import qualified Data.Binary as Binary--putHeader :: Header -> Binary.Put-putHeader header = do- putWord32 (headerEngineVersion header)- putWord32 (headerLicenseeVersion header)- case headerPatchVersion header of- Nothing -> pure ()- Just patchVersion -> putWord32 patchVersion- putText (headerLabel header)- putDictionary putProperty (headerProperties header)
@@ -1,19 +0,0 @@-module Rattletrap.Encode.Initialization- ( putInitialization- )-where--import Rattletrap.Encode.Int8Vector-import Rattletrap.Encode.Vector-import Rattletrap.Type.Initialization--import qualified Data.Binary.Bits.Put as BinaryBits--putInitialization :: Initialization -> BinaryBits.BitPut ()-putInitialization initialization = do- case initializationLocation initialization of- Nothing -> pure ()- Just location -> putVector location- case initializationRotation initialization of- Nothing -> pure ()- Just rotation -> putInt8Vector rotation
@@ -1,21 +0,0 @@-module Rattletrap.Encode.Int32le- ( putInt32- , putInt32Bits- )-where--import Rattletrap.Type.Int32le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putInt32 :: Int32le -> Binary.Put-putInt32 int32 = Binary.putInt32le (int32leValue int32)--putInt32Bits :: Int32le -> BinaryBits.BitPut ()-putInt32Bits int32 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putInt32 int32))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,13 +0,0 @@-module Rattletrap.Encode.Int64Attribute- ( putInt64Attribute- )-where--import Rattletrap.Encode.Int64le-import Rattletrap.Type.Int64Attribute--import qualified Data.Binary.Bits.Put as BinaryBits--putInt64Attribute :: Int64Attribute -> BinaryBits.BitPut ()-putInt64Attribute int64Attribute =- putInt64Bits (int64AttributeValue int64Attribute)
@@ -1,20 +0,0 @@-module Rattletrap.Encode.Int64le- ( putInt64Bits- )-where--import Rattletrap.Type.Int64le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putInt64 :: Int64le -> Binary.Put-putInt64 int64 = Binary.putInt64le (int64leValue int64)--putInt64Bits :: Int64le -> BinaryBits.BitPut ()-putInt64Bits int64 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putInt64 int64))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,23 +0,0 @@-module Rattletrap.Encode.Int8Vector- ( putInt8Vector- )-where--import Rattletrap.Encode.Int8le-import Rattletrap.Type.Int8Vector-import Rattletrap.Type.Int8le--import qualified Data.Binary.Bits.Put as BinaryBits--putInt8Vector :: Int8Vector -> BinaryBits.BitPut ()-putInt8Vector int8Vector = do- putInt8VectorField (int8VectorX int8Vector)- putInt8VectorField (int8VectorY int8Vector)- putInt8VectorField (int8VectorZ int8Vector)--putInt8VectorField :: Maybe Int8le -> BinaryBits.BitPut ()-putInt8VectorField maybeField = case maybeField of- Nothing -> BinaryBits.putBool False- Just field -> do- BinaryBits.putBool True- putInt8Bits field
@@ -1,19 +0,0 @@-module Rattletrap.Encode.Int8le- ( putInt8Bits- )-where--import Rattletrap.Type.Int8le-import Rattletrap.Utility.Bytes--import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putInt8 :: Int8le -> Binary.Put-putInt8 int8 = Binary.putInt8 (int8leValue int8)--putInt8Bits :: Int8le -> BinaryBits.BitPut ()-putInt8Bits int8 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putInt8 int8))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,12 +0,0 @@-module Rattletrap.Encode.IntAttribute- ( putIntAttribute- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Type.IntAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putIntAttribute :: IntAttribute -> BinaryBits.BitPut ()-putIntAttribute intAttribute = putInt32Bits (intAttributeValue intAttribute)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.KeyFrame- ( putKeyFrame- )-where--import Rattletrap.Encode.Float32le-import Rattletrap.Encode.Word32le-import Rattletrap.Type.KeyFrame--import qualified Data.Binary as Binary--putKeyFrame :: KeyFrame -> Binary.Put-putKeyFrame keyFrame = do- putFloat32 (keyFrameTime keyFrame)- putWord32 (keyFrameFrame keyFrame)- putWord32 (keyFramePosition keyFrame)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.List- ( putList- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Type.List-import Rattletrap.Type.Word32le--import qualified Data.Binary as Binary--putList :: (a -> Binary.Put) -> List a -> Binary.Put-putList putElement list = do- let elements = listValue list- putWord32 (Word32le (fromIntegral (length elements)))- mapM_ putElement elements
@@ -1,35 +0,0 @@-module Rattletrap.Encode.LoadoutAttribute- ( putLoadoutAttribute- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Encode.Word8le-import Rattletrap.Type.LoadoutAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putLoadoutAttribute :: LoadoutAttribute -> BinaryBits.BitPut ()-putLoadoutAttribute loadoutAttribute = do- putWord8Bits (loadoutAttributeVersion loadoutAttribute)- putWord32Bits (loadoutAttributeBody loadoutAttribute)- putWord32Bits (loadoutAttributeDecal loadoutAttribute)- putWord32Bits (loadoutAttributeWheels loadoutAttribute)- putWord32Bits (loadoutAttributeRocketTrail loadoutAttribute)- putWord32Bits (loadoutAttributeAntenna loadoutAttribute)- putWord32Bits (loadoutAttributeTopper loadoutAttribute)- putWord32Bits (loadoutAttributeUnknown1 loadoutAttribute)- putOptional (loadoutAttributeUnknown2 loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeEngineAudio loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeTrail loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeGoalExplosion loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeBanner loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeUnknown3 loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeUnknown4 loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeUnknown5 loadoutAttribute) putWord32Bits- putOptional (loadoutAttributeUnknown6 loadoutAttribute) putWord32Bits--putOptional :: Maybe a -> (a -> BinaryBits.BitPut ()) -> BinaryBits.BitPut ()-putOptional m f = case m of- Just x -> f x- Nothing -> pure ()
@@ -1,17 +0,0 @@-module Rattletrap.Encode.LoadoutOnlineAttribute- ( putLoadoutOnlineAttribute- )-where--import Rattletrap.Encode.ProductAttribute-import Rattletrap.Encode.Word8le-import Rattletrap.Type.LoadoutOnlineAttribute-import Rattletrap.Type.Word8le--import qualified Data.Binary.Bits.Put as BinaryBits--putLoadoutOnlineAttribute :: LoadoutOnlineAttribute -> BinaryBits.BitPut ()-putLoadoutOnlineAttribute loadoutAttribute = do- let attributes = loadoutAttributeValue loadoutAttribute- putWord8Bits (Word8le (fromIntegral (length attributes)))- mapM_ putProductAttributes attributes
@@ -1,14 +0,0 @@-module Rattletrap.Encode.LoadoutsAttribute- ( putLoadoutsAttribute- )-where--import Rattletrap.Encode.LoadoutAttribute-import Rattletrap.Type.LoadoutsAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putLoadoutsAttribute :: LoadoutsAttribute -> BinaryBits.BitPut ()-putLoadoutsAttribute loadoutsAttribute = do- putLoadoutAttribute (loadoutsAttributeBlue loadoutsAttribute)- putLoadoutAttribute (loadoutsAttributeOrange loadoutsAttribute)
@@ -1,18 +0,0 @@-module Rattletrap.Encode.LoadoutsOnlineAttribute- ( putLoadoutsOnlineAttribute- )-where--import Rattletrap.Encode.LoadoutOnlineAttribute-import Rattletrap.Type.LoadoutsOnlineAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putLoadoutsOnlineAttribute :: LoadoutsOnlineAttribute -> BinaryBits.BitPut ()-putLoadoutsOnlineAttribute loadoutsOnlineAttribute = do- putLoadoutOnlineAttribute- (loadoutsOnlineAttributeBlue loadoutsOnlineAttribute)- putLoadoutOnlineAttribute- (loadoutsOnlineAttributeOrange loadoutsOnlineAttribute)- BinaryBits.putBool (loadoutsOnlineAttributeUnknown1 loadoutsOnlineAttribute)- BinaryBits.putBool (loadoutsOnlineAttributeUnknown2 loadoutsOnlineAttribute)
@@ -1,13 +0,0 @@-module Rattletrap.Encode.LocationAttribute- ( putLocationAttribute- )-where--import Rattletrap.Encode.Vector-import Rattletrap.Type.LocationAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putLocationAttribute :: LocationAttribute -> BinaryBits.BitPut ()-putLocationAttribute locationAttribute =- putVector (locationAttributeValue locationAttribute)
@@ -1,15 +0,0 @@-module Rattletrap.Encode.Mark- ( putMark- )-where--import Rattletrap.Encode.Str-import Rattletrap.Encode.Word32le-import Rattletrap.Type.Mark--import qualified Data.Binary as Binary--putMark :: Mark -> Binary.Put-putMark mark = do- putText (markValue mark)- putWord32 (markFrame mark)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.Message- ( putMessage- )-where--import Rattletrap.Encode.Str-import Rattletrap.Encode.Word32le-import Rattletrap.Type.Message--import qualified Data.Binary as Binary--putMessage :: Message -> Binary.Put-putMessage message = do- putWord32 (messageFrame message)- putText (messageName message)- putText (messageValue message)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.MusicStingerAttribute- ( putMusicStingerAttribute- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Encode.Word8le-import Rattletrap.Type.MusicStingerAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putMusicStingerAttribute :: MusicStingerAttribute -> BinaryBits.BitPut ()-putMusicStingerAttribute musicStingerAttribute = do- BinaryBits.putBool (musicStingerAttributeFlag musicStingerAttribute)- putWord32Bits (musicStingerAttributeCue musicStingerAttribute)- putWord8Bits (musicStingerAttributeTrigger musicStingerAttribute)
@@ -1,19 +0,0 @@-module Rattletrap.Encode.PartyLeaderAttribute- ( putPartyLeaderAttribute- )-where--import Rattletrap.Encode.RemoteId-import Rattletrap.Encode.Word8le-import Rattletrap.Type.PartyLeaderAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putPartyLeaderAttribute :: PartyLeaderAttribute -> BinaryBits.BitPut ()-putPartyLeaderAttribute partyLeaderAttribute = do- putWord8Bits (partyLeaderAttributeSystemId partyLeaderAttribute)- case partyLeaderAttributeId partyLeaderAttribute of- Nothing -> pure ()- Just (remoteId, localId) -> do- putRemoteId remoteId- putWord8Bits localId
@@ -1,18 +0,0 @@-module Rattletrap.Encode.PickupAttribute- ( putPickupAttribute- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Type.PickupAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putPickupAttribute :: PickupAttribute -> BinaryBits.BitPut ()-putPickupAttribute pickupAttribute = do- case pickupAttributeInstigatorId pickupAttribute of- Nothing -> BinaryBits.putBool False- Just instigatorId -> do- BinaryBits.putBool True- putWord32Bits instigatorId- BinaryBits.putBool (pickupAttributePickedUp pickupAttribute)
@@ -1,19 +0,0 @@-module Rattletrap.Encode.PickupAttributeNew- ( putPickupAttributeNew- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Encode.Word8le-import Rattletrap.Type.PickupAttributeNew--import qualified Data.Binary.Bits.Put as BinaryBits--putPickupAttributeNew :: PickupAttributeNew -> BinaryBits.BitPut ()-putPickupAttributeNew pickupAttributeNew = do- case pickupAttributeNewInstigatorId pickupAttributeNew of- Nothing -> BinaryBits.putBool False- Just instigatorId -> do- BinaryBits.putBool True- putWord32Bits instigatorId- putWord8Bits (pickupAttributeNewPickedUp pickupAttributeNew)
@@ -1,13 +0,0 @@-module Rattletrap.Encode.PlayerHistoryKeyAttribute- ( putPlayerHistoryKeyAttribute- )-where--import Rattletrap.Encode.Common-import Rattletrap.Type.PlayerHistoryKeyAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putPlayerHistoryKeyAttribute- :: PlayerHistoryKeyAttribute -> BinaryBits.BitPut ()-putPlayerHistoryKeyAttribute = putBitsLE 14 . playerHistoryKeyAttributeUnknown
@@ -1,26 +0,0 @@-module Rattletrap.Encode.PrivateMatchSettingsAttribute- ( putPrivateMatchSettingsAttribute- )-where--import Rattletrap.Encode.Str-import Rattletrap.Encode.Word32le-import Rattletrap.Type.PrivateMatchSettingsAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putPrivateMatchSettingsAttribute- :: PrivateMatchSettingsAttribute -> BinaryBits.BitPut ()-putPrivateMatchSettingsAttribute privateMatchSettingsAttribute = do- putTextBits- (privateMatchSettingsAttributeMutators privateMatchSettingsAttribute)- putWord32Bits- (privateMatchSettingsAttributeJoinableBy privateMatchSettingsAttribute)- putWord32Bits- (privateMatchSettingsAttributeMaxPlayers privateMatchSettingsAttribute)- putTextBits- (privateMatchSettingsAttributeGameName privateMatchSettingsAttribute)- putTextBits- (privateMatchSettingsAttributePassword privateMatchSettingsAttribute)- BinaryBits.putBool- (privateMatchSettingsAttributeFlag privateMatchSettingsAttribute)
@@ -1,37 +0,0 @@-module Rattletrap.Encode.ProductAttribute- ( putProductAttributes- )-where--import Rattletrap.Encode.Common-import Rattletrap.Encode.CompressedWord-import Rattletrap.Encode.Word32le-import Rattletrap.Encode.Word8le-import Rattletrap.Encode.Str-import Rattletrap.Type.ProductAttribute-import Rattletrap.Type.Word8le--import qualified Data.Binary.Bits.Put as BinaryBits--putProductAttributes :: [ProductAttribute] -> BinaryBits.BitPut ()-putProductAttributes attributes = do- putWord8Bits (Word8le (fromIntegral (length attributes)))- mapM_ putProductAttribute attributes--putProductAttribute :: ProductAttribute -> BinaryBits.BitPut ()-putProductAttribute attribute = do- BinaryBits.putBool (productAttributeUnknown attribute)- putWord32Bits (productAttributeObjectId attribute)- case productAttributeValue attribute of- ProductAttributeValuePaintedOld x -> putCompressedWord x- ProductAttributeValuePaintedNew x -> putBitsLE 31 x- ProductAttributeValueTeamEditionOld x -> putCompressedWord x- ProductAttributeValueTeamEditionNew x -> putBitsLE 31 x- ProductAttributeValueSpecialEdition x -> putBitsLE 31 x- ProductAttributeValueUserColorOld x -> case x of- Nothing -> BinaryBits.putBool False- Just y -> do- BinaryBits.putBool True- putBitsLE 31 y- ProductAttributeValueUserColorNew x -> putWord32Bits x- ProductAttributeValueTitleId x -> putTextBits x
@@ -1,17 +0,0 @@-module Rattletrap.Encode.Property- ( putProperty- )-where--import Rattletrap.Encode.PropertyValue-import Rattletrap.Encode.Str-import Rattletrap.Encode.Word64le-import Rattletrap.Type.Property--import qualified Data.Binary as Binary--putProperty :: Property -> Binary.Put-putProperty property = do- putText (propertyKind property)- putWord64 (propertySize property)- putPropertyValue putProperty (propertyValue property)
@@ -1,30 +0,0 @@-module Rattletrap.Encode.PropertyValue- ( putPropertyValue- )-where--import Rattletrap.Encode.Dictionary-import Rattletrap.Encode.Float32le-import Rattletrap.Encode.Int32le-import Rattletrap.Encode.List-import Rattletrap.Encode.Str-import Rattletrap.Encode.Word64le-import Rattletrap.Encode.Word8le-import Rattletrap.Type.PropertyValue--import qualified Data.Binary as Binary--putPropertyValue :: (a -> Binary.Put) -> PropertyValue a -> Binary.Put-putPropertyValue putProperty value = case value of- PropertyValueArray list -> putList (putDictionary putProperty) list- PropertyValueBool word8 -> putWord8 word8- PropertyValueByte k mv -> do- putText k- case mv of- Nothing -> pure ()- Just v -> putText v- PropertyValueFloat float32 -> putFloat32 float32- PropertyValueInt int32 -> putInt32 int32- PropertyValueName text -> putText text- PropertyValueQWord word64 -> putWord64 word64- PropertyValueStr text -> putText text
@@ -1,13 +0,0 @@-module Rattletrap.Encode.QWordAttribute- ( putQWordAttribute- )-where--import Rattletrap.Encode.Word64le-import Rattletrap.Type.QWordAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putQWordAttribute :: QWordAttribute -> BinaryBits.BitPut ()-putQWordAttribute qWordAttribute =- putWord64Bits (qWordAttributeValue qWordAttribute)
@@ -1,41 +0,0 @@-module Rattletrap.Encode.Quaternion- ( putQuaternion- )-where--import Rattletrap.Encode.CompressedWord-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Quaternion--import qualified Data.Binary.Bits.Put as BinaryBits--putQuaternion :: Quaternion -> BinaryBits.BitPut ()-putQuaternion q = do- let c = maxComponent q- putComponent c- case c of- ComponentX -> putParts (quaternionY q) (quaternionZ q) (quaternionW q)- ComponentY -> putParts (quaternionX q) (quaternionZ q) (quaternionW q)- ComponentZ -> putParts (quaternionX q) (quaternionY q) (quaternionW q)- ComponentW -> putParts (quaternionX q) (quaternionY q) (quaternionZ q)--putComponent :: Component -> BinaryBits.BitPut ()-putComponent component = putCompressedWord- (CompressedWord- 3- (case component of- ComponentX -> 0- ComponentY -> 1- ComponentZ -> 2- ComponentW -> 3- )- )--putParts :: Double -> Double -> Double -> BinaryBits.BitPut ()-putParts a b c = do- putPart a- putPart b- putPart c--putPart :: Double -> BinaryBits.BitPut ()-putPart = putCompressedWord . compressPart
@@ -1,37 +0,0 @@-module Rattletrap.Encode.RemoteId- ( putRemoteId- )-where--import Rattletrap.Encode.Common-import Rattletrap.Encode.Str-import Rattletrap.Encode.Word64le-import Rattletrap.Type.RemoteId-import Rattletrap.Type.Word64le-import Rattletrap.Utility.Bytes--import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.ByteString as Bytes--putRemoteId :: RemoteId -> BinaryBits.BitPut ()-putRemoteId remoteId = case remoteId of- RemoteIdPlayStation name bytes -> do- let rawName = reverseBytes (padBytes (16 :: Int) (encodeLatin1 name))- BinaryBits.putByteString rawName- BinaryBits.putByteString (Bytes.pack bytes)- RemoteIdPsyNet e -> case e of- Left l -> putWord64Bits l- Right (a, b, c, d) -> putWord256 a b c d- RemoteIdSplitscreen word24 -> putBitsLE 24 word24- RemoteIdSteam word64 -> putWord64Bits word64- RemoteIdSwitch a b c d -> putWord256 a b c d- RemoteIdXbox word64 -> putWord64Bits word64- RemoteIdEpic str -> putTextBits str--putWord256- :: Word64le -> Word64le -> Word64le -> Word64le -> BinaryBits.BitPut ()-putWord256 a b c d = do- putWord64Bits a- putWord64Bits b- putWord64Bits c- putWord64Bits d
@@ -1,21 +0,0 @@-module Rattletrap.Encode.Replay- ( putReplay- )-where--import Rattletrap.Encode.Content-import Rattletrap.Encode.Header-import Rattletrap.Encode.Section-import Rattletrap.Type.Replay--import qualified Data.Binary as Binary---- | Generates a raw replay. Use this with 'Data.Binary.Put.runPut'.------ @--- let bytes = 'Data.Binary.Put.runPut' ('putReplay' replay)--- @-putReplay :: Replay -> Binary.Put-putReplay replay = do- putSection putHeader (replayHeader replay)- putSection putContent (replayContent replay)
@@ -1,26 +0,0 @@-module Rattletrap.Encode.Replication- ( putReplications- )-where--import Rattletrap.Encode.CompressedWord-import Rattletrap.Encode.ReplicationValue-import Rattletrap.Type.Replication--import qualified Data.Binary.Bits.Put as BinaryBits--putReplications :: [Replication] -> BinaryBits.BitPut ()-putReplications replications = case replications of- [] -> BinaryBits.putBool False- [replication] -> do- putReplication replication- BinaryBits.putBool False- first : rest -> do- putReplication first- putReplications rest--putReplication :: Replication -> BinaryBits.BitPut ()-putReplication replication = do- BinaryBits.putBool True- putCompressedWord (replicationActorId replication)- putReplicationValue (replicationValue replication)
@@ -1,25 +0,0 @@-module Rattletrap.Encode.ReplicationValue- ( putReplicationValue- )-where--import Rattletrap.Encode.DestroyedReplication-import Rattletrap.Encode.SpawnedReplication-import Rattletrap.Encode.UpdatedReplication-import Rattletrap.Type.ReplicationValue--import qualified Data.Binary.Bits.Put as BinaryBits--putReplicationValue :: ReplicationValue -> BinaryBits.BitPut ()-putReplicationValue value = case value of- ReplicationValueSpawned x -> do- BinaryBits.putBool True- BinaryBits.putBool True- putSpawnedReplication x- ReplicationValueUpdated x -> do- BinaryBits.putBool True- BinaryBits.putBool False- putUpdatedReplication x- ReplicationValueDestroyed x -> do- BinaryBits.putBool False- putDestroyedReplication x
@@ -1,24 +0,0 @@-module Rattletrap.Encode.ReservationAttribute- ( putReservationAttribute- )-where--import Rattletrap.Encode.CompressedWord-import Rattletrap.Encode.Str-import Rattletrap.Encode.UniqueIdAttribute-import Rattletrap.Type.ReservationAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putReservationAttribute :: ReservationAttribute -> BinaryBits.BitPut ()-putReservationAttribute reservationAttribute = do- putCompressedWord (reservationAttributeNumber reservationAttribute)- putUniqueIdAttribute (reservationAttributeUniqueId reservationAttribute)- case reservationAttributeName reservationAttribute of- Nothing -> pure ()- Just name -> putTextBits name- BinaryBits.putBool (reservationAttributeUnknown1 reservationAttribute)- BinaryBits.putBool (reservationAttributeUnknown2 reservationAttribute)- case reservationAttributeUnknown3 reservationAttribute of- Nothing -> pure ()- Just c -> BinaryBits.putWord8 6 c
@@ -1,22 +0,0 @@-module Rattletrap.Encode.RigidBodyStateAttribute- ( putRigidBodyStateAttribute- )-where--import Rattletrap.Encode.Rotation-import Rattletrap.Encode.Vector-import Rattletrap.Type.RigidBodyStateAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putRigidBodyStateAttribute :: RigidBodyStateAttribute -> BinaryBits.BitPut ()-putRigidBodyStateAttribute rigidBodyStateAttribute = do- BinaryBits.putBool (rigidBodyStateAttributeSleeping rigidBodyStateAttribute)- putVector (rigidBodyStateAttributeLocation rigidBodyStateAttribute)- putRotation (rigidBodyStateAttributeRotation rigidBodyStateAttribute)- case rigidBodyStateAttributeLinearVelocity rigidBodyStateAttribute of- Nothing -> pure ()- Just linearVelocity -> putVector linearVelocity- case rigidBodyStateAttributeAngularVelocity rigidBodyStateAttribute of- Nothing -> pure ()- Just angularVelocity -> putVector angularVelocity
@@ -1,15 +0,0 @@-module Rattletrap.Encode.Rotation- ( putRotation- )-where--import Rattletrap.Encode.CompressedWordVector-import Rattletrap.Encode.Quaternion-import Rattletrap.Type.Rotation--import qualified Data.Binary.Bits.Put as BinaryBits--putRotation :: Rotation -> BinaryBits.BitPut ()-putRotation r = case r of- RotationCompressedWordVector cwv -> putCompressedWordVector cwv- RotationQuaternion q -> putQuaternion q
@@ -1,31 +0,0 @@-module Rattletrap.Encode.Section- ( putSection- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Type.Section-import Rattletrap.Type.Word32le-import Rattletrap.Utility.Crc--import qualified Data.Binary as Binary-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Lazy as LazyBytes---- | Given a way to put the 'sectionBody', puts a section. This will also put--- the size and CRC.------ @--- let bytes = 'Data.Binary.Put.runPut' ('putSection' 'Rattletrap.Content.putContent' content)--- @-putSection :: (a -> Binary.Put) -> Section a -> Binary.Put-putSection putBody section = do- let- rawBody =- LazyBytes.toStrict (Binary.runPut (putBody (sectionBody section)))- let size = Bytes.length rawBody- let crc = getCrc32 rawBody- putWord32 (Word32le (fromIntegral size))- putWord32 (Word32le crc)- Binary.putByteString rawBody
@@ -1,19 +0,0 @@-module Rattletrap.Encode.SpawnedReplication- ( putSpawnedReplication- )-where--import Rattletrap.Encode.Initialization-import Rattletrap.Encode.Word32le-import Rattletrap.Type.SpawnedReplication--import qualified Data.Binary.Bits.Put as BinaryBits--putSpawnedReplication :: SpawnedReplication -> BinaryBits.BitPut ()-putSpawnedReplication spawnedReplication = do- BinaryBits.putBool (spawnedReplicationFlag spawnedReplication)- case spawnedReplicationNameIndex spawnedReplication of- Nothing -> pure ()- Just nameIndex -> putWord32Bits nameIndex- putWord32Bits (spawnedReplicationObjectId spawnedReplication)- putInitialization (spawnedReplicationInitialization spawnedReplication)
@@ -1,14 +0,0 @@-module Rattletrap.Encode.StatEventAttribute- ( putStatEventAttribute- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Type.StatEventAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putStatEventAttribute :: StatEventAttribute -> BinaryBits.BitPut ()-putStatEventAttribute statEventAttribute = do- BinaryBits.putBool (statEventAttributeUnknown statEventAttribute)- putInt32Bits (statEventAttributeObjectId statEventAttribute)
@@ -1,53 +0,0 @@-module Rattletrap.Encode.Str- ( putText- , putTextBits- )-where--import Rattletrap.Encode.Int32le-import Rattletrap.Type.Common-import Rattletrap.Type.Int32le-import Rattletrap.Type.Str-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString as Bytes-import qualified Data.Char as Char-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text--putText :: Str -> Binary.Put-putText text = do- let size = getTextSize text- let encode = getTextEncoder size- putInt32 size- Binary.putByteString (encode (addNull (strValue text)))--putTextBits :: Str -> BinaryBits.BitPut ()-putTextBits text = do- let size = getTextSize text- let encode = getTextEncoder size- putInt32Bits size- BinaryBits.putByteString (reverseBytes (encode (addNull (strValue text))))--getTextSize :: Str -> Int32le-getTextSize text =- let- value = strValue text- scale = if Text.all Char.isLatin1 value then 1 else -1 :: Int32- rawSize = if Text.null value- then 0- else fromIntegral (Text.length value) + 1 :: Int32- size = if value == Text.pack "\x00\x00\x00None"- then 0x05000000- else scale * rawSize :: Int32- in Int32le size--getTextEncoder :: Int32le -> Text.Text -> Bytes.ByteString-getTextEncoder size text =- if size < Int32le 0 then Text.encodeUtf16LE text else encodeLatin1 text--addNull :: Text.Text -> Text.Text-addNull text = if Text.null text then text else Text.snoc text '\x00'
@@ -1,13 +0,0 @@-module Rattletrap.Encode.StringAttribute- ( putStringAttribute- )-where--import Rattletrap.Encode.Str-import Rattletrap.Type.StringAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putStringAttribute :: StringAttribute -> BinaryBits.BitPut ()-putStringAttribute stringAttribute =- putTextBits (stringAttributeValue stringAttribute)
@@ -1,18 +0,0 @@-module Rattletrap.Encode.TeamPaintAttribute- ( putTeamPaintAttribute- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Encode.Word8le-import Rattletrap.Type.TeamPaintAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putTeamPaintAttribute :: TeamPaintAttribute -> BinaryBits.BitPut ()-putTeamPaintAttribute teamPaintAttribute = do- putWord8Bits (teamPaintAttributeTeam teamPaintAttribute)- putWord8Bits (teamPaintAttributePrimaryColor teamPaintAttribute)- putWord8Bits (teamPaintAttributeAccentColor teamPaintAttribute)- putWord32Bits (teamPaintAttributePrimaryFinish teamPaintAttribute)- putWord32Bits (teamPaintAttributeAccentFinish teamPaintAttribute)
@@ -1,20 +0,0 @@-module Rattletrap.Encode.TitleAttribute- ( putTitleAttribute- )-where--import Rattletrap.Encode.Word32le-import Rattletrap.Type.TitleAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putTitleAttribute :: TitleAttribute -> BinaryBits.BitPut ()-putTitleAttribute titleAttribute = do- BinaryBits.putBool (titleAttributeUnknown1 titleAttribute)- BinaryBits.putBool (titleAttributeUnknown2 titleAttribute)- putWord32Bits (titleAttributeUnknown3 titleAttribute)- putWord32Bits (titleAttributeUnknown4 titleAttribute)- putWord32Bits (titleAttributeUnknown5 titleAttribute)- putWord32Bits (titleAttributeUnknown6 titleAttribute)- putWord32Bits (titleAttributeUnknown7 titleAttribute)- BinaryBits.putBool (titleAttributeUnknown8 titleAttribute)
@@ -1,16 +0,0 @@-module Rattletrap.Encode.UniqueIdAttribute- ( putUniqueIdAttribute- )-where--import Rattletrap.Encode.RemoteId-import Rattletrap.Encode.Word8le-import Rattletrap.Type.UniqueIdAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putUniqueIdAttribute :: UniqueIdAttribute -> BinaryBits.BitPut ()-putUniqueIdAttribute uniqueIdAttribute = do- putWord8Bits (uniqueIdAttributeSystemId uniqueIdAttribute)- putRemoteId (uniqueIdAttributeRemoteId uniqueIdAttribute)- putWord8Bits (uniqueIdAttributeLocalId uniqueIdAttribute)
@@ -1,13 +0,0 @@-module Rattletrap.Encode.UpdatedReplication- ( putUpdatedReplication- )-where--import Rattletrap.Encode.Attribute-import Rattletrap.Type.UpdatedReplication--import qualified Data.Binary.Bits.Put as BinaryBits--putUpdatedReplication :: UpdatedReplication -> BinaryBits.BitPut ()-putUpdatedReplication updatedReplication =- putAttributes (updatedReplicationAttributes updatedReplication)
@@ -1,27 +0,0 @@-module Rattletrap.Encode.Vector- ( putVector- )-where--import Rattletrap.Encode.CompressedWord-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Vector--import qualified Data.Binary.Bits.Put as BinaryBits--putVector :: Vector -> BinaryBits.BitPut ()-putVector vector = do- let- bitSize =- round (logBase (2 :: Float) (fromIntegral (vectorBias vector))) - 1 :: Word- dx =- fromIntegral (vectorX vector + fromIntegral (vectorBias vector)) :: Word- dy =- fromIntegral (vectorY vector + fromIntegral (vectorBias vector)) :: Word- dz =- fromIntegral (vectorZ vector + fromIntegral (vectorBias vector)) :: Word- limit = 2 ^ (bitSize + 2) :: Word- putCompressedWord (vectorSize vector)- putCompressedWord (CompressedWord limit dx)- putCompressedWord (CompressedWord limit dy)- putCompressedWord (CompressedWord limit dz)
@@ -1,20 +0,0 @@-module Rattletrap.Encode.WeldedInfoAttribute- ( putWeldedInfoAttribute- )-where--import Rattletrap.Encode.Float32le-import Rattletrap.Encode.Int32le-import Rattletrap.Encode.Int8Vector-import Rattletrap.Encode.Vector-import Rattletrap.Type.WeldedInfoAttribute--import qualified Data.Binary.Bits.Put as BinaryBits--putWeldedInfoAttribute :: WeldedInfoAttribute -> BinaryBits.BitPut ()-putWeldedInfoAttribute weldedInfoAttribute = do- BinaryBits.putBool (weldedInfoAttributeActive weldedInfoAttribute)- putInt32Bits (weldedInfoAttributeActorId weldedInfoAttribute)- putVector (weldedInfoAttributeOffset weldedInfoAttribute)- putFloat32Bits (weldedInfoAttributeMass weldedInfoAttribute)- putInt8Vector (weldedInfoAttributeRotation weldedInfoAttribute)
@@ -1,21 +0,0 @@-module Rattletrap.Encode.Word32le- ( putWord32- , putWord32Bits- )-where--import Rattletrap.Type.Word32le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putWord32 :: Word32le -> Binary.Put-putWord32 word32 = Binary.putWord32le (word32leValue word32)--putWord32Bits :: Word32le -> BinaryBits.BitPut ()-putWord32Bits word32 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putWord32 word32))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,21 +0,0 @@-module Rattletrap.Encode.Word64le- ( putWord64- , putWord64Bits- )-where--import Rattletrap.Type.Word64le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putWord64 :: Word64le -> Binary.Put-putWord64 word64 = Binary.putWord64le (word64leValue word64)--putWord64Bits :: Word64le -> BinaryBits.BitPut ()-putWord64Bits word64 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putWord64 word64))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,21 +0,0 @@-module Rattletrap.Encode.Word8le- ( putWord8- , putWord8Bits- )-where--import Rattletrap.Type.Word8le-import Rattletrap.Utility.Bytes--import qualified Data.Binary as Binary-import qualified Data.Binary.Bits.Put as BinaryBits-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy as LazyBytes--putWord8 :: Word8le -> Binary.Put-putWord8 word8 = Binary.putWord8 (word8leValue word8)--putWord8Bits :: Word8le -> BinaryBits.BitPut ()-putWord8Bits word8 = do- let bytes = LazyBytes.toStrict (Binary.runPut (putWord8 word8))- BinaryBits.putByteString (reverseBytes bytes)
@@ -1,20 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.AppliedDamageAttribute- ( AppliedDamageAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int32le-import Rattletrap.Type.Vector-import Rattletrap.Type.Word8le--data AppliedDamageAttribute = AppliedDamageAttribute- { appliedDamageAttributeUnknown1 :: Word8le- , appliedDamageAttributeLocation :: Vector- , appliedDamageAttributeUnknown3 :: Int32le- , appliedDamageAttributeUnknown4 :: Int32le- } deriving (Eq, Ord, Show)--$(deriveJson ''AppliedDamageAttribute)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Attribute- ( Attribute(..)- )-where--import Rattletrap.Type.AttributeValue-import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Str--data Attribute = Attribute- { attributeId :: CompressedWord- , attributeName :: Str- -- ^ Read-only! Changing an attribute's name requires editing the class- -- attribute map.- , attributeValue :: AttributeValue- } deriving (Eq, Ord, Show)--$(deriveJson ''Attribute)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.AttributeMapping- ( AttributeMapping(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le--data AttributeMapping = AttributeMapping- { attributeMappingObjectId :: Word32le- , attributeMappingStreamId :: Word32le- } deriving (Eq, Ord, Show)--$(deriveJson ''AttributeMapping)
@@ -1,50 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.AttributeType- ( AttributeType(..)- )-where--import Rattletrap.Type.Common--data AttributeType- = AttributeTypeAppliedDamage- | AttributeTypeBoolean- | AttributeTypeByte- | AttributeTypeCamSettings- | AttributeTypeClubColors- | AttributeTypeCustomDemolish- | AttributeTypeDamageState- | AttributeTypeDemolish- | AttributeTypeEnum- | AttributeTypeExplosion- | AttributeTypeExtendedExplosion- | AttributeTypeFlaggedInt- | AttributeTypeFlaggedByte- | AttributeTypeFloat- | AttributeTypeGameMode- | AttributeTypeInt- | AttributeTypeInt64- | AttributeTypeLoadout- | AttributeTypeLoadoutOnline- | AttributeTypeLoadouts- | AttributeTypeLoadoutsOnline- | AttributeTypeLocation- | AttributeTypeMusicStinger- | AttributeTypePartyLeader- | AttributeTypePickup- | AttributeTypePickupNew- | AttributeTypePlayerHistoryKey- | AttributeTypePrivateMatchSettings- | AttributeTypeQWord- | AttributeTypeReservation- | AttributeTypeRigidBodyState- | AttributeTypeStatEvent- | AttributeTypeString- | AttributeTypeTeamPaint- | AttributeTypeTitle- | AttributeTypeUniqueId- | AttributeTypeWeldedInfo- deriving (Eq, Ord, Show)--$(deriveJson ''AttributeType)
@@ -1,87 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.AttributeValue- ( AttributeValue(..)- )-where--import Rattletrap.Type.AppliedDamageAttribute-import Rattletrap.Type.BooleanAttribute-import Rattletrap.Type.ByteAttribute-import Rattletrap.Type.CamSettingsAttribute-import Rattletrap.Type.ClubColorsAttribute-import Rattletrap.Type.Common-import Rattletrap.Type.CustomDemolishAttribute-import Rattletrap.Type.DamageStateAttribute-import Rattletrap.Type.DemolishAttribute-import Rattletrap.Type.EnumAttribute-import Rattletrap.Type.ExplosionAttribute-import Rattletrap.Type.ExtendedExplosionAttribute-import Rattletrap.Type.FlaggedIntAttribute-import Rattletrap.Type.FlaggedByteAttribute-import Rattletrap.Type.FloatAttribute-import Rattletrap.Type.GameModeAttribute-import Rattletrap.Type.Int64Attribute-import Rattletrap.Type.IntAttribute-import Rattletrap.Type.LoadoutAttribute-import Rattletrap.Type.LoadoutOnlineAttribute-import Rattletrap.Type.LoadoutsAttribute-import Rattletrap.Type.LoadoutsOnlineAttribute-import Rattletrap.Type.LocationAttribute-import Rattletrap.Type.MusicStingerAttribute-import Rattletrap.Type.PartyLeaderAttribute-import Rattletrap.Type.PickupAttribute-import Rattletrap.Type.PickupAttributeNew-import Rattletrap.Type.PlayerHistoryKeyAttribute-import Rattletrap.Type.PrivateMatchSettingsAttribute-import Rattletrap.Type.QWordAttribute-import Rattletrap.Type.ReservationAttribute-import Rattletrap.Type.RigidBodyStateAttribute-import Rattletrap.Type.StatEventAttribute-import Rattletrap.Type.StringAttribute-import Rattletrap.Type.TeamPaintAttribute-import Rattletrap.Type.TitleAttribute-import Rattletrap.Type.UniqueIdAttribute-import Rattletrap.Type.WeldedInfoAttribute--data AttributeValue- = AttributeValueAppliedDamage AppliedDamageAttribute- | AttributeValueBoolean BooleanAttribute- | AttributeValueByte ByteAttribute- | AttributeValueCamSettings CamSettingsAttribute- | AttributeValueClubColors ClubColorsAttribute- | AttributeValueCustomDemolish CustomDemolishAttribute- | AttributeValueDamageState DamageStateAttribute- | AttributeValueDemolish DemolishAttribute- | AttributeValueEnum EnumAttribute- | AttributeValueExplosion ExplosionAttribute- | AttributeValueExtendedExplosion ExtendedExplosionAttribute- | AttributeValueFlaggedInt FlaggedIntAttribute- | AttributeValueFlaggedByte FlaggedByteAttribute- | AttributeValueFloat FloatAttribute- | AttributeValueGameMode GameModeAttribute- | AttributeValueInt IntAttribute- | AttributeValueInt64 Int64Attribute- | AttributeValueLoadout LoadoutAttribute- | AttributeValueLoadoutOnline LoadoutOnlineAttribute- | AttributeValueLoadouts LoadoutsAttribute- | AttributeValueLoadoutsOnline LoadoutsOnlineAttribute- | AttributeValueLocation LocationAttribute- | AttributeValueMusicStinger MusicStingerAttribute- | AttributeValuePartyLeader PartyLeaderAttribute- | AttributeValuePickup PickupAttribute- | AttributeValuePickupNew PickupAttributeNew- | AttributeValuePlayerHistoryKey PlayerHistoryKeyAttribute- | AttributeValuePrivateMatchSettings PrivateMatchSettingsAttribute- | AttributeValueQWord QWordAttribute- | AttributeValueReservation ReservationAttribute- | AttributeValueRigidBodyState RigidBodyStateAttribute- | AttributeValueStatEvent StatEventAttribute- | AttributeValueString StringAttribute- | AttributeValueTeamPaint TeamPaintAttribute- | AttributeValueTitle TitleAttribute- | AttributeValueUniqueId UniqueIdAttribute- | AttributeValueWeldedInfo WeldedInfoAttribute- deriving (Eq, Ord, Show)--$(deriveJson ''AttributeValue)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.BooleanAttribute- ( BooleanAttribute(..)- )-where--import Rattletrap.Type.Common--newtype BooleanAttribute = BooleanAttribute- { booleanAttributeValue :: Bool- } deriving (Eq, Ord, Show)--$(deriveJson ''BooleanAttribute)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ByteAttribute- ( ByteAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word8le--newtype ByteAttribute = ByteAttribute- { byteAttributeValue :: Word8le- } deriving (Eq, Ord, Show)--$(deriveJson ''ByteAttribute)
@@ -1,20 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Cache- ( Cache(..)- )-where--import Rattletrap.Type.AttributeMapping-import Rattletrap.Type.Common-import Rattletrap.Type.List-import Rattletrap.Type.Word32le--data Cache = Cache- { cacheClassId :: Word32le- , cacheParentCacheId :: Word32le- , cacheCacheId :: Word32le- , cacheAttributeMappings :: List AttributeMapping- } deriving (Eq, Ord, Show)--$(deriveJson ''Cache)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.CamSettingsAttribute- ( CamSettingsAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Float32le--data CamSettingsAttribute = CamSettingsAttribute- { camSettingsAttributeFov :: Float32le- , camSettingsAttributeHeight :: Float32le- , camSettingsAttributeAngle :: Float32le- , camSettingsAttributeDistance :: Float32le- , camSettingsAttributeStiffness :: Float32le- , camSettingsAttributeSwivelSpeed :: Float32le- , camSettingsAttributeTransitionSpeed :: Maybe Float32le- } deriving (Eq, Ord, Show)--$(deriveJson ''CamSettingsAttribute)
@@ -1,324 +0,0 @@-module Rattletrap.Type.ClassAttributeMap- ( ClassAttributeMap(..)- , classHasLocation- , classHasRotation- , getAttributeIdLimit- , getAttributeMap- , getAttributeName- , getClassName- , getName- , getObjectName- , makeClassAttributeMap- )-where--import Rattletrap.Data-import Rattletrap.Type.AttributeMapping-import Rattletrap.Type.Cache-import Rattletrap.Type.ClassMapping-import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.List-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--import qualified Data.IntMap as IntMap-import qualified Data.List as List-import qualified Data.Map as Map-import qualified Data.Maybe as Maybe-import qualified Data.Set as Set-import qualified Data.Text as Text-import qualified Data.Tuple as Tuple---- | This data structure holds all the information about classes, objects, and--- attributes in the replay. The class hierarchy is not fixed; it is encoded--- in the 'Rattletrap.Content.Content'. Similarly, the attributes that belong--- to each class are not fixed either. Converting the raw data into a usable--- structure is tedious; see 'makeClassAttributeMap'.-data ClassAttributeMap = ClassAttributeMap- { classAttributeMapObjectMap :: Map Word32le Str- -- ^ A map from object IDs to their names.- , classAttributeMapObjectClassMap :: Map Word32le Word32le- -- ^ A map from object IDs to their class IDs.- , classAttributeMapValue :: Map Word32le (Map Word32le Word32le)- -- ^ A map from class IDs to a map from attribute stream IDs to attribute- -- IDs.- , classAttributeMapNameMap :: IntMap.IntMap Str- } deriving (Eq, Ord, Show)--type Bimap l r = (Map l r, Map r l)--bimap :: (Ord l, Ord r) => [(l, r)] -> Bimap l r-bimap xs = (Map.fromList xs, Map.fromList (fmap Tuple.swap xs))--lookupL :: Ord l => l -> Bimap l r -> Maybe r-lookupL k = Map.lookup k . fst--lookupR :: Ord r => r -> Bimap l r -> Maybe l-lookupR k = Map.lookup k . snd---- | Makes a 'ClassAttributeMap' given the necessary fields from the--- 'Rattletrap.Content.Content'.-makeClassAttributeMap- :: List Str- -- ^ From 'Rattletrap.Content.contentObjects'.- -> List ClassMapping- -- ^ From 'Rattletrap.Content.contentClassMappings'.- -> List Cache- -- ^ From 'Rattletrap.Content.contentCaches'.- -> List Str- -- ^ From 'Rattletrap.Content.contentNames'.- -> ClassAttributeMap-makeClassAttributeMap objects classMappings caches names =- let- objectMap = makeObjectMap objects- classMap = makeClassMap classMappings- objectClassMap = makeObjectClassMap objectMap classMap- classCache = makeClassCache classMap caches- attributeMap = makeAttributeMap caches- classIds = fmap (\(_, classId, _, _) -> classId) classCache- parentMap = makeParentMap classCache- value = Map.fromList- (fmap- (\classId ->- let- ownAttributes =- Maybe.fromMaybe Map.empty (Map.lookup classId attributeMap)- parentsAttributes = case Map.lookup classId parentMap of- Nothing -> []- Just parentClassIds -> fmap- (\parentClassId -> Maybe.fromMaybe- Map.empty- (Map.lookup parentClassId attributeMap)- )- parentClassIds- attributes = ownAttributes : parentsAttributes- in (classId, Map.fromList (concatMap Map.toList attributes))- )- classIds- )- nameMap = makeNameMap names- in ClassAttributeMap objectMap objectClassMap value nameMap--makeNameMap :: List Str -> IntMap.IntMap Str-makeNameMap names = IntMap.fromDistinctAscList (zip [0 ..] (listValue names))--getName :: IntMap.IntMap Str -> Word32le -> Maybe Str-getName nameMap nameIndex =- IntMap.lookup (fromIntegral (word32leValue nameIndex)) nameMap--makeObjectClassMap- :: Map Word32le Str -> Bimap Word32le Str -> Map Word32le Word32le-makeObjectClassMap objectMap classMap = do- let objectIds = Map.keys objectMap- let classIds = fmap (getClassId objectMap classMap) objectIds- let rawPairs = zip objectIds classIds- let- pairs = Maybe.mapMaybe- (\(objectId, maybeClassId) -> case maybeClassId of- Nothing -> Nothing- Just classId -> Just (objectId, classId)- )- rawPairs- Map.fromList pairs--getClassId- :: Map Word32le Str -> Bimap Word32le Str -> Word32le -> Maybe Word32le-getClassId objectMap classMap objectId = do- objectName <- getObjectName objectMap objectId- className <- getClassName objectName- lookupR className classMap--makeClassCache- :: Bimap Word32le Str- -> List Cache- -> [(Maybe Str, Word32le, Word32le, Word32le)]-makeClassCache classMap caches = fmap- (\cache ->- let classId = cacheClassId cache- in- ( lookupL classId classMap- , classId- , cacheCacheId cache- , cacheParentCacheId cache- )- )- (listValue caches)--makeClassMap :: List ClassMapping -> Bimap Word32le Str-makeClassMap classMappings = bimap- (fmap- (\classMapping ->- (classMappingStreamId classMapping, classMappingName classMapping)- )- (listValue classMappings)- )--makeAttributeMap :: List Cache -> Map Word32le (Map Word32le Word32le)-makeAttributeMap caches = Map.fromList- (fmap- (\cache ->- ( cacheClassId cache- , Map.fromList- (fmap- (\attributeMapping ->- ( attributeMappingStreamId attributeMapping- , attributeMappingObjectId attributeMapping- )- )- (listValue (cacheAttributeMappings cache))- )- )- )- (listValue caches)- )--makeShallowParentMap- :: [(Maybe Str, Word32le, Word32le, Word32le)] -> Map Word32le Word32le-makeShallowParentMap classCache = Map.fromList- (Maybe.mapMaybe- (\xs -> case xs of- [] -> Nothing- (maybeClassName, classId, _, parentCacheId) : rest -> do- parentClassId <- getParentClass maybeClassName parentCacheId rest- pure (classId, parentClassId)- )- (List.tails (reverse classCache))- )--makeParentMap- :: [(Maybe Str, Word32le, Word32le, Word32le)] -> Map Word32le [Word32le]-makeParentMap classCache =- let shallowParentMap = makeShallowParentMap classCache- in- Map.mapWithKey- (\classId _ -> getParentClasses shallowParentMap classId)- shallowParentMap--getParentClasses :: Map Word32le Word32le -> Word32le -> [Word32le]-getParentClasses shallowParentMap classId =- case Map.lookup classId shallowParentMap of- Nothing -> []- Just parentClassId ->- parentClassId : getParentClasses shallowParentMap parentClassId--getParentClass- :: Maybe Str- -> Word32le- -> [(Maybe Str, Word32le, Word32le, Word32le)]- -> Maybe Word32le-getParentClass maybeClassName parentCacheId xs = case maybeClassName of- Nothing -> getParentClassById parentCacheId xs- Just className -> getParentClassByName className parentCacheId xs--getParentClassById- :: Word32le -> [(Maybe Str, Word32le, Word32le, Word32le)] -> Maybe Word32le-getParentClassById parentCacheId xs =- case dropWhile (\(_, _, cacheId, _) -> cacheId /= parentCacheId) xs of- [] -> if parentCacheId == Word32le 0- then Nothing- else getParentClassById (Word32le (word32leValue parentCacheId - 1)) xs- (_, parentClassId, _, _) : _ -> Just parentClassId--getParentClassByName- :: Str- -> Word32le- -> [(Maybe Str, Word32le, Word32le, Word32le)]- -> Maybe Word32le-getParentClassByName className parentCacheId xs =- case Map.lookup className parentClasses of- Nothing -> getParentClassById parentCacheId xs- Just parentClassName -> Maybe.maybe- (getParentClassById parentCacheId xs)- Just- (Maybe.listToMaybe- (fmap- (\(_, parentClassId, _, _) -> parentClassId)- (filter- (\(_, _, cacheId, _) -> cacheId <= parentCacheId)- (filter- (\(maybeClassName, _, _, _) ->- maybeClassName == Just parentClassName- )- xs- )- )- )- )--parentClasses :: Map Str Str-parentClasses =- Map.map toStr (Map.mapKeys toStr (Map.fromList rawParentClasses))--makeObjectMap :: List Str -> Map Word32le Str-makeObjectMap objects =- Map.fromAscList (zip (fmap Word32le [0 ..]) (listValue objects))--getObjectName :: Map Word32le Str -> Word32le -> Maybe Str-getObjectName objectMap objectId = Map.lookup objectId objectMap--getClassName :: Str -> Maybe Str-getClassName rawObjectName =- Map.lookup (normalizeObjectName rawObjectName) objectClasses--normalizeObjectName :: Str -> Str-normalizeObjectName objectName =- let- name = strValue objectName- crowdActor = Text.pack "TheWorld:PersistentLevel.CrowdActor_TA"- crowdManager = Text.pack "TheWorld:PersistentLevel.CrowdManager_TA"- boostPickup = Text.pack "TheWorld:PersistentLevel.VehiclePickup_Boost_TA"- mapScoreboard = Text.pack "TheWorld:PersistentLevel.InMapScoreboard_TA"- breakout = Text.pack "TheWorld:PersistentLevel.BreakOutActor_Platform_TA"- in if Text.isInfixOf crowdActor name- then Str crowdActor- else if Text.isInfixOf crowdManager name- then Str crowdManager- else if Text.isInfixOf boostPickup name- then Str boostPickup- else if Text.isInfixOf mapScoreboard name- then Str mapScoreboard- else if Text.isInfixOf breakout name- then Str breakout- else objectName--objectClasses :: Map Str Str-objectClasses =- Map.map toStr (Map.mapKeys toStr (Map.fromList rawObjectClasses))--classHasLocation :: Str -> Bool-classHasLocation className = Set.member className classesWithLocation--classesWithLocation :: Set.Set Str-classesWithLocation = Set.fromList (fmap toStr rawClassesWithLocation)--classHasRotation :: Str -> Bool-classHasRotation className = Set.member className classesWithRotation--classesWithRotation :: Set.Set Str-classesWithRotation = Set.fromList (fmap toStr rawClassesWithRotation)--getAttributeIdLimit :: Map Word32le Word32le -> Maybe Word-getAttributeIdLimit attributeMap = do- ((streamId, _), _) <- Map.maxViewWithKey attributeMap- pure (fromIntegral (word32leValue streamId))--getAttributeName- :: ClassAttributeMap -> Map Word32le Word32le -> CompressedWord -> Maybe Str-getAttributeName classAttributeMap attributeMap streamId = do- let key = Word32le (fromIntegral (compressedWordValue streamId))- attributeId <- Map.lookup key attributeMap- let objectMap = classAttributeMapObjectMap classAttributeMap- Map.lookup attributeId objectMap--getAttributeMap- :: ClassAttributeMap- -> Map CompressedWord Word32le- -> CompressedWord- -> Maybe (Map Word32le Word32le)-getAttributeMap classAttributeMap actorMap actorId = do- objectId <- Map.lookup actorId actorMap- let objectClassMap = classAttributeMapObjectClassMap classAttributeMap- classId <- Map.lookup objectId objectClassMap- let value = classAttributeMapValue classAttributeMap- Map.lookup classId value
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ClassMapping- ( ClassMapping(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--data ClassMapping = ClassMapping- { classMappingName :: Str- , classMappingStreamId :: Word32le- } deriving (Eq, Ord, Show)--$(deriveJson ''ClassMapping)
@@ -1,18 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ClubColorsAttribute- ( ClubColorsAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word8le--data ClubColorsAttribute = ClubColorsAttribute- { clubColorsAttributeBlueFlag :: Bool- , clubColorsAttributeBlueColor :: Word8le- , clubColorsAttributeOrangeFlag :: Bool- , clubColorsAttributeOrangeColor :: Word8le- } deriving (Eq, Ord, Show)--$(deriveJson ''ClubColorsAttribute)
@@ -1,56 +0,0 @@-module Rattletrap.Type.Common- ( Int.Int8- , Int.Int32- , Int.Int64- , Map.Map- , Text.Text- , Word.Word8- , Word.Word16- , Word.Word32- , Word.Word64- , deriveJson- )-where--import qualified Data.Aeson as Json-import qualified Data.Aeson.TH as Json-import qualified Data.Char as Char-import qualified Data.Int as Int-import qualified Data.Map as Map-import qualified Data.Maybe as Maybe-import qualified Data.Text as Text-import qualified Data.Word as Word-import qualified Language.Haskell.TH as TH--deriveJson :: TH.Name -> TH.Q [TH.Dec]-deriveJson name = Json.deriveJSON (jsonOptions (TH.nameBase name)) name--jsonOptions :: String -> Json.Options-jsonOptions prefix = Json.defaultOptions- { Json.constructorTagModifier = toSnakeCase . partialDropPrefix prefix- , Json.fieldLabelModifier = toSnakeCase- . partialDropPrefix (lowerFirst prefix)- , Json.omitNothingFields = True- , Json.sumEncoding = Json.ObjectWithSingleField- , Json.unwrapUnaryRecords = True- }--lowerFirst :: String -> String-lowerFirst string = case string of- "" -> string- first : rest -> Char.toLower first : rest--toSnakeCase :: String -> String-toSnakeCase = Json.camelTo2 '_'--partialDropPrefix :: (Eq a, Show a) => [a] -> [a] -> [a]-partialDropPrefix prefix list = Maybe.fromMaybe- (error (unwords [show prefix, "is not a prefix of", show list]))- (dropPrefix prefix list)--dropPrefix :: Eq a => [a] -> [a] -> Maybe [a]-dropPrefix prefix list = case prefix of- [] -> Just list- ph : pt -> case list of- [] -> Nothing- lh : lt -> if ph == lh then dropPrefix pt lt else Nothing
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.CompressedWord- ( CompressedWord(..)- )-where--import Rattletrap.Type.Common---- | Although there's no guarantee that these values will not overflow, it's--- exceptionally unlikely. Most 'CompressedWord's are very small.-data CompressedWord = CompressedWord- { compressedWordLimit :: Word- , compressedWordValue :: Word- } deriving (Eq, Ord, Show)--$(deriveJson ''CompressedWord)
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.CompressedWordVector- ( CompressedWordVector(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord--data CompressedWordVector = CompressedWordVector- { compressedWordVectorX :: CompressedWord- , compressedWordVectorY :: CompressedWord- , compressedWordVectorZ :: CompressedWord- } deriving (Eq, Ord, Show)--$(deriveJson ''CompressedWordVector)
@@ -1,71 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Content- ( Content(..)- , defaultContent- )-where--import Rattletrap.Type.Cache-import Rattletrap.Type.ClassMapping-import Rattletrap.Type.Common-import Rattletrap.Type.Frame-import Rattletrap.Type.KeyFrame-import Rattletrap.Type.List-import Rattletrap.Type.Mark-import Rattletrap.Type.Message-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le---- | Contains low-level game data about a 'Rattletrap.Replay.Replay'.-data Content = Content- { contentLevels :: List Str- -- ^ This typically only has one element, like @stadium_oob_audio_map@.- , contentKeyFrames :: List KeyFrame- -- ^ A list of which frames are key frames. Although they aren't necessary- -- for replay, key frames are frames that replicate every actor. They- -- typically happen once every 10 seconds.- , contentStreamSize :: Word32le- -- ^ The size of the stream in bytes. This is only really necessary because- -- the stream has some arbitrary amount of padding at the end.- , contentFrames :: [Frame]- -- ^ The actual game data. This is where all the interesting information is.- , contentMessages :: List Message- -- ^ Debugging messages. In newer replays, this is always empty.- , contentMarks :: List Mark- -- ^ Tick marks shown on the scrubber when watching a replay.- , contentPackages :: List Str- -- ^ A list of @.upk@ files to load, like- -- @..\\..\\TAGame\\CookedPCConsole\\Stadium_P.upk@.- , contentObjects :: List Str- -- ^ Objects in the stream. Used for the- -- 'Rattletrap.Type.ClassAttributeMap.ClassAttributeMap'.- , contentNames :: List Str- -- ^ It's not clear what these are used for. This list is usually not empty,- -- but appears unused otherwise.- , contentClassMappings :: List ClassMapping- -- ^ A mapping between classes and their ID in the stream. Used for the- -- 'Rattletrap.Type.ClassAttributeMap.ClassAttributeMap'.- , contentCaches :: List Cache- -- ^ A list of classes along with their parent classes and attributes. Used- -- for the 'Rattletrap.Type.ClassAttributeMap.ClassAttributeMap'.- , contentUnknown :: [Word8]- } deriving (Eq, Ord, Show)--$(deriveJson ''Content)--defaultContent :: Content-defaultContent = Content- { contentLevels = List []- , contentKeyFrames = List []- , contentStreamSize = Word32le 0- , contentFrames = []- , contentMessages = List []- , contentMarks = List []- , contentPackages = List []- , contentObjects = List []- , contentNames = List []- , contentClassMappings = List []- , contentCaches = List []- , contentUnknown = []- }
@@ -1,18 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.CustomDemolishAttribute- ( CustomDemolishAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.DemolishAttribute-import Rattletrap.Type.Int32le--data CustomDemolishAttribute = CustomDemolishAttribute- { customDemolishAttributeFlag :: Bool- , customDemolishAttributeId :: Int32le- , customDemolishAttributeDemolish :: DemolishAttribute- } deriving (Eq, Ord, Show)--$(deriveJson ''CustomDemolishAttribute)
@@ -1,22 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.DamageStateAttribute- ( DamageStateAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int32le-import Rattletrap.Type.Vector-import Rattletrap.Type.Word8le--data DamageStateAttribute = DamageStateAttribute- { damageStateAttributeUnknown1 :: Word8le- , damageStateAttributeUnknown2 :: Bool- , damageStateAttributeUnknown3 :: Int32le- , damageStateAttributeUnknown4 :: Vector- , damageStateAttributeUnknown5 :: Bool- , damageStateAttributeUnknown6 :: Bool- } deriving (Eq, Ord, Show)--$(deriveJson ''DamageStateAttribute)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.DemolishAttribute- ( DemolishAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Vector-import Rattletrap.Type.Word32le--data DemolishAttribute = DemolishAttribute- { demolishAttributeAttackerFlag :: Bool- , demolishAttributeAttackerActorId :: Word32le- , demolishAttributeVictimFlag :: Bool- , demolishAttributeVictimActorId :: Word32le- , demolishAttributeAttackerVelocity :: Vector- , demolishAttributeVictimVelocity :: Vector- } deriving (Eq, Ord, Show)--$(deriveJson ''DemolishAttribute)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.DestroyedReplication- ( DestroyedReplication(..)- )-where--import Rattletrap.Type.Common---- | Destroyed replications don't actually contain any extra information. All--- you need to know is the actor's ID, which is given by the--- 'Rattletrap.Replication.Replication'.-data DestroyedReplication = DestroyedReplication- deriving (Eq, Ord, Show)--$(deriveJson ''DestroyedReplication)
@@ -1,69 +0,0 @@-module Rattletrap.Type.Dictionary- ( Dictionary(..)- , dictionaryLookup- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str--import qualified Control.Monad as Monad-import qualified Data.Aeson as Json-import qualified Data.Aeson.Types as Json-import qualified Data.Map as Map-import qualified Data.Text as Text--data Dictionary a- = DictionaryElement Str a (Dictionary a)- | DictionaryEnd Str- deriving (Eq, Ord, Show)--instance Json.FromJSON a => Json.FromJSON (Dictionary a) where- parseJSON = Json.withObject- "Dictionary"- (\o -> do- keys <- get o "keys"- lastKey <- get o "last_key"- value <- get o "value"- Monad.foldM- (\d k -> case Map.lookup k value of- Nothing -> fail (unwords ["missing key", show k])- Just v -> pure (DictionaryElement (Str k) v d)- )- (DictionaryEnd lastKey)- (reverse keys)- )--instance Json.ToJSON a => Json.ToJSON (Dictionary a) where- toJSON d = Json.object- [ pair "keys" (dictionaryKeys d)- , pair "last_key" (dictionaryLastKey d)- , pair "value" (dictionaryValue d)- ]--dictionaryKeys :: Dictionary a -> [Str]-dictionaryKeys = fmap fst . toList--dictionaryLastKey :: Dictionary a -> Str-dictionaryLastKey x = case x of- DictionaryElement _ _ y -> dictionaryLastKey y- DictionaryEnd y -> y--dictionaryLookup :: Str -> Dictionary a -> Maybe a-dictionaryLookup k x = case x of- DictionaryElement j v y -> if k == j then Just v else dictionaryLookup k y- DictionaryEnd _ -> Nothing--dictionaryValue :: Dictionary a -> Map Text a-dictionaryValue = Map.mapKeys strValue . Map.fromList . toList--get :: Json.FromJSON a => Json.Object -> String -> Json.Parser a-get o k = o Json..: Text.pack k--pair :: Json.ToJSON a => String -> a -> (Text, Json.Value)-pair k v = (Text.pack k, Json.toJSON v)--toList :: Dictionary a -> [(Str, a)]-toList x = case x of- DictionaryElement k v y -> (k, v) : toList y- DictionaryEnd _ -> []
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.EnumAttribute- ( EnumAttribute(..)- )-where--import Rattletrap.Type.Common--newtype EnumAttribute = EnumAttribute- { enumAttributeValue :: Word16- } deriving (Eq, Ord, Show)--$(deriveJson ''EnumAttribute)
@@ -1,18 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ExplosionAttribute- ( ExplosionAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int32le-import Rattletrap.Type.Vector--data ExplosionAttribute = ExplosionAttribute- { explosionAttributeFlag :: Bool- , explosionAttributeActorId :: Int32le- , explosionAttributeLocation :: Vector- } deriving (Eq, Ord, Show)--$(deriveJson ''ExplosionAttribute)
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ExtendedExplosionAttribute- ( ExtendedExplosionAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.ExplosionAttribute-import Rattletrap.Type.FlaggedIntAttribute--data ExtendedExplosionAttribute = ExtendedExplosionAttribute- { extendedExplosionAttributeExplosion :: ExplosionAttribute- , extendedExplosionAttributeUnknown :: FlaggedIntAttribute- } deriving (Eq, Ord, Show)--$(deriveJson ''ExtendedExplosionAttribute)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.FlaggedByteAttribute- ( FlaggedByteAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word8le--data FlaggedByteAttribute = FlaggedByteAttribute- { flaggedByteAttributeFlag :: Bool- , flaggedByteAttributeByte :: Word8le- } deriving (Eq, Ord, Show)--$(deriveJson ''FlaggedByteAttribute)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.FlaggedIntAttribute- ( FlaggedIntAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int32le--data FlaggedIntAttribute = FlaggedIntAttribute- { flaggedIntAttributeFlag :: Bool- , flaggedIntAttributeInt :: Int32le- } deriving (Eq, Ord, Show)--$(deriveJson ''FlaggedIntAttribute)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Float32le- ( Float32le(..)- )-where--import Rattletrap.Type.Common--newtype Float32le = Float32le- { float32leValue :: Float- } deriving (Eq, Ord, Show)--$(deriveJson ''Float32le)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.FloatAttribute- ( FloatAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Float32le--newtype FloatAttribute = FloatAttribute- { floatAttributeValue :: Float32le- } deriving (Eq, Ord, Show)--$(deriveJson ''FloatAttribute)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Frame- ( Frame(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Float32le-import Rattletrap.Type.Replication--data Frame = Frame- { frameTime :: Float32le- -- ^ Time in seconds since the beginning of the match.- , frameDelta :: Float32le- -- ^ Time in seconds since the last frame. Usually about 0.03 since there- -- are 30 frames per second.- , frameReplications :: [Replication]- } deriving (Eq, Ord, Show)--$(deriveJson ''Frame)
@@ -1,19 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.GameModeAttribute- ( GameModeAttribute(..)- )-where--import Rattletrap.Type.Common--data GameModeAttribute = GameModeAttribute- { gameModeAttributeNumBits :: Int- -- ^ This field is guaranteed to be small. In other words, it won't overflow.- -- It's stored as a regular 'Int' rather than something more precise like an- -- 'Int8' because it just gets passed to functions that expect 'Int's.- -- There's no reason to do a bunch of conversions.- , gameModeAttributeWord :: Word8- } deriving (Eq, Ord, Show)--$(deriveJson ''GameModeAttribute)
@@ -1,61 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Header- ( Header(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Dictionary-import Rattletrap.Type.Property-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le---- | Contains high-level metadata about a 'Rattletrap.Replay.Replay'.-data Header = Header- { headerEngineVersion :: Word32le- -- ^ The "major" ("engine") version number.- , headerLicenseeVersion :: Word32le- -- ^ The "minor" ("licensee") version number.- , headerPatchVersion :: Maybe Word32le- -- ^ The "patch" ("net") version number.- , headerLabel :: Str- -- ^ Always @TAGame.Replay_Soccar_TA@.- , headerProperties :: Dictionary Property- -- ^ These properties determine how a replay will look in the list of- -- replays in-game. One element is required for the replay to show up:- --- -- - MapName: This is a 'Rattletrap.PropertyValue.NameProperty' with a- -- case-insensitive map identifier, like @Stadium_P@.- --- -- There are many other properties that affect how the replay looks in the- -- list of replays.- --- -- - Date: A 'Rattletrap.PropertyValue.StrProperty' with the format- -- @YYYY-mm-dd:HH-MM@. Dates are not validated, but the month must be- -- between 1 and 12 to show up. The hour is shown modulo 12 with AM or PM.- -- - MatchType: A 'Rattletrap.PropertyValue.NameProperty'. If this is not- -- one of the expected values, nothing will be shown next to the replay's- -- map. The expected values are: @Online@, @Offline@, @Private@, and- -- @Season@.- -- - NumFrames: This 'Rattletrap.PropertyValue.IntProperty' is used to- -- calculate the length of the match. There are 30 frames per second,- -- a typical 5-minute match has about 9,000 frames.- -- - PrimaryPlayerTeam: This is an 'Rattletrap.PropertyValue.IntProperty'.- -- It is either 0 (blue) or 1 (orange). Any other value is ignored. If- -- this would be 0, you don't have to set it at all.- -- - ReplayName: An optional 'Rattletrap.PropertyValue.StrProperty' with a- -- user-supplied name for the replay.- -- - Team0Score: The blue team's score as an- -- 'Rattletrap.PropertyValue.IntProperty'. Can be omitted if the score is- -- 0.- -- - Team1Score: The orange team's score as an- -- 'Rattletrap.PropertyValue.IntProperty'. Can also be omitted if the- -- score is 0.- -- - TeamSize: An 'Rattletrap.PropertyValue.IntProperty' with the number of- -- players per team. This value is not validated, so you can put absurd- -- values like 99. To get an "unfair" team size like 1v4, you must set the- -- bUnfairBots 'Rattletrap.PropertyValue.BoolProperty' to @True@.- } deriving (Eq, Ord, Show)--$(deriveJson ''Header)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Initialization- ( Initialization(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int8Vector-import Rattletrap.Type.Vector--data Initialization = Initialization- { initializationLocation :: Maybe Vector- -- ^ Not every class has an initial location. See- -- 'Rattletrap.Data.rawClassesWithLocation'.- , initializationRotation :: Maybe Int8Vector- -- ^ Only classes with location can have rotation, but not every one does.- -- See 'Rattletrap.Data.rawClassesWithRotation'.- } deriving (Eq, Ord, Show)--$(deriveJson ''Initialization)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Int32le- ( Int32le(..)- )-where--import Rattletrap.Type.Common--newtype Int32le = Int32le- { int32leValue :: Int32- } deriving (Eq, Ord, Show)--$(deriveJson ''Int32le)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Int64Attribute- ( Int64Attribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int64le--newtype Int64Attribute = Int64Attribute- { int64AttributeValue :: Int64le- } deriving (Eq, Ord, Show)--$(deriveJson ''Int64Attribute)
@@ -1,28 +0,0 @@-module Rattletrap.Type.Int64le- ( Int64le(..)- )-where--import qualified Data.Aeson as Aeson-import qualified Data.Aeson.Types as Aeson-import qualified Data.Int as Int-import qualified Data.Scientific as Scientific-import qualified Data.Text as Text-import qualified Text.Read as Read--newtype Int64le = Int64le- { int64leValue :: Int.Int64- } deriving (Eq, Ord, Show)--instance Aeson.FromJSON Int64le where- parseJSON value = case value of- Aeson.String text -> case Read.readEither $ Text.unpack text of- Left _ -> Aeson.typeMismatch "Int64le" value- Right int64 -> pure $ Int64le int64- Aeson.Number number -> case Scientific.toBoundedInteger number of- Nothing -> Aeson.typeMismatch "Int64le" value- Just int64 -> pure $ Int64le int64- _ -> Aeson.typeMismatch "Int64le" value--instance Aeson.ToJSON Int64le where- toJSON = Aeson.toJSON . show . int64leValue
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Int8Vector- ( Int8Vector(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int8le--data Int8Vector = Int8Vector- { int8VectorX :: Maybe Int8le- , int8VectorY :: Maybe Int8le- , int8VectorZ :: Maybe Int8le- } deriving (Eq, Ord, Show)--$(deriveJson ''Int8Vector)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Int8le- ( Int8le(..)- )-where--import Rattletrap.Type.Common--newtype Int8le = Int8le- { int8leValue :: Int8- } deriving (Eq, Ord, Show)--$(deriveJson ''Int8le)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.IntAttribute- ( IntAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int32le--newtype IntAttribute = IntAttribute- { intAttributeValue :: Int32le- } deriving (Eq, Ord, Show)--$(deriveJson ''IntAttribute)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.KeyFrame- ( KeyFrame(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Float32le-import Rattletrap.Type.Word32le--data KeyFrame = KeyFrame- { keyFrameTime :: Float32le- -- ^ When this key frame occurs, in seconds.- , keyFrameFrame :: Word32le- -- ^ The frame number of this key frame, starting from 0.- , keyFramePosition :: Word32le- -- ^ The bit position of this key frame in the stream.- } deriving (Eq, Ord, Show)--$(deriveJson ''KeyFrame)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.List- ( List(..)- )-where--import Rattletrap.Type.Common--newtype List a = List- { listValue :: [a]- } deriving (Eq, Ord, Show)--$(deriveJson ''List)
@@ -1,33 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.LoadoutAttribute- ( LoadoutAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le-import Rattletrap.Type.Word8le--data LoadoutAttribute = LoadoutAttribute- { loadoutAttributeVersion :: Word8le- , loadoutAttributeBody :: Word32le- , loadoutAttributeDecal :: Word32le- , loadoutAttributeWheels :: Word32le- , loadoutAttributeRocketTrail :: Word32le- -- ^ Now known as "rocket boost".- , loadoutAttributeAntenna :: Word32le- , loadoutAttributeTopper :: Word32le- , loadoutAttributeUnknown1 :: Word32le- , loadoutAttributeUnknown2 :: Maybe Word32le- , loadoutAttributeEngineAudio :: Maybe Word32le- , loadoutAttributeTrail :: Maybe Word32le- , loadoutAttributeGoalExplosion :: Maybe Word32le- , loadoutAttributeBanner :: Maybe Word32le- , loadoutAttributeUnknown3 :: Maybe Word32le- , loadoutAttributeUnknown4 :: Maybe Word32le- , loadoutAttributeUnknown5 :: Maybe Word32le- , loadoutAttributeUnknown6 :: Maybe Word32le- } deriving (Eq, Ord, Show)--$(deriveJson ''LoadoutAttribute)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.LoadoutOnlineAttribute- ( LoadoutOnlineAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.ProductAttribute--newtype LoadoutOnlineAttribute = LoadoutOnlineAttribute- { loadoutAttributeValue :: [[ProductAttribute]]- } deriving (Eq, Ord, Show)--$(deriveJson ''LoadoutOnlineAttribute)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.LoadoutsAttribute- ( LoadoutsAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.LoadoutAttribute--data LoadoutsAttribute = LoadoutsAttribute- { loadoutsAttributeBlue :: LoadoutAttribute- , loadoutsAttributeOrange :: LoadoutAttribute- } deriving (Eq, Ord, Show)--$(deriveJson ''LoadoutsAttribute)
@@ -1,18 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.LoadoutsOnlineAttribute- ( LoadoutsOnlineAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.LoadoutOnlineAttribute--data LoadoutsOnlineAttribute = LoadoutsOnlineAttribute- { loadoutsOnlineAttributeBlue :: LoadoutOnlineAttribute- , loadoutsOnlineAttributeOrange :: LoadoutOnlineAttribute- , loadoutsOnlineAttributeUnknown1 :: Bool- , loadoutsOnlineAttributeUnknown2 :: Bool- } deriving (Eq, Ord, Show)--$(deriveJson ''LoadoutsOnlineAttribute)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.LocationAttribute- ( LocationAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Vector--newtype LocationAttribute = LocationAttribute- { locationAttributeValue :: Vector- } deriving (Eq, Ord, Show)--$(deriveJson ''LocationAttribute)
@@ -1,19 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Mark- ( Mark(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--data Mark = Mark- { markValue :: Str- -- ^ Which type of mark this is, like @Team0Goal@.- , markFrame :: Word32le- -- ^ Which frame this mark belongs to, starting from 0.- } deriving (Eq, Ord, Show)--$(deriveJson ''Mark)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Message- ( Message(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--data Message = Message- { messageFrame :: Word32le- -- ^ Which frame this message belongs to, starting from 0.- , messageName :: Str- -- ^ The primary player's name.- , messageValue :: Str- -- ^ The content of the message.- } deriving (Eq, Ord, Show)--$(deriveJson ''Message)
@@ -1,18 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.MusicStingerAttribute- ( MusicStingerAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le-import Rattletrap.Type.Word8le--data MusicStingerAttribute = MusicStingerAttribute- { musicStingerAttributeFlag :: Bool- , musicStingerAttributeCue :: Word32le- , musicStingerAttributeTrigger :: Word8le- } deriving (Eq, Ord, Show)--$(deriveJson ''MusicStingerAttribute)
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PartyLeaderAttribute- ( PartyLeaderAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.RemoteId-import Rattletrap.Type.Word8le--data PartyLeaderAttribute = PartyLeaderAttribute- { partyLeaderAttributeSystemId :: Word8le- , partyLeaderAttributeId :: Maybe (RemoteId, Word8le)- } deriving (Eq, Ord, Show)--$(deriveJson ''PartyLeaderAttribute)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PickupAttribute- ( PickupAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le--data PickupAttribute = PickupAttribute- { pickupAttributeInstigatorId :: Maybe Word32le- , pickupAttributePickedUp :: Bool- } deriving (Eq, Ord, Show)--$(deriveJson ''PickupAttribute)
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PickupAttributeNew- ( PickupAttributeNew(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word8le-import Rattletrap.Type.Word32le--data PickupAttributeNew = PickupAttributeNew- { pickupAttributeNewInstigatorId :: Maybe Word32le- , pickupAttributeNewPickedUp :: Word8le- } deriving (Eq, Ord, Show)--$(deriveJson ''PickupAttributeNew)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PlayerHistoryKeyAttribute- ( PlayerHistoryKeyAttribute(..)- )-where--import Rattletrap.Type.Common--newtype PlayerHistoryKeyAttribute = PlayerHistoryKeyAttribute- { playerHistoryKeyAttributeUnknown :: Word16- } deriving (Eq, Ord, Show)--$(deriveJson ''PlayerHistoryKeyAttribute)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PrivateMatchSettingsAttribute- ( PrivateMatchSettingsAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--data PrivateMatchSettingsAttribute = PrivateMatchSettingsAttribute- { privateMatchSettingsAttributeMutators :: Str- , privateMatchSettingsAttributeJoinableBy :: Word32le- , privateMatchSettingsAttributeMaxPlayers :: Word32le- , privateMatchSettingsAttributeGameName :: Str- , privateMatchSettingsAttributePassword :: Str- , privateMatchSettingsAttributeFlag :: Bool- } deriving (Eq, Ord, Show)--$(deriveJson ''PrivateMatchSettingsAttribute)
@@ -1,35 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ProductAttribute- ( ProductAttribute(..)- , ProductAttributeValue(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--data ProductAttributeValue- = ProductAttributeValuePaintedOld CompressedWord- | ProductAttributeValuePaintedNew Word32- | ProductAttributeValueTeamEditionOld CompressedWord- | ProductAttributeValueTeamEditionNew Word32- | ProductAttributeValueSpecialEdition Word32- | ProductAttributeValueUserColorOld (Maybe Word32)- | ProductAttributeValueUserColorNew Word32le- | ProductAttributeValueTitleId Str- deriving (Eq, Ord, Show)--$(deriveJson ''ProductAttributeValue)--data ProductAttribute = ProductAttribute- { productAttributeUnknown :: Bool- , productAttributeObjectId :: Word32le- , productAttributeObjectName :: Maybe Str- -- ^ read-only- , productAttributeValue :: ProductAttributeValue- } deriving (Eq, Ord, Show)--$(deriveJson ''ProductAttribute)
@@ -1,20 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Property- ( Property(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.PropertyValue-import Rattletrap.Type.Str-import Rattletrap.Type.Word64le--data Property = Property- { propertyKind :: Str- , propertySize :: Word64le- -- ^ Not used.- , propertyValue :: PropertyValue Property- } deriving (Eq, Ord, Show)--$(deriveJson ''Property)
@@ -1,32 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PropertyValue- ( PropertyValue(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Dictionary-import Rattletrap.Type.Float32le-import Rattletrap.Type.Int32le-import Rattletrap.Type.List-import Rattletrap.Type.Str-import Rattletrap.Type.Word64le-import Rattletrap.Type.Word8le--data PropertyValue a- = PropertyValueArray (List (Dictionary a))- -- ^ Yes, a list of dictionaries. No, it doesn't make sense. These usually- -- only have one element.- | PropertyValueBool Word8le- | PropertyValueByte Str (Maybe Str)- -- ^ This is a strange name for essentially a key-value pair.- | PropertyValueFloat Float32le- | PropertyValueInt Int32le- | PropertyValueName Str- -- ^ It's unclear how exactly this is different than a 'StrProperty'.- | PropertyValueQWord Word64le- | PropertyValueStr Str- deriving (Eq, Ord, Show)--$(deriveJson ''PropertyValue)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.QWordAttribute- ( QWordAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word64le--newtype QWordAttribute = QWordAttribute- { qWordAttributeValue :: Word64le- } deriving (Eq, Ord, Show)--$(deriveJson ''QWordAttribute)
@@ -1,98 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Quaternion- ( Quaternion(..)- , Component(..)- , toQuaternion- , compressPart- , decompressPart- , maxComponent- , maxCompressedValue- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord--import qualified Data.List as List-import qualified Data.Maybe as Maybe--data Quaternion = Quaternion- { quaternionX :: Double- , quaternionY :: Double- , quaternionZ :: Double- , quaternionW :: Double- } deriving (Eq, Ord, Show)--$(deriveJson ''Quaternion)--data Component- = ComponentX- | ComponentY- | ComponentZ- | ComponentW- deriving (Eq, Ord, Show)--toQuaternion :: Component -> Double -> Double -> Double -> Quaternion-toQuaternion component a b c =- let d = toPart a b c- in- case component of- ComponentX -> Quaternion d a b c- ComponentY -> Quaternion a d b c- ComponentZ -> Quaternion a b d c- ComponentW -> Quaternion a b c d--toPart :: Double -> Double -> Double -> Double-toPart a b c = sqrt (1 - (a * a) - (b * b) - (c * c))--compressPart :: Double -> CompressedWord-compressPart =- CompressedWord maxCompressedValue- . round- . (* wordToDouble maxCompressedValue)- . (+ 0.5)- . (/ 2.0)- . (/ maxValue)--decompressPart :: CompressedWord -> Double-decompressPart x =- (* maxValue)- . (* 2.0)- . subtract 0.5- . (/ wordToDouble (compressedWordLimit x))- . wordToDouble- $ compressedWordValue x--maxComponent :: Quaternion -> Component-maxComponent quaternion =- let- x = quaternionX quaternion- y = quaternionY quaternion- z = quaternionZ quaternion- w = quaternionW quaternion- parts =- [(x, ComponentX), (y, ComponentY), (z, ComponentZ), (w, ComponentW)]- biggestPart = maximum parts- roundTrip = decompressPart . compressPart- computedPart = Maybe.fromMaybe- biggestPart- (List.find (\(value, _) -> value /= roundTrip value) parts)- in snd- (if (biggestPart == computedPart)- || (abs (fst biggestPart - fst computedPart) > 0.00001)- then biggestPart- else computedPart- )--numBits :: Word-numBits = 18--wordToDouble :: Word -> Double-wordToDouble = fromIntegral--maxCompressedValue :: Word-maxCompressedValue = (2 ^ numBits) - 1--maxValue :: Double-maxValue = 1.0 / sqrt 2.0
@@ -1,23 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.RemoteId- ( RemoteId(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word64le--data RemoteId- = RemoteIdPlayStation Text [Word8]- | RemoteIdPsyNet (Either Word64le (Word64le, Word64le, Word64le, Word64le))- | RemoteIdSplitscreen Word32- -- ^ Really only 24 bits.- | RemoteIdSteam Word64le- | RemoteIdSwitch Word64le Word64le Word64le Word64le- | RemoteIdXbox Word64le- | RemoteIdEpic Str- deriving (Eq, Ord, Show)--$(deriveJson ''RemoteId)
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Replay- ( Replay(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Content-import Rattletrap.Type.Header-import Rattletrap.Type.Section---- | A Rocket League replay.-data Replay = Replay- { replayHeader :: Section Header- -- ^ This has most of the high-level metadata.- , replayContent :: Section Content- -- ^ This has most of the low-level game data.- } deriving (Eq, Ord, Show)--$(deriveJson ''Replay)
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Replication- ( Replication(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.ReplicationValue--data Replication = Replication- { replicationActorId :: CompressedWord- , replicationValue :: ReplicationValue- } deriving (Eq, Ord, Show)--$(deriveJson ''Replication)
@@ -1,22 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ReplicationValue- ( ReplicationValue(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.DestroyedReplication-import Rattletrap.Type.SpawnedReplication-import Rattletrap.Type.UpdatedReplication--data ReplicationValue- = ReplicationValueSpawned SpawnedReplication- -- ^ Creates a new actor.- | ReplicationValueUpdated UpdatedReplication- -- ^ Updates an existing actor.- | ReplicationValueDestroyed DestroyedReplication- -- ^ Destroys an existing actor.- deriving (Eq, Ord, Show)--$(deriveJson ''ReplicationValue)
@@ -1,22 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ReservationAttribute- ( ReservationAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Str-import Rattletrap.Type.UniqueIdAttribute--data ReservationAttribute = ReservationAttribute- { reservationAttributeNumber :: CompressedWord- , reservationAttributeUniqueId :: UniqueIdAttribute- , reservationAttributeName :: Maybe Str- , reservationAttributeUnknown1 :: Bool- , reservationAttributeUnknown2 :: Bool- , reservationAttributeUnknown3 :: Maybe Word8- } deriving (Eq, Ord, Show)--$(deriveJson ''ReservationAttribute)
@@ -1,20 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.RigidBodyStateAttribute- ( RigidBodyStateAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Rotation-import Rattletrap.Type.Vector--data RigidBodyStateAttribute = RigidBodyStateAttribute- { rigidBodyStateAttributeSleeping :: Bool- , rigidBodyStateAttributeLocation :: Vector- , rigidBodyStateAttributeRotation :: Rotation- , rigidBodyStateAttributeLinearVelocity :: Maybe Vector- , rigidBodyStateAttributeAngularVelocity :: Maybe Vector- } deriving (Eq, Ord, Show)--$(deriveJson ''RigidBodyStateAttribute)
@@ -1,17 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Rotation- ( Rotation(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Quaternion-import Rattletrap.Type.CompressedWordVector--data Rotation- = RotationCompressedWordVector CompressedWordVector- | RotationQuaternion Quaternion- deriving (Eq, Ord, Show)--$(deriveJson ''Rotation)
@@ -1,41 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Section- ( Section(..)- , toSection- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le-import Rattletrap.Utility.Crc--import qualified Data.Binary as Binary-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Lazy as LazyBytes---- | A section is a large piece of a 'Rattletrap.Replay.Replay'. It has a--- 32-bit size (in bytes), a 32-bit CRC (see "Rattletrap.Utility.Crc"), and then a--- bunch of data (the body). This interface is provided so that you don't have--- to think about the size and CRC.-data Section a = Section- { sectionSize :: Word32le- -- ^ read only- , sectionCrc :: Word32le- -- ^ read only- , sectionBody :: a- -- ^ The actual content in the section.- } deriving (Eq, Ord, Show)--$(deriveJson ''Section)--toSection :: (a -> Binary.Put) -> a -> Section a-toSection encode body =- let bytes = LazyBytes.toStrict . Binary.runPut $ encode body- in- Section- { sectionSize = Word32le . fromIntegral $ Bytes.length bytes- , sectionCrc = Word32le $ getCrc32 bytes- , sectionBody = body- }
@@ -1,30 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.SpawnedReplication- ( SpawnedReplication(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Initialization-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le--data SpawnedReplication = SpawnedReplication- { spawnedReplicationFlag :: Bool- -- ^ Unclear what this is.- , spawnedReplicationNameIndex :: Maybe Word32le- , spawnedReplicationName :: Maybe Str- -- ^ Read-only! Changing a replication's name requires editing the- -- 'spawnedReplicationNameIndex' and maybe the class attribute map.- , spawnedReplicationObjectId :: Word32le- , spawnedReplicationObjectName :: Str- -- ^ Read-only! Changing a replication's object requires editing the class- -- attribute map.- , spawnedReplicationClassName :: Str- -- ^ Read-only! Changing a replication's class requires editing the class- -- attribute map.- , spawnedReplicationInitialization :: Initialization- } deriving (Eq, Ord, Show)--$(deriveJson ''SpawnedReplication)
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.StatEventAttribute- ( StatEventAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Int32le--data StatEventAttribute = StatEventAttribute- { statEventAttributeUnknown :: Bool- , statEventAttributeObjectId :: Int32le- } deriving (Eq, Ord, Show)--$(deriveJson ''StatEventAttribute)
@@ -1,24 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Str- ( Str(..)- , toStr- , fromStr- )-where--import Rattletrap.Type.Common--import qualified Data.Text as Text--newtype Str = Str- { strValue :: Text- } deriving (Eq, Ord, Show)--$(deriveJson ''Str)--toStr :: String -> Str-toStr string = Str (Text.pack string)--fromStr :: Str -> String-fromStr text = Text.unpack (strValue text)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.StringAttribute- ( StringAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Str--newtype StringAttribute = StringAttribute- { stringAttributeValue :: Str- } deriving (Eq, Ord, Show)--$(deriveJson ''StringAttribute)
@@ -1,20 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.TeamPaintAttribute- ( TeamPaintAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le-import Rattletrap.Type.Word8le--data TeamPaintAttribute = TeamPaintAttribute- { teamPaintAttributeTeam :: Word8le- , teamPaintAttributePrimaryColor :: Word8le- , teamPaintAttributeAccentColor :: Word8le- , teamPaintAttributePrimaryFinish :: Word32le- , teamPaintAttributeAccentFinish :: Word32le- } deriving (Eq, Ord, Show)--$(deriveJson ''TeamPaintAttribute)
@@ -1,22 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.TitleAttribute- ( TitleAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Word32le--data TitleAttribute = TitleAttribute- { titleAttributeUnknown1 :: Bool- , titleAttributeUnknown2 :: Bool- , titleAttributeUnknown3 :: Word32le- , titleAttributeUnknown4 :: Word32le- , titleAttributeUnknown5 :: Word32le- , titleAttributeUnknown6 :: Word32le- , titleAttributeUnknown7 :: Word32le- , titleAttributeUnknown8 :: Bool- } deriving (Eq, Ord, Show)--$(deriveJson ''TitleAttribute)
@@ -1,18 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.UniqueIdAttribute- ( UniqueIdAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.RemoteId-import Rattletrap.Type.Word8le--data UniqueIdAttribute = UniqueIdAttribute- { uniqueIdAttributeSystemId :: Word8le- , uniqueIdAttributeRemoteId :: RemoteId- , uniqueIdAttributeLocalId :: Word8le- } deriving (Eq, Ord, Show)--$(deriveJson ''UniqueIdAttribute)
@@ -1,15 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.UpdatedReplication- ( UpdatedReplication(..)- )-where--import Rattletrap.Type.Attribute-import Rattletrap.Type.Common--newtype UpdatedReplication = UpdatedReplication- { updatedReplicationAttributes :: [Attribute]- } deriving (Eq, Ord, Show)--$(deriveJson ''UpdatedReplication)
@@ -1,26 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Vector- ( Vector(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord--data Vector = Vector- { vectorSize :: CompressedWord- , vectorBias :: Word- -- ^ This field is guaranteed to be small. In other words, it won't overflow.- -- It's stored as a regular 'Word' rather than something more precise like a- -- 'Word8' because it just gets passed to a functions that expect 'Word's.- -- There's no reason to do a bunch of conversions.- , vectorX :: Int- -- ^ See 'vectorBias'.- , vectorY :: Int- -- ^ See 'vectorBias'.- , vectorZ :: Int- -- ^ See 'vectorBias'.- } deriving (Eq, Ord, Show)--$(deriveJson ''Vector)
@@ -1,22 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.WeldedInfoAttribute- ( WeldedInfoAttribute(..)- )-where--import Rattletrap.Type.Common-import Rattletrap.Type.Float32le-import Rattletrap.Type.Int32le-import Rattletrap.Type.Int8Vector-import Rattletrap.Type.Vector--data WeldedInfoAttribute = WeldedInfoAttribute- { weldedInfoAttributeActive :: Bool- , weldedInfoAttributeActorId :: Int32le- , weldedInfoAttributeOffset :: Vector- , weldedInfoAttributeMass :: Float32le- , weldedInfoAttributeRotation :: Int8Vector- } deriving (Eq, Ord, Show)--$(deriveJson ''WeldedInfoAttribute)
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Word32le- ( Word32le(..)- )-where--import Rattletrap.Type.Common--newtype Word32le = Word32le- { word32leValue :: Word32- } deriving (Eq, Ord, Show)--$(deriveJson ''Word32le)
@@ -1,28 +0,0 @@-module Rattletrap.Type.Word64le- ( Word64le(..)- )-where--import qualified Data.Aeson as Aeson-import qualified Data.Aeson.Types as Aeson-import qualified Data.Scientific as Scientific-import qualified Data.Text as Text-import qualified Data.Word as Word-import qualified Text.Read as Read--newtype Word64le = Word64le- { word64leValue :: Word.Word64- } deriving (Eq, Ord, Show)--instance Aeson.FromJSON Word64le where- parseJSON value = case value of- Aeson.String text -> case Read.readEither $ Text.unpack text of- Left _ -> Aeson.typeMismatch "Word64le" value- Right word64 -> pure $ Word64le word64- Aeson.Number number -> case Scientific.toBoundedInteger number of- Nothing -> Aeson.typeMismatch "Word64le" value- Just word64 -> pure $ Word64le word64- _ -> Aeson.typeMismatch "Word64le" value--instance Aeson.ToJSON Word64le where- toJSON = Aeson.toJSON . show . word64leValue
@@ -1,14 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Word8le- ( Word8le(..)- )-where--import Rattletrap.Type.Common--newtype Word8le = Word8le- { word8leValue :: Word8- } deriving (Eq, Ord, Show)--$(deriveJson ''Word8le)
@@ -1,33 +0,0 @@-module Rattletrap.Utility.Bytes- ( encodeLatin1- , padBytes- , reverseBytes- )-where--import qualified Data.Bits as Bits-import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Char8 as Bytes8-import qualified Data.Text as Text-import qualified Data.Word as Word--encodeLatin1 :: Text.Text -> Bytes.ByteString-encodeLatin1 text = Bytes8.pack (Text.unpack text)--padBytes :: Integral a => a -> Bytes.ByteString -> Bytes.ByteString-padBytes size bytes =- bytes <> Bytes.replicate (fromIntegral size - Bytes.length bytes) 0x00--reverseByte :: Word.Word8 -> Word.Word8-reverseByte byte =- Bits.shiftR (byte Bits..&. Bits.bit 7) 7- + Bits.shiftR (byte Bits..&. Bits.bit 6) 5- + Bits.shiftR (byte Bits..&. Bits.bit 5) 3- + Bits.shiftR (byte Bits..&. Bits.bit 4) 1- + Bits.shiftL (byte Bits..&. Bits.bit 3) 1- + Bits.shiftL (byte Bits..&. Bits.bit 2) 3- + Bits.shiftL (byte Bits..&. Bits.bit 1) 5- + Bits.shiftL (byte Bits..&. Bits.bit 0) 7--reverseBytes :: Bytes.ByteString -> Bytes.ByteString-reverseBytes = Bytes.map reverseByte
@@ -1,47 +0,0 @@-module Rattletrap.Utility.Crc- ( getCrc32- )-where--import Rattletrap.Data--import qualified Data.Bits as Bits-import qualified Data.ByteString as Bytes-import qualified Data.IntMap as IntMap-import qualified Data.Word as Word---- | Computes the CRC32 of some bytes. This is done to ensure that the bytes--- are valid before trying to parse them.------ @--- getCrc32 ('Data.ByteString.Lazy.pack' [0x00])--- @------ This CRC uses an initial value of @0xefcbf201@ and a polynomial of--- @0x04c11db7@.-getCrc32 :: Bytes.ByteString -> Word.Word32-getCrc32 bytes = do- let- update = crc32Update crc32Table- initial = Bits.complement crc32Initial- crc = Bytes.foldl update initial bytes- Bits.complement crc--crc32Update- :: IntMap.IntMap Word.Word32 -> Word.Word32 -> Word.Word8 -> Word.Word32-crc32Update table crc byte = do- let- toWord8 :: (Integral a) => a -> Word.Word8- toWord8 = fromIntegral- toInt :: (Integral a) => a -> Int- toInt = fromIntegral- index = toInt (Bits.xor byte (toWord8 (Bits.shiftR crc 24)))- left = table IntMap.! index- right = Bits.shiftL crc 8- Bits.xor left right--crc32Initial :: Word.Word32-crc32Initial = 0xefcbf201--crc32Table :: IntMap.IntMap Word.Word32-crc32Table = IntMap.fromDistinctAscList (zip [0 ..] rawCrc32Table)
@@ -1,46 +0,0 @@--- | This module provides helper functions for converting replays to and from--- both their binary format and JSON.-module Rattletrap.Utility.Helper- ( decodeReplayFile- , encodeReplayJson- , decodeReplayJson- , encodeReplayFile- )-where--import Rattletrap.Decode.Common-import Rattletrap.Encode.Content-import Rattletrap.Decode.Replay-import Rattletrap.Encode.Replay-import Rattletrap.Type.Replay-import Rattletrap.Type.Section-import Rattletrap.Type.Content--import qualified Data.Aeson as Json-import qualified Data.Aeson.Encode.Pretty as Json-import qualified Data.Binary.Put as Binary-import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Lazy as LazyBytes---- | Parses a raw replay.-decodeReplayFile :: Bool -> Bytes.ByteString -> Either String Replay-decodeReplayFile fast = runDecode $ decodeReplay fast---- | Encodes a replay as JSON.-encodeReplayJson :: Replay -> Bytes.ByteString-encodeReplayJson = LazyBytes.toStrict . Json.encodePretty' Json.defConfig- { Json.confCompare = compare- , Json.confIndent = Json.Spaces 2- , Json.confTrailingNewline = True- }---- | Parses a JSON replay.-decodeReplayJson :: Bytes.ByteString -> Either String Replay-decodeReplayJson = Json.eitherDecodeStrict'---- | Encodes a raw replay.-encodeReplayFile :: Bool -> Replay -> Bytes.ByteString-encodeReplayFile fast replay =- LazyBytes.toStrict . Binary.runPut . putReplay $ if fast- then replay { replayContent = toSection putContent defaultContent }- else replay
@@ -1,199 +0,0 @@-module Main- ( main- )-where--import qualified Control.Monad as Monad-import qualified Data.ByteString.Lazy as Bytes-import qualified Data.Int as Int-import qualified Data.Word as Word-import qualified GHC.Clock as Clock-import qualified Rattletrap-import qualified System.Exit as Exit-import qualified System.FilePath as Path-import qualified System.IO.Temp as Temp-import qualified System.Mem as Mem-import qualified Test.HUnit as Test-import qualified Text.Printf as Printf--main :: IO ()-main = Temp.withSystemTempDirectory "rattletrap-" (runTests . toTests)--runTests :: Test.Test -> IO ()-runTests test = do- result <- Test.runTestTT test- Monad.when- (Test.errors result > 0 || Test.failures result > 0)- Exit.exitFailure--toTests :: FilePath -> Test.Test-toTests directory = Test.TestList (fmap (toTest directory) replays)--toTest :: FilePath -> (String, String) -> Test.Test-toTest directory (uuid, name) = Test.TestLabel- (toLabel uuid name)- (Test.TestCase (toAssertion directory uuid))--toLabel :: String -> String -> String-toLabel uuid name = uuid <> ": " <> name--toAssertion :: FilePath -> String -> Test.Assertion-toAssertion directory uuid = do- let- inputFile = Path.joinPath ["replays", Path.addExtension uuid ".replay"]- jsonFile = Path.joinPath [directory, Path.addExtension uuid ".json"]- outputFile = Path.joinPath [directory, Path.addExtension uuid ".replay"]- input <- Bytes.readFile inputFile- putStrLn ("\t" <> uuid)- do- (((), allocated), elapsed) <- withElapsed- (withAllocations (decode inputFile jsonFile))- put "decoding" (Bytes.length input) elapsed allocated- do- (((), allocated), elapsed) <- withElapsed- (withAllocations (encode jsonFile outputFile))- put "encoding" (Bytes.length input) elapsed allocated- output <- Bytes.readFile outputFile- Monad.unless- (output == input)- (Test.assertFailure "output does not match input")--put :: String -> Int.Int64 -> Word.Word64 -> Int.Int64 -> IO ()-put label size elapsed allocated = Printf.printf- "%s %d byte%s took %d nanosecond%s (%.3f MB/s) and allocated %d byte%s (%d x)\n"- label- size- (if size == 1 then "" else "s")- elapsed- (if elapsed == 1 then "" else "s")- ((1e9 * fromIntegral size) / (1048576 * fromIntegral elapsed) :: Double)- allocated- (if allocated == 1 then "" else "s")- (div allocated size)--decode :: FilePath -> FilePath -> IO ()-decode input output =- Rattletrap.rattletrap "" ["--compact", "--input", input, "--output", output]--encode :: FilePath -> FilePath -> IO ()-encode input output =- Rattletrap.rattletrap "" ["--input", input, "--output", output]--withAllocations :: IO a -> IO (a, Int.Int64)-withAllocations action = do- before <- Mem.getAllocationCounter- result <- action- after <- Mem.getAllocationCounter- pure (result, before - after)--withElapsed :: IO a -> IO (a, Word.Word64)-withElapsed action = do- before <- Clock.getMonotonicTimeNSec- result <- action- after <- Clock.getMonotonicTimeNSec- pure (result, after - before)--replays :: [(String, String)]-replays =- [ ("0008", "a flip time")- , ("000b", "nintendo switch")- , ("0416", "v1.78 demolition")- , ("07e9", "a game mode before Neo Tokyo")- , ("0ad2", "some Latin-1 text")- , ("1205", "rumble mode")- , ("160c", "a dedicated server IP")- , ("16d5", "new property types")- , ("18d6", "an online loadout attribute")- , ("1a12", "overtime")- , ("1ae4", "a game time")- , ("1bc2", "no padding after the frames")- , ("1d1d", "a camera pitch")- , ("1ec9", "a V1.63 match")- , ("1ef9", "a private hoops match")- , ("1f37", "splitscreen players")- , ("2114", "a match save")- , ("21a8", "v1.66")- , ("2266", "dropshot")- , ("22ba", "a vote to forfeit")- , ("27b6", "some UTF-16 text")- , ("29f5", "frames")- , ("2cfe", "a new playstation id")- , ("3381", "patch 1.37")- , ("372d", "a camera yaw attribute")- , ("383e", "older unknown content field")- , ("387f", "a frozen attribute")- , ("3abd", "rlcs")- , ("3ea1", "a custom team name")- , ("4126", "a game mode after Neo Tokyo")- , ("419a", "a club match")- , ("42f0", "reservations after Neo Tokyo")- , ("42f2", "anniversary ball")- , ("4bc3", "with timed out attribute")- , ("504e", "some messages")- , ("520e", "no pickup attribute")- , ("524f", "quat edge case")- , ("52aa", "a match-ending attribute")- , ("540d", "a demolish attribute")- , ("551c", "private match settings")- , ("5a06", "esports items")- , ("6210", "different player history key")- , ("6320", "a forfeit attribute")- , ("6688", "a malformed byte property")- , ("6b0d", "patch 1.37")- , ("6d1b", "a flip right")- , ("6f7c", "a map with numbers")- , ("7083", "weird basketball capitalization")- , ("7109", "a boost modifier")- , ("7256", "special edition")- , ("75ce", "primary and secondary titles")- , ("7bf6", "an online loadouts attribute")- , ("89cb", "remote user data")- , ("8ae5", "new painted items")- , ("92a6", "with server performance state")- , ("946f", "patch 1.43")- , ("9704", "a batarang")- , ("98e5", "a player using behind view")- , ("9a2c", "ghost hunt")- , ("9e35", "spike rush")- , ("9eaa", "newer replay without trailing bytes")- , ("a09e", "a tournament")- , ("a128", "a round count down")- , ("a184", "max score")- , ("a1c0", "epic system id")- , ("a52f", "some more mutators")- , ("a558", "extended explosion data")- , ("a671", "a waiting player")- , ("a676", "new user color")- , ("a7f0", "a ready attribute")- , ("a9df", "salty shores patch 1.45")- , ("aa70", "patch 1.50 - TitleID attribute")- , ("afb1", "patch 1.37")- , ("b9f9", "a party leader")- , ("c14f", "some mutators")- , ("c23b", "new psynet id")- , ("c837", "a spectator")- , ("cc4c", "after Starbase ARC")- , ("d044", "hoops mutators")- , ("d1d5", "v1.68")- , ("d236", "rlcs s2")- , ("d428", "a private hockey match")- , ("d44c", "ranked tournament")- , ("d52e", "psynet system id")- , ("d7fb", "an explosion attribute")- , ("d818", "heatseeker")- , ("db70", "new lag indicator")- , ("dcab", "weird ball attribute value")- , ("dcb3", "a pawn type attribute")- , ("dd14", "v1.88")- , ("de56", "a problematic product attribute")- , ("e80d", "unlimited time")- , ("e978", "distracted")- , ("eae3", "an actor/object ID collision")- , ("eae8", "custom team colors")- , ("edbb", "remote role")- , ("f299", "a location attribute")- , ("f7b9", "a hockey game event")- , ("f811", "no frames")- , ("fdc7", "an MVP")- , ("ffb7", "with difficulty")- ]
@@ -0,0 +1,6 @@+module Main+ ( main+ )+where++import Rattletrap (main)
@@ -0,0 +1,162 @@+module Rattletrap+ ( Rattletrap.Console.Main.main+ , Rattletrap.Console.Main.rattletrap+ , Rattletrap.Utility.Helper.decodeReplayFile+ , Rattletrap.Utility.Helper.encodeReplayJson+ , Rattletrap.Utility.Helper.decodeReplayJson+ , Rattletrap.Utility.Helper.encodeReplayFile+ , Rattletrap.Type.AppliedDamageAttribute.AppliedDamageAttribute(..)+ , Rattletrap.Type.Attribute.Attribute(..)+ , Rattletrap.Type.AttributeMapping.AttributeMapping(..)+ , Rattletrap.Type.AttributeType.AttributeType(..)+ , Rattletrap.Type.AttributeValue.AttributeValue(..)+ , Rattletrap.Type.BooleanAttribute.BooleanAttribute(..)+ , Rattletrap.Type.ByteAttribute.ByteAttribute(..)+ , Rattletrap.Type.Cache.Cache(..)+ , Rattletrap.Type.CamSettingsAttribute.CamSettingsAttribute(..)+ , Rattletrap.Type.ClassAttributeMap.ClassAttributeMap(..)+ , Rattletrap.Type.ClassMapping.ClassMapping(..)+ , Rattletrap.Type.ClubColorsAttribute.ClubColorsAttribute(..)+ , Rattletrap.Type.CompressedWord.CompressedWord(..)+ , Rattletrap.Type.CompressedWordVector.CompressedWordVector(..)+ , Rattletrap.Type.Content.Content(..)+ , Rattletrap.Type.DamageStateAttribute.DamageStateAttribute(..)+ , Rattletrap.Type.DemolishAttribute.DemolishAttribute(..)+ , Rattletrap.Type.DestroyedReplication.DestroyedReplication(..)+ , Rattletrap.Type.Dictionary.Dictionary(..)+ , Rattletrap.Type.EnumAttribute.EnumAttribute(..)+ , Rattletrap.Type.ExplosionAttribute.ExplosionAttribute(..)+ , Rattletrap.Type.ExtendedExplosionAttribute.ExtendedExplosionAttribute(..)+ , Rattletrap.Type.FlaggedIntAttribute.FlaggedIntAttribute(..)+ , Rattletrap.Type.Float32le.Float32le(..)+ , Rattletrap.Type.FloatAttribute.FloatAttribute(..)+ , Rattletrap.Type.Frame.Frame(..)+ , Rattletrap.Type.GameModeAttribute.GameModeAttribute(..)+ , Rattletrap.Type.Header.Header(..)+ , Rattletrap.Type.Initialization.Initialization(..)+ , Rattletrap.Type.Int32le.Int32le(..)+ , Rattletrap.Type.Int64Attribute.Int64Attribute(..)+ , Rattletrap.Type.Int64le.Int64le(..)+ , Rattletrap.Type.Int8le.Int8le(..)+ , Rattletrap.Type.Int8Vector.Int8Vector(..)+ , Rattletrap.Type.IntAttribute.IntAttribute(..)+ , Rattletrap.Type.KeyFrame.KeyFrame(..)+ , Rattletrap.Type.List.List(..)+ , Rattletrap.Type.LoadoutAttribute.LoadoutAttribute(..)+ , Rattletrap.Type.LoadoutOnlineAttribute.LoadoutOnlineAttribute(..)+ , Rattletrap.Type.LoadoutsAttribute.LoadoutsAttribute(..)+ , Rattletrap.Type.LoadoutsOnlineAttribute.LoadoutsOnlineAttribute(..)+ , Rattletrap.Type.LocationAttribute.LocationAttribute(..)+ , Rattletrap.Type.Mark.Mark(..)+ , Rattletrap.Type.Message.Message(..)+ , Rattletrap.Type.MusicStingerAttribute.MusicStingerAttribute(..)+ , Rattletrap.Type.PartyLeaderAttribute.PartyLeaderAttribute(..)+ , Rattletrap.Type.PickupAttribute.PickupAttribute(..)+ , Rattletrap.Type.PlayerHistoryKeyAttribute.PlayerHistoryKeyAttribute(..)+ , Rattletrap.Type.PrivateMatchSettingsAttribute.PrivateMatchSettingsAttribute(..)+ , Rattletrap.Type.ProductAttribute.ProductAttribute(..)+ , Rattletrap.Type.Property.Property(..)+ , Rattletrap.Type.PropertyValue.PropertyValue(..)+ , Rattletrap.Type.Quaternion.Quaternion(..)+ , Rattletrap.Type.QWordAttribute.QWordAttribute(..)+ , Rattletrap.Type.RemoteId.RemoteId(..)+ , Rattletrap.Type.Replay.Replay(..)+ , Rattletrap.Type.Replication.Replication(..)+ , Rattletrap.Type.ReplicationValue.ReplicationValue(..)+ , Rattletrap.Type.ReservationAttribute.ReservationAttribute(..)+ , Rattletrap.Type.RigidBodyStateAttribute.RigidBodyStateAttribute(..)+ , Rattletrap.Type.Rotation.Rotation(..)+ , Rattletrap.Type.Section.Section(..)+ , Rattletrap.Type.SpawnedReplication.SpawnedReplication(..)+ , Rattletrap.Type.StatEventAttribute.StatEventAttribute(..)+ , Rattletrap.Type.Str.Str(..)+ , Rattletrap.Type.StringAttribute.StringAttribute(..)+ , Rattletrap.Type.TeamPaintAttribute.TeamPaintAttribute(..)+ , Rattletrap.Type.TitleAttribute.TitleAttribute(..)+ , Rattletrap.Type.UniqueIdAttribute.UniqueIdAttribute(..)+ , Rattletrap.Type.UpdatedReplication.UpdatedReplication(..)+ , Rattletrap.Type.Vector.Vector(..)+ , Rattletrap.Type.WeldedInfoAttribute.WeldedInfoAttribute(..)+ , Rattletrap.Type.Word32le.Word32le(..)+ , Rattletrap.Type.Word64le.Word64le(..)+ , Rattletrap.Type.Word8le.Word8le(..)+ )+where++import qualified Rattletrap.Console.Main+import qualified Rattletrap.Type.AppliedDamageAttribute+import qualified Rattletrap.Type.Attribute+import qualified Rattletrap.Type.AttributeMapping+import qualified Rattletrap.Type.AttributeType+import qualified Rattletrap.Type.AttributeValue+import qualified Rattletrap.Type.BooleanAttribute+import qualified Rattletrap.Type.ByteAttribute+import qualified Rattletrap.Type.Cache+import qualified Rattletrap.Type.CamSettingsAttribute+import qualified Rattletrap.Type.ClassAttributeMap+import qualified Rattletrap.Type.ClassMapping+import qualified Rattletrap.Type.ClubColorsAttribute+import qualified Rattletrap.Type.CompressedWord+import qualified Rattletrap.Type.CompressedWordVector+import qualified Rattletrap.Type.Content+import qualified Rattletrap.Type.DamageStateAttribute+import qualified Rattletrap.Type.DemolishAttribute+import qualified Rattletrap.Type.DestroyedReplication+import qualified Rattletrap.Type.Dictionary+import qualified Rattletrap.Type.EnumAttribute+import qualified Rattletrap.Type.ExplosionAttribute+import qualified Rattletrap.Type.ExtendedExplosionAttribute+import qualified Rattletrap.Type.FlaggedIntAttribute+import qualified Rattletrap.Type.Float32le+import qualified Rattletrap.Type.FloatAttribute+import qualified Rattletrap.Type.Frame+import qualified Rattletrap.Type.GameModeAttribute+import qualified Rattletrap.Type.Header+import qualified Rattletrap.Type.Initialization+import qualified Rattletrap.Type.Int32le+import qualified Rattletrap.Type.Int64Attribute+import qualified Rattletrap.Type.Int64le+import qualified Rattletrap.Type.Int8le+import qualified Rattletrap.Type.Int8Vector+import qualified Rattletrap.Type.IntAttribute+import qualified Rattletrap.Type.KeyFrame+import qualified Rattletrap.Type.List+import qualified Rattletrap.Type.LoadoutAttribute+import qualified Rattletrap.Type.LoadoutOnlineAttribute+import qualified Rattletrap.Type.LoadoutsAttribute+import qualified Rattletrap.Type.LoadoutsOnlineAttribute+import qualified Rattletrap.Type.LocationAttribute+import qualified Rattletrap.Type.Mark+import qualified Rattletrap.Type.Message+import qualified Rattletrap.Type.MusicStingerAttribute+import qualified Rattletrap.Type.PartyLeaderAttribute+import qualified Rattletrap.Type.PickupAttribute+import qualified Rattletrap.Type.PlayerHistoryKeyAttribute+import qualified Rattletrap.Type.PrivateMatchSettingsAttribute+import qualified Rattletrap.Type.ProductAttribute+import qualified Rattletrap.Type.Property+import qualified Rattletrap.Type.PropertyValue+import qualified Rattletrap.Type.Quaternion+import qualified Rattletrap.Type.QWordAttribute+import qualified Rattletrap.Type.RemoteId+import qualified Rattletrap.Type.Replay+import qualified Rattletrap.Type.Replication+import qualified Rattletrap.Type.ReplicationValue+import qualified Rattletrap.Type.ReservationAttribute+import qualified Rattletrap.Type.RigidBodyStateAttribute+import qualified Rattletrap.Type.Rotation+import qualified Rattletrap.Type.Section+import qualified Rattletrap.Type.SpawnedReplication+import qualified Rattletrap.Type.StatEventAttribute+import qualified Rattletrap.Type.Str+import qualified Rattletrap.Type.StringAttribute+import qualified Rattletrap.Type.TeamPaintAttribute+import qualified Rattletrap.Type.TitleAttribute+import qualified Rattletrap.Type.UniqueIdAttribute+import qualified Rattletrap.Type.UpdatedReplication+import qualified Rattletrap.Type.Vector+import qualified Rattletrap.Type.WeldedInfoAttribute+import qualified Rattletrap.Type.Word32le+import qualified Rattletrap.Type.Word64le+import qualified Rattletrap.Type.Word8le+import qualified Rattletrap.Utility.Helper
@@ -0,0 +1,238 @@+module Rattletrap.Console.Main+ ( main+ , rattletrap+ )+where++import qualified Control.Monad as Monad+import qualified Data.Aeson as Json+import qualified Data.ByteString as Bytes+import qualified Data.ByteString.Lazy as LazyBytes+import qualified Data.Version as Version+import qualified Network.HTTP.Client as Client+import qualified Network.HTTP.Client.TLS as Client+import qualified Paths_rattletrap as This+import qualified Rattletrap.Type.Replay as Rattletrap+import qualified Rattletrap.Utility.Helper as Rattletrap+import qualified System.Console.GetOpt as Console+import qualified System.Environment as Environment+import qualified System.Exit as Exit+import qualified System.FilePath as Path+import qualified System.IO as IO+import qualified Text.Printf as Printf++main :: IO ()+main = do+ name <- Environment.getProgName+ arguments <- Environment.getArgs+ rattletrap name arguments++rattletrap :: String -> [String] -> IO ()+rattletrap name arguments = do+ config <- getConfig arguments+ Monad.when (configHelp config) (printHelp name *> Exit.exitFailure)+ Monad.when (configVersion config) (printVersion *> Exit.exitFailure)+ input <- getInput config+ let decode = getDecoder config+ replay <- either fail pure (decode input)+ let encode = getEncoder config+ putOutput config (encode replay)++getDecoder :: Config -> Bytes.ByteString -> Either String Rattletrap.FullReplay+getDecoder config = case getMode config of+ ModeDecode -> Rattletrap.decodeReplayFile $ configFast config+ ModeEncode -> Rattletrap.decodeReplayJson++getEncoder :: Config -> Rattletrap.FullReplay -> Bytes.ByteString+getEncoder config = case getMode config of+ ModeDecode -> if configCompact config+ then LazyBytes.toStrict . Json.encode+ else Rattletrap.encodeReplayJson+ ModeEncode -> Rattletrap.encodeReplayFile $ configFast config++getInput :: Config -> IO Bytes.ByteString+getInput config = case configInput config of+ Nothing -> Bytes.getContents+ Just fileOrUrl -> case Client.parseUrlThrow fileOrUrl of+ Nothing -> Bytes.readFile fileOrUrl+ Just request -> do+ manager <- Client.newTlsManager+ response <- Client.httpLbs request manager+ pure (LazyBytes.toStrict (Client.responseBody response))++putOutput :: Config -> Bytes.ByteString -> IO ()+putOutput = maybe Bytes.putStr Bytes.writeFile . configOutput++getConfig :: [String] -> IO Config+getConfig arguments = do+ let+ (updates, unexpectedArguments, unknownOptions, problems) =+ Console.getOpt' Console.Permute options arguments+ printUnexpectedArguments unexpectedArguments+ printUnknownOptions unknownOptions+ printProblems problems+ Monad.unless (null problems) Exit.exitFailure+ either fail pure (Monad.foldM applyUpdate defaultConfig updates)++type Option = Console.OptDescr Update++type Update = Config -> Either String Config++options :: [Option]+options =+ [ compactOption+ , fastOption+ , helpOption+ , inputOption+ , modeOption+ , outputOption+ , versionOption+ ]++compactOption :: Option+compactOption = Console.Option+ ['c']+ ["compact"]+ (Console.NoArg (\config -> pure config { configCompact = True }))+ "minify JSON output"++fastOption :: Option+fastOption = Console.Option+ ['f']+ ["fast"]+ (Console.NoArg (\config -> pure config { configFast = True }))+ "only encode or decode the header"++helpOption :: Option+helpOption = Console.Option+ ['h']+ ["help"]+ (Console.NoArg (\config -> pure config { configHelp = True }))+ "show the help"++inputOption :: Option+inputOption = Console.Option+ ['i']+ ["input"]+ (Console.ReqArg+ (\input config -> pure config { configInput = Just input })+ "FILE|URL"+ )+ "input file or URL"++modeOption :: Option+modeOption = Console.Option+ ['m']+ ["mode"]+ (Console.ReqArg+ (\rawMode config -> do+ mode <- parseMode rawMode+ pure config { configMode = Just mode }+ )+ "MODE"+ )+ "decode or encode"++outputOption :: Option+outputOption = Console.Option+ ['o']+ ["output"]+ (Console.ReqArg+ (\output config -> pure config { configOutput = Just output })+ "FILE"+ )+ "output file"++versionOption :: Option+versionOption = Console.Option+ ['v']+ ["version"]+ (Console.NoArg (\config -> pure config { configVersion = True }))+ "show the version"++applyUpdate :: Config -> Update -> Either String Config+applyUpdate config update = update config++data Config = Config+ { configCompact :: Bool+ , configFast :: Bool+ , configHelp :: Bool+ , configInput :: Maybe String+ , configMode :: Maybe Mode+ , configOutput :: Maybe String+ , configVersion :: Bool+ } deriving (Show)++defaultConfig :: Config+defaultConfig = Config+ { configCompact = False+ , configFast = False+ , configHelp = False+ , configInput = Nothing+ , configMode = Nothing+ , configOutput = Nothing+ , configVersion = False+ }++getMode :: Config -> Mode+getMode config = case getExtension (configInput config) of+ ".json" -> ModeEncode+ ".replay" -> ModeDecode+ _ -> case getExtension (configOutput config) of+ ".json" -> ModeDecode+ ".replay" -> ModeEncode+ _ -> ModeDecode++getExtension :: Maybe String -> String+getExtension = maybe "" Path.takeExtension++data Mode+ = ModeDecode+ | ModeEncode+ deriving (Show)++parseMode :: String -> Either String Mode+parseMode mode = case mode of+ "decode" -> Right ModeDecode+ "encode" -> Right ModeEncode+ _ -> Left (Printf.printf "invalid mode: %s" (show mode))++printUnexpectedArguments :: [String] -> IO ()+printUnexpectedArguments = mapM_ printUnexpectedArgument++printUnexpectedArgument :: String -> IO ()+printUnexpectedArgument =+ warnLn . Printf.printf "WARNING: unexpected argument `%s'"++printUnknownOptions :: [String] -> IO ()+printUnknownOptions = mapM_ printUnknownOption++printUnknownOption :: String -> IO ()+printUnknownOption = warnLn . Printf.printf "WARNING: unknown option `%s'"++printProblems :: [String] -> IO ()+printProblems = mapM_ printProblem++printProblem :: String -> IO ()+printProblem = warn . Printf.printf "ERROR: %s"++printHelp :: String -> IO ()+printHelp = warn . help++help :: String -> String+help name = Console.usageInfo (header name) options++header :: String -> String+header name = unwords [name, "version", version]++version :: String+version = Version.showVersion This.version++printVersion :: IO ()+printVersion = warnLn version++warn :: String -> IO ()+warn = IO.hPutStr IO.stderr++warnLn :: String -> IO ()+warnLn = IO.hPutStrLn IO.stderr
@@ -0,0 +1,665 @@+-- brittany --columns 120+module Rattletrap.Data+ ( rawParentClasses+ , rawClassesWithLocation+ , rawClassesWithRotation+ , rawObjectClasses+ , rawAttributeTypes+ , rawCrc32Table+ )+where++import Rattletrap.Type.AttributeType++rawParentClasses :: [(String, String)]+rawParentClasses =+ [ ("Engine.Actor", "Core.Object")+ , ("Engine.GameReplicationInfo", "Engine.ReplicationInfo")+ , ("Engine.Info", "Engine.Actor")+ , ("Engine.Pawn", "Engine.Actor")+ , ("Engine.PlayerReplicationInfo", "Engine.ReplicationInfo")+ , ("Engine.ReplicationInfo", "Engine.Info")+ , ("Engine.TeamInfo", "Engine.ReplicationInfo")+ , ("ProjectX.GRI_X", "Engine.GameReplicationInfo")+ , ("ProjectX.Pawn_X", "Engine.Pawn")+ , ("ProjectX.PRI_X", "Engine.PlayerReplicationInfo")+ , ("TAGame.Ball_God_TA", "TAGame.Ball_TA")+ , ("TAGame.Ball_Haunted_TA", "TAGame.Ball_TA")+ , ("TAGame.Ball_TA", "TAGame.RBActor_TA")+ , ("TAGame.CameraSettingsActor_TA", "Engine.ReplicationInfo")+ , ("TAGame.Car_Season_TA", "TAGame.PRI_TA")+ , ("TAGame.Car_TA", "TAGame.Vehicle_TA")+ , ("TAGame.CarComponent_Boost_TA", "TAGame.CarComponent_TA")+ , ("TAGame.CarComponent_Dodge_TA", "TAGame.CarComponent_TA")+ , ("TAGame.CarComponent_DoubleJump_TA", "TAGame.CarComponent_TA")+ , ("TAGame.CarComponent_FlipCar_TA", "TAGame.CarComponent_TA")+ , ("TAGame.CarComponent_Jump_TA", "TAGame.CarComponent_TA")+ , ("TAGame.CarComponent_TA", "Engine.ReplicationInfo")+ , ("TAGame.CrowdActor_TA", "Engine.ReplicationInfo")+ , ("TAGame.CrowdManager_TA", "Engine.ReplicationInfo")+ , ("TAGame.GameEvent_GodBall_TA", "TAGame.GameEvent_Soccar_TA")+ , ("TAGame.GameEvent_Season_TA", "TAGame.GameEvent_Soccar_TA")+ , ("TAGame.GameEvent_Soccar_TA", "TAGame.GameEvent_Team_TA")+ , ("TAGame.GameEvent_SoccarPrivate_TA", "TAGame.GameEvent_Soccar_TA")+ , ("TAGame.GameEvent_SoccarSplitscreen_TA", "TAGame.GameEvent_SoccarPrivate_TA")+ , ("TAGame.GameEvent_TA", "Engine.ReplicationInfo")+ , ("TAGame.GameEvent_Team_TA", "TAGame.GameEvent_TA")+ , ("TAGame.GRI_TA", "ProjectX.GRI_X")+ , ("TAGame.HauntedBallTrapTrigger_TA", "Engine.Actor")+ , ("TAGame.InMapScoreboard_TA", "Engine.Actor")+ , ("TAGame.PRI_TA", "ProjectX.PRI_X")+ , ("TAGame.RBActor_TA", "ProjectX.Pawn_X")+ , ("TAGame.SpecialPickup_BallCarSpring_TA", "TAGame.SpecialPickup_Spring_TA")+ , ("TAGame.SpecialPickup_BallFreeze_TA", "TAGame.SpecialPickup_Targeted_TA")+ , ("TAGame.SpecialPickup_BallGravity_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.SpecialPickup_BallLasso_TA", "TAGame.SpecialPickup_GrapplingHook_TA")+ , ("TAGame.SpecialPickup_BallVelcro_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.SpecialPickup_Batarang_TA", "TAGame.SpecialPickup_BallLasso_TA")+ , ("TAGame.SpecialPickup_BoostOverride_TA", "TAGame.SpecialPickup_Targeted_TA")+ , ("TAGame.SpecialPickup_GrapplingHook_TA", "TAGame.SpecialPickup_Targeted_TA")+ , ("TAGame.SpecialPickup_HauntedBallBeam_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.SpecialPickup_HitForce_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.SpecialPickup_Rugby_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.SpecialPickup_Spring_TA", "TAGame.SpecialPickup_Targeted_TA")+ , ("TAGame.SpecialPickup_Swapper_TA", "TAGame.SpecialPickup_Targeted_TA")+ , ("TAGame.SpecialPickup_TA", "TAGame.CarComponent_TA")+ , ("TAGame.SpecialPickup_Targeted_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.SpecialPickup_Tornado_TA", "TAGame.SpecialPickup_TA")+ , ("TAGame.Team_Soccar_TA", "TAGame.Team_TA")+ , ("TAGame.Team_TA", "Engine.TeamInfo")+ , ("TAGame.Vehicle_TA", "TAGame.RBActor_TA")+ , ("TAGame.VehiclePickup_Boost_TA", "TAGame.VehiclePickup_TA")+ , ("TAGame.VehiclePickup_TA", "Engine.ReplicationInfo")+ ]++rawClassesWithLocation :: [String]+rawClassesWithLocation =+ [ "Archetypes.Ball.Ball_BasketBall_Mutator"+ , "Archetypes.Ball.Ball_Basketball"+ , "Archetypes.Ball.Ball_BasketBall"+ , "Archetypes.Ball.Ball_Breakout"+ , "Archetypes.Ball.Ball_Default"+ , "Archetypes.Ball.Ball_Puck"+ , "Archetypes.Ball.CubeBall"+ , "Archetypes.Car.Car_Default"+ , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"+ , "Archetypes.SpecialPickups.SpecialPickup_Rugby"+ , "ProjectX.NetModeReplicator"+ , "TAGame.Ball_Breakout_TA"+ , "TAGame.Ball_God_TA"+ , "TAGame.Ball_Haunted_TA"+ , "TAGame.Ball_TA"+ , "TAGame.CameraSettingsActor_TA"+ , "TAGame.Car_Season_TA"+ , "TAGame.Car_TA"+ , "TAGame.CarComponent_Boost_TA"+ , "TAGame.CarComponent_Dodge_TA"+ , "TAGame.CarComponent_DoubleJump_TA"+ , "TAGame.CarComponent_FlipCar_TA"+ , "TAGame.CarComponent_Jump_TA"+ , "TAGame.Default__CameraSettingsActor_TA"+ , "TAGame.Default__PRI_TA"+ , "TAGame.GameEvent_GodBall_TA"+ , "TAGame.GameEvent_Season_TA"+ , "TAGame.GameEvent_Soccar_TA"+ , "TAGame.GameEvent_SoccarPrivate_TA"+ , "TAGame.GameEvent_SoccarSplitscreen_TA"+ , "TAGame.GRI_TA"+ , "TAGame.MaxTimeWarningData_TA"+ , "TAGame.RumblePickups_TA"+ , "TAGame.PRI_TA"+ , "TAGame.SpecialPickup_BallCarSpring_TA"+ , "TAGame.SpecialPickup_BallFreeze_TA"+ , "TAGame.SpecialPickup_BallGravity_TA"+ , "TAGame.SpecialPickup_BallLasso_TA"+ , "TAGame.SpecialPickup_BallVelcro_TA"+ , "TAGame.SpecialPickup_Batarang_TA"+ , "TAGame.SpecialPickup_BoostOverride_TA"+ , "TAGame.SpecialPickup_GrapplingHook_TA"+ , "TAGame.SpecialPickup_HauntedBallBeam_TA"+ , "TAGame.SpecialPickup_HitForce_TA"+ , "TAGame.SpecialPickup_Rugby_TA"+ , "TAGame.SpecialPickup_Swapper_TA"+ , "TAGame.SpecialPickup_Tornado_TA"+ , "TAGame.Team_Soccar_TA"+ , "TheWorld:PersistentLevel.BreakOutActor_Platform_TA"+ , "TheWorld:PersistentLevel.CrowdActor_TA"+ , "TheWorld:PersistentLevel.CrowdManager_TA"+ , "TheWorld:PersistentLevel.InMapScoreboard_TA"+ , "TheWorld:PersistentLevel.VehiclePickup_Boost_TA"+ ]++rawClassesWithRotation :: [String]+rawClassesWithRotation =+ [ "Archetypes.Ball.Ball_BasketBall_Mutator"+ , "Archetypes.Ball.Ball_Basketball"+ , "Archetypes.Ball.Ball_BasketBall"+ , "Archetypes.Ball.Ball_Breakout"+ , "Archetypes.Ball.Ball_Default"+ , "Archetypes.Ball.Ball_Puck"+ , "Archetypes.Ball.CubeBall"+ , "Archetypes.Car.Car_Default"+ , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"+ , "Archetypes.SpecialPickups.SpecialPickup_Rugby"+ , "TAGame.Ball_Breakout_TA"+ , "TAGame.Ball_God_TA"+ , "TAGame.Ball_Haunted_TA"+ , "TAGame.Ball_TA"+ , "TAGame.Car_Season_TA"+ , "TAGame.Car_TA"+ ]++rawObjectClasses :: [(String, String)]+rawObjectClasses =+ [ ("Archetypes.Ball.Ball_Anniversary", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_BasketBall_Mutator", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_Basketball", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_BasketBall", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_Beachball", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_Breakout", "TAGame.Ball_Breakout_TA")+ , ("Archetypes.Ball.Ball_Default", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_God", "TAGame.Ball_God_TA")+ , ("Archetypes.Ball.Ball_Haunted", "TAGame.Ball_Haunted_TA")+ , ("Archetypes.Ball.Ball_Puck", "TAGame.Ball_TA")+ , ("Archetypes.Ball.CubeBall", "TAGame.Ball_TA")+ , ("Archetypes.Car.Car_Default", "TAGame.Car_TA")+ , ("Archetypes.CarComponents.CarComponent_Boost", "TAGame.CarComponent_Boost_TA")+ , ("Archetypes.CarComponents.CarComponent_Dodge", "TAGame.CarComponent_Dodge_TA")+ , ("Archetypes.CarComponents.CarComponent_DoubleJump", "TAGame.CarComponent_DoubleJump_TA")+ , ("Archetypes.CarComponents.CarComponent_FlipCar", "TAGame.CarComponent_FlipCar_TA")+ , ("Archetypes.CarComponents.CarComponent_Jump", "TAGame.CarComponent_Jump_TA")+ , ("Archetypes.GameEvent.GameEvent_Basketball", "TAGame.GameEvent_Soccar_TA")+ , ("Archetypes.GameEvent.GameEvent_BasketballPrivate", "TAGame.GameEvent_SoccarPrivate_TA")+ , ("Archetypes.GameEvent.GameEvent_BasketballSplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")+ , ("Archetypes.GameEvent.GameEvent_Breakout", "TAGame.GameEvent_Soccar_TA")+ , ("Archetypes.GameEvent.GameEvent_Hockey", "TAGame.GameEvent_Soccar_TA")+ , ("Archetypes.GameEvent.GameEvent_HockeyPrivate", "TAGame.GameEvent_SoccarPrivate_TA")+ , ("Archetypes.GameEvent.GameEvent_HockeySplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")+ , ("Archetypes.GameEvent.GameEvent_Items", "TAGame.GameEvent_Soccar_TA")+ , ("Archetypes.GameEvent.GameEvent_Season:CarArchetype", "TAGame.Car_TA")+ , ("Archetypes.GameEvent.GameEvent_Season", "TAGame.GameEvent_Season_TA")+ , ("Archetypes.GameEvent.GameEvent_Soccar", "TAGame.GameEvent_Soccar_TA")+ , ("Archetypes.GameEvent.GameEvent_SoccarLan", "TAGame.GameEvent_Soccar_TA")+ , ("Archetypes.GameEvent.GameEvent_SoccarPrivate", "TAGame.GameEvent_SoccarPrivate_TA")+ , ("Archetypes.GameEvent.GameEvent_SoccarSplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_BallFreeze", "TAGame.SpecialPickup_BallFreeze_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_BallGrapplingHook", "TAGame.SpecialPickup_GrapplingHook_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_BallLasso", "TAGame.SpecialPickup_BallLasso_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_BallSpring", "TAGame.SpecialPickup_BallCarSpring_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_BallVelcro", "TAGame.SpecialPickup_BallVelcro_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_Batarang", "TAGame.SpecialPickup_Batarang_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_BoostOverride", "TAGame.SpecialPickup_BoostOverride_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_CarSpring", "TAGame.SpecialPickup_BallCarSpring_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_GravityWell", "TAGame.SpecialPickup_BallGravity_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_HauntedBallBeam", "TAGame.SpecialPickup_HauntedBallBeam_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_Rugby", "TAGame.SpecialPickup_Rugby_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_StrongHit", "TAGame.SpecialPickup_HitForce_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_Swapper", "TAGame.SpecialPickup_Swapper_TA")+ , ("Archetypes.SpecialPickups.SpecialPickup_Tornado", "TAGame.SpecialPickup_Tornado_TA")+ , ("Archetypes.Teams.Team0", "TAGame.Team_Soccar_TA")+ , ("Archetypes.Teams.Team1", "TAGame.Team_Soccar_TA")+ , ("GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("GameInfo_Breakout.GameInfo.GameInfo_Breakout:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("gameinfo_godball.GameInfo.gameinfo_godball:Archetype", "TAGame.GameEvent_GodBall_TA")+ , ("gameinfo_godball.GameInfo.gameinfo_godball:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("GameInfo_Items.GameInfo.GameInfo_Items:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("GameInfo_Season.GameInfo.GameInfo_Season:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype", "TAGame.GRI_TA")+ , ("Haunted_TrainStation_P.TheWorld:PersistentLevel.HauntedBallTrapTrigger_TA_0", "TAGame.HauntedBallTrapTrigger_TA")+ , ("Haunted_TrainStation_P.TheWorld:PersistentLevel.HauntedBallTrapTrigger_TA_1", "TAGame.HauntedBallTrapTrigger_TA")+ , ("ProjectX.Default__NetModeReplicator_X", "ProjectX.NetModeReplicator")+ , ("TAGame.Default__CameraSettingsActor_TA", "TAGame.CameraSettingsActor_TA")+ , ("TAGame.Default__MaxTimeWarningData_TA", "TAGame.MaxTimeWarningData_TA")+ , ("TAGame.Default__RumblePickups_TA", "TAGame.RumblePickups_TA")+ , ("TAGame.Default__PRI_TA", "TAGame.PRI_TA")+ , ("TheWorld:PersistentLevel.BreakOutActor_Platform_TA", "TAGame.BreakOutActor_Platform_TA")+ , ("TheWorld:PersistentLevel.CrowdActor_TA", "TAGame.CrowdActor_TA")+ , ("TheWorld:PersistentLevel.CrowdManager_TA", "TAGame.CrowdManager_TA")+ , ("TheWorld:PersistentLevel.InMapScoreboard_TA", "TAGame.InMapScoreboard_TA")+ , ("TheWorld:PersistentLevel.VehiclePickup_Boost_TA", "TAGame.VehiclePickup_Boost_TA")+ ]++rawAttributeTypes :: [(String, AttributeType)]+rawAttributeTypes =+ [ ("Engine.Actor:bBlockActors", AttributeTypeBoolean)+ , ("Engine.Actor:bCollideActors", AttributeTypeBoolean)+ , ("Engine.Actor:bHidden", AttributeTypeBoolean)+ , ("Engine.Actor:DrawScale", AttributeTypeFloat)+ , ("Engine.Actor:RemoteRole", AttributeTypeEnum)+ , ("Engine.Actor:Role", AttributeTypeEnum)+ , ("Engine.GameReplicationInfo:bMatchIsOver", AttributeTypeBoolean)+ , ("Engine.GameReplicationInfo:GameClass", AttributeTypeFlaggedInt)+ , ("TAGame.Car_TA:RumblePickups", AttributeTypeFlaggedInt)+ , ("Engine.GameReplicationInfo:ServerName", AttributeTypeString)+ , ("Engine.Pawn:PlayerReplicationInfo", AttributeTypeFlaggedInt)+ , ("Engine.PlayerReplicationInfo:bBot", AttributeTypeBoolean)+ , ("Engine.PlayerReplicationInfo:bIsSpectator", AttributeTypeBoolean)+ , ("Engine.PlayerReplicationInfo:bReadyToPlay", AttributeTypeBoolean)+ , ("Engine.PlayerReplicationInfo:bTimedOut", AttributeTypeBoolean)+ , ("Engine.PlayerReplicationInfo:bWaitingPlayer", AttributeTypeBoolean)+ , ("Engine.PlayerReplicationInfo:Ping", AttributeTypeByte)+ , ("Engine.PlayerReplicationInfo:PlayerID", AttributeTypeInt)+ , ("Engine.PlayerReplicationInfo:PlayerName", AttributeTypeString)+ , ("Engine.PlayerReplicationInfo:RemoteUserData", AttributeTypeString)+ , ("Engine.PlayerReplicationInfo:Score", AttributeTypeInt)+ , ("Engine.PlayerReplicationInfo:Team", AttributeTypeFlaggedInt)+ , ("Engine.PlayerReplicationInfo:UniqueId", AttributeTypeUniqueId)+ , ("Engine.ReplicatedActor_ORS:ReplicatedOwner", AttributeTypeFlaggedInt)+ , ("Engine.TeamInfo:Score", AttributeTypeInt)+ , ("ProjectX.GRI_X:bGameStarted", AttributeTypeBoolean)+ , ("ProjectX.GRI_X:GameServerID", AttributeTypeQWord)+ , ("ProjectX.GRI_X:MatchGUID", AttributeTypeString)+ , ("ProjectX.GRI_X:ReplicatedGameMutatorIndex", AttributeTypeInt)+ , ("ProjectX.GRI_X:ReplicatedGamePlaylist", AttributeTypeInt)+ , ("ProjectX.GRI_X:Reservations", AttributeTypeReservation)+ , ("TAGame.Ball_Breakout_TA:AppliedDamage", AttributeTypeAppliedDamage)+ , ("TAGame.Ball_Breakout_TA:DamageIndex", AttributeTypeInt)+ , ("TAGame.Ball_Breakout_TA:LastTeamTouch", AttributeTypeByte)+ , ("TAGame.Ball_God_TA:TargetSpeed", AttributeTypeFloat)+ , ("TAGame.Ball_Haunted_TA:bIsBallBeamed", AttributeTypeBoolean)+ , ("TAGame.Ball_Haunted_TA:DeactivatedGoalIndex", AttributeTypeByte)+ , ("TAGame.Ball_Haunted_TA:LastTeamTouch", AttributeTypeByte)+ , ("TAGame.Ball_Haunted_TA:ReplicatedBeamBrokenValue", AttributeTypeByte)+ , ("TAGame.Ball_Haunted_TA:TotalActiveBeams", AttributeTypeByte)+ , ("TAGame.Ball_TA:GameEvent", AttributeTypeFlaggedInt)+ , ("TAGame.Ball_TA:HitTeamNum", AttributeTypeByte)+ , ("TAGame.Ball_TA:ReplicatedAddedCarBounceScale", AttributeTypeFloat)+ , ("TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale", AttributeTypeFloat)+ , ("TAGame.Ball_TA:ReplicatedBallScale", AttributeTypeFloat)+ , ("TAGame.Ball_TA:ReplicatedExplosionData", AttributeTypeExplosion)+ , ("TAGame.Ball_TA:ReplicatedExplosionDataExtended", AttributeTypeExtendedExplosion)+ , ("TAGame.Ball_TA:ReplicatedPhysMatOverride", AttributeTypeFlaggedInt)+ , ("TAGame.Ball_TA:ReplicatedWorldBounceScale", AttributeTypeFloat)+ , ("TAGame.BreakOutActor_Platform_TA:DamageState", AttributeTypeDamageState)+ , ("TAGame.CameraSettingsActor_TA:bMouseCameraToggleEnabled", AttributeTypeBoolean)+ , ("TAGame.CameraSettingsActor_TA:bUsingBehindView", AttributeTypeBoolean)+ , ("TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera", AttributeTypeBoolean)+ , ("TAGame.CameraSettingsActor_TA:bUsingSwivel", AttributeTypeBoolean)+ , ("TAGame.CameraSettingsActor_TA:CameraPitch", AttributeTypeByte)+ , ("TAGame.CameraSettingsActor_TA:CameraYaw", AttributeTypeByte)+ , ("TAGame.CameraSettingsActor_TA:PRI", AttributeTypeFlaggedInt)+ , ("TAGame.CameraSettingsActor_TA:ProfileSettings", AttributeTypeCamSettings)+ , ("TAGame.Car_TA:AddedBallForceMultiplier", AttributeTypeFloat)+ , ("TAGame.Car_TA:AddedCarForceMultiplier", AttributeTypeFloat)+ , ("TAGame.Car_TA:AttachedPickup", AttributeTypeFlaggedInt)+ , ("TAGame.Car_TA:ClubColors", AttributeTypeClubColors)+ , ("TAGame.Car_TA:ReplicatedDemolish_CustomFX", AttributeTypeCustomDemolish)+ , ("TAGame.Car_TA:ReplicatedDemolish", AttributeTypeDemolish)+ , ("TAGame.Car_TA:TeamPaint", AttributeTypeTeamPaint)+ , ("TAGame.CarComponent_Boost_TA:bNoBoost", AttributeTypeBoolean)+ , ("TAGame.CarComponent_Boost_TA:BoostModifier", AttributeTypeFloat)+ , ("TAGame.CarComponent_Boost_TA:bUnlimitedBoost", AttributeTypeBoolean)+ , ("TAGame.CarComponent_Boost_TA:RechargeDelay", AttributeTypeFloat)+ , ("TAGame.CarComponent_Boost_TA:RechargeRate", AttributeTypeFloat)+ , ("TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount", AttributeTypeByte)+ , ("TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount", AttributeTypeInt)+ , ("TAGame.CarComponent_Dodge_TA:DodgeTorque", AttributeTypeLocation)+ , ("TAGame.CarComponent_FlipCar_TA:bFlipRight", AttributeTypeBoolean)+ , ("TAGame.CarComponent_FlipCar_TA:FlipCarTime", AttributeTypeFloat)+ , ("TAGame.CarComponent_TA:ReplicatedActive", AttributeTypeByte)+ , ("TAGame.CarComponent_TA:ReplicatedActivityTime", AttributeTypeFloat)+ , ("TAGame.CarComponent_TA:Vehicle", AttributeTypeFlaggedInt)+ , ("TAGame.CrowdActor_TA:GameEvent", AttributeTypeFlaggedInt)+ , ("TAGame.CrowdActor_TA:ModifiedNoise", AttributeTypeFloat)+ , ("TAGame.CrowdActor_TA:ReplicatedCountDownNumber", AttributeTypeInt)+ , ("TAGame.CrowdActor_TA:ReplicatedOneShotSound", AttributeTypeFlaggedInt)+ , ("TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber", AttributeTypeInt)+ , ("TAGame.CrowdManager_TA:GameEvent", AttributeTypeFlaggedInt)+ , ("TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound", AttributeTypeFlaggedInt)+ , ("TAGame.GameEvent_Soccar_TA:bBallHasBeenHit", AttributeTypeBoolean)+ , ("TAGame.GameEvent_Soccar_TA:bClubMatch", AttributeTypeBoolean)+ , ("TAGame.GameEvent_Soccar_TA:bOverTime", AttributeTypeBoolean)+ , ("TAGame.GameEvent_Soccar_TA:bUnlimitedTime", AttributeTypeBoolean)+ , ("TAGame.GameEvent_Soccar_TA:GameTime", AttributeTypeInt)+ , ("TAGame.GameEvent_Soccar_TA:MaxScore", AttributeTypeInt)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger", AttributeTypeMusicStinger)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam", AttributeTypeByte)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedServerPerformanceState", AttributeTypeByte)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedStatEvent", AttributeTypeStatEvent)+ , ("TAGame.GameEvent_Soccar_TA:RoundNum", AttributeTypeInt)+ , ("TAGame.GameEvent_Soccar_TA:SecondsRemaining", AttributeTypeInt)+ , ("TAGame.GameEvent_Soccar_TA:SeriesLength", AttributeTypeInt)+ , ("TAGame.GameEvent_Soccar_TA:SubRulesArchetype", AttributeTypeFlaggedInt)+ , ("TAGame.GameEvent_SoccarPrivate_TA:MatchSettings", AttributeTypePrivateMatchSettings)+ , ("TAGame.GameEvent_TA:bCanVoteToForfeit", AttributeTypeBoolean)+ , ("TAGame.GameEvent_TA:bHasLeaveMatchPenalty", AttributeTypeBoolean)+ , ("TAGame.GameEvent_TA:BotSkill", AttributeTypeInt)+ , ("TAGame.GameEvent_TA:GameMode", AttributeTypeGameMode)+ , ("TAGame.GameEvent_TA:MatchTypeClass", AttributeTypeFlaggedInt)+ , ("TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining", AttributeTypeInt)+ , ("TAGame.GameEvent_TA:ReplicatedRoundCountDownNumber", AttributeTypeInt)+ , ("TAGame.GameEvent_TA:ReplicatedStateIndex", AttributeTypeByte)+ , ("TAGame.GameEvent_TA:ReplicatedStateName", AttributeTypeInt)+ , ("TAGame.GameEvent_Team_TA:bForfeit", AttributeTypeBoolean)+ , ("TAGame.GameEvent_Team_TA:MaxTeamSize", AttributeTypeInt)+ , ("TAGame.GRI_TA:NewDedicatedServerIP", AttributeTypeString)+ , ("TAGame.MaxTimeWarningData_TA:EndGameEpochTime", AttributeTypeInt64)+ , ("TAGame.MaxTimeWarningData_TA:EndGameWarningEpochTime", AttributeTypeInt64)+ , ("TAGame.PRI_TA:bIsDistracted", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bIsInSplitScreen", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bMatchMVP", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bOnlineLoadoutSet", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bOnlineLoadoutsSet", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:BotProductName", AttributeTypeInt)+ , ("TAGame.PRI_TA:bReady", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bUsingBehindView", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bUsingItems", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:bUsingSecondaryCamera", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:CameraPitch", AttributeTypeByte)+ , ("TAGame.PRI_TA:CameraSettings", AttributeTypeCamSettings)+ , ("TAGame.PRI_TA:CameraYaw", AttributeTypeByte)+ , ("TAGame.PRI_TA:ClientLoadout", AttributeTypeLoadout)+ , ("TAGame.PRI_TA:ClientLoadoutOnline", AttributeTypeLoadoutOnline)+ , ("TAGame.PRI_TA:ClientLoadouts", AttributeTypeLoadouts)+ , ("TAGame.PRI_TA:ClientLoadoutsOnline", AttributeTypeLoadoutsOnline)+ , ("TAGame.PRI_TA:ClubID", AttributeTypeInt64)+ , ("TAGame.PRI_TA:MatchAssists", AttributeTypeInt)+ , ("TAGame.PRI_TA:MatchBreakoutDamage", AttributeTypeInt)+ , ("TAGame.PRI_TA:MatchGoals", AttributeTypeInt)+ , ("TAGame.PRI_TA:MatchSaves", AttributeTypeInt)+ , ("TAGame.PRI_TA:MatchScore", AttributeTypeInt)+ , ("TAGame.PRI_TA:MatchShots", AttributeTypeInt)+ , ("TAGame.PRI_TA:MaxTimeTillItem", AttributeTypeInt)+ , ("TAGame.PRI_TA:PartyLeader", AttributeTypePartyLeader)+ , ("TAGame.PRI_TA:PawnType", AttributeTypeByte)+ , ("TAGame.PRI_TA:PersistentCamera", AttributeTypeFlaggedInt)+ , ("TAGame.PRI_TA:PlayerHistoryKey", AttributeTypePlayerHistoryKey)+ , ("TAGame.PRI_TA:PlayerHistoryValid", AttributeTypeBoolean)+ , ("TAGame.PRI_TA:PrimaryTitle", AttributeTypeTitle)+ , ("TAGame.PRI_TA:ReplicatedGameEvent", AttributeTypeFlaggedInt)+ , ("TAGame.PRI_TA:ReplicatedWorstNetQualityBeyondLatency", AttributeTypeByte)+ , ("TAGame.PRI_TA:SecondaryTitle", AttributeTypeTitle)+ , ("TAGame.PRI_TA:SkillTier", AttributeTypeFlaggedByte)+ , ("TAGame.PRI_TA:SpectatorShortcut", AttributeTypeInt)+ , ("TAGame.PRI_TA:SteeringSensitivity", AttributeTypeFloat)+ , ("TAGame.PRI_TA:TimeTillItem", AttributeTypeInt)+ , ("TAGame.PRI_TA:Title", AttributeTypeInt)+ , ("TAGame.PRI_TA:TotalXP", AttributeTypeInt)+ , ("TAGame.RBActor_TA:bFrozen", AttributeTypeBoolean)+ , ("TAGame.RBActor_TA:bIgnoreSyncing", AttributeTypeBoolean)+ , ("TAGame.RBActor_TA:bReplayActor", AttributeTypeBoolean)+ , ("TAGame.RBActor_TA:ReplicatedRBState", AttributeTypeRigidBodyState)+ , ("TAGame.RBActor_TA:WeldedInfo", AttributeTypeWeldedInfo)+ , ("TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed", AttributeTypeFloat)+ , ("TAGame.SpecialPickup_BallVelcro_TA:AttachTime", AttributeTypeFloat)+ , ("TAGame.SpecialPickup_BallVelcro_TA:bBroken", AttributeTypeBoolean)+ , ("TAGame.SpecialPickup_BallVelcro_TA:bHit", AttributeTypeBoolean)+ , ("TAGame.SpecialPickup_BallVelcro_TA:BreakTime", AttributeTypeFloat)+ , ("TAGame.SpecialPickup_Rugby_TA:bBallWelded", AttributeTypeBoolean)+ , ("TAGame.SpecialPickup_Targeted_TA:Targeted", AttributeTypeFlaggedInt)+ , ("TAGame.Team_Soccar_TA:GameScore", AttributeTypeInt)+ , ("TAGame.Team_TA:ClubColors", AttributeTypeClubColors)+ , ("TAGame.Team_TA:ClubID", AttributeTypeInt64)+ , ("TAGame.Team_TA:CustomTeamName", AttributeTypeString)+ , ("TAGame.Team_TA:Difficulty", AttributeTypeInt)+ , ("TAGame.Team_TA:GameEvent", AttributeTypeFlaggedInt)+ , ("TAGame.Team_TA:LogoData", AttributeTypeFlaggedInt)+ , ("TAGame.Vehicle_TA:bDriving", AttributeTypeBoolean)+ , ("TAGame.Vehicle_TA:bReplicatedHandbrake", AttributeTypeBoolean)+ , ("TAGame.Vehicle_TA:ReplicatedSteer", AttributeTypeByte)+ , ("TAGame.Vehicle_TA:ReplicatedThrottle", AttributeTypeByte)+ , ("TAGame.VehiclePickup_TA:bNoPickup", AttributeTypeBoolean)+ , ("TAGame.VehiclePickup_TA:NewReplicatedPickupData", AttributeTypePickupNew)+ , ("TAGame.VehiclePickup_TA:ReplicatedPickupData", AttributeTypePickup)+ ]++rawCrc32Table :: Integral a => [a]+rawCrc32Table =+ [ 0x00000000+ , 0x04c11db7+ , 0x09823b6e+ , 0x0d4326d9+ , 0x130476dc+ , 0x17c56b6b+ , 0x1a864db2+ , 0x1e475005+ , 0x2608edb8+ , 0x22c9f00f+ , 0x2f8ad6d6+ , 0x2b4bcb61+ , 0x350c9b64+ , 0x31cd86d3+ , 0x3c8ea00a+ , 0x384fbdbd+ , 0x4c11db70+ , 0x48d0c6c7+ , 0x4593e01e+ , 0x4152fda9+ , 0x5f15adac+ , 0x5bd4b01b+ , 0x569796c2+ , 0x52568b75+ , 0x6a1936c8+ , 0x6ed82b7f+ , 0x639b0da6+ , 0x675a1011+ , 0x791d4014+ , 0x7ddc5da3+ , 0x709f7b7a+ , 0x745e66cd+ , 0x9823b6e0+ , 0x9ce2ab57+ , 0x91a18d8e+ , 0x95609039+ , 0x8b27c03c+ , 0x8fe6dd8b+ , 0x82a5fb52+ , 0x8664e6e5+ , 0xbe2b5b58+ , 0xbaea46ef+ , 0xb7a96036+ , 0xb3687d81+ , 0xad2f2d84+ , 0xa9ee3033+ , 0xa4ad16ea+ , 0xa06c0b5d+ , 0xd4326d90+ , 0xd0f37027+ , 0xddb056fe+ , 0xd9714b49+ , 0xc7361b4c+ , 0xc3f706fb+ , 0xceb42022+ , 0xca753d95+ , 0xf23a8028+ , 0xf6fb9d9f+ , 0xfbb8bb46+ , 0xff79a6f1+ , 0xe13ef6f4+ , 0xe5ffeb43+ , 0xe8bccd9a+ , 0xec7dd02d+ , 0x34867077+ , 0x30476dc0+ , 0x3d044b19+ , 0x39c556ae+ , 0x278206ab+ , 0x23431b1c+ , 0x2e003dc5+ , 0x2ac12072+ , 0x128e9dcf+ , 0x164f8078+ , 0x1b0ca6a1+ , 0x1fcdbb16+ , 0x018aeb13+ , 0x054bf6a4+ , 0x0808d07d+ , 0x0cc9cdca+ , 0x7897ab07+ , 0x7c56b6b0+ , 0x71159069+ , 0x75d48dde+ , 0x6b93dddb+ , 0x6f52c06c+ , 0x6211e6b5+ , 0x66d0fb02+ , 0x5e9f46bf+ , 0x5a5e5b08+ , 0x571d7dd1+ , 0x53dc6066+ , 0x4d9b3063+ , 0x495a2dd4+ , 0x44190b0d+ , 0x40d816ba+ , 0xaca5c697+ , 0xa864db20+ , 0xa527fdf9+ , 0xa1e6e04e+ , 0xbfa1b04b+ , 0xbb60adfc+ , 0xb6238b25+ , 0xb2e29692+ , 0x8aad2b2f+ , 0x8e6c3698+ , 0x832f1041+ , 0x87ee0df6+ , 0x99a95df3+ , 0x9d684044+ , 0x902b669d+ , 0x94ea7b2a+ , 0xe0b41de7+ , 0xe4750050+ , 0xe9362689+ , 0xedf73b3e+ , 0xf3b06b3b+ , 0xf771768c+ , 0xfa325055+ , 0xfef34de2+ , 0xc6bcf05f+ , 0xc27dede8+ , 0xcf3ecb31+ , 0xcbffd686+ , 0xd5b88683+ , 0xd1799b34+ , 0xdc3abded+ , 0xd8fba05a+ , 0x690ce0ee+ , 0x6dcdfd59+ , 0x608edb80+ , 0x644fc637+ , 0x7a089632+ , 0x7ec98b85+ , 0x738aad5c+ , 0x774bb0eb+ , 0x4f040d56+ , 0x4bc510e1+ , 0x46863638+ , 0x42472b8f+ , 0x5c007b8a+ , 0x58c1663d+ , 0x558240e4+ , 0x51435d53+ , 0x251d3b9e+ , 0x21dc2629+ , 0x2c9f00f0+ , 0x285e1d47+ , 0x36194d42+ , 0x32d850f5+ , 0x3f9b762c+ , 0x3b5a6b9b+ , 0x0315d626+ , 0x07d4cb91+ , 0x0a97ed48+ , 0x0e56f0ff+ , 0x1011a0fa+ , 0x14d0bd4d+ , 0x19939b94+ , 0x1d528623+ , 0xf12f560e+ , 0xf5ee4bb9+ , 0xf8ad6d60+ , 0xfc6c70d7+ , 0xe22b20d2+ , 0xe6ea3d65+ , 0xeba91bbc+ , 0xef68060b+ , 0xd727bbb6+ , 0xd3e6a601+ , 0xdea580d8+ , 0xda649d6f+ , 0xc423cd6a+ , 0xc0e2d0dd+ , 0xcda1f604+ , 0xc960ebb3+ , 0xbd3e8d7e+ , 0xb9ff90c9+ , 0xb4bcb610+ , 0xb07daba7+ , 0xae3afba2+ , 0xaafbe615+ , 0xa7b8c0cc+ , 0xa379dd7b+ , 0x9b3660c6+ , 0x9ff77d71+ , 0x92b45ba8+ , 0x9675461f+ , 0x8832161a+ , 0x8cf30bad+ , 0x81b02d74+ , 0x857130c3+ , 0x5d8a9099+ , 0x594b8d2e+ , 0x5408abf7+ , 0x50c9b640+ , 0x4e8ee645+ , 0x4a4ffbf2+ , 0x470cdd2b+ , 0x43cdc09c+ , 0x7b827d21+ , 0x7f436096+ , 0x7200464f+ , 0x76c15bf8+ , 0x68860bfd+ , 0x6c47164a+ , 0x61043093+ , 0x65c52d24+ , 0x119b4be9+ , 0x155a565e+ , 0x18197087+ , 0x1cd86d30+ , 0x029f3d35+ , 0x065e2082+ , 0x0b1d065b+ , 0x0fdc1bec+ , 0x3793a651+ , 0x3352bbe6+ , 0x3e119d3f+ , 0x3ad08088+ , 0x2497d08d+ , 0x2056cd3a+ , 0x2d15ebe3+ , 0x29d4f654+ , 0xc5a92679+ , 0xc1683bce+ , 0xcc2b1d17+ , 0xc8ea00a0+ , 0xd6ad50a5+ , 0xd26c4d12+ , 0xdf2f6bcb+ , 0xdbee767c+ , 0xe3a1cbc1+ , 0xe760d676+ , 0xea23f0af+ , 0xeee2ed18+ , 0xf0a5bd1d+ , 0xf464a0aa+ , 0xf9278673+ , 0xfde69bc4+ , 0x89b8fd09+ , 0x8d79e0be+ , 0x803ac667+ , 0x84fbdbd0+ , 0x9abc8bd5+ , 0x9e7d9662+ , 0x933eb0bb+ , 0x97ffad0c+ , 0xafb010b1+ , 0xab710d06+ , 0xa6322bdf+ , 0xa2f33668+ , 0xbcb4666d+ , 0xb8757bda+ , 0xb5365d03+ , 0xb1f740b4+ ]
@@ -0,0 +1,19 @@+module Rattletrap.Decode.AppliedDamageAttribute+ ( decodeAppliedDamageAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Decode.Vector+import Rattletrap.Decode.Word8le+import Rattletrap.Type.AppliedDamageAttribute++decodeAppliedDamageAttributeBits+ :: (Int, Int, Int) -> DecodeBits AppliedDamageAttribute+decodeAppliedDamageAttributeBits version =+ AppliedDamageAttribute+ <$> decodeWord8leBits+ <*> decodeVectorBits version+ <*> decodeInt32leBits+ <*> decodeInt32leBits
@@ -0,0 +1,73 @@+module Rattletrap.Decode.Attribute+ ( decodeAttributesBits+ )+where++import Rattletrap.Decode.AttributeValue+import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Type.Attribute+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.Common+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le++decodeAttributesBits+ :: (Int, Int, Int)+ -> ClassAttributeMap+ -> Map CompressedWord Word32le+ -> CompressedWord+ -> DecodeBits [Attribute]+decodeAttributesBits version classes actors actor = do+ hasAttribute <- getBool+ if hasAttribute+ then+ (:)+ <$> decodeAttributeBits version classes actors actor+ <*> decodeAttributesBits version classes actors actor+ else pure []++decodeAttributeBits+ :: (Int, Int, Int)+ -> ClassAttributeMap+ -> Map CompressedWord Word32le+ -> CompressedWord+ -> DecodeBits Attribute+decodeAttributeBits version classes actors actor = do+ attributes <- lookupAttributeMap classes actors actor+ limit <- lookupAttributeIdLimit attributes actor+ attribute <- decodeCompressedWordBits limit+ name <- lookupAttributeName classes attributes attribute+ Attribute attribute name+ <$> decodeAttributeValueBits+ version+ (classAttributeMapObjectMap classes)+ name++lookupAttributeMap+ :: ClassAttributeMap+ -> Map CompressedWord Word32le+ -> CompressedWord+ -> DecodeBits (Map Word32le Word32le)+lookupAttributeMap classes actors actor = fromMaybe+ ("[RT01] could not get attribute map for " <> show actor)+ (getAttributeMap classes actors actor)++lookupAttributeIdLimit+ :: Map Word32le Word32le -> CompressedWord -> DecodeBits Word+lookupAttributeIdLimit attributes actor = fromMaybe+ ("[RT02] could not get attribute ID limit for " <> show actor)+ (getAttributeIdLimit attributes)++lookupAttributeName+ :: ClassAttributeMap+ -> Map Word32le Word32le+ -> CompressedWord+ -> DecodeBits Str+lookupAttributeName classes attributes attribute = fromMaybe+ ("[RT03] could not get attribute name for " <> show attribute)+ (getAttributeName classes attributes attribute)++fromMaybe :: String -> Maybe a -> DecodeBits a+fromMaybe message = maybe (fail message) pure
@@ -0,0 +1,12 @@+module Rattletrap.Decode.AttributeMapping+ ( decodeAttributeMapping+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Type.AttributeMapping++decodeAttributeMapping :: Decode AttributeMapping+decodeAttributeMapping =+ AttributeMapping <$> decodeWord32le <*> decodeWord32le
@@ -0,0 +1,131 @@+module Rattletrap.Decode.AttributeValue+ ( decodeAttributeValueBits+ )+where++import Rattletrap.Data+import Rattletrap.Decode.AppliedDamageAttribute+import Rattletrap.Decode.BooleanAttribute+import Rattletrap.Decode.ByteAttribute+import Rattletrap.Decode.CamSettingsAttribute+import Rattletrap.Decode.ClubColorsAttribute+import Rattletrap.Decode.Common+import Rattletrap.Decode.CustomDemolishAttribute+import Rattletrap.Decode.DamageStateAttribute+import Rattletrap.Decode.DemolishAttribute+import Rattletrap.Decode.EnumAttribute+import Rattletrap.Decode.ExplosionAttribute+import Rattletrap.Decode.ExtendedExplosionAttribute+import Rattletrap.Decode.FlaggedIntAttribute+import Rattletrap.Decode.FlaggedByteAttribute+import Rattletrap.Decode.FloatAttribute+import Rattletrap.Decode.GameModeAttribute+import Rattletrap.Decode.Int64Attribute+import Rattletrap.Decode.IntAttribute+import Rattletrap.Decode.LoadoutAttribute+import Rattletrap.Decode.LoadoutOnlineAttribute+import Rattletrap.Decode.LoadoutsAttribute+import Rattletrap.Decode.LoadoutsOnlineAttribute+import Rattletrap.Decode.LocationAttribute+import Rattletrap.Decode.MusicStingerAttribute+import Rattletrap.Decode.PartyLeaderAttribute+import Rattletrap.Decode.PickupAttribute+import Rattletrap.Decode.PickupAttributeNew+import Rattletrap.Decode.PlayerHistoryKeyAttribute+import Rattletrap.Decode.PrivateMatchSettingsAttribute+import Rattletrap.Decode.QWordAttribute+import Rattletrap.Decode.ReservationAttribute+import Rattletrap.Decode.RigidBodyStateAttribute+import Rattletrap.Decode.StatEventAttribute+import Rattletrap.Decode.StringAttribute+import Rattletrap.Decode.TeamPaintAttribute+import Rattletrap.Decode.TitleAttribute+import Rattletrap.Decode.UniqueIdAttribute+import Rattletrap.Decode.WeldedInfoAttribute+import Rattletrap.Type.AttributeType+import Rattletrap.Type.AttributeValue+import Rattletrap.Type.Common+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le++import qualified Data.Map as Map++decodeAttributeValueBits+ :: (Int, Int, Int) -> Map Word32le Str -> Str -> DecodeBits AttributeValue+decodeAttributeValueBits version objectMap name = do+ constructor <- maybe+ (fail ("[RT04] don't know how to get attribute value " <> show name))+ pure+ (Map.lookup name attributeTypes)+ case constructor of+ AttributeTypeAppliedDamage ->+ AttributeValueAppliedDamage <$> decodeAppliedDamageAttributeBits version+ AttributeTypeBoolean ->+ AttributeValueBoolean <$> decodeBooleanAttributeBits+ AttributeTypeByte -> AttributeValueByte <$> decodeByteAttributeBits+ AttributeTypeCamSettings ->+ AttributeValueCamSettings <$> decodeCamSettingsAttributeBits version+ AttributeTypeClubColors ->+ AttributeValueClubColors <$> decodeClubColorsAttributeBits+ AttributeTypeCustomDemolish ->+ AttributeValueCustomDemolish <$> decodeCustomDemolishAttributeBits version+ AttributeTypeDamageState ->+ AttributeValueDamageState <$> decodeDamageStateAttributeBits version+ AttributeTypeDemolish ->+ AttributeValueDemolish <$> decodeDemolishAttributeBits version+ AttributeTypeEnum -> AttributeValueEnum <$> decodeEnumAttributeBits+ AttributeTypeExplosion ->+ AttributeValueExplosion <$> decodeExplosionAttributeBits version+ AttributeTypeExtendedExplosion -> AttributeValueExtendedExplosion+ <$> decodeExtendedExplosionAttributeBits version+ AttributeTypeFlaggedInt ->+ AttributeValueFlaggedInt <$> decodeFlaggedIntAttributeBits+ AttributeTypeFlaggedByte ->+ AttributeValueFlaggedByte <$> decodeFlaggedByteAttributeBits+ AttributeTypeFloat -> AttributeValueFloat <$> decodeFloatAttributeBits+ AttributeTypeGameMode ->+ AttributeValueGameMode <$> decodeGameModeAttributeBits version+ AttributeTypeInt -> AttributeValueInt <$> decodeIntAttributeBits+ AttributeTypeInt64 -> AttributeValueInt64 <$> decodeInt64AttributeBits+ AttributeTypeLoadout ->+ AttributeValueLoadout <$> decodeLoadoutAttributeBits+ AttributeTypeLoadoutOnline ->+ AttributeValueLoadoutOnline+ <$> decodeLoadoutOnlineAttributeBits version objectMap+ AttributeTypeLoadouts ->+ AttributeValueLoadouts <$> decodeLoadoutsAttributeBits+ AttributeTypeLoadoutsOnline ->+ AttributeValueLoadoutsOnline+ <$> decodeLoadoutsOnlineAttributeBits version objectMap+ AttributeTypeLocation ->+ AttributeValueLocation <$> decodeLocationAttributeBits version+ AttributeTypeMusicStinger ->+ AttributeValueMusicStinger <$> decodeMusicStingerAttributeBits+ AttributeTypePartyLeader ->+ AttributeValuePartyLeader <$> decodePartyLeaderAttributeBits version+ AttributeTypePickup -> AttributeValuePickup <$> decodePickupAttributeBits+ AttributeTypePickupNew ->+ AttributeValuePickupNew <$> decodePickupAttributeNewBits+ AttributeTypePlayerHistoryKey ->+ AttributeValuePlayerHistoryKey <$> decodePlayerHistoryKeyAttributeBits+ AttributeTypePrivateMatchSettings ->+ AttributeValuePrivateMatchSettings+ <$> decodePrivateMatchSettingsAttributeBits+ AttributeTypeQWord -> AttributeValueQWord <$> decodeQWordAttributeBits+ AttributeTypeReservation ->+ AttributeValueReservation <$> decodeReservationAttributeBits version+ AttributeTypeRigidBodyState -> AttributeValueRigidBodyState+ <$> decodeRigidBodyStateAttributeBits version+ AttributeTypeStatEvent ->+ AttributeValueStatEvent <$> decodeStatEventAttributeBits+ AttributeTypeString -> AttributeValueString <$> decodeStringAttributeBits+ AttributeTypeTeamPaint ->+ AttributeValueTeamPaint <$> decodeTeamPaintAttributeBits+ AttributeTypeTitle -> AttributeValueTitle <$> decodeTitleAttributeBits+ AttributeTypeUniqueId ->+ AttributeValueUniqueId <$> decodeUniqueIdAttributeBits version+ AttributeTypeWeldedInfo ->+ AttributeValueWeldedInfo <$> decodeWeldedInfoAttributeBits version++attributeTypes :: Map Str AttributeType+attributeTypes = Map.mapKeys toStr (Map.fromList rawAttributeTypes)
@@ -0,0 +1,10 @@+module Rattletrap.Decode.BooleanAttribute+ ( decodeBooleanAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.BooleanAttribute++decodeBooleanAttributeBits :: DecodeBits BooleanAttribute+decodeBooleanAttributeBits = BooleanAttribute <$> getBool
@@ -0,0 +1,11 @@+module Rattletrap.Decode.ByteAttribute+ ( decodeByteAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word8le+import Rattletrap.Type.ByteAttribute++decodeByteAttributeBits :: DecodeBits ByteAttribute+decodeByteAttributeBits = ByteAttribute <$> decodeWord8leBits
@@ -0,0 +1,18 @@+module Rattletrap.Decode.Cache+ ( decodeCache+ )+where++import Rattletrap.Decode.AttributeMapping+import Rattletrap.Decode.Common+import Rattletrap.Decode.List+import Rattletrap.Decode.Word32le+import Rattletrap.Type.Cache++decodeCache :: Decode Cache+decodeCache =+ Cache+ <$> decodeWord32le+ <*> decodeWord32le+ <*> decodeWord32le+ <*> decodeList decodeAttributeMapping
@@ -0,0 +1,20 @@+module Rattletrap.Decode.CamSettingsAttribute+ ( decodeCamSettingsAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Float32le+import Rattletrap.Type.CamSettingsAttribute++decodeCamSettingsAttributeBits+ :: (Int, Int, Int) -> DecodeBits CamSettingsAttribute+decodeCamSettingsAttributeBits version =+ CamSettingsAttribute+ <$> decodeFloat32leBits+ <*> decodeFloat32leBits+ <*> decodeFloat32leBits+ <*> decodeFloat32leBits+ <*> decodeFloat32leBits+ <*> decodeFloat32leBits+ <*> decodeWhen (version >= (868, 20, 0)) decodeFloat32leBits
@@ -0,0 +1,12 @@+module Rattletrap.Decode.ClassMapping+ ( decodeClassMapping+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word32le+import Rattletrap.Type.ClassMapping++decodeClassMapping :: Decode ClassMapping+decodeClassMapping = ClassMapping <$> decodeStr <*> decodeWord32le
@@ -0,0 +1,16 @@+module Rattletrap.Decode.ClubColorsAttribute+ ( decodeClubColorsAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word8le+import Rattletrap.Type.ClubColorsAttribute++decodeClubColorsAttributeBits :: DecodeBits ClubColorsAttribute+decodeClubColorsAttributeBits =+ ClubColorsAttribute+ <$> getBool+ <*> decodeWord8leBits+ <*> getBool+ <*> decodeWord8leBits
@@ -0,0 +1,70 @@+module Rattletrap.Decode.Common+ ( Decode+ , DecodeBits+ , decodeWhen+ , getBitsLE+ , getByteStringBits+ , getWord8Bits+ , runDecode+ , runDecodeBits+ , toBits+ , Binary.getFloatle+ , Binary.getByteString+ , Binary.getInt8+ , Binary.getInt32le+ , Binary.getInt64le+ , Binary.getWord8+ , Binary.getWord32le+ , Binary.getWord64le+ , BinaryBits.getBool+ )+where++import qualified Control.Applicative as Applicative+import qualified Control.Monad as Monad+import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Get as BinaryBits+import qualified Data.Binary.Get as Binary+import qualified Data.Bits as Bits+import qualified Data.ByteString as Bytes+import qualified Data.ByteString.Lazy as LazyBytes+import qualified Data.Word as Word+import qualified Rattletrap.Utility.Bytes as Utility++type Decode = Binary.Get++type DecodeBits = BinaryBits.BitGet++decodeWhen+ :: (Applicative m, Applicative.Alternative f) => Bool -> m a -> m (f a)+decodeWhen p f = if p then fmap pure f else pure Applicative.empty++getByteStringBits :: Int -> DecodeBits Bytes.ByteString+getByteStringBits = BinaryBits.getByteString++getWord8Bits :: Int -> DecodeBits Word.Word8+getWord8Bits = BinaryBits.getWord8++runDecode :: Decode a -> Bytes.ByteString -> Either String a+runDecode decode bytes =+ case Binary.runGetOrFail decode (LazyBytes.fromStrict bytes) of+ Left (_, _, x) -> Left x+ Right (_, _, x) -> Right x++runDecodeBits :: DecodeBits a -> Bytes.ByteString -> Either String a+runDecodeBits = runDecode . BinaryBits.runBitGet++toBits :: Decode a -> Int -> DecodeBits a+toBits decode size = do+ bytes <- BinaryBits.getByteString size+ case runDecode decode (Utility.reverseBytes bytes) of+ Left problem -> fail problem+ Right result -> pure result++getBitsLE :: Bits.Bits a => Int -> BinaryBits.BitGet a+getBitsLE size = do+ bits <- Monad.replicateM size BinaryBits.getBool+ pure $ foldr+ (\bit x -> let y = Bits.shiftL x 1 in if bit then Bits.setBit y 0 else y)+ Bits.zeroBits+ bits
@@ -0,0 +1,30 @@+module Rattletrap.Decode.CompressedWord+ ( decodeCompressedWordBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.CompressedWord++import qualified Data.Bits as Bits++decodeCompressedWordBits :: Word -> DecodeBits CompressedWord+decodeCompressedWordBits limit =+ CompressedWord limit <$> step limit (getMaxBits limit) 0 0++getMaxBits :: Word -> Word+getMaxBits x = do+ let+ n :: Word+ n = max 1 (ceiling (logBase (2 :: Double) (fromIntegral (max 1 x))))+ if x < 1024 && x == 2 ^ n then n + 1 else n++step :: Word -> Word -> Word -> Word -> DecodeBits Word+step limit maxBits position value = do+ let x = Bits.shiftL 1 (fromIntegral position) :: Word+ if position < maxBits && value + x <= limit+ then do+ bit <- getBool+ let newValue = if bit then value + x else value+ step limit maxBits (position + 1) newValue+ else pure value
@@ -0,0 +1,18 @@+module Rattletrap.Decode.CompressedWordVector+ ( decodeCompressedWordVectorBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Type.CompressedWordVector++decodeCompressedWordVectorBits :: DecodeBits CompressedWordVector+decodeCompressedWordVectorBits =+ CompressedWordVector+ <$> decodeCompressedWordBits limit+ <*> decodeCompressedWordBits limit+ <*> decodeCompressedWordBits limit++limit :: Word+limit = 65536
@@ -0,0 +1,71 @@+module Rattletrap.Decode.Content+ ( decodeContent+ )+where++import Rattletrap.Decode.Cache+import Rattletrap.Decode.ClassMapping+import Rattletrap.Decode.Common+import Rattletrap.Decode.Frame+import Rattletrap.Decode.KeyFrame+import Rattletrap.Decode.List+import Rattletrap.Decode.Mark+import Rattletrap.Decode.Message+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word32le+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.Content+import Rattletrap.Type.Word32le+import Rattletrap.Utility.Bytes++import qualified Control.Monad.Trans.State as State+import qualified Data.Binary.Get as Binary+import qualified Data.ByteString.Lazy as LazyBytes++decodeContent+ :: (Int, Int, Int)+ -- ^ Version numbers, usually from 'Rattletrap.Header.getVersion'.+ -> Int+ -- ^ The number of frames in the stream, usually from+ -- 'Rattletrap.Header.getNumFrames'.+ -> Word+ -- ^ The maximum number of channels in the stream, usually from+ -- 'Rattletrap.Header.getMaxChannels'.+ -> Decode Content+decodeContent version numFrames maxChannels = do+ (levels, keyFrames, streamSize) <-+ (,,)+ <$> decodeList decodeStr+ <*> decodeList decodeKeyFrame+ <*> decodeWord32le+ (stream, messages, marks, packages, objects, names, classMappings, caches) <-+ (,,,,,,,)+ <$> getByteString (fromIntegral (word32leValue streamSize))+ <*> decodeList decodeMessage+ <*> decodeList decodeMark+ <*> decodeList decodeStr+ <*> decodeList decodeStr+ <*> decodeList decodeStr+ <*> decodeList decodeClassMapping+ <*> decodeList decodeCache+ let+ classAttributeMap =+ makeClassAttributeMap objects classMappings caches names+ bitGet = State.evalStateT+ (decodeFramesBits version numFrames maxChannels classAttributeMap)+ mempty+ frames <- either fail pure (runDecodeBits bitGet (reverseBytes stream))+ Content+ levels+ keyFrames+ streamSize+ frames+ messages+ marks+ packages+ objects+ names+ classMappings+ caches+ . LazyBytes.unpack+ <$> Binary.getRemainingLazyByteString
@@ -0,0 +1,16 @@+module Rattletrap.Decode.CustomDemolishAttribute+ ( decodeCustomDemolishAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.DemolishAttribute+import Rattletrap.Decode.Int32le+import Rattletrap.Type.CustomDemolishAttribute++decodeCustomDemolishAttributeBits :: (Int, Int, Int) -> DecodeBits CustomDemolishAttribute+decodeCustomDemolishAttributeBits version =+ CustomDemolishAttribute+ <$> getBool+ <*> decodeInt32leBits+ <*> decodeDemolishAttributeBits version
@@ -0,0 +1,21 @@+module Rattletrap.Decode.DamageStateAttribute+ ( decodeDamageStateAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Decode.Vector+import Rattletrap.Decode.Word8le+import Rattletrap.Type.DamageStateAttribute++decodeDamageStateAttributeBits+ :: (Int, Int, Int) -> DecodeBits DamageStateAttribute+decodeDamageStateAttributeBits version =+ DamageStateAttribute+ <$> decodeWord8leBits+ <*> getBool+ <*> decodeInt32leBits+ <*> decodeVectorBits version+ <*> getBool+ <*> getBool
@@ -0,0 +1,19 @@+module Rattletrap.Decode.DemolishAttribute+ ( decodeDemolishAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Vector+import Rattletrap.Decode.Word32le+import Rattletrap.Type.DemolishAttribute++decodeDemolishAttributeBits :: (Int, Int, Int) -> DecodeBits DemolishAttribute+decodeDemolishAttributeBits version =+ DemolishAttribute+ <$> getBool+ <*> decodeWord32leBits+ <*> getBool+ <*> decodeWord32leBits+ <*> decodeVectorBits version+ <*> decodeVectorBits version
@@ -0,0 +1,10 @@+module Rattletrap.Decode.DestroyedReplication+ ( decodeDestroyedReplicationBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.DestroyedReplication++decodeDestroyedReplicationBits :: DecodeBits DestroyedReplication+decodeDestroyedReplicationBits = pure DestroyedReplication
@@ -0,0 +1,17 @@+module Rattletrap.Decode.Dictionary+ ( decodeDictionary+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Type.Dictionary+import Rattletrap.Type.Str++decodeDictionary :: Decode a -> Decode (Dictionary a)+decodeDictionary decodeValue = do+ key <- decodeStr+ case filter (/= '\x00') (fromStr key) of+ "None" -> pure (DictionaryEnd key)+ _ ->+ DictionaryElement key <$> decodeValue <*> decodeDictionary decodeValue
@@ -0,0 +1,10 @@+module Rattletrap.Decode.EnumAttribute+ ( decodeEnumAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.EnumAttribute++decodeEnumAttributeBits :: DecodeBits EnumAttribute+decodeEnumAttributeBits = EnumAttribute <$> getBitsLE 11
@@ -0,0 +1,17 @@+module Rattletrap.Decode.ExplosionAttribute+ ( decodeExplosionAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Decode.Vector+import Rattletrap.Type.ExplosionAttribute++decodeExplosionAttributeBits+ :: (Int, Int, Int) -> DecodeBits ExplosionAttribute+decodeExplosionAttributeBits version =+ ExplosionAttribute+ <$> getBool+ <*> decodeInt32leBits+ <*> decodeVectorBits version
@@ -0,0 +1,16 @@+module Rattletrap.Decode.ExtendedExplosionAttribute+ ( decodeExtendedExplosionAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.ExplosionAttribute+import Rattletrap.Decode.FlaggedIntAttribute+import Rattletrap.Type.ExtendedExplosionAttribute++decodeExtendedExplosionAttributeBits+ :: (Int, Int, Int) -> DecodeBits ExtendedExplosionAttribute+decodeExtendedExplosionAttributeBits version =+ ExtendedExplosionAttribute+ <$> decodeExplosionAttributeBits version+ <*> decodeFlaggedIntAttributeBits
@@ -0,0 +1,13 @@+module Rattletrap.Decode.FlaggedByteAttribute+ ( decodeFlaggedByteAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word8le+import Rattletrap.Type.FlaggedByteAttribute+++decodeFlaggedByteAttributeBits :: DecodeBits FlaggedByteAttribute+decodeFlaggedByteAttributeBits =+ FlaggedByteAttribute <$> getBool <*> decodeWord8leBits
@@ -0,0 +1,12 @@+module Rattletrap.Decode.FlaggedIntAttribute+ ( decodeFlaggedIntAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Type.FlaggedIntAttribute++decodeFlaggedIntAttributeBits :: DecodeBits FlaggedIntAttribute+decodeFlaggedIntAttributeBits =+ FlaggedIntAttribute <$> getBool <*> decodeInt32leBits
@@ -0,0 +1,14 @@+module Rattletrap.Decode.Float32le+ ( decodeFloat32le+ , decodeFloat32leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Float32le++decodeFloat32le :: Decode Float32le+decodeFloat32le = Float32le <$> getFloatle++decodeFloat32leBits :: DecodeBits Float32le+decodeFloat32leBits = toBits decodeFloat32le 4
@@ -0,0 +1,11 @@+module Rattletrap.Decode.FloatAttribute+ ( decodeFloatAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Float32le+import Rattletrap.Type.FloatAttribute++decodeFloatAttributeBits :: DecodeBits FloatAttribute+decodeFloatAttributeBits = FloatAttribute <$> decodeFloat32leBits
@@ -0,0 +1,43 @@+module Rattletrap.Decode.Frame+ ( decodeFramesBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Float32le+import Rattletrap.Decode.Replication+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Frame+import Rattletrap.Type.Word32le++import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map++decodeFramesBits+ :: (Int, Int, Int)+ -> Int+ -> Word+ -> ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord Word32le)+ DecodeBits+ [Frame]+decodeFramesBits version count limit classes = if count <= 0+ then pure []+ else+ (:)+ <$> decodeFrameBits version limit classes+ <*> decodeFramesBits version (count - 1) limit classes++decodeFrameBits+ :: (Int, Int, Int)+ -> Word+ -> ClassAttributeMap+ -> State.StateT (Map.Map CompressedWord Word32le) DecodeBits Frame+decodeFrameBits version limit classes =+ Frame+ <$> Trans.lift decodeFloat32leBits+ <*> Trans.lift decodeFloat32leBits+ <*> decodeReplicationsBits version limit classes
@@ -0,0 +1,15 @@+module Rattletrap.Decode.GameModeAttribute+ ( decodeGameModeAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.GameModeAttribute++decodeGameModeAttributeBits :: (Int, Int, Int) -> DecodeBits GameModeAttribute+decodeGameModeAttributeBits version =+ GameModeAttribute <$> pure (numBits version) <*> getWord8Bits+ (numBits version)++numBits :: (Int, Int, Int) -> Int+numBits version = if version >= (868, 12, 0) then 8 else 2
@@ -0,0 +1,22 @@+module Rattletrap.Decode.Header+ ( decodeHeader+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Dictionary+import Rattletrap.Decode.Property+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word32le+import Rattletrap.Type.Header+import Rattletrap.Type.Word32le++decodeHeader :: Decode Header+decodeHeader = do+ (major, minor) <- (,) <$> decodeWord32le <*> decodeWord32le+ Header major minor+ <$> decodeWhen+ (major >= Word32le 868 && minor >= Word32le 18)+ decodeWord32le+ <*> decodeStr+ <*> decodeDictionary decodeProperty
@@ -0,0 +1,16 @@+module Rattletrap.Decode.Initialization+ ( decodeInitializationBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int8Vector+import Rattletrap.Decode.Vector+import Rattletrap.Type.Initialization++decodeInitializationBits+ :: (Int, Int, Int) -> Bool -> Bool -> DecodeBits Initialization+decodeInitializationBits version hasLocation hasRotation =+ Initialization+ <$> decodeWhen hasLocation (decodeVectorBits version)+ <*> decodeWhen hasRotation decodeInt8VectorBits
@@ -0,0 +1,14 @@+module Rattletrap.Decode.Int32le+ ( decodeInt32le+ , decodeInt32leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Int32le++decodeInt32le :: Decode Int32le+decodeInt32le = Int32le <$> getInt32le++decodeInt32leBits :: DecodeBits Int32le+decodeInt32leBits = toBits decodeInt32le 4
@@ -0,0 +1,11 @@+module Rattletrap.Decode.Int64Attribute+ ( decodeInt64AttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int64le+import Rattletrap.Type.Int64Attribute++decodeInt64AttributeBits :: DecodeBits Int64Attribute+decodeInt64AttributeBits = Int64Attribute <$> decodeInt64leBits
@@ -0,0 +1,13 @@+module Rattletrap.Decode.Int64le+ ( decodeInt64leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Int64le++decodeInt64le :: Decode Int64le+decodeInt64le = Int64le <$> getInt64le++decodeInt64leBits :: DecodeBits Int64le+decodeInt64leBits = toBits decodeInt64le 8
@@ -0,0 +1,18 @@+module Rattletrap.Decode.Int8Vector+ ( decodeInt8VectorBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int8le+import Rattletrap.Type.Int8Vector+import Rattletrap.Type.Int8le++decodeInt8VectorBits :: DecodeBits Int8Vector+decodeInt8VectorBits =+ Int8Vector <$> decodeFieldBits <*> decodeFieldBits <*> decodeFieldBits++decodeFieldBits :: DecodeBits (Maybe Int8le)+decodeFieldBits = do+ hasField <- getBool+ decodeWhen hasField decodeInt8leBits
@@ -0,0 +1,13 @@+module Rattletrap.Decode.Int8le+ ( decodeInt8leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Int8le++decodeInt8le :: Decode Int8le+decodeInt8le = Int8le <$> getInt8++decodeInt8leBits :: DecodeBits Int8le+decodeInt8leBits = toBits decodeInt8le 1
@@ -0,0 +1,11 @@+module Rattletrap.Decode.IntAttribute+ ( decodeIntAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Type.IntAttribute++decodeIntAttributeBits :: DecodeBits IntAttribute+decodeIntAttributeBits = IntAttribute <$> decodeInt32leBits
@@ -0,0 +1,13 @@+module Rattletrap.Decode.KeyFrame+ ( decodeKeyFrame+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Float32le+import Rattletrap.Decode.Word32le+import Rattletrap.Type.KeyFrame++decodeKeyFrame :: Decode KeyFrame+decodeKeyFrame =+ KeyFrame <$> decodeFloat32le <*> decodeWord32le <*> decodeWord32le
@@ -0,0 +1,16 @@+module Rattletrap.Decode.List+ ( decodeList+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Type.List+import Rattletrap.Type.Word32le++import qualified Control.Monad as Monad++decodeList :: Decode a -> Decode (List a)+decodeList decodeElement = do+ size <- decodeWord32le+ List <$> Monad.replicateM (fromIntegral (word32leValue size)) decodeElement
@@ -0,0 +1,31 @@+module Rattletrap.Decode.LoadoutAttribute+ ( decodeLoadoutAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Decode.Word8le+import Rattletrap.Type.LoadoutAttribute+import Rattletrap.Type.Word8le++decodeLoadoutAttributeBits :: DecodeBits LoadoutAttribute+decodeLoadoutAttributeBits = do+ version <- decodeWord8leBits+ LoadoutAttribute version+ <$> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWhen (version >= Word8le 11) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 16) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 16) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 16) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 17) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 19) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 22) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 22) decodeWord32leBits+ <*> decodeWhen (version >= Word8le 22) decodeWord32leBits
@@ -0,0 +1,25 @@+module Rattletrap.Decode.LoadoutOnlineAttribute+ ( decodeLoadoutOnlineAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.ProductAttribute+import Rattletrap.Decode.Word8le+import Rattletrap.Type.LoadoutOnlineAttribute+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le+import Rattletrap.Type.Word8le++import qualified Control.Monad as Monad+import qualified Data.Map as Map++decodeLoadoutOnlineAttributeBits+ :: (Int, Int, Int)+ -> Map.Map Word32le Str+ -> DecodeBits LoadoutOnlineAttribute+decodeLoadoutOnlineAttributeBits version objectMap = do+ size <- decodeWord8leBits+ LoadoutOnlineAttribute <$> Monad.replicateM+ (fromIntegral (word8leValue size))+ (decodeProductAttributesBits version objectMap)
@@ -0,0 +1,14 @@+module Rattletrap.Decode.LoadoutsAttribute+ ( decodeLoadoutsAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.LoadoutAttribute+import Rattletrap.Type.LoadoutsAttribute++decodeLoadoutsAttributeBits :: DecodeBits LoadoutsAttribute+decodeLoadoutsAttributeBits =+ LoadoutsAttribute+ <$> decodeLoadoutAttributeBits+ <*> decodeLoadoutAttributeBits
@@ -0,0 +1,23 @@+module Rattletrap.Decode.LoadoutsOnlineAttribute+ ( decodeLoadoutsOnlineAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.LoadoutOnlineAttribute+import Rattletrap.Type.LoadoutsOnlineAttribute+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le++import qualified Data.Map as Map++decodeLoadoutsOnlineAttributeBits+ :: (Int, Int, Int)+ -> Map.Map Word32le Str+ -> DecodeBits LoadoutsOnlineAttribute+decodeLoadoutsOnlineAttributeBits version objectMap =+ LoadoutsOnlineAttribute+ <$> decodeLoadoutOnlineAttributeBits version objectMap+ <*> decodeLoadoutOnlineAttributeBits version objectMap+ <*> getBool+ <*> getBool
@@ -0,0 +1,12 @@+module Rattletrap.Decode.LocationAttribute+ ( decodeLocationAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Vector+import Rattletrap.Type.LocationAttribute++decodeLocationAttributeBits :: (Int, Int, Int) -> DecodeBits LocationAttribute+decodeLocationAttributeBits version =+ LocationAttribute <$> decodeVectorBits version
@@ -0,0 +1,12 @@+module Rattletrap.Decode.Mark+ ( decodeMark+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word32le+import Rattletrap.Type.Mark++decodeMark :: Decode Mark+decodeMark = Mark <$> decodeStr <*> decodeWord32le
@@ -0,0 +1,12 @@+module Rattletrap.Decode.Message+ ( decodeMessage+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word32le+import Rattletrap.Type.Message++decodeMessage :: Decode Message+decodeMessage = Message <$> decodeWord32le <*> decodeStr <*> decodeStr
@@ -0,0 +1,16 @@+module Rattletrap.Decode.MusicStingerAttribute+ ( decodeMusicStingerAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Decode.Word8le+import Rattletrap.Type.MusicStingerAttribute++decodeMusicStingerAttributeBits :: DecodeBits MusicStingerAttribute+decodeMusicStingerAttributeBits =+ MusicStingerAttribute+ <$> getBool+ <*> decodeWord32leBits+ <*> decodeWord8leBits
@@ -0,0 +1,18 @@+module Rattletrap.Decode.PartyLeaderAttribute+ ( decodePartyLeaderAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.RemoteId+import Rattletrap.Decode.Word8le+import Rattletrap.Type.PartyLeaderAttribute+import Rattletrap.Type.Word8le++decodePartyLeaderAttributeBits+ :: (Int, Int, Int) -> DecodeBits PartyLeaderAttribute+decodePartyLeaderAttributeBits version = do+ systemId <- decodeWord8leBits+ PartyLeaderAttribute systemId <$> decodeWhen+ (systemId /= Word8le 0)+ ((,) <$> decodeRemoteIdBits version systemId <*> decodeWord8leBits)
@@ -0,0 +1,13 @@+module Rattletrap.Decode.PickupAttribute+ ( decodePickupAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Type.PickupAttribute++decodePickupAttributeBits :: DecodeBits PickupAttribute+decodePickupAttributeBits = do+ instigator <- getBool+ PickupAttribute <$> decodeWhen instigator decodeWord32leBits <*> getBool
@@ -0,0 +1,16 @@+module Rattletrap.Decode.PickupAttributeNew+ ( decodePickupAttributeNewBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word8le+import Rattletrap.Decode.Word32le+import Rattletrap.Type.PickupAttributeNew++decodePickupAttributeNewBits :: DecodeBits PickupAttributeNew+decodePickupAttributeNewBits = do+ instigator <- getBool+ PickupAttributeNew+ <$> decodeWhen instigator decodeWord32leBits+ <*> decodeWord8leBits
@@ -0,0 +1,11 @@+module Rattletrap.Decode.PlayerHistoryKeyAttribute+ ( decodePlayerHistoryKeyAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.PlayerHistoryKeyAttribute++decodePlayerHistoryKeyAttributeBits :: DecodeBits PlayerHistoryKeyAttribute+decodePlayerHistoryKeyAttributeBits =+ PlayerHistoryKeyAttribute <$> getBitsLE 14
@@ -0,0 +1,20 @@+module Rattletrap.Decode.PrivateMatchSettingsAttribute+ ( decodePrivateMatchSettingsAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word32le+import Rattletrap.Type.PrivateMatchSettingsAttribute++decodePrivateMatchSettingsAttributeBits+ :: DecodeBits PrivateMatchSettingsAttribute+decodePrivateMatchSettingsAttributeBits =+ PrivateMatchSettingsAttribute+ <$> decodeStrBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeStrBits+ <*> decodeStrBits+ <*> getBool
@@ -0,0 +1,70 @@+module Rattletrap.Decode.ProductAttribute+ ( decodeProductAttributesBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Decode.Word32le+import Rattletrap.Decode.Word8le+import Rattletrap.Decode.Str+import Rattletrap.Type.Common+import Rattletrap.Type.ProductAttribute+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le+import Rattletrap.Type.Word8le++import qualified Control.Monad as Monad+import qualified Data.Map as Map++decodeProductAttributesBits+ :: (Int, Int, Int) -> Map Word32le Str -> DecodeBits [ProductAttribute]+decodeProductAttributesBits version objectMap = do+ size <- decodeWord8leBits+ Monad.replicateM+ (fromIntegral (word8leValue size))+ (decodeProductAttributeBits version objectMap)++decodeProductAttributeBits+ :: (Int, Int, Int) -> Map Word32le Str -> DecodeBits ProductAttribute+decodeProductAttributeBits version objectMap = do+ flag <- getBool+ objectId <- decodeWord32leBits+ let maybeObjectName = Map.lookup objectId objectMap+ value <- case fromStr <$> maybeObjectName of+ Just "TAGame.ProductAttribute_Painted_TA" -> decodePainted version+ Just "TAGame.ProductAttribute_SpecialEdition_TA" -> decodeSpecialEdition+ Just "TAGame.ProductAttribute_TeamEdition_TA" -> decodeTeamEdition version+ Just "TAGame.ProductAttribute_TitleID_TA" -> decodeTitle+ Just "TAGame.ProductAttribute_UserColor_TA" -> decodeColor version+ Just objectName -> fail+ ("[RT05] unknown object name "+ <> show objectName+ <> " for ID "+ <> show objectId+ )+ Nothing -> fail ("[RT06] missing object name for ID " <> show objectId)+ pure (ProductAttribute flag objectId maybeObjectName value)++decodeSpecialEdition :: DecodeBits ProductAttributeValue+decodeSpecialEdition = ProductAttributeValueSpecialEdition <$> getBitsLE 31++decodePainted :: (Int, Int, Int) -> DecodeBits ProductAttributeValue+decodePainted version = if version >= (868, 18, 0)+ then ProductAttributeValuePaintedNew <$> getBitsLE 31+ else ProductAttributeValuePaintedOld <$> decodeCompressedWordBits 13++decodeTeamEdition :: (Int, Int, Int) -> DecodeBits ProductAttributeValue+decodeTeamEdition version = if version >= (868, 18, 0)+ then ProductAttributeValueTeamEditionNew <$> getBitsLE 31+ else ProductAttributeValueTeamEditionOld <$> decodeCompressedWordBits 13++decodeColor :: (Int, Int, Int) -> DecodeBits ProductAttributeValue+decodeColor version = if version >= (868, 23, 8)+ then ProductAttributeValueUserColorNew <$> decodeWord32leBits+ else do+ hasValue <- getBool+ ProductAttributeValueUserColorOld <$> decodeWhen hasValue (getBitsLE 31)++decodeTitle :: DecodeBits ProductAttributeValue+decodeTitle = ProductAttributeValueTitleId <$> decodeStrBits
@@ -0,0 +1,15 @@+module Rattletrap.Decode.Property+ ( decodeProperty+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.PropertyValue+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word64le+import Rattletrap.Type.Property++decodeProperty :: Decode Property+decodeProperty = do+ kind <- decodeStr+ Property kind <$> decodeWord64le <*> decodePropertyValue decodeProperty kind
@@ -0,0 +1,31 @@+module Rattletrap.Decode.PropertyValue+ ( decodePropertyValue+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Dictionary+import Rattletrap.Decode.Float32le+import Rattletrap.Decode.Int32le+import Rattletrap.Decode.List+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word64le+import Rattletrap.Decode.Word8le+import Rattletrap.Type.PropertyValue+import Rattletrap.Type.Str++decodePropertyValue :: Decode a -> Str -> Decode (PropertyValue a)+decodePropertyValue getProperty kind = case fromStr kind of+ "ArrayProperty" ->+ PropertyValueArray <$> decodeList (decodeDictionary getProperty)+ "BoolProperty" -> PropertyValueBool <$> decodeWord8le+ "ByteProperty" -> do+ k <- decodeStr+ PropertyValueByte k+ <$> decodeWhen (fromStr k /= "OnlinePlatform_Steam") decodeStr+ "FloatProperty" -> PropertyValueFloat <$> decodeFloat32le+ "IntProperty" -> PropertyValueInt <$> decodeInt32le+ "NameProperty" -> PropertyValueName <$> decodeStr+ "QWordProperty" -> PropertyValueQWord <$> decodeWord64le+ "StrProperty" -> PropertyValueStr <$> decodeStr+ _ -> fail ("[RT07] don't know how to read property value " <> show kind)
@@ -0,0 +1,11 @@+module Rattletrap.Decode.QWordAttribute+ ( decodeQWordAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word64le+import Rattletrap.Type.QWordAttribute++decodeQWordAttributeBits :: DecodeBits QWordAttribute+decodeQWordAttributeBits = QWordAttribute <$> decodeWord64leBits
@@ -0,0 +1,26 @@+module Rattletrap.Decode.Quaternion+ ( decodeQuaternionBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Quaternion++decodeQuaternionBits :: DecodeBits Quaternion+decodeQuaternionBits =+ toQuaternion <$> decodeComponent <*> decodePart <*> decodePart <*> decodePart++decodeComponent :: DecodeBits Component+decodeComponent = do+ x <- decodeCompressedWordBits 3+ case compressedWordValue x of+ 0 -> pure ComponentX+ 1 -> pure ComponentY+ 2 -> pure ComponentZ+ 3 -> pure ComponentW+ y -> fail ("[RT08] invalid component: " <> show y)++decodePart :: DecodeBits Double+decodePart = decompressPart <$> decodeCompressedWordBits maxCompressedValue
@@ -0,0 +1,49 @@+module Rattletrap.Decode.RemoteId+ ( decodeRemoteIdBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Decode.Word64le+import Rattletrap.Type.RemoteId+import Rattletrap.Type.Word64le+import Rattletrap.Type.Word8le+import Rattletrap.Utility.Bytes++import qualified Data.ByteString as Bytes+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Word as Word++decodeRemoteIdBits :: (Int, Int, Int) -> Word8le -> DecodeBits RemoteId+decodeRemoteIdBits version systemId = case word8leValue systemId of+ 0 -> RemoteIdSplitscreen <$> getBitsLE 24+ 1 -> RemoteIdSteam <$> decodeWord64leBits+ 2 -> RemoteIdPlayStation <$> decodePsName <*> decodePsBytes version+ 4 -> RemoteIdXbox <$> decodeWord64leBits+ 6 -> do+ (a, b, c, d) <- getWord256+ pure $ RemoteIdSwitch a b c d+ 7 -> if version >= (868, 24, 10)+ then RemoteIdPsyNet . Left <$> decodeWord64leBits+ else RemoteIdPsyNet . Right <$> getWord256+ 11 -> RemoteIdEpic <$> decodeStrBits+ _ -> fail ("[RT09] unknown system id " <> show systemId)++decodePsName :: DecodeBits Text.Text+decodePsName = fmap+ (Text.dropWhileEnd (== '\x00') . Text.decodeLatin1 . reverseBytes)+ (getByteStringBits 16)++decodePsBytes :: (Int, Int, Int) -> DecodeBits [Word.Word8]+decodePsBytes version = Bytes.unpack+ <$> getByteStringBits (if version >= (868, 20, 1) then 24 else 16)++getWord256 :: DecodeBits (Word64le, Word64le, Word64le, Word64le)+getWord256 = do+ a <- decodeWord64leBits+ b <- decodeWord64leBits+ c <- decodeWord64leBits+ d <- decodeWord64leBits+ pure (a, b, c, d)
@@ -0,0 +1,66 @@+module Rattletrap.Decode.Replay+ ( decodeReplay+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Content+import Rattletrap.Decode.Header+import Rattletrap.Decode.Section+import Rattletrap.Encode.Content+import Rattletrap.Type.Content+import Rattletrap.Type.Dictionary+import Rattletrap.Type.Header+import Rattletrap.Type.Int32le+import Rattletrap.Type.Property+import Rattletrap.Type.PropertyValue+import Rattletrap.Type.Replay+import Rattletrap.Type.Section+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le++decodeReplay :: Bool -> Decode FullReplay+decodeReplay fast = do+ header <- decodeSection decodeHeader+ content <- if fast+ then pure $ toSection putContent defaultContent+ else+ let body = sectionBody header+ in+ decodeSection $ decodeContent+ (getVersion body)+ (getNumFrames body)+ (getMaxChannels body)+ pure $ Replay header content++getVersion :: Header -> (Int, Int, Int)+getVersion header =+ ( fromIntegral (word32leValue (headerEngineVersion header))+ , fromIntegral (word32leValue (headerLicenseeVersion header))+ , getPatchVersion header+ )++getPatchVersion :: Header -> Int+getPatchVersion header = case headerPatchVersion header of+ Just version -> fromIntegral (word32leValue version)+ Nothing ->+ case dictionaryLookup (toStr "MatchType") (headerProperties header) of+ -- This is an ugly, ugly hack to handle replays from season 2 of RLCS.+ -- See `decodeSpawnedReplicationBits` and #85.+ Just Property { propertyValue = PropertyValueName str }+ | fromStr str == "Lan" -> -1+ _ -> 0++getNumFrames :: Header -> Int+getNumFrames header =+ case dictionaryLookup (toStr "NumFrames") (headerProperties header) of+ Just (Property _ _ (PropertyValueInt numFrames)) ->+ fromIntegral (int32leValue numFrames)+ _ -> 0++getMaxChannels :: Header -> Word+getMaxChannels header =+ case dictionaryLookup (toStr "MaxChannels") (headerProperties header) of+ Just (Property _ _ (PropertyValueInt numFrames)) ->+ fromIntegral (int32leValue numFrames)+ _ -> 1023
@@ -0,0 +1,45 @@+module Rattletrap.Decode.Replication+ ( decodeReplicationsBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Decode.ReplicationValue+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Replication+import Rattletrap.Type.Word32le++import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map++decodeReplicationsBits+ :: (Int, Int, Int)+ -> Word+ -> ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord Word32le)+ DecodeBits+ [Replication]+decodeReplicationsBits version limit classes = do+ hasReplication <- Trans.lift getBool+ if hasReplication+ then+ (:)+ <$> decodeReplicationBits version limit classes+ <*> decodeReplicationsBits version limit classes+ else pure []++decodeReplicationBits+ :: (Int, Int, Int)+ -> Word+ -> ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord Word32le)+ DecodeBits+ Replication+decodeReplicationBits version limit classes = do+ actor <- Trans.lift (decodeCompressedWordBits limit)+ Replication actor <$> decodeReplicationValueBits version classes actor
@@ -0,0 +1,45 @@+module Rattletrap.Decode.ReplicationValue+ ( decodeReplicationValueBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.DestroyedReplication+import Rattletrap.Decode.SpawnedReplication+import Rattletrap.Decode.UpdatedReplication+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.ReplicationValue+import Rattletrap.Type.Word32le++import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map++decodeReplicationValueBits+ :: (Int, Int, Int)+ -> ClassAttributeMap+ -> CompressedWord+ -> State.StateT+ (Map.Map CompressedWord Word32le)+ DecodeBits+ ReplicationValue+decodeReplicationValueBits version classAttributeMap actorId = do+ actorMap <- State.get+ isOpen <- Trans.lift getBool+ if isOpen+ then do+ isNew <- Trans.lift getBool+ if isNew+ then+ ReplicationValueSpawned+ <$> decodeSpawnedReplicationBits version classAttributeMap actorId+ else ReplicationValueUpdated <$> Trans.lift+ (decodeUpdatedReplicationBits+ version+ classAttributeMap+ actorMap+ actorId+ )+ else ReplicationValueDestroyed+ <$> Trans.lift decodeDestroyedReplicationBits
@@ -0,0 +1,25 @@+module Rattletrap.Decode.ReservationAttribute+ ( decodeReservationAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Decode.Str+import Rattletrap.Decode.UniqueIdAttribute+import Rattletrap.Type.ReservationAttribute+import Rattletrap.Type.UniqueIdAttribute+import Rattletrap.Type.Word8le++decodeReservationAttributeBits+ :: (Int, Int, Int) -> DecodeBits ReservationAttribute+decodeReservationAttributeBits version = do+ number <- decodeCompressedWordBits 7+ uniqueId <- decodeUniqueIdAttributeBits version+ ReservationAttribute number uniqueId+ <$> decodeWhen+ (uniqueIdAttributeSystemId uniqueId /= Word8le 0)+ decodeStrBits+ <*> getBool+ <*> getBool+ <*> decodeWhen (version >= (868, 12, 0)) (getWord8Bits 6)
@@ -0,0 +1,19 @@+module Rattletrap.Decode.RigidBodyStateAttribute+ ( decodeRigidBodyStateAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Rotation+import Rattletrap.Decode.Vector+import Rattletrap.Type.RigidBodyStateAttribute++decodeRigidBodyStateAttributeBits+ :: (Int, Int, Int) -> DecodeBits RigidBodyStateAttribute+decodeRigidBodyStateAttributeBits version = do+ sleeping <- getBool+ RigidBodyStateAttribute sleeping+ <$> decodeVectorBits version+ <*> decodeRotationBits version+ <*> decodeWhen (not sleeping) (decodeVectorBits version)+ <*> decodeWhen (not sleeping) (decodeVectorBits version)
@@ -0,0 +1,14 @@+module Rattletrap.Decode.Rotation+ ( decodeRotationBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWordVector+import Rattletrap.Decode.Quaternion+import Rattletrap.Type.Rotation++decodeRotationBits :: (Int, Int, Int) -> DecodeBits Rotation+decodeRotationBits version = if version >= (868, 22, 7)+ then RotationQuaternion <$> decodeQuaternionBits+ else RotationCompressedWordVector <$> decodeCompressedWordVectorBits
@@ -0,0 +1,30 @@+module Rattletrap.Decode.Section+ ( decodeSection+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Type.Section+import Rattletrap.Type.Word32le+import Rattletrap.Utility.Crc++import qualified Control.Monad as Monad++decodeSection :: Decode a -> Decode (Section a)+decodeSection getBody = do+ size <- decodeWord32le+ crc <- decodeWord32le+ rawBody <- getByteString (fromIntegral (word32leValue size))+ let actualCrc = Word32le (getCrc32 rawBody)+ Monad.when (actualCrc /= crc) (fail (crcMessage actualCrc crc))+ body <- either fail pure (runDecode getBody rawBody)+ pure (Section size crc body)++crcMessage :: Word32le -> Word32le -> String+crcMessage actual expected = unwords+ [ "[RT10] actual CRC"+ , show actual+ , "does not match expected CRC"+ , show expected+ ]
@@ -0,0 +1,72 @@+module Rattletrap.Decode.SpawnedReplication+ ( decodeSpawnedReplicationBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Initialization+import Rattletrap.Decode.Word32le+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.SpawnedReplication+import Rattletrap.Type.Str+import Rattletrap.Type.Word32le++import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map++decodeSpawnedReplicationBits+ :: (Int, Int, Int)+ -> ClassAttributeMap+ -> CompressedWord+ -> State.StateT+ (Map.Map CompressedWord Word32le)+ DecodeBits+ SpawnedReplication+decodeSpawnedReplicationBits version classAttributeMap actorId = do+ flag <- Trans.lift getBool+ nameIndex <- decodeWhen+ (version >= (868, 14, 0))+ (Trans.lift decodeWord32leBits)+ name <- either fail pure (lookupName classAttributeMap nameIndex)+ objectId <- Trans.lift decodeWord32leBits+ State.modify (Map.insert actorId objectId)+ objectName <- either fail pure (lookupObjectName classAttributeMap objectId)+ className <- either fail pure (lookupClassName objectName)+ let hasLocation = classHasLocation className+ let hasRotation = classHasRotation className+ initialization <- Trans.lift+ (decodeInitializationBits version hasLocation hasRotation)+ pure+ (SpawnedReplication+ flag+ nameIndex+ name+ objectId+ objectName+ className+ initialization+ )++lookupName :: ClassAttributeMap -> Maybe Word32le -> Either String (Maybe Str)+lookupName classAttributeMap maybeNameIndex = case maybeNameIndex of+ Nothing -> Right Nothing+ Just nameIndex ->+ case getName (classAttributeMapNameMap classAttributeMap) nameIndex of+ Nothing ->+ Left ("[RT11] could not get name for index " <> show nameIndex)+ Just name -> Right (Just name)++lookupObjectName :: ClassAttributeMap -> Word32le -> Either String Str+lookupObjectName classAttributeMap objectId =+ case getObjectName (classAttributeMapObjectMap classAttributeMap) objectId of+ Nothing ->+ Left ("[RT12] could not get object name for id " <> show objectId)+ Just objectName -> Right objectName++lookupClassName :: Str -> Either String Str+lookupClassName objectName = case getClassName objectName of+ Nothing ->+ Left ("[RT13] could not get class name for object " <> show objectName)+ Just className -> Right className
@@ -0,0 +1,12 @@+module Rattletrap.Decode.StatEventAttribute+ ( decodeStatEventAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Type.StatEventAttribute++decodeStatEventAttributeBits :: DecodeBits StatEventAttribute+decodeStatEventAttributeBits =+ StatEventAttribute <$> getBool <*> decodeInt32leBits
@@ -0,0 +1,47 @@+module Rattletrap.Decode.Str+ ( decodeStr+ , decodeStrBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Int32le+import Rattletrap.Type.Int32le+import Rattletrap.Type.Str+import Rattletrap.Utility.Bytes++import qualified Data.ByteString as Bytes+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Text.Encoding.Error as Text+import qualified Debug.Trace as Debug++decodeStr :: Decode Str+decodeStr = do+ rawSize <- decodeInt32le+ bytes <- getByteString (normalizeTextSize rawSize)+ pure (Str (dropNull (getTextDecoder rawSize bytes)))++decodeStrBits :: DecodeBits Str+decodeStrBits = do+ rawSize <- decodeInt32leBits+ bytes <- getByteStringBits (normalizeTextSize rawSize)+ pure (Str (dropNull (getTextDecoder rawSize (reverseBytes bytes))))++normalizeTextSize :: Integral a => Int32le -> a+normalizeTextSize size = case int32leValue size of+ 0x05000000 -> 8+ x -> if x < 0 then (-2 * fromIntegral x) else fromIntegral x++getTextDecoder :: Int32le -> Bytes.ByteString -> Text.Text+getTextDecoder size bytes =+ let+ decode = if size < Int32le 0+ then Text.decodeUtf16LEWith $ \message input -> do+ Debug.traceM $ "WARNING: " <> show (Text.DecodeError message input)+ Text.lenientDecode message input+ else Text.decodeLatin1+ in decode bytes++dropNull :: Text.Text -> Text.Text+dropNull = Text.dropWhileEnd (== '\x00')
@@ -0,0 +1,11 @@+module Rattletrap.Decode.StringAttribute+ ( decodeStringAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Str+import Rattletrap.Type.StringAttribute++decodeStringAttributeBits :: DecodeBits StringAttribute+decodeStringAttributeBits = StringAttribute <$> decodeStrBits
@@ -0,0 +1,18 @@+module Rattletrap.Decode.TeamPaintAttribute+ ( decodeTeamPaintAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Decode.Word8le+import Rattletrap.Type.TeamPaintAttribute++decodeTeamPaintAttributeBits :: DecodeBits TeamPaintAttribute+decodeTeamPaintAttributeBits =+ TeamPaintAttribute+ <$> decodeWord8leBits+ <*> decodeWord8leBits+ <*> decodeWord8leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits
@@ -0,0 +1,20 @@+module Rattletrap.Decode.TitleAttribute+ ( decodeTitleAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Word32le+import Rattletrap.Type.TitleAttribute++decodeTitleAttributeBits :: DecodeBits TitleAttribute+decodeTitleAttributeBits =+ TitleAttribute+ <$> getBool+ <*> getBool+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> decodeWord32leBits+ <*> getBool
@@ -0,0 +1,16 @@+module Rattletrap.Decode.UniqueIdAttribute+ ( decodeUniqueIdAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.RemoteId+import Rattletrap.Decode.Word8le+import Rattletrap.Type.UniqueIdAttribute++decodeUniqueIdAttributeBits :: (Int, Int, Int) -> DecodeBits UniqueIdAttribute+decodeUniqueIdAttributeBits version = do+ systemId <- decodeWord8leBits+ UniqueIdAttribute systemId+ <$> decodeRemoteIdBits version systemId+ <*> decodeWord8leBits
@@ -0,0 +1,22 @@+module Rattletrap.Decode.UpdatedReplication+ ( decodeUpdatedReplicationBits+ )+where++import Rattletrap.Decode.Attribute+import Rattletrap.Decode.Common+import Rattletrap.Type.ClassAttributeMap+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.UpdatedReplication+import Rattletrap.Type.Word32le++import qualified Data.Map as Map++decodeUpdatedReplicationBits+ :: (Int, Int, Int)+ -> ClassAttributeMap+ -> Map.Map CompressedWord Word32le+ -> CompressedWord+ -> DecodeBits UpdatedReplication+decodeUpdatedReplicationBits version classes actors actor =+ UpdatedReplication <$> decodeAttributesBits version classes actors actor
@@ -0,0 +1,29 @@+module Rattletrap.Decode.Vector+ ( decodeVectorBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.CompressedWord+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Vector++decodeVectorBits :: (Int, Int, Int) -> DecodeBits Vector+decodeVectorBits version = do+ size <- decodeCompressedWordBits (if version >= (868, 22, 7) then 21 else 19)+ let+ limit = getLimit size+ bias = getBias size+ Vector size bias+ <$> fmap (fromDelta bias) (decodeCompressedWordBits limit)+ <*> fmap (fromDelta bias) (decodeCompressedWordBits limit)+ <*> fmap (fromDelta bias) (decodeCompressedWordBits limit)++getLimit :: CompressedWord -> Word+getLimit = (2 ^) . (+ 2) . compressedWordValue++getBias :: CompressedWord -> Word+getBias = (2 ^) . (+ 1) . compressedWordValue++fromDelta :: Word -> CompressedWord -> Int+fromDelta bias x = fromIntegral (compressedWordValue x) - fromIntegral bias
@@ -0,0 +1,21 @@+module Rattletrap.Decode.WeldedInfoAttribute+ ( decodeWeldedInfoAttributeBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Decode.Float32le+import Rattletrap.Decode.Int32le+import Rattletrap.Decode.Int8Vector+import Rattletrap.Decode.Vector+import Rattletrap.Type.WeldedInfoAttribute++decodeWeldedInfoAttributeBits+ :: (Int, Int, Int) -> DecodeBits WeldedInfoAttribute+decodeWeldedInfoAttributeBits version =+ WeldedInfoAttribute+ <$> getBool+ <*> decodeInt32leBits+ <*> decodeVectorBits version+ <*> decodeFloat32leBits+ <*> decodeInt8VectorBits
@@ -0,0 +1,14 @@+module Rattletrap.Decode.Word32le+ ( decodeWord32le+ , decodeWord32leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Word32le++decodeWord32le :: Decode Word32le+decodeWord32le = Word32le <$> getWord32le++decodeWord32leBits :: DecodeBits Word32le+decodeWord32leBits = toBits decodeWord32le 4
@@ -0,0 +1,14 @@+module Rattletrap.Decode.Word64le+ ( decodeWord64le+ , decodeWord64leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Word64le++decodeWord64le :: Decode Word64le+decodeWord64le = Word64le <$> getWord64le++decodeWord64leBits :: DecodeBits Word64le+decodeWord64leBits = toBits decodeWord64le 8
@@ -0,0 +1,14 @@+module Rattletrap.Decode.Word8le+ ( decodeWord8le+ , decodeWord8leBits+ )+where++import Rattletrap.Decode.Common+import Rattletrap.Type.Word8le++decodeWord8le :: Decode Word8le+decodeWord8le = Word8le <$> getWord8++decodeWord8leBits :: DecodeBits Word8le+decodeWord8leBits = toBits decodeWord8le 1
@@ -0,0 +1,18 @@+module Rattletrap.Encode.AppliedDamageAttribute+ ( putAppliedDamageAttribute+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Encode.Vector+import Rattletrap.Encode.Word8le+import Rattletrap.Type.AppliedDamageAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putAppliedDamageAttribute :: AppliedDamageAttribute -> BinaryBits.BitPut ()+putAppliedDamageAttribute appliedDamageAttribute = do+ putWord8Bits (appliedDamageAttributeUnknown1 appliedDamageAttribute)+ putVector (appliedDamageAttributeLocation appliedDamageAttribute)+ putInt32Bits (appliedDamageAttributeUnknown3 appliedDamageAttribute)+ putInt32Bits (appliedDamageAttributeUnknown4 appliedDamageAttribute)
@@ -0,0 +1,26 @@+module Rattletrap.Encode.Attribute+ ( putAttributes+ )+where++import Rattletrap.Encode.AttributeValue+import Rattletrap.Encode.CompressedWord+import Rattletrap.Type.Attribute++import qualified Data.Binary.Bits.Put as BinaryBits++putAttributes :: [Attribute] -> BinaryBits.BitPut ()+putAttributes attributes = case attributes of+ [] -> BinaryBits.putBool False+ [attribute] -> do+ putAttribute attribute+ BinaryBits.putBool False+ first : rest -> do+ putAttribute first+ putAttributes rest++putAttribute :: Attribute -> BinaryBits.BitPut ()+putAttribute attribute = do+ BinaryBits.putBool True+ putCompressedWord (attributeId attribute)+ putAttributeValue (attributeValue attribute)
@@ -0,0 +1,14 @@+module Rattletrap.Encode.AttributeMapping+ ( putAttributeMapping+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Type.AttributeMapping++import qualified Data.Binary as Binary++putAttributeMapping :: AttributeMapping -> Binary.Put+putAttributeMapping attributeMapping = do+ putWord32 (attributeMappingObjectId attributeMapping)+ putWord32 (attributeMappingStreamId attributeMapping)
@@ -0,0 +1,85 @@+module Rattletrap.Encode.AttributeValue+ ( putAttributeValue+ )+where++import Rattletrap.Encode.AppliedDamageAttribute+import Rattletrap.Encode.BooleanAttribute+import Rattletrap.Encode.ByteAttribute+import Rattletrap.Encode.CamSettingsAttribute+import Rattletrap.Encode.ClubColorsAttribute+import Rattletrap.Encode.CustomDemolishAttribute+import Rattletrap.Encode.DamageStateAttribute+import Rattletrap.Encode.DemolishAttribute+import Rattletrap.Encode.EnumAttribute+import Rattletrap.Encode.ExplosionAttribute+import Rattletrap.Encode.ExtendedExplosionAttribute+import Rattletrap.Encode.FlaggedIntAttribute+import Rattletrap.Encode.FlaggedByteAttribute+import Rattletrap.Encode.FloatAttribute+import Rattletrap.Encode.GameModeAttribute+import Rattletrap.Encode.Int64Attribute+import Rattletrap.Encode.IntAttribute+import Rattletrap.Encode.LoadoutAttribute+import Rattletrap.Encode.LoadoutOnlineAttribute+import Rattletrap.Encode.LoadoutsAttribute+import Rattletrap.Encode.LoadoutsOnlineAttribute+import Rattletrap.Encode.LocationAttribute+import Rattletrap.Encode.MusicStingerAttribute+import Rattletrap.Encode.PartyLeaderAttribute+import Rattletrap.Encode.PickupAttribute+import Rattletrap.Encode.PickupAttributeNew+import Rattletrap.Encode.PlayerHistoryKeyAttribute+import Rattletrap.Encode.PrivateMatchSettingsAttribute+import Rattletrap.Encode.QWordAttribute+import Rattletrap.Encode.ReservationAttribute+import Rattletrap.Encode.RigidBodyStateAttribute+import Rattletrap.Encode.StatEventAttribute+import Rattletrap.Encode.StringAttribute+import Rattletrap.Encode.TeamPaintAttribute+import Rattletrap.Encode.TitleAttribute+import Rattletrap.Encode.UniqueIdAttribute+import Rattletrap.Encode.WeldedInfoAttribute+import Rattletrap.Type.AttributeValue++import qualified Data.Binary.Bits.Put as BinaryBits++putAttributeValue :: AttributeValue -> BinaryBits.BitPut ()+putAttributeValue value = case value of+ AttributeValueAppliedDamage x -> putAppliedDamageAttribute x+ AttributeValueBoolean x -> putBooleanAttribute x+ AttributeValueByte x -> putByteAttribute x+ AttributeValueCamSettings x -> putCamSettingsAttribute x+ AttributeValueClubColors x -> putClubColorsAttribute x+ AttributeValueCustomDemolish x -> putCustomDemolishAttribute x+ AttributeValueDamageState x -> putDamageStateAttribute x+ AttributeValueDemolish x -> putDemolishAttribute x+ AttributeValueEnum x -> putEnumAttribute x+ AttributeValueExplosion x -> putExplosionAttribute x+ AttributeValueExtendedExplosion x -> putExtendedExplosionAttribute x+ AttributeValueFlaggedInt x -> putFlaggedIntAttribute x+ AttributeValueFlaggedByte x -> putFlaggedByteAttribute x+ AttributeValueFloat x -> putFloatAttribute x+ AttributeValueGameMode x -> putGameModeAttribute x+ AttributeValueInt x -> putIntAttribute x+ AttributeValueInt64 x -> putInt64Attribute x+ AttributeValueLoadout x -> putLoadoutAttribute x+ AttributeValueLoadoutOnline x -> putLoadoutOnlineAttribute x+ AttributeValueLoadouts x -> putLoadoutsAttribute x+ AttributeValueLoadoutsOnline x -> putLoadoutsOnlineAttribute x+ AttributeValueLocation x -> putLocationAttribute x+ AttributeValueMusicStinger x -> putMusicStingerAttribute x+ AttributeValuePartyLeader x -> putPartyLeaderAttribute x+ AttributeValuePickup x -> putPickupAttribute x+ AttributeValuePickupNew x -> putPickupAttributeNew x+ AttributeValuePlayerHistoryKey x -> putPlayerHistoryKeyAttribute x+ AttributeValuePrivateMatchSettings x -> putPrivateMatchSettingsAttribute x+ AttributeValueQWord x -> putQWordAttribute x+ AttributeValueReservation x -> putReservationAttribute x+ AttributeValueRigidBodyState x -> putRigidBodyStateAttribute x+ AttributeValueStatEvent x -> putStatEventAttribute x+ AttributeValueString x -> putStringAttribute x+ AttributeValueTeamPaint x -> putTeamPaintAttribute x+ AttributeValueTitle x -> putTitleAttribute x+ AttributeValueUniqueId x -> putUniqueIdAttribute x+ AttributeValueWeldedInfo x -> putWeldedInfoAttribute x
@@ -0,0 +1,12 @@+module Rattletrap.Encode.BooleanAttribute+ ( putBooleanAttribute+ )+where++import Rattletrap.Type.BooleanAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putBooleanAttribute :: BooleanAttribute -> BinaryBits.BitPut ()+putBooleanAttribute booleanAttribute =+ BinaryBits.putBool (booleanAttributeValue booleanAttribute)
@@ -0,0 +1,13 @@+module Rattletrap.Encode.ByteAttribute+ ( putByteAttribute+ )+where++import Rattletrap.Encode.Word8le+import Rattletrap.Type.ByteAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putByteAttribute :: ByteAttribute -> BinaryBits.BitPut ()+putByteAttribute byteAttribute =+ putWord8Bits (byteAttributeValue byteAttribute)
@@ -0,0 +1,18 @@+module Rattletrap.Encode.Cache+ ( putCache+ )+where++import Rattletrap.Encode.AttributeMapping+import Rattletrap.Encode.List+import Rattletrap.Encode.Word32le+import Rattletrap.Type.Cache++import qualified Data.Binary as Binary++putCache :: Cache -> Binary.Put+putCache cache = do+ putWord32 (cacheClassId cache)+ putWord32 (cacheParentCacheId cache)+ putWord32 (cacheCacheId cache)+ putList putAttributeMapping (cacheAttributeMappings cache)
@@ -0,0 +1,21 @@+module Rattletrap.Encode.CamSettingsAttribute+ ( putCamSettingsAttribute+ )+where++import Rattletrap.Encode.Float32le+import Rattletrap.Type.CamSettingsAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putCamSettingsAttribute :: CamSettingsAttribute -> BinaryBits.BitPut ()+putCamSettingsAttribute camSettingsAttribute = do+ putFloat32Bits (camSettingsAttributeFov camSettingsAttribute)+ putFloat32Bits (camSettingsAttributeHeight camSettingsAttribute)+ putFloat32Bits (camSettingsAttributeAngle camSettingsAttribute)+ putFloat32Bits (camSettingsAttributeDistance camSettingsAttribute)+ putFloat32Bits (camSettingsAttributeStiffness camSettingsAttribute)+ putFloat32Bits (camSettingsAttributeSwivelSpeed camSettingsAttribute)+ case camSettingsAttributeTransitionSpeed camSettingsAttribute of+ Nothing -> pure ()+ Just transitionSpeed -> putFloat32Bits transitionSpeed
@@ -0,0 +1,15 @@+module Rattletrap.Encode.ClassMapping+ ( putClassMapping+ )+where++import Rattletrap.Encode.Str+import Rattletrap.Encode.Word32le+import Rattletrap.Type.ClassMapping++import qualified Data.Binary as Binary++putClassMapping :: ClassMapping -> Binary.Put+putClassMapping classMapping = do+ putText (classMappingName classMapping)+ putWord32 (classMappingStreamId classMapping)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.ClubColorsAttribute+ ( putClubColorsAttribute+ )+where++import Rattletrap.Encode.Word8le+import Rattletrap.Type.ClubColorsAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putClubColorsAttribute :: ClubColorsAttribute -> BinaryBits.BitPut ()+putClubColorsAttribute clubColorsAttribute = do+ BinaryBits.putBool (clubColorsAttributeBlueFlag clubColorsAttribute)+ putWord8Bits (clubColorsAttributeBlueColor clubColorsAttribute)+ BinaryBits.putBool (clubColorsAttributeOrangeFlag clubColorsAttribute)+ putWord8Bits (clubColorsAttributeOrangeColor clubColorsAttribute)
@@ -0,0 +1,10 @@+module Rattletrap.Encode.Common+ ( putBitsLE+ )+where++import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Bits as Bits++putBitsLE :: Bits.Bits a => Int -> a -> BinaryBits.BitPut ()+putBitsLE size x = mapM_ (BinaryBits.putBool . Bits.testBit x) [0 .. size - 1]
@@ -0,0 +1,44 @@+module Rattletrap.Encode.CompressedWord+ ( putCompressedWord+ )+where++import Rattletrap.Type.CompressedWord++import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Bits as Bits++putCompressedWord :: CompressedWord -> BinaryBits.BitPut ()+putCompressedWord compressedWord =+ let+ limit = compressedWordLimit compressedWord+ value = compressedWordValue compressedWord+ maxBits = getMaxBits limit+ in putCompressedWordStep limit value maxBits 0 0++putCompressedWordStep+ :: Word -> Word -> Int -> Int -> Word -> BinaryBits.BitPut ()+putCompressedWordStep limit value maxBits position soFar =+ if position < maxBits+ then do+ let x = Bits.shiftL 1 position :: Word+ if maxBits > 1 && position == maxBits - 1 && soFar + x > limit+ then pure ()+ else do+ let bit = Bits.testBit value position+ BinaryBits.putBool bit+ let delta = if bit then x else 0+ putCompressedWordStep+ limit+ value+ maxBits+ (position + 1)+ (soFar + delta)+ else pure ()++getMaxBits :: Word -> Int+getMaxBits x =+ let+ n :: Int+ n = max 1 (ceiling (logBase (2 :: Double) (fromIntegral (max 1 x))))+ in if x < 1024 && x == 2 ^ n then n + 1 else n
@@ -0,0 +1,15 @@+module Rattletrap.Encode.CompressedWordVector+ ( putCompressedWordVector+ )+where++import Rattletrap.Encode.CompressedWord+import Rattletrap.Type.CompressedWordVector++import qualified Data.Binary.Bits.Put as BinaryBits++putCompressedWordVector :: CompressedWordVector -> BinaryBits.BitPut ()+putCompressedWordVector compressedWordVector = do+ putCompressedWord (compressedWordVectorX compressedWordVector)+ putCompressedWord (compressedWordVectorY compressedWordVector)+ putCompressedWord (compressedWordVectorZ compressedWordVector)
@@ -0,0 +1,43 @@+module Rattletrap.Encode.Content+ ( putContent+ )+where++import Rattletrap.Encode.Cache+import Rattletrap.Encode.ClassMapping+import Rattletrap.Encode.Frame+import Rattletrap.Encode.KeyFrame+import Rattletrap.Encode.List+import Rattletrap.Encode.Mark+import Rattletrap.Encode.Message+import Rattletrap.Encode.Str+import Rattletrap.Encode.Word32le+import Rattletrap.Type.Content+import Rattletrap.Type.Word32le+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putContent :: Content -> Binary.Put+putContent content = do+ putList putText (contentLevels content)+ putList putKeyFrame (contentKeyFrames content)+ let streamSize = contentStreamSize content+ putWord32 streamSize+ let+ stream = LazyBytes.toStrict+ (Binary.runPut (BinaryBits.runBitPut (putFrames (contentFrames content)))+ )+ Binary.putByteString+ (reverseBytes (padBytes (word32leValue streamSize) stream))+ putList putMessage (contentMessages content)+ putList putMark (contentMarks content)+ putList putText (contentPackages content)+ putList putText (contentObjects content)+ putList putText (contentNames content)+ putList putClassMapping (contentClassMappings content)+ putList putCache (contentCaches content)+ mapM_ Binary.putWord8 (contentUnknown content)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.CustomDemolishAttribute+ ( putCustomDemolishAttribute+ )+where++import Rattletrap.Encode.DemolishAttribute+import Rattletrap.Encode.Int32le+import Rattletrap.Type.CustomDemolishAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putCustomDemolishAttribute :: CustomDemolishAttribute -> BinaryBits.BitPut ()+putCustomDemolishAttribute x = do+ BinaryBits.putBool (customDemolishAttributeFlag x)+ putInt32Bits (customDemolishAttributeId x)+ putDemolishAttribute (customDemolishAttributeDemolish x)
@@ -0,0 +1,20 @@+module Rattletrap.Encode.DamageStateAttribute+ ( putDamageStateAttribute+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Encode.Vector+import Rattletrap.Encode.Word8le+import Rattletrap.Type.DamageStateAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putDamageStateAttribute :: DamageStateAttribute -> BinaryBits.BitPut ()+putDamageStateAttribute damageStateAttribute = do+ putWord8Bits (damageStateAttributeUnknown1 damageStateAttribute)+ BinaryBits.putBool (damageStateAttributeUnknown2 damageStateAttribute)+ putInt32Bits (damageStateAttributeUnknown3 damageStateAttribute)+ putVector (damageStateAttributeUnknown4 damageStateAttribute)+ BinaryBits.putBool (damageStateAttributeUnknown5 damageStateAttribute)+ BinaryBits.putBool (damageStateAttributeUnknown6 damageStateAttribute)
@@ -0,0 +1,19 @@+module Rattletrap.Encode.DemolishAttribute+ ( putDemolishAttribute+ )+where++import Rattletrap.Encode.Vector+import Rattletrap.Encode.Word32le+import Rattletrap.Type.DemolishAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putDemolishAttribute :: DemolishAttribute -> BinaryBits.BitPut ()+putDemolishAttribute demolishAttribute = do+ BinaryBits.putBool (demolishAttributeAttackerFlag demolishAttribute)+ putWord32Bits (demolishAttributeAttackerActorId demolishAttribute)+ BinaryBits.putBool (demolishAttributeVictimFlag demolishAttribute)+ putWord32Bits (demolishAttributeVictimActorId demolishAttribute)+ putVector (demolishAttributeAttackerVelocity demolishAttribute)+ putVector (demolishAttributeVictimVelocity demolishAttribute)
@@ -0,0 +1,11 @@+module Rattletrap.Encode.DestroyedReplication+ ( putDestroyedReplication+ )+where++import Rattletrap.Type.DestroyedReplication++import qualified Data.Binary.Bits.Put as BinaryBits++putDestroyedReplication :: DestroyedReplication -> BinaryBits.BitPut ()+putDestroyedReplication _ = pure ()
@@ -0,0 +1,17 @@+module Rattletrap.Encode.Dictionary+ ( putDictionary+ )+where++import Rattletrap.Encode.Str+import Rattletrap.Type.Dictionary++import qualified Data.Binary as Binary++putDictionary :: (a -> Binary.Put) -> Dictionary a -> Binary.Put+putDictionary f x = case x of+ DictionaryElement k v y -> do+ putText k+ f v+ putDictionary f y+ DictionaryEnd y -> putText y
@@ -0,0 +1,13 @@+module Rattletrap.Encode.EnumAttribute+ ( putEnumAttribute+ )+where++import Rattletrap.Encode.Common+import Rattletrap.Type.EnumAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putEnumAttribute :: EnumAttribute -> BinaryBits.BitPut ()+putEnumAttribute enumAttribute =+ putBitsLE 11 (enumAttributeValue enumAttribute)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.ExplosionAttribute+ ( putExplosionAttribute+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Encode.Vector+import Rattletrap.Type.ExplosionAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putExplosionAttribute :: ExplosionAttribute -> BinaryBits.BitPut ()+putExplosionAttribute explosionAttribute = do+ BinaryBits.putBool False+ putInt32Bits (explosionAttributeActorId explosionAttribute)+ putVector (explosionAttributeLocation explosionAttribute)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.ExtendedExplosionAttribute+ ( putExtendedExplosionAttribute+ )+where++import Rattletrap.Encode.ExplosionAttribute+import Rattletrap.Encode.FlaggedIntAttribute+import Rattletrap.Type.ExtendedExplosionAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putExtendedExplosionAttribute+ :: ExtendedExplosionAttribute -> BinaryBits.BitPut ()+putExtendedExplosionAttribute x = do+ putExplosionAttribute (extendedExplosionAttributeExplosion x)+ putFlaggedIntAttribute (extendedExplosionAttributeUnknown x)
@@ -0,0 +1,14 @@+module Rattletrap.Encode.FlaggedByteAttribute+ ( putFlaggedByteAttribute+ )+where++import Rattletrap.Encode.Word8le+import Rattletrap.Type.FlaggedByteAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putFlaggedByteAttribute :: FlaggedByteAttribute -> BinaryBits.BitPut ()+putFlaggedByteAttribute flaggedByteAttribute = do+ BinaryBits.putBool (flaggedByteAttributeFlag flaggedByteAttribute)+ putWord8Bits (flaggedByteAttributeByte flaggedByteAttribute)
@@ -0,0 +1,14 @@+module Rattletrap.Encode.FlaggedIntAttribute+ ( putFlaggedIntAttribute+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Type.FlaggedIntAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putFlaggedIntAttribute :: FlaggedIntAttribute -> BinaryBits.BitPut ()+putFlaggedIntAttribute flaggedIntAttribute = do+ BinaryBits.putBool (flaggedIntAttributeFlag flaggedIntAttribute)+ putInt32Bits (flaggedIntAttributeInt flaggedIntAttribute)
@@ -0,0 +1,21 @@+module Rattletrap.Encode.Float32le+ ( putFloat32+ , putFloat32Bits+ )+where++import Rattletrap.Type.Float32le+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putFloat32 :: Float32le -> Binary.Put+putFloat32 = Binary.putFloatle . float32leValue++putFloat32Bits :: Float32le -> BinaryBits.BitPut ()+putFloat32Bits float32 = do+ let bytes = LazyBytes.toStrict (Binary.runPut (putFloat32 float32))+ BinaryBits.putByteString (reverseBytes bytes)
@@ -0,0 +1,13 @@+module Rattletrap.Encode.FloatAttribute+ ( putFloatAttribute+ )+where++import Rattletrap.Encode.Float32le+import Rattletrap.Type.FloatAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putFloatAttribute :: FloatAttribute -> BinaryBits.BitPut ()+putFloatAttribute floatAttribute =+ putFloat32Bits (floatAttributeValue floatAttribute)
@@ -0,0 +1,24 @@+module Rattletrap.Encode.Frame+ ( putFrames+ )+where++import Rattletrap.Encode.Float32le+import Rattletrap.Encode.Replication+import Rattletrap.Type.Frame++import qualified Data.Binary.Bits.Put as BinaryBits++putFrames :: [Frame] -> BinaryBits.BitPut ()+putFrames frames = case frames of+ [] -> pure ()+ [frame] -> putFrame frame+ first : rest -> do+ putFrame first+ putFrames rest++putFrame :: Frame -> BinaryBits.BitPut ()+putFrame frame = do+ putFloat32Bits (frameTime frame)+ putFloat32Bits (frameDelta frame)+ putReplications (frameReplications frame)
@@ -0,0 +1,14 @@+module Rattletrap.Encode.GameModeAttribute+ ( putGameModeAttribute+ )+where++import Rattletrap.Type.GameModeAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putGameModeAttribute :: GameModeAttribute -> BinaryBits.BitPut ()+putGameModeAttribute gameModeAttribute = do+ let numBits = gameModeAttributeNumBits gameModeAttribute+ let word = gameModeAttributeWord gameModeAttribute+ BinaryBits.putWord8 numBits word
@@ -0,0 +1,22 @@+module Rattletrap.Encode.Header+ ( putHeader+ )+where++import Rattletrap.Encode.Dictionary+import Rattletrap.Encode.Property+import Rattletrap.Encode.Str+import Rattletrap.Encode.Word32le+import Rattletrap.Type.Header++import qualified Data.Binary as Binary++putHeader :: Header -> Binary.Put+putHeader header = do+ putWord32 (headerEngineVersion header)+ putWord32 (headerLicenseeVersion header)+ case headerPatchVersion header of+ Nothing -> pure ()+ Just patchVersion -> putWord32 patchVersion+ putText (headerLabel header)+ putDictionary putProperty (headerProperties header)
@@ -0,0 +1,19 @@+module Rattletrap.Encode.Initialization+ ( putInitialization+ )+where++import Rattletrap.Encode.Int8Vector+import Rattletrap.Encode.Vector+import Rattletrap.Type.Initialization++import qualified Data.Binary.Bits.Put as BinaryBits++putInitialization :: Initialization -> BinaryBits.BitPut ()+putInitialization initialization = do+ case initializationLocation initialization of+ Nothing -> pure ()+ Just location -> putVector location+ case initializationRotation initialization of+ Nothing -> pure ()+ Just rotation -> putInt8Vector rotation
@@ -0,0 +1,21 @@+module Rattletrap.Encode.Int32le+ ( putInt32+ , putInt32Bits+ )+where++import Rattletrap.Type.Int32le+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putInt32 :: Int32le -> Binary.Put+putInt32 int32 = Binary.putInt32le (int32leValue int32)++putInt32Bits :: Int32le -> BinaryBits.BitPut ()+putInt32Bits int32 = do+ let bytes = LazyBytes.toStrict (Binary.runPut (putInt32 int32))+ BinaryBits.putByteString (reverseBytes bytes)
@@ -0,0 +1,13 @@+module Rattletrap.Encode.Int64Attribute+ ( putInt64Attribute+ )+where++import Rattletrap.Encode.Int64le+import Rattletrap.Type.Int64Attribute++import qualified Data.Binary.Bits.Put as BinaryBits++putInt64Attribute :: Int64Attribute -> BinaryBits.BitPut ()+putInt64Attribute int64Attribute =+ putInt64Bits (int64AttributeValue int64Attribute)
@@ -0,0 +1,20 @@+module Rattletrap.Encode.Int64le+ ( putInt64Bits+ )+where++import Rattletrap.Type.Int64le+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putInt64 :: Int64le -> Binary.Put+putInt64 int64 = Binary.putInt64le (int64leValue int64)++putInt64Bits :: Int64le -> BinaryBits.BitPut ()+putInt64Bits int64 = do+ let bytes = LazyBytes.toStrict (Binary.runPut (putInt64 int64))+ BinaryBits.putByteString (reverseBytes bytes)
@@ -0,0 +1,23 @@+module Rattletrap.Encode.Int8Vector+ ( putInt8Vector+ )+where++import Rattletrap.Encode.Int8le+import Rattletrap.Type.Int8Vector+import Rattletrap.Type.Int8le++import qualified Data.Binary.Bits.Put as BinaryBits++putInt8Vector :: Int8Vector -> BinaryBits.BitPut ()+putInt8Vector int8Vector = do+ putInt8VectorField (int8VectorX int8Vector)+ putInt8VectorField (int8VectorY int8Vector)+ putInt8VectorField (int8VectorZ int8Vector)++putInt8VectorField :: Maybe Int8le -> BinaryBits.BitPut ()+putInt8VectorField maybeField = case maybeField of+ Nothing -> BinaryBits.putBool False+ Just field -> do+ BinaryBits.putBool True+ putInt8Bits field
@@ -0,0 +1,19 @@+module Rattletrap.Encode.Int8le+ ( putInt8Bits+ )+where++import Rattletrap.Type.Int8le+import Rattletrap.Utility.Bytes++import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putInt8 :: Int8le -> Binary.Put+putInt8 int8 = Binary.putInt8 (int8leValue int8)++putInt8Bits :: Int8le -> BinaryBits.BitPut ()+putInt8Bits int8 = do+ let bytes = LazyBytes.toStrict (Binary.runPut (putInt8 int8))+ BinaryBits.putByteString (reverseBytes bytes)
@@ -0,0 +1,12 @@+module Rattletrap.Encode.IntAttribute+ ( putIntAttribute+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Type.IntAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putIntAttribute :: IntAttribute -> BinaryBits.BitPut ()+putIntAttribute intAttribute = putInt32Bits (intAttributeValue intAttribute)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.KeyFrame+ ( putKeyFrame+ )+where++import Rattletrap.Encode.Float32le+import Rattletrap.Encode.Word32le+import Rattletrap.Type.KeyFrame++import qualified Data.Binary as Binary++putKeyFrame :: KeyFrame -> Binary.Put+putKeyFrame keyFrame = do+ putFloat32 (keyFrameTime keyFrame)+ putWord32 (keyFrameFrame keyFrame)+ putWord32 (keyFramePosition keyFrame)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.List+ ( putList+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Type.List+import Rattletrap.Type.Word32le++import qualified Data.Binary as Binary++putList :: (a -> Binary.Put) -> List a -> Binary.Put+putList putElement list = do+ let elements = listValue list+ putWord32 (Word32le (fromIntegral (length elements)))+ mapM_ putElement elements
@@ -0,0 +1,35 @@+module Rattletrap.Encode.LoadoutAttribute+ ( putLoadoutAttribute+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Encode.Word8le+import Rattletrap.Type.LoadoutAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putLoadoutAttribute :: LoadoutAttribute -> BinaryBits.BitPut ()+putLoadoutAttribute loadoutAttribute = do+ putWord8Bits (loadoutAttributeVersion loadoutAttribute)+ putWord32Bits (loadoutAttributeBody loadoutAttribute)+ putWord32Bits (loadoutAttributeDecal loadoutAttribute)+ putWord32Bits (loadoutAttributeWheels loadoutAttribute)+ putWord32Bits (loadoutAttributeRocketTrail loadoutAttribute)+ putWord32Bits (loadoutAttributeAntenna loadoutAttribute)+ putWord32Bits (loadoutAttributeTopper loadoutAttribute)+ putWord32Bits (loadoutAttributeUnknown1 loadoutAttribute)+ putOptional (loadoutAttributeUnknown2 loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeEngineAudio loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeTrail loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeGoalExplosion loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeBanner loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeUnknown3 loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeUnknown4 loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeUnknown5 loadoutAttribute) putWord32Bits+ putOptional (loadoutAttributeUnknown6 loadoutAttribute) putWord32Bits++putOptional :: Maybe a -> (a -> BinaryBits.BitPut ()) -> BinaryBits.BitPut ()+putOptional m f = case m of+ Just x -> f x+ Nothing -> pure ()
@@ -0,0 +1,17 @@+module Rattletrap.Encode.LoadoutOnlineAttribute+ ( putLoadoutOnlineAttribute+ )+where++import Rattletrap.Encode.ProductAttribute+import Rattletrap.Encode.Word8le+import Rattletrap.Type.LoadoutOnlineAttribute+import Rattletrap.Type.Word8le++import qualified Data.Binary.Bits.Put as BinaryBits++putLoadoutOnlineAttribute :: LoadoutOnlineAttribute -> BinaryBits.BitPut ()+putLoadoutOnlineAttribute loadoutAttribute = do+ let attributes = loadoutAttributeValue loadoutAttribute+ putWord8Bits (Word8le (fromIntegral (length attributes)))+ mapM_ putProductAttributes attributes
@@ -0,0 +1,14 @@+module Rattletrap.Encode.LoadoutsAttribute+ ( putLoadoutsAttribute+ )+where++import Rattletrap.Encode.LoadoutAttribute+import Rattletrap.Type.LoadoutsAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putLoadoutsAttribute :: LoadoutsAttribute -> BinaryBits.BitPut ()+putLoadoutsAttribute loadoutsAttribute = do+ putLoadoutAttribute (loadoutsAttributeBlue loadoutsAttribute)+ putLoadoutAttribute (loadoutsAttributeOrange loadoutsAttribute)
@@ -0,0 +1,18 @@+module Rattletrap.Encode.LoadoutsOnlineAttribute+ ( putLoadoutsOnlineAttribute+ )+where++import Rattletrap.Encode.LoadoutOnlineAttribute+import Rattletrap.Type.LoadoutsOnlineAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putLoadoutsOnlineAttribute :: LoadoutsOnlineAttribute -> BinaryBits.BitPut ()+putLoadoutsOnlineAttribute loadoutsOnlineAttribute = do+ putLoadoutOnlineAttribute+ (loadoutsOnlineAttributeBlue loadoutsOnlineAttribute)+ putLoadoutOnlineAttribute+ (loadoutsOnlineAttributeOrange loadoutsOnlineAttribute)+ BinaryBits.putBool (loadoutsOnlineAttributeUnknown1 loadoutsOnlineAttribute)+ BinaryBits.putBool (loadoutsOnlineAttributeUnknown2 loadoutsOnlineAttribute)
@@ -0,0 +1,13 @@+module Rattletrap.Encode.LocationAttribute+ ( putLocationAttribute+ )+where++import Rattletrap.Encode.Vector+import Rattletrap.Type.LocationAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putLocationAttribute :: LocationAttribute -> BinaryBits.BitPut ()+putLocationAttribute locationAttribute =+ putVector (locationAttributeValue locationAttribute)
@@ -0,0 +1,15 @@+module Rattletrap.Encode.Mark+ ( putMark+ )+where++import Rattletrap.Encode.Str+import Rattletrap.Encode.Word32le+import Rattletrap.Type.Mark++import qualified Data.Binary as Binary++putMark :: Mark -> Binary.Put+putMark mark = do+ putText (markValue mark)+ putWord32 (markFrame mark)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.Message+ ( putMessage+ )+where++import Rattletrap.Encode.Str+import Rattletrap.Encode.Word32le+import Rattletrap.Type.Message++import qualified Data.Binary as Binary++putMessage :: Message -> Binary.Put+putMessage message = do+ putWord32 (messageFrame message)+ putText (messageName message)+ putText (messageValue message)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.MusicStingerAttribute+ ( putMusicStingerAttribute+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Encode.Word8le+import Rattletrap.Type.MusicStingerAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putMusicStingerAttribute :: MusicStingerAttribute -> BinaryBits.BitPut ()+putMusicStingerAttribute musicStingerAttribute = do+ BinaryBits.putBool (musicStingerAttributeFlag musicStingerAttribute)+ putWord32Bits (musicStingerAttributeCue musicStingerAttribute)+ putWord8Bits (musicStingerAttributeTrigger musicStingerAttribute)
@@ -0,0 +1,19 @@+module Rattletrap.Encode.PartyLeaderAttribute+ ( putPartyLeaderAttribute+ )+where++import Rattletrap.Encode.RemoteId+import Rattletrap.Encode.Word8le+import Rattletrap.Type.PartyLeaderAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putPartyLeaderAttribute :: PartyLeaderAttribute -> BinaryBits.BitPut ()+putPartyLeaderAttribute partyLeaderAttribute = do+ putWord8Bits (partyLeaderAttributeSystemId partyLeaderAttribute)+ case partyLeaderAttributeId partyLeaderAttribute of+ Nothing -> pure ()+ Just (remoteId, localId) -> do+ putRemoteId remoteId+ putWord8Bits localId
@@ -0,0 +1,18 @@+module Rattletrap.Encode.PickupAttribute+ ( putPickupAttribute+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Type.PickupAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putPickupAttribute :: PickupAttribute -> BinaryBits.BitPut ()+putPickupAttribute pickupAttribute = do+ case pickupAttributeInstigatorId pickupAttribute of+ Nothing -> BinaryBits.putBool False+ Just instigatorId -> do+ BinaryBits.putBool True+ putWord32Bits instigatorId+ BinaryBits.putBool (pickupAttributePickedUp pickupAttribute)
@@ -0,0 +1,19 @@+module Rattletrap.Encode.PickupAttributeNew+ ( putPickupAttributeNew+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Encode.Word8le+import Rattletrap.Type.PickupAttributeNew++import qualified Data.Binary.Bits.Put as BinaryBits++putPickupAttributeNew :: PickupAttributeNew -> BinaryBits.BitPut ()+putPickupAttributeNew pickupAttributeNew = do+ case pickupAttributeNewInstigatorId pickupAttributeNew of+ Nothing -> BinaryBits.putBool False+ Just instigatorId -> do+ BinaryBits.putBool True+ putWord32Bits instigatorId+ putWord8Bits (pickupAttributeNewPickedUp pickupAttributeNew)
@@ -0,0 +1,13 @@+module Rattletrap.Encode.PlayerHistoryKeyAttribute+ ( putPlayerHistoryKeyAttribute+ )+where++import Rattletrap.Encode.Common+import Rattletrap.Type.PlayerHistoryKeyAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putPlayerHistoryKeyAttribute+ :: PlayerHistoryKeyAttribute -> BinaryBits.BitPut ()+putPlayerHistoryKeyAttribute = putBitsLE 14 . playerHistoryKeyAttributeUnknown
@@ -0,0 +1,26 @@+module Rattletrap.Encode.PrivateMatchSettingsAttribute+ ( putPrivateMatchSettingsAttribute+ )+where++import Rattletrap.Encode.Str+import Rattletrap.Encode.Word32le+import Rattletrap.Type.PrivateMatchSettingsAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putPrivateMatchSettingsAttribute+ :: PrivateMatchSettingsAttribute -> BinaryBits.BitPut ()+putPrivateMatchSettingsAttribute privateMatchSettingsAttribute = do+ putTextBits+ (privateMatchSettingsAttributeMutators privateMatchSettingsAttribute)+ putWord32Bits+ (privateMatchSettingsAttributeJoinableBy privateMatchSettingsAttribute)+ putWord32Bits+ (privateMatchSettingsAttributeMaxPlayers privateMatchSettingsAttribute)+ putTextBits+ (privateMatchSettingsAttributeGameName privateMatchSettingsAttribute)+ putTextBits+ (privateMatchSettingsAttributePassword privateMatchSettingsAttribute)+ BinaryBits.putBool+ (privateMatchSettingsAttributeFlag privateMatchSettingsAttribute)
@@ -0,0 +1,37 @@+module Rattletrap.Encode.ProductAttribute+ ( putProductAttributes+ )+where++import Rattletrap.Encode.Common+import Rattletrap.Encode.CompressedWord+import Rattletrap.Encode.Word32le+import Rattletrap.Encode.Word8le+import Rattletrap.Encode.Str+import Rattletrap.Type.ProductAttribute+import Rattletrap.Type.Word8le++import qualified Data.Binary.Bits.Put as BinaryBits++putProductAttributes :: [ProductAttribute] -> BinaryBits.BitPut ()+putProductAttributes attributes = do+ putWord8Bits (Word8le (fromIntegral (length attributes)))+ mapM_ putProductAttribute attributes++putProductAttribute :: ProductAttribute -> BinaryBits.BitPut ()+putProductAttribute attribute = do+ BinaryBits.putBool (productAttributeUnknown attribute)+ putWord32Bits (productAttributeObjectId attribute)+ case productAttributeValue attribute of+ ProductAttributeValuePaintedOld x -> putCompressedWord x+ ProductAttributeValuePaintedNew x -> putBitsLE 31 x+ ProductAttributeValueTeamEditionOld x -> putCompressedWord x+ ProductAttributeValueTeamEditionNew x -> putBitsLE 31 x+ ProductAttributeValueSpecialEdition x -> putBitsLE 31 x+ ProductAttributeValueUserColorOld x -> case x of+ Nothing -> BinaryBits.putBool False+ Just y -> do+ BinaryBits.putBool True+ putBitsLE 31 y+ ProductAttributeValueUserColorNew x -> putWord32Bits x+ ProductAttributeValueTitleId x -> putTextBits x
@@ -0,0 +1,17 @@+module Rattletrap.Encode.Property+ ( putProperty+ )+where++import Rattletrap.Encode.PropertyValue+import Rattletrap.Encode.Str+import Rattletrap.Encode.Word64le+import Rattletrap.Type.Property++import qualified Data.Binary as Binary++putProperty :: Property -> Binary.Put+putProperty property = do+ putText (propertyKind property)+ putWord64 (propertySize property)+ putPropertyValue putProperty (propertyValue property)
@@ -0,0 +1,30 @@+module Rattletrap.Encode.PropertyValue+ ( putPropertyValue+ )+where++import Rattletrap.Encode.Dictionary+import Rattletrap.Encode.Float32le+import Rattletrap.Encode.Int32le+import Rattletrap.Encode.List+import Rattletrap.Encode.Str+import Rattletrap.Encode.Word64le+import Rattletrap.Encode.Word8le+import Rattletrap.Type.PropertyValue++import qualified Data.Binary as Binary++putPropertyValue :: (a -> Binary.Put) -> PropertyValue a -> Binary.Put+putPropertyValue putProperty value = case value of+ PropertyValueArray list -> putList (putDictionary putProperty) list+ PropertyValueBool word8 -> putWord8 word8+ PropertyValueByte k mv -> do+ putText k+ case mv of+ Nothing -> pure ()+ Just v -> putText v+ PropertyValueFloat float32 -> putFloat32 float32+ PropertyValueInt int32 -> putInt32 int32+ PropertyValueName text -> putText text+ PropertyValueQWord word64 -> putWord64 word64+ PropertyValueStr text -> putText text
@@ -0,0 +1,13 @@+module Rattletrap.Encode.QWordAttribute+ ( putQWordAttribute+ )+where++import Rattletrap.Encode.Word64le+import Rattletrap.Type.QWordAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putQWordAttribute :: QWordAttribute -> BinaryBits.BitPut ()+putQWordAttribute qWordAttribute =+ putWord64Bits (qWordAttributeValue qWordAttribute)
@@ -0,0 +1,41 @@+module Rattletrap.Encode.Quaternion+ ( putQuaternion+ )+where++import Rattletrap.Encode.CompressedWord+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Quaternion++import qualified Data.Binary.Bits.Put as BinaryBits++putQuaternion :: Quaternion -> BinaryBits.BitPut ()+putQuaternion q = do+ let c = maxComponent q+ putComponent c+ case c of+ ComponentX -> putParts (quaternionY q) (quaternionZ q) (quaternionW q)+ ComponentY -> putParts (quaternionX q) (quaternionZ q) (quaternionW q)+ ComponentZ -> putParts (quaternionX q) (quaternionY q) (quaternionW q)+ ComponentW -> putParts (quaternionX q) (quaternionY q) (quaternionZ q)++putComponent :: Component -> BinaryBits.BitPut ()+putComponent component = putCompressedWord+ (CompressedWord+ 3+ (case component of+ ComponentX -> 0+ ComponentY -> 1+ ComponentZ -> 2+ ComponentW -> 3+ )+ )++putParts :: Double -> Double -> Double -> BinaryBits.BitPut ()+putParts a b c = do+ putPart a+ putPart b+ putPart c++putPart :: Double -> BinaryBits.BitPut ()+putPart = putCompressedWord . compressPart
@@ -0,0 +1,37 @@+module Rattletrap.Encode.RemoteId+ ( putRemoteId+ )+where++import Rattletrap.Encode.Common+import Rattletrap.Encode.Str+import Rattletrap.Encode.Word64le+import Rattletrap.Type.RemoteId+import Rattletrap.Type.Word64le+import Rattletrap.Utility.Bytes++import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.ByteString as Bytes++putRemoteId :: RemoteId -> BinaryBits.BitPut ()+putRemoteId remoteId = case remoteId of+ RemoteIdPlayStation name bytes -> do+ let rawName = reverseBytes (padBytes (16 :: Int) (encodeLatin1 name))+ BinaryBits.putByteString rawName+ BinaryBits.putByteString (Bytes.pack bytes)+ RemoteIdPsyNet e -> case e of+ Left l -> putWord64Bits l+ Right (a, b, c, d) -> putWord256 a b c d+ RemoteIdSplitscreen word24 -> putBitsLE 24 word24+ RemoteIdSteam word64 -> putWord64Bits word64+ RemoteIdSwitch a b c d -> putWord256 a b c d+ RemoteIdXbox word64 -> putWord64Bits word64+ RemoteIdEpic str -> putTextBits str++putWord256+ :: Word64le -> Word64le -> Word64le -> Word64le -> BinaryBits.BitPut ()+putWord256 a b c d = do+ putWord64Bits a+ putWord64Bits b+ putWord64Bits c+ putWord64Bits d
@@ -0,0 +1,21 @@+module Rattletrap.Encode.Replay+ ( putReplay+ )+where++import Rattletrap.Encode.Content+import Rattletrap.Encode.Header+import Rattletrap.Encode.Section+import Rattletrap.Type.Replay++import qualified Data.Binary as Binary++-- | Generates a raw replay. Use this with 'Data.Binary.Put.runPut'.+--+-- @+-- let bytes = 'Data.Binary.Put.runPut' ('putReplay' replay)+-- @+putReplay :: FullReplay -> Binary.Put+putReplay replay = do+ putSection putHeader (replayHeader replay)+ putSection putContent (replayContent replay)
@@ -0,0 +1,26 @@+module Rattletrap.Encode.Replication+ ( putReplications+ )+where++import Rattletrap.Encode.CompressedWord+import Rattletrap.Encode.ReplicationValue+import Rattletrap.Type.Replication++import qualified Data.Binary.Bits.Put as BinaryBits++putReplications :: [Replication] -> BinaryBits.BitPut ()+putReplications replications = case replications of+ [] -> BinaryBits.putBool False+ [replication] -> do+ putReplication replication+ BinaryBits.putBool False+ first : rest -> do+ putReplication first+ putReplications rest++putReplication :: Replication -> BinaryBits.BitPut ()+putReplication replication = do+ BinaryBits.putBool True+ putCompressedWord (replicationActorId replication)+ putReplicationValue (replicationValue replication)
@@ -0,0 +1,25 @@+module Rattletrap.Encode.ReplicationValue+ ( putReplicationValue+ )+where++import Rattletrap.Encode.DestroyedReplication+import Rattletrap.Encode.SpawnedReplication+import Rattletrap.Encode.UpdatedReplication+import Rattletrap.Type.ReplicationValue++import qualified Data.Binary.Bits.Put as BinaryBits++putReplicationValue :: ReplicationValue -> BinaryBits.BitPut ()+putReplicationValue value = case value of+ ReplicationValueSpawned x -> do+ BinaryBits.putBool True+ BinaryBits.putBool True+ putSpawnedReplication x+ ReplicationValueUpdated x -> do+ BinaryBits.putBool True+ BinaryBits.putBool False+ putUpdatedReplication x+ ReplicationValueDestroyed x -> do+ BinaryBits.putBool False+ putDestroyedReplication x
@@ -0,0 +1,24 @@+module Rattletrap.Encode.ReservationAttribute+ ( putReservationAttribute+ )+where++import Rattletrap.Encode.CompressedWord+import Rattletrap.Encode.Str+import Rattletrap.Encode.UniqueIdAttribute+import Rattletrap.Type.ReservationAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putReservationAttribute :: ReservationAttribute -> BinaryBits.BitPut ()+putReservationAttribute reservationAttribute = do+ putCompressedWord (reservationAttributeNumber reservationAttribute)+ putUniqueIdAttribute (reservationAttributeUniqueId reservationAttribute)+ case reservationAttributeName reservationAttribute of+ Nothing -> pure ()+ Just name -> putTextBits name+ BinaryBits.putBool (reservationAttributeUnknown1 reservationAttribute)+ BinaryBits.putBool (reservationAttributeUnknown2 reservationAttribute)+ case reservationAttributeUnknown3 reservationAttribute of+ Nothing -> pure ()+ Just c -> BinaryBits.putWord8 6 c
@@ -0,0 +1,22 @@+module Rattletrap.Encode.RigidBodyStateAttribute+ ( putRigidBodyStateAttribute+ )+where++import Rattletrap.Encode.Rotation+import Rattletrap.Encode.Vector+import Rattletrap.Type.RigidBodyStateAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putRigidBodyStateAttribute :: RigidBodyStateAttribute -> BinaryBits.BitPut ()+putRigidBodyStateAttribute rigidBodyStateAttribute = do+ BinaryBits.putBool (rigidBodyStateAttributeSleeping rigidBodyStateAttribute)+ putVector (rigidBodyStateAttributeLocation rigidBodyStateAttribute)+ putRotation (rigidBodyStateAttributeRotation rigidBodyStateAttribute)+ case rigidBodyStateAttributeLinearVelocity rigidBodyStateAttribute of+ Nothing -> pure ()+ Just linearVelocity -> putVector linearVelocity+ case rigidBodyStateAttributeAngularVelocity rigidBodyStateAttribute of+ Nothing -> pure ()+ Just angularVelocity -> putVector angularVelocity
@@ -0,0 +1,15 @@+module Rattletrap.Encode.Rotation+ ( putRotation+ )+where++import Rattletrap.Encode.CompressedWordVector+import Rattletrap.Encode.Quaternion+import Rattletrap.Type.Rotation++import qualified Data.Binary.Bits.Put as BinaryBits++putRotation :: Rotation -> BinaryBits.BitPut ()+putRotation r = case r of+ RotationCompressedWordVector cwv -> putCompressedWordVector cwv+ RotationQuaternion q -> putQuaternion q
@@ -0,0 +1,31 @@+module Rattletrap.Encode.Section+ ( putSection+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Type.Section+import Rattletrap.Type.Word32le+import Rattletrap.Utility.Crc++import qualified Data.Binary as Binary+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString as Bytes+import qualified Data.ByteString.Lazy as LazyBytes++-- | Given a way to put the 'sectionBody', puts a section. This will also put+-- the size and CRC.+--+-- @+-- let bytes = 'Data.Binary.Put.runPut' ('putSection' 'Rattletrap.Content.putContent' content)+-- @+putSection :: (a -> Binary.Put) -> Section a -> Binary.Put+putSection putBody section = do+ let+ rawBody =+ LazyBytes.toStrict (Binary.runPut (putBody (sectionBody section)))+ let size = Bytes.length rawBody+ let crc = getCrc32 rawBody+ putWord32 (Word32le (fromIntegral size))+ putWord32 (Word32le crc)+ Binary.putByteString rawBody
@@ -0,0 +1,19 @@+module Rattletrap.Encode.SpawnedReplication+ ( putSpawnedReplication+ )+where++import Rattletrap.Encode.Initialization+import Rattletrap.Encode.Word32le+import Rattletrap.Type.SpawnedReplication++import qualified Data.Binary.Bits.Put as BinaryBits++putSpawnedReplication :: SpawnedReplication -> BinaryBits.BitPut ()+putSpawnedReplication spawnedReplication = do+ BinaryBits.putBool (spawnedReplicationFlag spawnedReplication)+ case spawnedReplicationNameIndex spawnedReplication of+ Nothing -> pure ()+ Just nameIndex -> putWord32Bits nameIndex+ putWord32Bits (spawnedReplicationObjectId spawnedReplication)+ putInitialization (spawnedReplicationInitialization spawnedReplication)
@@ -0,0 +1,14 @@+module Rattletrap.Encode.StatEventAttribute+ ( putStatEventAttribute+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Type.StatEventAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putStatEventAttribute :: StatEventAttribute -> BinaryBits.BitPut ()+putStatEventAttribute statEventAttribute = do+ BinaryBits.putBool (statEventAttributeUnknown statEventAttribute)+ putInt32Bits (statEventAttributeObjectId statEventAttribute)
@@ -0,0 +1,53 @@+module Rattletrap.Encode.Str+ ( putText+ , putTextBits+ )+where++import Rattletrap.Encode.Int32le+import Rattletrap.Type.Common+import Rattletrap.Type.Int32le+import Rattletrap.Type.Str+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString as Bytes+import qualified Data.Char as Char+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text++putText :: Str -> Binary.Put+putText text = do+ let size = getTextSize text+ let encode = getTextEncoder size+ putInt32 size+ Binary.putByteString (encode (addNull (strValue text)))++putTextBits :: Str -> BinaryBits.BitPut ()+putTextBits text = do+ let size = getTextSize text+ let encode = getTextEncoder size+ putInt32Bits size+ BinaryBits.putByteString (reverseBytes (encode (addNull (strValue text))))++getTextSize :: Str -> Int32le+getTextSize text =+ let+ value = strValue text+ scale = if Text.all Char.isLatin1 value then 1 else -1 :: Int32+ rawSize = if Text.null value+ then 0+ else fromIntegral (Text.length value) + 1 :: Int32+ size = if value == Text.pack "\x00\x00\x00None"+ then 0x05000000+ else scale * rawSize :: Int32+ in Int32le size++getTextEncoder :: Int32le -> Text.Text -> Bytes.ByteString+getTextEncoder size text =+ if size < Int32le 0 then Text.encodeUtf16LE text else encodeLatin1 text++addNull :: Text.Text -> Text.Text+addNull text = if Text.null text then text else Text.snoc text '\x00'
@@ -0,0 +1,13 @@+module Rattletrap.Encode.StringAttribute+ ( putStringAttribute+ )+where++import Rattletrap.Encode.Str+import Rattletrap.Type.StringAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putStringAttribute :: StringAttribute -> BinaryBits.BitPut ()+putStringAttribute stringAttribute =+ putTextBits (stringAttributeValue stringAttribute)
@@ -0,0 +1,18 @@+module Rattletrap.Encode.TeamPaintAttribute+ ( putTeamPaintAttribute+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Encode.Word8le+import Rattletrap.Type.TeamPaintAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putTeamPaintAttribute :: TeamPaintAttribute -> BinaryBits.BitPut ()+putTeamPaintAttribute teamPaintAttribute = do+ putWord8Bits (teamPaintAttributeTeam teamPaintAttribute)+ putWord8Bits (teamPaintAttributePrimaryColor teamPaintAttribute)+ putWord8Bits (teamPaintAttributeAccentColor teamPaintAttribute)+ putWord32Bits (teamPaintAttributePrimaryFinish teamPaintAttribute)+ putWord32Bits (teamPaintAttributeAccentFinish teamPaintAttribute)
@@ -0,0 +1,20 @@+module Rattletrap.Encode.TitleAttribute+ ( putTitleAttribute+ )+where++import Rattletrap.Encode.Word32le+import Rattletrap.Type.TitleAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putTitleAttribute :: TitleAttribute -> BinaryBits.BitPut ()+putTitleAttribute titleAttribute = do+ BinaryBits.putBool (titleAttributeUnknown1 titleAttribute)+ BinaryBits.putBool (titleAttributeUnknown2 titleAttribute)+ putWord32Bits (titleAttributeUnknown3 titleAttribute)+ putWord32Bits (titleAttributeUnknown4 titleAttribute)+ putWord32Bits (titleAttributeUnknown5 titleAttribute)+ putWord32Bits (titleAttributeUnknown6 titleAttribute)+ putWord32Bits (titleAttributeUnknown7 titleAttribute)+ BinaryBits.putBool (titleAttributeUnknown8 titleAttribute)
@@ -0,0 +1,16 @@+module Rattletrap.Encode.UniqueIdAttribute+ ( putUniqueIdAttribute+ )+where++import Rattletrap.Encode.RemoteId+import Rattletrap.Encode.Word8le+import Rattletrap.Type.UniqueIdAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putUniqueIdAttribute :: UniqueIdAttribute -> BinaryBits.BitPut ()+putUniqueIdAttribute uniqueIdAttribute = do+ putWord8Bits (uniqueIdAttributeSystemId uniqueIdAttribute)+ putRemoteId (uniqueIdAttributeRemoteId uniqueIdAttribute)+ putWord8Bits (uniqueIdAttributeLocalId uniqueIdAttribute)
@@ -0,0 +1,13 @@+module Rattletrap.Encode.UpdatedReplication+ ( putUpdatedReplication+ )+where++import Rattletrap.Encode.Attribute+import Rattletrap.Type.UpdatedReplication++import qualified Data.Binary.Bits.Put as BinaryBits++putUpdatedReplication :: UpdatedReplication -> BinaryBits.BitPut ()+putUpdatedReplication updatedReplication =+ putAttributes (updatedReplicationAttributes updatedReplication)
@@ -0,0 +1,27 @@+module Rattletrap.Encode.Vector+ ( putVector+ )+where++import Rattletrap.Encode.CompressedWord+import Rattletrap.Type.CompressedWord+import Rattletrap.Type.Vector++import qualified Data.Binary.Bits.Put as BinaryBits++putVector :: Vector -> BinaryBits.BitPut ()+putVector vector = do+ let+ bitSize =+ round (logBase (2 :: Float) (fromIntegral (vectorBias vector))) - 1 :: Word+ dx =+ fromIntegral (vectorX vector + fromIntegral (vectorBias vector)) :: Word+ dy =+ fromIntegral (vectorY vector + fromIntegral (vectorBias vector)) :: Word+ dz =+ fromIntegral (vectorZ vector + fromIntegral (vectorBias vector)) :: Word+ limit = 2 ^ (bitSize + 2) :: Word+ putCompressedWord (vectorSize vector)+ putCompressedWord (CompressedWord limit dx)+ putCompressedWord (CompressedWord limit dy)+ putCompressedWord (CompressedWord limit dz)
@@ -0,0 +1,20 @@+module Rattletrap.Encode.WeldedInfoAttribute+ ( putWeldedInfoAttribute+ )+where++import Rattletrap.Encode.Float32le+import Rattletrap.Encode.Int32le+import Rattletrap.Encode.Int8Vector+import Rattletrap.Encode.Vector+import Rattletrap.Type.WeldedInfoAttribute++import qualified Data.Binary.Bits.Put as BinaryBits++putWeldedInfoAttribute :: WeldedInfoAttribute -> BinaryBits.BitPut ()+putWeldedInfoAttribute weldedInfoAttribute = do+ BinaryBits.putBool (weldedInfoAttributeActive weldedInfoAttribute)+ putInt32Bits (weldedInfoAttributeActorId weldedInfoAttribute)+ putVector (weldedInfoAttributeOffset weldedInfoAttribute)+ putFloat32Bits (weldedInfoAttributeMass weldedInfoAttribute)+ putInt8Vector (weldedInfoAttributeRotation weldedInfoAttribute)
@@ -0,0 +1,21 @@+module Rattletrap.Encode.Word32le+ ( putWord32+ , putWord32Bits+ )+where++import Rattletrap.Type.Word32le+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putWord32 :: Word32le -> Binary.Put+putWord32 word32 = Binary.putWord32le (word32leValue word32)++putWord32Bits :: Word32le -> BinaryBits.BitPut ()+putWord32Bits word32 = do+ let bytes = LazyBytes.toStrict (Binary.runPut (putWord32 word32))+ BinaryBits.putByteString (reverseBytes bytes)
@@ -0,0 +1,21 @@+module Rattletrap.Encode.Word64le+ ( putWord64+ , putWord64Bits+ )+where++import Rattletrap.Type.Word64le+import Rattletrap.Utility.Bytes++import qualified Data.Binary as Binary+import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.ByteString.Lazy as LazyBytes++putWord64 :: Word64le -> Binary.Put+putWord64 word64 = Binary.putWord64le (word64leValue word64)++putWord64Bits :: Word64le -> BinaryBits.BitPut ()+putWord64Bits word64 = do+ let bytes = LazyBytes.toStrict (Binary.runPut (putWord64 word64))+ BinaryBits.putByteString (reverseBytes bytes)
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff