rattletrap 9.4.1 → 10.0.0
raw patch · 305 files changed
+6364/−6357 lines, 305 filesdep +arraydep −scientificdep −template-haskelldep −temporaryPVP ok
version bump matches the API change (PVP)
Dependencies added: array
Dependencies removed: scientific, template-haskell, temporary
API changes (from Hackage documentation)
- Rattletrap: AppliedDamageAttribute :: Word8le -> Vector -> Int32le -> Int32le -> AppliedDamageAttribute
- Rattletrap: Attribute :: CompressedWord -> Str -> AttributeValue -> Attribute
- Rattletrap: AttributeMapping :: Word32le -> Word32le -> AttributeMapping
- Rattletrap: AttributeTypeAppliedDamage :: AttributeType
- Rattletrap: AttributeTypeBoolean :: AttributeType
- Rattletrap: AttributeTypeByte :: AttributeType
- Rattletrap: AttributeTypeCamSettings :: AttributeType
- Rattletrap: AttributeTypeClubColors :: AttributeType
- Rattletrap: AttributeTypeCustomDemolish :: AttributeType
- Rattletrap: AttributeTypeDamageState :: AttributeType
- Rattletrap: AttributeTypeDemolish :: AttributeType
- Rattletrap: AttributeTypeEnum :: AttributeType
- Rattletrap: AttributeTypeExplosion :: AttributeType
- Rattletrap: AttributeTypeExtendedExplosion :: AttributeType
- Rattletrap: AttributeTypeFlaggedByte :: AttributeType
- Rattletrap: AttributeTypeFlaggedInt :: AttributeType
- Rattletrap: AttributeTypeFloat :: AttributeType
- Rattletrap: AttributeTypeGameMode :: AttributeType
- Rattletrap: AttributeTypeInt :: AttributeType
- Rattletrap: AttributeTypeInt64 :: AttributeType
- Rattletrap: AttributeTypeLoadout :: AttributeType
- Rattletrap: AttributeTypeLoadoutOnline :: AttributeType
- Rattletrap: AttributeTypeLoadouts :: AttributeType
- Rattletrap: AttributeTypeLoadoutsOnline :: AttributeType
- Rattletrap: AttributeTypeLocation :: AttributeType
- Rattletrap: AttributeTypeMusicStinger :: AttributeType
- Rattletrap: AttributeTypePartyLeader :: AttributeType
- Rattletrap: AttributeTypePickup :: AttributeType
- Rattletrap: AttributeTypePickupNew :: AttributeType
- Rattletrap: AttributeTypePlayerHistoryKey :: AttributeType
- Rattletrap: AttributeTypePrivateMatchSettings :: AttributeType
- Rattletrap: AttributeTypeQWord :: AttributeType
- Rattletrap: AttributeTypeReservation :: AttributeType
- Rattletrap: AttributeTypeRigidBodyState :: AttributeType
- Rattletrap: AttributeTypeStatEvent :: AttributeType
- Rattletrap: AttributeTypeString :: AttributeType
- Rattletrap: AttributeTypeTeamPaint :: AttributeType
- Rattletrap: AttributeTypeTitle :: AttributeType
- Rattletrap: AttributeTypeUniqueId :: AttributeType
- Rattletrap: AttributeTypeWeldedInfo :: AttributeType
- Rattletrap: AttributeValueAppliedDamage :: AppliedDamageAttribute -> AttributeValue
- Rattletrap: AttributeValueBoolean :: BooleanAttribute -> AttributeValue
- Rattletrap: AttributeValueByte :: ByteAttribute -> AttributeValue
- Rattletrap: AttributeValueCamSettings :: CamSettingsAttribute -> AttributeValue
- Rattletrap: AttributeValueClubColors :: ClubColorsAttribute -> AttributeValue
- Rattletrap: AttributeValueCustomDemolish :: CustomDemolishAttribute -> AttributeValue
- Rattletrap: AttributeValueDamageState :: DamageStateAttribute -> AttributeValue
- Rattletrap: AttributeValueDemolish :: DemolishAttribute -> AttributeValue
- Rattletrap: AttributeValueEnum :: EnumAttribute -> AttributeValue
- Rattletrap: AttributeValueExplosion :: ExplosionAttribute -> AttributeValue
- Rattletrap: AttributeValueExtendedExplosion :: ExtendedExplosionAttribute -> AttributeValue
- Rattletrap: AttributeValueFlaggedByte :: FlaggedByteAttribute -> AttributeValue
- Rattletrap: AttributeValueFlaggedInt :: FlaggedIntAttribute -> AttributeValue
- Rattletrap: AttributeValueFloat :: FloatAttribute -> AttributeValue
- Rattletrap: AttributeValueGameMode :: GameModeAttribute -> AttributeValue
- Rattletrap: AttributeValueInt :: IntAttribute -> AttributeValue
- Rattletrap: AttributeValueInt64 :: Int64Attribute -> AttributeValue
- Rattletrap: AttributeValueLoadout :: LoadoutAttribute -> AttributeValue
- Rattletrap: AttributeValueLoadoutOnline :: LoadoutOnlineAttribute -> AttributeValue
- Rattletrap: AttributeValueLoadouts :: LoadoutsAttribute -> AttributeValue
- Rattletrap: AttributeValueLoadoutsOnline :: LoadoutsOnlineAttribute -> AttributeValue
- Rattletrap: AttributeValueLocation :: LocationAttribute -> AttributeValue
- Rattletrap: AttributeValueMusicStinger :: MusicStingerAttribute -> AttributeValue
- Rattletrap: AttributeValuePartyLeader :: PartyLeaderAttribute -> AttributeValue
- Rattletrap: AttributeValuePickup :: PickupAttribute -> AttributeValue
- Rattletrap: AttributeValuePickupNew :: PickupAttributeNew -> AttributeValue
- Rattletrap: AttributeValuePlayerHistoryKey :: PlayerHistoryKeyAttribute -> AttributeValue
- Rattletrap: AttributeValuePrivateMatchSettings :: PrivateMatchSettingsAttribute -> AttributeValue
- Rattletrap: AttributeValueQWord :: QWordAttribute -> AttributeValue
- Rattletrap: AttributeValueReservation :: ReservationAttribute -> AttributeValue
- Rattletrap: AttributeValueRigidBodyState :: RigidBodyStateAttribute -> AttributeValue
- Rattletrap: AttributeValueStatEvent :: StatEventAttribute -> AttributeValue
- Rattletrap: AttributeValueString :: StringAttribute -> AttributeValue
- Rattletrap: AttributeValueTeamPaint :: TeamPaintAttribute -> AttributeValue
- Rattletrap: AttributeValueTitle :: TitleAttribute -> AttributeValue
- Rattletrap: AttributeValueUniqueId :: UniqueIdAttribute -> AttributeValue
- Rattletrap: AttributeValueWeldedInfo :: WeldedInfoAttribute -> AttributeValue
- Rattletrap: BooleanAttribute :: Bool -> BooleanAttribute
- Rattletrap: ByteAttribute :: Word8le -> ByteAttribute
- Rattletrap: Cache :: Word32le -> Word32le -> Word32le -> List AttributeMapping -> Cache
- Rattletrap: CamSettingsAttribute :: Float32le -> Float32le -> Float32le -> Float32le -> Float32le -> Float32le -> Maybe Float32le -> CamSettingsAttribute
- Rattletrap: ClassAttributeMap :: Map Word32le Str -> Map Word32le Word32le -> Map Word32le (Map Word32le Word32le) -> IntMap Str -> ClassAttributeMap
- Rattletrap: ClassMapping :: Str -> Word32le -> ClassMapping
- Rattletrap: ClubColorsAttribute :: Bool -> Word8le -> Bool -> Word8le -> ClubColorsAttribute
- Rattletrap: CompressedWord :: Word -> Word -> CompressedWord
- Rattletrap: CompressedWordVector :: CompressedWord -> CompressedWord -> CompressedWord -> CompressedWordVector
- Rattletrap: Content :: List Str -> List KeyFrame -> Word32le -> [Frame] -> List Message -> List Mark -> List Str -> List Str -> List Str -> List ClassMapping -> List Cache -> [Word8] -> Content
- Rattletrap: DamageStateAttribute :: Word8le -> Bool -> Int32le -> Vector -> Bool -> Bool -> DamageStateAttribute
- Rattletrap: DemolishAttribute :: Bool -> Word32le -> Bool -> Word32le -> Vector -> Vector -> DemolishAttribute
- Rattletrap: DestroyedReplication :: DestroyedReplication
- Rattletrap: DictionaryElement :: Str -> a -> Dictionary a -> Dictionary a
- Rattletrap: DictionaryEnd :: Str -> Dictionary a
- Rattletrap: EnumAttribute :: Word16 -> EnumAttribute
- Rattletrap: ExplosionAttribute :: Bool -> Int32le -> Vector -> ExplosionAttribute
- Rattletrap: ExtendedExplosionAttribute :: ExplosionAttribute -> FlaggedIntAttribute -> ExtendedExplosionAttribute
- Rattletrap: FlaggedIntAttribute :: Bool -> Int32le -> FlaggedIntAttribute
- Rattletrap: Float32le :: Float -> Float32le
- Rattletrap: FloatAttribute :: Float32le -> FloatAttribute
- Rattletrap: Frame :: Float32le -> Float32le -> [Replication] -> Frame
- Rattletrap: GameModeAttribute :: Int -> Word8 -> GameModeAttribute
- Rattletrap: Header :: Word32le -> Word32le -> Maybe Word32le -> Str -> Dictionary Property -> Header
- Rattletrap: Initialization :: Maybe Vector -> Maybe Int8Vector -> Initialization
- Rattletrap: Int32le :: Int32 -> Int32le
- Rattletrap: Int64Attribute :: Int64le -> Int64Attribute
- Rattletrap: Int64le :: Int64 -> Int64le
- Rattletrap: Int8Vector :: Maybe Int8le -> Maybe Int8le -> Maybe Int8le -> Int8Vector
- Rattletrap: Int8le :: Int8 -> Int8le
- Rattletrap: IntAttribute :: Int32le -> IntAttribute
- Rattletrap: KeyFrame :: Float32le -> Word32le -> Word32le -> KeyFrame
- Rattletrap: List :: [a] -> List a
- Rattletrap: LoadoutAttribute :: Word8le -> Word32le -> Word32le -> Word32le -> Word32le -> Word32le -> Word32le -> Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> Maybe Word32le -> LoadoutAttribute
- Rattletrap: LoadoutOnlineAttribute :: [[ProductAttribute]] -> LoadoutOnlineAttribute
- Rattletrap: LoadoutsAttribute :: LoadoutAttribute -> LoadoutAttribute -> LoadoutsAttribute
- Rattletrap: LoadoutsOnlineAttribute :: LoadoutOnlineAttribute -> LoadoutOnlineAttribute -> Bool -> Bool -> LoadoutsOnlineAttribute
- Rattletrap: LocationAttribute :: Vector -> LocationAttribute
- Rattletrap: Mark :: Str -> Word32le -> Mark
- Rattletrap: Message :: Word32le -> Str -> Str -> Message
- Rattletrap: MusicStingerAttribute :: Bool -> Word32le -> Word8le -> MusicStingerAttribute
- Rattletrap: PartyLeaderAttribute :: Word8le -> Maybe (RemoteId, Word8le) -> PartyLeaderAttribute
- Rattletrap: PickupAttribute :: Maybe Word32le -> Bool -> PickupAttribute
- Rattletrap: PlayerHistoryKeyAttribute :: Word16 -> PlayerHistoryKeyAttribute
- Rattletrap: PrivateMatchSettingsAttribute :: Str -> Word32le -> Word32le -> Str -> Str -> Bool -> PrivateMatchSettingsAttribute
- Rattletrap: ProductAttribute :: Bool -> Word32le -> Maybe Str -> ProductAttributeValue -> ProductAttribute
- Rattletrap: Property :: Str -> Word64le -> PropertyValue Property -> Property
- Rattletrap: PropertyValueArray :: List (Dictionary a) -> PropertyValue a
- Rattletrap: PropertyValueBool :: Word8le -> PropertyValue a
- Rattletrap: PropertyValueByte :: Str -> Maybe Str -> PropertyValue a
- Rattletrap: PropertyValueFloat :: Float32le -> PropertyValue a
- Rattletrap: PropertyValueInt :: Int32le -> PropertyValue a
- Rattletrap: PropertyValueName :: Str -> PropertyValue a
- Rattletrap: PropertyValueQWord :: Word64le -> PropertyValue a
- Rattletrap: PropertyValueStr :: Str -> PropertyValue a
- Rattletrap: QWordAttribute :: Word64le -> QWordAttribute
- Rattletrap: Quaternion :: Double -> Double -> Double -> Double -> Quaternion
- Rattletrap: RemoteIdEpic :: Str -> RemoteId
- Rattletrap: RemoteIdPlayStation :: Text -> [Word8] -> RemoteId
- Rattletrap: RemoteIdPsyNet :: Either Word64le (Word64le, Word64le, Word64le, Word64le) -> RemoteId
- Rattletrap: RemoteIdSplitscreen :: Word32 -> RemoteId
- Rattletrap: RemoteIdSteam :: Word64le -> RemoteId
- Rattletrap: RemoteIdSwitch :: Word64le -> Word64le -> Word64le -> Word64le -> RemoteId
- Rattletrap: RemoteIdXbox :: Word64le -> RemoteId
- Rattletrap: Replay :: Section Header -> Section content -> Replay content
- Rattletrap: Replication :: CompressedWord -> ReplicationValue -> Replication
- Rattletrap: ReplicationValueDestroyed :: DestroyedReplication -> ReplicationValue
- Rattletrap: ReplicationValueSpawned :: SpawnedReplication -> ReplicationValue
- Rattletrap: ReplicationValueUpdated :: UpdatedReplication -> ReplicationValue
- Rattletrap: ReservationAttribute :: CompressedWord -> UniqueIdAttribute -> Maybe Str -> Bool -> Bool -> Maybe Word8 -> ReservationAttribute
- Rattletrap: RigidBodyStateAttribute :: Bool -> Vector -> Rotation -> Maybe Vector -> Maybe Vector -> RigidBodyStateAttribute
- Rattletrap: RotationCompressedWordVector :: CompressedWordVector -> Rotation
- Rattletrap: RotationQuaternion :: Quaternion -> Rotation
- Rattletrap: Section :: Word32le -> Word32le -> a -> Section a
- Rattletrap: SpawnedReplication :: Bool -> Maybe Word32le -> Maybe Str -> Word32le -> Str -> Str -> Initialization -> SpawnedReplication
- Rattletrap: StatEventAttribute :: Bool -> Int32le -> StatEventAttribute
- Rattletrap: Str :: Text -> Str
- Rattletrap: StringAttribute :: Str -> StringAttribute
- Rattletrap: TeamPaintAttribute :: Word8le -> Word8le -> Word8le -> Word32le -> Word32le -> TeamPaintAttribute
- Rattletrap: TitleAttribute :: Bool -> Bool -> Word32le -> Word32le -> Word32le -> Word32le -> Word32le -> Bool -> TitleAttribute
- Rattletrap: UniqueIdAttribute :: Word8le -> RemoteId -> Word8le -> UniqueIdAttribute
- Rattletrap: UpdatedReplication :: [Attribute] -> UpdatedReplication
- Rattletrap: Vector :: CompressedWord -> Word -> Int -> Int -> Int -> Vector
- Rattletrap: WeldedInfoAttribute :: Bool -> Int32le -> Vector -> Float32le -> Int8Vector -> WeldedInfoAttribute
- Rattletrap: Word32le :: Word32 -> Word32le
- Rattletrap: Word64le :: Word64 -> Word64le
- Rattletrap: Word8le :: Word8 -> Word8le
- Rattletrap: [appliedDamageAttributeLocation] :: AppliedDamageAttribute -> Vector
- Rattletrap: [appliedDamageAttributeUnknown1] :: AppliedDamageAttribute -> Word8le
- Rattletrap: [appliedDamageAttributeUnknown3] :: AppliedDamageAttribute -> Int32le
- Rattletrap: [appliedDamageAttributeUnknown4] :: AppliedDamageAttribute -> Int32le
- Rattletrap: [attributeId] :: Attribute -> CompressedWord
- Rattletrap: [attributeMappingObjectId] :: AttributeMapping -> Word32le
- Rattletrap: [attributeMappingStreamId] :: AttributeMapping -> Word32le
- Rattletrap: [attributeName] :: Attribute -> Str
- Rattletrap: [attributeValue] :: Attribute -> AttributeValue
- Rattletrap: [booleanAttributeValue] :: BooleanAttribute -> Bool
- Rattletrap: [byteAttributeValue] :: ByteAttribute -> Word8le
- Rattletrap: [cacheAttributeMappings] :: Cache -> List AttributeMapping
- Rattletrap: [cacheCacheId] :: Cache -> Word32le
- Rattletrap: [cacheClassId] :: Cache -> Word32le
- Rattletrap: [cacheParentCacheId] :: Cache -> Word32le
- Rattletrap: [camSettingsAttributeAngle] :: CamSettingsAttribute -> Float32le
- Rattletrap: [camSettingsAttributeDistance] :: CamSettingsAttribute -> Float32le
- Rattletrap: [camSettingsAttributeFov] :: CamSettingsAttribute -> Float32le
- Rattletrap: [camSettingsAttributeHeight] :: CamSettingsAttribute -> Float32le
- Rattletrap: [camSettingsAttributeStiffness] :: CamSettingsAttribute -> Float32le
- Rattletrap: [camSettingsAttributeSwivelSpeed] :: CamSettingsAttribute -> Float32le
- Rattletrap: [camSettingsAttributeTransitionSpeed] :: CamSettingsAttribute -> Maybe Float32le
- Rattletrap: [classAttributeMapNameMap] :: ClassAttributeMap -> IntMap Str
- Rattletrap: [classAttributeMapObjectClassMap] :: ClassAttributeMap -> Map Word32le Word32le
- Rattletrap: [classAttributeMapObjectMap] :: ClassAttributeMap -> Map Word32le Str
- Rattletrap: [classAttributeMapValue] :: ClassAttributeMap -> Map Word32le (Map Word32le Word32le)
- Rattletrap: [classMappingName] :: ClassMapping -> Str
- Rattletrap: [classMappingStreamId] :: ClassMapping -> Word32le
- Rattletrap: [clubColorsAttributeBlueColor] :: ClubColorsAttribute -> Word8le
- Rattletrap: [clubColorsAttributeBlueFlag] :: ClubColorsAttribute -> Bool
- Rattletrap: [clubColorsAttributeOrangeColor] :: ClubColorsAttribute -> Word8le
- Rattletrap: [clubColorsAttributeOrangeFlag] :: ClubColorsAttribute -> Bool
- Rattletrap: [compressedWordLimit] :: CompressedWord -> Word
- Rattletrap: [compressedWordValue] :: CompressedWord -> Word
- Rattletrap: [compressedWordVectorX] :: CompressedWordVector -> CompressedWord
- Rattletrap: [compressedWordVectorY] :: CompressedWordVector -> CompressedWord
- Rattletrap: [compressedWordVectorZ] :: CompressedWordVector -> CompressedWord
- Rattletrap: [contentCaches] :: Content -> List Cache
- Rattletrap: [contentClassMappings] :: Content -> List ClassMapping
- Rattletrap: [contentFrames] :: Content -> [Frame]
- Rattletrap: [contentKeyFrames] :: Content -> List KeyFrame
- Rattletrap: [contentLevels] :: Content -> List Str
- Rattletrap: [contentMarks] :: Content -> List Mark
- Rattletrap: [contentMessages] :: Content -> List Message
- Rattletrap: [contentNames] :: Content -> List Str
- Rattletrap: [contentObjects] :: Content -> List Str
- Rattletrap: [contentPackages] :: Content -> List Str
- Rattletrap: [contentStreamSize] :: Content -> Word32le
- Rattletrap: [contentUnknown] :: Content -> [Word8]
- Rattletrap: [damageStateAttributeUnknown1] :: DamageStateAttribute -> Word8le
- Rattletrap: [damageStateAttributeUnknown2] :: DamageStateAttribute -> Bool
- Rattletrap: [damageStateAttributeUnknown3] :: DamageStateAttribute -> Int32le
- Rattletrap: [damageStateAttributeUnknown4] :: DamageStateAttribute -> Vector
- Rattletrap: [damageStateAttributeUnknown5] :: DamageStateAttribute -> Bool
- Rattletrap: [damageStateAttributeUnknown6] :: DamageStateAttribute -> Bool
- Rattletrap: [demolishAttributeAttackerActorId] :: DemolishAttribute -> Word32le
- Rattletrap: [demolishAttributeAttackerFlag] :: DemolishAttribute -> Bool
- Rattletrap: [demolishAttributeAttackerVelocity] :: DemolishAttribute -> Vector
- Rattletrap: [demolishAttributeVictimActorId] :: DemolishAttribute -> Word32le
- Rattletrap: [demolishAttributeVictimFlag] :: DemolishAttribute -> Bool
- Rattletrap: [demolishAttributeVictimVelocity] :: DemolishAttribute -> Vector
- Rattletrap: [enumAttributeValue] :: EnumAttribute -> Word16
- Rattletrap: [explosionAttributeActorId] :: ExplosionAttribute -> Int32le
- Rattletrap: [explosionAttributeFlag] :: ExplosionAttribute -> Bool
- Rattletrap: [explosionAttributeLocation] :: ExplosionAttribute -> Vector
- Rattletrap: [extendedExplosionAttributeExplosion] :: ExtendedExplosionAttribute -> ExplosionAttribute
- Rattletrap: [extendedExplosionAttributeUnknown] :: ExtendedExplosionAttribute -> FlaggedIntAttribute
- Rattletrap: [flaggedIntAttributeFlag] :: FlaggedIntAttribute -> Bool
- Rattletrap: [flaggedIntAttributeInt] :: FlaggedIntAttribute -> Int32le
- Rattletrap: [float32leValue] :: Float32le -> Float
- Rattletrap: [floatAttributeValue] :: FloatAttribute -> Float32le
- Rattletrap: [frameDelta] :: Frame -> Float32le
- Rattletrap: [frameReplications] :: Frame -> [Replication]
- Rattletrap: [frameTime] :: Frame -> Float32le
- Rattletrap: [gameModeAttributeNumBits] :: GameModeAttribute -> Int
- Rattletrap: [gameModeAttributeWord] :: GameModeAttribute -> Word8
- Rattletrap: [headerEngineVersion] :: Header -> Word32le
- Rattletrap: [headerLabel] :: Header -> Str
- Rattletrap: [headerLicenseeVersion] :: Header -> Word32le
- Rattletrap: [headerPatchVersion] :: Header -> Maybe Word32le
- Rattletrap: [headerProperties] :: Header -> Dictionary Property
- Rattletrap: [initializationLocation] :: Initialization -> Maybe Vector
- Rattletrap: [initializationRotation] :: Initialization -> Maybe Int8Vector
- Rattletrap: [int32leValue] :: Int32le -> Int32
- Rattletrap: [int64AttributeValue] :: Int64Attribute -> Int64le
- Rattletrap: [int64leValue] :: Int64le -> Int64
- Rattletrap: [int8VectorX] :: Int8Vector -> Maybe Int8le
- Rattletrap: [int8VectorY] :: Int8Vector -> Maybe Int8le
- Rattletrap: [int8VectorZ] :: Int8Vector -> Maybe Int8le
- Rattletrap: [int8leValue] :: Int8le -> Int8
- Rattletrap: [intAttributeValue] :: IntAttribute -> Int32le
- Rattletrap: [keyFrameFrame] :: KeyFrame -> Word32le
- Rattletrap: [keyFramePosition] :: KeyFrame -> Word32le
- Rattletrap: [keyFrameTime] :: KeyFrame -> Float32le
- Rattletrap: [listValue] :: List a -> [a]
- Rattletrap: [loadoutAttributeAntenna] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutAttributeBanner] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeBody] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutAttributeDecal] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutAttributeEngineAudio] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeGoalExplosion] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeRocketTrail] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutAttributeTopper] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutAttributeTrail] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeUnknown1] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutAttributeUnknown2] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeUnknown3] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeUnknown4] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeUnknown5] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeUnknown6] :: LoadoutAttribute -> Maybe Word32le
- Rattletrap: [loadoutAttributeValue] :: LoadoutOnlineAttribute -> [[ProductAttribute]]
- Rattletrap: [loadoutAttributeVersion] :: LoadoutAttribute -> Word8le
- Rattletrap: [loadoutAttributeWheels] :: LoadoutAttribute -> Word32le
- Rattletrap: [loadoutsAttributeBlue] :: LoadoutsAttribute -> LoadoutAttribute
- Rattletrap: [loadoutsAttributeOrange] :: LoadoutsAttribute -> LoadoutAttribute
- Rattletrap: [loadoutsOnlineAttributeBlue] :: LoadoutsOnlineAttribute -> LoadoutOnlineAttribute
- Rattletrap: [loadoutsOnlineAttributeOrange] :: LoadoutsOnlineAttribute -> LoadoutOnlineAttribute
- Rattletrap: [loadoutsOnlineAttributeUnknown1] :: LoadoutsOnlineAttribute -> Bool
- Rattletrap: [loadoutsOnlineAttributeUnknown2] :: LoadoutsOnlineAttribute -> Bool
- Rattletrap: [locationAttributeValue] :: LocationAttribute -> Vector
- Rattletrap: [markFrame] :: Mark -> Word32le
- Rattletrap: [markValue] :: Mark -> Str
- Rattletrap: [messageFrame] :: Message -> Word32le
- Rattletrap: [messageName] :: Message -> Str
- Rattletrap: [messageValue] :: Message -> Str
- Rattletrap: [musicStingerAttributeCue] :: MusicStingerAttribute -> Word32le
- Rattletrap: [musicStingerAttributeFlag] :: MusicStingerAttribute -> Bool
- Rattletrap: [musicStingerAttributeTrigger] :: MusicStingerAttribute -> Word8le
- Rattletrap: [partyLeaderAttributeId] :: PartyLeaderAttribute -> Maybe (RemoteId, Word8le)
- Rattletrap: [partyLeaderAttributeSystemId] :: PartyLeaderAttribute -> Word8le
- Rattletrap: [pickupAttributeInstigatorId] :: PickupAttribute -> Maybe Word32le
- Rattletrap: [pickupAttributePickedUp] :: PickupAttribute -> Bool
- Rattletrap: [playerHistoryKeyAttributeUnknown] :: PlayerHistoryKeyAttribute -> Word16
- Rattletrap: [privateMatchSettingsAttributeFlag] :: PrivateMatchSettingsAttribute -> Bool
- Rattletrap: [privateMatchSettingsAttributeGameName] :: PrivateMatchSettingsAttribute -> Str
- Rattletrap: [privateMatchSettingsAttributeJoinableBy] :: PrivateMatchSettingsAttribute -> Word32le
- Rattletrap: [privateMatchSettingsAttributeMaxPlayers] :: PrivateMatchSettingsAttribute -> Word32le
- Rattletrap: [privateMatchSettingsAttributeMutators] :: PrivateMatchSettingsAttribute -> Str
- Rattletrap: [privateMatchSettingsAttributePassword] :: PrivateMatchSettingsAttribute -> Str
- Rattletrap: [productAttributeObjectId] :: ProductAttribute -> Word32le
- Rattletrap: [productAttributeObjectName] :: ProductAttribute -> Maybe Str
- Rattletrap: [productAttributeUnknown] :: ProductAttribute -> Bool
- Rattletrap: [productAttributeValue] :: ProductAttribute -> ProductAttributeValue
- Rattletrap: [propertyKind] :: Property -> Str
- Rattletrap: [propertySize] :: Property -> Word64le
- Rattletrap: [propertyValue] :: Property -> PropertyValue Property
- Rattletrap: [qWordAttributeValue] :: QWordAttribute -> Word64le
- Rattletrap: [quaternionW] :: Quaternion -> Double
- Rattletrap: [quaternionX] :: Quaternion -> Double
- Rattletrap: [quaternionY] :: Quaternion -> Double
- Rattletrap: [quaternionZ] :: Quaternion -> Double
- Rattletrap: [replayContent] :: Replay content -> Section content
- Rattletrap: [replayHeader] :: Replay content -> Section Header
- Rattletrap: [replicationActorId] :: Replication -> CompressedWord
- Rattletrap: [replicationValue] :: Replication -> ReplicationValue
- Rattletrap: [reservationAttributeName] :: ReservationAttribute -> Maybe Str
- Rattletrap: [reservationAttributeNumber] :: ReservationAttribute -> CompressedWord
- Rattletrap: [reservationAttributeUniqueId] :: ReservationAttribute -> UniqueIdAttribute
- Rattletrap: [reservationAttributeUnknown1] :: ReservationAttribute -> Bool
- Rattletrap: [reservationAttributeUnknown2] :: ReservationAttribute -> Bool
- Rattletrap: [reservationAttributeUnknown3] :: ReservationAttribute -> Maybe Word8
- Rattletrap: [rigidBodyStateAttributeAngularVelocity] :: RigidBodyStateAttribute -> Maybe Vector
- Rattletrap: [rigidBodyStateAttributeLinearVelocity] :: RigidBodyStateAttribute -> Maybe Vector
- Rattletrap: [rigidBodyStateAttributeLocation] :: RigidBodyStateAttribute -> Vector
- Rattletrap: [rigidBodyStateAttributeRotation] :: RigidBodyStateAttribute -> Rotation
- Rattletrap: [rigidBodyStateAttributeSleeping] :: RigidBodyStateAttribute -> Bool
- Rattletrap: [sectionBody] :: Section a -> a
- Rattletrap: [sectionCrc] :: Section a -> Word32le
- Rattletrap: [sectionSize] :: Section a -> Word32le
- Rattletrap: [spawnedReplicationClassName] :: SpawnedReplication -> Str
- Rattletrap: [spawnedReplicationFlag] :: SpawnedReplication -> Bool
- Rattletrap: [spawnedReplicationInitialization] :: SpawnedReplication -> Initialization
- Rattletrap: [spawnedReplicationNameIndex] :: SpawnedReplication -> Maybe Word32le
- Rattletrap: [spawnedReplicationName] :: SpawnedReplication -> Maybe Str
- Rattletrap: [spawnedReplicationObjectId] :: SpawnedReplication -> Word32le
- Rattletrap: [spawnedReplicationObjectName] :: SpawnedReplication -> Str
- Rattletrap: [statEventAttributeObjectId] :: StatEventAttribute -> Int32le
- Rattletrap: [statEventAttributeUnknown] :: StatEventAttribute -> Bool
- Rattletrap: [strValue] :: Str -> Text
- Rattletrap: [stringAttributeValue] :: StringAttribute -> Str
- Rattletrap: [teamPaintAttributeAccentColor] :: TeamPaintAttribute -> Word8le
- Rattletrap: [teamPaintAttributeAccentFinish] :: TeamPaintAttribute -> Word32le
- Rattletrap: [teamPaintAttributePrimaryColor] :: TeamPaintAttribute -> Word8le
- Rattletrap: [teamPaintAttributePrimaryFinish] :: TeamPaintAttribute -> Word32le
- Rattletrap: [teamPaintAttributeTeam] :: TeamPaintAttribute -> Word8le
- Rattletrap: [titleAttributeUnknown1] :: TitleAttribute -> Bool
- Rattletrap: [titleAttributeUnknown2] :: TitleAttribute -> Bool
- Rattletrap: [titleAttributeUnknown3] :: TitleAttribute -> Word32le
- Rattletrap: [titleAttributeUnknown4] :: TitleAttribute -> Word32le
- Rattletrap: [titleAttributeUnknown5] :: TitleAttribute -> Word32le
- Rattletrap: [titleAttributeUnknown6] :: TitleAttribute -> Word32le
- Rattletrap: [titleAttributeUnknown7] :: TitleAttribute -> Word32le
- Rattletrap: [titleAttributeUnknown8] :: TitleAttribute -> Bool
- Rattletrap: [uniqueIdAttributeLocalId] :: UniqueIdAttribute -> Word8le
- Rattletrap: [uniqueIdAttributeRemoteId] :: UniqueIdAttribute -> RemoteId
- Rattletrap: [uniqueIdAttributeSystemId] :: UniqueIdAttribute -> Word8le
- Rattletrap: [updatedReplicationAttributes] :: UpdatedReplication -> [Attribute]
- Rattletrap: [vectorBias] :: Vector -> Word
- Rattletrap: [vectorSize] :: Vector -> CompressedWord
- Rattletrap: [vectorX] :: Vector -> Int
- Rattletrap: [vectorY] :: Vector -> Int
- Rattletrap: [vectorZ] :: Vector -> Int
- Rattletrap: [weldedInfoAttributeActive] :: WeldedInfoAttribute -> Bool
- Rattletrap: [weldedInfoAttributeActorId] :: WeldedInfoAttribute -> Int32le
- Rattletrap: [weldedInfoAttributeMass] :: WeldedInfoAttribute -> Float32le
- Rattletrap: [weldedInfoAttributeOffset] :: WeldedInfoAttribute -> Vector
- Rattletrap: [weldedInfoAttributeRotation] :: WeldedInfoAttribute -> Int8Vector
- Rattletrap: [word32leValue] :: Word32le -> Word32
- Rattletrap: [word64leValue] :: Word64le -> Word64
- Rattletrap: [word8leValue] :: Word8le -> Word8
- Rattletrap: data AppliedDamageAttribute
- Rattletrap: data Attribute
- Rattletrap: data AttributeMapping
- Rattletrap: data AttributeType
- Rattletrap: data AttributeValue
- Rattletrap: data Cache
- Rattletrap: data CamSettingsAttribute
- Rattletrap: data ClassAttributeMap
- Rattletrap: data ClassMapping
- Rattletrap: data ClubColorsAttribute
- Rattletrap: data CompressedWord
- Rattletrap: data CompressedWordVector
- Rattletrap: data Content
- Rattletrap: data DamageStateAttribute
- Rattletrap: data DemolishAttribute
- Rattletrap: data DestroyedReplication
- Rattletrap: data Dictionary a
- Rattletrap: data ExplosionAttribute
- Rattletrap: data ExtendedExplosionAttribute
- Rattletrap: data FlaggedIntAttribute
- Rattletrap: data Frame
- Rattletrap: data GameModeAttribute
- Rattletrap: data Header
- Rattletrap: data Initialization
- Rattletrap: data Int8Vector
- Rattletrap: data KeyFrame
- Rattletrap: data LoadoutAttribute
- Rattletrap: data LoadoutsAttribute
- Rattletrap: data LoadoutsOnlineAttribute
- Rattletrap: data Mark
- Rattletrap: data Message
- Rattletrap: data MusicStingerAttribute
- Rattletrap: data PartyLeaderAttribute
- Rattletrap: data PickupAttribute
- Rattletrap: data PrivateMatchSettingsAttribute
- Rattletrap: data ProductAttribute
- Rattletrap: data Property
- Rattletrap: data PropertyValue a
- Rattletrap: data Quaternion
- Rattletrap: data RemoteId
- Rattletrap: data Replay content
- Rattletrap: data Replication
- Rattletrap: data ReplicationValue
- Rattletrap: data ReservationAttribute
- Rattletrap: data RigidBodyStateAttribute
- Rattletrap: data Rotation
- Rattletrap: data Section a
- Rattletrap: data SpawnedReplication
- Rattletrap: data StatEventAttribute
- Rattletrap: data TeamPaintAttribute
- Rattletrap: data TitleAttribute
- Rattletrap: data UniqueIdAttribute
- Rattletrap: data Vector
- Rattletrap: data WeldedInfoAttribute
- Rattletrap: newtype BooleanAttribute
- Rattletrap: newtype ByteAttribute
- Rattletrap: newtype EnumAttribute
- Rattletrap: newtype Float32le
- Rattletrap: newtype FloatAttribute
- Rattletrap: newtype Int32le
- Rattletrap: newtype Int64Attribute
- Rattletrap: newtype Int64le
- Rattletrap: newtype Int8le
- Rattletrap: newtype IntAttribute
- Rattletrap: newtype List a
- Rattletrap: newtype LoadoutOnlineAttribute
- Rattletrap: newtype LocationAttribute
- Rattletrap: newtype PlayerHistoryKeyAttribute
- Rattletrap: newtype QWordAttribute
- Rattletrap: newtype Str
- Rattletrap: newtype StringAttribute
- Rattletrap: newtype UpdatedReplication
- Rattletrap: newtype Word32le
- Rattletrap: newtype Word64le
- Rattletrap: newtype Word8le
+ Paths_rattletrap: getBinDir :: IO FilePath
+ Paths_rattletrap: getDataDir :: IO FilePath
+ Paths_rattletrap: getDataFileName :: FilePath -> IO FilePath
+ Paths_rattletrap: getDynLibDir :: IO FilePath
+ Paths_rattletrap: getLibDir :: IO FilePath
+ Paths_rattletrap: getLibexecDir :: IO FilePath
+ Paths_rattletrap: getSysconfDir :: IO FilePath
+ Paths_rattletrap: version :: Version
+ Rattletrap.BitGet: binaryGetToByteGet :: Get a -> ByteGet a
+ Rattletrap.BitGet: bits :: Bits a => Int -> BitGet a
+ Rattletrap.BitGet: bool :: BitGet Bool
+ Rattletrap.BitGet: byteString :: Int -> BitGet ByteString
+ Rattletrap.BitGet: fromByteGet :: ByteGet a -> Int -> BitGet a
+ Rattletrap.BitGet: toByteGet :: BitGet a -> ByteGet a
+ Rattletrap.BitGet: type BitGet = BitGet
+ Rattletrap.BitGet: word8 :: Int -> BitGet Word8
+ Rattletrap.BitPut: BitPut :: BitPut () -> BitPut
+ Rattletrap.BitPut: bits :: Bits a => Int -> a -> BitPut
+ Rattletrap.BitPut: bool :: Bool -> BitPut
+ Rattletrap.BitPut: byteString :: ByteString -> BitPut
+ Rattletrap.BitPut: fromBinaryBits :: BitPut () -> BitPut
+ Rattletrap.BitPut: fromBytePut :: BytePut -> BitPut
+ Rattletrap.BitPut: instance GHC.Base.Monoid Rattletrap.BitPut.BitPut
+ Rattletrap.BitPut: instance GHC.Base.Semigroup Rattletrap.BitPut.BitPut
+ Rattletrap.BitPut: newtype BitPut
+ Rattletrap.BitPut: toBinaryBits :: BitPut -> BitPut ()
+ Rattletrap.BitPut: toBytePut :: BitPut -> BytePut
+ Rattletrap.BitPut: word8 :: Int -> Word8 -> BitPut
+ Rattletrap.ByteGet: byteString :: Int -> ByteGet ByteString
+ Rattletrap.ByteGet: float :: ByteGet Float
+ Rattletrap.ByteGet: int32 :: ByteGet Int32
+ Rattletrap.ByteGet: int64 :: ByteGet Int64
+ Rattletrap.ByteGet: int8 :: ByteGet Int8
+ Rattletrap.ByteGet: remaining :: ByteGet ByteString
+ Rattletrap.ByteGet: run :: ByteGet a -> ByteString -> Either String a
+ Rattletrap.ByteGet: type ByteGet = Get ByteString Identity
+ Rattletrap.ByteGet: word32 :: ByteGet Word32
+ Rattletrap.ByteGet: word64 :: ByteGet Word64
+ Rattletrap.ByteGet: word8 :: ByteGet Word8
+ Rattletrap.BytePut: byteString :: ByteString -> BytePut
+ Rattletrap.BytePut: float :: Float -> BytePut
+ Rattletrap.BytePut: int32 :: Int32 -> BytePut
+ Rattletrap.BytePut: int64 :: Int64 -> BytePut
+ Rattletrap.BytePut: int8 :: Int8 -> BytePut
+ Rattletrap.BytePut: toByteString :: BytePut -> ByteString
+ Rattletrap.BytePut: toLazyByteString :: BytePut -> ByteString
+ Rattletrap.BytePut: type BytePut = Builder
+ Rattletrap.BytePut: word32 :: Word32 -> BytePut
+ Rattletrap.BytePut: word64 :: Word64 -> BytePut
+ Rattletrap.BytePut: word8 :: Word8 -> BytePut
+ Rattletrap.Console.Config: Config :: Bool -> Bool -> Bool -> Maybe String -> Maybe Mode -> Maybe String -> Bool -> Bool -> Bool -> Config
+ Rattletrap.Console.Config: [compact] :: Config -> Bool
+ Rattletrap.Console.Config: [fast] :: Config -> Bool
+ Rattletrap.Console.Config: [help] :: Config -> Bool
+ Rattletrap.Console.Config: [input] :: Config -> Maybe String
+ Rattletrap.Console.Config: [mode] :: Config -> Maybe Mode
+ Rattletrap.Console.Config: [output] :: Config -> Maybe String
+ Rattletrap.Console.Config: [schema] :: Config -> Bool
+ Rattletrap.Console.Config: [skipCrc] :: Config -> Bool
+ Rattletrap.Console.Config: [version] :: Config -> Bool
+ Rattletrap.Console.Config: applyFlag :: Config -> Flag -> Either String Config
+ Rattletrap.Console.Config: data Config
+ Rattletrap.Console.Config: getMode :: Config -> Mode
+ Rattletrap.Console.Config: initial :: Config
+ Rattletrap.Console.Config: instance GHC.Classes.Eq Rattletrap.Console.Config.Config
+ Rattletrap.Console.Config: instance GHC.Show.Show Rattletrap.Console.Config.Config
+ Rattletrap.Console.Flag: Compact :: Flag
+ Rattletrap.Console.Flag: Fast :: Flag
+ Rattletrap.Console.Flag: Help :: Flag
+ Rattletrap.Console.Flag: Input :: FilePath -> Flag
+ Rattletrap.Console.Flag: Mode :: String -> Flag
+ Rattletrap.Console.Flag: Output :: FilePath -> Flag
+ Rattletrap.Console.Flag: Schema :: Flag
+ Rattletrap.Console.Flag: SkipCrc :: Flag
+ Rattletrap.Console.Flag: Version :: Flag
+ Rattletrap.Console.Flag: data Flag
+ Rattletrap.Console.Flag: instance GHC.Classes.Eq Rattletrap.Console.Flag.Flag
+ Rattletrap.Console.Flag: instance GHC.Show.Show Rattletrap.Console.Flag.Flag
+ Rattletrap.Console.Main: main :: IO ()
+ Rattletrap.Console.Main: rattletrap :: String -> [String] -> IO ()
+ Rattletrap.Console.Mode: Decode :: Mode
+ Rattletrap.Console.Mode: Encode :: Mode
+ Rattletrap.Console.Mode: data Mode
+ Rattletrap.Console.Mode: fromString :: String -> Either String Mode
+ Rattletrap.Console.Mode: instance GHC.Classes.Eq Rattletrap.Console.Mode.Mode
+ Rattletrap.Console.Mode: instance GHC.Show.Show Rattletrap.Console.Mode.Mode
+ Rattletrap.Console.Option: all :: [Option]
+ Rattletrap.Console.Option: compact :: Option
+ Rattletrap.Console.Option: fast :: Option
+ Rattletrap.Console.Option: help :: Option
+ Rattletrap.Console.Option: input :: Option
+ Rattletrap.Console.Option: mode :: Option
+ Rattletrap.Console.Option: output :: Option
+ Rattletrap.Console.Option: schema :: Option
+ Rattletrap.Console.Option: skipCrc :: Option
+ Rattletrap.Console.Option: type Option = OptDescr Flag
+ Rattletrap.Console.Option: version :: Option
+ Rattletrap.Data: attributeTypes :: Map Text AttributeType
+ Rattletrap.Data: classesWithLocation :: Set Text
+ Rattletrap.Data: classesWithRotation :: Set Text
+ Rattletrap.Data: objectClasses :: Map Text Text
+ Rattletrap.Data: parentClasses :: Map Text Text
+ Rattletrap.Get: Get :: (s -> m (Either String (s, a))) -> Get s m a
+ Rattletrap.Get: get :: Applicative m => Get s m s
+ Rattletrap.Get: instance GHC.Base.Functor m => GHC.Base.Functor (Rattletrap.Get.Get s m)
+ Rattletrap.Get: instance GHC.Base.Monad m => Control.Monad.Fail.MonadFail (Rattletrap.Get.Get s m)
+ Rattletrap.Get: instance GHC.Base.Monad m => GHC.Base.Alternative (Rattletrap.Get.Get s m)
+ Rattletrap.Get: instance GHC.Base.Monad m => GHC.Base.Applicative (Rattletrap.Get.Get s m)
+ Rattletrap.Get: instance GHC.Base.Monad m => GHC.Base.Monad (Rattletrap.Get.Get s m)
+ Rattletrap.Get: lift :: Functor m => m a -> Get s m a
+ Rattletrap.Get: newtype Get s m a
+ Rattletrap.Get: put :: Applicative m => s -> Get s m ()
+ Rattletrap.Get: run :: Get s m a -> s -> m (Either String (s, a))
+ Rattletrap.Schema: Schema :: Text -> Value -> Schema
+ Rattletrap.Schema: [json] :: Schema -> Value
+ Rattletrap.Schema: [name] :: Schema -> Text
+ Rattletrap.Schema: array :: Schema -> Schema
+ Rattletrap.Schema: boolean :: Schema
+ Rattletrap.Schema: data Schema
+ Rattletrap.Schema: instance GHC.Classes.Eq Rattletrap.Schema.Schema
+ Rattletrap.Schema: instance GHC.Show.Show Rattletrap.Schema.Schema
+ Rattletrap.Schema: integer :: Schema
+ Rattletrap.Schema: maybe :: Schema -> Schema
+ Rattletrap.Schema: named :: String -> Value -> Schema
+ Rattletrap.Schema: null :: Schema
+ Rattletrap.Schema: number :: Schema
+ Rattletrap.Schema: object :: [((Text, Value), Bool)] -> Value
+ Rattletrap.Schema: oneOf :: [Value] -> Value
+ Rattletrap.Schema: ref :: Schema -> Value
+ Rattletrap.Schema: string :: Schema
+ Rattletrap.Schema: tuple :: [Value] -> Value
+ Rattletrap.Type.Attribute: Attribute :: CompressedWord -> Str -> AttributeValue -> Attribute
+ Rattletrap.Type.Attribute: [id] :: Attribute -> CompressedWord
+ Rattletrap.Type.Attribute: [name] :: Attribute -> Str
+ Rattletrap.Type.Attribute: [value] :: Attribute -> AttributeValue
+ Rattletrap.Type.Attribute: bitGet :: Version -> ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet Attribute
+ Rattletrap.Type.Attribute: bitPut :: Attribute -> BitPut
+ Rattletrap.Type.Attribute: data Attribute
+ Rattletrap.Type.Attribute: fromMaybe :: String -> Maybe a -> BitGet a
+ Rattletrap.Type.Attribute: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Attribute
+ Rattletrap.Type.Attribute: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Attribute
+ Rattletrap.Type.Attribute: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Attribute
+ Rattletrap.Type.Attribute: instance GHC.Show.Show Rattletrap.Type.Attribute.Attribute
+ Rattletrap.Type.Attribute: lookupAttributeIdLimit :: Map U32 U32 -> CompressedWord -> BitGet Word
+ Rattletrap.Type.Attribute: lookupAttributeMap :: ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet (Map U32 U32)
+ Rattletrap.Type.Attribute: lookupAttributeName :: ClassAttributeMap -> Map U32 U32 -> CompressedWord -> BitGet Str
+ Rattletrap.Type.Attribute: schema :: Schema
+ Rattletrap.Type.Attribute.AppliedDamage: AppliedDamage :: U8 -> Vector -> I32 -> I32 -> AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: [location] :: AppliedDamage -> Vector
+ Rattletrap.Type.Attribute.AppliedDamage: [unknown1] :: AppliedDamage -> U8
+ Rattletrap.Type.Attribute.AppliedDamage: [unknown3] :: AppliedDamage -> I32
+ Rattletrap.Type.Attribute.AppliedDamage: [unknown4] :: AppliedDamage -> I32
+ Rattletrap.Type.Attribute.AppliedDamage: bitGet :: Version -> BitGet AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: bitPut :: AppliedDamage -> BitPut
+ Rattletrap.Type.Attribute.AppliedDamage: data AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.AppliedDamage.AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.AppliedDamage.AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: instance GHC.Classes.Eq Rattletrap.Type.Attribute.AppliedDamage.AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: instance GHC.Show.Show Rattletrap.Type.Attribute.AppliedDamage.AppliedDamage
+ Rattletrap.Type.Attribute.AppliedDamage: schema :: Schema
+ Rattletrap.Type.Attribute.Boolean: Boolean :: Bool -> Boolean
+ Rattletrap.Type.Attribute.Boolean: [value] :: Boolean -> Bool
+ Rattletrap.Type.Attribute.Boolean: bitGet :: BitGet Boolean
+ Rattletrap.Type.Attribute.Boolean: bitPut :: Boolean -> BitPut
+ Rattletrap.Type.Attribute.Boolean: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Boolean.Boolean
+ Rattletrap.Type.Attribute.Boolean: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Boolean.Boolean
+ Rattletrap.Type.Attribute.Boolean: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Boolean.Boolean
+ Rattletrap.Type.Attribute.Boolean: instance GHC.Show.Show Rattletrap.Type.Attribute.Boolean.Boolean
+ Rattletrap.Type.Attribute.Boolean: newtype Boolean
+ Rattletrap.Type.Attribute.Boolean: schema :: Schema
+ Rattletrap.Type.Attribute.Byte: Byte :: U8 -> Byte
+ Rattletrap.Type.Attribute.Byte: [value] :: Byte -> U8
+ Rattletrap.Type.Attribute.Byte: bitGet :: BitGet Byte
+ Rattletrap.Type.Attribute.Byte: bitPut :: Byte -> BitPut
+ Rattletrap.Type.Attribute.Byte: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Byte.Byte
+ Rattletrap.Type.Attribute.Byte: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Byte.Byte
+ Rattletrap.Type.Attribute.Byte: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Byte.Byte
+ Rattletrap.Type.Attribute.Byte: instance GHC.Show.Show Rattletrap.Type.Attribute.Byte.Byte
+ Rattletrap.Type.Attribute.Byte: newtype Byte
+ Rattletrap.Type.Attribute.Byte: schema :: Schema
+ Rattletrap.Type.Attribute.CamSettings: CamSettings :: F32 -> F32 -> F32 -> F32 -> F32 -> F32 -> Maybe F32 -> CamSettings
+ Rattletrap.Type.Attribute.CamSettings: [angle] :: CamSettings -> F32
+ Rattletrap.Type.Attribute.CamSettings: [distance] :: CamSettings -> F32
+ Rattletrap.Type.Attribute.CamSettings: [fov] :: CamSettings -> F32
+ Rattletrap.Type.Attribute.CamSettings: [height] :: CamSettings -> F32
+ Rattletrap.Type.Attribute.CamSettings: [stiffness] :: CamSettings -> F32
+ Rattletrap.Type.Attribute.CamSettings: [swivelSpeed] :: CamSettings -> F32
+ Rattletrap.Type.Attribute.CamSettings: [transitionSpeed] :: CamSettings -> Maybe F32
+ Rattletrap.Type.Attribute.CamSettings: bitGet :: Version -> BitGet CamSettings
+ Rattletrap.Type.Attribute.CamSettings: bitPut :: CamSettings -> BitPut
+ Rattletrap.Type.Attribute.CamSettings: data CamSettings
+ Rattletrap.Type.Attribute.CamSettings: hasTransitionSpeed :: Version -> Bool
+ Rattletrap.Type.Attribute.CamSettings: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.CamSettings.CamSettings
+ Rattletrap.Type.Attribute.CamSettings: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.CamSettings.CamSettings
+ Rattletrap.Type.Attribute.CamSettings: instance GHC.Classes.Eq Rattletrap.Type.Attribute.CamSettings.CamSettings
+ Rattletrap.Type.Attribute.CamSettings: instance GHC.Show.Show Rattletrap.Type.Attribute.CamSettings.CamSettings
+ Rattletrap.Type.Attribute.CamSettings: schema :: Schema
+ Rattletrap.Type.Attribute.ClubColors: ClubColors :: Bool -> U8 -> Bool -> U8 -> ClubColors
+ Rattletrap.Type.Attribute.ClubColors: [blueColor] :: ClubColors -> U8
+ Rattletrap.Type.Attribute.ClubColors: [blueFlag] :: ClubColors -> Bool
+ Rattletrap.Type.Attribute.ClubColors: [orangeColor] :: ClubColors -> U8
+ Rattletrap.Type.Attribute.ClubColors: [orangeFlag] :: ClubColors -> Bool
+ Rattletrap.Type.Attribute.ClubColors: bitGet :: BitGet ClubColors
+ Rattletrap.Type.Attribute.ClubColors: bitPut :: ClubColors -> BitPut
+ Rattletrap.Type.Attribute.ClubColors: data ClubColors
+ Rattletrap.Type.Attribute.ClubColors: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.ClubColors.ClubColors
+ Rattletrap.Type.Attribute.ClubColors: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.ClubColors.ClubColors
+ Rattletrap.Type.Attribute.ClubColors: instance GHC.Classes.Eq Rattletrap.Type.Attribute.ClubColors.ClubColors
+ Rattletrap.Type.Attribute.ClubColors: instance GHC.Show.Show Rattletrap.Type.Attribute.ClubColors.ClubColors
+ Rattletrap.Type.Attribute.ClubColors: schema :: Schema
+ Rattletrap.Type.Attribute.CustomDemolish: CustomDemolish :: Bool -> I32 -> Demolish -> CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: [demolish] :: CustomDemolish -> Demolish
+ Rattletrap.Type.Attribute.CustomDemolish: [flag] :: CustomDemolish -> Bool
+ Rattletrap.Type.Attribute.CustomDemolish: [id] :: CustomDemolish -> I32
+ Rattletrap.Type.Attribute.CustomDemolish: bitGet :: Version -> BitGet CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: bitPut :: CustomDemolish -> BitPut
+ Rattletrap.Type.Attribute.CustomDemolish: data CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.CustomDemolish.CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.CustomDemolish.CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: instance GHC.Classes.Eq Rattletrap.Type.Attribute.CustomDemolish.CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: instance GHC.Show.Show Rattletrap.Type.Attribute.CustomDemolish.CustomDemolish
+ Rattletrap.Type.Attribute.CustomDemolish: schema :: Schema
+ Rattletrap.Type.Attribute.DamageState: DamageState :: U8 -> Bool -> I32 -> Vector -> Bool -> Bool -> DamageState
+ Rattletrap.Type.Attribute.DamageState: [unknown1] :: DamageState -> U8
+ Rattletrap.Type.Attribute.DamageState: [unknown2] :: DamageState -> Bool
+ Rattletrap.Type.Attribute.DamageState: [unknown3] :: DamageState -> I32
+ Rattletrap.Type.Attribute.DamageState: [unknown4] :: DamageState -> Vector
+ Rattletrap.Type.Attribute.DamageState: [unknown5] :: DamageState -> Bool
+ Rattletrap.Type.Attribute.DamageState: [unknown6] :: DamageState -> Bool
+ Rattletrap.Type.Attribute.DamageState: bitGet :: Version -> BitGet DamageState
+ Rattletrap.Type.Attribute.DamageState: bitPut :: DamageState -> BitPut
+ Rattletrap.Type.Attribute.DamageState: data DamageState
+ Rattletrap.Type.Attribute.DamageState: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.DamageState.DamageState
+ Rattletrap.Type.Attribute.DamageState: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.DamageState.DamageState
+ Rattletrap.Type.Attribute.DamageState: instance GHC.Classes.Eq Rattletrap.Type.Attribute.DamageState.DamageState
+ Rattletrap.Type.Attribute.DamageState: instance GHC.Show.Show Rattletrap.Type.Attribute.DamageState.DamageState
+ Rattletrap.Type.Attribute.DamageState: schema :: Schema
+ Rattletrap.Type.Attribute.Demolish: Demolish :: Bool -> U32 -> Bool -> U32 -> Vector -> Vector -> Demolish
+ Rattletrap.Type.Attribute.Demolish: [attackerActorId] :: Demolish -> U32
+ Rattletrap.Type.Attribute.Demolish: [attackerFlag] :: Demolish -> Bool
+ Rattletrap.Type.Attribute.Demolish: [attackerVelocity] :: Demolish -> Vector
+ Rattletrap.Type.Attribute.Demolish: [victimActorId] :: Demolish -> U32
+ Rattletrap.Type.Attribute.Demolish: [victimFlag] :: Demolish -> Bool
+ Rattletrap.Type.Attribute.Demolish: [victimVelocity] :: Demolish -> Vector
+ Rattletrap.Type.Attribute.Demolish: bitGet :: Version -> BitGet Demolish
+ Rattletrap.Type.Attribute.Demolish: bitPut :: Demolish -> BitPut
+ Rattletrap.Type.Attribute.Demolish: data Demolish
+ Rattletrap.Type.Attribute.Demolish: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Demolish.Demolish
+ Rattletrap.Type.Attribute.Demolish: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Demolish.Demolish
+ Rattletrap.Type.Attribute.Demolish: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Demolish.Demolish
+ Rattletrap.Type.Attribute.Demolish: instance GHC.Show.Show Rattletrap.Type.Attribute.Demolish.Demolish
+ Rattletrap.Type.Attribute.Demolish: schema :: Schema
+ Rattletrap.Type.Attribute.Enum: Enum :: Word16 -> Enum
+ Rattletrap.Type.Attribute.Enum: [value] :: Enum -> Word16
+ Rattletrap.Type.Attribute.Enum: bitGet :: BitGet Enum
+ Rattletrap.Type.Attribute.Enum: bitPut :: Enum -> BitPut
+ Rattletrap.Type.Attribute.Enum: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Enum.Enum
+ Rattletrap.Type.Attribute.Enum: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Enum.Enum
+ Rattletrap.Type.Attribute.Enum: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Enum.Enum
+ Rattletrap.Type.Attribute.Enum: instance GHC.Show.Show Rattletrap.Type.Attribute.Enum.Enum
+ Rattletrap.Type.Attribute.Enum: newtype Enum
+ Rattletrap.Type.Attribute.Enum: schema :: Schema
+ Rattletrap.Type.Attribute.Explosion: Explosion :: Bool -> I32 -> Vector -> Explosion
+ Rattletrap.Type.Attribute.Explosion: [actorId] :: Explosion -> I32
+ Rattletrap.Type.Attribute.Explosion: [flag] :: Explosion -> Bool
+ Rattletrap.Type.Attribute.Explosion: [location] :: Explosion -> Vector
+ Rattletrap.Type.Attribute.Explosion: bitGet :: Version -> BitGet Explosion
+ Rattletrap.Type.Attribute.Explosion: bitPut :: Explosion -> BitPut
+ Rattletrap.Type.Attribute.Explosion: data Explosion
+ Rattletrap.Type.Attribute.Explosion: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Explosion.Explosion
+ Rattletrap.Type.Attribute.Explosion: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Explosion.Explosion
+ Rattletrap.Type.Attribute.Explosion: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Explosion.Explosion
+ Rattletrap.Type.Attribute.Explosion: instance GHC.Show.Show Rattletrap.Type.Attribute.Explosion.Explosion
+ Rattletrap.Type.Attribute.Explosion: schema :: Schema
+ Rattletrap.Type.Attribute.ExtendedExplosion: ExtendedExplosion :: Explosion -> FlaggedInt -> ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: [explosion] :: ExtendedExplosion -> Explosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: [unknown] :: ExtendedExplosion -> FlaggedInt
+ Rattletrap.Type.Attribute.ExtendedExplosion: bitGet :: Version -> BitGet ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: bitPut :: ExtendedExplosion -> BitPut
+ Rattletrap.Type.Attribute.ExtendedExplosion: data ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.ExtendedExplosion.ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.ExtendedExplosion.ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: instance GHC.Classes.Eq Rattletrap.Type.Attribute.ExtendedExplosion.ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: instance GHC.Show.Show Rattletrap.Type.Attribute.ExtendedExplosion.ExtendedExplosion
+ Rattletrap.Type.Attribute.ExtendedExplosion: schema :: Schema
+ Rattletrap.Type.Attribute.FlaggedByte: FlaggedByte :: Bool -> U8 -> FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: [byte] :: FlaggedByte -> U8
+ Rattletrap.Type.Attribute.FlaggedByte: [flag] :: FlaggedByte -> Bool
+ Rattletrap.Type.Attribute.FlaggedByte: bitGet :: BitGet FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: bitPut :: FlaggedByte -> BitPut
+ Rattletrap.Type.Attribute.FlaggedByte: data FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.FlaggedByte.FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.FlaggedByte.FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: instance GHC.Classes.Eq Rattletrap.Type.Attribute.FlaggedByte.FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: instance GHC.Show.Show Rattletrap.Type.Attribute.FlaggedByte.FlaggedByte
+ Rattletrap.Type.Attribute.FlaggedByte: schema :: Schema
+ Rattletrap.Type.Attribute.FlaggedInt: FlaggedInt :: Bool -> I32 -> FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: [flag] :: FlaggedInt -> Bool
+ Rattletrap.Type.Attribute.FlaggedInt: [int] :: FlaggedInt -> I32
+ Rattletrap.Type.Attribute.FlaggedInt: bitGet :: BitGet FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: bitPut :: FlaggedInt -> BitPut
+ Rattletrap.Type.Attribute.FlaggedInt: data FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.FlaggedInt.FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.FlaggedInt.FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: instance GHC.Classes.Eq Rattletrap.Type.Attribute.FlaggedInt.FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: instance GHC.Show.Show Rattletrap.Type.Attribute.FlaggedInt.FlaggedInt
+ Rattletrap.Type.Attribute.FlaggedInt: schema :: Schema
+ Rattletrap.Type.Attribute.Float: Float :: F32 -> Float
+ Rattletrap.Type.Attribute.Float: [value] :: Float -> F32
+ Rattletrap.Type.Attribute.Float: bitGet :: BitGet Float
+ Rattletrap.Type.Attribute.Float: bitPut :: Float -> BitPut
+ Rattletrap.Type.Attribute.Float: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Float.Float
+ Rattletrap.Type.Attribute.Float: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Float.Float
+ Rattletrap.Type.Attribute.Float: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Float.Float
+ Rattletrap.Type.Attribute.Float: instance GHC.Show.Show Rattletrap.Type.Attribute.Float.Float
+ Rattletrap.Type.Attribute.Float: newtype Float
+ Rattletrap.Type.Attribute.Float: schema :: Schema
+ Rattletrap.Type.Attribute.GameMode: GameMode :: Int -> Word8 -> GameMode
+ Rattletrap.Type.Attribute.GameMode: [numBits] :: GameMode -> Int
+ Rattletrap.Type.Attribute.GameMode: [word] :: GameMode -> Word8
+ Rattletrap.Type.Attribute.GameMode: bitGet :: Version -> BitGet GameMode
+ Rattletrap.Type.Attribute.GameMode: bitPut :: GameMode -> BitPut
+ Rattletrap.Type.Attribute.GameMode: data GameMode
+ Rattletrap.Type.Attribute.GameMode: has8Bits :: Version -> Bool
+ Rattletrap.Type.Attribute.GameMode: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.GameMode.GameMode
+ Rattletrap.Type.Attribute.GameMode: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.GameMode.GameMode
+ Rattletrap.Type.Attribute.GameMode: instance GHC.Classes.Eq Rattletrap.Type.Attribute.GameMode.GameMode
+ Rattletrap.Type.Attribute.GameMode: instance GHC.Show.Show Rattletrap.Type.Attribute.GameMode.GameMode
+ Rattletrap.Type.Attribute.GameMode: numBits_ :: Version -> Int
+ Rattletrap.Type.Attribute.GameMode: schema :: Schema
+ Rattletrap.Type.Attribute.Int: Int :: I32 -> Int
+ Rattletrap.Type.Attribute.Int: [value] :: Int -> I32
+ Rattletrap.Type.Attribute.Int: bitGet :: BitGet Int
+ Rattletrap.Type.Attribute.Int: bitPut :: Int -> BitPut
+ Rattletrap.Type.Attribute.Int: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Int.Int
+ Rattletrap.Type.Attribute.Int: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Int.Int
+ Rattletrap.Type.Attribute.Int: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Int.Int
+ Rattletrap.Type.Attribute.Int: instance GHC.Show.Show Rattletrap.Type.Attribute.Int.Int
+ Rattletrap.Type.Attribute.Int: newtype Int
+ Rattletrap.Type.Attribute.Int: schema :: Schema
+ Rattletrap.Type.Attribute.Int64: Int64 :: I64 -> Int64
+ Rattletrap.Type.Attribute.Int64: [value] :: Int64 -> I64
+ Rattletrap.Type.Attribute.Int64: bitGet :: BitGet Int64
+ Rattletrap.Type.Attribute.Int64: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Int64.Int64
+ Rattletrap.Type.Attribute.Int64: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Int64.Int64
+ Rattletrap.Type.Attribute.Int64: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Int64.Int64
+ Rattletrap.Type.Attribute.Int64: instance GHC.Show.Show Rattletrap.Type.Attribute.Int64.Int64
+ Rattletrap.Type.Attribute.Int64: newtype Int64
+ Rattletrap.Type.Attribute.Int64: putInt64Attribute :: Int64 -> BitPut
+ Rattletrap.Type.Attribute.Int64: schema :: Schema
+ Rattletrap.Type.Attribute.Loadout: Loadout :: U8 -> U32 -> U32 -> U32 -> U32 -> U32 -> U32 -> U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Maybe U32 -> Loadout
+ Rattletrap.Type.Attribute.Loadout: [antenna] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: [banner] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [body] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: [decal] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: [engineAudio] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [goalExplosion] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [rocketTrail] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: [topper] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: [trail] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [unknown1] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: [unknown2] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [unknown3] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [unknown4] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [unknown5] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [unknown6] :: Loadout -> Maybe U32
+ Rattletrap.Type.Attribute.Loadout: [version] :: Loadout -> U8
+ Rattletrap.Type.Attribute.Loadout: [wheels] :: Loadout -> U32
+ Rattletrap.Type.Attribute.Loadout: bitGet :: BitGet Loadout
+ Rattletrap.Type.Attribute.Loadout: bitPut :: Loadout -> BitPut
+ Rattletrap.Type.Attribute.Loadout: data Loadout
+ Rattletrap.Type.Attribute.Loadout: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Loadout.Loadout
+ Rattletrap.Type.Attribute.Loadout: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Loadout.Loadout
+ Rattletrap.Type.Attribute.Loadout: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Loadout.Loadout
+ Rattletrap.Type.Attribute.Loadout: instance GHC.Show.Show Rattletrap.Type.Attribute.Loadout.Loadout
+ Rattletrap.Type.Attribute.Loadout: schema :: Schema
+ Rattletrap.Type.Attribute.LoadoutOnline: LoadoutOnline :: List (List Product) -> LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: [value] :: LoadoutOnline -> List (List Product)
+ Rattletrap.Type.Attribute.LoadoutOnline: bitGet :: Version -> Map U32 Str -> BitGet LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: bitPut :: LoadoutOnline -> BitPut
+ Rattletrap.Type.Attribute.LoadoutOnline: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.LoadoutOnline.LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.LoadoutOnline.LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: instance GHC.Classes.Eq Rattletrap.Type.Attribute.LoadoutOnline.LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: instance GHC.Show.Show Rattletrap.Type.Attribute.LoadoutOnline.LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: newtype LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutOnline: schema :: Schema
+ Rattletrap.Type.Attribute.Loadouts: Loadouts :: Loadout -> Loadout -> Loadouts
+ Rattletrap.Type.Attribute.Loadouts: [blue] :: Loadouts -> Loadout
+ Rattletrap.Type.Attribute.Loadouts: [orange] :: Loadouts -> Loadout
+ Rattletrap.Type.Attribute.Loadouts: bitGet :: BitGet Loadouts
+ Rattletrap.Type.Attribute.Loadouts: bitPut :: Loadouts -> BitPut
+ Rattletrap.Type.Attribute.Loadouts: data Loadouts
+ Rattletrap.Type.Attribute.Loadouts: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Loadouts.Loadouts
+ Rattletrap.Type.Attribute.Loadouts: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Loadouts.Loadouts
+ Rattletrap.Type.Attribute.Loadouts: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Loadouts.Loadouts
+ Rattletrap.Type.Attribute.Loadouts: instance GHC.Show.Show Rattletrap.Type.Attribute.Loadouts.Loadouts
+ Rattletrap.Type.Attribute.Loadouts: schema :: Schema
+ Rattletrap.Type.Attribute.LoadoutsOnline: LoadoutsOnline :: LoadoutOnline -> LoadoutOnline -> Bool -> Bool -> LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: [blue] :: LoadoutsOnline -> LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: [orange] :: LoadoutsOnline -> LoadoutOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: [unknown1] :: LoadoutsOnline -> Bool
+ Rattletrap.Type.Attribute.LoadoutsOnline: [unknown2] :: LoadoutsOnline -> Bool
+ Rattletrap.Type.Attribute.LoadoutsOnline: bitGet :: Version -> Map U32 Str -> BitGet LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: bitPut :: LoadoutsOnline -> BitPut
+ Rattletrap.Type.Attribute.LoadoutsOnline: data LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.LoadoutsOnline.LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.LoadoutsOnline.LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: instance GHC.Classes.Eq Rattletrap.Type.Attribute.LoadoutsOnline.LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: instance GHC.Show.Show Rattletrap.Type.Attribute.LoadoutsOnline.LoadoutsOnline
+ Rattletrap.Type.Attribute.LoadoutsOnline: schema :: Schema
+ Rattletrap.Type.Attribute.Location: Location :: Vector -> Location
+ Rattletrap.Type.Attribute.Location: [value] :: Location -> Vector
+ Rattletrap.Type.Attribute.Location: bitGet :: Version -> BitGet Location
+ Rattletrap.Type.Attribute.Location: bitPut :: Location -> BitPut
+ Rattletrap.Type.Attribute.Location: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Location.Location
+ Rattletrap.Type.Attribute.Location: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Location.Location
+ Rattletrap.Type.Attribute.Location: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Location.Location
+ Rattletrap.Type.Attribute.Location: instance GHC.Show.Show Rattletrap.Type.Attribute.Location.Location
+ Rattletrap.Type.Attribute.Location: newtype Location
+ Rattletrap.Type.Attribute.Location: schema :: Schema
+ Rattletrap.Type.Attribute.MusicStinger: MusicStinger :: Bool -> U32 -> U8 -> MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: [cue] :: MusicStinger -> U32
+ Rattletrap.Type.Attribute.MusicStinger: [flag] :: MusicStinger -> Bool
+ Rattletrap.Type.Attribute.MusicStinger: [trigger] :: MusicStinger -> U8
+ Rattletrap.Type.Attribute.MusicStinger: bitGet :: BitGet MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: bitPut :: MusicStinger -> BitPut
+ Rattletrap.Type.Attribute.MusicStinger: data MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.MusicStinger.MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.MusicStinger.MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: instance GHC.Classes.Eq Rattletrap.Type.Attribute.MusicStinger.MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: instance GHC.Show.Show Rattletrap.Type.Attribute.MusicStinger.MusicStinger
+ Rattletrap.Type.Attribute.MusicStinger: schema :: Schema
+ Rattletrap.Type.Attribute.PartyLeader: PartyLeader :: U8 -> Maybe (RemoteId, U8) -> PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: [id] :: PartyLeader -> Maybe (RemoteId, U8)
+ Rattletrap.Type.Attribute.PartyLeader: [systemId] :: PartyLeader -> U8
+ Rattletrap.Type.Attribute.PartyLeader: bitGet :: Version -> BitGet PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: bitPut :: PartyLeader -> BitPut
+ Rattletrap.Type.Attribute.PartyLeader: data PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.PartyLeader.PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.PartyLeader.PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: instance GHC.Classes.Eq Rattletrap.Type.Attribute.PartyLeader.PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: instance GHC.Show.Show Rattletrap.Type.Attribute.PartyLeader.PartyLeader
+ Rattletrap.Type.Attribute.PartyLeader: schema :: Schema
+ Rattletrap.Type.Attribute.Pickup: Pickup :: Maybe U32 -> Bool -> Pickup
+ Rattletrap.Type.Attribute.Pickup: [instigatorId] :: Pickup -> Maybe U32
+ Rattletrap.Type.Attribute.Pickup: [pickedUp] :: Pickup -> Bool
+ Rattletrap.Type.Attribute.Pickup: bitGet :: BitGet Pickup
+ Rattletrap.Type.Attribute.Pickup: bitPut :: Pickup -> BitPut
+ Rattletrap.Type.Attribute.Pickup: data Pickup
+ Rattletrap.Type.Attribute.Pickup: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Pickup.Pickup
+ Rattletrap.Type.Attribute.Pickup: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Pickup.Pickup
+ Rattletrap.Type.Attribute.Pickup: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Pickup.Pickup
+ Rattletrap.Type.Attribute.Pickup: instance GHC.Show.Show Rattletrap.Type.Attribute.Pickup.Pickup
+ Rattletrap.Type.Attribute.Pickup: schema :: Schema
+ Rattletrap.Type.Attribute.PickupNew: PickupNew :: Maybe U32 -> U8 -> PickupNew
+ Rattletrap.Type.Attribute.PickupNew: [instigatorId] :: PickupNew -> Maybe U32
+ Rattletrap.Type.Attribute.PickupNew: [pickedUp] :: PickupNew -> U8
+ Rattletrap.Type.Attribute.PickupNew: bitGet :: BitGet PickupNew
+ Rattletrap.Type.Attribute.PickupNew: bitPut :: PickupNew -> BitPut
+ Rattletrap.Type.Attribute.PickupNew: data PickupNew
+ Rattletrap.Type.Attribute.PickupNew: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.PickupNew.PickupNew
+ Rattletrap.Type.Attribute.PickupNew: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.PickupNew.PickupNew
+ Rattletrap.Type.Attribute.PickupNew: instance GHC.Classes.Eq Rattletrap.Type.Attribute.PickupNew.PickupNew
+ Rattletrap.Type.Attribute.PickupNew: instance GHC.Show.Show Rattletrap.Type.Attribute.PickupNew.PickupNew
+ Rattletrap.Type.Attribute.PickupNew: schema :: Schema
+ Rattletrap.Type.Attribute.PlayerHistoryKey: PlayerHistoryKey :: Word16 -> PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: [unknown] :: PlayerHistoryKey -> Word16
+ Rattletrap.Type.Attribute.PlayerHistoryKey: bitGet :: BitGet PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: bitPut :: PlayerHistoryKey -> BitPut
+ Rattletrap.Type.Attribute.PlayerHistoryKey: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.PlayerHistoryKey.PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.PlayerHistoryKey.PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: instance GHC.Classes.Eq Rattletrap.Type.Attribute.PlayerHistoryKey.PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: instance GHC.Show.Show Rattletrap.Type.Attribute.PlayerHistoryKey.PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: newtype PlayerHistoryKey
+ Rattletrap.Type.Attribute.PlayerHistoryKey: schema :: Schema
+ Rattletrap.Type.Attribute.PrivateMatchSettings: PrivateMatchSettings :: Str -> U32 -> U32 -> Str -> Str -> Bool -> PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: [flag] :: PrivateMatchSettings -> Bool
+ Rattletrap.Type.Attribute.PrivateMatchSettings: [gameName] :: PrivateMatchSettings -> Str
+ Rattletrap.Type.Attribute.PrivateMatchSettings: [joinableBy] :: PrivateMatchSettings -> U32
+ Rattletrap.Type.Attribute.PrivateMatchSettings: [maxPlayers] :: PrivateMatchSettings -> U32
+ Rattletrap.Type.Attribute.PrivateMatchSettings: [mutators] :: PrivateMatchSettings -> Str
+ Rattletrap.Type.Attribute.PrivateMatchSettings: [password] :: PrivateMatchSettings -> Str
+ Rattletrap.Type.Attribute.PrivateMatchSettings: bitGet :: BitGet PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: bitPut :: PrivateMatchSettings -> BitPut
+ Rattletrap.Type.Attribute.PrivateMatchSettings: data PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.PrivateMatchSettings.PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.PrivateMatchSettings.PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: instance GHC.Classes.Eq Rattletrap.Type.Attribute.PrivateMatchSettings.PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: instance GHC.Show.Show Rattletrap.Type.Attribute.PrivateMatchSettings.PrivateMatchSettings
+ Rattletrap.Type.Attribute.PrivateMatchSettings: schema :: Schema
+ Rattletrap.Type.Attribute.Product: Product :: Bool -> U32 -> Maybe Str -> ProductValue -> Product
+ Rattletrap.Type.Attribute.Product: [objectId] :: Product -> U32
+ Rattletrap.Type.Attribute.Product: [objectName] :: Product -> Maybe Str
+ Rattletrap.Type.Attribute.Product: [unknown] :: Product -> Bool
+ Rattletrap.Type.Attribute.Product: [value] :: Product -> ProductValue
+ Rattletrap.Type.Attribute.Product: bitGet :: Version -> Map U32 Str -> BitGet Product
+ Rattletrap.Type.Attribute.Product: bitPut :: Product -> BitPut
+ Rattletrap.Type.Attribute.Product: data Product
+ Rattletrap.Type.Attribute.Product: decodeProductAttributesBits :: Version -> Map U32 Str -> BitGet (List Product)
+ Rattletrap.Type.Attribute.Product: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Product.Product
+ Rattletrap.Type.Attribute.Product: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Product.Product
+ Rattletrap.Type.Attribute.Product: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Product.Product
+ Rattletrap.Type.Attribute.Product: instance GHC.Show.Show Rattletrap.Type.Attribute.Product.Product
+ Rattletrap.Type.Attribute.Product: putProductAttributes :: List Product -> BitPut
+ Rattletrap.Type.Attribute.Product: schema :: Schema
+ Rattletrap.Type.Attribute.ProductValue: PaintedNew :: Word32 -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: PaintedOld :: CompressedWord -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: SpecialEdition :: Word32 -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: TeamEditionNew :: Word32 -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: TeamEditionOld :: CompressedWord -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: TitleId :: Str -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: UserColorNew :: U32 -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: UserColorOld :: Maybe Word32 -> ProductValue
+ Rattletrap.Type.Attribute.ProductValue: bitGet :: Version -> U32 -> Maybe Str -> BitGet ProductValue
+ Rattletrap.Type.Attribute.ProductValue: bitPut :: ProductValue -> BitPut
+ Rattletrap.Type.Attribute.ProductValue: data ProductValue
+ Rattletrap.Type.Attribute.ProductValue: decodeColor :: Version -> BitGet ProductValue
+ Rattletrap.Type.Attribute.ProductValue: decodePainted :: Version -> BitGet ProductValue
+ Rattletrap.Type.Attribute.ProductValue: decodeSpecialEdition :: BitGet ProductValue
+ Rattletrap.Type.Attribute.ProductValue: decodeTeamEdition :: Version -> BitGet ProductValue
+ Rattletrap.Type.Attribute.ProductValue: decodeTitle :: BitGet ProductValue
+ Rattletrap.Type.Attribute.ProductValue: hasNewColor :: Version -> Bool
+ Rattletrap.Type.Attribute.ProductValue: hasNewPainted :: Version -> Bool
+ Rattletrap.Type.Attribute.ProductValue: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.ProductValue.ProductValue
+ Rattletrap.Type.Attribute.ProductValue: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.ProductValue.ProductValue
+ Rattletrap.Type.Attribute.ProductValue: instance GHC.Classes.Eq Rattletrap.Type.Attribute.ProductValue.ProductValue
+ Rattletrap.Type.Attribute.ProductValue: instance GHC.Show.Show Rattletrap.Type.Attribute.ProductValue.ProductValue
+ Rattletrap.Type.Attribute.ProductValue: schema :: Schema
+ Rattletrap.Type.Attribute.QWord: QWord :: U64 -> QWord
+ Rattletrap.Type.Attribute.QWord: [value] :: QWord -> U64
+ Rattletrap.Type.Attribute.QWord: bitGet :: BitGet QWord
+ Rattletrap.Type.Attribute.QWord: bitPut :: QWord -> BitPut
+ Rattletrap.Type.Attribute.QWord: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.QWord.QWord
+ Rattletrap.Type.Attribute.QWord: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.QWord.QWord
+ Rattletrap.Type.Attribute.QWord: instance GHC.Classes.Eq Rattletrap.Type.Attribute.QWord.QWord
+ Rattletrap.Type.Attribute.QWord: instance GHC.Show.Show Rattletrap.Type.Attribute.QWord.QWord
+ Rattletrap.Type.Attribute.QWord: newtype QWord
+ Rattletrap.Type.Attribute.QWord: schema :: Schema
+ Rattletrap.Type.Attribute.Reservation: Reservation :: CompressedWord -> UniqueId -> Maybe Str -> Bool -> Bool -> Maybe Word8 -> Reservation
+ Rattletrap.Type.Attribute.Reservation: [name] :: Reservation -> Maybe Str
+ Rattletrap.Type.Attribute.Reservation: [number] :: Reservation -> CompressedWord
+ Rattletrap.Type.Attribute.Reservation: [uniqueId] :: Reservation -> UniqueId
+ Rattletrap.Type.Attribute.Reservation: [unknown1] :: Reservation -> Bool
+ Rattletrap.Type.Attribute.Reservation: [unknown2] :: Reservation -> Bool
+ Rattletrap.Type.Attribute.Reservation: [unknown3] :: Reservation -> Maybe Word8
+ Rattletrap.Type.Attribute.Reservation: bitGet :: Version -> BitGet Reservation
+ Rattletrap.Type.Attribute.Reservation: bitPut :: Reservation -> BitPut
+ Rattletrap.Type.Attribute.Reservation: data Reservation
+ Rattletrap.Type.Attribute.Reservation: hasUnknown3 :: Version -> Bool
+ Rattletrap.Type.Attribute.Reservation: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Reservation.Reservation
+ Rattletrap.Type.Attribute.Reservation: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Reservation.Reservation
+ Rattletrap.Type.Attribute.Reservation: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Reservation.Reservation
+ Rattletrap.Type.Attribute.Reservation: instance GHC.Show.Show Rattletrap.Type.Attribute.Reservation.Reservation
+ Rattletrap.Type.Attribute.Reservation: schema :: Schema
+ Rattletrap.Type.Attribute.RigidBodyState: RigidBodyState :: Bool -> Vector -> Rotation -> Maybe Vector -> Maybe Vector -> RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: [angularVelocity] :: RigidBodyState -> Maybe Vector
+ Rattletrap.Type.Attribute.RigidBodyState: [linearVelocity] :: RigidBodyState -> Maybe Vector
+ Rattletrap.Type.Attribute.RigidBodyState: [location] :: RigidBodyState -> Vector
+ Rattletrap.Type.Attribute.RigidBodyState: [rotation] :: RigidBodyState -> Rotation
+ Rattletrap.Type.Attribute.RigidBodyState: [sleeping] :: RigidBodyState -> Bool
+ Rattletrap.Type.Attribute.RigidBodyState: bitGet :: Version -> BitGet RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: bitPut :: RigidBodyState -> BitPut
+ Rattletrap.Type.Attribute.RigidBodyState: data RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.RigidBodyState.RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.RigidBodyState.RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: instance GHC.Classes.Eq Rattletrap.Type.Attribute.RigidBodyState.RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: instance GHC.Show.Show Rattletrap.Type.Attribute.RigidBodyState.RigidBodyState
+ Rattletrap.Type.Attribute.RigidBodyState: schema :: Schema
+ Rattletrap.Type.Attribute.StatEvent: StatEvent :: Bool -> I32 -> StatEvent
+ Rattletrap.Type.Attribute.StatEvent: [objectId] :: StatEvent -> I32
+ Rattletrap.Type.Attribute.StatEvent: [unknown] :: StatEvent -> Bool
+ Rattletrap.Type.Attribute.StatEvent: bitGet :: BitGet StatEvent
+ Rattletrap.Type.Attribute.StatEvent: bitPut :: StatEvent -> BitPut
+ Rattletrap.Type.Attribute.StatEvent: data StatEvent
+ Rattletrap.Type.Attribute.StatEvent: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.StatEvent.StatEvent
+ Rattletrap.Type.Attribute.StatEvent: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.StatEvent.StatEvent
+ Rattletrap.Type.Attribute.StatEvent: instance GHC.Classes.Eq Rattletrap.Type.Attribute.StatEvent.StatEvent
+ Rattletrap.Type.Attribute.StatEvent: instance GHC.Show.Show Rattletrap.Type.Attribute.StatEvent.StatEvent
+ Rattletrap.Type.Attribute.StatEvent: schema :: Schema
+ Rattletrap.Type.Attribute.String: String :: Str -> String
+ Rattletrap.Type.Attribute.String: [value] :: String -> Str
+ Rattletrap.Type.Attribute.String: bitGet :: BitGet String
+ Rattletrap.Type.Attribute.String: bitPut :: String -> BitPut
+ Rattletrap.Type.Attribute.String: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.String.String
+ Rattletrap.Type.Attribute.String: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.String.String
+ Rattletrap.Type.Attribute.String: instance GHC.Classes.Eq Rattletrap.Type.Attribute.String.String
+ Rattletrap.Type.Attribute.String: instance GHC.Show.Show Rattletrap.Type.Attribute.String.String
+ Rattletrap.Type.Attribute.String: newtype String
+ Rattletrap.Type.Attribute.String: schema :: Schema
+ Rattletrap.Type.Attribute.TeamPaint: TeamPaint :: U8 -> U8 -> U8 -> U32 -> U32 -> TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: [accentColor] :: TeamPaint -> U8
+ Rattletrap.Type.Attribute.TeamPaint: [accentFinish] :: TeamPaint -> U32
+ Rattletrap.Type.Attribute.TeamPaint: [primaryColor] :: TeamPaint -> U8
+ Rattletrap.Type.Attribute.TeamPaint: [primaryFinish] :: TeamPaint -> U32
+ Rattletrap.Type.Attribute.TeamPaint: [team] :: TeamPaint -> U8
+ Rattletrap.Type.Attribute.TeamPaint: bitGet :: BitGet TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: bitPut :: TeamPaint -> BitPut
+ Rattletrap.Type.Attribute.TeamPaint: data TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.TeamPaint.TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.TeamPaint.TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: instance GHC.Classes.Eq Rattletrap.Type.Attribute.TeamPaint.TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: instance GHC.Show.Show Rattletrap.Type.Attribute.TeamPaint.TeamPaint
+ Rattletrap.Type.Attribute.TeamPaint: schema :: Schema
+ Rattletrap.Type.Attribute.Title: Title :: Bool -> Bool -> U32 -> U32 -> U32 -> U32 -> U32 -> Bool -> Title
+ Rattletrap.Type.Attribute.Title: [unknown1] :: Title -> Bool
+ Rattletrap.Type.Attribute.Title: [unknown2] :: Title -> Bool
+ Rattletrap.Type.Attribute.Title: [unknown3] :: Title -> U32
+ Rattletrap.Type.Attribute.Title: [unknown4] :: Title -> U32
+ Rattletrap.Type.Attribute.Title: [unknown5] :: Title -> U32
+ Rattletrap.Type.Attribute.Title: [unknown6] :: Title -> U32
+ Rattletrap.Type.Attribute.Title: [unknown7] :: Title -> U32
+ Rattletrap.Type.Attribute.Title: [unknown8] :: Title -> Bool
+ Rattletrap.Type.Attribute.Title: bitGet :: BitGet Title
+ Rattletrap.Type.Attribute.Title: bitPut :: Title -> BitPut
+ Rattletrap.Type.Attribute.Title: data Title
+ Rattletrap.Type.Attribute.Title: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.Title.Title
+ Rattletrap.Type.Attribute.Title: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.Title.Title
+ Rattletrap.Type.Attribute.Title: instance GHC.Classes.Eq Rattletrap.Type.Attribute.Title.Title
+ Rattletrap.Type.Attribute.Title: instance GHC.Show.Show Rattletrap.Type.Attribute.Title.Title
+ Rattletrap.Type.Attribute.Title: schema :: Schema
+ Rattletrap.Type.Attribute.UniqueId: UniqueId :: U8 -> RemoteId -> U8 -> UniqueId
+ Rattletrap.Type.Attribute.UniqueId: [localId] :: UniqueId -> U8
+ Rattletrap.Type.Attribute.UniqueId: [remoteId] :: UniqueId -> RemoteId
+ Rattletrap.Type.Attribute.UniqueId: [systemId] :: UniqueId -> U8
+ Rattletrap.Type.Attribute.UniqueId: bitGet :: Version -> BitGet UniqueId
+ Rattletrap.Type.Attribute.UniqueId: bitPut :: UniqueId -> BitPut
+ Rattletrap.Type.Attribute.UniqueId: data UniqueId
+ Rattletrap.Type.Attribute.UniqueId: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.UniqueId.UniqueId
+ Rattletrap.Type.Attribute.UniqueId: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.UniqueId.UniqueId
+ Rattletrap.Type.Attribute.UniqueId: instance GHC.Classes.Eq Rattletrap.Type.Attribute.UniqueId.UniqueId
+ Rattletrap.Type.Attribute.UniqueId: instance GHC.Show.Show Rattletrap.Type.Attribute.UniqueId.UniqueId
+ Rattletrap.Type.Attribute.UniqueId: schema :: Schema
+ Rattletrap.Type.Attribute.WeldedInfo: WeldedInfo :: Bool -> I32 -> Vector -> F32 -> Int8Vector -> WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: [active] :: WeldedInfo -> Bool
+ Rattletrap.Type.Attribute.WeldedInfo: [actorId] :: WeldedInfo -> I32
+ Rattletrap.Type.Attribute.WeldedInfo: [mass] :: WeldedInfo -> F32
+ Rattletrap.Type.Attribute.WeldedInfo: [offset] :: WeldedInfo -> Vector
+ Rattletrap.Type.Attribute.WeldedInfo: [rotation] :: WeldedInfo -> Int8Vector
+ Rattletrap.Type.Attribute.WeldedInfo: bitGet :: Version -> BitGet WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: bitPut :: WeldedInfo -> BitPut
+ Rattletrap.Type.Attribute.WeldedInfo: data WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.WeldedInfo.WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.WeldedInfo.WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: instance GHC.Classes.Eq Rattletrap.Type.Attribute.WeldedInfo.WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: instance GHC.Show.Show Rattletrap.Type.Attribute.WeldedInfo.WeldedInfo
+ Rattletrap.Type.Attribute.WeldedInfo: schema :: Schema
+ Rattletrap.Type.AttributeMapping: AttributeMapping :: U32 -> U32 -> AttributeMapping
+ Rattletrap.Type.AttributeMapping: [objectId] :: AttributeMapping -> U32
+ Rattletrap.Type.AttributeMapping: [streamId] :: AttributeMapping -> U32
+ Rattletrap.Type.AttributeMapping: byteGet :: ByteGet AttributeMapping
+ Rattletrap.Type.AttributeMapping: bytePut :: AttributeMapping -> BytePut
+ Rattletrap.Type.AttributeMapping: data AttributeMapping
+ Rattletrap.Type.AttributeMapping: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.AttributeMapping.AttributeMapping
+ Rattletrap.Type.AttributeMapping: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.AttributeMapping.AttributeMapping
+ Rattletrap.Type.AttributeMapping: instance GHC.Classes.Eq Rattletrap.Type.AttributeMapping.AttributeMapping
+ Rattletrap.Type.AttributeMapping: instance GHC.Show.Show Rattletrap.Type.AttributeMapping.AttributeMapping
+ Rattletrap.Type.AttributeMapping: schema :: Schema
+ Rattletrap.Type.AttributeType: AppliedDamage :: AttributeType
+ Rattletrap.Type.AttributeType: Boolean :: AttributeType
+ Rattletrap.Type.AttributeType: Byte :: AttributeType
+ Rattletrap.Type.AttributeType: CamSettings :: AttributeType
+ Rattletrap.Type.AttributeType: ClubColors :: AttributeType
+ Rattletrap.Type.AttributeType: CustomDemolish :: AttributeType
+ Rattletrap.Type.AttributeType: DamageState :: AttributeType
+ Rattletrap.Type.AttributeType: Demolish :: AttributeType
+ Rattletrap.Type.AttributeType: Enum :: AttributeType
+ Rattletrap.Type.AttributeType: Explosion :: AttributeType
+ Rattletrap.Type.AttributeType: ExtendedExplosion :: AttributeType
+ Rattletrap.Type.AttributeType: FlaggedByte :: AttributeType
+ Rattletrap.Type.AttributeType: FlaggedInt :: AttributeType
+ Rattletrap.Type.AttributeType: Float :: AttributeType
+ Rattletrap.Type.AttributeType: GameMode :: AttributeType
+ Rattletrap.Type.AttributeType: Int :: AttributeType
+ Rattletrap.Type.AttributeType: Int64 :: AttributeType
+ Rattletrap.Type.AttributeType: Loadout :: AttributeType
+ Rattletrap.Type.AttributeType: LoadoutOnline :: AttributeType
+ Rattletrap.Type.AttributeType: Loadouts :: AttributeType
+ Rattletrap.Type.AttributeType: LoadoutsOnline :: AttributeType
+ Rattletrap.Type.AttributeType: Location :: AttributeType
+ Rattletrap.Type.AttributeType: MusicStinger :: AttributeType
+ Rattletrap.Type.AttributeType: PartyLeader :: AttributeType
+ Rattletrap.Type.AttributeType: Pickup :: AttributeType
+ Rattletrap.Type.AttributeType: PickupNew :: AttributeType
+ Rattletrap.Type.AttributeType: PlayerHistoryKey :: AttributeType
+ Rattletrap.Type.AttributeType: PrivateMatchSettings :: AttributeType
+ Rattletrap.Type.AttributeType: QWord :: AttributeType
+ Rattletrap.Type.AttributeType: Reservation :: AttributeType
+ Rattletrap.Type.AttributeType: RigidBodyState :: AttributeType
+ Rattletrap.Type.AttributeType: StatEvent :: AttributeType
+ Rattletrap.Type.AttributeType: String :: AttributeType
+ Rattletrap.Type.AttributeType: TeamPaint :: AttributeType
+ Rattletrap.Type.AttributeType: Title :: AttributeType
+ Rattletrap.Type.AttributeType: UniqueId :: AttributeType
+ Rattletrap.Type.AttributeType: WeldedInfo :: AttributeType
+ Rattletrap.Type.AttributeType: data AttributeType
+ Rattletrap.Type.AttributeType: instance GHC.Classes.Eq Rattletrap.Type.AttributeType.AttributeType
+ Rattletrap.Type.AttributeType: instance GHC.Show.Show Rattletrap.Type.AttributeType.AttributeType
+ Rattletrap.Type.AttributeValue: AppliedDamage :: AppliedDamage -> AttributeValue
+ Rattletrap.Type.AttributeValue: Boolean :: Boolean -> AttributeValue
+ Rattletrap.Type.AttributeValue: Byte :: Byte -> AttributeValue
+ Rattletrap.Type.AttributeValue: CamSettings :: CamSettings -> AttributeValue
+ Rattletrap.Type.AttributeValue: ClubColors :: ClubColors -> AttributeValue
+ Rattletrap.Type.AttributeValue: CustomDemolish :: CustomDemolish -> AttributeValue
+ Rattletrap.Type.AttributeValue: DamageState :: DamageState -> AttributeValue
+ Rattletrap.Type.AttributeValue: Demolish :: Demolish -> AttributeValue
+ Rattletrap.Type.AttributeValue: Enum :: Enum -> AttributeValue
+ Rattletrap.Type.AttributeValue: Explosion :: Explosion -> AttributeValue
+ Rattletrap.Type.AttributeValue: ExtendedExplosion :: ExtendedExplosion -> AttributeValue
+ Rattletrap.Type.AttributeValue: FlaggedByte :: FlaggedByte -> AttributeValue
+ Rattletrap.Type.AttributeValue: FlaggedInt :: FlaggedInt -> AttributeValue
+ Rattletrap.Type.AttributeValue: Float :: Float -> AttributeValue
+ Rattletrap.Type.AttributeValue: GameMode :: GameMode -> AttributeValue
+ Rattletrap.Type.AttributeValue: Int :: Int -> AttributeValue
+ Rattletrap.Type.AttributeValue: Int64 :: Int64 -> AttributeValue
+ Rattletrap.Type.AttributeValue: Loadout :: Loadout -> AttributeValue
+ Rattletrap.Type.AttributeValue: LoadoutOnline :: LoadoutOnline -> AttributeValue
+ Rattletrap.Type.AttributeValue: Loadouts :: Loadouts -> AttributeValue
+ Rattletrap.Type.AttributeValue: LoadoutsOnline :: LoadoutsOnline -> AttributeValue
+ Rattletrap.Type.AttributeValue: Location :: Location -> AttributeValue
+ Rattletrap.Type.AttributeValue: MusicStinger :: MusicStinger -> AttributeValue
+ Rattletrap.Type.AttributeValue: PartyLeader :: PartyLeader -> AttributeValue
+ Rattletrap.Type.AttributeValue: Pickup :: Pickup -> AttributeValue
+ Rattletrap.Type.AttributeValue: PickupNew :: PickupNew -> AttributeValue
+ Rattletrap.Type.AttributeValue: PlayerHistoryKey :: PlayerHistoryKey -> AttributeValue
+ Rattletrap.Type.AttributeValue: PrivateMatchSettings :: PrivateMatchSettings -> AttributeValue
+ Rattletrap.Type.AttributeValue: QWord :: QWord -> AttributeValue
+ Rattletrap.Type.AttributeValue: Reservation :: Reservation -> AttributeValue
+ Rattletrap.Type.AttributeValue: RigidBodyState :: RigidBodyState -> AttributeValue
+ Rattletrap.Type.AttributeValue: StatEvent :: StatEvent -> AttributeValue
+ Rattletrap.Type.AttributeValue: String :: String -> AttributeValue
+ Rattletrap.Type.AttributeValue: TeamPaint :: TeamPaint -> AttributeValue
+ Rattletrap.Type.AttributeValue: Title :: Title -> AttributeValue
+ Rattletrap.Type.AttributeValue: UniqueId :: UniqueId -> AttributeValue
+ Rattletrap.Type.AttributeValue: WeldedInfo :: WeldedInfo -> AttributeValue
+ Rattletrap.Type.AttributeValue: bitGet :: Version -> Map U32 Str -> Str -> BitGet AttributeValue
+ Rattletrap.Type.AttributeValue: bitPut :: AttributeValue -> BitPut
+ Rattletrap.Type.AttributeValue: data AttributeValue
+ Rattletrap.Type.AttributeValue: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.AttributeValue.AttributeValue
+ Rattletrap.Type.AttributeValue: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.AttributeValue.AttributeValue
+ Rattletrap.Type.AttributeValue: instance GHC.Classes.Eq Rattletrap.Type.AttributeValue.AttributeValue
+ Rattletrap.Type.AttributeValue: instance GHC.Show.Show Rattletrap.Type.AttributeValue.AttributeValue
+ Rattletrap.Type.AttributeValue: schema :: Schema
+ Rattletrap.Type.Cache: Cache :: U32 -> U32 -> U32 -> List AttributeMapping -> Cache
+ Rattletrap.Type.Cache: [attributeMappings] :: Cache -> List AttributeMapping
+ Rattletrap.Type.Cache: [cacheId] :: Cache -> U32
+ Rattletrap.Type.Cache: [classId] :: Cache -> U32
+ Rattletrap.Type.Cache: [parentCacheId] :: Cache -> U32
+ Rattletrap.Type.Cache: byteGet :: ByteGet Cache
+ Rattletrap.Type.Cache: bytePut :: Cache -> BytePut
+ Rattletrap.Type.Cache: data Cache
+ Rattletrap.Type.Cache: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Cache.Cache
+ Rattletrap.Type.Cache: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Cache.Cache
+ Rattletrap.Type.Cache: instance GHC.Classes.Eq Rattletrap.Type.Cache.Cache
+ Rattletrap.Type.Cache: instance GHC.Show.Show Rattletrap.Type.Cache.Cache
+ Rattletrap.Type.Cache: schema :: Schema
+ Rattletrap.Type.ClassAttributeMap: ClassAttributeMap :: Map U32 Str -> Map U32 U32 -> Map U32 (Map U32 U32) -> IntMap Str -> ClassAttributeMap
+ Rattletrap.Type.ClassAttributeMap: [nameMap] :: ClassAttributeMap -> IntMap Str
+ Rattletrap.Type.ClassAttributeMap: [objectClassMap] :: ClassAttributeMap -> Map U32 U32
+ Rattletrap.Type.ClassAttributeMap: [objectMap] :: ClassAttributeMap -> Map U32 Str
+ Rattletrap.Type.ClassAttributeMap: [value] :: ClassAttributeMap -> Map U32 (Map U32 U32)
+ Rattletrap.Type.ClassAttributeMap: classHasLocation :: Str -> Bool
+ Rattletrap.Type.ClassAttributeMap: classHasRotation :: Str -> Bool
+ Rattletrap.Type.ClassAttributeMap: data ClassAttributeMap
+ Rattletrap.Type.ClassAttributeMap: getAttributeIdLimit :: Map U32 U32 -> Maybe Word
+ Rattletrap.Type.ClassAttributeMap: getAttributeMap :: ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> Maybe (Map U32 U32)
+ Rattletrap.Type.ClassAttributeMap: getAttributeName :: ClassAttributeMap -> Map U32 U32 -> CompressedWord -> Maybe Str
+ Rattletrap.Type.ClassAttributeMap: getClassName :: Str -> Maybe Str
+ Rattletrap.Type.ClassAttributeMap: getName :: IntMap Str -> U32 -> Maybe Str
+ Rattletrap.Type.ClassAttributeMap: getObjectName :: Map U32 Str -> U32 -> Maybe Str
+ Rattletrap.Type.ClassAttributeMap: instance GHC.Classes.Eq Rattletrap.Type.ClassAttributeMap.ClassAttributeMap
+ Rattletrap.Type.ClassAttributeMap: instance GHC.Show.Show Rattletrap.Type.ClassAttributeMap.ClassAttributeMap
+ Rattletrap.Type.ClassAttributeMap: make :: List Str -> List ClassMapping -> List Cache -> List Str -> ClassAttributeMap
+ Rattletrap.Type.ClassMapping: ClassMapping :: Str -> U32 -> ClassMapping
+ Rattletrap.Type.ClassMapping: [name] :: ClassMapping -> Str
+ Rattletrap.Type.ClassMapping: [streamId] :: ClassMapping -> U32
+ Rattletrap.Type.ClassMapping: byteGet :: ByteGet ClassMapping
+ Rattletrap.Type.ClassMapping: bytePut :: ClassMapping -> BytePut
+ Rattletrap.Type.ClassMapping: data ClassMapping
+ Rattletrap.Type.ClassMapping: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.ClassMapping.ClassMapping
+ Rattletrap.Type.ClassMapping: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.ClassMapping.ClassMapping
+ Rattletrap.Type.ClassMapping: instance GHC.Classes.Eq Rattletrap.Type.ClassMapping.ClassMapping
+ Rattletrap.Type.ClassMapping: instance GHC.Show.Show Rattletrap.Type.ClassMapping.ClassMapping
+ Rattletrap.Type.ClassMapping: schema :: Schema
+ Rattletrap.Type.CompressedWord: CompressedWord :: Word -> Word -> CompressedWord
+ Rattletrap.Type.CompressedWord: [limit] :: CompressedWord -> Word
+ Rattletrap.Type.CompressedWord: [value] :: CompressedWord -> Word
+ Rattletrap.Type.CompressedWord: bitGet :: Word -> BitGet CompressedWord
+ Rattletrap.Type.CompressedWord: bitPut :: CompressedWord -> BitPut
+ Rattletrap.Type.CompressedWord: data CompressedWord
+ Rattletrap.Type.CompressedWord: getMaxBits :: Word -> Int
+ Rattletrap.Type.CompressedWord: getMaxBits_ :: Word -> Word
+ Rattletrap.Type.CompressedWord: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.CompressedWord.CompressedWord
+ Rattletrap.Type.CompressedWord: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.CompressedWord.CompressedWord
+ Rattletrap.Type.CompressedWord: instance GHC.Classes.Eq Rattletrap.Type.CompressedWord.CompressedWord
+ Rattletrap.Type.CompressedWord: instance GHC.Classes.Ord Rattletrap.Type.CompressedWord.CompressedWord
+ Rattletrap.Type.CompressedWord: instance GHC.Show.Show Rattletrap.Type.CompressedWord.CompressedWord
+ Rattletrap.Type.CompressedWord: putCompressedWordStep :: Word -> Word -> Int -> Int -> Word -> BitPut
+ Rattletrap.Type.CompressedWord: schema :: Schema
+ Rattletrap.Type.CompressedWord: step :: Word -> Word -> Word -> Word -> BitGet Word
+ Rattletrap.Type.CompressedWordVector: CompressedWordVector :: CompressedWord -> CompressedWord -> CompressedWord -> CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: [x] :: CompressedWordVector -> CompressedWord
+ Rattletrap.Type.CompressedWordVector: [y] :: CompressedWordVector -> CompressedWord
+ Rattletrap.Type.CompressedWordVector: [z] :: CompressedWordVector -> CompressedWord
+ Rattletrap.Type.CompressedWordVector: bitGet :: BitGet CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: bitPut :: CompressedWordVector -> BitPut
+ Rattletrap.Type.CompressedWordVector: data CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.CompressedWordVector.CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.CompressedWordVector.CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: instance GHC.Classes.Eq Rattletrap.Type.CompressedWordVector.CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: instance GHC.Show.Show Rattletrap.Type.CompressedWordVector.CompressedWordVector
+ Rattletrap.Type.CompressedWordVector: limit :: Word
+ Rattletrap.Type.CompressedWordVector: schema :: Schema
+ Rattletrap.Type.Content: Content :: List Str -> List KeyFrame -> U32 -> frames -> List Message -> List Mark -> List Str -> List Str -> List Str -> List ClassMapping -> List Cache -> [Word8] -> ContentWith frames
+ Rattletrap.Type.Content: [caches] :: ContentWith frames -> List Cache
+ Rattletrap.Type.Content: [classMappings] :: ContentWith frames -> List ClassMapping
+ Rattletrap.Type.Content: [frames] :: ContentWith frames -> frames
+ Rattletrap.Type.Content: [keyFrames] :: ContentWith frames -> List KeyFrame
+ Rattletrap.Type.Content: [levels] :: ContentWith frames -> List Str
+ Rattletrap.Type.Content: [marks] :: ContentWith frames -> List Mark
+ Rattletrap.Type.Content: [messages] :: ContentWith frames -> List Message
+ Rattletrap.Type.Content: [names] :: ContentWith frames -> List Str
+ Rattletrap.Type.Content: [objects] :: ContentWith frames -> List Str
+ Rattletrap.Type.Content: [packages] :: ContentWith frames -> List Str
+ Rattletrap.Type.Content: [streamSize] :: ContentWith frames -> U32
+ Rattletrap.Type.Content: [unknown] :: ContentWith frames -> [Word8]
+ Rattletrap.Type.Content: byteGet :: Version -> Int -> Word -> ByteGet Content
+ Rattletrap.Type.Content: bytePut :: Content -> BytePut
+ Rattletrap.Type.Content: data ContentWith frames
+ Rattletrap.Type.Content: empty :: Content
+ Rattletrap.Type.Content: instance Data.Aeson.Types.FromJSON.FromJSON frames => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Type.Content.ContentWith frames)
+ Rattletrap.Type.Content: instance Data.Aeson.Types.ToJSON.ToJSON frames => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Type.Content.ContentWith frames)
+ Rattletrap.Type.Content: instance GHC.Classes.Eq frames => GHC.Classes.Eq (Rattletrap.Type.Content.ContentWith frames)
+ Rattletrap.Type.Content: instance GHC.Show.Show frames => GHC.Show.Show (Rattletrap.Type.Content.ContentWith frames)
+ Rattletrap.Type.Content: putFrames :: Content -> BytePut
+ Rattletrap.Type.Content: schema :: Schema -> Schema
+ Rattletrap.Type.Content: type Content = ContentWith (List Frame)
+ Rattletrap.Type.Dictionary: Dictionary :: List (Str, a) -> Str -> Dictionary a
+ Rattletrap.Type.Dictionary: [elements] :: Dictionary a -> List (Str, a)
+ Rattletrap.Type.Dictionary: [lastKey] :: Dictionary a -> Str
+ Rattletrap.Type.Dictionary: byteGet :: ByteGet a -> ByteGet (Dictionary a)
+ Rattletrap.Type.Dictionary: byteGetWith :: Int -> [(Int, (Str, a))] -> ByteGet a -> ByteGet (Dictionary a)
+ Rattletrap.Type.Dictionary: bytePut :: (a -> BytePut) -> Dictionary a -> BytePut
+ Rattletrap.Type.Dictionary: data Dictionary a
+ Rattletrap.Type.Dictionary: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Type.Dictionary.Dictionary a)
+ Rattletrap.Type.Dictionary: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Type.Dictionary.Dictionary a)
+ Rattletrap.Type.Dictionary: instance GHC.Classes.Eq a => GHC.Classes.Eq (Rattletrap.Type.Dictionary.Dictionary a)
+ Rattletrap.Type.Dictionary: instance GHC.Show.Show a => GHC.Show.Show (Rattletrap.Type.Dictionary.Dictionary a)
+ Rattletrap.Type.Dictionary: isNone :: Str -> Bool
+ Rattletrap.Type.Dictionary: lookup :: Str -> Dictionary a -> Maybe a
+ Rattletrap.Type.Dictionary: schema :: Schema -> Schema
+ Rattletrap.Type.F32: F32 :: Float -> F32
+ Rattletrap.Type.F32: bitGet :: BitGet F32
+ Rattletrap.Type.F32: bitPut :: F32 -> BitPut
+ Rattletrap.Type.F32: byteGet :: ByteGet F32
+ Rattletrap.Type.F32: bytePut :: F32 -> BytePut
+ Rattletrap.Type.F32: fromFloat :: Float -> F32
+ Rattletrap.Type.F32: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.F32.F32
+ Rattletrap.Type.F32: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.F32.F32
+ Rattletrap.Type.F32: instance GHC.Classes.Eq Rattletrap.Type.F32.F32
+ Rattletrap.Type.F32: instance GHC.Show.Show Rattletrap.Type.F32.F32
+ Rattletrap.Type.F32: newtype F32
+ Rattletrap.Type.F32: schema :: Schema
+ Rattletrap.Type.F32: toFloat :: F32 -> Float
+ Rattletrap.Type.Frame: Frame :: F32 -> F32 -> List Replication -> Frame
+ Rattletrap.Type.Frame: [delta] :: Frame -> F32
+ Rattletrap.Type.Frame: [replications] :: Frame -> List Replication
+ Rattletrap.Type.Frame: [time] :: Frame -> F32
+ Rattletrap.Type.Frame: bitGet :: Version -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet Frame
+ Rattletrap.Type.Frame: bitPut :: Frame -> BitPut
+ Rattletrap.Type.Frame: data Frame
+ Rattletrap.Type.Frame: decodeFramesBits :: Version -> Int -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet (List Frame)
+ Rattletrap.Type.Frame: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Frame.Frame
+ Rattletrap.Type.Frame: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Frame.Frame
+ Rattletrap.Type.Frame: instance GHC.Classes.Eq Rattletrap.Type.Frame.Frame
+ Rattletrap.Type.Frame: instance GHC.Show.Show Rattletrap.Type.Frame.Frame
+ Rattletrap.Type.Frame: putFrames :: List Frame -> BitPut
+ Rattletrap.Type.Frame: schema :: Schema
+ Rattletrap.Type.Header: Header :: U32 -> U32 -> Maybe U32 -> Str -> Dictionary Property -> Header
+ Rattletrap.Type.Header: [engineVersion] :: Header -> U32
+ Rattletrap.Type.Header: [label] :: Header -> Str
+ Rattletrap.Type.Header: [licenseeVersion] :: Header -> U32
+ Rattletrap.Type.Header: [patchVersion] :: Header -> Maybe U32
+ Rattletrap.Type.Header: [properties] :: Header -> Dictionary Property
+ Rattletrap.Type.Header: byteGet :: ByteGet Header
+ Rattletrap.Type.Header: bytePut :: Header -> BytePut
+ Rattletrap.Type.Header: data Header
+ Rattletrap.Type.Header: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Header.Header
+ Rattletrap.Type.Header: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Header.Header
+ Rattletrap.Type.Header: instance GHC.Classes.Eq Rattletrap.Type.Header.Header
+ Rattletrap.Type.Header: instance GHC.Show.Show Rattletrap.Type.Header.Header
+ Rattletrap.Type.Header: schema :: Schema
+ Rattletrap.Type.I32: I32 :: Int32 -> I32
+ Rattletrap.Type.I32: bitGet :: BitGet I32
+ Rattletrap.Type.I32: bitPut :: I32 -> BitPut
+ Rattletrap.Type.I32: byteGet :: ByteGet I32
+ Rattletrap.Type.I32: bytePut :: I32 -> BytePut
+ Rattletrap.Type.I32: fromInt32 :: Int32 -> I32
+ Rattletrap.Type.I32: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.I32.I32
+ Rattletrap.Type.I32: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.I32.I32
+ Rattletrap.Type.I32: instance GHC.Classes.Eq Rattletrap.Type.I32.I32
+ Rattletrap.Type.I32: instance GHC.Show.Show Rattletrap.Type.I32.I32
+ Rattletrap.Type.I32: newtype I32
+ Rattletrap.Type.I32: schema :: Schema
+ Rattletrap.Type.I32: toInt32 :: I32 -> Int32
+ Rattletrap.Type.I64: I64 :: Int64 -> I64
+ Rattletrap.Type.I64: bitGet :: BitGet I64
+ Rattletrap.Type.I64: bitPut :: I64 -> BitPut
+ Rattletrap.Type.I64: byteGet :: ByteGet I64
+ Rattletrap.Type.I64: bytePut :: I64 -> BytePut
+ Rattletrap.Type.I64: fromInt64 :: Int64 -> I64
+ Rattletrap.Type.I64: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.I64.I64
+ Rattletrap.Type.I64: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.I64.I64
+ Rattletrap.Type.I64: instance GHC.Classes.Eq Rattletrap.Type.I64.I64
+ Rattletrap.Type.I64: instance GHC.Show.Show Rattletrap.Type.I64.I64
+ Rattletrap.Type.I64: newtype I64
+ Rattletrap.Type.I64: schema :: Schema
+ Rattletrap.Type.I64: toInt64 :: I64 -> Int64
+ Rattletrap.Type.I8: I8 :: Int8 -> I8
+ Rattletrap.Type.I8: bitGet :: BitGet I8
+ Rattletrap.Type.I8: bitPut :: I8 -> BitPut
+ Rattletrap.Type.I8: byteGet :: ByteGet I8
+ Rattletrap.Type.I8: bytePut :: I8 -> BytePut
+ Rattletrap.Type.I8: fromInt8 :: Int8 -> I8
+ Rattletrap.Type.I8: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.I8.I8
+ Rattletrap.Type.I8: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.I8.I8
+ Rattletrap.Type.I8: instance GHC.Classes.Eq Rattletrap.Type.I8.I8
+ Rattletrap.Type.I8: instance GHC.Show.Show Rattletrap.Type.I8.I8
+ Rattletrap.Type.I8: newtype I8
+ Rattletrap.Type.I8: schema :: Schema
+ Rattletrap.Type.I8: toInt8 :: I8 -> Int8
+ Rattletrap.Type.Initialization: Initialization :: Maybe Vector -> Maybe Int8Vector -> Initialization
+ Rattletrap.Type.Initialization: [location] :: Initialization -> Maybe Vector
+ Rattletrap.Type.Initialization: [rotation] :: Initialization -> Maybe Int8Vector
+ Rattletrap.Type.Initialization: bitGet :: Version -> Bool -> Bool -> BitGet Initialization
+ Rattletrap.Type.Initialization: bitPut :: Initialization -> BitPut
+ Rattletrap.Type.Initialization: data Initialization
+ Rattletrap.Type.Initialization: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Initialization.Initialization
+ Rattletrap.Type.Initialization: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Initialization.Initialization
+ Rattletrap.Type.Initialization: instance GHC.Classes.Eq Rattletrap.Type.Initialization.Initialization
+ Rattletrap.Type.Initialization: instance GHC.Show.Show Rattletrap.Type.Initialization.Initialization
+ Rattletrap.Type.Initialization: schema :: Schema
+ Rattletrap.Type.Int8Vector: Int8Vector :: Maybe I8 -> Maybe I8 -> Maybe I8 -> Int8Vector
+ Rattletrap.Type.Int8Vector: [x] :: Int8Vector -> Maybe I8
+ Rattletrap.Type.Int8Vector: [y] :: Int8Vector -> Maybe I8
+ Rattletrap.Type.Int8Vector: [z] :: Int8Vector -> Maybe I8
+ Rattletrap.Type.Int8Vector: bitGet :: BitGet Int8Vector
+ Rattletrap.Type.Int8Vector: bitPut :: Int8Vector -> BitPut
+ Rattletrap.Type.Int8Vector: data Int8Vector
+ Rattletrap.Type.Int8Vector: decodeFieldBits :: BitGet (Maybe I8)
+ Rattletrap.Type.Int8Vector: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Int8Vector.Int8Vector
+ Rattletrap.Type.Int8Vector: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Int8Vector.Int8Vector
+ Rattletrap.Type.Int8Vector: instance GHC.Classes.Eq Rattletrap.Type.Int8Vector.Int8Vector
+ Rattletrap.Type.Int8Vector: instance GHC.Show.Show Rattletrap.Type.Int8Vector.Int8Vector
+ Rattletrap.Type.Int8Vector: putInt8VectorField :: Maybe I8 -> BitPut
+ Rattletrap.Type.Int8Vector: schema :: Schema
+ Rattletrap.Type.KeyFrame: KeyFrame :: F32 -> U32 -> U32 -> KeyFrame
+ Rattletrap.Type.KeyFrame: [frame] :: KeyFrame -> U32
+ Rattletrap.Type.KeyFrame: [position] :: KeyFrame -> U32
+ Rattletrap.Type.KeyFrame: [time] :: KeyFrame -> F32
+ Rattletrap.Type.KeyFrame: byteGet :: ByteGet KeyFrame
+ Rattletrap.Type.KeyFrame: bytePut :: KeyFrame -> BytePut
+ Rattletrap.Type.KeyFrame: data KeyFrame
+ Rattletrap.Type.KeyFrame: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.KeyFrame.KeyFrame
+ Rattletrap.Type.KeyFrame: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.KeyFrame.KeyFrame
+ Rattletrap.Type.KeyFrame: instance GHC.Classes.Eq Rattletrap.Type.KeyFrame.KeyFrame
+ Rattletrap.Type.KeyFrame: instance GHC.Show.Show Rattletrap.Type.KeyFrame.KeyFrame
+ Rattletrap.Type.KeyFrame: schema :: Schema
+ Rattletrap.Type.List: List :: [a] -> List a
+ Rattletrap.Type.List: byteGet :: ByteGet a -> ByteGet (List a)
+ Rattletrap.Type.List: bytePut :: (a -> BytePut) -> List a -> BytePut
+ Rattletrap.Type.List: empty :: List a
+ Rattletrap.Type.List: fromList :: [a] -> List a
+ Rattletrap.Type.List: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Type.List.List a)
+ Rattletrap.Type.List: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Type.List.List a)
+ Rattletrap.Type.List: instance GHC.Classes.Eq a => GHC.Classes.Eq (Rattletrap.Type.List.List a)
+ Rattletrap.Type.List: instance GHC.Show.Show a => GHC.Show.Show (Rattletrap.Type.List.List a)
+ Rattletrap.Type.List: newtype List a
+ Rattletrap.Type.List: replicateM :: Monad m => Int -> m a -> m (List a)
+ Rattletrap.Type.List: schema :: Schema -> Schema
+ Rattletrap.Type.List: toList :: List a -> [a]
+ Rattletrap.Type.List: untilM :: Monad m => m (Maybe a) -> m (List a)
+ Rattletrap.Type.List: untilMWith :: Monad m => m (Maybe a) -> Int -> [(Int, a)] -> m (List a)
+ Rattletrap.Type.Mark: Mark :: Str -> U32 -> Mark
+ Rattletrap.Type.Mark: [frame] :: Mark -> U32
+ Rattletrap.Type.Mark: [value] :: Mark -> Str
+ Rattletrap.Type.Mark: byteGet :: ByteGet Mark
+ Rattletrap.Type.Mark: bytePut :: Mark -> BytePut
+ Rattletrap.Type.Mark: data Mark
+ Rattletrap.Type.Mark: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Mark.Mark
+ Rattletrap.Type.Mark: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Mark.Mark
+ Rattletrap.Type.Mark: instance GHC.Classes.Eq Rattletrap.Type.Mark.Mark
+ Rattletrap.Type.Mark: instance GHC.Show.Show Rattletrap.Type.Mark.Mark
+ Rattletrap.Type.Mark: schema :: Schema
+ Rattletrap.Type.Message: Message :: U32 -> Str -> Str -> Message
+ Rattletrap.Type.Message: [frame] :: Message -> U32
+ Rattletrap.Type.Message: [name] :: Message -> Str
+ Rattletrap.Type.Message: [value] :: Message -> Str
+ Rattletrap.Type.Message: byteGet :: ByteGet Message
+ Rattletrap.Type.Message: bytePut :: Message -> BytePut
+ Rattletrap.Type.Message: data Message
+ Rattletrap.Type.Message: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Message.Message
+ Rattletrap.Type.Message: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Message.Message
+ Rattletrap.Type.Message: instance GHC.Classes.Eq Rattletrap.Type.Message.Message
+ Rattletrap.Type.Message: instance GHC.Show.Show Rattletrap.Type.Message.Message
+ Rattletrap.Type.Message: schema :: Schema
+ Rattletrap.Type.Property: Property :: Str -> U64 -> PropertyValue Property -> Property
+ Rattletrap.Type.Property: [kind] :: Property -> Str
+ Rattletrap.Type.Property: [size] :: Property -> U64
+ Rattletrap.Type.Property: [value] :: Property -> PropertyValue Property
+ Rattletrap.Type.Property: byteGet :: ByteGet Property
+ Rattletrap.Type.Property: bytePut :: Property -> BytePut
+ Rattletrap.Type.Property: data Property
+ Rattletrap.Type.Property: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Property.Property
+ Rattletrap.Type.Property: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Property.Property
+ Rattletrap.Type.Property: instance GHC.Classes.Eq Rattletrap.Type.Property.Property
+ Rattletrap.Type.Property: instance GHC.Show.Show Rattletrap.Type.Property.Property
+ Rattletrap.Type.Property: schema :: Schema
+ Rattletrap.Type.PropertyValue: Array :: List (Dictionary a) -> PropertyValue a
+ Rattletrap.Type.PropertyValue: Bool :: U8 -> PropertyValue a
+ Rattletrap.Type.PropertyValue: Byte :: Str -> Maybe Str -> PropertyValue a
+ Rattletrap.Type.PropertyValue: Float :: F32 -> PropertyValue a
+ Rattletrap.Type.PropertyValue: Int :: I32 -> PropertyValue a
+ Rattletrap.Type.PropertyValue: Name :: Str -> PropertyValue a
+ Rattletrap.Type.PropertyValue: QWord :: U64 -> PropertyValue a
+ Rattletrap.Type.PropertyValue: Str :: Str -> PropertyValue a
+ Rattletrap.Type.PropertyValue: byteGet :: ByteGet a -> Str -> ByteGet (PropertyValue a)
+ Rattletrap.Type.PropertyValue: bytePut :: (a -> BytePut) -> PropertyValue a -> BytePut
+ Rattletrap.Type.PropertyValue: data PropertyValue a
+ Rattletrap.Type.PropertyValue: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Type.PropertyValue.PropertyValue a)
+ Rattletrap.Type.PropertyValue: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Type.PropertyValue.PropertyValue a)
+ Rattletrap.Type.PropertyValue: instance GHC.Classes.Eq a => GHC.Classes.Eq (Rattletrap.Type.PropertyValue.PropertyValue a)
+ Rattletrap.Type.PropertyValue: instance GHC.Show.Show a => GHC.Show.Show (Rattletrap.Type.PropertyValue.PropertyValue a)
+ Rattletrap.Type.PropertyValue: schema :: Schema -> Schema
+ Rattletrap.Type.Quaternion: Quaternion :: Double -> Double -> Double -> Double -> Quaternion
+ Rattletrap.Type.Quaternion: W :: Component
+ Rattletrap.Type.Quaternion: X :: Component
+ Rattletrap.Type.Quaternion: Y :: Component
+ Rattletrap.Type.Quaternion: Z :: Component
+ Rattletrap.Type.Quaternion: [w] :: Quaternion -> Double
+ Rattletrap.Type.Quaternion: [x] :: Quaternion -> Double
+ Rattletrap.Type.Quaternion: [y] :: Quaternion -> Double
+ Rattletrap.Type.Quaternion: [z] :: Quaternion -> Double
+ Rattletrap.Type.Quaternion: bitGet :: BitGet Quaternion
+ Rattletrap.Type.Quaternion: bitPut :: Quaternion -> BitPut
+ Rattletrap.Type.Quaternion: compressPart :: Double -> CompressedWord
+ Rattletrap.Type.Quaternion: data Component
+ Rattletrap.Type.Quaternion: data Quaternion
+ Rattletrap.Type.Quaternion: decodeComponent :: BitGet Component
+ Rattletrap.Type.Quaternion: decodePart :: BitGet Double
+ Rattletrap.Type.Quaternion: decompressPart :: CompressedWord -> Double
+ Rattletrap.Type.Quaternion: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Quaternion.Quaternion
+ Rattletrap.Type.Quaternion: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Quaternion.Quaternion
+ Rattletrap.Type.Quaternion: instance GHC.Classes.Eq Rattletrap.Type.Quaternion.Component
+ Rattletrap.Type.Quaternion: instance GHC.Classes.Eq Rattletrap.Type.Quaternion.Quaternion
+ Rattletrap.Type.Quaternion: instance GHC.Show.Show Rattletrap.Type.Quaternion.Component
+ Rattletrap.Type.Quaternion: instance GHC.Show.Show Rattletrap.Type.Quaternion.Quaternion
+ Rattletrap.Type.Quaternion: maxComponent :: Quaternion -> Component
+ Rattletrap.Type.Quaternion: maxCompressedValue :: Word
+ Rattletrap.Type.Quaternion: maxValue :: Double
+ Rattletrap.Type.Quaternion: maximumOn :: (Foldable t, Ord b) => (a -> b) -> t a -> a
+ Rattletrap.Type.Quaternion: numBits :: Word
+ Rattletrap.Type.Quaternion: putComponent :: Component -> BitPut
+ Rattletrap.Type.Quaternion: putPart :: Double -> BitPut
+ Rattletrap.Type.Quaternion: putParts :: Double -> Double -> Double -> BitPut
+ Rattletrap.Type.Quaternion: schema :: Schema
+ Rattletrap.Type.Quaternion: toPart :: Double -> Double -> Double -> Double
+ Rattletrap.Type.Quaternion: toQuaternion :: Component -> Double -> Double -> Double -> Quaternion
+ Rattletrap.Type.Quaternion: wordToDouble :: Word -> Double
+ Rattletrap.Type.RemoteId: Epic :: Str -> RemoteId
+ Rattletrap.Type.RemoteId: PlayStation :: Text -> [Word8] -> RemoteId
+ Rattletrap.Type.RemoteId: PsyNet :: Either U64 (U64, U64, U64, U64) -> RemoteId
+ Rattletrap.Type.RemoteId: Splitscreen :: Word32 -> RemoteId
+ Rattletrap.Type.RemoteId: Steam :: U64 -> RemoteId
+ Rattletrap.Type.RemoteId: Switch :: U64 -> U64 -> U64 -> U64 -> RemoteId
+ Rattletrap.Type.RemoteId: Xbox :: U64 -> RemoteId
+ Rattletrap.Type.RemoteId: bitGet :: Version -> U8 -> BitGet RemoteId
+ Rattletrap.Type.RemoteId: bitPut :: RemoteId -> BitPut
+ Rattletrap.Type.RemoteId: data RemoteId
+ Rattletrap.Type.RemoteId: decodePsBytes :: Version -> BitGet [Word8]
+ Rattletrap.Type.RemoteId: decodePsName :: BitGet Text
+ Rattletrap.Type.RemoteId: getWord256 :: BitGet (U64, U64, U64, U64)
+ Rattletrap.Type.RemoteId: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.RemoteId.RemoteId
+ Rattletrap.Type.RemoteId: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.RemoteId.RemoteId
+ Rattletrap.Type.RemoteId: instance GHC.Classes.Eq Rattletrap.Type.RemoteId.RemoteId
+ Rattletrap.Type.RemoteId: instance GHC.Show.Show Rattletrap.Type.RemoteId.RemoteId
+ Rattletrap.Type.RemoteId: playStationIsU24 :: Version -> Bool
+ Rattletrap.Type.RemoteId: psyNetIsU64 :: Version -> Bool
+ Rattletrap.Type.RemoteId: putWord256 :: U64 -> U64 -> U64 -> U64 -> BitPut
+ Rattletrap.Type.RemoteId: schema :: Schema
+ Rattletrap.Type.RemoteId: uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
+ Rattletrap.Type.Replay: Replay :: header -> content -> ReplayWith header content
+ Rattletrap.Type.Replay: [content] :: ReplayWith header content -> content
+ Rattletrap.Type.Replay: [header] :: ReplayWith header content -> header
+ Rattletrap.Type.Replay: byteGet :: Bool -> Bool -> ByteGet Replay
+ Rattletrap.Type.Replay: bytePut :: Replay -> BytePut
+ Rattletrap.Type.Replay: data ReplayWith header content
+ Rattletrap.Type.Replay: getContent :: Header -> ByteGet Content
+ Rattletrap.Type.Replay: getMaxChannels :: Header -> Word
+ Rattletrap.Type.Replay: getNumFrames :: Header -> Int
+ Rattletrap.Type.Replay: getPatchVersion :: Header -> Int
+ Rattletrap.Type.Replay: getVersion :: Header -> Version
+ Rattletrap.Type.Replay: instance (Data.Aeson.Types.FromJSON.FromJSON h, Data.Aeson.Types.FromJSON.FromJSON c) => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Type.Replay.ReplayWith h c)
+ Rattletrap.Type.Replay: instance (Data.Aeson.Types.ToJSON.ToJSON h, Data.Aeson.Types.ToJSON.ToJSON c) => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Type.Replay.ReplayWith h c)
+ Rattletrap.Type.Replay: instance (GHC.Classes.Eq header, GHC.Classes.Eq content) => GHC.Classes.Eq (Rattletrap.Type.Replay.ReplayWith header content)
+ Rattletrap.Type.Replay: instance (GHC.Show.Show header, GHC.Show.Show content) => GHC.Show.Show (Rattletrap.Type.Replay.ReplayWith header content)
+ Rattletrap.Type.Replay: schema :: Schema -> Schema -> Schema
+ Rattletrap.Type.Replay: schemaUrl :: String
+ Rattletrap.Type.Replay: type Replay = ReplayWith (Section Header) (Section Content)
+ Rattletrap.Type.Replication: Replication :: CompressedWord -> ReplicationValue -> Replication
+ Rattletrap.Type.Replication: [actorId] :: Replication -> CompressedWord
+ Rattletrap.Type.Replication: [value] :: Replication -> ReplicationValue
+ Rattletrap.Type.Replication: bitGet :: Version -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet Replication
+ Rattletrap.Type.Replication: bitPut :: Replication -> BitPut
+ Rattletrap.Type.Replication: data Replication
+ Rattletrap.Type.Replication: decodeReplicationsBits :: Version -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet (List Replication)
+ Rattletrap.Type.Replication: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Replication.Replication
+ Rattletrap.Type.Replication: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Replication.Replication
+ Rattletrap.Type.Replication: instance GHC.Classes.Eq Rattletrap.Type.Replication.Replication
+ Rattletrap.Type.Replication: instance GHC.Show.Show Rattletrap.Type.Replication.Replication
+ Rattletrap.Type.Replication: putReplications :: List Replication -> BitPut
+ Rattletrap.Type.Replication: schema :: Schema
+ Rattletrap.Type.Replication.Destroyed: Destroyed :: Destroyed
+ Rattletrap.Type.Replication.Destroyed: bitGet :: BitGet Destroyed
+ Rattletrap.Type.Replication.Destroyed: bitPut :: Destroyed -> BitPut
+ Rattletrap.Type.Replication.Destroyed: data Destroyed
+ Rattletrap.Type.Replication.Destroyed: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Replication.Destroyed.Destroyed
+ Rattletrap.Type.Replication.Destroyed: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Replication.Destroyed.Destroyed
+ Rattletrap.Type.Replication.Destroyed: instance GHC.Classes.Eq Rattletrap.Type.Replication.Destroyed.Destroyed
+ Rattletrap.Type.Replication.Destroyed: instance GHC.Show.Show Rattletrap.Type.Replication.Destroyed.Destroyed
+ Rattletrap.Type.Replication.Destroyed: schema :: Schema
+ Rattletrap.Type.Replication.Spawned: Spawned :: Bool -> Maybe U32 -> Maybe Str -> U32 -> Str -> Str -> Initialization -> Spawned
+ Rattletrap.Type.Replication.Spawned: [className] :: Spawned -> Str
+ Rattletrap.Type.Replication.Spawned: [flag] :: Spawned -> Bool
+ Rattletrap.Type.Replication.Spawned: [initialization] :: Spawned -> Initialization
+ Rattletrap.Type.Replication.Spawned: [nameIndex] :: Spawned -> Maybe U32
+ Rattletrap.Type.Replication.Spawned: [name] :: Spawned -> Maybe Str
+ Rattletrap.Type.Replication.Spawned: [objectId] :: Spawned -> U32
+ Rattletrap.Type.Replication.Spawned: [objectName] :: Spawned -> Str
+ Rattletrap.Type.Replication.Spawned: bitGet :: Version -> ClassAttributeMap -> CompressedWord -> StateT (Map CompressedWord U32) BitGet Spawned
+ Rattletrap.Type.Replication.Spawned: bitPut :: Spawned -> BitPut
+ Rattletrap.Type.Replication.Spawned: data Spawned
+ Rattletrap.Type.Replication.Spawned: hasNameIndex :: Version -> Bool
+ Rattletrap.Type.Replication.Spawned: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Replication.Spawned.Spawned
+ Rattletrap.Type.Replication.Spawned: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Replication.Spawned.Spawned
+ Rattletrap.Type.Replication.Spawned: instance GHC.Classes.Eq Rattletrap.Type.Replication.Spawned.Spawned
+ Rattletrap.Type.Replication.Spawned: instance GHC.Show.Show Rattletrap.Type.Replication.Spawned.Spawned
+ Rattletrap.Type.Replication.Spawned: lookupClassName :: Str -> Either String Str
+ Rattletrap.Type.Replication.Spawned: lookupName :: ClassAttributeMap -> Maybe U32 -> Either String (Maybe Str)
+ Rattletrap.Type.Replication.Spawned: lookupObjectName :: ClassAttributeMap -> U32 -> Either String Str
+ Rattletrap.Type.Replication.Spawned: schema :: Schema
+ Rattletrap.Type.Replication.Updated: Updated :: List Attribute -> Updated
+ Rattletrap.Type.Replication.Updated: [attributes] :: Updated -> List Attribute
+ Rattletrap.Type.Replication.Updated: bitGet :: Version -> ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet Updated
+ Rattletrap.Type.Replication.Updated: bitPut :: Updated -> BitPut
+ Rattletrap.Type.Replication.Updated: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Replication.Updated.Updated
+ Rattletrap.Type.Replication.Updated: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Replication.Updated.Updated
+ Rattletrap.Type.Replication.Updated: instance GHC.Classes.Eq Rattletrap.Type.Replication.Updated.Updated
+ Rattletrap.Type.Replication.Updated: instance GHC.Show.Show Rattletrap.Type.Replication.Updated.Updated
+ Rattletrap.Type.Replication.Updated: newtype Updated
+ Rattletrap.Type.Replication.Updated: schema :: Schema
+ Rattletrap.Type.ReplicationValue: Destroyed :: Destroyed -> ReplicationValue
+ Rattletrap.Type.ReplicationValue: Spawned :: Spawned -> ReplicationValue
+ Rattletrap.Type.ReplicationValue: Updated :: Updated -> ReplicationValue
+ Rattletrap.Type.ReplicationValue: bitGet :: Version -> ClassAttributeMap -> CompressedWord -> StateT (Map CompressedWord U32) BitGet ReplicationValue
+ Rattletrap.Type.ReplicationValue: bitPut :: ReplicationValue -> BitPut
+ Rattletrap.Type.ReplicationValue: data ReplicationValue
+ Rattletrap.Type.ReplicationValue: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.ReplicationValue.ReplicationValue
+ Rattletrap.Type.ReplicationValue: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.ReplicationValue.ReplicationValue
+ Rattletrap.Type.ReplicationValue: instance GHC.Classes.Eq Rattletrap.Type.ReplicationValue.ReplicationValue
+ Rattletrap.Type.ReplicationValue: instance GHC.Show.Show Rattletrap.Type.ReplicationValue.ReplicationValue
+ Rattletrap.Type.ReplicationValue: schema :: Schema
+ Rattletrap.Type.Rotation: CompressedWordVector :: CompressedWordVector -> Rotation
+ Rattletrap.Type.Rotation: Quaternion :: Quaternion -> Rotation
+ Rattletrap.Type.Rotation: bitGet :: Version -> BitGet Rotation
+ Rattletrap.Type.Rotation: bitPut :: Rotation -> BitPut
+ Rattletrap.Type.Rotation: data Rotation
+ Rattletrap.Type.Rotation: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Rotation.Rotation
+ Rattletrap.Type.Rotation: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Rotation.Rotation
+ Rattletrap.Type.Rotation: instance GHC.Classes.Eq Rattletrap.Type.Rotation.Rotation
+ Rattletrap.Type.Rotation: instance GHC.Show.Show Rattletrap.Type.Rotation.Rotation
+ Rattletrap.Type.Rotation: isQuaternion :: Version -> Bool
+ Rattletrap.Type.Rotation: schema :: Schema
+ Rattletrap.Type.Section: Section :: U32 -> U32 -> a -> Section a
+ Rattletrap.Type.Section: [body] :: Section a -> a
+ Rattletrap.Type.Section: [crc] :: Section a -> U32
+ Rattletrap.Type.Section: [size] :: Section a -> U32
+ Rattletrap.Type.Section: byteGet :: Bool -> (U32 -> ByteGet a) -> ByteGet (Section a)
+ Rattletrap.Type.Section: bytePut :: (a -> BytePut) -> Section a -> BytePut
+ Rattletrap.Type.Section: crcMessage :: U32 -> U32 -> String
+ Rattletrap.Type.Section: create :: (a -> BytePut) -> a -> Section a
+ Rattletrap.Type.Section: data Section a
+ Rattletrap.Type.Section: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Type.Section.Section a)
+ Rattletrap.Type.Section: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Type.Section.Section a)
+ Rattletrap.Type.Section: instance GHC.Classes.Eq a => GHC.Classes.Eq (Rattletrap.Type.Section.Section a)
+ Rattletrap.Type.Section: instance GHC.Show.Show a => GHC.Show.Show (Rattletrap.Type.Section.Section a)
+ Rattletrap.Type.Section: schema :: Schema -> Schema
+ Rattletrap.Type.Str: Str :: Text -> Str
+ Rattletrap.Type.Str: addNull :: Text -> Text
+ Rattletrap.Type.Str: bitGet :: BitGet Str
+ Rattletrap.Type.Str: bitPut :: Str -> BitPut
+ Rattletrap.Type.Str: byteGet :: ByteGet Str
+ Rattletrap.Type.Str: bytePut :: Str -> BytePut
+ Rattletrap.Type.Str: dropNull :: Text -> Text
+ Rattletrap.Type.Str: fromString :: String -> Str
+ Rattletrap.Type.Str: fromText :: Text -> Str
+ Rattletrap.Type.Str: getTextDecoder :: I32 -> ByteString -> Text
+ Rattletrap.Type.Str: getTextEncoder :: I32 -> Text -> ByteString
+ Rattletrap.Type.Str: getTextSize :: Str -> I32
+ Rattletrap.Type.Str: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Str.Str
+ Rattletrap.Type.Str: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Str.Str
+ Rattletrap.Type.Str: instance GHC.Classes.Eq Rattletrap.Type.Str.Str
+ Rattletrap.Type.Str: instance GHC.Classes.Ord Rattletrap.Type.Str.Str
+ Rattletrap.Type.Str: instance GHC.Show.Show Rattletrap.Type.Str.Str
+ Rattletrap.Type.Str: newtype Str
+ Rattletrap.Type.Str: normalizeTextSize :: Integral a => I32 -> a
+ Rattletrap.Type.Str: schema :: Schema
+ Rattletrap.Type.Str: toString :: Str -> String
+ Rattletrap.Type.Str: toText :: Str -> Text
+ Rattletrap.Type.U32: U32 :: Word32 -> U32
+ Rattletrap.Type.U32: bitGet :: BitGet U32
+ Rattletrap.Type.U32: bitPut :: U32 -> BitPut
+ Rattletrap.Type.U32: byteGet :: ByteGet U32
+ Rattletrap.Type.U32: bytePut :: U32 -> BytePut
+ Rattletrap.Type.U32: fromWord32 :: Word32 -> U32
+ Rattletrap.Type.U32: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.U32.U32
+ Rattletrap.Type.U32: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.U32.U32
+ Rattletrap.Type.U32: instance GHC.Classes.Eq Rattletrap.Type.U32.U32
+ Rattletrap.Type.U32: instance GHC.Classes.Ord Rattletrap.Type.U32.U32
+ Rattletrap.Type.U32: instance GHC.Show.Show Rattletrap.Type.U32.U32
+ Rattletrap.Type.U32: newtype U32
+ Rattletrap.Type.U32: schema :: Schema
+ Rattletrap.Type.U32: toWord32 :: U32 -> Word32
+ Rattletrap.Type.U64: U64 :: Word64 -> U64
+ Rattletrap.Type.U64: bitGet :: BitGet U64
+ Rattletrap.Type.U64: bitPut :: U64 -> BitPut
+ Rattletrap.Type.U64: byteGet :: ByteGet U64
+ Rattletrap.Type.U64: bytePut :: U64 -> BytePut
+ Rattletrap.Type.U64: fromWord64 :: Word64 -> U64
+ Rattletrap.Type.U64: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.U64.U64
+ Rattletrap.Type.U64: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.U64.U64
+ Rattletrap.Type.U64: instance GHC.Classes.Eq Rattletrap.Type.U64.U64
+ Rattletrap.Type.U64: instance GHC.Show.Show Rattletrap.Type.U64.U64
+ Rattletrap.Type.U64: newtype U64
+ Rattletrap.Type.U64: schema :: Schema
+ Rattletrap.Type.U64: toWord64 :: U64 -> Word64
+ Rattletrap.Type.U8: U8 :: Word8 -> U8
+ Rattletrap.Type.U8: bitGet :: BitGet U8
+ Rattletrap.Type.U8: bitPut :: U8 -> BitPut
+ Rattletrap.Type.U8: byteGet :: ByteGet U8
+ Rattletrap.Type.U8: bytePut :: U8 -> BytePut
+ Rattletrap.Type.U8: fromWord8 :: Word8 -> U8
+ Rattletrap.Type.U8: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.U8.U8
+ Rattletrap.Type.U8: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.U8.U8
+ Rattletrap.Type.U8: instance GHC.Classes.Eq Rattletrap.Type.U8.U8
+ Rattletrap.Type.U8: instance GHC.Show.Show Rattletrap.Type.U8.U8
+ Rattletrap.Type.U8: newtype U8
+ Rattletrap.Type.U8: schema :: Schema
+ Rattletrap.Type.U8: toWord8 :: U8 -> Word8
+ Rattletrap.Type.Vector: Vector :: CompressedWord -> Word -> Int -> Int -> Int -> Vector
+ Rattletrap.Type.Vector: [bias] :: Vector -> Word
+ Rattletrap.Type.Vector: [size] :: Vector -> CompressedWord
+ Rattletrap.Type.Vector: [x] :: Vector -> Int
+ Rattletrap.Type.Vector: [y] :: Vector -> Int
+ Rattletrap.Type.Vector: [z] :: Vector -> Int
+ Rattletrap.Type.Vector: bitGet :: Version -> BitGet Vector
+ Rattletrap.Type.Vector: bitPut :: Vector -> BitPut
+ Rattletrap.Type.Vector: data Vector
+ Rattletrap.Type.Vector: fromDelta :: Word -> CompressedWord -> Int
+ Rattletrap.Type.Vector: getBias :: CompressedWord -> Word
+ Rattletrap.Type.Vector: getLimit :: CompressedWord -> Word
+ Rattletrap.Type.Vector: has21Bits :: Version -> Bool
+ Rattletrap.Type.Vector: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Vector.Vector
+ Rattletrap.Type.Vector: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Vector.Vector
+ Rattletrap.Type.Vector: instance GHC.Classes.Eq Rattletrap.Type.Vector.Vector
+ Rattletrap.Type.Vector: instance GHC.Show.Show Rattletrap.Type.Vector.Vector
+ Rattletrap.Type.Vector: schema :: Schema
+ Rattletrap.Type.Version: Version :: Int -> Int -> Int -> Version
+ Rattletrap.Type.Version: [major] :: Version -> Int
+ Rattletrap.Type.Version: [minor] :: Version -> Int
+ Rattletrap.Type.Version: [patch] :: Version -> Int
+ Rattletrap.Type.Version: data Version
+ Rattletrap.Type.Version: instance GHC.Classes.Eq Rattletrap.Type.Version.Version
+ Rattletrap.Type.Version: instance GHC.Show.Show Rattletrap.Type.Version.Version
+ Rattletrap.Utility.Bytes: encodeLatin1 :: Text -> ByteString
+ Rattletrap.Utility.Bytes: padBytes :: Integral a => a -> ByteString -> ByteString
+ Rattletrap.Utility.Bytes: reverseBytes :: ByteString -> ByteString
+ Rattletrap.Utility.Crc: compute :: ByteString -> Word32
+ Rattletrap.Utility.Helper: decodeReplayFile :: Bool -> Bool -> ByteString -> Either String Replay
+ Rattletrap.Utility.Helper: decodeReplayJson :: ByteString -> Either String Replay
+ Rattletrap.Utility.Helper: encodeReplayFile :: Bool -> Replay -> ByteString
+ Rattletrap.Utility.Helper: encodeReplayJson :: Replay -> ByteString
+ Rattletrap.Utility.Json: class FromJSON a
+ Rattletrap.Utility.Json: class ToJSON a
+ Rattletrap.Utility.Json: data Value
+ Rattletrap.Utility.Json: object :: [Pair] -> Value
+ Rattletrap.Utility.Json: optional :: FromJSON value => Object -> String -> Parser (Maybe value)
+ Rattletrap.Utility.Json: pair :: (ToJSON value, KeyValue pair) => String -> value -> pair
+ Rattletrap.Utility.Json: parseJSON :: FromJSON a => Value -> Parser a
+ Rattletrap.Utility.Json: required :: FromJSON value => Object -> String -> Parser value
+ Rattletrap.Utility.Json: toJSON :: ToJSON a => a -> Value
+ Rattletrap.Utility.Json: withObject :: String -> (Object -> Parser a) -> Value -> Parser a
+ Rattletrap.Utility.Json: withText :: String -> (Text -> Parser a) -> Value -> Parser a
+ Rattletrap.Utility.Monad: whenMaybe :: Applicative m => Bool -> m a -> m (Maybe a)
+ Rattletrap.Version: string :: String
- Rattletrap: decodeReplayFile :: Bool -> ByteString -> Either String FullReplay
+ Rattletrap: decodeReplayFile :: Bool -> Bool -> ByteString -> Either String Replay
- Rattletrap: decodeReplayJson :: ByteString -> Either String FullReplay
+ Rattletrap: decodeReplayJson :: ByteString -> Either String Replay
- Rattletrap: encodeReplayFile :: Bool -> FullReplay -> ByteString
+ Rattletrap: encodeReplayFile :: Bool -> Replay -> ByteString
- Rattletrap: encodeReplayJson :: FullReplay -> ByteString
+ Rattletrap: encodeReplayJson :: Replay -> ByteString
Files
- rattletrap.cabal +87/−239
- src/exe/Main.hs +1/−2
- src/lib/Rattletrap.hs +1/−152
- src/lib/Rattletrap/BitGet.hs +48/−0
- src/lib/Rattletrap/BitPut.hs +41/−0
- src/lib/Rattletrap/ByteGet.hs +65/−0
- src/lib/Rattletrap/BytePut.hs +39/−0
- src/lib/Rattletrap/Console/Config.hs +57/−0
- src/lib/Rattletrap/Console/Flag.hs +13/−0
- src/lib/Rattletrap/Console/Main.hs +248/−199
- src/lib/Rattletrap/Console/Mode.hs +12/−0
- src/lib/Rattletrap/Console/Option.hs +62/−0
- src/lib/Rattletrap/Data.hs +208/−466
- src/lib/Rattletrap/Decode/AppliedDamageAttribute.hs +0/−19
- src/lib/Rattletrap/Decode/Attribute.hs +0/−73
- src/lib/Rattletrap/Decode/AttributeMapping.hs +0/−12
- src/lib/Rattletrap/Decode/AttributeValue.hs +0/−131
- src/lib/Rattletrap/Decode/BooleanAttribute.hs +0/−10
- src/lib/Rattletrap/Decode/ByteAttribute.hs +0/−11
- src/lib/Rattletrap/Decode/Cache.hs +0/−18
- src/lib/Rattletrap/Decode/CamSettingsAttribute.hs +0/−20
- src/lib/Rattletrap/Decode/ClassMapping.hs +0/−12
- src/lib/Rattletrap/Decode/ClubColorsAttribute.hs +0/−16
- src/lib/Rattletrap/Decode/Common.hs +0/−70
- src/lib/Rattletrap/Decode/CompressedWord.hs +0/−30
- src/lib/Rattletrap/Decode/CompressedWordVector.hs +0/−18
- src/lib/Rattletrap/Decode/Content.hs +0/−71
- src/lib/Rattletrap/Decode/CustomDemolishAttribute.hs +0/−16
- src/lib/Rattletrap/Decode/DamageStateAttribute.hs +0/−21
- src/lib/Rattletrap/Decode/DemolishAttribute.hs +0/−19
- src/lib/Rattletrap/Decode/DestroyedReplication.hs +0/−10
- src/lib/Rattletrap/Decode/Dictionary.hs +0/−17
- src/lib/Rattletrap/Decode/EnumAttribute.hs +0/−10
- src/lib/Rattletrap/Decode/ExplosionAttribute.hs +0/−17
- src/lib/Rattletrap/Decode/ExtendedExplosionAttribute.hs +0/−16
- src/lib/Rattletrap/Decode/FlaggedByteAttribute.hs +0/−13
- src/lib/Rattletrap/Decode/FlaggedIntAttribute.hs +0/−12
- src/lib/Rattletrap/Decode/Float32le.hs +0/−14
- src/lib/Rattletrap/Decode/FloatAttribute.hs +0/−11
- src/lib/Rattletrap/Decode/Frame.hs +0/−43
- src/lib/Rattletrap/Decode/GameModeAttribute.hs +0/−15
- src/lib/Rattletrap/Decode/Header.hs +0/−22
- src/lib/Rattletrap/Decode/Initialization.hs +0/−16
- src/lib/Rattletrap/Decode/Int32le.hs +0/−14
- src/lib/Rattletrap/Decode/Int64Attribute.hs +0/−11
- src/lib/Rattletrap/Decode/Int64le.hs +0/−13
- src/lib/Rattletrap/Decode/Int8Vector.hs +0/−18
- src/lib/Rattletrap/Decode/Int8le.hs +0/−13
- src/lib/Rattletrap/Decode/IntAttribute.hs +0/−11
- src/lib/Rattletrap/Decode/KeyFrame.hs +0/−13
- src/lib/Rattletrap/Decode/List.hs +0/−16
- src/lib/Rattletrap/Decode/LoadoutAttribute.hs +0/−31
- src/lib/Rattletrap/Decode/LoadoutOnlineAttribute.hs +0/−25
- src/lib/Rattletrap/Decode/LoadoutsAttribute.hs +0/−14
- src/lib/Rattletrap/Decode/LoadoutsOnlineAttribute.hs +0/−23
- src/lib/Rattletrap/Decode/LocationAttribute.hs +0/−12
- src/lib/Rattletrap/Decode/Mark.hs +0/−12
- src/lib/Rattletrap/Decode/Message.hs +0/−12
- src/lib/Rattletrap/Decode/MusicStingerAttribute.hs +0/−16
- src/lib/Rattletrap/Decode/PartyLeaderAttribute.hs +0/−18
- src/lib/Rattletrap/Decode/PickupAttribute.hs +0/−13
- src/lib/Rattletrap/Decode/PickupAttributeNew.hs +0/−16
- src/lib/Rattletrap/Decode/PlayerHistoryKeyAttribute.hs +0/−11
- src/lib/Rattletrap/Decode/PrivateMatchSettingsAttribute.hs +0/−20
- src/lib/Rattletrap/Decode/ProductAttribute.hs +0/−70
- src/lib/Rattletrap/Decode/Property.hs +0/−15
- src/lib/Rattletrap/Decode/PropertyValue.hs +0/−31
- src/lib/Rattletrap/Decode/QWordAttribute.hs +0/−11
- src/lib/Rattletrap/Decode/Quaternion.hs +0/−26
- src/lib/Rattletrap/Decode/RemoteId.hs +0/−49
- src/lib/Rattletrap/Decode/Replay.hs +0/−66
- src/lib/Rattletrap/Decode/Replication.hs +0/−45
- src/lib/Rattletrap/Decode/ReplicationValue.hs +0/−45
- src/lib/Rattletrap/Decode/ReservationAttribute.hs +0/−25
- src/lib/Rattletrap/Decode/RigidBodyStateAttribute.hs +0/−19
- src/lib/Rattletrap/Decode/Rotation.hs +0/−14
- src/lib/Rattletrap/Decode/Section.hs +0/−30
- src/lib/Rattletrap/Decode/SpawnedReplication.hs +0/−72
- src/lib/Rattletrap/Decode/StatEventAttribute.hs +0/−12
- src/lib/Rattletrap/Decode/Str.hs +0/−47
- src/lib/Rattletrap/Decode/StringAttribute.hs +0/−11
- src/lib/Rattletrap/Decode/TeamPaintAttribute.hs +0/−18
- src/lib/Rattletrap/Decode/TitleAttribute.hs +0/−20
- src/lib/Rattletrap/Decode/UniqueIdAttribute.hs +0/−16
- src/lib/Rattletrap/Decode/UpdatedReplication.hs +0/−22
- src/lib/Rattletrap/Decode/Vector.hs +0/−29
- src/lib/Rattletrap/Decode/WeldedInfoAttribute.hs +0/−21
- src/lib/Rattletrap/Decode/Word32le.hs +0/−14
- src/lib/Rattletrap/Decode/Word64le.hs +0/−14
- src/lib/Rattletrap/Decode/Word8le.hs +0/−14
- src/lib/Rattletrap/Encode/AppliedDamageAttribute.hs +0/−18
- src/lib/Rattletrap/Encode/Attribute.hs +0/−26
- src/lib/Rattletrap/Encode/AttributeMapping.hs +0/−14
- src/lib/Rattletrap/Encode/AttributeValue.hs +0/−85
- src/lib/Rattletrap/Encode/BooleanAttribute.hs +0/−12
- src/lib/Rattletrap/Encode/ByteAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/Cache.hs +0/−18
- src/lib/Rattletrap/Encode/CamSettingsAttribute.hs +0/−21
- src/lib/Rattletrap/Encode/ClassMapping.hs +0/−15
- src/lib/Rattletrap/Encode/ClubColorsAttribute.hs +0/−16
- src/lib/Rattletrap/Encode/Common.hs +0/−10
- src/lib/Rattletrap/Encode/CompressedWord.hs +0/−44
- src/lib/Rattletrap/Encode/CompressedWordVector.hs +0/−15
- src/lib/Rattletrap/Encode/Content.hs +0/−58
- src/lib/Rattletrap/Encode/CustomDemolishAttribute.hs +0/−16
- src/lib/Rattletrap/Encode/DamageStateAttribute.hs +0/−20
- src/lib/Rattletrap/Encode/DemolishAttribute.hs +0/−19
- src/lib/Rattletrap/Encode/DestroyedReplication.hs +0/−11
- src/lib/Rattletrap/Encode/Dictionary.hs +0/−17
- src/lib/Rattletrap/Encode/EnumAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/ExplosionAttribute.hs +0/−16
- src/lib/Rattletrap/Encode/ExtendedExplosionAttribute.hs +0/−16
- src/lib/Rattletrap/Encode/FlaggedByteAttribute.hs +0/−14
- src/lib/Rattletrap/Encode/FlaggedIntAttribute.hs +0/−14
- src/lib/Rattletrap/Encode/Float32le.hs +0/−21
- src/lib/Rattletrap/Encode/FloatAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/Frame.hs +0/−24
- src/lib/Rattletrap/Encode/GameModeAttribute.hs +0/−14
- src/lib/Rattletrap/Encode/Header.hs +0/−22
- src/lib/Rattletrap/Encode/Initialization.hs +0/−19
- src/lib/Rattletrap/Encode/Int32le.hs +0/−21
- src/lib/Rattletrap/Encode/Int64Attribute.hs +0/−13
- src/lib/Rattletrap/Encode/Int64le.hs +0/−20
- src/lib/Rattletrap/Encode/Int8Vector.hs +0/−23
- src/lib/Rattletrap/Encode/Int8le.hs +0/−19
- src/lib/Rattletrap/Encode/IntAttribute.hs +0/−12
- src/lib/Rattletrap/Encode/KeyFrame.hs +0/−16
- src/lib/Rattletrap/Encode/List.hs +0/−16
- src/lib/Rattletrap/Encode/LoadoutAttribute.hs +0/−35
- src/lib/Rattletrap/Encode/LoadoutOnlineAttribute.hs +0/−17
- src/lib/Rattletrap/Encode/LoadoutsAttribute.hs +0/−14
- src/lib/Rattletrap/Encode/LoadoutsOnlineAttribute.hs +0/−18
- src/lib/Rattletrap/Encode/LocationAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/Mark.hs +0/−15
- src/lib/Rattletrap/Encode/Message.hs +0/−16
- src/lib/Rattletrap/Encode/MusicStingerAttribute.hs +0/−16
- src/lib/Rattletrap/Encode/PartyLeaderAttribute.hs +0/−19
- src/lib/Rattletrap/Encode/PickupAttribute.hs +0/−18
- src/lib/Rattletrap/Encode/PickupAttributeNew.hs +0/−19
- src/lib/Rattletrap/Encode/PlayerHistoryKeyAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/PrivateMatchSettingsAttribute.hs +0/−26
- src/lib/Rattletrap/Encode/ProductAttribute.hs +0/−37
- src/lib/Rattletrap/Encode/Property.hs +0/−17
- src/lib/Rattletrap/Encode/PropertyValue.hs +0/−30
- src/lib/Rattletrap/Encode/QWordAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/Quaternion.hs +0/−41
- src/lib/Rattletrap/Encode/RemoteId.hs +0/−37
- src/lib/Rattletrap/Encode/Replay.hs +0/−21
- src/lib/Rattletrap/Encode/Replication.hs +0/−26
- src/lib/Rattletrap/Encode/ReplicationValue.hs +0/−25
- src/lib/Rattletrap/Encode/ReservationAttribute.hs +0/−24
- src/lib/Rattletrap/Encode/RigidBodyStateAttribute.hs +0/−22
- src/lib/Rattletrap/Encode/Rotation.hs +0/−15
- src/lib/Rattletrap/Encode/Section.hs +0/−31
- src/lib/Rattletrap/Encode/SpawnedReplication.hs +0/−19
- src/lib/Rattletrap/Encode/StatEventAttribute.hs +0/−14
- src/lib/Rattletrap/Encode/Str.hs +0/−53
- src/lib/Rattletrap/Encode/StringAttribute.hs +0/−13
- src/lib/Rattletrap/Encode/TeamPaintAttribute.hs +0/−18
- src/lib/Rattletrap/Encode/TitleAttribute.hs +0/−20
- src/lib/Rattletrap/Encode/UniqueIdAttribute.hs +0/−16
- src/lib/Rattletrap/Encode/UpdatedReplication.hs +0/−13
- src/lib/Rattletrap/Encode/Vector.hs +0/−27
- src/lib/Rattletrap/Encode/WeldedInfoAttribute.hs +0/−20
- src/lib/Rattletrap/Encode/Word32le.hs +0/−21
- src/lib/Rattletrap/Encode/Word64le.hs +0/−21
- src/lib/Rattletrap/Encode/Word8le.hs +0/−21
- src/lib/Rattletrap/Get.hs +48/−0
- src/lib/Rattletrap/Schema.hs +61/−0
- src/lib/Rattletrap/Type/AppliedDamageAttribute.hs +0/−20
- src/lib/Rattletrap/Type/Attribute.hs +89/−15
- src/lib/Rattletrap/Type/Attribute/AppliedDamage.hs +57/−0
- src/lib/Rattletrap/Type/Attribute/Boolean.hs +25/−0
- src/lib/Rattletrap/Type/Attribute/Byte.hs +26/−0
- src/lib/Rattletrap/Type/Attribute/CamSettings.hs +88/−0
- src/lib/Rattletrap/Type/Attribute/ClubColors.hs +50/−0
- src/lib/Rattletrap/Type/Attribute/CustomDemolish.hs +48/−0
- src/lib/Rattletrap/Type/Attribute/DamageState.hs +76/−0
- src/lib/Rattletrap/Type/Attribute/Demolish.hs +75/−0
- src/lib/Rattletrap/Type/Attribute/Enum.hs +27/−0
- src/lib/Rattletrap/Type/Attribute/Explosion.hs +47/−0
- src/lib/Rattletrap/Type/Attribute/ExtendedExplosion.hs +38/−0
- src/lib/Rattletrap/Type/Attribute/FlaggedByte.hs +36/−0
- src/lib/Rattletrap/Type/Attribute/FlaggedInt.hs +35/−0
- src/lib/Rattletrap/Type/Attribute/Float.hs +27/−0
- src/lib/Rattletrap/Type/Attribute/GameMode.hs +49/−0
- src/lib/Rattletrap/Type/Attribute/Int.hs +27/−0
- src/lib/Rattletrap/Type/Attribute/Int64.hs +26/−0
- src/lib/Rattletrap/Type/Attribute/Loadout.hs +153/−0
- src/lib/Rattletrap/Type/Attribute/LoadoutOnline.hs +46/−0
- src/lib/Rattletrap/Type/Attribute/Loadouts.hs +36/−0
- src/lib/Rattletrap/Type/Attribute/LoadoutsOnline.hs +60/−0
- src/lib/Rattletrap/Type/Attribute/Location.hs +27/−0
- src/lib/Rattletrap/Type/Attribute/MusicStinger.hs +45/−0
- src/lib/Rattletrap/Type/Attribute/PartyLeader.hs +50/−0
- src/lib/Rattletrap/Type/Attribute/Pickup.hs +45/−0
- src/lib/Rattletrap/Type/Attribute/PickupNew.hs +46/−0
- src/lib/Rattletrap/Type/Attribute/PlayerHistoryKey.hs +27/−0
- src/lib/Rattletrap/Type/Attribute/PrivateMatchSettings.hs +74/−0
- src/lib/Rattletrap/Type/Attribute/Product.hs +74/−0
- src/lib/Rattletrap/Type/Attribute/ProductValue.hs +121/−0
- src/lib/Rattletrap/Type/Attribute/QWord.hs +26/−0
- src/lib/Rattletrap/Type/Attribute/Reservation.hs +76/−0
- src/lib/Rattletrap/Type/Attribute/RigidBodyState.hs +73/−0
- src/lib/Rattletrap/Type/Attribute/StatEvent.hs +36/−0
- src/lib/Rattletrap/Type/Attribute/String.hs +27/−0
- src/lib/Rattletrap/Type/Attribute/TeamPaint.hs +67/−0
- src/lib/Rattletrap/Type/Attribute/Title.hs +87/−0
- src/lib/Rattletrap/Type/Attribute/UniqueId.hs +48/−0
- src/lib/Rattletrap/Type/Attribute/WeldedInfo.hs +64/−0
- src/lib/Rattletrap/Type/AttributeMapping.hs +31/−12
- src/lib/Rattletrap/Type/AttributeType.hs +39/−48
- src/lib/Rattletrap/Type/AttributeValue.hs +307/−82
- src/lib/Rattletrap/Type/BooleanAttribute.hs +0/−14
- src/lib/Rattletrap/Type/ByteAttribute.hs +0/−15
- src/lib/Rattletrap/Type/Cache.hs +55/−16
- src/lib/Rattletrap/Type/CamSettingsAttribute.hs +0/−21
- src/lib/Rattletrap/Type/ClassAttributeMap.hs +124/−122
- src/lib/Rattletrap/Type/ClassMapping.hs +32/−13
- src/lib/Rattletrap/Type/ClubColorsAttribute.hs +0/−18
- src/lib/Rattletrap/Type/Common.hs +0/−56
- src/lib/Rattletrap/Type/CompressedWord.hs +79/−10
- src/lib/Rattletrap/Type/CompressedWordVector.hs +44/−13
- src/lib/Rattletrap/Type/Content.hs +204/−45
- src/lib/Rattletrap/Type/CustomDemolishAttribute.hs +0/−18
- src/lib/Rattletrap/Type/DamageStateAttribute.hs +0/−22
- src/lib/Rattletrap/Type/DemolishAttribute.hs +0/−21
- src/lib/Rattletrap/Type/DestroyedReplication.hs +0/−16
- src/lib/Rattletrap/Type/Dictionary.hs +77/−53
- src/lib/Rattletrap/Type/EnumAttribute.hs +0/−14
- src/lib/Rattletrap/Type/ExplosionAttribute.hs +0/−18
- src/lib/Rattletrap/Type/ExtendedExplosionAttribute.hs +0/−17
- src/lib/Rattletrap/Type/F32.hs +39/−0
- src/lib/Rattletrap/Type/FlaggedByteAttribute.hs +0/−16
- src/lib/Rattletrap/Type/FlaggedIntAttribute.hs +0/−16
- src/lib/Rattletrap/Type/Float32le.hs +0/−14
- src/lib/Rattletrap/Type/FloatAttribute.hs +0/−15
- src/lib/Rattletrap/Type/Frame.hs +77/−13
- src/lib/Rattletrap/Type/GameModeAttribute.hs +0/−19
- src/lib/Rattletrap/Type/Header.hs +69/−18
- src/lib/Rattletrap/Type/I32.hs +44/−0
- src/lib/Rattletrap/Type/I64.hs +48/−0
- src/lib/Rattletrap/Type/I8.hs +44/−0
- src/lib/Rattletrap/Type/Initialization.hs +43/−15
- src/lib/Rattletrap/Type/Int32le.hs +0/−14
- src/lib/Rattletrap/Type/Int64Attribute.hs +0/−15
- src/lib/Rattletrap/Type/Int64le.hs +0/−28
- src/lib/Rattletrap/Type/Int8Vector.hs +49/−13
- src/lib/Rattletrap/Type/Int8le.hs +0/−14
- src/lib/Rattletrap/Type/IntAttribute.hs +0/−15
- src/lib/Rattletrap/Type/KeyFrame.hs +39/−14
- src/lib/Rattletrap/Type/List.hs +50/−10
- src/lib/Rattletrap/Type/LoadoutAttribute.hs +0/−33
- src/lib/Rattletrap/Type/LoadoutOnlineAttribute.hs +0/−15
- src/lib/Rattletrap/Type/LoadoutsAttribute.hs +0/−16
- src/lib/Rattletrap/Type/LoadoutsOnlineAttribute.hs +0/−18
- src/lib/Rattletrap/Type/LocationAttribute.hs +0/−15
- src/lib/Rattletrap/Type/Mark.hs +32/−13
- src/lib/Rattletrap/Type/Message.hs +42/−14
- src/lib/Rattletrap/Type/MusicStingerAttribute.hs +0/−18
- src/lib/Rattletrap/Type/PartyLeaderAttribute.hs +0/−17
- src/lib/Rattletrap/Type/PickupAttribute.hs +0/−16
- src/lib/Rattletrap/Type/PickupAttributeNew.hs +0/−17
- src/lib/Rattletrap/Type/PlayerHistoryKeyAttribute.hs +0/−14
- src/lib/Rattletrap/Type/PrivateMatchSettingsAttribute.hs +0/−21
- src/lib/Rattletrap/Type/ProductAttribute.hs +0/−35
- src/lib/Rattletrap/Type/Property.hs +44/−15
- src/lib/Rattletrap/Type/PropertyValue.hs +90/−24
- src/lib/Rattletrap/Type/QWordAttribute.hs +0/−15
- src/lib/Rattletrap/Type/Quaternion.hs +105/−42
- src/lib/Rattletrap/Type/RemoteId.hs +129/−17
- src/lib/Rattletrap/Type/Replay.hs +117/−17
- src/lib/Rattletrap/Type/Replication.hs +66/−12
- src/lib/Rattletrap/Type/Replication/Destroyed.hs +30/−0
- src/lib/Rattletrap/Type/Replication/Spawned.hs +156/−0
- src/lib/Rattletrap/Type/Replication/Updated.hs +47/−0
- src/lib/Rattletrap/Type/ReplicationValue.hs +66/−14
- src/lib/Rattletrap/Type/ReservationAttribute.hs +0/−22
- src/lib/Rattletrap/Type/RigidBodyStateAttribute.hs +0/−20
- src/lib/Rattletrap/Type/Rotation.hs +44/−13
- src/lib/Rattletrap/Type/Section.hs +74/−24
- src/lib/Rattletrap/Type/SpawnedReplication.hs +0/−30
- src/lib/Rattletrap/Type/StatEventAttribute.hs +0/−16
- src/lib/Rattletrap/Type/Str.hs +96/−17
- src/lib/Rattletrap/Type/StringAttribute.hs +0/−15
- src/lib/Rattletrap/Type/TeamPaintAttribute.hs +0/−20
- src/lib/Rattletrap/Type/TitleAttribute.hs +0/−22
- src/lib/Rattletrap/Type/U32.hs +44/−0
- src/lib/Rattletrap/Type/U64.hs +48/−0
- src/lib/Rattletrap/Type/U8.hs +44/−0
- src/lib/Rattletrap/Type/UniqueIdAttribute.hs +0/−18
- src/lib/Rattletrap/Type/UpdatedReplication.hs +0/−15
- src/lib/Rattletrap/Type/Vector.hs +83/−18
- src/lib/Rattletrap/Type/Version.hs +8/−0
- src/lib/Rattletrap/Type/WeldedInfoAttribute.hs +0/−22
- src/lib/Rattletrap/Type/Word32le.hs +0/−14
- src/lib/Rattletrap/Type/Word64le.hs +0/−28
- src/lib/Rattletrap/Type/Word8le.hs +0/−14
- src/lib/Rattletrap/Utility/Bytes.hs +1/−2
- src/lib/Rattletrap/Utility/Crc.hs +276/−28
- src/lib/Rattletrap/Utility/Helper.hs +23/−24
- src/lib/Rattletrap/Utility/Json.hs +23/−0
- src/lib/Rattletrap/Utility/Monad.hs +4/−0
- src/lib/Rattletrap/Version.hs +7/−0
- src/test/Main.hs +26/−52
rattletrap.cabal view
@@ -1,7 +1,7 @@-cabal-version: >= 1.10+cabal-version: 2.0 name: rattletrap-version: 9.4.1+version: 10.0.0 synopsis: Parse and generate Rocket League replays. description: Rattletrap parses and generates Rocket League replays. @@ -16,16 +16,13 @@ type: git location: https://github.com/tfausak/rattletrap -flag static- manual: True- default: False- library autogen-modules: Paths_rattletrap build-depends: base >= 4.14.1 && < 4.15 , aeson >= 1.5.5 && < 1.6 , aeson-pretty >= 0.8.8 && < 0.9+ , array >= 0.5.4 && < 0.6 , binary >= 0.8.8 && < 0.9 , bytestring >= 0.10.12 && < 0.11 , caerbannog >= 0.6.0 && < 0.7@@ -33,288 +30,139 @@ , filepath >= 1.4.2 && < 1.5 , http-client >= 0.6.4 && < 0.8 , http-client-tls >= 0.3.5 && < 0.4- , scientific >= 0.3.6 && < 0.4- , template-haskell >= 2.16.0 && < 2.17 , text >= 1.2.4 && < 1.3 , transformers >= 0.5.6 && < 0.6+ default-extensions: NamedFieldPuns default-language: Haskell2010- exposed-modules: Rattletrap- ghc-options:- -Weverything- -Wno-all-missed-specialisations- -Wno-implicit-prelude- -Wno-missing-deriving-strategies- -Wno-missing-exported-signatures- -Wno-missing-import-lists- -Wno-safe- -Wno-unsafe- hs-source-dirs: src/lib- other-modules:+ exposed-modules: Paths_rattletrap+ Rattletrap+ Rattletrap.BitGet+ Rattletrap.BitPut+ Rattletrap.ByteGet+ Rattletrap.BytePut+ Rattletrap.Console.Config+ Rattletrap.Console.Flag Rattletrap.Console.Main+ Rattletrap.Console.Mode+ Rattletrap.Console.Option Rattletrap.Data- Rattletrap.Decode.AppliedDamageAttribute- Rattletrap.Decode.Attribute- Rattletrap.Decode.AttributeMapping- Rattletrap.Decode.AttributeValue- Rattletrap.Decode.BooleanAttribute- Rattletrap.Decode.ByteAttribute- Rattletrap.Decode.Cache- Rattletrap.Decode.CamSettingsAttribute- Rattletrap.Decode.ClassMapping- Rattletrap.Decode.ClubColorsAttribute- Rattletrap.Decode.Common- Rattletrap.Decode.CompressedWord- Rattletrap.Decode.CompressedWordVector- Rattletrap.Decode.Content- Rattletrap.Decode.CustomDemolishAttribute- Rattletrap.Decode.DamageStateAttribute- Rattletrap.Decode.DemolishAttribute- Rattletrap.Decode.DestroyedReplication- Rattletrap.Decode.Dictionary- Rattletrap.Decode.EnumAttribute- Rattletrap.Decode.ExplosionAttribute- Rattletrap.Decode.ExtendedExplosionAttribute- Rattletrap.Decode.FlaggedIntAttribute- Rattletrap.Decode.FlaggedByteAttribute- Rattletrap.Decode.Float32le- Rattletrap.Decode.FloatAttribute- Rattletrap.Decode.Frame- Rattletrap.Decode.GameModeAttribute- Rattletrap.Decode.Header- Rattletrap.Decode.Initialization- Rattletrap.Decode.Int32le- Rattletrap.Decode.Int64Attribute- Rattletrap.Decode.Int64le- Rattletrap.Decode.Int8le- Rattletrap.Decode.Int8Vector- Rattletrap.Decode.IntAttribute- Rattletrap.Decode.KeyFrame- Rattletrap.Decode.List- Rattletrap.Decode.LoadoutAttribute- Rattletrap.Decode.LoadoutOnlineAttribute- Rattletrap.Decode.LoadoutsAttribute- Rattletrap.Decode.LoadoutsOnlineAttribute- Rattletrap.Decode.LocationAttribute- Rattletrap.Decode.Mark- Rattletrap.Decode.Message- Rattletrap.Decode.MusicStingerAttribute- Rattletrap.Decode.PartyLeaderAttribute- Rattletrap.Decode.PickupAttribute- Rattletrap.Decode.PickupAttributeNew- Rattletrap.Decode.PlayerHistoryKeyAttribute- Rattletrap.Decode.PrivateMatchSettingsAttribute- Rattletrap.Decode.ProductAttribute- Rattletrap.Decode.Property- Rattletrap.Decode.PropertyValue- Rattletrap.Decode.Quaternion- Rattletrap.Decode.QWordAttribute- Rattletrap.Decode.RemoteId- Rattletrap.Decode.Replay- Rattletrap.Decode.Replication- Rattletrap.Decode.ReplicationValue- Rattletrap.Decode.ReservationAttribute- Rattletrap.Decode.RigidBodyStateAttribute- Rattletrap.Decode.Rotation- Rattletrap.Decode.Section- Rattletrap.Decode.SpawnedReplication- Rattletrap.Decode.StatEventAttribute- Rattletrap.Decode.Str- Rattletrap.Decode.StringAttribute- Rattletrap.Decode.TeamPaintAttribute- Rattletrap.Decode.TitleAttribute- Rattletrap.Decode.UniqueIdAttribute- Rattletrap.Decode.UpdatedReplication- Rattletrap.Decode.Vector- Rattletrap.Decode.WeldedInfoAttribute- Rattletrap.Decode.Word32le- Rattletrap.Decode.Word64le- Rattletrap.Decode.Word8le- Rattletrap.Encode.AppliedDamageAttribute- Rattletrap.Encode.Attribute- Rattletrap.Encode.AttributeMapping- Rattletrap.Encode.AttributeValue- Rattletrap.Encode.BooleanAttribute- Rattletrap.Encode.ByteAttribute- Rattletrap.Encode.Cache- Rattletrap.Encode.CamSettingsAttribute- Rattletrap.Encode.ClassMapping- Rattletrap.Encode.ClubColorsAttribute- Rattletrap.Encode.Common- Rattletrap.Encode.CompressedWord- Rattletrap.Encode.CompressedWordVector- Rattletrap.Encode.Content- Rattletrap.Encode.CustomDemolishAttribute- Rattletrap.Encode.DamageStateAttribute- Rattletrap.Encode.DemolishAttribute- Rattletrap.Encode.DestroyedReplication- Rattletrap.Encode.Dictionary- Rattletrap.Encode.EnumAttribute- Rattletrap.Encode.ExplosionAttribute- Rattletrap.Encode.ExtendedExplosionAttribute- Rattletrap.Encode.FlaggedIntAttribute- Rattletrap.Encode.FlaggedByteAttribute- Rattletrap.Encode.Float32le- Rattletrap.Encode.FloatAttribute- Rattletrap.Encode.Frame- Rattletrap.Encode.GameModeAttribute- Rattletrap.Encode.Header- Rattletrap.Encode.Initialization- Rattletrap.Encode.Int32le- Rattletrap.Encode.Int64Attribute- Rattletrap.Encode.Int64le- Rattletrap.Encode.Int8le- Rattletrap.Encode.Int8Vector- Rattletrap.Encode.IntAttribute- Rattletrap.Encode.KeyFrame- Rattletrap.Encode.List- Rattletrap.Encode.LoadoutAttribute- Rattletrap.Encode.LoadoutOnlineAttribute- Rattletrap.Encode.LoadoutsAttribute- Rattletrap.Encode.LoadoutsOnlineAttribute- Rattletrap.Encode.LocationAttribute- Rattletrap.Encode.Mark- Rattletrap.Encode.Message- Rattletrap.Encode.MusicStingerAttribute- Rattletrap.Encode.PartyLeaderAttribute- Rattletrap.Encode.PickupAttribute- Rattletrap.Encode.PickupAttributeNew- Rattletrap.Encode.PlayerHistoryKeyAttribute- Rattletrap.Encode.PrivateMatchSettingsAttribute- Rattletrap.Encode.ProductAttribute- Rattletrap.Encode.Property- Rattletrap.Encode.PropertyValue- Rattletrap.Encode.Quaternion- Rattletrap.Encode.QWordAttribute- Rattletrap.Encode.RemoteId- Rattletrap.Encode.Replay- Rattletrap.Encode.Replication- Rattletrap.Encode.ReplicationValue- Rattletrap.Encode.ReservationAttribute- Rattletrap.Encode.RigidBodyStateAttribute- Rattletrap.Encode.Rotation- Rattletrap.Encode.Section- Rattletrap.Encode.SpawnedReplication- Rattletrap.Encode.StatEventAttribute- Rattletrap.Encode.Str- Rattletrap.Encode.StringAttribute- Rattletrap.Encode.TeamPaintAttribute- Rattletrap.Encode.TitleAttribute- Rattletrap.Encode.UniqueIdAttribute- Rattletrap.Encode.UpdatedReplication- Rattletrap.Encode.Vector- Rattletrap.Encode.WeldedInfoAttribute- Rattletrap.Encode.Word32le- Rattletrap.Encode.Word64le- Rattletrap.Encode.Word8le- Rattletrap.Type.AppliedDamageAttribute+ Rattletrap.Get+ Rattletrap.Schema Rattletrap.Type.Attribute+ Rattletrap.Type.Attribute.AppliedDamage+ Rattletrap.Type.Attribute.Boolean+ Rattletrap.Type.Attribute.Byte+ Rattletrap.Type.Attribute.CamSettings+ Rattletrap.Type.Attribute.ClubColors+ Rattletrap.Type.Attribute.CustomDemolish+ Rattletrap.Type.Attribute.DamageState+ Rattletrap.Type.Attribute.Demolish+ Rattletrap.Type.Attribute.Enum+ Rattletrap.Type.Attribute.Explosion+ Rattletrap.Type.Attribute.ExtendedExplosion+ Rattletrap.Type.Attribute.FlaggedByte+ Rattletrap.Type.Attribute.FlaggedInt+ Rattletrap.Type.Attribute.Float+ Rattletrap.Type.Attribute.GameMode+ Rattletrap.Type.Attribute.Int+ Rattletrap.Type.Attribute.Int64+ Rattletrap.Type.Attribute.Loadout+ Rattletrap.Type.Attribute.LoadoutOnline+ Rattletrap.Type.Attribute.Loadouts+ Rattletrap.Type.Attribute.LoadoutsOnline+ Rattletrap.Type.Attribute.Location+ Rattletrap.Type.Attribute.MusicStinger+ Rattletrap.Type.Attribute.PartyLeader+ Rattletrap.Type.Attribute.Pickup+ Rattletrap.Type.Attribute.PickupNew+ Rattletrap.Type.Attribute.PlayerHistoryKey+ Rattletrap.Type.Attribute.PrivateMatchSettings+ Rattletrap.Type.Attribute.Product+ Rattletrap.Type.Attribute.ProductValue+ Rattletrap.Type.Attribute.QWord+ Rattletrap.Type.Attribute.Reservation+ Rattletrap.Type.Attribute.RigidBodyState+ Rattletrap.Type.Attribute.StatEvent+ Rattletrap.Type.Attribute.String+ Rattletrap.Type.Attribute.TeamPaint+ Rattletrap.Type.Attribute.Title+ Rattletrap.Type.Attribute.UniqueId+ Rattletrap.Type.Attribute.WeldedInfo Rattletrap.Type.AttributeMapping Rattletrap.Type.AttributeType Rattletrap.Type.AttributeValue- Rattletrap.Type.BooleanAttribute- Rattletrap.Type.ByteAttribute Rattletrap.Type.Cache- Rattletrap.Type.CamSettingsAttribute Rattletrap.Type.ClassAttributeMap Rattletrap.Type.ClassMapping- Rattletrap.Type.ClubColorsAttribute- Rattletrap.Type.Common Rattletrap.Type.CompressedWord Rattletrap.Type.CompressedWordVector Rattletrap.Type.Content- Rattletrap.Type.CustomDemolishAttribute- Rattletrap.Type.DamageStateAttribute- Rattletrap.Type.DemolishAttribute- Rattletrap.Type.DestroyedReplication Rattletrap.Type.Dictionary- Rattletrap.Type.EnumAttribute- Rattletrap.Type.ExplosionAttribute- Rattletrap.Type.ExtendedExplosionAttribute- Rattletrap.Type.FlaggedIntAttribute- Rattletrap.Type.FlaggedByteAttribute- Rattletrap.Type.Float32le- Rattletrap.Type.FloatAttribute+ Rattletrap.Type.F32 Rattletrap.Type.Frame- Rattletrap.Type.GameModeAttribute Rattletrap.Type.Header+ Rattletrap.Type.I32+ Rattletrap.Type.I64+ Rattletrap.Type.I8 Rattletrap.Type.Initialization- Rattletrap.Type.Int32le- Rattletrap.Type.Int64Attribute- Rattletrap.Type.Int64le- Rattletrap.Type.Int8le Rattletrap.Type.Int8Vector- Rattletrap.Type.IntAttribute Rattletrap.Type.KeyFrame Rattletrap.Type.List- Rattletrap.Type.LoadoutAttribute- Rattletrap.Type.LoadoutOnlineAttribute- Rattletrap.Type.LoadoutsAttribute- Rattletrap.Type.LoadoutsOnlineAttribute- Rattletrap.Type.LocationAttribute Rattletrap.Type.Mark Rattletrap.Type.Message- Rattletrap.Type.MusicStingerAttribute- Rattletrap.Type.PartyLeaderAttribute- Rattletrap.Type.PickupAttribute- Rattletrap.Type.PickupAttributeNew- Rattletrap.Type.PlayerHistoryKeyAttribute- Rattletrap.Type.PrivateMatchSettingsAttribute- Rattletrap.Type.ProductAttribute Rattletrap.Type.Property Rattletrap.Type.PropertyValue Rattletrap.Type.Quaternion- Rattletrap.Type.QWordAttribute Rattletrap.Type.RemoteId Rattletrap.Type.Replay Rattletrap.Type.Replication+ Rattletrap.Type.Replication.Destroyed+ Rattletrap.Type.Replication.Spawned+ Rattletrap.Type.Replication.Updated Rattletrap.Type.ReplicationValue- Rattletrap.Type.ReservationAttribute- Rattletrap.Type.RigidBodyStateAttribute Rattletrap.Type.Rotation Rattletrap.Type.Section- Rattletrap.Type.SpawnedReplication- Rattletrap.Type.StatEventAttribute Rattletrap.Type.Str- Rattletrap.Type.StringAttribute- Rattletrap.Type.TeamPaintAttribute- Rattletrap.Type.TitleAttribute- Rattletrap.Type.UniqueIdAttribute- Rattletrap.Type.UpdatedReplication+ Rattletrap.Type.U32+ Rattletrap.Type.U64+ Rattletrap.Type.U8 Rattletrap.Type.Vector- Rattletrap.Type.WeldedInfoAttribute- Rattletrap.Type.Word32le- Rattletrap.Type.Word64le- Rattletrap.Type.Word8le+ Rattletrap.Type.Version Rattletrap.Utility.Bytes Rattletrap.Utility.Crc Rattletrap.Utility.Helper-- if impl(ghc >= 8.10)- ghc-options:- -Wno-missing-safe-haskell-mode- -Wno-prepositive-qualified-module+ Rattletrap.Utility.Json+ Rattletrap.Utility.Monad+ Rattletrap.Version+ ghc-options:+ -Weverything+ -Wno-all-missed-specialisations+ -Wno-implicit-prelude+ -Wno-missing-deriving-strategies+ -Wno-missing-export-lists+ -Wno-missing-exported-signatures+ -Wno-missing-import-lists+ -Wno-missing-safe-haskell-mode+ -Wno-prepositive-qualified-module+ -Wno-safe+ -Wno-unsafe+ hs-source-dirs: src/lib executable rattletrap- build-depends:- base -any- , rattletrap -any+ build-depends: base, rattletrap default-language: Haskell2010 ghc-options: -rtsopts -threaded hs-source-dirs: src/exe main-is: Main.hs - if flag(static)- ld-options: -static- test-suite test build-depends:- base -any- , bytestring -any- , filepath -any+ base+ , bytestring+ , filepath , HUnit >= 1.6.1 && < 1.7- , rattletrap -any- , temporary >= 1.3 && < 1.4+ , rattletrap default-language: Haskell2010 ghc-options: -rtsopts -threaded hs-source-dirs: src/test
src/exe/Main.hs view
@@ -1,6 +1,5 @@ module Main ( main- )-where+ ) where import Rattletrap (main)
src/lib/Rattletrap.hs view
@@ -5,158 +5,7 @@ , 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+ ) 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
+ src/lib/Rattletrap/BitGet.hs view
@@ -0,0 +1,48 @@+module Rattletrap.BitGet where++import qualified Control.Monad as Monad+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 ByteString+import qualified Data.ByteString.Lazy as LazyByteString+import qualified Data.Word as Word+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.Get as Get+import qualified Rattletrap.Utility.Bytes as Utility++type BitGet = BinaryBits.BitGet++toByteGet :: BitGet a -> ByteGet.ByteGet a+toByteGet = binaryGetToByteGet . BinaryBits.runBitGet++binaryGetToByteGet :: Binary.Get a -> ByteGet.ByteGet a+binaryGetToByteGet g = do+ s1 <- Get.get+ case Binary.runGetOrFail g $ LazyByteString.fromStrict s1 of+ Left (_, _, x) -> fail x+ Right (s2, _, x) -> do+ Get.put $ LazyByteString.toStrict s2+ pure x++fromByteGet :: ByteGet.ByteGet a -> Int -> BitGet a+fromByteGet f n = do+ x <- BinaryBits.getByteString n+ either fail pure . ByteGet.run f $ Utility.reverseBytes x++bits :: Bits.Bits a => Int -> BitGet a+bits n =+ foldr+ (\bit x -> let y = Bits.shiftL x 1 in if bit then Bits.setBit y 0 else y+ )+ Bits.zeroBits+ <$> Monad.replicateM n bool++bool :: BitGet Bool+bool = BinaryBits.getBool++byteString :: Int -> BitGet ByteString.ByteString+byteString = BinaryBits.getByteString++word8 :: Int -> BitGet Word.Word8+word8 = BinaryBits.getWord8
+ src/lib/Rattletrap/BitPut.hs view
@@ -0,0 +1,41 @@+module Rattletrap.BitPut where++import qualified Data.Binary.Bits.Put as BinaryBits+import qualified Data.Binary.Put as Binary+import qualified Data.Bits as Bits+import qualified Data.ByteString as ByteString+import qualified Data.Word as Word+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Utility.Bytes as Utility++newtype BitPut = BitPut (BinaryBits.BitPut ())++instance Semigroup BitPut where+ x <> y = fromBinaryBits $ toBinaryBits x >> toBinaryBits y++instance Monoid BitPut where+ mempty = fromBinaryBits $ pure ()++fromBinaryBits :: BinaryBits.BitPut () -> BitPut+fromBinaryBits = BitPut++toBinaryBits :: BitPut -> BinaryBits.BitPut ()+toBinaryBits (BitPut x) = x++toBytePut :: BitPut -> BytePut.BytePut+toBytePut = Binary.execPut . BinaryBits.runBitPut . toBinaryBits++fromBytePut :: BytePut.BytePut -> BitPut+fromBytePut = byteString . Utility.reverseBytes . BytePut.toByteString++bits :: Bits.Bits a => Int -> a -> BitPut+bits n x = foldMap (bool . Bits.testBit x) [0 .. n - 1]++bool :: Bool -> BitPut+bool = fromBinaryBits . BinaryBits.putBool++byteString :: ByteString.ByteString -> BitPut+byteString = fromBinaryBits . BinaryBits.putByteString++word8 :: Int -> Word.Word8 -> BitPut+word8 n = fromBinaryBits . BinaryBits.putWord8 n
+ src/lib/Rattletrap/ByteGet.hs view
@@ -0,0 +1,65 @@+module Rattletrap.ByteGet where++import qualified Data.Bits as Bits+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Lazy as LazyByteString+import qualified Data.Functor.Identity as Identity+import qualified Data.Int as Int+import qualified Data.Word as Word+import qualified GHC.Float as Float+import qualified Rattletrap.Get as Get++type ByteGet = Get.Get ByteString.ByteString Identity.Identity++run :: ByteGet a -> ByteString.ByteString -> Either String a+run g = fmap snd . Identity.runIdentity . Get.run g++byteString :: Int -> ByteGet ByteString.ByteString+byteString n = do+ s1 <- Get.get+ let (x, s2) = ByteString.splitAt n s1+ Get.put s2+ pure x++float :: ByteGet Float+float = Float.castWord32ToFloat <$> word32++int8 :: ByteGet Int.Int8+int8 = fromIntegral <$> word8++int32 :: ByteGet Int.Int32+int32 = fromIntegral <$> word32++int64 :: ByteGet Int.Int64+int64 = fromIntegral <$> word64++remaining :: ByteGet LazyByteString.ByteString+remaining = do+ x <- Get.get+ Get.put ByteString.empty+ pure $ LazyByteString.fromStrict x++word8 :: ByteGet Word.Word8+word8 = ByteString.head <$> byteString 1++word32 :: ByteGet Word.Word32+word32 = do+ x <- byteString 4+ pure+ $ Bits.shiftL (fromIntegral $ ByteString.index x 0) 0+ + Bits.shiftL (fromIntegral $ ByteString.index x 1) 8+ + Bits.shiftL (fromIntegral $ ByteString.index x 2) 16+ + Bits.shiftL (fromIntegral $ ByteString.index x 3) 24++word64 :: ByteGet Word.Word64+word64 = do+ x <- byteString 8+ pure+ $ Bits.shiftL (fromIntegral $ ByteString.index x 0) 0+ + Bits.shiftL (fromIntegral $ ByteString.index x 1) 8+ + Bits.shiftL (fromIntegral $ ByteString.index x 2) 16+ + Bits.shiftL (fromIntegral $ ByteString.index x 3) 24+ + Bits.shiftL (fromIntegral $ ByteString.index x 4) 32+ + Bits.shiftL (fromIntegral $ ByteString.index x 5) 40+ + Bits.shiftL (fromIntegral $ ByteString.index x 6) 48+ + Bits.shiftL (fromIntegral $ ByteString.index x 7) 56
+ src/lib/Rattletrap/BytePut.hs view
@@ -0,0 +1,39 @@+module Rattletrap.BytePut where++import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Builder as Builder+import qualified Data.ByteString.Lazy as LazyByteString+import qualified Data.Int as Int+import qualified Data.Word as Word++type BytePut = Builder.Builder++toByteString :: BytePut -> ByteString.ByteString+toByteString = LazyByteString.toStrict . toLazyByteString++toLazyByteString :: BytePut -> LazyByteString.ByteString+toLazyByteString = Builder.toLazyByteString++byteString :: ByteString.ByteString -> BytePut+byteString = Builder.byteString++float :: Float -> BytePut+float = Builder.floatLE++int8 :: Int.Int8 -> BytePut+int8 = Builder.int8++int32 :: Int.Int32 -> BytePut+int32 = Builder.int32LE++int64 :: Int.Int64 -> BytePut+int64 = Builder.int64LE++word8 :: Word.Word8 -> BytePut+word8 = Builder.word8++word32 :: Word.Word32 -> BytePut+word32 = Builder.word32LE++word64 :: Word.Word64 -> BytePut+word64 = Builder.word64LE
+ src/lib/Rattletrap/Console/Config.hs view
@@ -0,0 +1,57 @@+module Rattletrap.Console.Config where++import qualified Rattletrap.Console.Flag as Flag+import qualified Rattletrap.Console.Mode as Mode+import qualified System.FilePath as FilePath++data Config = Config+ { compact :: Bool+ , fast :: Bool+ , help :: Bool+ , input :: Maybe String+ , mode :: Maybe Mode.Mode+ , output :: Maybe String+ , schema :: Bool+ , skipCrc :: Bool+ , version :: Bool+ }+ deriving (Eq, Show)++initial :: Config+initial = Config+ { compact = False+ , fast = False+ , help = False+ , input = Nothing+ , mode = Nothing+ , output = Nothing+ , schema = False+ , skipCrc = False+ , version = False+ }++applyFlag :: Config -> Flag.Flag -> Either String Config+applyFlag config flag = case flag of+ Flag.Compact -> Right config { compact = True }+ Flag.Fast -> Right config { fast = True }+ Flag.Help -> Right config { help = True }+ Flag.Input x -> Right config { input = Just x }+ Flag.Mode x -> do+ y <- Mode.fromString x+ Right config { mode = Just y }+ Flag.Output x -> Right config { output = Just x }+ Flag.Schema -> Right config { schema = True }+ Flag.SkipCrc -> Right config { skipCrc = True }+ Flag.Version -> Right config { version = True }++getMode :: Config -> Mode.Mode+getMode config =+ let+ i = FilePath.takeExtension <$> input config+ o = FilePath.takeExtension <$> output config+ in case (i, o) of+ (Just ".json", _) -> Mode.Encode+ (Just ".replay", _) -> Mode.Decode+ (_, Just ".json") -> Mode.Decode+ (_, Just ".replay") -> Mode.Encode+ _ -> Mode.Decode
+ src/lib/Rattletrap/Console/Flag.hs view
@@ -0,0 +1,13 @@+module Rattletrap.Console.Flag where++data Flag+ = Compact+ | Fast+ | Help+ | Input FilePath+ | Mode String+ | Output FilePath+ | Schema+ | SkipCrc+ | Version+ deriving (Eq, Show)
src/lib/Rattletrap/Console/Main.hs view
@@ -1,25 +1,103 @@ module Rattletrap.Console.Main ( main , rattletrap- )-where+ ) 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 Data.Aeson as Aeson+import qualified Data.Aeson.Encode.Pretty as Aeson+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Lazy as LazyByteString 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.Console.Config as Config+import qualified Rattletrap.Console.Mode as Mode+import qualified Rattletrap.Console.Option as Option+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute as Attribute+import qualified Rattletrap.Type.Attribute.AppliedDamage as Attribute.AppliedDamage+import qualified Rattletrap.Type.Attribute.Boolean as Attribute.Boolean+import qualified Rattletrap.Type.Attribute.Byte as Attribute.Byte+import qualified Rattletrap.Type.Attribute.CamSettings as Attribute.CamSettings+import qualified Rattletrap.Type.Attribute.ClubColors as Attribute.ClubColors+import qualified Rattletrap.Type.Attribute.CustomDemolish as Attribute.CustomDemolish+import qualified Rattletrap.Type.Attribute.DamageState as Attribute.DamageState+import qualified Rattletrap.Type.Attribute.Demolish as Attribute.Demolish+import qualified Rattletrap.Type.Attribute.Enum as Attribute.Enum+import qualified Rattletrap.Type.Attribute.Explosion as Attribute.Explosion+import qualified Rattletrap.Type.Attribute.ExtendedExplosion as Attribute.ExtendedExplosion+import qualified Rattletrap.Type.Attribute.FlaggedByte as Attribute.FlaggedByte+import qualified Rattletrap.Type.Attribute.FlaggedInt as Attribute.FlaggedInt+import qualified Rattletrap.Type.Attribute.Float as Attribute.Float+import qualified Rattletrap.Type.Attribute.GameMode as Attribute.GameMode+import qualified Rattletrap.Type.Attribute.Int as Attribute.Int+import qualified Rattletrap.Type.Attribute.Int64 as Attribute.Int64+import qualified Rattletrap.Type.Attribute.Loadout as Attribute.Loadout+import qualified Rattletrap.Type.Attribute.LoadoutOnline as Attribute.LoadoutOnline+import qualified Rattletrap.Type.Attribute.Loadouts as Attribute.Loadouts+import qualified Rattletrap.Type.Attribute.LoadoutsOnline as Attribute.LoadoutsOnline+import qualified Rattletrap.Type.Attribute.Location as Attribute.Location+import qualified Rattletrap.Type.Attribute.MusicStinger as Attribute.MusicStinger+import qualified Rattletrap.Type.Attribute.PartyLeader as Attribute.PartyLeader+import qualified Rattletrap.Type.Attribute.Pickup as Attribute.Pickup+import qualified Rattletrap.Type.Attribute.PickupNew as Attribute.PickupNew+import qualified Rattletrap.Type.Attribute.PlayerHistoryKey as Attribute.PlayerHistoryKey+import qualified Rattletrap.Type.Attribute.PrivateMatchSettings as Attribute.PrivateMatchSettings+import qualified Rattletrap.Type.Attribute.Product as Attribute.Product+import qualified Rattletrap.Type.Attribute.ProductValue as Attribute.ProductValue+import qualified Rattletrap.Type.Attribute.QWord as Attribute.QWord+import qualified Rattletrap.Type.Attribute.Reservation as Attribute.Reservation+import qualified Rattletrap.Type.Attribute.RigidBodyState as Attribute.RigidBodyState+import qualified Rattletrap.Type.Attribute.StatEvent as Attribute.StatEvent+import qualified Rattletrap.Type.Attribute.String as Attribute.String+import qualified Rattletrap.Type.Attribute.TeamPaint as Attribute.TeamPaint+import qualified Rattletrap.Type.Attribute.Title as Attribute.Title+import qualified Rattletrap.Type.Attribute.UniqueId as Attribute.UniqueId+import qualified Rattletrap.Type.Attribute.WeldedInfo as Attribute.WeldedInfo+import qualified Rattletrap.Type.AttributeMapping as AttributeMapping+import qualified Rattletrap.Type.AttributeValue as AttributeValue+import qualified Rattletrap.Type.Cache as Cache+import qualified Rattletrap.Type.ClassMapping as ClassMapping+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.CompressedWordVector as CompressedWordVector+import qualified Rattletrap.Type.Content as Content+import qualified Rattletrap.Type.Dictionary as Dictionary+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Type.Frame as Frame+import qualified Rattletrap.Type.Header as Header+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.I64 as I64+import qualified Rattletrap.Type.I8 as I8+import qualified Rattletrap.Type.Initialization as Initialization+import qualified Rattletrap.Type.Int8Vector as Int8Vector+import qualified Rattletrap.Type.KeyFrame as KeyFrame+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Mark as Mark+import qualified Rattletrap.Type.Message as Message+import qualified Rattletrap.Type.Property as Property+import qualified Rattletrap.Type.PropertyValue as PropertyValue+import qualified Rattletrap.Type.Quaternion as Quaternion+import qualified Rattletrap.Type.RemoteId as RemoteId+import qualified Rattletrap.Type.Replay as Replay+import qualified Rattletrap.Type.Replication as Replication+import qualified Rattletrap.Type.Replication.Destroyed as Replication.Destroyed+import qualified Rattletrap.Type.Replication.Spawned as Replication.Spawned+import qualified Rattletrap.Type.Replication.Updated as Replication.Updated+import qualified Rattletrap.Type.ReplicationValue as ReplicationValue+import qualified Rattletrap.Type.Rotation as Rotation+import qualified Rattletrap.Type.Section as Section+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U64 as U64+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Vector as Vector import qualified Rattletrap.Utility.Helper as Rattletrap+import qualified Rattletrap.Utility.Json as Json+import qualified Rattletrap.Version as Version 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@@ -30,209 +108,180 @@ 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)+ if Config.help config+ then helpMain name+ else if Config.version config+ then versionMain+ else if Config.schema config+ then schemaMain config+ else defaultMain config++helpMain :: String -> IO ()+helpMain name = do+ putStr $ Console.usageInfo+ (unwords [name, "version", Version.string])+ Option.all++versionMain :: IO ()+versionMain = do+ putStrLn Version.string++schemaMain :: Config.Config -> IO ()+schemaMain config = do+ let+ json = Aeson.encodePretty'+ Aeson.defConfig+ { Aeson.confCompare = compare+ , Aeson.confIndent = Aeson.Tab+ , Aeson.confTrailingNewline = True+ }+ schema+ case Config.output config of+ Nothing -> LazyByteString.putStr json+ Just file -> LazyByteString.writeFile file json++defaultMain :: Config.Config -> IO ()+defaultMain config = do 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+schema :: Aeson.Value+schema =+ let contentSchema = Content.schema $ List.schema Frame.schema+ in+ Aeson.object+ [ Json.pair "$schema" "https://json-schema.org/draft-07/schema"+ , Json.pair "$id" Replay.schemaUrl+ , Json.pair "$ref" "#/definitions/replay"+ , Json.pair "definitions" . Aeson.object $ fmap+ (\s -> Schema.name s Aeson..= Schema.json s)+ [ Attribute.schema+ , Attribute.AppliedDamage.schema+ , Attribute.Boolean.schema+ , Attribute.Byte.schema+ , Attribute.CamSettings.schema+ , Attribute.ClubColors.schema+ , Attribute.CustomDemolish.schema+ , Attribute.DamageState.schema+ , Attribute.Demolish.schema+ , Attribute.Enum.schema+ , Attribute.Explosion.schema+ , Attribute.ExtendedExplosion.schema+ , Attribute.FlaggedByte.schema+ , Attribute.FlaggedInt.schema+ , Attribute.Float.schema+ , Attribute.GameMode.schema+ , Attribute.Int.schema+ , Attribute.Int64.schema+ , Attribute.Loadout.schema+ , Attribute.LoadoutOnline.schema+ , Attribute.Loadouts.schema+ , Attribute.LoadoutsOnline.schema+ , Attribute.Location.schema+ , Attribute.MusicStinger.schema+ , Attribute.PartyLeader.schema+ , Attribute.Pickup.schema+ , Attribute.PickupNew.schema+ , Attribute.PlayerHistoryKey.schema+ , Attribute.PrivateMatchSettings.schema+ , Attribute.Product.schema+ , Attribute.ProductValue.schema+ , Attribute.QWord.schema+ , Attribute.Reservation.schema+ , Attribute.RigidBodyState.schema+ , Attribute.StatEvent.schema+ , Attribute.String.schema+ , Attribute.TeamPaint.schema+ , Attribute.Title.schema+ , Attribute.UniqueId.schema+ , Attribute.WeldedInfo.schema+ , AttributeMapping.schema+ , AttributeValue.schema+ , Cache.schema+ , ClassMapping.schema+ , CompressedWord.schema+ , CompressedWordVector.schema+ , contentSchema+ , Dictionary.schema Property.schema+ , F32.schema+ , Frame.schema+ , Header.schema+ , I32.schema+ , I64.schema+ , I8.schema+ , Initialization.schema+ , Int8Vector.schema+ , KeyFrame.schema+ , List.schema Attribute.Product.schema+ , Mark.schema+ , Message.schema+ , Property.schema+ , PropertyValue.schema Property.schema+ , Quaternion.schema+ , RemoteId.schema+ , Replay.schema (Section.schema Header.schema)+ . Section.schema+ $ contentSchema+ , Replication.Destroyed.schema+ , Replication.schema+ , Replication.Spawned.schema+ , Replication.Updated.schema+ , ReplicationValue.schema+ , Rotation.schema+ , Schema.boolean+ , Schema.integer+ , Schema.null+ , Schema.number+ , Schema.string+ , Section.schema contentSchema+ , Section.schema Header.schema+ , Str.schema+ , U32.schema+ , U64.schema+ , U8.schema+ , Vector.schema+ ]+ ] -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+getDecoder+ :: Config.Config -> ByteString.ByteString -> Either String Replay.Replay+getDecoder config = case Config.getMode config of+ Mode.Decode ->+ Rattletrap.decodeReplayFile (Config.fast config) (Config.skipCrc config)+ Mode.Encode -> Rattletrap.decodeReplayJson -getInput :: Config -> IO Bytes.ByteString-getInput config = case configInput config of- Nothing -> Bytes.getContents+getEncoder :: Config.Config -> Replay.Replay -> LazyByteString.ByteString+getEncoder config = case Config.getMode config of+ Mode.Decode ->+ if Config.compact config then Aeson.encode else Rattletrap.encodeReplayJson+ Mode.Encode -> Rattletrap.encodeReplayFile $ Config.fast config++getInput :: Config.Config -> IO ByteString.ByteString+getInput config = case Config.input config of+ Nothing -> ByteString.getContents Just fileOrUrl -> case Client.parseUrlThrow fileOrUrl of- Nothing -> Bytes.readFile fileOrUrl+ Nothing -> ByteString.readFile fileOrUrl Just request -> do manager <- Client.newTlsManager response <- Client.httpLbs request manager- pure (LazyBytes.toStrict (Client.responseBody response))+ pure (LazyByteString.toStrict (Client.responseBody response)) -putOutput :: Config -> Bytes.ByteString -> IO ()-putOutput = maybe Bytes.putStr Bytes.writeFile . configOutput+putOutput :: Config.Config -> LazyByteString.ByteString -> IO ()+putOutput =+ maybe LazyByteString.putStr LazyByteString.writeFile . Config.output -getConfig :: [String] -> IO Config+getConfig :: [String] -> IO Config.Config getConfig arguments = do let- (updates, unexpectedArguments, unknownOptions, problems) =- Console.getOpt' Console.Permute options arguments- printUnexpectedArguments unexpectedArguments- printUnknownOptions unknownOptions- printProblems problems+ (flags, unexpectedArguments, unknownOptions, problems) =+ Console.getOpt' Console.Permute Option.all arguments+ Monad.forM_ unexpectedArguments $ \x ->+ IO.hPutStrLn IO.stderr $ "WARNING: unexpected argument `" <> x <> "'"+ Monad.forM_ unknownOptions+ $ \x -> IO.hPutStrLn IO.stderr $ "WARNING: unknown option `" <> x <> "'"+ Monad.forM_ problems $ \x -> IO.hPutStr IO.stderr $ "ERROR: " <> x 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+ either fail pure $ Monad.foldM Config.applyFlag Config.initial flags
+ src/lib/Rattletrap/Console/Mode.hs view
@@ -0,0 +1,12 @@+module Rattletrap.Console.Mode where++data Mode+ = Decode+ | Encode+ deriving (Eq, Show)++fromString :: String -> Either String Mode+fromString string = case string of+ "decode" -> Right Decode+ "encode" -> Right Encode+ _ -> Left $ "invalid mode: " <> show string
+ src/lib/Rattletrap/Console/Option.hs view
@@ -0,0 +1,62 @@+module Rattletrap.Console.Option where++import qualified Rattletrap.Console.Flag as Flag+import qualified System.Console.GetOpt as Console++type Option = Console.OptDescr Flag.Flag++all :: [Option]+all = [compact, fast, help, input, mode, output, schema, skipCrc, version]++compact :: Option+compact = Console.Option+ ['c']+ ["compact"]+ (Console.NoArg Flag.Compact)+ "minify JSON output"++fast :: Option+fast = Console.Option+ ['f']+ ["fast"]+ (Console.NoArg Flag.Fast)+ "only encode or decode the header"++help :: Option+help = Console.Option ['h'] ["help"] (Console.NoArg Flag.Help) "show the help"++input :: Option+input = Console.Option+ ['i']+ ["input"]+ (Console.ReqArg Flag.Input "FILE|URL")+ "input file or URL"++mode :: Option+mode = Console.Option+ ['m']+ ["mode"]+ (Console.ReqArg Flag.Mode "MODE")+ "decode or encode"++output :: Option+output = Console.Option+ ['o']+ ["output"]+ (Console.ReqArg Flag.Output "FILE")+ "output file"++schema :: Option+schema =+ Console.Option [] ["schema"] (Console.NoArg Flag.Schema) "output the schema"++skipCrc :: Option+skipCrc =+ Console.Option [] ["skip-crc"] (Console.NoArg Flag.SkipCrc) "skip the CRC"++version :: Option+version = Console.Option+ ['v']+ ["version"]+ (Console.NoArg Flag.Version)+ "show the version"
src/lib/Rattletrap/Data.hs view
@@ -1,18 +1,16 @@ -- brittany --columns 120-module Rattletrap.Data- ( rawParentClasses- , rawClassesWithLocation- , rawClassesWithRotation- , rawObjectClasses- , rawAttributeTypes- , rawCrc32Table- )-where+module Rattletrap.Data where -import Rattletrap.Type.AttributeType+import qualified Rattletrap.Type.AttributeType as AttributeType -rawParentClasses :: [(String, String)]-rawParentClasses =+import qualified Data.Bifunctor as Bifunctor+import qualified Data.Map as Map+import qualified Data.Set as Set+import qualified Data.Text as Text++parentClasses :: Map.Map Text.Text Text.Text+parentClasses = Map.fromList $ fmap+ (Bifunctor.bimap Text.pack Text.pack) [ ("Engine.Actor", "Core.Object") , ("Engine.GameReplicationInfo", "Engine.ReplicationInfo") , ("Engine.Info", "Engine.Actor")@@ -54,10 +52,10 @@ , ("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_Football_TA", "TAGame.SpecialPickup_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_Football_TA", "TAGame.SpecialPickup_TA") , ("TAGame.SpecialPickup_GrapplingHook_TA", "TAGame.SpecialPickup_Targeted_TA") , ("TAGame.SpecialPickup_HauntedBallBeam_TA", "TAGame.SpecialPickup_TA") , ("TAGame.SpecialPickup_HitForce_TA", "TAGame.SpecialPickup_TA")@@ -74,8 +72,9 @@ , ("TAGame.VehiclePickup_TA", "Engine.ReplicationInfo") ] -rawClassesWithLocation :: [String]-rawClassesWithLocation =+classesWithLocation :: Set.Set Text.Text+classesWithLocation = Set.fromList $ fmap+ Text.pack [ "Archetypes.Ball.Ball_BasketBall_Mutator" , "Archetypes.Ball.Ball_Basketball" , "Archetypes.Ball.Ball_BasketBall"@@ -109,8 +108,8 @@ , "TAGame.GameEvent_SoccarSplitscreen_TA" , "TAGame.GRI_TA" , "TAGame.MaxTimeWarningData_TA"- , "TAGame.RumblePickups_TA" , "TAGame.PRI_TA"+ , "TAGame.RumblePickups_TA" , "TAGame.SpecialPickup_BallCarSpring_TA" , "TAGame.SpecialPickup_BallFreeze_TA" , "TAGame.SpecialPickup_BallGravity_TA"@@ -133,8 +132,9 @@ , "TheWorld:PersistentLevel.VehiclePickup_Boost_TA" ] -rawClassesWithRotation :: [String]-rawClassesWithRotation =+classesWithRotation :: Set.Set Text.Text+classesWithRotation = Set.fromList $ fmap+ Text.pack [ "Archetypes.Ball.Ball_BasketBall_Mutator" , "Archetypes.Ball.Ball_Basketball" , "Archetypes.Ball.Ball_BasketBall"@@ -153,8 +153,9 @@ , "TAGame.Car_TA" ] -rawObjectClasses :: [(String, String)]-rawObjectClasses =+objectClasses :: Map.Map Text.Text Text.Text+objectClasses = Map.fromList $ fmap+ (Bifunctor.bimap Text.pack Text.pack) [ ("Archetypes.Ball.Ball_Anniversary", "TAGame.Ball_TA") , ("Archetypes.Ball.Ball_BasketBall_Mutator", "TAGame.Ball_TA") , ("Archetypes.Ball.Ball_Basketball", "TAGame.Ball_TA")@@ -219,8 +220,8 @@ , ("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")+ , ("TAGame.Default__RumblePickups_TA", "TAGame.RumblePickups_TA") , ("TheWorld:PersistentLevel.BreakOutActor_Platform_TA", "TAGame.BreakOutActor_Platform_TA") , ("TheWorld:PersistentLevel.CrowdActor_TA", "TAGame.CrowdActor_TA") , ("TheWorld:PersistentLevel.CrowdManager_TA", "TAGame.CrowdManager_TA")@@ -228,449 +229,190 @@ , ("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.RumblePickups_TA:AttachedPickup", AttributeTypeFlaggedInt)- , ("TAGame.RumblePickups_TA:ConcurrentItemCount", AttributeTypeInt)- , ("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_Football_TA:WeldedBall", AttributeTypeFlaggedInt)- , ("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+attributeTypes :: Map.Map Text.Text AttributeType.AttributeType+attributeTypes = Map.fromList $ fmap+ (Bifunctor.first Text.pack)+ [ ("Engine.Actor:bBlockActors", AttributeType.Boolean)+ , ("Engine.Actor:bCollideActors", AttributeType.Boolean)+ , ("Engine.Actor:bHidden", AttributeType.Boolean)+ , ("Engine.Actor:DrawScale", AttributeType.Float)+ , ("Engine.Actor:RemoteRole", AttributeType.Enum)+ , ("Engine.Actor:Role", AttributeType.Enum)+ , ("Engine.GameReplicationInfo:bMatchIsOver", AttributeType.Boolean)+ , ("Engine.GameReplicationInfo:GameClass", AttributeType.FlaggedInt)+ , ("Engine.GameReplicationInfo:ServerName", AttributeType.String)+ , ("Engine.Pawn:PlayerReplicationInfo", AttributeType.FlaggedInt)+ , ("Engine.PlayerReplicationInfo:bBot", AttributeType.Boolean)+ , ("Engine.PlayerReplicationInfo:bIsSpectator", AttributeType.Boolean)+ , ("Engine.PlayerReplicationInfo:bReadyToPlay", AttributeType.Boolean)+ , ("Engine.PlayerReplicationInfo:bTimedOut", AttributeType.Boolean)+ , ("Engine.PlayerReplicationInfo:bWaitingPlayer", AttributeType.Boolean)+ , ("Engine.PlayerReplicationInfo:Ping", AttributeType.Byte)+ , ("Engine.PlayerReplicationInfo:PlayerID", AttributeType.Int)+ , ("Engine.PlayerReplicationInfo:PlayerName", AttributeType.String)+ , ("Engine.PlayerReplicationInfo:RemoteUserData", AttributeType.String)+ , ("Engine.PlayerReplicationInfo:Score", AttributeType.Int)+ , ("Engine.PlayerReplicationInfo:Team", AttributeType.FlaggedInt)+ , ("Engine.PlayerReplicationInfo:UniqueId", AttributeType.UniqueId)+ , ("Engine.ReplicatedActor_ORS:ReplicatedOwner", AttributeType.FlaggedInt)+ , ("Engine.TeamInfo:Score", AttributeType.Int)+ , ("ProjectX.GRI_X:bGameStarted", AttributeType.Boolean)+ , ("ProjectX.GRI_X:GameServerID", AttributeType.QWord)+ , ("ProjectX.GRI_X:MatchGUID", AttributeType.String)+ , ("ProjectX.GRI_X:ReplicatedGameMutatorIndex", AttributeType.Int)+ , ("ProjectX.GRI_X:ReplicatedGamePlaylist", AttributeType.Int)+ , ("ProjectX.GRI_X:Reservations", AttributeType.Reservation)+ , ("TAGame.Ball_Breakout_TA:AppliedDamage", AttributeType.AppliedDamage)+ , ("TAGame.Ball_Breakout_TA:DamageIndex", AttributeType.Int)+ , ("TAGame.Ball_Breakout_TA:LastTeamTouch", AttributeType.Byte)+ , ("TAGame.Ball_God_TA:TargetSpeed", AttributeType.Float)+ , ("TAGame.Ball_Haunted_TA:bIsBallBeamed", AttributeType.Boolean)+ , ("TAGame.Ball_Haunted_TA:DeactivatedGoalIndex", AttributeType.Byte)+ , ("TAGame.Ball_Haunted_TA:LastTeamTouch", AttributeType.Byte)+ , ("TAGame.Ball_Haunted_TA:ReplicatedBeamBrokenValue", AttributeType.Byte)+ , ("TAGame.Ball_Haunted_TA:TotalActiveBeams", AttributeType.Byte)+ , ("TAGame.Ball_TA:GameEvent", AttributeType.FlaggedInt)+ , ("TAGame.Ball_TA:HitTeamNum", AttributeType.Byte)+ , ("TAGame.Ball_TA:ReplicatedAddedCarBounceScale", AttributeType.Float)+ , ("TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale", AttributeType.Float)+ , ("TAGame.Ball_TA:ReplicatedBallScale", AttributeType.Float)+ , ("TAGame.Ball_TA:ReplicatedExplosionData", AttributeType.Explosion)+ , ("TAGame.Ball_TA:ReplicatedExplosionDataExtended", AttributeType.ExtendedExplosion)+ , ("TAGame.Ball_TA:ReplicatedPhysMatOverride", AttributeType.FlaggedInt)+ , ("TAGame.Ball_TA:ReplicatedWorldBounceScale", AttributeType.Float)+ , ("TAGame.BreakOutActor_Platform_TA:DamageState", AttributeType.DamageState)+ , ("TAGame.CameraSettingsActor_TA:bMouseCameraToggleEnabled", AttributeType.Boolean)+ , ("TAGame.CameraSettingsActor_TA:bUsingBehindView", AttributeType.Boolean)+ , ("TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera", AttributeType.Boolean)+ , ("TAGame.CameraSettingsActor_TA:bUsingSwivel", AttributeType.Boolean)+ , ("TAGame.CameraSettingsActor_TA:CameraPitch", AttributeType.Byte)+ , ("TAGame.CameraSettingsActor_TA:CameraYaw", AttributeType.Byte)+ , ("TAGame.CameraSettingsActor_TA:PRI", AttributeType.FlaggedInt)+ , ("TAGame.CameraSettingsActor_TA:ProfileSettings", AttributeType.CamSettings)+ , ("TAGame.Car_TA:AddedBallForceMultiplier", AttributeType.Float)+ , ("TAGame.Car_TA:AddedCarForceMultiplier", AttributeType.Float)+ , ("TAGame.Car_TA:AttachedPickup", AttributeType.FlaggedInt)+ , ("TAGame.Car_TA:ClubColors", AttributeType.ClubColors)+ , ("TAGame.Car_TA:ReplicatedDemolish_CustomFX", AttributeType.CustomDemolish)+ , ("TAGame.Car_TA:ReplicatedDemolish", AttributeType.Demolish)+ , ("TAGame.Car_TA:RumblePickups", AttributeType.FlaggedInt)+ , ("TAGame.Car_TA:TeamPaint", AttributeType.TeamPaint)+ , ("TAGame.CarComponent_Boost_TA:bNoBoost", AttributeType.Boolean)+ , ("TAGame.CarComponent_Boost_TA:BoostModifier", AttributeType.Float)+ , ("TAGame.CarComponent_Boost_TA:bUnlimitedBoost", AttributeType.Boolean)+ , ("TAGame.CarComponent_Boost_TA:RechargeDelay", AttributeType.Float)+ , ("TAGame.CarComponent_Boost_TA:RechargeRate", AttributeType.Float)+ , ("TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount", AttributeType.Byte)+ , ("TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount", AttributeType.Int)+ , ("TAGame.CarComponent_Dodge_TA:DodgeTorque", AttributeType.Location)+ , ("TAGame.CarComponent_FlipCar_TA:bFlipRight", AttributeType.Boolean)+ , ("TAGame.CarComponent_FlipCar_TA:FlipCarTime", AttributeType.Float)+ , ("TAGame.CarComponent_TA:ReplicatedActive", AttributeType.Byte)+ , ("TAGame.CarComponent_TA:ReplicatedActivityTime", AttributeType.Float)+ , ("TAGame.CarComponent_TA:Vehicle", AttributeType.FlaggedInt)+ , ("TAGame.CrowdActor_TA:GameEvent", AttributeType.FlaggedInt)+ , ("TAGame.CrowdActor_TA:ModifiedNoise", AttributeType.Float)+ , ("TAGame.CrowdActor_TA:ReplicatedCountDownNumber", AttributeType.Int)+ , ("TAGame.CrowdActor_TA:ReplicatedOneShotSound", AttributeType.FlaggedInt)+ , ("TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber", AttributeType.Int)+ , ("TAGame.CrowdManager_TA:GameEvent", AttributeType.FlaggedInt)+ , ("TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound", AttributeType.FlaggedInt)+ , ("TAGame.GameEvent_Soccar_TA:bBallHasBeenHit", AttributeType.Boolean)+ , ("TAGame.GameEvent_Soccar_TA:bClubMatch", AttributeType.Boolean)+ , ("TAGame.GameEvent_Soccar_TA:bOverTime", AttributeType.Boolean)+ , ("TAGame.GameEvent_Soccar_TA:bUnlimitedTime", AttributeType.Boolean)+ , ("TAGame.GameEvent_Soccar_TA:GameTime", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:MaxScore", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger", AttributeType.MusicStinger)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam", AttributeType.Byte)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedServerPerformanceState", AttributeType.Byte)+ , ("TAGame.GameEvent_Soccar_TA:ReplicatedStatEvent", AttributeType.StatEvent)+ , ("TAGame.GameEvent_Soccar_TA:RoundNum", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:SecondsRemaining", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:SeriesLength", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:SubRulesArchetype", AttributeType.FlaggedInt)+ , ("TAGame.GameEvent_SoccarPrivate_TA:MatchSettings", AttributeType.PrivateMatchSettings)+ , ("TAGame.GameEvent_TA:bCanVoteToForfeit", AttributeType.Boolean)+ , ("TAGame.GameEvent_TA:bHasLeaveMatchPenalty", AttributeType.Boolean)+ , ("TAGame.GameEvent_TA:BotSkill", AttributeType.Int)+ , ("TAGame.GameEvent_TA:GameMode", AttributeType.GameMode)+ , ("TAGame.GameEvent_TA:MatchTypeClass", AttributeType.FlaggedInt)+ , ("TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining", AttributeType.Int)+ , ("TAGame.GameEvent_TA:ReplicatedRoundCountDownNumber", AttributeType.Int)+ , ("TAGame.GameEvent_TA:ReplicatedStateIndex", AttributeType.Byte)+ , ("TAGame.GameEvent_TA:ReplicatedStateName", AttributeType.Int)+ , ("TAGame.GameEvent_Team_TA:bForfeit", AttributeType.Boolean)+ , ("TAGame.GameEvent_Team_TA:MaxTeamSize", AttributeType.Int)+ , ("TAGame.GRI_TA:NewDedicatedServerIP", AttributeType.String)+ , ("TAGame.MaxTimeWarningData_TA:EndGameEpochTime", AttributeType.Int64)+ , ("TAGame.MaxTimeWarningData_TA:EndGameWarningEpochTime", AttributeType.Int64)+ , ("TAGame.PRI_TA:bIsDistracted", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bIsInSplitScreen", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bMatchMVP", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bOnlineLoadoutSet", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bOnlineLoadoutsSet", AttributeType.Boolean)+ , ("TAGame.PRI_TA:BotProductName", AttributeType.Int)+ , ("TAGame.PRI_TA:bReady", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bUsingBehindView", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bUsingItems", AttributeType.Boolean)+ , ("TAGame.PRI_TA:bUsingSecondaryCamera", AttributeType.Boolean)+ , ("TAGame.PRI_TA:CameraPitch", AttributeType.Byte)+ , ("TAGame.PRI_TA:CameraSettings", AttributeType.CamSettings)+ , ("TAGame.PRI_TA:CameraYaw", AttributeType.Byte)+ , ("TAGame.PRI_TA:ClientLoadout", AttributeType.Loadout)+ , ("TAGame.PRI_TA:ClientLoadoutOnline", AttributeType.LoadoutOnline)+ , ("TAGame.PRI_TA:ClientLoadouts", AttributeType.Loadouts)+ , ("TAGame.PRI_TA:ClientLoadoutsOnline", AttributeType.LoadoutsOnline)+ , ("TAGame.PRI_TA:ClubID", AttributeType.Int64)+ , ("TAGame.PRI_TA:MatchAssists", AttributeType.Int)+ , ("TAGame.PRI_TA:MatchBreakoutDamage", AttributeType.Int)+ , ("TAGame.PRI_TA:MatchGoals", AttributeType.Int)+ , ("TAGame.PRI_TA:MatchSaves", AttributeType.Int)+ , ("TAGame.PRI_TA:MatchScore", AttributeType.Int)+ , ("TAGame.PRI_TA:MatchShots", AttributeType.Int)+ , ("TAGame.PRI_TA:MaxTimeTillItem", AttributeType.Int)+ , ("TAGame.PRI_TA:PartyLeader", AttributeType.PartyLeader)+ , ("TAGame.PRI_TA:PawnType", AttributeType.Byte)+ , ("TAGame.PRI_TA:PersistentCamera", AttributeType.FlaggedInt)+ , ("TAGame.PRI_TA:PlayerHistoryKey", AttributeType.PlayerHistoryKey)+ , ("TAGame.PRI_TA:PlayerHistoryValid", AttributeType.Boolean)+ , ("TAGame.PRI_TA:PrimaryTitle", AttributeType.Title)+ , ("TAGame.PRI_TA:ReplicatedGameEvent", AttributeType.FlaggedInt)+ , ("TAGame.PRI_TA:ReplicatedWorstNetQualityBeyondLatency", AttributeType.Byte)+ , ("TAGame.PRI_TA:SecondaryTitle", AttributeType.Title)+ , ("TAGame.PRI_TA:SkillTier", AttributeType.FlaggedByte)+ , ("TAGame.PRI_TA:SpectatorShortcut", AttributeType.Int)+ , ("TAGame.PRI_TA:SteeringSensitivity", AttributeType.Float)+ , ("TAGame.PRI_TA:TimeTillItem", AttributeType.Int)+ , ("TAGame.PRI_TA:Title", AttributeType.Int)+ , ("TAGame.PRI_TA:TotalXP", AttributeType.Int)+ , ("TAGame.RBActor_TA:bFrozen", AttributeType.Boolean)+ , ("TAGame.RBActor_TA:bIgnoreSyncing", AttributeType.Boolean)+ , ("TAGame.RBActor_TA:bReplayActor", AttributeType.Boolean)+ , ("TAGame.RBActor_TA:ReplicatedRBState", AttributeType.RigidBodyState)+ , ("TAGame.RBActor_TA:WeldedInfo", AttributeType.WeldedInfo)+ , ("TAGame.RumblePickups_TA:AttachedPickup", AttributeType.FlaggedInt)+ , ("TAGame.RumblePickups_TA:ConcurrentItemCount", AttributeType.Int)+ , ("TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed", AttributeType.Float)+ , ("TAGame.SpecialPickup_BallVelcro_TA:AttachTime", AttributeType.Float)+ , ("TAGame.SpecialPickup_BallVelcro_TA:bBroken", AttributeType.Boolean)+ , ("TAGame.SpecialPickup_BallVelcro_TA:bHit", AttributeType.Boolean)+ , ("TAGame.SpecialPickup_BallVelcro_TA:BreakTime", AttributeType.Float)+ , ("TAGame.SpecialPickup_Football_TA:WeldedBall", AttributeType.FlaggedInt)+ , ("TAGame.SpecialPickup_Rugby_TA:bBallWelded", AttributeType.Boolean)+ , ("TAGame.SpecialPickup_Targeted_TA:Targeted", AttributeType.FlaggedInt)+ , ("TAGame.Team_Soccar_TA:GameScore", AttributeType.Int)+ , ("TAGame.Team_TA:ClubColors", AttributeType.ClubColors)+ , ("TAGame.Team_TA:ClubID", AttributeType.Int64)+ , ("TAGame.Team_TA:CustomTeamName", AttributeType.String)+ , ("TAGame.Team_TA:Difficulty", AttributeType.Int)+ , ("TAGame.Team_TA:GameEvent", AttributeType.FlaggedInt)+ , ("TAGame.Team_TA:LogoData", AttributeType.FlaggedInt)+ , ("TAGame.Vehicle_TA:bDriving", AttributeType.Boolean)+ , ("TAGame.Vehicle_TA:bReplicatedHandbrake", AttributeType.Boolean)+ , ("TAGame.Vehicle_TA:ReplicatedSteer", AttributeType.Byte)+ , ("TAGame.Vehicle_TA:ReplicatedThrottle", AttributeType.Byte)+ , ("TAGame.VehiclePickup_TA:bNoPickup", AttributeType.Boolean)+ , ("TAGame.VehiclePickup_TA:NewReplicatedPickupData", AttributeType.PickupNew)+ , ("TAGame.VehiclePickup_TA:ReplicatedPickupData", AttributeType.Pickup) ]
− src/lib/Rattletrap/Decode/AppliedDamageAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Attribute.hs
@@ -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
− src/lib/Rattletrap/Decode/AttributeMapping.hs
@@ -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
− src/lib/Rattletrap/Decode/AttributeValue.hs
@@ -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)
− src/lib/Rattletrap/Decode/BooleanAttribute.hs
@@ -1,10 +0,0 @@-module Rattletrap.Decode.BooleanAttribute- ( decodeBooleanAttributeBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.BooleanAttribute--decodeBooleanAttributeBits :: DecodeBits BooleanAttribute-decodeBooleanAttributeBits = BooleanAttribute <$> getBool
− src/lib/Rattletrap/Decode/ByteAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Cache.hs
@@ -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
− src/lib/Rattletrap/Decode/CamSettingsAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/ClassMapping.hs
@@ -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
− src/lib/Rattletrap/Decode/ClubColorsAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Common.hs
@@ -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
− src/lib/Rattletrap/Decode/CompressedWord.hs
@@ -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
− src/lib/Rattletrap/Decode/CompressedWordVector.hs
@@ -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
− src/lib/Rattletrap/Decode/Content.hs
@@ -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
− src/lib/Rattletrap/Decode/CustomDemolishAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/DamageStateAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/DemolishAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/DestroyedReplication.hs
@@ -1,10 +0,0 @@-module Rattletrap.Decode.DestroyedReplication- ( decodeDestroyedReplicationBits- )-where--import Rattletrap.Decode.Common-import Rattletrap.Type.DestroyedReplication--decodeDestroyedReplicationBits :: DecodeBits DestroyedReplication-decodeDestroyedReplicationBits = pure DestroyedReplication
− src/lib/Rattletrap/Decode/Dictionary.hs
@@ -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
− src/lib/Rattletrap/Decode/EnumAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/ExplosionAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/ExtendedExplosionAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/FlaggedByteAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/FlaggedIntAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Float32le.hs
@@ -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
− src/lib/Rattletrap/Decode/FloatAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Frame.hs
@@ -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
− src/lib/Rattletrap/Decode/GameModeAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Header.hs
@@ -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
− src/lib/Rattletrap/Decode/Initialization.hs
@@ -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
− src/lib/Rattletrap/Decode/Int32le.hs
@@ -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
− src/lib/Rattletrap/Decode/Int64Attribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Int64le.hs
@@ -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
− src/lib/Rattletrap/Decode/Int8Vector.hs
@@ -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
− src/lib/Rattletrap/Decode/Int8le.hs
@@ -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
− src/lib/Rattletrap/Decode/IntAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/KeyFrame.hs
@@ -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
− src/lib/Rattletrap/Decode/List.hs
@@ -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
− src/lib/Rattletrap/Decode/LoadoutAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/LoadoutOnlineAttribute.hs
@@ -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)
− src/lib/Rattletrap/Decode/LoadoutsAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/LoadoutsOnlineAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/LocationAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Mark.hs
@@ -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
− src/lib/Rattletrap/Decode/Message.hs
@@ -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
− src/lib/Rattletrap/Decode/MusicStingerAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/PartyLeaderAttribute.hs
@@ -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)
− src/lib/Rattletrap/Decode/PickupAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/PickupAttributeNew.hs
@@ -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
− src/lib/Rattletrap/Decode/PlayerHistoryKeyAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/PrivateMatchSettingsAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/ProductAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Property.hs
@@ -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
− src/lib/Rattletrap/Decode/PropertyValue.hs
@@ -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)
− src/lib/Rattletrap/Decode/QWordAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Quaternion.hs
@@ -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
− src/lib/Rattletrap/Decode/RemoteId.hs
@@ -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)
− src/lib/Rattletrap/Decode/Replay.hs
@@ -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 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
− src/lib/Rattletrap/Decode/Replication.hs
@@ -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
− src/lib/Rattletrap/Decode/ReplicationValue.hs
@@ -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
− src/lib/Rattletrap/Decode/ReservationAttribute.hs
@@ -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)
− src/lib/Rattletrap/Decode/RigidBodyStateAttribute.hs
@@ -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)
− src/lib/Rattletrap/Decode/Rotation.hs
@@ -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
− src/lib/Rattletrap/Decode/Section.hs
@@ -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- ]
− src/lib/Rattletrap/Decode/SpawnedReplication.hs
@@ -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
− src/lib/Rattletrap/Decode/StatEventAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Str.hs
@@ -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')
− src/lib/Rattletrap/Decode/StringAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/TeamPaintAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/TitleAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/UniqueIdAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/UpdatedReplication.hs
@@ -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
− src/lib/Rattletrap/Decode/Vector.hs
@@ -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
− src/lib/Rattletrap/Decode/WeldedInfoAttribute.hs
@@ -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
− src/lib/Rattletrap/Decode/Word32le.hs
@@ -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
− src/lib/Rattletrap/Decode/Word64le.hs
@@ -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
− src/lib/Rattletrap/Decode/Word8le.hs
@@ -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
− src/lib/Rattletrap/Encode/AppliedDamageAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Attribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/AttributeMapping.hs
@@ -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)
− src/lib/Rattletrap/Encode/AttributeValue.hs
@@ -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
− src/lib/Rattletrap/Encode/BooleanAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/ByteAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Cache.hs
@@ -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)
− src/lib/Rattletrap/Encode/CamSettingsAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/ClassMapping.hs
@@ -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)
− src/lib/Rattletrap/Encode/ClubColorsAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Common.hs
@@ -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]
− src/lib/Rattletrap/Encode/CompressedWord.hs
@@ -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
− src/lib/Rattletrap/Encode/CompressedWordVector.hs
@@ -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)
− src/lib/Rattletrap/Encode/Content.hs
@@ -1,58 +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 as Bytes-import qualified Data.ByteString.Lazy as LazyBytes--putContent :: Content -> Binary.Put-putContent content = do- putList putText (contentLevels content)- putList putKeyFrame (contentKeyFrames content)- let- stream = LazyBytes.toStrict- (Binary.runPut (BinaryBits.runBitPut (putFrames (contentFrames content)))- )- -- This is a little strange. When parsing a binary replay, the stream size- -- is given before the stream itself. When generating the JSON, the stream- -- size is included. That allows a bit-for-bit identical binary replay to- -- be generated from the JSON. However if you modify the JSON before- -- converting it back into binary, the stream size might be different.- --- -- If it was possible to know how much padding the stream required without- -- carrying it along as extra data on the side, this logic could go away.- -- Unforunately that isn't currently known. See this issue for details:- -- <https://github.com/tfausak/rattletrap/issues/171>.- expectedStreamSize = contentStreamSize content- actualStreamSize = Word32le . fromIntegral $ Bytes.length stream- streamSize = Word32le $ max- (word32leValue expectedStreamSize)- (word32leValue actualStreamSize)- putWord32 streamSize- 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)
− src/lib/Rattletrap/Encode/CustomDemolishAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/DamageStateAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/DemolishAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/DestroyedReplication.hs
@@ -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 ()
− src/lib/Rattletrap/Encode/Dictionary.hs
@@ -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
− src/lib/Rattletrap/Encode/EnumAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/ExplosionAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/ExtendedExplosionAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/FlaggedByteAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/FlaggedIntAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Float32le.hs
@@ -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)
− src/lib/Rattletrap/Encode/FloatAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Frame.hs
@@ -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)
− src/lib/Rattletrap/Encode/GameModeAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/Header.hs
@@ -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)
− src/lib/Rattletrap/Encode/Initialization.hs
@@ -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
− src/lib/Rattletrap/Encode/Int32le.hs
@@ -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)
− src/lib/Rattletrap/Encode/Int64Attribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Int64le.hs
@@ -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)
− src/lib/Rattletrap/Encode/Int8Vector.hs
@@ -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
− src/lib/Rattletrap/Encode/Int8le.hs
@@ -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)
− src/lib/Rattletrap/Encode/IntAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/KeyFrame.hs
@@ -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)
− src/lib/Rattletrap/Encode/List.hs
@@ -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
− src/lib/Rattletrap/Encode/LoadoutAttribute.hs
@@ -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 ()
− src/lib/Rattletrap/Encode/LoadoutOnlineAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/LoadoutsAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/LoadoutsOnlineAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/LocationAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Mark.hs
@@ -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)
− src/lib/Rattletrap/Encode/Message.hs
@@ -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)
− src/lib/Rattletrap/Encode/MusicStingerAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/PartyLeaderAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/PickupAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/PickupAttributeNew.hs
@@ -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)
− src/lib/Rattletrap/Encode/PlayerHistoryKeyAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/PrivateMatchSettingsAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/ProductAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/Property.hs
@@ -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)
− src/lib/Rattletrap/Encode/PropertyValue.hs
@@ -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
− src/lib/Rattletrap/Encode/QWordAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Quaternion.hs
@@ -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
− src/lib/Rattletrap/Encode/RemoteId.hs
@@ -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
− src/lib/Rattletrap/Encode/Replay.hs
@@ -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 :: FullReplay -> Binary.Put-putReplay replay = do- putSection putHeader (replayHeader replay)- putSection putContent (replayContent replay)
− src/lib/Rattletrap/Encode/Replication.hs
@@ -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)
− src/lib/Rattletrap/Encode/ReplicationValue.hs
@@ -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
− src/lib/Rattletrap/Encode/ReservationAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/RigidBodyStateAttribute.hs
@@ -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
− src/lib/Rattletrap/Encode/Rotation.hs
@@ -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
− src/lib/Rattletrap/Encode/Section.hs
@@ -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
− src/lib/Rattletrap/Encode/SpawnedReplication.hs
@@ -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)
− src/lib/Rattletrap/Encode/StatEventAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Str.hs
@@ -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'
− src/lib/Rattletrap/Encode/StringAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/TeamPaintAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/TitleAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/UniqueIdAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/UpdatedReplication.hs
@@ -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)
− src/lib/Rattletrap/Encode/Vector.hs
@@ -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)
− src/lib/Rattletrap/Encode/WeldedInfoAttribute.hs
@@ -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)
− src/lib/Rattletrap/Encode/Word32le.hs
@@ -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)
− src/lib/Rattletrap/Encode/Word64le.hs
@@ -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)
− src/lib/Rattletrap/Encode/Word8le.hs
@@ -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)
+ src/lib/Rattletrap/Get.hs view
@@ -0,0 +1,48 @@+module Rattletrap.Get where++import qualified Control.Applicative as Applicative++newtype Get s m a = Get (s -> m (Either String (s, a)))++instance Functor m => Functor (Get s m) where+ fmap f g = Get $ fmap (fmap (fmap f)) . run g++instance Monad m => Applicative (Get s m) where+ pure x = Get $ \s -> pure $ Right (s, x)++ gf <*> gx = Get $ \s1 -> do+ r <- run gf s1+ case r of+ Left e -> pure $ Left e+ Right (s2, f) -> run (fmap f gx) s2++instance Monad m => Monad (Get s m) where+ g >>= f = Get $ \s1 -> do+ r <- run g s1+ case r of+ Left e -> pure $ Left e+ Right (s2, x) -> run (f x) s2++instance Monad m => MonadFail (Get s m) where+ fail = Get . const . pure . Left++instance Monad m => Applicative.Alternative (Get s m) where+ empty = fail "empty"++ gx <|> gy = Get $ \s -> do+ r <- run gx s+ case r of+ Left _ -> run gy s+ Right x -> pure $ Right x++run :: Get s m a -> s -> m (Either String (s, a))+run (Get f) = f++get :: Applicative m => Get s m s+get = Get $ \s -> pure $ Right (s, s)++put :: Applicative m => s -> Get s m ()+put s = Get $ \_ -> pure $ Right (s, ())++lift :: Functor m => m a -> Get s m a+lift m = Get $ \s -> fmap (\x -> Right (s, x)) m
+ src/lib/Rattletrap/Schema.hs view
@@ -0,0 +1,61 @@+module Rattletrap.Schema where++import qualified Data.Text as Text+import qualified Rattletrap.Utility.Json as Json++data Schema = Schema+ { name :: Text.Text+ , json :: Json.Value+ }+ deriving (Eq, Show)++named :: String -> Json.Value -> Schema+named n j = Schema { name = Text.pack n, json = j }++ref :: Schema -> Json.Value+ref s = Json.object [Json.pair "$ref" $ Text.pack "#/definitions/" <> name s]++object :: [((Text.Text, Json.Value), Bool)] -> Json.Value+object xs = Json.object+ [ Json.pair "type" "object"+ , Json.pair "properties" . Json.object $ fmap fst xs+ , Json.pair "required" . fmap (fst . fst) $ filter snd xs+ ]++maybe :: Schema -> Schema+maybe s = Schema+ { name = Text.pack "maybe-" <> name s+ , json = oneOf [ref s, json Rattletrap.Schema.null]+ }++oneOf :: [Json.Value] -> Json.Value+oneOf xs = Json.object [Json.pair "oneOf" xs]++tuple :: [Json.Value] -> Json.Value+tuple xs = Json.object+ [ Json.pair "type" "array"+ , Json.pair "items" xs+ , Json.pair "minItems" $ length xs+ , Json.pair "maxItems" $ length xs+ ]++array :: Schema -> Schema+array s = Schema+ { name = Text.pack "array-" <> name s+ , json = Json.object [Json.pair "type" "array", Json.pair "items" $ ref s]+ }++boolean :: Schema+boolean = named "boolean" $ Json.object [Json.pair "type" "boolean"]++integer :: Schema+integer = named "integer" $ Json.object [Json.pair "type" "integer"]++null :: Schema+null = named "null" $ Json.object [Json.pair "type" "null"]++number :: Schema+number = named "number" $ Json.object [Json.pair "type" "number"]++string :: Schema+string = named "string" $ Json.object [Json.pair "type" "string"]
− src/lib/Rattletrap/Type/AppliedDamageAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Attribute.hs view
@@ -1,21 +1,95 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Attribute- ( Attribute(..)- )-where+module Rattletrap.Type.Attribute where -import Rattletrap.Type.AttributeValue-import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.Str+import qualified Data.Map as Map+import Prelude hiding (id)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.AttributeValue as AttributeValue+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json data Attribute = Attribute- { attributeId :: CompressedWord- , attributeName :: Str+ { id :: CompressedWord.CompressedWord+ , name :: Str.Str -- ^ Read-only! Changing an attribute's name requires editing the class -- attribute map.- , attributeValue :: AttributeValue- } deriving (Eq, Ord, Show)+ , value :: AttributeValue.AttributeValue+ }+ deriving (Eq, Show) -$(deriveJson ''Attribute)+instance Json.FromJSON Attribute where+ parseJSON = Json.withObject "Attribute" $ \object -> do+ id <- Json.required object "id"+ name <- Json.required object "name"+ value <- Json.required object "value"+ pure Attribute { id, name, value }++instance Json.ToJSON Attribute where+ toJSON x = Json.object+ [ Json.pair "id" $ id x+ , Json.pair "name" $ name x+ , Json.pair "value" $ value x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute" $ Schema.object+ [ (Json.pair "id" $ Schema.ref CompressedWord.schema, True)+ , (Json.pair "name" $ Schema.ref Str.schema, True)+ , (Json.pair "value" $ Schema.ref AttributeValue.schema, True)+ ]++bitPut :: Attribute -> BitPut.BitPut+bitPut attribute =+ CompressedWord.bitPut (Rattletrap.Type.Attribute.id attribute)+ <> AttributeValue.bitPut (value attribute)++bitGet+ :: Version.Version+ -> ClassAttributeMap.ClassAttributeMap+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> CompressedWord.CompressedWord+ -> BitGet.BitGet Attribute+bitGet version classes actors actor = do+ attributes <- lookupAttributeMap classes actors actor+ limit <- lookupAttributeIdLimit attributes actor+ attribute <- CompressedWord.bitGet limit+ name_ <- lookupAttributeName classes attributes attribute+ Attribute attribute name_+ <$> AttributeValue.bitGet+ version+ (ClassAttributeMap.objectMap classes)+ name_++lookupAttributeMap+ :: ClassAttributeMap.ClassAttributeMap+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> CompressedWord.CompressedWord+ -> BitGet.BitGet (Map.Map U32.U32 U32.U32)+lookupAttributeMap classes actors actor = fromMaybe+ ("[RT01] could not get attribute map for " <> show actor)+ (ClassAttributeMap.getAttributeMap classes actors actor)++lookupAttributeIdLimit+ :: Map.Map U32.U32 U32.U32+ -> CompressedWord.CompressedWord+ -> BitGet.BitGet Word+lookupAttributeIdLimit attributes actor = fromMaybe+ ("[RT02] could not get attribute ID limit for " <> show actor)+ (ClassAttributeMap.getAttributeIdLimit attributes)++lookupAttributeName+ :: ClassAttributeMap.ClassAttributeMap+ -> Map.Map U32.U32 U32.U32+ -> CompressedWord.CompressedWord+ -> BitGet.BitGet Str.Str+lookupAttributeName classes attributes attribute = fromMaybe+ ("[RT03] could not get attribute name for " <> show attribute)+ (ClassAttributeMap.getAttributeName classes attributes attribute)++fromMaybe :: String -> Maybe a -> BitGet.BitGet a+fromMaybe message = maybe (fail message) pure
+ src/lib/Rattletrap/Type/Attribute/AppliedDamage.hs view
@@ -0,0 +1,57 @@+module Rattletrap.Type.Attribute.AppliedDamage where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data AppliedDamage = AppliedDamage+ { unknown1 :: U8.U8+ , location :: Vector.Vector+ , unknown3 :: I32.I32+ , unknown4 :: I32.I32+ }+ deriving (Eq, Show)++instance Json.FromJSON AppliedDamage where+ parseJSON = Json.withObject "AppliedDamage" $ \object -> do+ unknown1 <- Json.required object "unknown1"+ location <- Json.required object "location"+ unknown3 <- Json.required object "unknown3"+ unknown4 <- Json.required object "unknown4"+ pure AppliedDamage { unknown1, location, unknown3, unknown4 }++instance Json.ToJSON AppliedDamage where+ toJSON x = Json.object+ [ Json.pair "unknown1" $ unknown1 x+ , Json.pair "location" $ location x+ , Json.pair "unknown3" $ unknown3 x+ , Json.pair "unknown4" $ unknown4 x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-applied-damage" $ Schema.object+ [ (Json.pair "unknown1" $ Schema.ref U8.schema, True)+ , (Json.pair "location" $ Schema.ref Vector.schema, True)+ , (Json.pair "unknown3" $ Schema.ref I32.schema, True)+ , (Json.pair "unknown4" $ Schema.ref I32.schema, True)+ ]++bitPut :: AppliedDamage -> BitPut.BitPut+bitPut appliedDamageAttribute =+ U8.bitPut (unknown1 appliedDamageAttribute)+ <> Vector.bitPut (location appliedDamageAttribute)+ <> I32.bitPut (unknown3 appliedDamageAttribute)+ <> I32.bitPut (unknown4 appliedDamageAttribute)++bitGet :: Version.Version -> BitGet.BitGet AppliedDamage+bitGet version =+ AppliedDamage+ <$> U8.bitGet+ <*> Vector.bitGet version+ <*> I32.bitGet+ <*> I32.bitGet
+ src/lib/Rattletrap/Type/Attribute/Boolean.hs view
@@ -0,0 +1,25 @@+module Rattletrap.Type.Attribute.Boolean where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype Boolean = Boolean+ { value :: Bool+ } deriving (Eq, Show)++instance Json.FromJSON Boolean where+ parseJSON = fmap Boolean . Json.parseJSON++instance Json.ToJSON Boolean where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-boolean" $ Schema.ref Schema.boolean++bitPut :: Boolean -> BitPut.BitPut+bitPut booleanAttribute = BitPut.bool (value booleanAttribute)++bitGet :: BitGet.BitGet Boolean+bitGet = Boolean <$> BitGet.bool
+ src/lib/Rattletrap/Type/Attribute/Byte.hs view
@@ -0,0 +1,26 @@+module Rattletrap.Type.Attribute.Byte where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json++newtype Byte = Byte+ { value :: U8.U8+ } deriving (Eq, Show)++instance Json.FromJSON Byte where+ parseJSON = fmap Byte . Json.parseJSON++instance Json.ToJSON Byte where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-byte" $ Schema.ref U8.schema++bitPut :: Byte -> BitPut.BitPut+bitPut byteAttribute = U8.bitPut (value byteAttribute)++bitGet :: BitGet.BitGet Byte+bitGet = Byte <$> U8.bitGet
+ src/lib/Rattletrap/Type/Attribute/CamSettings.hs view
@@ -0,0 +1,88 @@+module Rattletrap.Type.Attribute.CamSettings where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data CamSettings = CamSettings+ { fov :: F32.F32+ , height :: F32.F32+ , angle :: F32.F32+ , distance :: F32.F32+ , stiffness :: F32.F32+ , swivelSpeed :: F32.F32+ , transitionSpeed :: Maybe F32.F32+ }+ deriving (Eq, Show)++instance Json.FromJSON CamSettings where+ parseJSON = Json.withObject "CamSettings" $ \object -> do+ fov <- Json.required object "fov"+ height <- Json.required object "height"+ angle <- Json.required object "angle"+ distance <- Json.required object "distance"+ stiffness <- Json.required object "stiffness"+ swivelSpeed <- Json.required object "swivel_speed"+ transitionSpeed <- Json.optional object "transition_speed"+ pure CamSettings+ { fov+ , height+ , angle+ , distance+ , stiffness+ , swivelSpeed+ , transitionSpeed+ }++instance Json.ToJSON CamSettings where+ toJSON x = Json.object+ [ Json.pair "fov" $ fov x+ , Json.pair "height" $ height x+ , Json.pair "angle" $ angle x+ , Json.pair "distance" $ distance x+ , Json.pair "stiffness" $ stiffness x+ , Json.pair "swivel_speed" $ swivelSpeed x+ , Json.pair "transition_speed" $ transitionSpeed x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-cam-settings" $ Schema.object+ [ (Json.pair "fov" $ Schema.ref F32.schema, True)+ , (Json.pair "height" $ Schema.ref F32.schema, True)+ , (Json.pair "angle" $ Schema.ref F32.schema, True)+ , (Json.pair "distance" $ Schema.ref F32.schema, True)+ , (Json.pair "stiffness" $ Schema.ref F32.schema, True)+ , (Json.pair "swivel_speed" $ Schema.ref F32.schema, True)+ , ( Json.pair "transition_speed" . Schema.json $ Schema.maybe F32.schema+ , False+ )+ ]++bitPut :: CamSettings -> BitPut.BitPut+bitPut camSettingsAttribute =+ F32.bitPut (fov camSettingsAttribute)+ <> F32.bitPut (height camSettingsAttribute)+ <> F32.bitPut (angle camSettingsAttribute)+ <> F32.bitPut (distance camSettingsAttribute)+ <> F32.bitPut (stiffness camSettingsAttribute)+ <> F32.bitPut (swivelSpeed camSettingsAttribute)+ <> foldMap F32.bitPut (transitionSpeed camSettingsAttribute)++bitGet :: Version.Version -> BitGet.BitGet CamSettings+bitGet version =+ CamSettings+ <$> F32.bitGet+ <*> F32.bitGet+ <*> F32.bitGet+ <*> F32.bitGet+ <*> F32.bitGet+ <*> F32.bitGet+ <*> whenMaybe (hasTransitionSpeed version) F32.bitGet++hasTransitionSpeed :: Version.Version -> Bool+hasTransitionSpeed v =+ Version.major v >= 868 && Version.minor v >= 20 && Version.patch v >= 0
+ src/lib/Rattletrap/Type/Attribute/ClubColors.hs view
@@ -0,0 +1,50 @@+module Rattletrap.Type.Attribute.ClubColors where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json++data ClubColors = ClubColors+ { blueFlag :: Bool+ , blueColor :: U8.U8+ , orangeFlag :: Bool+ , orangeColor :: U8.U8+ }+ deriving (Eq, Show)++instance Json.FromJSON ClubColors where+ parseJSON = Json.withObject "ClubColors" $ \object -> do+ blueFlag <- Json.required object "blue_flag"+ blueColor <- Json.required object "blue_color"+ orangeFlag <- Json.required object "orange_flag"+ orangeColor <- Json.required object "orange_color"+ pure ClubColors { blueFlag, blueColor, orangeFlag, orangeColor }++instance Json.ToJSON ClubColors where+ toJSON x = Json.object+ [ Json.pair "blue_flag" $ blueFlag x+ , Json.pair "blue_color" $ blueColor x+ , Json.pair "orange_flag" $ orangeFlag x+ , Json.pair "orange_color" $ orangeColor x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-club-colors" $ Schema.object+ [ (Json.pair "blue_flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "blue_color" $ Schema.ref U8.schema, True)+ , (Json.pair "orange_flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "orange_color" $ Schema.ref U8.schema, True)+ ]++bitPut :: ClubColors -> BitPut.BitPut+bitPut clubColorsAttribute =+ BitPut.bool (blueFlag clubColorsAttribute)+ <> U8.bitPut (blueColor clubColorsAttribute)+ <> BitPut.bool (orangeFlag clubColorsAttribute)+ <> U8.bitPut (orangeColor clubColorsAttribute)++bitGet :: BitGet.BitGet ClubColors+bitGet =+ ClubColors <$> BitGet.bool <*> U8.bitGet <*> BitGet.bool <*> U8.bitGet
+ src/lib/Rattletrap/Type/Attribute/CustomDemolish.hs view
@@ -0,0 +1,48 @@+module Rattletrap.Type.Attribute.CustomDemolish where++import Prelude hiding (id)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.Demolish as Demolish+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data CustomDemolish = CustomDemolish+ { flag :: Bool+ , id :: I32.I32+ , demolish :: Demolish.Demolish+ }+ deriving (Eq, Show)++instance Json.FromJSON CustomDemolish where+ parseJSON = Json.withObject "CustomDemolish" $ \object -> do+ flag <- Json.required object "flag"+ id <- Json.required object "id"+ demolish <- Json.required object "demolish"+ pure CustomDemolish { flag, id, demolish }++instance Json.ToJSON CustomDemolish where+ toJSON x = Json.object+ [ Json.pair "flag" $ flag x+ , Json.pair "id" $ id x+ , Json.pair "demolish" $ demolish x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-custom-demolish" $ Schema.object+ [ (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "id" $ Schema.ref I32.schema, True)+ , (Json.pair "demolish" $ Schema.ref Demolish.schema, True)+ ]++bitPut :: CustomDemolish -> BitPut.BitPut+bitPut x =+ BitPut.bool (flag x)+ <> I32.bitPut (Rattletrap.Type.Attribute.CustomDemolish.id x)+ <> Demolish.bitPut (demolish x)++bitGet :: Version.Version -> BitGet.BitGet CustomDemolish+bitGet version =+ CustomDemolish <$> BitGet.bool <*> I32.bitGet <*> Demolish.bitGet version
+ src/lib/Rattletrap/Type/Attribute/DamageState.hs view
@@ -0,0 +1,76 @@+module Rattletrap.Type.Attribute.DamageState where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data DamageState = DamageState+ { unknown1 :: U8.U8+ , unknown2 :: Bool+ , unknown3 :: I32.I32+ , unknown4 :: Vector.Vector+ , unknown5 :: Bool+ , unknown6 :: Bool+ }+ deriving (Eq, Show)++instance Json.FromJSON DamageState where+ parseJSON = Json.withObject "DamageState" $ \object -> do+ unknown1 <- Json.required object "unknown1"+ unknown2 <- Json.required object "unknown2"+ unknown3 <- Json.required object "unknown3"+ unknown4 <- Json.required object "unknown4"+ unknown5 <- Json.required object "unknown5"+ unknown6 <- Json.required object "unknown6"+ pure DamageState+ { unknown1+ , unknown2+ , unknown3+ , unknown4+ , unknown5+ , unknown6+ }++instance Json.ToJSON DamageState where+ toJSON x = Json.object+ [ Json.pair "unknown1" $ unknown1 x+ , Json.pair "unknown2" $ unknown2 x+ , Json.pair "unknown3" $ unknown3 x+ , Json.pair "unknown4" $ unknown4 x+ , Json.pair "unknown5" $ unknown5 x+ , Json.pair "unknown6" $ unknown6 x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-damage-state" $ Schema.object+ [ (Json.pair "unknown1" $ Schema.ref U8.schema, True)+ , (Json.pair "unknown2" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown3" $ Schema.ref I32.schema, True)+ , (Json.pair "unknown4" $ Schema.ref Vector.schema, True)+ , (Json.pair "unknown5" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown6" $ Schema.ref Schema.boolean, True)+ ]++bitPut :: DamageState -> BitPut.BitPut+bitPut damageStateAttribute =+ U8.bitPut (unknown1 damageStateAttribute)+ <> BitPut.bool (unknown2 damageStateAttribute)+ <> I32.bitPut (unknown3 damageStateAttribute)+ <> Vector.bitPut (unknown4 damageStateAttribute)+ <> BitPut.bool (unknown5 damageStateAttribute)+ <> BitPut.bool (unknown6 damageStateAttribute)++bitGet :: Version.Version -> BitGet.BitGet DamageState+bitGet version =+ DamageState+ <$> U8.bitGet+ <*> BitGet.bool+ <*> I32.bitGet+ <*> Vector.bitGet version+ <*> BitGet.bool+ <*> BitGet.bool
+ src/lib/Rattletrap/Type/Attribute/Demolish.hs view
@@ -0,0 +1,75 @@+module Rattletrap.Type.Attribute.Demolish where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data Demolish = Demolish+ { attackerFlag :: Bool+ , attackerActorId :: U32.U32+ , victimFlag :: Bool+ , victimActorId :: U32.U32+ , attackerVelocity :: Vector.Vector+ , victimVelocity :: Vector.Vector+ }+ deriving (Eq, Show)++instance Json.FromJSON Demolish where+ parseJSON = Json.withObject "Demolish" $ \object -> do+ attackerFlag <- Json.required object "attacker_flag"+ attackerActorId <- Json.required object "attacker_actor_id"+ victimFlag <- Json.required object "victim_flag"+ victimActorId <- Json.required object "victim_actor_id"+ attackerVelocity <- Json.required object "attacker_velocity"+ victimVelocity <- Json.required object "victim_velocity"+ pure Demolish+ { attackerFlag+ , attackerActorId+ , victimFlag+ , victimActorId+ , attackerVelocity+ , victimVelocity+ }++instance Json.ToJSON Demolish where+ toJSON x = Json.object+ [ Json.pair "attacker_flag" $ attackerFlag x+ , Json.pair "attacker_actor_id" $ attackerActorId x+ , Json.pair "victim_flag" $ victimFlag x+ , Json.pair "victim_actor_id" $ victimActorId x+ , Json.pair "attacker_velocity" $ attackerVelocity x+ , Json.pair "victim_velocity" $ victimVelocity x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-demolish" $ Schema.object+ [ (Json.pair "attacker_flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "attacker_actor_id" $ Schema.ref U32.schema, True)+ , (Json.pair "victim_flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "victim_actor_id" $ Schema.ref U32.schema, True)+ , (Json.pair "attacker_velocity" $ Schema.ref Vector.schema, True)+ , (Json.pair "victim_velocity" $ Schema.ref Vector.schema, True)+ ]++bitPut :: Demolish -> BitPut.BitPut+bitPut demolishAttribute =+ BitPut.bool (attackerFlag demolishAttribute)+ <> U32.bitPut (attackerActorId demolishAttribute)+ <> BitPut.bool (victimFlag demolishAttribute)+ <> U32.bitPut (victimActorId demolishAttribute)+ <> Vector.bitPut (attackerVelocity demolishAttribute)+ <> Vector.bitPut (victimVelocity demolishAttribute)++bitGet :: Version.Version -> BitGet.BitGet Demolish+bitGet version =+ Demolish+ <$> BitGet.bool+ <*> U32.bitGet+ <*> BitGet.bool+ <*> U32.bitGet+ <*> Vector.bitGet version+ <*> Vector.bitGet version
+ src/lib/Rattletrap/Type/Attribute/Enum.hs view
@@ -0,0 +1,27 @@+module Rattletrap.Type.Attribute.Enum where++import qualified Data.Word as Word+import Prelude hiding (Enum)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype Enum = Enum+ { value :: Word.Word16+ } deriving (Eq, Show)++instance Json.FromJSON Enum where+ parseJSON = fmap Enum . Json.parseJSON++instance Json.ToJSON Enum where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-enum" $ Schema.ref Schema.integer++bitPut :: Enum -> BitPut.BitPut+bitPut enumAttribute = BitPut.bits 11 (value enumAttribute)++bitGet :: BitGet.BitGet Enum+bitGet = Enum <$> BitGet.bits 11
+ src/lib/Rattletrap/Type/Attribute/Explosion.hs view
@@ -0,0 +1,47 @@+module Rattletrap.Type.Attribute.Explosion where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data Explosion = Explosion+ { flag :: Bool+ , actorId :: I32.I32+ , location :: Vector.Vector+ }+ deriving (Eq, Show)++instance Json.FromJSON Explosion where+ parseJSON = Json.withObject "Explosion" $ \object -> do+ flag <- Json.required object "flag"+ actorId <- Json.required object "actor_id"+ location <- Json.required object "location"+ pure Explosion { flag, actorId, location }++instance Json.ToJSON Explosion where+ toJSON x = Json.object+ [ Json.pair "flag" $ flag x+ , Json.pair "actor_id" $ actorId x+ , Json.pair "location" $ location x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-explosion" $ Schema.object+ [ (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "actor_id" $ Schema.ref I32.schema, True)+ , (Json.pair "location" $ Schema.ref Vector.schema, True)+ ]++bitPut :: Explosion -> BitPut.BitPut+bitPut explosionAttribute =+ BitPut.bool (flag explosionAttribute)+ <> I32.bitPut (actorId explosionAttribute)+ <> Vector.bitPut (location explosionAttribute)++bitGet :: Version.Version -> BitGet.BitGet Explosion+bitGet version =+ Explosion <$> BitGet.bool <*> I32.bitGet <*> Vector.bitGet version
+ src/lib/Rattletrap/Type/Attribute/ExtendedExplosion.hs view
@@ -0,0 +1,38 @@+module Rattletrap.Type.Attribute.ExtendedExplosion where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.Explosion as Explosion+import qualified Rattletrap.Type.Attribute.FlaggedInt as FlaggedInt+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data ExtendedExplosion = ExtendedExplosion+ { explosion :: Explosion.Explosion+ , unknown :: FlaggedInt.FlaggedInt+ }+ deriving (Eq, Show)++instance Json.FromJSON ExtendedExplosion where+ parseJSON = Json.withObject "ExtendedExplosion" $ \object -> do+ explosion <- Json.required object "explosion"+ unknown <- Json.required object "unknown"+ pure ExtendedExplosion { explosion, unknown }++instance Json.ToJSON ExtendedExplosion where+ toJSON x = Json.object+ [Json.pair "explosion" $ explosion x, Json.pair "unknown" $ unknown x]++schema :: Schema.Schema+schema = Schema.named "attribute-extended-explosion" $ Schema.object+ [ (Json.pair "explosion" $ Schema.ref Explosion.schema, True)+ , (Json.pair "unknown" $ Schema.ref FlaggedInt.schema, True)+ ]++bitPut :: ExtendedExplosion -> BitPut.BitPut+bitPut x = Explosion.bitPut (explosion x) <> FlaggedInt.bitPut (unknown x)++bitGet :: Version.Version -> BitGet.BitGet ExtendedExplosion+bitGet version =+ ExtendedExplosion <$> Explosion.bitGet version <*> FlaggedInt.bitGet
+ src/lib/Rattletrap/Type/Attribute/FlaggedByte.hs view
@@ -0,0 +1,36 @@+module Rattletrap.Type.Attribute.FlaggedByte where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json++data FlaggedByte = FlaggedByte+ { flag :: Bool+ , byte :: U8.U8+ }+ deriving (Eq, Show)++instance Json.FromJSON FlaggedByte where+ parseJSON = Json.withObject "FlaggedByte" $ \object -> do+ flag <- Json.required object "flag"+ byte <- Json.required object "byte"+ pure FlaggedByte { flag, byte }++instance Json.ToJSON FlaggedByte where+ toJSON x =+ Json.object [Json.pair "flag" $ flag x, Json.pair "byte" $ byte x]++schema :: Schema.Schema+schema = Schema.named "attribute-flagged-byte" $ Schema.object+ [ (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "byte" $ Schema.ref U8.schema, True)+ ]++bitPut :: FlaggedByte -> BitPut.BitPut+bitPut flaggedByteAttribute = BitPut.bool (flag flaggedByteAttribute)+ <> U8.bitPut (byte flaggedByteAttribute)++bitGet :: BitGet.BitGet FlaggedByte+bitGet = FlaggedByte <$> BitGet.bool <*> U8.bitGet
+ src/lib/Rattletrap/Type/Attribute/FlaggedInt.hs view
@@ -0,0 +1,35 @@+module Rattletrap.Type.Attribute.FlaggedInt where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Utility.Json as Json++data FlaggedInt = FlaggedInt+ { flag :: Bool+ , int :: I32.I32+ }+ deriving (Eq, Show)++instance Json.FromJSON FlaggedInt where+ parseJSON = Json.withObject "FlaggedInt" $ \object -> do+ flag <- Json.required object "flag"+ int <- Json.required object "int"+ pure FlaggedInt { flag, int }++instance Json.ToJSON FlaggedInt where+ toJSON x = Json.object [Json.pair "flag" $ flag x, Json.pair "int" $ int x]++schema :: Schema.Schema+schema = Schema.named "attribute-flagged-int" $ Schema.object+ [ (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "int" $ Schema.ref I32.schema, True)+ ]++bitPut :: FlaggedInt -> BitPut.BitPut+bitPut flaggedIntAttribute = BitPut.bool (flag flaggedIntAttribute)+ <> I32.bitPut (int flaggedIntAttribute)++bitGet :: BitGet.BitGet FlaggedInt+bitGet = FlaggedInt <$> BitGet.bool <*> I32.bitGet
+ src/lib/Rattletrap/Type/Attribute/Float.hs view
@@ -0,0 +1,27 @@+module Rattletrap.Type.Attribute.Float where++import Prelude hiding (Float)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Utility.Json as Json++newtype Float = Float+ { value :: F32.F32+ } deriving (Eq, Show)++instance Json.FromJSON Float where+ parseJSON = fmap Float . Json.parseJSON++instance Json.ToJSON Float where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-float" $ Schema.ref F32.schema++bitPut :: Float -> BitPut.BitPut+bitPut floatAttribute = F32.bitPut (value floatAttribute)++bitGet :: BitGet.BitGet Float+bitGet = Float <$> F32.bitGet
+ src/lib/Rattletrap/Type/Attribute/GameMode.hs view
@@ -0,0 +1,49 @@+module Rattletrap.Type.Attribute.GameMode where++import qualified Data.Word as Word+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data GameMode = GameMode+ { numBits :: 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.+ , word :: Word.Word8+ }+ deriving (Eq, Show)++instance Json.FromJSON GameMode where+ parseJSON = Json.withObject "GameMode" $ \object -> do+ numBits <- Json.required object "num_bits"+ word <- Json.required object "word"+ pure GameMode { numBits, word }++instance Json.ToJSON GameMode where+ toJSON x =+ Json.object [Json.pair "num_bits" $ numBits x, Json.pair "word" $ word x]++schema :: Schema.Schema+schema = Schema.named "attribute-game-mode" $ Schema.object+ [ (Json.pair "num_bits" $ Schema.ref Schema.integer, True)+ , (Json.pair "word" $ Schema.ref Schema.integer, True)+ ]++bitPut :: GameMode -> BitPut.BitPut+bitPut gameModeAttribute = do+ BitPut.word8 (numBits gameModeAttribute) (word gameModeAttribute)++bitGet :: Version.Version -> BitGet.BitGet GameMode+bitGet version =+ GameMode (numBits_ version) <$> BitGet.word8 (numBits_ version)++numBits_ :: Version.Version -> Int+numBits_ version = if has8Bits version then 8 else 2++has8Bits :: Version.Version -> Bool+has8Bits v =+ Version.major v >= 868 && Version.minor v >= 12 && Version.patch v >= 0
+ src/lib/Rattletrap/Type/Attribute/Int.hs view
@@ -0,0 +1,27 @@+module Rattletrap.Type.Attribute.Int where++import Prelude hiding (Int)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Utility.Json as Json++newtype Int = Int+ { value :: I32.I32+ } deriving (Eq, Show)++instance Json.FromJSON Int where+ parseJSON = fmap Int . Json.parseJSON++instance Json.ToJSON Int where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-int" $ Schema.ref I32.schema++bitPut :: Int -> BitPut.BitPut+bitPut intAttribute = I32.bitPut (value intAttribute)++bitGet :: BitGet.BitGet Int+bitGet = Int <$> I32.bitGet
+ src/lib/Rattletrap/Type/Attribute/Int64.hs view
@@ -0,0 +1,26 @@+module Rattletrap.Type.Attribute.Int64 where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I64 as I64+import qualified Rattletrap.Utility.Json as Json++newtype Int64 = Int64+ { value :: I64.I64+ } deriving (Eq, Show)++instance Json.FromJSON Int64 where+ parseJSON = fmap Int64 . Json.parseJSON++instance Json.ToJSON Int64 where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-int64" $ Schema.ref I64.schema++putInt64Attribute :: Int64 -> BitPut.BitPut+putInt64Attribute int64Attribute = I64.bitPut (value int64Attribute)++bitGet :: BitGet.BitGet Int64+bitGet = Int64 <$> I64.bitGet
+ src/lib/Rattletrap/Type/Attribute/Loadout.hs view
@@ -0,0 +1,153 @@+module Rattletrap.Type.Attribute.Loadout where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data Loadout = Loadout+ { version :: U8.U8+ , body :: U32.U32+ , decal :: U32.U32+ , wheels :: U32.U32+ , rocketTrail :: U32.U32+ -- ^ Now known as "rocket boost".+ , antenna :: U32.U32+ , topper :: U32.U32+ , unknown1 :: U32.U32+ , unknown2 :: Maybe U32.U32+ , engineAudio :: Maybe U32.U32+ , trail :: Maybe U32.U32+ , goalExplosion :: Maybe U32.U32+ , banner :: Maybe U32.U32+ , unknown3 :: Maybe U32.U32+ , unknown4 :: Maybe U32.U32+ , unknown5 :: Maybe U32.U32+ , unknown6 :: Maybe U32.U32+ }+ deriving (Eq, Show)++instance Json.FromJSON Loadout where+ parseJSON = Json.withObject "Loadout" $ \object -> do+ version <- Json.required object "version"+ body <- Json.required object "body"+ decal <- Json.required object "decal"+ wheels <- Json.required object "wheels"+ rocketTrail <- Json.required object "rocket_trail"+ antenna <- Json.required object "antenna"+ topper <- Json.required object "topper"+ unknown1 <- Json.required object "unknown1"+ unknown2 <- Json.optional object "unknown2"+ engineAudio <- Json.optional object "engine_audio"+ trail <- Json.optional object "trail"+ goalExplosion <- Json.optional object "goal_explosion"+ banner <- Json.optional object "banner"+ unknown3 <- Json.optional object "unknown3"+ unknown4 <- Json.optional object "unknown4"+ unknown5 <- Json.optional object "unknown5"+ unknown6 <- Json.optional object "unknown6"+ pure Loadout+ { version+ , body+ , decal+ , wheels+ , rocketTrail+ , antenna+ , topper+ , unknown1+ , unknown2+ , engineAudio+ , trail+ , goalExplosion+ , banner+ , unknown3+ , unknown4+ , unknown5+ , unknown6+ }++instance Json.ToJSON Loadout where+ toJSON x = Json.object+ [ Json.pair "version" $ version x+ , Json.pair "body" $ body x+ , Json.pair "decal" $ decal x+ , Json.pair "wheels" $ wheels x+ , Json.pair "rocket_trail" $ rocketTrail x+ , Json.pair "antenna" $ antenna x+ , Json.pair "topper" $ topper x+ , Json.pair "unknown1" $ unknown1 x+ , Json.pair "unknown2" $ unknown2 x+ , Json.pair "engine_audio" $ engineAudio x+ , Json.pair "trail" $ trail x+ , Json.pair "goal_explosion" $ goalExplosion x+ , Json.pair "banner" $ banner x+ , Json.pair "unknown3" $ unknown3 x+ , Json.pair "unknown4" $ unknown4 x+ , Json.pair "unknown5" $ unknown5 x+ , Json.pair "unknown6" $ unknown6 x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-loadout" $ Schema.object+ [ (Json.pair "version" $ Schema.ref U8.schema, True)+ , (Json.pair "body" $ Schema.ref U32.schema, True)+ , (Json.pair "decal" $ Schema.ref U32.schema, True)+ , (Json.pair "wheels" $ Schema.ref U32.schema, True)+ , (Json.pair "rocket_trail" $ Schema.ref U32.schema, True)+ , (Json.pair "antenna" $ Schema.ref U32.schema, True)+ , (Json.pair "topper" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown1" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown2" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "engine_audio" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "trail" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "goal_explosion" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "banner" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "unknown3" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "unknown4" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "unknown5" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "unknown6" . Schema.json $ Schema.maybe U32.schema, False)+ ]++bitPut :: Loadout -> BitPut.BitPut+bitPut loadoutAttribute =+ U8.bitPut (version loadoutAttribute)+ <> U32.bitPut (body loadoutAttribute)+ <> U32.bitPut (decal loadoutAttribute)+ <> U32.bitPut (wheels loadoutAttribute)+ <> U32.bitPut (rocketTrail loadoutAttribute)+ <> U32.bitPut (antenna loadoutAttribute)+ <> U32.bitPut (topper loadoutAttribute)+ <> U32.bitPut (unknown1 loadoutAttribute)+ <> foldMap U32.bitPut (unknown2 loadoutAttribute)+ <> foldMap U32.bitPut (engineAudio loadoutAttribute)+ <> foldMap U32.bitPut (trail loadoutAttribute)+ <> foldMap U32.bitPut (goalExplosion loadoutAttribute)+ <> foldMap U32.bitPut (banner loadoutAttribute)+ <> foldMap U32.bitPut (unknown3 loadoutAttribute)+ <> foldMap U32.bitPut (unknown4 loadoutAttribute)+ <> foldMap U32.bitPut (unknown5 loadoutAttribute)+ <> foldMap U32.bitPut (unknown6 loadoutAttribute)++bitGet :: BitGet.BitGet Loadout+bitGet = do+ version_ <- U8.bitGet+ Loadout version_+ <$> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 11) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 16) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 16) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 16) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 17) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 19) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 22) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 22) U32.bitGet+ <*> whenMaybe (U8.toWord8 version_ >= 22) U32.bitGet
+ src/lib/Rattletrap/Type/Attribute/LoadoutOnline.hs view
@@ -0,0 +1,46 @@+module Rattletrap.Type.Attribute.LoadoutOnline where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.Product as Product+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++import qualified Data.Map as Map++newtype LoadoutOnline = LoadoutOnline+ { value :: List.List (List.List Product.Product)+ } deriving (Eq, Show)++instance Json.FromJSON LoadoutOnline where+ parseJSON = fmap LoadoutOnline . Json.parseJSON++instance Json.ToJSON LoadoutOnline where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema =+ Schema.named "attribute-loadout-online"+ . Schema.json+ . List.schema+ $ List.schema Product.schema++bitPut :: LoadoutOnline -> BitPut.BitPut+bitPut loadoutAttribute =+ let attributes = List.toList $ value loadoutAttribute+ in+ (U8.bitPut . U8.fromWord8 . fromIntegral $ length attributes)+ <> foldMap Product.putProductAttributes attributes++bitGet+ :: Version.Version -> Map.Map U32.U32 Str.Str -> BitGet.BitGet LoadoutOnline+bitGet version objectMap = do+ size <- U8.bitGet+ LoadoutOnline <$> List.replicateM+ (fromIntegral (U8.toWord8 size))+ (Product.decodeProductAttributesBits version objectMap)
+ src/lib/Rattletrap/Type/Attribute/Loadouts.hs view
@@ -0,0 +1,36 @@+module Rattletrap.Type.Attribute.Loadouts where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.Loadout as Loadout+import qualified Rattletrap.Utility.Json as Json++data Loadouts = Loadouts+ { blue :: Loadout.Loadout+ , orange :: Loadout.Loadout+ }+ deriving (Eq, Show)++instance Json.FromJSON Loadouts where+ parseJSON = Json.withObject "Loadouts" $ \object -> do+ blue <- Json.required object "blue"+ orange <- Json.required object "orange"+ pure Loadouts { blue, orange }++instance Json.ToJSON Loadouts where+ toJSON x =+ Json.object [Json.pair "blue" $ blue x, Json.pair "orange" $ orange x]++schema :: Schema.Schema+schema = Schema.named "attribute-loadouts" $ Schema.object+ [ (Json.pair "blue" $ Schema.ref Loadout.schema, True)+ , (Json.pair "orange" $ Schema.ref Loadout.schema, True)+ ]++bitPut :: Loadouts -> BitPut.BitPut+bitPut loadoutsAttribute = Loadout.bitPut (blue loadoutsAttribute)+ <> Loadout.bitPut (orange loadoutsAttribute)++bitGet :: BitGet.BitGet Loadouts+bitGet = Loadouts <$> Loadout.bitGet <*> Loadout.bitGet
+ src/lib/Rattletrap/Type/Attribute/LoadoutsOnline.hs view
@@ -0,0 +1,60 @@+module Rattletrap.Type.Attribute.LoadoutsOnline where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.LoadoutOnline as LoadoutOnline+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++import qualified Data.Map as Map++data LoadoutsOnline = LoadoutsOnline+ { blue :: LoadoutOnline.LoadoutOnline+ , orange :: LoadoutOnline.LoadoutOnline+ , unknown1 :: Bool+ , unknown2 :: Bool+ }+ deriving (Eq, Show)++instance Json.FromJSON LoadoutsOnline where+ parseJSON = Json.withObject "LoadoutsOnline" $ \object -> do+ blue <- Json.required object "blue"+ orange <- Json.required object "orange"+ unknown1 <- Json.required object "unknown1"+ unknown2 <- Json.required object "unknown2"+ pure LoadoutsOnline { blue, orange, unknown1, unknown2 }++instance Json.ToJSON LoadoutsOnline where+ toJSON x = Json.object+ [ Json.pair "blue" $ blue x+ , Json.pair "orange" $ orange x+ , Json.pair "unknown1" $ unknown1 x+ , Json.pair "unknown2" $ unknown2 x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-loadouts-online" $ Schema.object+ [ (Json.pair "blue" $ Schema.ref LoadoutOnline.schema, True)+ , (Json.pair "orange" $ Schema.ref LoadoutOnline.schema, True)+ , (Json.pair "unknown1" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown2" $ Schema.ref Schema.boolean, True)+ ]++bitPut :: LoadoutsOnline -> BitPut.BitPut+bitPut loadoutsOnlineAttribute =+ LoadoutOnline.bitPut (blue loadoutsOnlineAttribute)+ <> LoadoutOnline.bitPut (orange loadoutsOnlineAttribute)+ <> BitPut.bool (unknown1 loadoutsOnlineAttribute)+ <> BitPut.bool (unknown2 loadoutsOnlineAttribute)++bitGet+ :: Version.Version -> Map.Map U32.U32 Str.Str -> BitGet.BitGet LoadoutsOnline+bitGet version objectMap =+ LoadoutsOnline+ <$> LoadoutOnline.bitGet version objectMap+ <*> LoadoutOnline.bitGet version objectMap+ <*> BitGet.bool+ <*> BitGet.bool
+ src/lib/Rattletrap/Type/Attribute/Location.hs view
@@ -0,0 +1,27 @@+module Rattletrap.Type.Attribute.Location where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++newtype Location = Location+ { value :: Vector.Vector+ } deriving (Eq, Show)++instance Json.FromJSON Location where+ parseJSON = fmap Location . Json.parseJSON++instance Json.ToJSON Location where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-location" $ Schema.ref Vector.schema++bitPut :: Location -> BitPut.BitPut+bitPut locationAttribute = Vector.bitPut (value locationAttribute)++bitGet :: Version.Version -> BitGet.BitGet Location+bitGet version = Location <$> Vector.bitGet version
+ src/lib/Rattletrap/Type/Attribute/MusicStinger.hs view
@@ -0,0 +1,45 @@+module Rattletrap.Type.Attribute.MusicStinger where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json++data MusicStinger = MusicStinger+ { flag :: Bool+ , cue :: U32.U32+ , trigger :: U8.U8+ }+ deriving (Eq, Show)++instance Json.FromJSON MusicStinger where+ parseJSON = Json.withObject "MusicStinger" $ \object -> do+ flag <- Json.required object "flag"+ cue <- Json.required object "cue"+ trigger <- Json.required object "trigger"+ pure MusicStinger { flag, cue, trigger }++instance Json.ToJSON MusicStinger where+ toJSON x = Json.object+ [ Json.pair "flag" $ flag x+ , Json.pair "cue" $ cue x+ , Json.pair "trigger" $ trigger x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-music-stinger" $ Schema.object+ [ (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "cue" $ Schema.ref U32.schema, True)+ , (Json.pair "trigger" $ Schema.ref U8.schema, True)+ ]++bitPut :: MusicStinger -> BitPut.BitPut+bitPut musicStingerAttribute =+ BitPut.bool (flag musicStingerAttribute)+ <> U32.bitPut (cue musicStingerAttribute)+ <> U8.bitPut (trigger musicStingerAttribute)++bitGet :: BitGet.BitGet MusicStinger+bitGet = MusicStinger <$> BitGet.bool <*> U32.bitGet <*> U8.bitGet
+ src/lib/Rattletrap/Type/Attribute/PartyLeader.hs view
@@ -0,0 +1,50 @@+module Rattletrap.Type.Attribute.PartyLeader where++import Prelude hiding (id)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.RemoteId as RemoteId+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data PartyLeader = PartyLeader+ { systemId :: U8.U8+ , id :: Maybe (RemoteId.RemoteId, U8.U8)+ }+ deriving (Eq, Show)++instance Json.FromJSON PartyLeader where+ parseJSON = Json.withObject "PartyLeader" $ \object -> do+ systemId <- Json.required object "system_id"+ id <- Json.optional object "id"+ pure PartyLeader { systemId, id }++instance Json.ToJSON PartyLeader where+ toJSON x =+ Json.object [Json.pair "system_id" $ systemId x, Json.pair "id" $ id x]++schema :: Schema.Schema+schema = Schema.named "attribute-party-leader" $ Schema.object+ [ (Json.pair "system_id" $ Schema.ref U8.schema, True)+ , ( Json.pair "id" $ Schema.oneOf+ [ Schema.tuple [Schema.ref RemoteId.schema, Schema.ref U8.schema]+ , Schema.ref Schema.null+ ]+ , False+ )+ ]++bitPut :: PartyLeader -> BitPut.BitPut+bitPut x = U8.bitPut (systemId x) <> foldMap+ (\(y, z) -> RemoteId.bitPut y <> U8.bitPut z)+ (Rattletrap.Type.Attribute.PartyLeader.id x)++bitGet :: Version.Version -> BitGet.BitGet PartyLeader+bitGet version = do+ systemId_ <- U8.bitGet+ PartyLeader systemId_ <$> whenMaybe+ (systemId_ /= U8.fromWord8 0)+ ((,) <$> RemoteId.bitGet version systemId_ <*> U8.bitGet)
+ src/lib/Rattletrap/Type/Attribute/Pickup.hs view
@@ -0,0 +1,45 @@+module Rattletrap.Type.Attribute.Pickup where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data Pickup = Pickup+ { instigatorId :: Maybe U32.U32+ , pickedUp :: Bool+ }+ deriving (Eq, Show)++instance Json.FromJSON Pickup where+ parseJSON = Json.withObject "Pickup" $ \object -> do+ instigatorId <- Json.optional object "instigator_id"+ pickedUp <- Json.required object "picked_up"+ pure Pickup { instigatorId, pickedUp }++instance Json.ToJSON Pickup where+ toJSON x = Json.object+ [ Json.pair "instigator_id" $ instigatorId x+ , Json.pair "picked_up" $ pickedUp x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-pickup" $ Schema.object+ [ (Json.pair "instigator_id" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "picked_up" $ Schema.ref Schema.boolean, True)+ ]++bitPut :: Pickup -> BitPut.BitPut+bitPut x =+ maybe+ (BitPut.bool False)+ (\y -> BitPut.bool True <> U32.bitPut y)+ (instigatorId x)+ <> BitPut.bool (pickedUp x)++bitGet :: BitGet.BitGet Pickup+bitGet = do+ instigator <- BitGet.bool+ Pickup <$> whenMaybe instigator U32.bitGet <*> BitGet.bool
+ src/lib/Rattletrap/Type/Attribute/PickupNew.hs view
@@ -0,0 +1,46 @@+module Rattletrap.Type.Attribute.PickupNew where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data PickupNew = PickupNew+ { instigatorId :: Maybe U32.U32+ , pickedUp :: U8.U8+ }+ deriving (Eq, Show)++instance Json.FromJSON PickupNew where+ parseJSON = Json.withObject "PickupNew" $ \object -> do+ instigatorId <- Json.optional object "instigator_id"+ pickedUp <- Json.required object "picked_up"+ pure PickupNew { instigatorId, pickedUp }++instance Json.ToJSON PickupNew where+ toJSON x = Json.object+ [ Json.pair "instigator_id" $ instigatorId x+ , Json.pair "picked_up" $ pickedUp x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-pickup-new" $ Schema.object+ [ (Json.pair "instigator_id" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "picked_up" $ Schema.ref U8.schema, True)+ ]++bitPut :: PickupNew -> BitPut.BitPut+bitPut x =+ maybe+ (BitPut.bool False)+ (\y -> BitPut.bool True <> U32.bitPut y)+ (instigatorId x)+ <> U8.bitPut (pickedUp x)++bitGet :: BitGet.BitGet PickupNew+bitGet = do+ instigator <- BitGet.bool+ PickupNew <$> whenMaybe instigator U32.bitGet <*> U8.bitGet
+ src/lib/Rattletrap/Type/Attribute/PlayerHistoryKey.hs view
@@ -0,0 +1,27 @@+module Rattletrap.Type.Attribute.PlayerHistoryKey where++import qualified Data.Word as Word+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype PlayerHistoryKey = PlayerHistoryKey+ { unknown :: Word.Word16+ } deriving (Eq, Show)++instance Json.FromJSON PlayerHistoryKey where+ parseJSON = fmap PlayerHistoryKey . Json.parseJSON++instance Json.ToJSON PlayerHistoryKey where+ toJSON = Json.toJSON . unknown++schema :: Schema.Schema+schema =+ Schema.named "attribute-player-history-key" $ Schema.ref Schema.number++bitPut :: PlayerHistoryKey -> BitPut.BitPut+bitPut = BitPut.bits 14 . unknown++bitGet :: BitGet.BitGet PlayerHistoryKey+bitGet = PlayerHistoryKey <$> BitGet.bits 14
+ src/lib/Rattletrap/Type/Attribute/PrivateMatchSettings.hs view
@@ -0,0 +1,74 @@+module Rattletrap.Type.Attribute.PrivateMatchSettings where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json++data PrivateMatchSettings = PrivateMatchSettings+ { mutators :: Str.Str+ , joinableBy :: U32.U32+ , maxPlayers :: U32.U32+ , gameName :: Str.Str+ , password :: Str.Str+ , flag :: Bool+ }+ deriving (Eq, Show)++instance Json.FromJSON PrivateMatchSettings where+ parseJSON = Json.withObject "PrivateMatchSettings" $ \object -> do+ mutators <- Json.required object "mutators"+ joinableBy <- Json.required object "joinable_by"+ maxPlayers <- Json.required object "max_players"+ gameName <- Json.required object "game_name"+ password <- Json.required object "password"+ flag <- Json.required object "flag"+ pure PrivateMatchSettings+ { mutators+ , joinableBy+ , maxPlayers+ , gameName+ , password+ , flag+ }++instance Json.ToJSON PrivateMatchSettings where+ toJSON x = Json.object+ [ Json.pair "mutators" $ mutators x+ , Json.pair "joinable_by" $ joinableBy x+ , Json.pair "max_players" $ maxPlayers x+ , Json.pair "game_name" $ gameName x+ , Json.pair "password" $ password x+ , Json.pair "flag" $ flag x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-private-match-settings" $ Schema.object+ [ (Json.pair "mutators" $ Schema.ref Str.schema, True)+ , (Json.pair "joinable_by" $ Schema.ref U32.schema, True)+ , (Json.pair "max_players" $ Schema.ref U32.schema, True)+ , (Json.pair "game_name" $ Schema.ref Str.schema, True)+ , (Json.pair "password" $ Schema.ref Str.schema, True)+ , (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ ]++bitPut :: PrivateMatchSettings -> BitPut.BitPut+bitPut privateMatchSettingsAttribute =+ Str.bitPut (mutators privateMatchSettingsAttribute)+ <> U32.bitPut (joinableBy privateMatchSettingsAttribute)+ <> U32.bitPut (maxPlayers privateMatchSettingsAttribute)+ <> Str.bitPut (gameName privateMatchSettingsAttribute)+ <> Str.bitPut (password privateMatchSettingsAttribute)+ <> BitPut.bool (flag privateMatchSettingsAttribute)++bitGet :: BitGet.BitGet PrivateMatchSettings+bitGet =+ PrivateMatchSettings+ <$> Str.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> Str.bitGet+ <*> Str.bitGet+ <*> BitGet.bool
+ src/lib/Rattletrap/Type/Attribute/Product.hs view
@@ -0,0 +1,74 @@+module Rattletrap.Type.Attribute.Product where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.ProductValue as ProductValue+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++import qualified Data.Map as Map++data Product = Product+ { unknown :: Bool+ , objectId :: U32.U32+ , objectName :: Maybe Str.Str+ -- ^ read-only+ , value :: ProductValue.ProductValue+ }+ deriving (Eq, Show)++instance Json.FromJSON Product where+ parseJSON = Json.withObject "Product" $ \object -> do+ unknown <- Json.required object "unknown"+ objectId <- Json.required object "object_id"+ objectName <- Json.optional object "object_name"+ value <- Json.required object "value"+ pure Product { unknown, objectId, objectName, value }++instance Json.ToJSON Product where+ toJSON x = Json.object+ [ Json.pair "unknown" $ unknown x+ , Json.pair "object_id" $ objectId x+ , Json.pair "object_name" $ objectName x+ , Json.pair "value" $ value x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-product" $ Schema.object+ [ (Json.pair "unknown" $ Schema.ref Schema.boolean, True)+ , (Json.pair "object_id" $ Schema.ref U32.schema, True)+ , (Json.pair "object_name" . Schema.json $ Schema.maybe Str.schema, False)+ , (Json.pair "value" $ Schema.ref ProductValue.schema, True)+ ]++putProductAttributes :: List.List Product -> BitPut.BitPut+putProductAttributes attributes =+ let v = List.toList attributes+ in (U8.bitPut . U8.fromWord8 . fromIntegral $ length v) <> foldMap bitPut v++bitPut :: Product -> BitPut.BitPut+bitPut attribute =+ BitPut.bool (unknown attribute)+ <> U32.bitPut (objectId attribute)+ <> ProductValue.bitPut (value attribute)++decodeProductAttributesBits+ :: Version.Version+ -> Map.Map U32.U32 Str.Str+ -> BitGet.BitGet (List.List Product)+decodeProductAttributesBits version objectMap = do+ size <- U8.bitGet+ List.replicateM (fromIntegral $ U8.toWord8 size) $ bitGet version objectMap++bitGet :: Version.Version -> Map.Map U32.U32 Str.Str -> BitGet.BitGet Product+bitGet version objectMap = do+ flag <- BitGet.bool+ objectId_ <- U32.bitGet+ let maybeObjectName = Map.lookup objectId_ objectMap+ value_ <- ProductValue.bitGet version objectId_ maybeObjectName+ pure (Product flag objectId_ maybeObjectName value_)
+ src/lib/Rattletrap/Type/Attribute/ProductValue.hs view
@@ -0,0 +1,121 @@+module Rattletrap.Type.Attribute.ProductValue where++import qualified Data.Foldable as Foldable+import qualified Data.Word as Word+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data ProductValue+ = PaintedOld CompressedWord.CompressedWord+ | PaintedNew Word.Word32+ | TeamEditionOld CompressedWord.CompressedWord+ | TeamEditionNew Word.Word32+ | SpecialEdition Word.Word32+ | UserColorOld (Maybe Word.Word32)+ | UserColorNew U32.U32+ | TitleId Str.Str+ deriving (Eq, Show)++instance Json.FromJSON ProductValue where+ parseJSON = Json.withObject "ProductValue" $ \object -> Foldable.asum+ [ PaintedOld <$> Json.required object "painted_old"+ , PaintedNew <$> Json.required object "painted_new"+ , TeamEditionOld <$> Json.required object "team_edition_old"+ , TeamEditionNew <$> Json.required object "team_edition_new"+ , SpecialEdition <$> Json.required object "special_edition"+ , UserColorOld <$> Json.required object "user_color_old"+ , UserColorNew <$> Json.required object "user_color_new"+ , TitleId <$> Json.required object "title_id"+ ]++instance Json.ToJSON ProductValue where+ toJSON x = case x of+ PaintedOld y -> Json.object [Json.pair "painted_old" y]+ PaintedNew y -> Json.object [Json.pair "painted_new" y]+ TeamEditionOld y -> Json.object [Json.pair "team_edition_old" y]+ TeamEditionNew y -> Json.object [Json.pair "team_edition_new" y]+ SpecialEdition y -> Json.object [Json.pair "special_edition" y]+ UserColorOld y -> Json.object [Json.pair "user_color_old" y]+ UserColorNew y -> Json.object [Json.pair "user_color_new" y]+ TitleId y -> Json.object [Json.pair "title_id" y]++schema :: Schema.Schema+schema = Schema.named "attribute-product-value" . Schema.oneOf $ fmap+ (\(k, v) -> Schema.object [(Json.pair k v, True)])+ [ ("painted_old", Schema.ref CompressedWord.schema)+ , ("painted_new", Schema.ref Schema.integer)+ , ("team_edition_old", Schema.ref CompressedWord.schema)+ , ("team_edition_new", Schema.ref Schema.integer)+ , ("special_edition", Schema.ref Schema.integer)+ , ("user_color_old", Schema.json $ Schema.maybe Schema.integer)+ , ("user_color_new", Schema.ref U32.schema)+ , ("title_id", Schema.ref Str.schema)+ ]++bitPut :: ProductValue -> BitPut.BitPut+bitPut val = case val of+ PaintedOld x -> CompressedWord.bitPut x+ PaintedNew x -> BitPut.bits 31 x+ TeamEditionOld x -> CompressedWord.bitPut x+ TeamEditionNew x -> BitPut.bits 31 x+ SpecialEdition x -> BitPut.bits 31 x+ UserColorOld x -> case x of+ Nothing -> BitPut.bool False+ Just y -> BitPut.bool True <> BitPut.bits 31 y+ UserColorNew x -> U32.bitPut x+ TitleId x -> Str.bitPut x++bitGet+ :: Version.Version -> U32.U32 -> Maybe Str.Str -> BitGet.BitGet ProductValue+bitGet version objectId maybeObjectName =+ case Str.toString <$> 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)++decodeSpecialEdition :: BitGet.BitGet ProductValue+decodeSpecialEdition = SpecialEdition <$> BitGet.bits 31++decodePainted :: Version.Version -> BitGet.BitGet ProductValue+decodePainted version = if hasNewPainted version+ then PaintedNew <$> BitGet.bits 31+ else PaintedOld <$> CompressedWord.bitGet 13++decodeTeamEdition :: Version.Version -> BitGet.BitGet ProductValue+decodeTeamEdition version = if hasNewPainted version+ then TeamEditionNew <$> BitGet.bits 31+ else TeamEditionOld <$> CompressedWord.bitGet 13++decodeColor :: Version.Version -> BitGet.BitGet ProductValue+decodeColor version = if hasNewColor version+ then UserColorNew <$> U32.bitGet+ else do+ hasValue <- BitGet.bool+ UserColorOld <$> whenMaybe hasValue (BitGet.bits 31)++hasNewPainted :: Version.Version -> Bool+hasNewPainted v =+ Version.major v >= 868 && Version.minor v >= 18 && Version.patch v >= 0++hasNewColor :: Version.Version -> Bool+hasNewColor v =+ Version.major v >= 868 && Version.minor v >= 23 && Version.patch v >= 8++decodeTitle :: BitGet.BitGet ProductValue+decodeTitle = TitleId <$> Str.bitGet
+ src/lib/Rattletrap/Type/Attribute/QWord.hs view
@@ -0,0 +1,26 @@+module Rattletrap.Type.Attribute.QWord where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U64 as U64+import qualified Rattletrap.Utility.Json as Json++newtype QWord = QWord+ { value :: U64.U64+ } deriving (Eq, Show)++instance Json.FromJSON QWord where+ parseJSON = fmap QWord . Json.parseJSON++instance Json.ToJSON QWord where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-q-word" $ Schema.ref U64.schema++bitPut :: QWord -> BitPut.BitPut+bitPut qWordAttribute = U64.bitPut (value qWordAttribute)++bitGet :: BitGet.BitGet QWord+bitGet = QWord <$> U64.bitGet
+ src/lib/Rattletrap/Type/Attribute/Reservation.hs view
@@ -0,0 +1,76 @@+module Rattletrap.Type.Attribute.Reservation where++import qualified Data.Word as Word+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.UniqueId as UniqueId+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data Reservation = Reservation+ { number :: CompressedWord.CompressedWord+ , uniqueId :: UniqueId.UniqueId+ , name :: Maybe Str.Str+ , unknown1 :: Bool+ , unknown2 :: Bool+ , unknown3 :: Maybe Word.Word8+ }+ deriving (Eq, Show)++instance Json.FromJSON Reservation where+ parseJSON = Json.withObject "Reservation" $ \object -> do+ number <- Json.required object "number"+ uniqueId <- Json.required object "unique_id"+ name <- Json.optional object "name"+ unknown1 <- Json.required object "unknown1"+ unknown2 <- Json.required object "unknown2"+ unknown3 <- Json.optional object "unknown3"+ pure Reservation { number, uniqueId, name, unknown1, unknown2, unknown3 }++instance Json.ToJSON Reservation where+ toJSON x = Json.object+ [ Json.pair "number" $ number x+ , Json.pair "unique_id" $ uniqueId x+ , Json.pair "name" $ name x+ , Json.pair "unknown1" $ unknown1 x+ , Json.pair "unknown2" $ unknown2 x+ , Json.pair "unknown3" $ unknown3 x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-reservation" $ Schema.object+ [ (Json.pair "number" $ Schema.ref CompressedWord.schema, True)+ , (Json.pair "unique_id" $ Schema.ref UniqueId.schema, True)+ , (Json.pair "name" . Schema.json $ Schema.maybe Str.schema, False)+ , (Json.pair "unknown1" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown2" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown3" . Schema.json $ Schema.maybe Schema.integer, False)+ ]++bitPut :: Reservation -> BitPut.BitPut+bitPut reservationAttribute =+ CompressedWord.bitPut (number reservationAttribute)+ <> UniqueId.bitPut (uniqueId reservationAttribute)+ <> foldMap Str.bitPut (name reservationAttribute)+ <> BitPut.bool (unknown1 reservationAttribute)+ <> BitPut.bool (unknown2 reservationAttribute)+ <> foldMap (BitPut.word8 6) (unknown3 reservationAttribute)++bitGet :: Version.Version -> BitGet.BitGet Reservation+bitGet version = do+ number_ <- CompressedWord.bitGet 7+ uniqueId_ <- UniqueId.bitGet version+ Reservation number_ uniqueId_+ <$> whenMaybe (UniqueId.systemId uniqueId_ /= U8.fromWord8 0) Str.bitGet+ <*> BitGet.bool+ <*> BitGet.bool+ <*> whenMaybe (hasUnknown3 version) (BitGet.word8 6)++hasUnknown3 :: Version.Version -> Bool+hasUnknown3 v =+ Version.major v >= 868 && Version.minor v >= 12 && Version.patch v >= 0
+ src/lib/Rattletrap/Type/Attribute/RigidBodyState.hs view
@@ -0,0 +1,73 @@+module Rattletrap.Type.Attribute.RigidBodyState where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Rotation as Rotation+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++data RigidBodyState = RigidBodyState+ { sleeping :: Bool+ , location :: Vector.Vector+ , rotation :: Rotation.Rotation+ , linearVelocity :: Maybe Vector.Vector+ , angularVelocity :: Maybe Vector.Vector+ }+ deriving (Eq, Show)++instance Json.FromJSON RigidBodyState where+ parseJSON = Json.withObject "RigidBodyState" $ \object -> do+ sleeping <- Json.required object "sleeping"+ location <- Json.required object "location"+ rotation <- Json.required object "rotation"+ linearVelocity <- Json.optional object "linear_velocity"+ angularVelocity <- Json.optional object "angular_velocity"+ pure RigidBodyState+ { sleeping+ , location+ , rotation+ , linearVelocity+ , angularVelocity+ }++instance Json.ToJSON RigidBodyState where+ toJSON x = Json.object+ [ Json.pair "sleeping" $ sleeping x+ , Json.pair "location" $ location x+ , Json.pair "rotation" $ rotation x+ , Json.pair "linear_velocity" $ linearVelocity x+ , Json.pair "angular_velocity" $ angularVelocity x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-rigid-body-state" $ Schema.object+ [ (Json.pair "sleeping" $ Schema.ref Schema.boolean, True)+ , (Json.pair "location" $ Schema.ref Vector.schema, True)+ , (Json.pair "rotation" $ Schema.ref Rotation.schema, True)+ , ( Json.pair "linear_velocity" . Schema.json $ Schema.maybe Vector.schema+ , False+ )+ , ( Json.pair "angular_velocity" . Schema.json $ Schema.maybe Vector.schema+ , False+ )+ ]++bitPut :: RigidBodyState -> BitPut.BitPut+bitPut rigidBodyStateAttribute =+ BitPut.bool (sleeping rigidBodyStateAttribute)+ <> Vector.bitPut (location rigidBodyStateAttribute)+ <> Rotation.bitPut (rotation rigidBodyStateAttribute)+ <> foldMap Vector.bitPut (linearVelocity rigidBodyStateAttribute)+ <> foldMap Vector.bitPut (angularVelocity rigidBodyStateAttribute)++bitGet :: Version.Version -> BitGet.BitGet RigidBodyState+bitGet version = do+ sleeping_ <- BitGet.bool+ RigidBodyState sleeping_+ <$> Vector.bitGet version+ <*> Rotation.bitGet version+ <*> whenMaybe (not sleeping_) (Vector.bitGet version)+ <*> whenMaybe (not sleeping_) (Vector.bitGet version)
+ src/lib/Rattletrap/Type/Attribute/StatEvent.hs view
@@ -0,0 +1,36 @@+module Rattletrap.Type.Attribute.StatEvent where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Utility.Json as Json++data StatEvent = StatEvent+ { unknown :: Bool+ , objectId :: I32.I32+ }+ deriving (Eq, Show)++instance Json.FromJSON StatEvent where+ parseJSON = Json.withObject "StatEvent" $ \object -> do+ unknown <- Json.required object "unknown"+ objectId <- Json.required object "object_id"+ pure StatEvent { unknown, objectId }++instance Json.ToJSON StatEvent where+ toJSON x = Json.object+ [Json.pair "unknown" $ unknown x, Json.pair "object_id" $ objectId x]++schema :: Schema.Schema+schema = Schema.named "attribute-stat-event" $ Schema.object+ [ (Json.pair "unknown" $ Schema.ref Schema.boolean, True)+ , (Json.pair "object_id" $ Schema.ref I32.schema, True)+ ]++bitPut :: StatEvent -> BitPut.BitPut+bitPut statEventAttribute = BitPut.bool (unknown statEventAttribute)+ <> I32.bitPut (objectId statEventAttribute)++bitGet :: BitGet.BitGet StatEvent+bitGet = StatEvent <$> BitGet.bool <*> I32.bitGet
+ src/lib/Rattletrap/Type/Attribute/String.hs view
@@ -0,0 +1,27 @@+module Rattletrap.Type.Attribute.String where++import Prelude hiding (String)+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Utility.Json as Json++newtype String = String+ { value :: Str.Str+ } deriving (Eq, Show)++instance Json.FromJSON String where+ parseJSON = fmap String . Json.parseJSON++instance Json.ToJSON String where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-string" $ Schema.ref Str.schema++bitPut :: String -> BitPut.BitPut+bitPut stringAttribute = Str.bitPut (value stringAttribute)++bitGet :: BitGet.BitGet String+bitGet = String <$> Str.bitGet
+ src/lib/Rattletrap/Type/Attribute/TeamPaint.hs view
@@ -0,0 +1,67 @@+module Rattletrap.Type.Attribute.TeamPaint where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json++data TeamPaint = TeamPaint+ { team :: U8.U8+ , primaryColor :: U8.U8+ , accentColor :: U8.U8+ , primaryFinish :: U32.U32+ , accentFinish :: U32.U32+ }+ deriving (Eq, Show)++instance Json.FromJSON TeamPaint where+ parseJSON = Json.withObject "TeamPaint" $ \object -> do+ team <- Json.required object "team"+ primaryColor <- Json.required object "primary_color"+ accentColor <- Json.required object "accent_color"+ primaryFinish <- Json.required object "primary_finish"+ accentFinish <- Json.required object "accent_finish"+ pure TeamPaint+ { team+ , primaryColor+ , accentColor+ , primaryFinish+ , accentFinish+ }++instance Json.ToJSON TeamPaint where+ toJSON x = Json.object+ [ Json.pair "team" $ team x+ , Json.pair "primary_color" $ primaryColor x+ , Json.pair "accent_color" $ accentColor x+ , Json.pair "primary_finish" $ primaryFinish x+ , Json.pair "accent_finish" $ accentFinish x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-team-paint" $ Schema.object+ [ (Json.pair "team" $ Schema.ref U8.schema, True)+ , (Json.pair "primary_color" $ Schema.ref U8.schema, True)+ , (Json.pair "accent_color" $ Schema.ref U8.schema, True)+ , (Json.pair "primary_finish" $ Schema.ref U32.schema, True)+ , (Json.pair "accent_finish" $ Schema.ref U32.schema, True)+ ]++bitPut :: TeamPaint -> BitPut.BitPut+bitPut teamPaintAttribute =+ U8.bitPut (team teamPaintAttribute)+ <> U8.bitPut (primaryColor teamPaintAttribute)+ <> U8.bitPut (accentColor teamPaintAttribute)+ <> U32.bitPut (primaryFinish teamPaintAttribute)+ <> U32.bitPut (accentFinish teamPaintAttribute)++bitGet :: BitGet.BitGet TeamPaint+bitGet =+ TeamPaint+ <$> U8.bitGet+ <*> U8.bitGet+ <*> U8.bitGet+ <*> U32.bitGet+ <*> U32.bitGet
+ src/lib/Rattletrap/Type/Attribute/Title.hs view
@@ -0,0 +1,87 @@+module Rattletrap.Type.Attribute.Title where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json++data Title = Title+ { unknown1 :: Bool+ , unknown2 :: Bool+ , unknown3 :: U32.U32+ , unknown4 :: U32.U32+ , unknown5 :: U32.U32+ , unknown6 :: U32.U32+ , unknown7 :: U32.U32+ , unknown8 :: Bool+ }+ deriving (Eq, Show)++instance Json.FromJSON Title where+ parseJSON = Json.withObject "Title" $ \object -> do+ unknown1 <- Json.required object "unknown1"+ unknown2 <- Json.required object "unknown2"+ unknown3 <- Json.required object "unknown3"+ unknown4 <- Json.required object "unknown4"+ unknown5 <- Json.required object "unknown5"+ unknown6 <- Json.required object "unknown6"+ unknown7 <- Json.required object "unknown7"+ unknown8 <- Json.required object "unknown8"+ pure Title+ { unknown1+ , unknown2+ , unknown3+ , unknown4+ , unknown5+ , unknown6+ , unknown7+ , unknown8+ }++instance Json.ToJSON Title where+ toJSON x = Json.object+ [ Json.pair "unknown1" $ unknown1 x+ , Json.pair "unknown2" $ unknown2 x+ , Json.pair "unknown3" $ unknown3 x+ , Json.pair "unknown4" $ unknown4 x+ , Json.pair "unknown5" $ unknown5 x+ , Json.pair "unknown6" $ unknown6 x+ , Json.pair "unknown7" $ unknown7 x+ , Json.pair "unknown8" $ unknown8 x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-title" $ Schema.object+ [ (Json.pair "unknown1" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown2" $ Schema.ref Schema.boolean, True)+ , (Json.pair "unknown3" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown4" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown5" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown6" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown7" $ Schema.ref U32.schema, True)+ , (Json.pair "unknown8" $ Schema.ref Schema.boolean, True)+ ]++bitPut :: Title -> BitPut.BitPut+bitPut titleAttribute =+ BitPut.bool (unknown1 titleAttribute)+ <> BitPut.bool (unknown2 titleAttribute)+ <> U32.bitPut (unknown3 titleAttribute)+ <> U32.bitPut (unknown4 titleAttribute)+ <> U32.bitPut (unknown5 titleAttribute)+ <> U32.bitPut (unknown6 titleAttribute)+ <> U32.bitPut (unknown7 titleAttribute)+ <> BitPut.bool (unknown8 titleAttribute)++bitGet :: BitGet.BitGet Title+bitGet =+ Title+ <$> BitGet.bool+ <*> BitGet.bool+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> U32.bitGet+ <*> BitGet.bool
+ src/lib/Rattletrap/Type/Attribute/UniqueId.hs view
@@ -0,0 +1,48 @@+module Rattletrap.Type.Attribute.UniqueId where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.RemoteId as RemoteId+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data UniqueId = UniqueId+ { systemId :: U8.U8+ , remoteId :: RemoteId.RemoteId+ , localId :: U8.U8+ }+ deriving (Eq, Show)++instance Json.FromJSON UniqueId where+ parseJSON = Json.withObject "UniqueId" $ \object -> do+ systemId <- Json.required object "system_id"+ remoteId <- Json.required object "remote_id"+ localId <- Json.required object "local_id"+ pure UniqueId { systemId, remoteId, localId }++instance Json.ToJSON UniqueId where+ toJSON x = Json.object+ [ Json.pair "system_id" $ systemId x+ , Json.pair "remote_id" $ remoteId x+ , Json.pair "local_id" $ localId x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-unique-id" $ Schema.object+ [ (Json.pair "system_id" $ Schema.ref U8.schema, True)+ , (Json.pair "remote_id" $ Schema.ref RemoteId.schema, True)+ , (Json.pair "local_id" $ Schema.ref U8.schema, True)+ ]++bitPut :: UniqueId -> BitPut.BitPut+bitPut uniqueIdAttribute =+ U8.bitPut (systemId uniqueIdAttribute)+ <> RemoteId.bitPut (remoteId uniqueIdAttribute)+ <> U8.bitPut (localId uniqueIdAttribute)++bitGet :: Version.Version -> BitGet.BitGet UniqueId+bitGet version = do+ systemId_ <- U8.bitGet+ UniqueId systemId_ <$> RemoteId.bitGet version systemId_ <*> U8.bitGet
+ src/lib/Rattletrap/Type/Attribute/WeldedInfo.hs view
@@ -0,0 +1,64 @@+module Rattletrap.Type.Attribute.WeldedInfo where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.Int8Vector as Int8Vector+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++data WeldedInfo = WeldedInfo+ { active :: Bool+ , actorId :: I32.I32+ , offset :: Vector.Vector+ , mass :: F32.F32+ , rotation :: Int8Vector.Int8Vector+ }+ deriving (Eq, Show)++instance Json.FromJSON WeldedInfo where+ parseJSON = Json.withObject "WeldedInfo" $ \object -> do+ active <- Json.required object "active"+ actorId <- Json.required object "actor_id"+ offset <- Json.required object "offset"+ mass <- Json.required object "mass"+ rotation <- Json.required object "rotation"+ pure WeldedInfo { active, actorId, offset, mass, rotation }++instance Json.ToJSON WeldedInfo where+ toJSON x = Json.object+ [ Json.pair "active" $ active x+ , Json.pair "actor_id" $ actorId x+ , Json.pair "offset" $ offset x+ , Json.pair "mass" $ mass x+ , Json.pair "rotation" $ rotation x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-welded-info" $ Schema.object+ [ (Json.pair "active" $ Schema.ref Schema.boolean, True)+ , (Json.pair "actor_id" $ Schema.ref I32.schema, True)+ , (Json.pair "offset" $ Schema.ref Vector.schema, True)+ , (Json.pair "mass" $ Schema.ref F32.schema, True)+ , (Json.pair "rotation" $ Schema.ref Int8Vector.schema, True)+ ]++bitPut :: WeldedInfo -> BitPut.BitPut+bitPut weldedInfoAttribute =+ BitPut.bool (active weldedInfoAttribute)+ <> I32.bitPut (actorId weldedInfoAttribute)+ <> Vector.bitPut (offset weldedInfoAttribute)+ <> F32.bitPut (mass weldedInfoAttribute)+ <> Int8Vector.bitPut (rotation weldedInfoAttribute)++bitGet :: Version.Version -> BitGet.BitGet WeldedInfo+bitGet version =+ WeldedInfo+ <$> BitGet.bool+ <*> I32.bitGet+ <*> Vector.bitGet version+ <*> F32.bitGet+ <*> Int8Vector.bitGet
src/lib/Rattletrap/Type/AttributeMapping.hs view
@@ -1,16 +1,35 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.AttributeMapping- ( AttributeMapping(..)- )-where+module Rattletrap.Type.AttributeMapping where -import Rattletrap.Type.Common-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json data AttributeMapping = AttributeMapping- { attributeMappingObjectId :: Word32le- , attributeMappingStreamId :: Word32le- } deriving (Eq, Ord, Show)+ { objectId :: U32.U32+ , streamId :: U32.U32+ }+ deriving (Eq, Show) -$(deriveJson ''AttributeMapping)+instance Json.FromJSON AttributeMapping where+ parseJSON = Json.withObject "AttributeMapping" $ \object -> do+ objectId <- Json.required object "object_id"+ streamId <- Json.required object "stream_id"+ pure AttributeMapping { objectId, streamId }++instance Json.ToJSON AttributeMapping where+ toJSON x = Json.object+ [Json.pair "object_id" $ objectId x, Json.pair "stream_id" $ streamId x]++schema :: Schema.Schema+schema = Schema.named "attributeMapping" $ Schema.object+ [ (Json.pair "object_id" $ Schema.ref U32.schema, True)+ , (Json.pair "stream_id" $ Schema.ref U32.schema, True)+ ]++bytePut :: AttributeMapping -> BytePut.BytePut+bytePut x = U32.bytePut (objectId x) <> U32.bytePut (streamId x)++byteGet :: ByteGet.ByteGet AttributeMapping+byteGet = AttributeMapping <$> U32.byteGet <*> U32.byteGet
src/lib/Rattletrap/Type/AttributeType.hs view
@@ -1,50 +1,41 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.AttributeType- ( AttributeType(..)- )-where--import Rattletrap.Type.Common+module Rattletrap.Type.AttributeType where 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)+ = AppliedDamage+ | Boolean+ | Byte+ | CamSettings+ | ClubColors+ | CustomDemolish+ | DamageState+ | Demolish+ | Enum+ | Explosion+ | ExtendedExplosion+ | FlaggedInt+ | FlaggedByte+ | Float+ | GameMode+ | Int+ | Int64+ | Loadout+ | LoadoutOnline+ | Loadouts+ | LoadoutsOnline+ | Location+ | MusicStinger+ | PartyLeader+ | Pickup+ | PickupNew+ | PlayerHistoryKey+ | PrivateMatchSettings+ | QWord+ | Reservation+ | RigidBodyState+ | StatEvent+ | String+ | TeamPaint+ | Title+ | UniqueId+ | WeldedInfo+ deriving (Eq, Show)
src/lib/Rattletrap/Type/AttributeValue.hs view
@@ -1,87 +1,312 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.AttributeValue where -module Rattletrap.Type.AttributeValue- ( AttributeValue(..)- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Data as Data+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.AppliedDamage as AppliedDamage+import qualified Rattletrap.Type.Attribute.Boolean as Boolean+import qualified Rattletrap.Type.Attribute.Byte as Byte+import qualified Rattletrap.Type.Attribute.CamSettings as CamSettings+import qualified Rattletrap.Type.Attribute.ClubColors as ClubColors+import qualified Rattletrap.Type.Attribute.CustomDemolish as CustomDemolish+import qualified Rattletrap.Type.Attribute.DamageState as DamageState+import qualified Rattletrap.Type.Attribute.Demolish as Demolish+import qualified Rattletrap.Type.Attribute.Enum as Enum+import qualified Rattletrap.Type.Attribute.Explosion as Explosion+import qualified Rattletrap.Type.Attribute.ExtendedExplosion as ExtendedExplosion+import qualified Rattletrap.Type.Attribute.FlaggedByte as FlaggedByte+import qualified Rattletrap.Type.Attribute.FlaggedInt as FlaggedInt+import qualified Rattletrap.Type.Attribute.Float as Float+import qualified Rattletrap.Type.Attribute.GameMode as GameMode+import qualified Rattletrap.Type.Attribute.Int as Int+import qualified Rattletrap.Type.Attribute.Int64 as Int64+import qualified Rattletrap.Type.Attribute.Loadout as Loadout+import qualified Rattletrap.Type.Attribute.LoadoutOnline as LoadoutOnline+import qualified Rattletrap.Type.Attribute.Loadouts as Loadouts+import qualified Rattletrap.Type.Attribute.LoadoutsOnline as LoadoutsOnline+import qualified Rattletrap.Type.Attribute.Location as Location+import qualified Rattletrap.Type.Attribute.MusicStinger as MusicStinger+import qualified Rattletrap.Type.Attribute.PartyLeader as PartyLeader+import qualified Rattletrap.Type.Attribute.Pickup as Pickup+import qualified Rattletrap.Type.Attribute.PickupNew as PickupNew+import qualified Rattletrap.Type.Attribute.PlayerHistoryKey as PlayerHistoryKey+import qualified Rattletrap.Type.Attribute.PrivateMatchSettings as PrivateMatchSettings+import qualified Rattletrap.Type.Attribute.QWord as QWord+import qualified Rattletrap.Type.Attribute.Reservation as Reservation+import qualified Rattletrap.Type.Attribute.RigidBodyState as RigidBodyState+import qualified Rattletrap.Type.Attribute.StatEvent as StatEvent+import qualified Rattletrap.Type.Attribute.String as String+import qualified Rattletrap.Type.Attribute.TeamPaint as TeamPaint+import qualified Rattletrap.Type.Attribute.Title as Title+import qualified Rattletrap.Type.Attribute.UniqueId as UniqueId+import qualified Rattletrap.Type.Attribute.WeldedInfo as WeldedInfo+import qualified Rattletrap.Type.AttributeType as AttributeType+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json -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+import qualified Data.Foldable as Foldable+import qualified Data.Map as Map 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)+ = AppliedDamage AppliedDamage.AppliedDamage+ | Boolean Boolean.Boolean+ | Byte Byte.Byte+ | CamSettings CamSettings.CamSettings+ | ClubColors ClubColors.ClubColors+ | CustomDemolish CustomDemolish.CustomDemolish+ | DamageState DamageState.DamageState+ | Demolish Demolish.Demolish+ | Enum Enum.Enum+ | Explosion Explosion.Explosion+ | ExtendedExplosion ExtendedExplosion.ExtendedExplosion+ | FlaggedInt FlaggedInt.FlaggedInt+ | FlaggedByte FlaggedByte.FlaggedByte+ | Float Float.Float+ | GameMode GameMode.GameMode+ | Int Int.Int+ | Int64 Int64.Int64+ | Loadout Loadout.Loadout+ | LoadoutOnline LoadoutOnline.LoadoutOnline+ | Loadouts Loadouts.Loadouts+ | LoadoutsOnline LoadoutsOnline.LoadoutsOnline+ | Location Location.Location+ | MusicStinger MusicStinger.MusicStinger+ | PartyLeader PartyLeader.PartyLeader+ | Pickup Pickup.Pickup+ | PickupNew PickupNew.PickupNew+ | PlayerHistoryKey PlayerHistoryKey.PlayerHistoryKey+ | PrivateMatchSettings PrivateMatchSettings.PrivateMatchSettings+ | QWord QWord.QWord+ | Reservation Reservation.Reservation+ | RigidBodyState RigidBodyState.RigidBodyState+ | StatEvent StatEvent.StatEvent+ | String String.String+ | TeamPaint TeamPaint.TeamPaint+ | Title Title.Title+ | UniqueId UniqueId.UniqueId+ | WeldedInfo WeldedInfo.WeldedInfo+ deriving (Eq, Show) -$(deriveJson ''AttributeValue)+instance Json.FromJSON AttributeValue where+ parseJSON = Json.withObject "AttributeValue" $ \object -> Foldable.asum+ [ AppliedDamage <$> Json.required object "applied_damage"+ , Boolean <$> Json.required object "boolean"+ , Byte <$> Json.required object "byte"+ , CamSettings <$> Json.required object "cam_settings"+ , ClubColors <$> Json.required object "club_colors"+ , CustomDemolish <$> Json.required object "custom_demolish"+ , DamageState <$> Json.required object "damage_state"+ , Demolish <$> Json.required object "demolish"+ , Enum <$> Json.required object "enum"+ , Explosion <$> Json.required object "explosion"+ , ExtendedExplosion <$> Json.required object "extended_explosion"+ , FlaggedByte <$> Json.required object "flagged_byte"+ , FlaggedInt <$> Json.required object "flagged_int"+ , Float <$> Json.required object "float"+ , GameMode <$> Json.required object "game_mode"+ , Int <$> Json.required object "int"+ , Int64 <$> Json.required object "int64"+ , Loadout <$> Json.required object "loadout"+ , LoadoutOnline <$> Json.required object "loadout_online"+ , Loadouts <$> Json.required object "loadouts"+ , LoadoutsOnline <$> Json.required object "loadouts_online"+ , Location <$> Json.required object "location"+ , MusicStinger <$> Json.required object "music_stinger"+ , PartyLeader <$> Json.required object "party_leader"+ , Pickup <$> Json.required object "pickup"+ , PickupNew <$> Json.required object "pickup_new"+ , PlayerHistoryKey <$> Json.required object "player_history_key"+ , PrivateMatchSettings <$> Json.required object "private_match_settings"+ , QWord <$> Json.required object "q_word"+ , Reservation <$> Json.required object "reservation"+ , RigidBodyState <$> Json.required object "rigid_body_state"+ , StatEvent <$> Json.required object "stat_event"+ , String <$> Json.required object "string"+ , TeamPaint <$> Json.required object "team_paint"+ , Title <$> Json.required object "title"+ , UniqueId <$> Json.required object "unique_id"+ , WeldedInfo <$> Json.required object "welded_info"+ ]++instance Json.ToJSON AttributeValue where+ toJSON x = case x of+ AppliedDamage y -> Json.object [Json.pair "applied_damage" y]+ Boolean y -> Json.object [Json.pair "boolean" y]+ Byte y -> Json.object [Json.pair "byte" y]+ CamSettings y -> Json.object [Json.pair "cam_settings" y]+ ClubColors y -> Json.object [Json.pair "club_colors" y]+ CustomDemolish y -> Json.object [Json.pair "custom_demolish" y]+ DamageState y -> Json.object [Json.pair "damage_state" y]+ Demolish y -> Json.object [Json.pair "demolish" y]+ Enum y -> Json.object [Json.pair "enum" y]+ Explosion y -> Json.object [Json.pair "explosion" y]+ ExtendedExplosion y -> Json.object [Json.pair "extended_explosion" y]+ FlaggedByte y -> Json.object [Json.pair "flagged_byte" y]+ FlaggedInt y -> Json.object [Json.pair "flagged_int" y]+ Float y -> Json.object [Json.pair "float" y]+ GameMode y -> Json.object [Json.pair "game_mode" y]+ Int y -> Json.object [Json.pair "int" y]+ Int64 y -> Json.object [Json.pair "int64" y]+ Loadout y -> Json.object [Json.pair "loadout" y]+ LoadoutOnline y -> Json.object [Json.pair "loadout_online" y]+ Loadouts y -> Json.object [Json.pair "loadouts" y]+ LoadoutsOnline y -> Json.object [Json.pair "loadouts_online" y]+ Location y -> Json.object [Json.pair "location" y]+ MusicStinger y -> Json.object [Json.pair "music_stinger" y]+ PartyLeader y -> Json.object [Json.pair "party_leader" y]+ Pickup y -> Json.object [Json.pair "pickup" y]+ PickupNew y -> Json.object [Json.pair "pickup_new" y]+ PlayerHistoryKey y -> Json.object [Json.pair "player_history_key" y]+ PrivateMatchSettings y ->+ Json.object [Json.pair "private_match_settings" y]+ QWord y -> Json.object [Json.pair "q_word" y]+ Reservation y -> Json.object [Json.pair "reservation" y]+ RigidBodyState y -> Json.object [Json.pair "rigid_body_state" y]+ StatEvent y -> Json.object [Json.pair "stat_event" y]+ String y -> Json.object [Json.pair "string" y]+ TeamPaint y -> Json.object [Json.pair "team_paint" y]+ Title y -> Json.object [Json.pair "title" y]+ UniqueId y -> Json.object [Json.pair "unique_id" y]+ WeldedInfo y -> Json.object [Json.pair "welded_info" y]++schema :: Schema.Schema+schema = Schema.named "attribute-value" . Schema.oneOf $ fmap+ (\(k, v) -> Schema.object [(Json.pair k $ Schema.ref v, True)])+ [ ("applied_damage", AppliedDamage.schema)+ , ("boolean", Boolean.schema)+ , ("byte", Byte.schema)+ , ("cam_settings", CamSettings.schema)+ , ("club_colors", ClubColors.schema)+ , ("custom_demolish", CustomDemolish.schema)+ , ("damage_state", DamageState.schema)+ , ("demolish", Demolish.schema)+ , ("enum", Enum.schema)+ , ("explosion", Explosion.schema)+ , ("extended_explosion", ExtendedExplosion.schema)+ , ("flagged_byte", FlaggedByte.schema)+ , ("flagged_int", FlaggedInt.schema)+ , ("float", Float.schema)+ , ("game_mode", GameMode.schema)+ , ("int", Int.schema)+ , ("int64", Int64.schema)+ , ("loadout_online", LoadoutOnline.schema)+ , ("loadout", Loadout.schema)+ , ("loadouts_online", LoadoutsOnline.schema)+ , ("loadouts", Loadouts.schema)+ , ("location", Location.schema)+ , ("music_stinger", MusicStinger.schema)+ , ("party_leader", PartyLeader.schema)+ , ("pickup_new", PickupNew.schema)+ , ("pickup", Pickup.schema)+ , ("player_history_key", PlayerHistoryKey.schema)+ , ("private_match_settings", PrivateMatchSettings.schema)+ , ("q_word", QWord.schema)+ , ("reservation", Reservation.schema)+ , ("rigid_body_state", RigidBodyState.schema)+ , ("stat_event", StatEvent.schema)+ , ("string", String.schema)+ , ("team_paint", TeamPaint.schema)+ , ("title", Title.schema)+ , ("unique_id", UniqueId.schema)+ , ("welded_info", WeldedInfo.schema)+ ]++bitPut :: AttributeValue -> BitPut.BitPut+bitPut value = case value of+ AppliedDamage x -> AppliedDamage.bitPut x+ Boolean x -> Boolean.bitPut x+ Byte x -> Byte.bitPut x+ CamSettings x -> CamSettings.bitPut x+ ClubColors x -> ClubColors.bitPut x+ CustomDemolish x -> CustomDemolish.bitPut x+ DamageState x -> DamageState.bitPut x+ Demolish x -> Demolish.bitPut x+ Enum x -> Enum.bitPut x+ Explosion x -> Explosion.bitPut x+ ExtendedExplosion x -> ExtendedExplosion.bitPut x+ FlaggedInt x -> FlaggedInt.bitPut x+ FlaggedByte x -> FlaggedByte.bitPut x+ Float x -> Float.bitPut x+ GameMode x -> GameMode.bitPut x+ Int x -> Int.bitPut x+ Int64 x -> Int64.putInt64Attribute x+ Loadout x -> Loadout.bitPut x+ LoadoutOnline x -> LoadoutOnline.bitPut x+ Loadouts x -> Loadouts.bitPut x+ LoadoutsOnline x -> LoadoutsOnline.bitPut x+ Location x -> Location.bitPut x+ MusicStinger x -> MusicStinger.bitPut x+ PartyLeader x -> PartyLeader.bitPut x+ Pickup x -> Pickup.bitPut x+ PickupNew x -> PickupNew.bitPut x+ PlayerHistoryKey x -> PlayerHistoryKey.bitPut x+ PrivateMatchSettings x -> PrivateMatchSettings.bitPut x+ QWord x -> QWord.bitPut x+ Reservation x -> Reservation.bitPut x+ RigidBodyState x -> RigidBodyState.bitPut x+ StatEvent x -> StatEvent.bitPut x+ String x -> String.bitPut x+ TeamPaint x -> TeamPaint.bitPut x+ Title x -> Title.bitPut x+ UniqueId x -> UniqueId.bitPut x+ WeldedInfo x -> WeldedInfo.bitPut x++bitGet+ :: Version.Version+ -> Map.Map U32.U32 Str.Str+ -> Str.Str+ -> BitGet.BitGet AttributeValue+bitGet version objectMap name = do+ constructor <- maybe+ (fail ("[RT04] don't know how to get attribute value " <> show name))+ pure+ (Map.lookup (Str.toText name) Data.attributeTypes)+ case constructor of+ AttributeType.AppliedDamage ->+ AppliedDamage <$> AppliedDamage.bitGet version+ AttributeType.Boolean -> Boolean <$> Boolean.bitGet+ AttributeType.Byte -> Byte <$> Byte.bitGet+ AttributeType.CamSettings -> CamSettings <$> CamSettings.bitGet version+ AttributeType.ClubColors -> ClubColors <$> ClubColors.bitGet+ AttributeType.CustomDemolish ->+ CustomDemolish <$> CustomDemolish.bitGet version+ AttributeType.DamageState -> DamageState <$> DamageState.bitGet version+ AttributeType.Demolish -> Demolish <$> Demolish.bitGet version+ AttributeType.Enum -> Enum <$> Enum.bitGet+ AttributeType.Explosion -> Explosion <$> Explosion.bitGet version+ AttributeType.ExtendedExplosion ->+ ExtendedExplosion <$> ExtendedExplosion.bitGet version+ AttributeType.FlaggedInt -> FlaggedInt <$> FlaggedInt.bitGet+ AttributeType.FlaggedByte -> FlaggedByte <$> FlaggedByte.bitGet+ AttributeType.Float -> Float <$> Float.bitGet+ AttributeType.GameMode -> GameMode <$> GameMode.bitGet version+ AttributeType.Int -> Int <$> Int.bitGet+ AttributeType.Int64 -> Int64 <$> Int64.bitGet+ AttributeType.Loadout -> Loadout <$> Loadout.bitGet+ AttributeType.LoadoutOnline ->+ LoadoutOnline <$> LoadoutOnline.bitGet version objectMap+ AttributeType.Loadouts -> Loadouts <$> Loadouts.bitGet+ AttributeType.LoadoutsOnline ->+ LoadoutsOnline <$> LoadoutsOnline.bitGet version objectMap+ AttributeType.Location -> Location <$> Location.bitGet version+ AttributeType.MusicStinger -> MusicStinger <$> MusicStinger.bitGet+ AttributeType.PartyLeader -> PartyLeader <$> PartyLeader.bitGet version+ AttributeType.Pickup -> Pickup <$> Pickup.bitGet+ AttributeType.PickupNew -> PickupNew <$> PickupNew.bitGet+ AttributeType.PlayerHistoryKey ->+ PlayerHistoryKey <$> PlayerHistoryKey.bitGet+ AttributeType.PrivateMatchSettings ->+ PrivateMatchSettings <$> PrivateMatchSettings.bitGet+ AttributeType.QWord -> QWord <$> QWord.bitGet+ AttributeType.Reservation -> Reservation <$> Reservation.bitGet version+ AttributeType.RigidBodyState ->+ RigidBodyState <$> RigidBodyState.bitGet version+ AttributeType.StatEvent -> StatEvent <$> StatEvent.bitGet+ AttributeType.String -> String <$> String.bitGet+ AttributeType.TeamPaint -> TeamPaint <$> TeamPaint.bitGet+ AttributeType.Title -> Title <$> Title.bitGet+ AttributeType.UniqueId -> UniqueId <$> UniqueId.bitGet version+ AttributeType.WeldedInfo -> WeldedInfo <$> WeldedInfo.bitGet version
− src/lib/Rattletrap/Type/BooleanAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/ByteAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Cache.hs view
@@ -1,20 +1,59 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Cache- ( Cache(..)- )-where+module Rattletrap.Type.Cache where -import Rattletrap.Type.AttributeMapping-import Rattletrap.Type.Common-import Rattletrap.Type.List-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.AttributeMapping as AttributeMapping+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json data Cache = Cache- { cacheClassId :: Word32le- , cacheParentCacheId :: Word32le- , cacheCacheId :: Word32le- , cacheAttributeMappings :: List AttributeMapping- } deriving (Eq, Ord, Show)+ { classId :: U32.U32+ , parentCacheId :: U32.U32+ , cacheId :: U32.U32+ , attributeMappings :: List.List AttributeMapping.AttributeMapping+ }+ deriving (Eq, Show) -$(deriveJson ''Cache)+instance Json.FromJSON Cache where+ parseJSON = Json.withObject "Cache" $ \object -> do+ classId <- Json.required object "class_id"+ parentCacheId <- Json.required object "parent_cache_id"+ cacheId <- Json.required object "cache_id"+ attributeMappings <- Json.required object "attribute_mappings"+ pure Cache { classId, parentCacheId, cacheId, attributeMappings }++instance Json.ToJSON Cache where+ toJSON x = Json.object+ [ Json.pair "class_id" $ classId x+ , Json.pair "parent_cache_id" $ parentCacheId x+ , Json.pair "cache_id" $ cacheId x+ , Json.pair "attribute_mappings" $ attributeMappings x+ ]++schema :: Schema.Schema+schema = Schema.named "cache" $ Schema.object+ [ (Json.pair "class_id" $ Schema.ref U32.schema, True)+ , (Json.pair "parent_cache_id" $ Schema.ref U32.schema, True)+ , (Json.pair "cache_id" $ Schema.ref U32.schema, True)+ , ( Json.pair "attribute_mappings" . Schema.json $ List.schema+ AttributeMapping.schema+ , True+ )+ ]++bytePut :: Cache -> BytePut.BytePut+bytePut x =+ U32.bytePut (classId x)+ <> U32.bytePut (parentCacheId x)+ <> U32.bytePut (cacheId x)+ <> List.bytePut AttributeMapping.bytePut (attributeMappings x)++byteGet :: ByteGet.ByteGet Cache+byteGet =+ Cache+ <$> U32.byteGet+ <*> U32.byteGet+ <*> U32.byteGet+ <*> List.byteGet AttributeMapping.byteGet
− src/lib/Rattletrap/Type/CamSettingsAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/ClassAttributeMap.hs view
@@ -8,19 +8,17 @@ , getClassName , getName , getObjectName- , makeClassAttributeMap- )-where+ , make+ ) 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 Rattletrap.Data as Data+import qualified Rattletrap.Type.AttributeMapping as AttributeMapping+import qualified Rattletrap.Type.Cache as Cache+import qualified Rattletrap.Type.ClassMapping as ClassMapping+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32 import qualified Data.IntMap as IntMap import qualified Data.List as List@@ -34,19 +32,20 @@ -- 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'.+-- structure is tedious; see 'make'. data ClassAttributeMap = ClassAttributeMap- { classAttributeMapObjectMap :: Map Word32le Str+ { objectMap :: Map.Map U32.U32 Str.Str -- ^ A map from object IDs to their names.- , classAttributeMapObjectClassMap :: Map Word32le Word32le+ , objectClassMap :: Map.Map U32.U32 U32.U32 -- ^ A map from object IDs to their class IDs.- , classAttributeMapValue :: Map Word32le (Map Word32le Word32le)+ , value :: Map.Map U32.U32 (Map.Map U32.U32 U32.U32) -- ^ A map from class IDs to a map from attribute stream IDs to attribute -- IDs.- , classAttributeMapNameMap :: IntMap.IntMap Str- } deriving (Eq, Ord, Show)+ , nameMap :: IntMap.IntMap Str.Str+ }+ deriving (Eq, Show) -type Bimap l r = (Map l r, Map r l)+type Bimap l r = (Map.Map l r, Map.Map r l) bimap :: (Ord l, Ord r) => [(l, r)] -> Bimap l r bimap xs = (Map.fromList xs, Map.fromList (fmap Tuple.swap xs))@@ -59,26 +58,26 @@ -- | 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'.+make+ :: List.List Str.Str+ -- ^ From 'Rattletrap.Content.objects'.+ -> List.List ClassMapping.ClassMapping+ -- ^ From 'Rattletrap.Content.classMappings'.+ -> List.List Cache.Cache+ -- ^ From 'Rattletrap.Content.caches'.+ -> List.List Str.Str+ -- ^ From 'Rattletrap.Content.names'. -> ClassAttributeMap-makeClassAttributeMap objects classMappings caches names =+make objects classMappings caches names = let- objectMap = makeObjectMap objects+ objectMap_ = makeObjectMap objects classMap = makeClassMap classMappings- objectClassMap = makeObjectClassMap objectMap classMap+ objectClassMap_ = makeObjectClassMap objectMap_ classMap classCache = makeClassCache classMap caches attributeMap = makeAttributeMap caches classIds = fmap (\(_, classId, _, _) -> classId) classCache parentMap = makeParentMap classCache- value = Map.fromList+ value_ = Map.fromList (fmap (\classId -> let@@ -97,21 +96,24 @@ ) classIds )- nameMap = makeNameMap names- in ClassAttributeMap objectMap objectClassMap value nameMap+ nameMap_ = makeNameMap names+ in ClassAttributeMap objectMap_ objectClassMap_ value_ nameMap_ -makeNameMap :: List Str -> IntMap.IntMap Str-makeNameMap names = IntMap.fromDistinctAscList (zip [0 ..] (listValue names))+makeNameMap :: List.List Str.Str -> IntMap.IntMap Str.Str+makeNameMap names =+ IntMap.fromDistinctAscList (zip [0 ..] (List.toList names)) -getName :: IntMap.IntMap Str -> Word32le -> Maybe Str-getName nameMap nameIndex =- IntMap.lookup (fromIntegral (word32leValue nameIndex)) nameMap+getName :: IntMap.IntMap Str.Str -> U32.U32 -> Maybe Str.Str+getName nameMap_ nameIndex =+ IntMap.lookup (fromIntegral (U32.toWord32 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+ :: Map.Map U32.U32 Str.Str+ -> Bimap U32.U32 Str.Str+ -> Map.Map U32.U32 U32.U32+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@@ -123,58 +125,62 @@ Map.fromList pairs getClassId- :: Map Word32le Str -> Bimap Word32le Str -> Word32le -> Maybe Word32le-getClassId objectMap classMap objectId = do- objectName <- getObjectName objectMap objectId+ :: Map.Map U32.U32 Str.Str+ -> Bimap U32.U32 Str.Str+ -> U32.U32+ -> Maybe U32.U32+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)]+ :: Bimap U32.U32 Str.Str+ -> List.List Cache.Cache+ -> [(Maybe Str.Str, U32.U32, U32.U32, U32.U32)] makeClassCache classMap caches = fmap (\cache ->- let classId = cacheClassId cache+ let classId = Cache.classId cache in ( lookupL classId classMap , classId- , cacheCacheId cache- , cacheParentCacheId cache+ , Cache.cacheId cache+ , Cache.parentCacheId cache ) )- (listValue caches)+ (List.toList caches) -makeClassMap :: List ClassMapping -> Bimap Word32le Str+makeClassMap :: List.List ClassMapping.ClassMapping -> Bimap U32.U32 Str.Str makeClassMap classMappings = bimap (fmap (\classMapping ->- (classMappingStreamId classMapping, classMappingName classMapping)+ (ClassMapping.streamId classMapping, ClassMapping.name classMapping) )- (listValue classMappings)+ (List.toList classMappings) ) -makeAttributeMap :: List Cache -> Map Word32le (Map Word32le Word32le)+makeAttributeMap+ :: List.List Cache.Cache -> Map.Map U32.U32 (Map.Map U32.U32 U32.U32) makeAttributeMap caches = Map.fromList (fmap (\cache ->- ( cacheClassId cache+ ( Cache.classId cache , Map.fromList (fmap (\attributeMapping ->- ( attributeMappingStreamId attributeMapping- , attributeMappingObjectId attributeMapping+ ( AttributeMapping.streamId attributeMapping+ , AttributeMapping.objectId attributeMapping ) )- (listValue (cacheAttributeMappings cache))+ (List.toList (Cache.attributeMappings cache)) ) ) )- (listValue caches)+ (List.toList caches) ) makeShallowParentMap- :: [(Maybe Str, Word32le, Word32le, Word32le)] -> Map Word32le Word32le+ :: [(Maybe Str.Str, U32.U32, U32.U32, U32.U32)] -> Map.Map U32.U32 U32.U32 makeShallowParentMap classCache = Map.fromList (Maybe.mapMaybe (\xs -> case xs of@@ -187,7 +193,7 @@ ) makeParentMap- :: [(Maybe Str, Word32le, Word32le, Word32le)] -> Map Word32le [Word32le]+ :: [(Maybe Str.Str, U32.U32, U32.U32, U32.U32)] -> Map.Map U32.U32 [U32.U32] makeParentMap classCache = let shallowParentMap = makeShallowParentMap classCache in@@ -195,7 +201,7 @@ (\classId _ -> getParentClasses shallowParentMap classId) shallowParentMap -getParentClasses :: Map Word32le Word32le -> Word32le -> [Word32le]+getParentClasses :: Map.Map U32.U32 U32.U32 -> U32.U32 -> [U32.U32] getParentClasses shallowParentMap classId = case Map.lookup classId shallowParentMap of Nothing -> []@@ -203,30 +209,32 @@ parentClassId : getParentClasses shallowParentMap parentClassId getParentClass- :: Maybe Str- -> Word32le- -> [(Maybe Str, Word32le, Word32le, Word32le)]- -> Maybe Word32le+ :: Maybe Str.Str+ -> U32.U32+ -> [(Maybe Str.Str, U32.U32, U32.U32, U32.U32)]+ -> Maybe U32.U32 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+ :: U32.U32 -> [(Maybe Str.Str, U32.U32, U32.U32, U32.U32)] -> Maybe U32.U32 getParentClassById parentCacheId xs = case dropWhile (\(_, _, cacheId, _) -> cacheId /= parentCacheId) xs of- [] -> if parentCacheId == Word32le 0+ [] -> if parentCacheId == U32.fromWord32 0 then Nothing- else getParentClassById (Word32le (word32leValue parentCacheId - 1)) xs+ else getParentClassById+ (U32.fromWord32 (U32.toWord32 parentCacheId - 1))+ xs (_, parentClassId, _, _) : _ -> Just parentClassId getParentClassByName- :: Str- -> Word32le- -> [(Maybe Str, Word32le, Word32le, Word32le)]- -> Maybe Word32le+ :: Str.Str+ -> U32.U32+ -> [(Maybe Str.Str, U32.U32, U32.U32, U32.U32)]+ -> Maybe U32.U32 getParentClassByName className parentCacheId xs =- case Map.lookup className parentClasses of+ case Map.lookup (Str.toText className) Data.parentClasses of Nothing -> getParentClassById parentCacheId xs Just parentClassName -> Maybe.maybe (getParentClassById parentCacheId xs)@@ -238,7 +246,7 @@ (\(_, _, cacheId, _) -> cacheId <= parentCacheId) (filter (\(maybeClassName, _, _, _) ->- maybeClassName == Just parentClassName+ fmap Str.toText maybeClassName == Just parentClassName ) xs )@@ -246,79 +254,73 @@ ) ) -parentClasses :: Map Str Str-parentClasses =- Map.map toStr (Map.mapKeys toStr (Map.fromList rawParentClasses))--makeObjectMap :: List Str -> Map Word32le Str+makeObjectMap :: List.List Str.Str -> Map.Map U32.U32 Str.Str makeObjectMap objects =- Map.fromAscList (zip (fmap Word32le [0 ..]) (listValue objects))+ Map.fromAscList (zip (fmap U32.fromWord32 [0 ..]) (List.toList objects)) -getObjectName :: Map Word32le Str -> Word32le -> Maybe Str-getObjectName objectMap objectId = Map.lookup objectId objectMap+getObjectName :: Map.Map U32.U32 Str.Str -> U32.U32 -> Maybe Str.Str+getObjectName objectMap_ objectId = Map.lookup objectId objectMap_ -getClassName :: Str -> Maybe Str+getClassName :: Str.Str -> Maybe Str.Str getClassName rawObjectName =- Map.lookup (normalizeObjectName rawObjectName) objectClasses+ Str.fromText+ <$> Map.lookup+ (Str.toText $ normalizeObjectName rawObjectName)+ Data.objectClasses -normalizeObjectName :: Str -> Str+normalizeObjectName :: Str.Str -> Str.Str normalizeObjectName objectName = let- name = strValue objectName+ name = Str.toText 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+ then Str.fromText crowdActor else if Text.isInfixOf crowdManager name- then Str crowdManager+ then Str.fromText crowdManager else if Text.isInfixOf boostPickup name- then Str boostPickup+ then Str.fromText boostPickup else if Text.isInfixOf mapScoreboard name- then Str mapScoreboard+ then Str.fromText mapScoreboard else if Text.isInfixOf breakout name- then Str breakout+ then Str.fromText 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+classHasLocation :: Str.Str -> Bool+classHasLocation className =+ Set.member (Str.toText className) Data.classesWithLocation -classesWithRotation :: Set.Set Str-classesWithRotation = Set.fromList (fmap toStr rawClassesWithRotation)+classHasRotation :: Str.Str -> Bool+classHasRotation className =+ Set.member (Str.toText className) Data.classesWithRotation -getAttributeIdLimit :: Map Word32le Word32le -> Maybe Word+getAttributeIdLimit :: Map.Map U32.U32 U32.U32 -> Maybe Word getAttributeIdLimit attributeMap = do ((streamId, _), _) <- Map.maxViewWithKey attributeMap- pure (fromIntegral (word32leValue streamId))+ pure (fromIntegral (U32.toWord32 streamId)) getAttributeName- :: ClassAttributeMap -> Map Word32le Word32le -> CompressedWord -> Maybe Str+ :: ClassAttributeMap+ -> Map.Map U32.U32 U32.U32+ -> CompressedWord.CompressedWord+ -> Maybe Str.Str getAttributeName classAttributeMap attributeMap streamId = do- let key = Word32le (fromIntegral (compressedWordValue streamId))+ let key = U32.fromWord32 (fromIntegral (CompressedWord.value streamId)) attributeId <- Map.lookup key attributeMap- let objectMap = classAttributeMapObjectMap classAttributeMap- Map.lookup attributeId objectMap+ let objectMap_ = objectMap classAttributeMap+ Map.lookup attributeId objectMap_ getAttributeMap :: ClassAttributeMap- -> Map CompressedWord Word32le- -> CompressedWord- -> Maybe (Map Word32le Word32le)+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> CompressedWord.CompressedWord+ -> Maybe (Map.Map U32.U32 U32.U32) 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+ let objectClassMap_ = objectClassMap classAttributeMap+ classId <- Map.lookup objectId objectClassMap_+ let value_ = value classAttributeMap+ Map.lookup classId value_
src/lib/Rattletrap/Type/ClassMapping.hs view
@@ -1,17 +1,36 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.ClassMapping- ( ClassMapping(..)- )-where+module Rattletrap.Type.ClassMapping where -import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json data ClassMapping = ClassMapping- { classMappingName :: Str- , classMappingStreamId :: Word32le- } deriving (Eq, Ord, Show)+ { name :: Str.Str+ , streamId :: U32.U32+ }+ deriving (Eq, Show) -$(deriveJson ''ClassMapping)+instance Json.FromJSON ClassMapping where+ parseJSON = Json.withObject "ClassMapping" $ \object -> do+ name <- Json.required object "name"+ streamId <- Json.required object "stream_id"+ pure ClassMapping { name, streamId }++instance Json.ToJSON ClassMapping where+ toJSON x =+ Json.object [Json.pair "name" $ name x, Json.pair "stream_id" $ streamId x]++schema :: Schema.Schema+schema = Schema.named "classMapping" $ Schema.object+ [ (Json.pair "name" $ Schema.ref Str.schema, True)+ , (Json.pair "stream_id" $ Schema.ref U32.schema, True)+ ]++bytePut :: ClassMapping -> BytePut.BytePut+bytePut x = Str.bytePut (name x) <> U32.bytePut (streamId x)++byteGet :: ByteGet.ByteGet ClassMapping+byteGet = ClassMapping <$> Str.byteGet <*> U32.byteGet
− src/lib/Rattletrap/Type/ClubColorsAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/Common.hs
@@ -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
src/lib/Rattletrap/Type/CompressedWord.hs view
@@ -1,17 +1,86 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.CompressedWord where -module Rattletrap.Type.CompressedWord- ( CompressedWord(..)- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json -import Rattletrap.Type.Common+import qualified Data.Bits as Bits -- | 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)+ { limit :: Word+ , value :: Word+ }+ deriving (Eq, Ord, Show) -$(deriveJson ''CompressedWord)+instance Json.FromJSON CompressedWord where+ parseJSON = Json.withObject "CompressedWord" $ \object -> do+ limit <- Json.required object "limit"+ value <- Json.required object "value"+ pure CompressedWord { limit, value }++instance Json.ToJSON CompressedWord where+ toJSON x =+ Json.object [Json.pair "limit" $ limit x, Json.pair "value" $ value x]++schema :: Schema.Schema+schema = Schema.named "compressedWord" $ Schema.object+ [ (Json.pair "limit" $ Json.object [Json.pair "type" "integer"], True)+ , (Json.pair "value" $ Json.object [Json.pair "type" "integer"], True)+ ]++bitPut :: CompressedWord -> BitPut.BitPut+bitPut compressedWord =+ let+ limit_ = limit compressedWord+ value_ = value compressedWord+ maxBits = getMaxBits limit_+ in putCompressedWordStep limit_ value_ maxBits 0 0++putCompressedWordStep :: Word -> Word -> Int -> Int -> Word -> BitPut.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 mempty+ else+ let+ bit = Bits.testBit value_ position+ delta = if bit then x else 0+ in BitPut.bool bit <> putCompressedWordStep+ limit_+ value_+ maxBits+ (position + 1)+ (soFar + delta)+ else mempty++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++bitGet :: Word -> BitGet.BitGet CompressedWord+bitGet 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 -> BitGet.BitGet Word+step limit_ maxBits position value_ = do+ let x = Bits.shiftL 1 (fromIntegral position) :: Word+ if position < maxBits && value_ + x <= limit_+ then do+ bit <- BitGet.bool+ let newValue = if bit then value_ + x else value_+ step limit_ maxBits (position + 1) newValue+ else pure value_
src/lib/Rattletrap/Type/CompressedWordVector.hs view
@@ -1,17 +1,48 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.CompressedWordVector- ( CompressedWordVector(..)- )-where+module Rattletrap.Type.CompressedWordVector where -import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Utility.Json as Json data CompressedWordVector = CompressedWordVector- { compressedWordVectorX :: CompressedWord- , compressedWordVectorY :: CompressedWord- , compressedWordVectorZ :: CompressedWord- } deriving (Eq, Ord, Show)+ { x :: CompressedWord.CompressedWord+ , y :: CompressedWord.CompressedWord+ , z :: CompressedWord.CompressedWord+ }+ deriving (Eq, Show) -$(deriveJson ''CompressedWordVector)+instance Json.FromJSON CompressedWordVector where+ parseJSON = Json.withObject "CompressedWordVector" $ \object -> do+ x <- Json.required object "x"+ y <- Json.required object "y"+ z <- Json.required object "z"+ pure CompressedWordVector { x, y, z }++instance Json.ToJSON CompressedWordVector where+ toJSON a =+ Json.object [Json.pair "x" $ x a, Json.pair "y" $ y a, Json.pair "z" $ z a]++schema :: Schema.Schema+schema = Schema.named "compressed-word-vector" $ Schema.object+ [ (Json.pair "x" $ Schema.ref CompressedWord.schema, True)+ , (Json.pair "y" $ Schema.ref CompressedWord.schema, True)+ , (Json.pair "z" $ Schema.ref CompressedWord.schema, True)+ ]++bitPut :: CompressedWordVector -> BitPut.BitPut+bitPut compressedWordVector =+ CompressedWord.bitPut (x compressedWordVector)+ <> CompressedWord.bitPut (y compressedWordVector)+ <> CompressedWord.bitPut (z compressedWordVector)++bitGet :: BitGet.BitGet CompressedWordVector+bitGet =+ CompressedWordVector+ <$> CompressedWord.bitGet limit+ <*> CompressedWord.bitGet limit+ <*> CompressedWord.bitGet limit++limit :: Word+limit = 65536
src/lib/Rattletrap/Type/Content.hs view
@@ -1,71 +1,230 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.Content where -module Rattletrap.Type.Content- ( Content(..)- , defaultContent- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Cache as Cache+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.ClassMapping as ClassMapping+import qualified Rattletrap.Type.Frame as Frame+import qualified Rattletrap.Type.KeyFrame as KeyFrame+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Mark as Mark+import qualified Rattletrap.Type.Message as Message+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import Rattletrap.Utility.Bytes+import qualified Rattletrap.Utility.Json as Json -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+import qualified Control.Monad.Trans.State as State+import qualified Data.ByteString as Bytes+import qualified Data.ByteString.Lazy as LazyBytes+import qualified Data.Word as Word +type Content = ContentWith (List.List Frame.Frame)+ -- | Contains low-level game data about a 'Rattletrap.Replay.Replay'.-data Content = Content- { contentLevels :: List Str+data ContentWith frames = Content+ { levels :: List.List Str.Str -- ^ This typically only has one element, like @stadium_oob_audio_map@.- , contentKeyFrames :: List KeyFrame+ , keyFrames :: List.List KeyFrame.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+ , streamSize :: U32.U32 -- ^ 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]+ , frames :: frames -- ^ The actual game data. This is where all the interesting information is.- , contentMessages :: List Message+ , messages :: List.List Message.Message -- ^ Debugging messages. In newer replays, this is always empty.- , contentMarks :: List Mark+ , marks :: List.List Mark.Mark -- ^ Tick marks shown on the scrubber when watching a replay.- , contentPackages :: List Str+ , packages :: List.List Str.Str -- ^ A list of @.upk@ files to load, like -- @..\\..\\TAGame\\CookedPCConsole\\Stadium_P.upk@.- , contentObjects :: List Str+ , objects :: List.List Str.Str -- ^ Objects in the stream. Used for the -- 'Rattletrap.Type.ClassAttributeMap.ClassAttributeMap'.- , contentNames :: List Str+ , names :: List.List Str.Str -- ^ It's not clear what these are used for. This list is usually not empty, -- but appears unused otherwise.- , contentClassMappings :: List ClassMapping+ , classMappings :: List.List ClassMapping.ClassMapping -- ^ A mapping between classes and their ID in the stream. Used for the -- 'Rattletrap.Type.ClassAttributeMap.ClassAttributeMap'.- , contentCaches :: List Cache+ , caches :: List.List Cache.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)+ , unknown :: [Word.Word8]+ }+ deriving (Eq, Show) -$(deriveJson ''Content)+instance Json.FromJSON frames => Json.FromJSON (ContentWith frames) where+ parseJSON = Json.withObject "Content" $ \object -> do+ levels <- Json.required object "levels"+ keyFrames <- Json.required object "key_frames"+ streamSize <- Json.required object "stream_size"+ frames <- Json.required object "frames"+ messages <- Json.required object "messages"+ marks <- Json.required object "marks"+ packages <- Json.required object "packages"+ objects <- Json.required object "objects"+ names <- Json.required object "names"+ classMappings <- Json.required object "class_mappings"+ caches <- Json.required object "caches"+ unknown <- Json.required object "unknown"+ pure Content+ { levels+ , keyFrames+ , streamSize+ , frames+ , messages+ , marks+ , packages+ , objects+ , names+ , classMappings+ , caches+ , unknown+ } -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 = []+instance Json.ToJSON frames => Json.ToJSON (ContentWith frames) where+ toJSON x = Json.object+ [ Json.pair "levels" $ levels x+ , Json.pair "key_frames" $ keyFrames x+ , Json.pair "stream_size" $ streamSize x+ , Json.pair "frames" $ frames x+ , Json.pair "messages" $ messages x+ , Json.pair "marks" $ marks x+ , Json.pair "packages" $ packages x+ , Json.pair "objects" $ objects x+ , Json.pair "names" $ names x+ , Json.pair "class_mappings" $ classMappings x+ , Json.pair "caches" $ caches x+ , Json.pair "unknown" $ unknown x+ ]++schema :: Schema.Schema -> Schema.Schema+schema s = Schema.named "content" $ Schema.object+ [ (Json.pair "levels" . Schema.json $ List.schema Str.schema, True)+ , (Json.pair "key_frames" . Schema.json $ List.schema KeyFrame.schema, True)+ , (Json.pair "stream_size" $ Schema.ref U32.schema, True)+ , (Json.pair "frames" $ Schema.json s, True)+ , (Json.pair "messages" . Schema.json $ List.schema Message.schema, True)+ , (Json.pair "marks" . Schema.json $ List.schema Mark.schema, True)+ , (Json.pair "packages" . Schema.json $ List.schema Str.schema, True)+ , (Json.pair "objects" . Schema.json $ List.schema Str.schema, True)+ , (Json.pair "names" . Schema.json $ List.schema Str.schema, True)+ , ( Json.pair "class_mappings" . Schema.json $ List.schema+ ClassMapping.schema+ , True+ )+ , (Json.pair "caches" . Schema.json $ List.schema Cache.schema, True)+ , (Json.pair "unknown" . Schema.json $ Schema.array U8.schema, True)+ ]++empty :: Content+empty = Content+ { levels = List.empty+ , keyFrames = List.empty+ , streamSize = U32.fromWord32 0+ , frames = List.empty+ , messages = List.empty+ , marks = List.empty+ , packages = List.empty+ , objects = List.empty+ , names = List.empty+ , classMappings = List.empty+ , caches = List.empty+ , unknown = [] }++bytePut :: Content -> BytePut.BytePut+bytePut x =+ List.bytePut Str.bytePut (levels x)+ <> List.bytePut KeyFrame.bytePut (keyFrames x)+ <> putFrames x+ <> List.bytePut Message.bytePut (messages x)+ <> List.bytePut Mark.bytePut (marks x)+ <> List.bytePut Str.bytePut (packages x)+ <> List.bytePut Str.bytePut (objects x)+ <> List.bytePut Str.bytePut (names x)+ <> List.bytePut ClassMapping.bytePut (classMappings x)+ <> List.bytePut Cache.bytePut (caches x)+ <> foldMap BytePut.word8 (unknown x)++putFrames :: Content -> BytePut.BytePut+putFrames x =+ let+ stream =+ BytePut.toByteString . BitPut.toBytePut . Frame.putFrames $ frames x+ -- This is a little strange. When parsing a binary replay, the stream size+ -- is given before the stream itself. When generating the JSON, the stream+ -- size is included. That allows a bit-for-bit identical binary replay to+ -- be generated from the JSON. However if you modify the JSON before+ -- converting it back into binary, the stream size might be different.+ --+ -- If it was possible to know how much padding the stream required without+ -- carrying it along as extra data on the side, this logic could go away.+ -- Unforunately that isn't currently known. See this issue for details:+ -- <https://github.com/tfausak/rattletrap/issues/171>.+ expectedStreamSize = streamSize x+ actualStreamSize = U32.fromWord32 . fromIntegral $ Bytes.length stream+ streamSize_ = U32.fromWord32+ $ max (U32.toWord32 expectedStreamSize) (U32.toWord32 actualStreamSize)+ in U32.bytePut streamSize_ <> BytePut.byteString+ (reverseBytes (padBytes (U32.toWord32 streamSize_) stream))++byteGet+ :: Version.Version+ -- ^ 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'.+ -> ByteGet.ByteGet Content+byteGet version numFrames maxChannels = do+ (levels_, keyFrames_, streamSize_) <-+ (,,)+ <$> List.byteGet Str.byteGet+ <*> List.byteGet KeyFrame.byteGet+ <*> U32.byteGet+ (stream, messages_, marks_, packages_, objects_, names_, classMappings_, caches_) <-+ (,,,,,,,)+ <$> ByteGet.byteString (fromIntegral (U32.toWord32 streamSize_))+ <*> List.byteGet Message.byteGet+ <*> List.byteGet Mark.byteGet+ <*> List.byteGet Str.byteGet+ <*> List.byteGet Str.byteGet+ <*> List.byteGet Str.byteGet+ <*> List.byteGet ClassMapping.byteGet+ <*> List.byteGet Cache.byteGet+ let+ classAttributeMap =+ ClassAttributeMap.make objects_ classMappings_ caches_ names_+ bitGet = State.evalStateT+ (Frame.decodeFramesBits version numFrames maxChannels classAttributeMap)+ mempty+ frames_ <-+ either fail pure . ByteGet.run (BitGet.toByteGet bitGet) $ reverseBytes+ stream+ Content+ levels_+ keyFrames_+ streamSize_+ frames_+ messages_+ marks_+ packages_+ objects_+ names_+ classMappings_+ caches_+ . LazyBytes.unpack+ <$> ByteGet.remaining
− src/lib/Rattletrap/Type/CustomDemolishAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/DamageStateAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/DemolishAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/DestroyedReplication.hs
@@ -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)
src/lib/Rattletrap/Type/Dictionary.hs view
@@ -1,69 +1,93 @@-module Rattletrap.Type.Dictionary- ( Dictionary(..)- , dictionaryLookup- )-where+module Rattletrap.Type.Dictionary where -import Rattletrap.Type.Common-import Rattletrap.Type.Str+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Utility.Json as Json -import qualified Control.Monad as Monad-import qualified Data.Aeson as Json-import qualified Data.Aeson.Types as Json+import qualified Data.Bifunctor as Bifunctor 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)+data Dictionary a = Dictionary+ { elements :: List.List (Str.Str, a)+ , lastKey :: Str.Str+ }+ deriving (Eq, 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)- )+ parseJSON = Json.withObject "Dictionary" $ \o -> do+ keys <- Json.required o "keys"+ lastKey_ <- Json.required o "last_key"+ value <- Json.required o "value"+ let+ build+ :: MonadFail m+ => Map.Map Text.Text a+ -> Int+ -> [(Int, (Str.Str, a))]+ -> [Text.Text]+ -> m (List.List (Str.Str, a))+ build m i xs ks = case ks of+ [] -> pure . List.fromList . reverse $ fmap snd xs+ k : t -> case Map.lookup k m of+ Nothing -> fail $ "missing required key " <> show k+ Just v -> build m (i + 1) ((i, (Str.fromText k, v)) : xs) t+ elements_ <- build value 0 [] keys+ pure Dictionary { elements = elements_, lastKey = lastKey_ } 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)+ toJSON x = Json.object+ [ Json.pair "keys" . fmap fst . List.toList $ elements x+ , Json.pair "last_key" $ lastKey x+ , Json.pair "value"+ . Map.fromList+ . fmap (Bifunctor.first Str.toText)+ . List.toList+ $ elements x ] -dictionaryKeys :: Dictionary a -> [Str]-dictionaryKeys = fmap fst . toList--dictionaryLastKey :: Dictionary a -> Str-dictionaryLastKey x = case x of- DictionaryElement _ _ y -> dictionaryLastKey y- DictionaryEnd y -> y+schema :: Schema.Schema -> Schema.Schema+schema s =+ Schema.named ("dictionary-" <> Text.unpack (Schema.name s)) $ Schema.object+ [ (Json.pair "keys" . Schema.json $ Schema.array Str.schema, True)+ , (Json.pair "last_key" $ Schema.ref Str.schema, True)+ , ( Json.pair "value" $ Json.object+ [ Json.pair "type" "object"+ , Json.pair "additionalProperties" $ Schema.ref s+ ]+ , True+ )+ ] -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+lookup :: Str.Str -> Dictionary a -> Maybe a+lookup k = Prelude.lookup k . List.toList . elements -dictionaryValue :: Dictionary a -> Map Text a-dictionaryValue = Map.mapKeys strValue . Map.fromList . toList+bytePut :: (a -> BytePut.BytePut) -> Dictionary a -> BytePut.BytePut+bytePut f x =+ foldMap (\(k, v) -> Str.bytePut k <> f v) (List.toList $ elements x)+ <> Str.bytePut (lastKey x) -get :: Json.FromJSON a => Json.Object -> String -> Json.Parser a-get o k = o Json..: Text.pack k+byteGet :: ByteGet.ByteGet a -> ByteGet.ByteGet (Dictionary a)+byteGet = byteGetWith 0 [] -pair :: Json.ToJSON a => String -> a -> (Text, Json.Value)-pair k v = (Text.pack k, Json.toJSON v)+byteGetWith+ :: Int+ -> [(Int, (Str.Str, a))]+ -> ByteGet.ByteGet a+ -> ByteGet.ByteGet (Dictionary a)+byteGetWith i xs f = do+ k <- Str.byteGet+ if isNone k+ then pure Dictionary+ { elements = List.fromList . reverse $ fmap snd xs+ , lastKey = k+ }+ else do+ v <- f+ byteGetWith (i + 1) ((i, (k, v)) : xs) f -toList :: Dictionary a -> [(Str, a)]-toList x = case x of- DictionaryElement k v y -> (k, v) : toList y- DictionaryEnd _ -> []+isNone :: Str.Str -> Bool+isNone = (== Text.pack "None") . Text.filter (/= '\x00') . Str.toText
− src/lib/Rattletrap/Type/EnumAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/ExplosionAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/ExtendedExplosionAttribute.hs
@@ -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)
+ src/lib/Rattletrap/Type/F32.hs view
@@ -0,0 +1,39 @@+module Rattletrap.Type.F32 where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype F32+ = F32 Float+ deriving (Eq, Show)++instance Json.FromJSON F32 where+ parseJSON = fmap fromFloat . Json.parseJSON++instance Json.ToJSON F32 where+ toJSON = Json.toJSON . toFloat++schema :: Schema.Schema+schema = Schema.named "f32" $ Json.object [Json.pair "type" "number"]++fromFloat :: Float -> F32+fromFloat = F32++toFloat :: F32 -> Float+toFloat (F32 x) = x++bytePut :: F32 -> BytePut.BytePut+bytePut = BytePut.float . toFloat++bitPut :: F32 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet F32+byteGet = fromFloat <$> ByteGet.float++bitGet :: BitGet.BitGet F32+bitGet = BitGet.fromByteGet byteGet 4
− src/lib/Rattletrap/Type/FlaggedByteAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/FlaggedIntAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/Float32le.hs
@@ -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)
− src/lib/Rattletrap/Type/FloatAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Frame.hs view
@@ -1,21 +1,85 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.Frame where -module Rattletrap.Type.Frame- ( Frame(..)- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Replication as Replication+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json -import Rattletrap.Type.Common-import Rattletrap.Type.Float32le-import Rattletrap.Type.Replication+import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map data Frame = Frame- { frameTime :: Float32le+ { time :: F32.F32 -- ^ Time in seconds since the beginning of the match.- , frameDelta :: Float32le+ , delta :: F32.F32 -- ^ Time in seconds since the last frame. Usually about 0.03 since there -- are 30 frames per second.- , frameReplications :: [Replication]- } deriving (Eq, Ord, Show)+ , replications :: List.List Replication.Replication+ }+ deriving (Eq, Show) -$(deriveJson ''Frame)+instance Json.FromJSON Frame where+ parseJSON = Json.withObject "Frame" $ \object -> do+ time <- Json.required object "time"+ delta <- Json.required object "delta"+ replications <- Json.required object "replications"+ pure Frame { time, delta, replications }++instance Json.ToJSON Frame where+ toJSON x = Json.object+ [ Json.pair "time" $ time x+ , Json.pair "delta" $ delta x+ , Json.pair "replications" $ replications x+ ]++schema :: Schema.Schema+schema = Schema.named "frame" $ Schema.object+ [ (Json.pair "time" $ Schema.ref F32.schema, True)+ , (Json.pair "delta" $ Schema.ref F32.schema, True)+ , ( Json.pair "replications" . Schema.json $ List.schema Replication.schema+ , True+ )+ ]++putFrames :: List.List Frame -> BitPut.BitPut+putFrames = foldMap bitPut . List.toList++bitPut :: Frame -> BitPut.BitPut+bitPut frame =+ F32.bitPut (time frame)+ <> F32.bitPut (delta frame)+ <> Replication.putReplications (replications frame)++decodeFramesBits+ :: Version.Version+ -> Int+ -> Word+ -> ClassAttributeMap.ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord.CompressedWord U32.U32)+ BitGet.BitGet+ (List.List Frame)+decodeFramesBits version count limit classes =+ List.replicateM count $ bitGet version limit classes++bitGet+ :: Version.Version+ -> Word+ -> ClassAttributeMap.ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord.CompressedWord U32.U32)+ BitGet.BitGet+ Frame+bitGet version limit classes =+ Frame+ <$> Trans.lift F32.bitGet+ <*> Trans.lift F32.bitGet+ <*> Replication.decodeReplicationsBits version limit classes
− src/lib/Rattletrap/Type/GameModeAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Header.hs view
@@ -1,27 +1,26 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Header- ( Header(..)- )-where+module Rattletrap.Type.Header where -import Rattletrap.Type.Common-import Rattletrap.Type.Dictionary-import Rattletrap.Type.Property-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Dictionary as Dictionary+import qualified Rattletrap.Type.Property as Property+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad -- | Contains high-level metadata about a 'Rattletrap.Replay.Replay'. data Header = Header- { headerEngineVersion :: Word32le+ { engineVersion :: U32.U32 -- ^ The "major" ("engine") version number.- , headerLicenseeVersion :: Word32le+ , licenseeVersion :: U32.U32 -- ^ The "minor" ("licensee") version number.- , headerPatchVersion :: Maybe Word32le+ , patchVersion :: Maybe U32.U32 -- ^ The "patch" ("net") version number.- , headerLabel :: Str+ , label :: Str.Str -- ^ Always @TAGame.Replay_Soccar_TA@.- , headerProperties :: Dictionary Property+ , properties :: Dictionary.Dictionary Property.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: --@@ -56,6 +55,58 @@ -- 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)+ }+ deriving (Eq, Show) -$(deriveJson ''Header)+instance Json.FromJSON Header where+ parseJSON = Json.withObject "Header" $ \object -> do+ engineVersion <- Json.required object "engine_version"+ licenseeVersion <- Json.required object "licensee_version"+ patchVersion <- Json.optional object "patch_version"+ label <- Json.required object "label"+ properties <- Json.required object "properties"+ pure Header+ { engineVersion+ , licenseeVersion+ , patchVersion+ , label+ , properties+ }++instance Json.ToJSON Header where+ toJSON x = Json.object+ [ Json.pair "engine_version" $ engineVersion x+ , Json.pair "licensee_version" $ licenseeVersion x+ , Json.pair "patch_version" $ patchVersion x+ , Json.pair "label" $ label x+ , Json.pair "properties" $ properties x+ ]++schema :: Schema.Schema+schema = Schema.named "header" $ Schema.object+ [ (Json.pair "engine_version" $ Schema.ref U32.schema, True)+ , (Json.pair "licensee_version" $ Schema.ref U32.schema, True)+ , (Json.pair "patch_version" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "label" $ Schema.ref Str.schema, True)+ , ( Json.pair "properties" . Schema.json $ Dictionary.schema Property.schema+ , True+ )+ ]++bytePut :: Header -> BytePut.BytePut+bytePut x =+ U32.bytePut (engineVersion x)+ <> U32.bytePut (licenseeVersion x)+ <> foldMap U32.bytePut (patchVersion x)+ <> Str.bytePut (label x)+ <> Dictionary.bytePut Property.bytePut (properties x)++byteGet :: ByteGet.ByteGet Header+byteGet = do+ (major, minor) <- (,) <$> U32.byteGet <*> U32.byteGet+ Header major minor+ <$> whenMaybe+ (U32.toWord32 major >= 868 && U32.toWord32 minor >= 18)+ U32.byteGet+ <*> Str.byteGet+ <*> Dictionary.byteGet Property.byteGet
+ src/lib/Rattletrap/Type/I32.hs view
@@ -0,0 +1,44 @@+module Rattletrap.Type.I32 where++import qualified Data.Int as Int+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype I32+ = I32 Int.Int32+ deriving (Eq, Show)++instance Json.FromJSON I32 where+ parseJSON = fmap fromInt32 . Json.parseJSON++instance Json.ToJSON I32 where+ toJSON = Json.toJSON . toInt32++schema :: Schema.Schema+schema = Schema.named "i32" $ Json.object+ [ Json.pair "type" "integer"+ , Json.pair "minimum" (minBound :: Int.Int32)+ , Json.pair "maximum" (maxBound :: Int.Int32)+ ]++fromInt32 :: Int.Int32 -> I32+fromInt32 = I32++toInt32 :: I32 -> Int.Int32+toInt32 (I32 x) = x++bytePut :: I32 -> BytePut.BytePut+bytePut = BytePut.int32 . toInt32++bitPut :: I32 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet I32+byteGet = fromInt32 <$> ByteGet.int32++bitGet :: BitGet.BitGet I32+bitGet = BitGet.fromByteGet byteGet 4
+ src/lib/Rattletrap/Type/I64.hs view
@@ -0,0 +1,48 @@+module Rattletrap.Type.I64 where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++import qualified Data.Int as Int+import qualified Data.Text as Text+import qualified Text.Read as Read++newtype I64+ = I64 Int.Int64+ deriving (Eq, Show)++instance Json.FromJSON I64 where+ parseJSON =+ Json.withText "I64"+ $ either fail (pure . fromInt64)+ . Read.readEither+ . Text.unpack++instance Json.ToJSON I64 where+ toJSON = Json.toJSON . show . toInt64++schema :: Schema.Schema+schema = Schema.named "i64"+ $ Json.object [Json.pair "type" "string", Json.pair "pattern" "^-?[0-9]+$"]++fromInt64 :: Int.Int64 -> I64+fromInt64 = I64++toInt64 :: I64 -> Int.Int64+toInt64 (I64 x) = x++bytePut :: I64 -> BytePut.BytePut+bytePut = BytePut.int64 . toInt64++bitPut :: I64 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet I64+byteGet = fromInt64 <$> ByteGet.int64++bitGet :: BitGet.BitGet I64+bitGet = BitGet.fromByteGet byteGet 8
+ src/lib/Rattletrap/Type/I8.hs view
@@ -0,0 +1,44 @@+module Rattletrap.Type.I8 where++import qualified Data.Int as Int+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype I8+ = I8 Int.Int8+ deriving (Eq, Show)++instance Json.FromJSON I8 where+ parseJSON = fmap fromInt8 . Json.parseJSON++instance Json.ToJSON I8 where+ toJSON = Json.toJSON . toInt8++schema :: Schema.Schema+schema = Schema.named "i8" $ Json.object+ [ Json.pair "type" "integer"+ , Json.pair "minimum" (minBound :: Int.Int8)+ , Json.pair "maximum" (maxBound :: Int.Int8)+ ]++fromInt8 :: Int.Int8 -> I8+fromInt8 = I8++toInt8 :: I8 -> Int.Int8+toInt8 (I8 x) = x++bytePut :: I8 -> BytePut.BytePut+bytePut = BytePut.int8 . toInt8++bitPut :: I8 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet I8+byteGet = fromInt8 <$> ByteGet.int8++bitGet :: BitGet.BitGet I8+bitGet = BitGet.fromByteGet byteGet 1
src/lib/Rattletrap/Type/Initialization.hs view
@@ -1,21 +1,49 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Initialization- ( Initialization(..)- )-where+module Rattletrap.Type.Initialization where -import Rattletrap.Type.Common-import Rattletrap.Type.Int8Vector-import Rattletrap.Type.Vector+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Int8Vector as Int8Vector+import qualified Rattletrap.Type.Vector as Vector+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad data Initialization = Initialization- { initializationLocation :: Maybe Vector+ { location :: Maybe Vector.Vector -- ^ Not every class has an initial location. See- -- 'Rattletrap.Data.rawClassesWithLocation'.- , initializationRotation :: Maybe Int8Vector+ -- 'Rattletrap.Data.classesWithLocation'.+ , rotation :: Maybe Int8Vector.Int8Vector -- ^ Only classes with location can have rotation, but not every one does.- -- See 'Rattletrap.Data.rawClassesWithRotation'.- } deriving (Eq, Ord, Show)+ -- See 'Rattletrap.Data.classesWithRotation'.+ }+ deriving (Eq, Show) -$(deriveJson ''Initialization)+instance Json.FromJSON Initialization where+ parseJSON = Json.withObject "Initialization" $ \object -> do+ location <- Json.optional object "location"+ rotation <- Json.optional object "rotation"+ pure Initialization { location, rotation }++instance Json.ToJSON Initialization where+ toJSON x = Json.object+ [Json.pair "location" $ location x, Json.pair "rotation" $ rotation x]++schema :: Schema.Schema+schema = Schema.named "initialization" $ Schema.object+ [ (Json.pair "location" . Schema.json $ Schema.maybe Vector.schema, False)+ , ( Json.pair "rotation" . Schema.json $ Schema.maybe Int8Vector.schema+ , False+ )+ ]++bitPut :: Initialization -> BitPut.BitPut+bitPut initialization =+ foldMap Vector.bitPut (location initialization)+ <> foldMap Int8Vector.bitPut (rotation initialization)++bitGet :: Version.Version -> Bool -> Bool -> BitGet.BitGet Initialization+bitGet version hasLocation hasRotation =+ Initialization+ <$> whenMaybe hasLocation (Vector.bitGet version)+ <*> whenMaybe hasRotation Int8Vector.bitGet
− src/lib/Rattletrap/Type/Int32le.hs
@@ -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)
− src/lib/Rattletrap/Type/Int64Attribute.hs
@@ -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)
− src/lib/Rattletrap/Type/Int64le.hs
@@ -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
src/lib/Rattletrap/Type/Int8Vector.hs view
@@ -1,17 +1,53 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Int8Vector- ( Int8Vector(..)- )-where+module Rattletrap.Type.Int8Vector where -import Rattletrap.Type.Common-import Rattletrap.Type.Int8le+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I8 as I8+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad data Int8Vector = Int8Vector- { int8VectorX :: Maybe Int8le- , int8VectorY :: Maybe Int8le- , int8VectorZ :: Maybe Int8le- } deriving (Eq, Ord, Show)+ { x :: Maybe I8.I8+ , y :: Maybe I8.I8+ , z :: Maybe I8.I8+ }+ deriving (Eq, Show) -$(deriveJson ''Int8Vector)+instance Json.FromJSON Int8Vector where+ parseJSON = Json.withObject "Int8Vector" $ \object -> do+ x <- Json.optional object "x"+ y <- Json.optional object "y"+ z <- Json.optional object "z"+ pure Int8Vector { x, y, z }++instance Json.ToJSON Int8Vector where+ toJSON a =+ Json.object [Json.pair "x" $ x a, Json.pair "y" $ y a, Json.pair "z" $ z a]++schema :: Schema.Schema+schema = Schema.named "int8Vector" $ Schema.object+ [ (Json.pair "x" . Schema.json $ Schema.maybe I8.schema, False)+ , (Json.pair "y" . Schema.json $ Schema.maybe I8.schema, False)+ , (Json.pair "z" . Schema.json $ Schema.maybe I8.schema, False)+ ]++bitPut :: Int8Vector -> BitPut.BitPut+bitPut int8Vector =+ putInt8VectorField (x int8Vector)+ <> putInt8VectorField (y int8Vector)+ <> putInt8VectorField (z int8Vector)++putInt8VectorField :: Maybe I8.I8 -> BitPut.BitPut+putInt8VectorField maybeField = case maybeField of+ Nothing -> BitPut.bool False+ Just field -> BitPut.bool True <> I8.bitPut field++bitGet :: BitGet.BitGet Int8Vector+bitGet =+ Int8Vector <$> decodeFieldBits <*> decodeFieldBits <*> decodeFieldBits++decodeFieldBits :: BitGet.BitGet (Maybe I8.I8)+decodeFieldBits = do+ hasField <- BitGet.bool+ whenMaybe hasField I8.bitGet
− src/lib/Rattletrap/Type/Int8le.hs
@@ -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)
− src/lib/Rattletrap/Type/IntAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/KeyFrame.hs view
@@ -1,21 +1,46 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.KeyFrame- ( KeyFrame(..)- )-where+module Rattletrap.Type.KeyFrame where -import Rattletrap.Type.Common-import Rattletrap.Type.Float32le-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json data KeyFrame = KeyFrame- { keyFrameTime :: Float32le+ { time :: F32.F32 -- ^ When this key frame occurs, in seconds.- , keyFrameFrame :: Word32le+ , frame :: U32.U32 -- ^ The frame number of this key frame, starting from 0.- , keyFramePosition :: Word32le+ , position :: U32.U32 -- ^ The bit position of this key frame in the stream.- } deriving (Eq, Ord, Show)+ }+ deriving (Eq, Show) -$(deriveJson ''KeyFrame)+instance Json.FromJSON KeyFrame where+ parseJSON = Json.withObject "KeyFrame" $ \object -> do+ time <- Json.required object "time"+ frame <- Json.required object "frame"+ position <- Json.required object "position"+ pure KeyFrame { time, frame, position }++instance Json.ToJSON KeyFrame where+ toJSON x = Json.object+ [ Json.pair "time" $ time x+ , Json.pair "frame" $ frame x+ , Json.pair "position" $ position x+ ]++schema :: Schema.Schema+schema = Schema.named "keyFrame" $ Schema.object+ [ (Json.pair "time" $ Schema.ref F32.schema, True)+ , (Json.pair "frame" $ Schema.ref U32.schema, True)+ , (Json.pair "position" $ Schema.ref U32.schema, True)+ ]++bytePut :: KeyFrame -> BytePut.BytePut+bytePut x =+ F32.bytePut (time x) <> U32.bytePut (frame x) <> U32.bytePut (position x)++byteGet :: ByteGet.ByteGet KeyFrame+byteGet = KeyFrame <$> F32.byteGet <*> U32.byteGet <*> U32.byteGet
src/lib/Rattletrap/Type/List.hs view
@@ -1,14 +1,54 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.List where -module Rattletrap.Type.List- ( List(..)- )-where+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json -import Rattletrap.Type.Common+import qualified Control.Monad as Monad -newtype List a = List- { listValue :: [a]- } deriving (Eq, Ord, Show)+newtype List a+ = List [a]+ deriving (Eq, Show) -$(deriveJson ''List)+instance Json.FromJSON a => Json.FromJSON (List a) where+ parseJSON = fmap fromList . Json.parseJSON++instance Json.ToJSON a => Json.ToJSON (List a) where+ toJSON = Json.toJSON . toList++schema :: Schema.Schema -> Schema.Schema+schema = Schema.array++fromList :: [a] -> List a+fromList = List++empty :: List a+empty = fromList []++toList :: List a -> [a]+toList (List x) = x++bytePut :: (a -> BytePut.BytePut) -> List a -> BytePut.BytePut+bytePut f x =+ let v = toList x+ in (U32.bytePut . U32.fromWord32 . fromIntegral $ length v) <> foldMap f v++byteGet :: ByteGet.ByteGet a -> ByteGet.ByteGet (List a)+byteGet f = do+ size <- U32.byteGet+ replicateM (fromIntegral $ U32.toWord32 size) f++replicateM :: Monad m => Int -> m a -> m (List a)+replicateM n = fmap fromList . Monad.replicateM n++untilM :: Monad m => m (Maybe a) -> m (List a)+untilM f = untilMWith f 0 []++untilMWith :: Monad m => m (Maybe a) -> Int -> [(Int, a)] -> m (List a)+untilMWith f i xs = do+ m <- f+ case m of+ Nothing -> pure . fromList . reverse $ fmap snd xs+ Just x -> untilMWith f (i + 1) ((i, x) : xs)
− src/lib/Rattletrap/Type/LoadoutAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/LoadoutOnlineAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/LoadoutsAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/LoadoutsOnlineAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/LocationAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Mark.hs view
@@ -1,19 +1,38 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Mark- ( Mark(..)- )-where+module Rattletrap.Type.Mark where -import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json data Mark = Mark- { markValue :: Str+ { value :: Str.Str -- ^ Which type of mark this is, like @Team0Goal@.- , markFrame :: Word32le+ , frame :: U32.U32 -- ^ Which frame this mark belongs to, starting from 0.- } deriving (Eq, Ord, Show)+ }+ deriving (Eq, Show) -$(deriveJson ''Mark)+instance Json.FromJSON Mark where+ parseJSON = Json.withObject "Mark" $ \object -> do+ value <- Json.required object "value"+ frame <- Json.required object "frame"+ pure Mark { value, frame }++instance Json.ToJSON Mark where+ toJSON x =+ Json.object [Json.pair "value" $ value x, Json.pair "frame" $ frame x]++schema :: Schema.Schema+schema = Schema.named "mark" $ Schema.object+ [ (Json.pair "value" $ Schema.ref Str.schema, True)+ , (Json.pair "frame" $ Schema.ref U32.schema, True)+ ]++bytePut :: Mark -> BytePut.BytePut+bytePut x = Str.bytePut (value x) <> U32.bytePut (frame x)++byteGet :: ByteGet.ByteGet Mark+byteGet = Mark <$> Str.byteGet <*> U32.byteGet
src/lib/Rattletrap/Type/Message.hs view
@@ -1,21 +1,49 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Message- ( Message(..)- )-where+module Rattletrap.Type.Message where -import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word32le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json data Message = Message- { messageFrame :: Word32le+ { frame :: U32.U32 -- ^ Which frame this message belongs to, starting from 0.- , messageName :: Str+ , name :: Str.Str -- ^ The primary player's name.- , messageValue :: Str+ , value :: Str.Str -- ^ The content of the message.- } deriving (Eq, Ord, Show)+ }+ deriving (Eq, Show) -$(deriveJson ''Message)+instance Json.FromJSON Message where+ parseJSON = Json.withObject "Message" $ \object -> do+ frame <- Json.required object "frame"+ name <- Json.required object "name"+ value <- Json.required object "value"+ pure Message { frame, name, value }++instance Json.ToJSON Message where+ toJSON x = Json.object+ [ Json.pair "frame" $ frame x+ , Json.pair "name" $ name x+ , Json.pair "value" $ value x+ ]++schema :: Schema.Schema+schema = Schema.named "message" $ Schema.object+ [ (Json.pair "frame" $ Schema.ref U32.schema, True)+ , (Json.pair "name" $ Schema.ref Str.schema, True)+ , (Json.pair "value" $ Schema.ref Str.schema, True)+ ]++bytePut :: Message -> BytePut.BytePut+bytePut x =+ do+ U32.bytePut (frame x)+ <> Str.bytePut (name x)+ <> Str.bytePut (value x)++byteGet :: ByteGet.ByteGet Message+byteGet = Message <$> U32.byteGet <*> Str.byteGet <*> Str.byteGet
− src/lib/Rattletrap/Type/MusicStingerAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/PartyLeaderAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/PickupAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/PickupAttributeNew.hs
@@ -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)
− src/lib/Rattletrap/Type/PlayerHistoryKeyAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/PrivateMatchSettingsAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/ProductAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Property.hs view
@@ -1,20 +1,49 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Property- ( Property(..)- )-where+module Rattletrap.Type.Property where -import Rattletrap.Type.Common-import Rattletrap.Type.PropertyValue-import Rattletrap.Type.Str-import Rattletrap.Type.Word64le+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.PropertyValue as PropertyValue+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U64 as U64+import qualified Rattletrap.Utility.Json as Json data Property = Property- { propertyKind :: Str- , propertySize :: Word64le+ { kind :: Str.Str+ , size :: U64.U64 -- ^ Not used.- , propertyValue :: PropertyValue Property- } deriving (Eq, Ord, Show)+ , value :: PropertyValue.PropertyValue Property+ }+ deriving (Eq, Show) -$(deriveJson ''Property)+instance Json.FromJSON Property where+ parseJSON = Json.withObject "Property" $ \object -> do+ kind <- Json.required object "kind"+ size <- Json.required object "size"+ value <- Json.required object "value"+ pure Property { kind, size, value }++instance Json.ToJSON Property where+ toJSON x = Json.object+ [ Json.pair "kind" $ kind x+ , Json.pair "size" $ size x+ , Json.pair "value" $ value x+ ]++schema :: Schema.Schema+schema = Schema.named "property" $ Schema.object+ [ (Json.pair "kind" $ Schema.ref Str.schema, True)+ , (Json.pair "size" $ Schema.ref U64.schema, True)+ , (Json.pair "value" . Schema.ref $ PropertyValue.schema schema, True)+ ]++bytePut :: Property -> BytePut.BytePut+bytePut x =+ Str.bytePut (kind x) <> U64.bytePut (size x) <> PropertyValue.bytePut+ bytePut+ (value x)++byteGet :: ByteGet.ByteGet Property+byteGet = do+ kind_ <- Str.byteGet+ Property kind_ <$> U64.byteGet <*> PropertyValue.byteGet byteGet kind_
src/lib/Rattletrap/Type/PropertyValue.hs view
@@ -1,32 +1,98 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.PropertyValue- ( PropertyValue(..)- )-where+module Rattletrap.Type.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+import qualified Data.Foldable as Foldable+import qualified Data.Text as Text+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Dictionary as Dictionary+import qualified Rattletrap.Type.F32 as F32+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U64 as U64+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad data PropertyValue a- = PropertyValueArray (List (Dictionary a))+ = Array (List.List (Dictionary.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)+ | Bool U8.U8+ | Byte Str.Str (Maybe Str.Str) -- ^ This is a strange name for essentially a key-value pair.- | PropertyValueFloat Float32le- | PropertyValueInt Int32le- | PropertyValueName Str+ | Float F32.F32+ | Int I32.I32+ | Name Str.Str -- ^ It's unclear how exactly this is different than a 'StrProperty'.- | PropertyValueQWord Word64le- | PropertyValueStr Str- deriving (Eq, Ord, Show)+ | QWord U64.U64+ | Str Str.Str+ deriving (Eq, Show) -$(deriveJson ''PropertyValue)+instance Json.FromJSON a => Json.FromJSON (PropertyValue a) where+ parseJSON = Json.withObject "PropertyValue" $ \object -> Foldable.asum+ [ Array <$> Json.required object "array"+ , Bool <$> Json.required object "bool"+ , uncurry Byte <$> Json.required object "byte"+ , Float <$> Json.required object "float"+ , Int <$> Json.required object "int"+ , Name <$> Json.required object "name"+ , QWord <$> Json.required object "q_word"+ , Str <$> Json.required object "str"+ ]++instance Json.ToJSON a => Json.ToJSON (PropertyValue a) where+ toJSON x = case x of+ Array y -> Json.object [Json.pair "array" y]+ Bool y -> Json.object [Json.pair "bool" y]+ Byte y z -> Json.object [Json.pair "byte" (y, z)]+ Float y -> Json.object [Json.pair "float" y]+ Int y -> Json.object [Json.pair "int" y]+ Name y -> Json.object [Json.pair "name" y]+ QWord y -> Json.object [Json.pair "q_word" y]+ Str y -> Json.object [Json.pair "str" y]++schema :: Schema.Schema -> Schema.Schema+schema s =+ Schema.named ("property-value-" <> Text.unpack (Schema.name s))+ . Schema.oneOf+ $ fmap+ (\(k, v) -> Schema.object [(Json.pair k v, True)])+ [ ("array", Schema.json . List.schema $ Dictionary.schema s)+ , ("bool", Schema.ref U8.schema)+ , ( "byte"+ , Schema.tuple+ [Schema.ref Str.schema, Schema.json $ Schema.maybe Str.schema]+ )+ , ("float", Schema.ref F32.schema)+ , ("int", Schema.ref I32.schema)+ , ("name", Schema.ref Str.schema)+ , ("q_word", Schema.ref U64.schema)+ , ("str", Schema.ref Str.schema)+ ]++bytePut :: (a -> BytePut.BytePut) -> PropertyValue a -> BytePut.BytePut+bytePut putProperty value = case value of+ Array x -> List.bytePut (Dictionary.bytePut putProperty) x+ Bool x -> U8.bytePut x+ Byte k mv -> Str.bytePut k <> foldMap Str.bytePut mv+ Float x -> F32.bytePut x+ Int x -> I32.bytePut x+ Name x -> Str.bytePut x+ QWord x -> U64.bytePut x+ Str x -> Str.bytePut x++byteGet :: ByteGet.ByteGet a -> Str.Str -> ByteGet.ByteGet (PropertyValue a)+byteGet getProperty kind = case Str.toString kind of+ "ArrayProperty" -> Array <$> List.byteGet (Dictionary.byteGet getProperty)+ "BoolProperty" -> Bool <$> U8.byteGet+ "ByteProperty" -> do+ k <- Str.byteGet+ Byte k <$> whenMaybe (Str.toString k /= "OnlinePlatform_Steam") Str.byteGet+ "FloatProperty" -> Float <$> F32.byteGet+ "IntProperty" -> Int <$> I32.byteGet+ "NameProperty" -> Name <$> Str.byteGet+ "QWordProperty" -> QWord <$> U64.byteGet+ "StrProperty" -> Str <$> Str.byteGet+ _ -> fail ("[RT07] don't know how to read property value " <> show kind)
− src/lib/Rattletrap/Type/QWordAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Quaternion.hs view
@@ -1,79 +1,94 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Quaternion- ( Quaternion(..)- , Component(..)- , toQuaternion- , compressPart- , decompressPart- , maxComponent- , maxCompressedValue- )-where+module Rattletrap.Type.Quaternion where -import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Utility.Json as Json import qualified Data.List as List import qualified Data.Maybe as Maybe+import qualified Data.Ord as Ord data Quaternion = Quaternion- { quaternionX :: Double- , quaternionY :: Double- , quaternionZ :: Double- , quaternionW :: Double- } deriving (Eq, Ord, Show)+ { x :: Double+ , y :: Double+ , z :: Double+ , w :: Double+ }+ deriving (Eq, Show) -$(deriveJson ''Quaternion)+instance Json.FromJSON Quaternion where+ parseJSON = Json.withObject "Quaternion" $ \object -> do+ x <- Json.required object "x"+ y <- Json.required object "y"+ z <- Json.required object "z"+ w <- Json.required object "w"+ pure Quaternion { x, y, z, w } +instance Json.ToJSON Quaternion where+ toJSON a = Json.object+ [ Json.pair "x" $ x a+ , Json.pair "y" $ y a+ , Json.pair "z" $ z a+ , Json.pair "w" $ w a+ ]++schema :: Schema.Schema+schema = Schema.named "quaternion" $ Schema.object+ [ (Json.pair "x" $ Schema.ref Schema.number, True)+ , (Json.pair "y" $ Schema.ref Schema.number, True)+ , (Json.pair "z" $ Schema.ref Schema.number, True)+ , (Json.pair "w" $ Schema.ref Schema.number, True)+ ]+ data Component- = ComponentX- | ComponentY- | ComponentZ- | ComponentW- deriving (Eq, Ord, Show)+ = X+ | Y+ | Z+ | W+ deriving (Eq, 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+ X -> Quaternion d a b c+ Y -> Quaternion a d b c+ Z -> Quaternion a b d c+ W -> 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 :: Double -> CompressedWord.CompressedWord compressPart =- CompressedWord maxCompressedValue+ CompressedWord.CompressedWord maxCompressedValue . round . (* wordToDouble maxCompressedValue) . (+ 0.5) . (/ 2.0) . (/ maxValue) -decompressPart :: CompressedWord -> Double-decompressPart x =+decompressPart :: CompressedWord.CompressedWord -> Double+decompressPart x_ = (* maxValue) . (* 2.0) . subtract 0.5- . (/ wordToDouble (compressedWordLimit x))+ . (/ wordToDouble (CompressedWord.limit x_)) . wordToDouble- $ compressedWordValue x+ $ CompressedWord.value 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+ x_ = x quaternion+ y_ = y quaternion+ z_ = z quaternion+ w_ = w quaternion+ parts = [(x_, X), (y_, Y), (z_, Z), (w_, W)]+ biggestPart = maximumOn fst parts roundTrip = decompressPart . compressPart computedPart = Maybe.fromMaybe biggestPart@@ -85,6 +100,9 @@ else computedPart ) +maximumOn :: (Foldable t, Ord b) => (a -> b) -> t a -> a+maximumOn f = List.maximumBy (Ord.comparing f)+ numBits :: Word numBits = 18 @@ -96,3 +114,48 @@ maxValue :: Double maxValue = 1.0 / sqrt 2.0++bitPut :: Quaternion -> BitPut.BitPut+bitPut q =+ let c = maxComponent q+ in+ putComponent c <> case c of+ X -> putParts (y q) (z q) (w q)+ Y -> putParts (x q) (z q) (w q)+ Z -> putParts (x q) (y q) (w q)+ W -> putParts (x q) (y q) (z q)++putComponent :: Component -> BitPut.BitPut+putComponent component = CompressedWord.bitPut+ (CompressedWord.CompressedWord+ 3+ (case component of+ X -> 0+ Y -> 1+ Z -> 2+ W -> 3+ )+ )++putParts :: Double -> Double -> Double -> BitPut.BitPut+putParts a b c = putPart a <> putPart b <> putPart c++putPart :: Double -> BitPut.BitPut+putPart = CompressedWord.bitPut . compressPart++bitGet :: BitGet.BitGet Quaternion+bitGet =+ toQuaternion <$> decodeComponent <*> decodePart <*> decodePart <*> decodePart++decodeComponent :: BitGet.BitGet Component+decodeComponent = do+ x_ <- CompressedWord.bitGet 3+ case CompressedWord.value x_ of+ 0 -> pure X+ 1 -> pure Y+ 2 -> pure Z+ 3 -> pure W+ y_ -> fail ("[RT08] invalid component: " <> show y_)++decodePart :: BitGet.BitGet Double+decodePart = decompressPart <$> CompressedWord.bitGet maxCompressedValue
src/lib/Rattletrap/Type/RemoteId.hs view
@@ -1,23 +1,135 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.RemoteId where -module Rattletrap.Type.RemoteId- ( RemoteId(..)- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U64 as U64+import qualified Rattletrap.Type.U8 as U8+import qualified Rattletrap.Type.Version as Version+import Rattletrap.Utility.Bytes+import qualified Rattletrap.Utility.Json as Json -import Rattletrap.Type.Common-import Rattletrap.Type.Str-import Rattletrap.Type.Word64le+import qualified Data.ByteString as Bytes+import qualified Data.Foldable as Foldable+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Word as Word data RemoteId- = RemoteIdPlayStation Text [Word8]- | RemoteIdPsyNet (Either Word64le (Word64le, Word64le, Word64le, Word64le))- | RemoteIdSplitscreen Word32+ = PlayStation Text.Text [Word.Word8]+ | PsyNet (Either U64.U64 (U64.U64, U64.U64, U64.U64, U64.U64))+ | Splitscreen Word.Word32 -- ^ Really only 24 bits.- | RemoteIdSteam Word64le- | RemoteIdSwitch Word64le Word64le Word64le Word64le- | RemoteIdXbox Word64le- | RemoteIdEpic Str- deriving (Eq, Ord, Show)+ | Steam U64.U64+ | Switch U64.U64 U64.U64 U64.U64 U64.U64+ | Xbox U64.U64+ | Epic Str.Str+ deriving (Eq, Show) -$(deriveJson ''RemoteId)+instance Json.FromJSON RemoteId where+ parseJSON = Json.withObject "RemoteId" $ \object -> Foldable.asum+ [ uncurry PlayStation <$> Json.required object "play_station"+ , PsyNet <$> Json.required object "psy_net"+ , Splitscreen <$> Json.required object "splitscreen"+ , Steam <$> Json.required object "steam"+ , uncurry4 Switch <$> Json.required object "switch"+ , Xbox <$> Json.required object "xbox"+ , Epic <$> Json.required object "epic"+ ]++uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e+uncurry4 f (a, b, c, d) = f a b c d++instance Json.ToJSON RemoteId where+ toJSON x = case x of+ PlayStation y z -> Json.object [Json.pair "play_station" (y, z)]+ PsyNet y -> Json.object [Json.pair "psy_net" y]+ Splitscreen y -> Json.object [Json.pair "splitscreen" y]+ Steam y -> Json.object [Json.pair "steam" y]+ Switch y z a b -> Json.object [Json.pair "switch" (y, z, a, b)]+ Xbox y -> Json.object [Json.pair "xbox" y]+ Epic y -> Json.object [Json.pair "epic" y]++schema :: Schema.Schema+schema = Schema.named "remote-id" . Schema.oneOf $ fmap+ (\(k, v) -> Schema.object [(Json.pair k v, True)])+ [ ( "play_station"+ , Schema.tuple+ [Schema.ref Schema.string, Schema.json $ Schema.array Schema.number]+ )+ , ( "psy_net"+ , Schema.oneOf+ [ Schema.object [(Json.pair "Left" $ Schema.ref U64.schema, True)]+ , Schema.object+ [ ( Json.pair "Right" . Schema.tuple . replicate 4 $ Schema.ref+ U64.schema+ , True+ )+ ]+ ]+ )+ , ("splitscreen", Schema.ref Schema.integer)+ , ("steam", Schema.ref U64.schema)+ , ("switch", Schema.tuple . replicate 4 $ Schema.ref U64.schema)+ , ("xbox", Schema.ref U64.schema)+ , ("epic", Schema.ref Str.schema)+ ]++bitPut :: RemoteId -> BitPut.BitPut+bitPut remoteId = case remoteId of+ PlayStation name bytes ->+ let rawName = reverseBytes (padBytes (16 :: Int) (encodeLatin1 name))+ in BitPut.byteString rawName <> BitPut.byteString (Bytes.pack bytes)+ PsyNet e -> case e of+ Left l -> U64.bitPut l+ Right (a, b, c, d) -> putWord256 a b c d+ Splitscreen word24 -> BitPut.bits 24 word24+ Steam word64 -> U64.bitPut word64+ Switch a b c d -> putWord256 a b c d+ Xbox word64 -> U64.bitPut word64+ Epic str -> Str.bitPut str++putWord256 :: U64.U64 -> U64.U64 -> U64.U64 -> U64.U64 -> BitPut.BitPut+putWord256 a b c d =+ U64.bitPut a <> U64.bitPut b <> U64.bitPut c <> U64.bitPut d++bitGet :: Version.Version -> U8.U8 -> BitGet.BitGet RemoteId+bitGet version systemId = case U8.toWord8 systemId of+ 0 -> Splitscreen <$> BitGet.bits 24+ 1 -> Steam <$> U64.bitGet+ 2 -> PlayStation <$> decodePsName <*> decodePsBytes version+ 4 -> Xbox <$> U64.bitGet+ 6 -> do+ (a, b, c, d) <- getWord256+ pure $ Switch a b c d+ 7 -> if psyNetIsU64 version+ then PsyNet . Left <$> U64.bitGet+ else PsyNet . Right <$> getWord256+ 11 -> Epic <$> Str.bitGet+ _ -> fail ("[RT09] unknown system id " <> show systemId)++psyNetIsU64 :: Version.Version -> Bool+psyNetIsU64 v =+ Version.major v >= 868 && Version.minor v >= 24 && Version.patch v >= 10++decodePsName :: BitGet.BitGet Text.Text+decodePsName = fmap+ (Text.dropWhileEnd (== '\x00') . Text.decodeLatin1 . reverseBytes)+ (BitGet.byteString 16)++decodePsBytes :: Version.Version -> BitGet.BitGet [Word.Word8]+decodePsBytes version = Bytes.unpack+ <$> BitGet.byteString (if playStationIsU24 version then 24 else 16)++playStationIsU24 :: Version.Version -> Bool+playStationIsU24 v =+ Version.major v >= 868 && Version.minor v >= 20 && Version.patch v >= 1++getWord256 :: BitGet.BitGet (U64.U64, U64.U64, U64.U64, U64.U64)+getWord256 = do+ a <- U64.bitGet+ b <- U64.bitGet+ c <- U64.bitGet+ d <- U64.bitGet+ pure (a, b, c, d)
src/lib/Rattletrap/Type/Replay.hs view
@@ -1,24 +1,124 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Replay- ( FullReplay- , Replay(..)- )-where+module Rattletrap.Type.Replay where -import Rattletrap.Type.Common-import Rattletrap.Type.Content-import Rattletrap.Type.Header-import Rattletrap.Type.Section+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Content as Content+import qualified Rattletrap.Type.Dictionary as Dictionary+import qualified Rattletrap.Type.Header as Header+import qualified Rattletrap.Type.I32 as I32+import qualified Rattletrap.Type.Property as Property+import qualified Rattletrap.Type.PropertyValue as PropertyValue+import qualified Rattletrap.Type.Section as Section+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import qualified Rattletrap.Version as Version -type FullReplay = Replay Content+type Replay+ = ReplayWith+ (Section.Section Header.Header)+ (Section.Section Content.Content) -- | A Rocket League replay.-data Replay content = Replay- { replayHeader :: Section Header+data ReplayWith header content = Replay+ { header :: header -- ^ This has most of the high-level metadata.- , replayContent :: Section content+ , content :: content -- ^ This has most of the low-level game data.- } deriving (Eq, Ord, Show)+ }+ deriving (Eq, Show) -$(deriveJson ''Replay)+instance (Json.FromJSON h, Json.FromJSON c) => Json.FromJSON (ReplayWith h c) where+ parseJSON = Json.withObject "Replay" $ \object -> do+ header <- Json.required object "header"+ content <- Json.required object "content"+ pure Replay { header, content }++instance (Json.ToJSON h, Json.ToJSON c) => Json.ToJSON (ReplayWith h c) where+ toJSON x = Json.object+ [ Json.pair "$schema" schemaUrl+ , Json.pair "header" $ header x+ , Json.pair "content" $ content x+ ]++schema :: Schema.Schema -> Schema.Schema -> Schema.Schema+schema h c = Schema.named "replay" $ Schema.object+ [ (Json.pair "header" $ Schema.ref h, True)+ , (Json.pair "content" $ Schema.ref c, True)+ ]++schemaUrl :: String+schemaUrl = mconcat+ [ "https://github.com/tfausak/rattletrap/releases/download/"+ , Version.string+ , "/rattletrap-"+ , Version.string+ , "-schema.json"+ ]++bytePut :: Replay -> BytePut.BytePut+bytePut x = Section.bytePut Header.bytePut (header x)+ <> Section.bytePut Content.bytePut (content x)++byteGet :: Bool -> Bool -> ByteGet.ByteGet Replay+byteGet fast skip = do+ hs <- Section.byteGet skip $ ByteGet.byteString . fromIntegral . U32.toWord32+ h <- either fail pure . ByteGet.run Header.byteGet $ Section.body hs+ cs <- Section.byteGet skip $ ByteGet.byteString . fromIntegral . U32.toWord32+ c <- if fast+ then pure Content.empty+ else either fail pure . ByteGet.run (getContent h) $ Section.body cs+ pure Replay+ { header = hs { Section.body = h }+ , content = cs { Section.body = c }+ }++getContent :: Header.Header -> ByteGet.ByteGet Content.Content+getContent h =+ Content.byteGet (getVersion h) (getNumFrames h) (getMaxChannels h)++getVersion :: Header.Header -> Version.Version+getVersion x = Version.Version+ { Version.major = fromIntegral . U32.toWord32 $ Header.engineVersion x+ , Version.minor = fromIntegral . U32.toWord32 $ Header.licenseeVersion x+ , Version.patch = getPatchVersion x+ }++getPatchVersion :: Header.Header -> Int+getPatchVersion header_ = case Header.patchVersion header_ of+ Just version -> fromIntegral (U32.toWord32 version)+ Nothing ->+ case+ Dictionary.lookup+ (Str.fromString "MatchType")+ (Header.properties header_)+ of+ -- This is an ugly, ugly hack to handle replays from season 2 of RLCS.+ -- See `decodeSpawnedReplicationBits` and #85.+ Just Property.Property { Property.value = PropertyValue.Name str }+ | Str.toString str == "Lan" -> -1+ _ -> 0++getNumFrames :: Header.Header -> Int+getNumFrames header_ =+ case+ Dictionary.lookup+ (Str.fromString "NumFrames")+ (Header.properties header_)+ of+ Just (Property.Property _ _ (PropertyValue.Int numFrames)) ->+ fromIntegral (I32.toInt32 numFrames)+ _ -> 0++getMaxChannels :: Header.Header -> Word+getMaxChannels header_ =+ case+ Dictionary.lookup+ (Str.fromString "MaxChannels")+ (Header.properties header_)+ of+ Just (Property.Property _ _ (PropertyValue.Int numFrames)) ->+ fromIntegral (I32.toInt32 numFrames)+ _ -> 1023
src/lib/Rattletrap/Type/Replication.hs view
@@ -1,17 +1,71 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.Replication where -module Rattletrap.Type.Replication- ( Replication(..)- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.ReplicationValue as ReplicationValue+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json -import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord-import Rattletrap.Type.ReplicationValue+import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map data Replication = Replication- { replicationActorId :: CompressedWord- , replicationValue :: ReplicationValue- } deriving (Eq, Ord, Show)+ { actorId :: CompressedWord.CompressedWord+ , value :: ReplicationValue.ReplicationValue+ }+ deriving (Eq, Show) -$(deriveJson ''Replication)+instance Json.FromJSON Replication where+ parseJSON = Json.withObject "Replication" $ \object -> do+ actorId <- Json.required object "actor_id"+ value <- Json.required object "value"+ pure Replication { actorId, value }++instance Json.ToJSON Replication where+ toJSON x =+ Json.object [Json.pair "actor_id" $ actorId x, Json.pair "value" $ value x]++schema :: Schema.Schema+schema = Schema.named "replication" $ Schema.object+ [ (Json.pair "actor_id" $ Schema.ref CompressedWord.schema, True)+ , (Json.pair "value" $ Schema.ref ReplicationValue.schema, True)+ ]++putReplications :: List.List Replication -> BitPut.BitPut+putReplications xs =+ foldMap (\x -> BitPut.bool True <> bitPut x) (List.toList xs)+ <> BitPut.bool False++bitPut :: Replication -> BitPut.BitPut+bitPut replication = CompressedWord.bitPut (actorId replication)+ <> ReplicationValue.bitPut (value replication)++decodeReplicationsBits+ :: Version.Version+ -> Word+ -> ClassAttributeMap.ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord.CompressedWord U32.U32)+ BitGet.BitGet+ (List.List Replication)+decodeReplicationsBits version limit classes = List.untilM $ do+ p <- Trans.lift BitGet.bool+ if p then Just <$> bitGet version limit classes else pure Nothing++bitGet+ :: Version.Version+ -> Word+ -> ClassAttributeMap.ClassAttributeMap+ -> State.StateT+ (Map.Map CompressedWord.CompressedWord U32.U32)+ BitGet.BitGet+ Replication+bitGet version limit classes = do+ actor <- Trans.lift (CompressedWord.bitGet limit)+ Replication actor <$> ReplicationValue.bitGet version classes actor
+ src/lib/Rattletrap/Type/Replication/Destroyed.hs view
@@ -0,0 +1,30 @@+module Rattletrap.Type.Replication.Destroyed where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++-- | 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 Destroyed = Destroyed+ deriving (Eq, Show)++instance Json.FromJSON Destroyed where+ parseJSON json = do+ () <- Json.parseJSON json+ pure Destroyed++instance Json.ToJSON Destroyed where+ toJSON = const $ Json.toJSON ()++schema :: Schema.Schema+schema =+ Schema.named "replication-destroyed" $ Json.object [Json.pair "type" "array"]++bitPut :: Destroyed -> BitPut.BitPut+bitPut _ = mempty++bitGet :: BitGet.BitGet Destroyed+bitGet = pure Destroyed
+ src/lib/Rattletrap/Type/Replication/Spawned.hs view
@@ -0,0 +1,156 @@+module Rattletrap.Type.Replication.Spawned where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.Initialization as Initialization+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json+import Rattletrap.Utility.Monad++import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Map as Map++data Spawned = Spawned+ { flag :: Bool+ -- ^ Unclear what this is.+ , nameIndex :: Maybe U32.U32+ , name :: Maybe Str.Str+ -- ^ Read-only! Changing a replication's name requires editing the+ -- 'nameIndex' and maybe the class attribute map.+ , objectId :: U32.U32+ , objectName :: Str.Str+ -- ^ Read-only! Changing a replication's object requires editing the class+ -- attribute map.+ , className :: Str.Str+ -- ^ Read-only! Changing a replication's class requires editing the class+ -- attribute map.+ , initialization :: Initialization.Initialization+ }+ deriving (Eq, Show)++instance Json.FromJSON Spawned where+ parseJSON = Json.withObject "Spawned" $ \object -> do+ flag <- Json.required object "flag"+ nameIndex <- Json.optional object "name_index"+ name <- Json.optional object "name"+ objectId <- Json.required object "object_id"+ objectName <- Json.required object "object_name"+ className <- Json.required object "class_name"+ initialization <- Json.required object "initialization"+ pure Spawned+ { flag+ , nameIndex+ , name+ , objectId+ , objectName+ , className+ , initialization+ }++instance Json.ToJSON Spawned where+ toJSON x = Json.object+ [ Json.pair "flag" $ flag x+ , Json.pair "name_index" $ nameIndex x+ , Json.pair "name" $ name x+ , Json.pair "object_id" $ objectId x+ , Json.pair "object_name" $ objectName x+ , Json.pair "class_name" $ className x+ , Json.pair "initialization" $ initialization x+ ]++schema :: Schema.Schema+schema = Schema.named "replication-spawned" $ Schema.object+ [ (Json.pair "flag" $ Schema.ref Schema.boolean, True)+ , (Json.pair "name_index" . Schema.json $ Schema.maybe U32.schema, False)+ , (Json.pair "name" . Schema.json $ Schema.maybe Str.schema, False)+ , (Json.pair "object_id" $ Schema.ref U32.schema, True)+ , (Json.pair "object_name" $ Schema.ref Str.schema, True)+ , (Json.pair "class_name" $ Schema.ref Str.schema, True)+ , (Json.pair "initialization" $ Schema.ref Initialization.schema, True)+ ]++bitPut :: Spawned -> BitPut.BitPut+bitPut spawnedReplication =+ BitPut.bool (flag spawnedReplication)+ <> foldMap U32.bitPut (nameIndex spawnedReplication)+ <> U32.bitPut (objectId spawnedReplication)+ <> Initialization.bitPut (initialization spawnedReplication)++bitGet+ :: Version.Version+ -> ClassAttributeMap.ClassAttributeMap+ -> CompressedWord.CompressedWord+ -> State.StateT+ (Map.Map CompressedWord.CompressedWord U32.U32)+ BitGet.BitGet+ Spawned+bitGet version classAttributeMap actorId = do+ flag_ <- Trans.lift BitGet.bool+ nameIndex_ <- whenMaybe (hasNameIndex version) (Trans.lift U32.bitGet)+ name_ <- either fail pure (lookupName classAttributeMap nameIndex_)+ objectId_ <- Trans.lift U32.bitGet+ State.modify (Map.insert actorId objectId_)+ objectName_ <- either+ fail+ pure+ (lookupObjectName classAttributeMap objectId_)+ className_ <- either fail pure (lookupClassName objectName_)+ let hasLocation = ClassAttributeMap.classHasLocation className_+ let hasRotation = ClassAttributeMap.classHasRotation className_+ initialization_ <- Trans.lift+ (Initialization.bitGet version hasLocation hasRotation)+ pure+ (Spawned+ flag_+ nameIndex_+ name_+ objectId_+ objectName_+ className_+ initialization_+ )++hasNameIndex :: Version.Version -> Bool+hasNameIndex v =+ Version.major v >= 868 && Version.minor v >= 14 && Version.patch v >= 0++lookupName+ :: ClassAttributeMap.ClassAttributeMap+ -> Maybe U32.U32+ -> Either String (Maybe Str.Str)+lookupName classAttributeMap maybeNameIndex = case maybeNameIndex of+ Nothing -> Right Nothing+ Just nameIndex_ ->+ case+ ClassAttributeMap.getName+ (ClassAttributeMap.nameMap classAttributeMap)+ nameIndex_+ of+ Nothing ->+ Left ("[RT11] could not get name for index " <> show nameIndex_)+ Just name_ -> Right (Just name_)++lookupObjectName+ :: ClassAttributeMap.ClassAttributeMap -> U32.U32 -> Either String Str.Str+lookupObjectName classAttributeMap objectId_ =+ case+ ClassAttributeMap.getObjectName+ (ClassAttributeMap.objectMap classAttributeMap)+ objectId_+ of+ Nothing ->+ Left ("[RT12] could not get object name for id " <> show objectId_)+ Just objectName_ -> Right objectName_++lookupClassName :: Str.Str -> Either String Str.Str+lookupClassName objectName_ =+ case ClassAttributeMap.getClassName objectName_ of+ Nothing ->+ Left ("[RT13] could not get class name for object " <> show objectName_)+ Just className_ -> Right className_
+ src/lib/Rattletrap/Type/Replication/Updated.hs view
@@ -0,0 +1,47 @@+module Rattletrap.Type.Replication.Updated where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute as Attribute+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json++import qualified Data.Map as Map++newtype Updated = Updated+ { attributes :: List.List Attribute.Attribute+ } deriving (Eq, Show)++instance Json.FromJSON Updated where+ parseJSON = fmap Updated . Json.parseJSON++instance Json.ToJSON Updated where+ toJSON = Json.toJSON . attributes++schema :: Schema.Schema+schema = Schema.named "replication-updated" . Schema.json $ List.schema+ Attribute.schema++bitPut :: Updated -> BitPut.BitPut+bitPut x =+ foldMap+ (\y -> BitPut.bool True <> Attribute.bitPut y)+ (List.toList $ attributes x)+ <> BitPut.bool False++bitGet+ :: Version.Version+ -> ClassAttributeMap.ClassAttributeMap+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> CompressedWord.CompressedWord+ -> BitGet.BitGet Updated+bitGet version classes actors actor = fmap Updated . List.untilM $ do+ p <- BitGet.bool+ if p+ then Just <$> Attribute.bitGet version classes actors actor+ else pure Nothing
src/lib/Rattletrap/Type/ReplicationValue.hs view
@@ -1,22 +1,74 @@-{-# LANGUAGE TemplateHaskell #-}+module Rattletrap.Type.ReplicationValue where -module Rattletrap.Type.ReplicationValue- ( ReplicationValue(..)- )-where+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.Replication.Destroyed as Destroyed+import qualified Rattletrap.Type.Replication.Spawned as Spawned+import qualified Rattletrap.Type.Replication.Updated as Updated+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json -import Rattletrap.Type.Common-import Rattletrap.Type.DestroyedReplication-import Rattletrap.Type.SpawnedReplication-import Rattletrap.Type.UpdatedReplication+import qualified Control.Monad.Trans.Class as Trans+import qualified Control.Monad.Trans.State as State+import qualified Data.Foldable as Foldable+import qualified Data.Map as Map data ReplicationValue- = ReplicationValueSpawned SpawnedReplication+ = Spawned Spawned.Spawned -- ^ Creates a new actor.- | ReplicationValueUpdated UpdatedReplication+ | Updated Updated.Updated -- ^ Updates an existing actor.- | ReplicationValueDestroyed DestroyedReplication+ | Destroyed Destroyed.Destroyed -- ^ Destroys an existing actor.- deriving (Eq, Ord, Show)+ deriving (Eq, Show) -$(deriveJson ''ReplicationValue)+instance Json.FromJSON ReplicationValue where+ parseJSON = Json.withObject "ReplicationValue" $ \object -> Foldable.asum+ [ Spawned <$> Json.required object "spawned"+ , Updated <$> Json.required object "updated"+ , Destroyed <$> Json.required object "destroyed"+ ]++instance Json.ToJSON ReplicationValue where+ toJSON x = case x of+ Spawned y -> Json.object [Json.pair "spawned" y]+ Updated y -> Json.object [Json.pair "updated" y]+ Destroyed y -> Json.object [Json.pair "destroyed" y]++schema :: Schema.Schema+schema = Schema.named "replicationValue" . Schema.oneOf $ fmap+ (\(k, v) -> Schema.object [(Json.pair k $ Schema.ref v, True)])+ [ ("spawned", Spawned.schema)+ , ("updated", Updated.schema)+ , ("destroyed", Destroyed.schema)+ ]++bitPut :: ReplicationValue -> BitPut.BitPut+bitPut value = case value of+ Spawned x -> BitPut.bool True <> BitPut.bool True <> Spawned.bitPut x+ Updated x -> BitPut.bool True <> BitPut.bool False <> Updated.bitPut x+ Destroyed x -> BitPut.bool False <> Destroyed.bitPut x++bitGet+ :: Version.Version+ -> ClassAttributeMap.ClassAttributeMap+ -> CompressedWord.CompressedWord+ -> State.StateT+ (Map.Map CompressedWord.CompressedWord U32.U32)+ BitGet.BitGet+ ReplicationValue+bitGet version classAttributeMap actorId = do+ actorMap <- State.get+ isOpen <- Trans.lift BitGet.bool+ if isOpen+ then do+ isNew <- Trans.lift BitGet.bool+ if isNew+ then Spawned <$> Spawned.bitGet version classAttributeMap actorId+ else Updated <$> Trans.lift+ (Updated.bitGet version classAttributeMap actorMap actorId)+ else Destroyed <$> Trans.lift Destroyed.bitGet
− src/lib/Rattletrap/Type/ReservationAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/RigidBodyStateAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Rotation.hs view
@@ -1,17 +1,48 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Rotation- ( Rotation(..)- )-where+module Rattletrap.Type.Rotation where -import Rattletrap.Type.Common-import Rattletrap.Type.Quaternion-import Rattletrap.Type.CompressedWordVector+import qualified Data.Foldable as Foldable+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.CompressedWordVector as CompressedWordVector+import qualified Rattletrap.Type.Quaternion as Quaternion+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json data Rotation- = RotationCompressedWordVector CompressedWordVector- | RotationQuaternion Quaternion- deriving (Eq, Ord, Show)+ = CompressedWordVector CompressedWordVector.CompressedWordVector+ | Quaternion Quaternion.Quaternion+ deriving (Eq, Show) -$(deriveJson ''Rotation)+instance Json.FromJSON Rotation where+ parseJSON = Json.withObject "Rotation" $ \object -> Foldable.asum+ [ CompressedWordVector <$> Json.required object "compressed_word_vector"+ , Quaternion <$> Json.required object "quaternion"+ ]++instance Json.ToJSON Rotation where+ toJSON x = case x of+ CompressedWordVector y ->+ Json.object [Json.pair "compressed_word_vector" y]+ Quaternion y -> Json.object [Json.pair "quaternion" y]++schema :: Schema.Schema+schema = Schema.named "rotation" . Schema.oneOf $ fmap+ (\(k, v) -> Schema.object [(Json.pair k $ Schema.ref v, True)])+ [ ("compressed_word_vector", CompressedWordVector.schema)+ , ("quaternion", Quaternion.schema)+ ]++bitPut :: Rotation -> BitPut.BitPut+bitPut r = case r of+ CompressedWordVector cwv -> CompressedWordVector.bitPut cwv+ Quaternion q -> Quaternion.bitPut q++bitGet :: Version.Version -> BitGet.BitGet Rotation+bitGet version = if isQuaternion version+ then Quaternion <$> Quaternion.bitGet+ else CompressedWordVector <$> CompressedWordVector.bitGet++isQuaternion :: Version.Version -> Bool+isQuaternion v =+ Version.major v >= 868 && Version.minor v >= 22 && Version.patch v >= 7
src/lib/Rattletrap/Type/Section.hs view
@@ -1,41 +1,91 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Section- ( Section(..)- , toSection- )-where+module Rattletrap.Type.Section where -import Rattletrap.Type.Common-import Rattletrap.Type.Word32le-import Rattletrap.Utility.Crc+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Crc as Crc+import qualified Rattletrap.Utility.Json as Json -import qualified Data.Binary as Binary-import qualified Data.Binary.Put as Binary+import qualified Control.Monad as Monad import qualified Data.ByteString as Bytes-import qualified Data.ByteString.Lazy as LazyBytes+import qualified Data.Text as Text -- | 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+ { size :: U32.U32 -- ^ read only- , sectionCrc :: Word32le+ , crc :: U32.U32 -- ^ read only- , sectionBody :: a+ , body :: a -- ^ The actual content in the section.- } deriving (Eq, Ord, Show)+ }+ deriving (Eq, Show) -$(deriveJson ''Section)+instance Json.FromJSON a => Json.FromJSON (Section a) where+ parseJSON = Json.withObject "Section" $ \object -> do+ size <- Json.required object "size"+ crc <- Json.required object "crc"+ body <- Json.required object "body"+ pure Section { size, crc, body } -toSection :: (a -> Binary.Put) -> a -> Section a-toSection encode body =- let bytes = LazyBytes.toStrict . Binary.runPut $ encode body+instance Json.ToJSON a => Json.ToJSON (Section a) where+ toJSON x = Json.object+ [ Json.pair "size" $ size x+ , Json.pair "crc" $ crc x+ , Json.pair "body" $ body x+ ]++schema :: Schema.Schema -> Schema.Schema+schema s =+ Schema.named ("section-" <> Text.unpack (Schema.name s)) $ Schema.object+ [ (Json.pair "size" $ Schema.ref U32.schema, True)+ , (Json.pair "crc" $ Schema.ref U32.schema, True)+ , (Json.pair "body" $ Schema.ref s, True)+ ]++create :: (a -> BytePut.BytePut) -> a -> Section a+create encode body_ =+ let bytes = BytePut.toByteString $ encode body_ in Section- { sectionSize = Word32le . fromIntegral $ Bytes.length bytes- , sectionCrc = Word32le $ getCrc32 bytes- , sectionBody = body+ { size = U32.fromWord32 . fromIntegral $ Bytes.length bytes+ , crc = U32.fromWord32 $ Crc.compute bytes+ , body = body_ }++-- | Given a way to put the 'body', puts a section. This will also put+-- the size and CRC.+bytePut :: (a -> BytePut.BytePut) -> Section a -> BytePut.BytePut+bytePut putBody section =+ let+ rawBody = BytePut.toByteString . putBody $ body section+ size_ = Bytes.length rawBody+ crc_ = Crc.compute rawBody+ in+ U32.bytePut (U32.fromWord32 (fromIntegral size_))+ <> U32.bytePut (U32.fromWord32 crc_)+ <> BytePut.byteString rawBody++byteGet+ :: Bool -> (U32.U32 -> ByteGet.ByteGet a) -> ByteGet.ByteGet (Section a)+byteGet skip getBody = do+ size_ <- U32.byteGet+ crc_ <- U32.byteGet+ rawBody <- ByteGet.byteString (fromIntegral (U32.toWord32 size_))+ Monad.unless skip $ do+ let actualCrc = U32.fromWord32 (Crc.compute rawBody)+ Monad.when (actualCrc /= crc_) (fail (crcMessage actualCrc crc_))+ body_ <- either fail pure $ ByteGet.run (getBody size_) rawBody+ pure (Section size_ crc_ body_)++crcMessage :: U32.U32 -> U32.U32 -> String+crcMessage actual expected = unwords+ [ "[RT10] actual CRC"+ , show actual+ , "does not match expected CRC"+ , show expected+ ]
− src/lib/Rattletrap/Type/SpawnedReplication.hs
@@ -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)
− src/lib/Rattletrap/Type/StatEventAttribute.hs
@@ -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)
src/lib/Rattletrap/Type/Str.hs view
@@ -1,24 +1,103 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Str- ( Str(..)- , toStr- , fromStr- )-where+module Rattletrap.Type.Str where -import Rattletrap.Type.Common+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.I32 as I32+import Rattletrap.Utility.Bytes+import qualified Rattletrap.Utility.Json as Json +import qualified Data.ByteString as Bytes+import qualified Data.Char as Char+import qualified Data.Int as Int 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 -newtype Str = Str- { strValue :: Text- } deriving (Eq, Ord, Show)+newtype Str+ = Str Text.Text+ deriving (Eq, Ord, Show) -$(deriveJson ''Str)+instance Json.FromJSON Str where+ parseJSON = fmap fromText . Json.parseJSON -toStr :: String -> Str-toStr string = Str (Text.pack string)+instance Json.ToJSON Str where+ toJSON = Json.toJSON . toText -fromStr :: Str -> String-fromStr text = Text.unpack (strValue text)+schema :: Schema.Schema+schema = Schema.named "str" $ Json.object [Json.pair "type" "string"]++fromText :: Text.Text -> Str+fromText = Str++toText :: Str -> Text.Text+toText (Str x) = x++fromString :: String -> Str+fromString = fromText . Text.pack++toString :: Str -> String+toString = Text.unpack . toText++bytePut :: Str -> BytePut.BytePut+bytePut text =+ let+ size = getTextSize text+ encode = getTextEncoder size+ in I32.bytePut size <> (BytePut.byteString . encode . addNull $ toText text)++bitPut :: Str -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++getTextSize :: Str -> I32.I32+getTextSize text =+ let+ value = toText text+ scale = if Text.all Char.isLatin1 value then 1 else -1 :: Int.Int32+ rawSize = if Text.null value+ then 0+ else fromIntegral (Text.length value) + 1 :: Int.Int32+ size = if value == Text.pack "\x00\x00\x00None"+ then 0x05000000+ else scale * rawSize :: Int.Int32+ in I32.fromInt32 size++getTextEncoder :: I32.I32 -> Text.Text -> Bytes.ByteString+getTextEncoder size text =+ if I32.toInt32 size < 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'++byteGet :: ByteGet.ByteGet Str+byteGet = do+ rawSize <- I32.byteGet+ bytes <- ByteGet.byteString (normalizeTextSize rawSize)+ pure (fromText (dropNull (getTextDecoder rawSize bytes)))++bitGet :: BitGet.BitGet Str+bitGet = do+ rawSize <- I32.bitGet+ bytes <- BitGet.byteString (normalizeTextSize rawSize)+ pure (fromText (dropNull (getTextDecoder rawSize (reverseBytes bytes))))++normalizeTextSize :: Integral a => I32.I32 -> a+normalizeTextSize size = case I32.toInt32 size of+ 0x05000000 -> 8+ x -> if x < 0 then (-2 * fromIntegral x) else fromIntegral x++getTextDecoder :: I32.I32 -> Bytes.ByteString -> Text.Text+getTextDecoder size bytes =+ let+ decode = if I32.toInt32 size < 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')
− src/lib/Rattletrap/Type/StringAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/TeamPaintAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/TitleAttribute.hs
@@ -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)
+ src/lib/Rattletrap/Type/U32.hs view
@@ -0,0 +1,44 @@+module Rattletrap.Type.U32 where++import qualified Data.Word as Word+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype U32+ = U32 Word.Word32+ deriving (Eq, Ord, Show)++instance Json.FromJSON U32 where+ parseJSON = fmap fromWord32 . Json.parseJSON++instance Json.ToJSON U32 where+ toJSON = Json.toJSON . toWord32++schema :: Schema.Schema+schema = Schema.named "u32" $ Json.object+ [ Json.pair "type" "integer"+ , Json.pair "minimum" (minBound :: Word.Word32)+ , Json.pair "maximum" (maxBound :: Word.Word32)+ ]++fromWord32 :: Word.Word32 -> U32+fromWord32 = U32++toWord32 :: U32 -> Word.Word32+toWord32 (U32 x) = x++bytePut :: U32 -> BytePut.BytePut+bytePut = BytePut.word32 . toWord32++bitPut :: U32 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet U32+byteGet = fromWord32 <$> ByteGet.word32++bitGet :: BitGet.BitGet U32+bitGet = BitGet.fromByteGet byteGet 4
+ src/lib/Rattletrap/Type/U64.hs view
@@ -0,0 +1,48 @@+module Rattletrap.Type.U64 where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++import qualified Data.Text as Text+import qualified Data.Word as Word+import qualified Text.Read as Read++newtype U64+ = U64 Word.Word64+ deriving (Eq, Show)++instance Json.FromJSON U64 where+ parseJSON =+ Json.withText "U64"+ $ either fail (pure . fromWord64)+ . Read.readEither+ . Text.unpack++instance Json.ToJSON U64 where+ toJSON = Json.toJSON . show . toWord64++schema :: Schema.Schema+schema = Schema.named "u64"+ $ Json.object [Json.pair "type" "string", Json.pair "pattern" "^[0-9]+$"]++fromWord64 :: Word.Word64 -> U64+fromWord64 = U64++toWord64 :: U64 -> Word.Word64+toWord64 (U64 x) = x++bytePut :: U64 -> BytePut.BytePut+bytePut = BytePut.word64 . toWord64++bitPut :: U64 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet U64+byteGet = fromWord64 <$> ByteGet.word64++bitGet :: BitGet.BitGet U64+bitGet = BitGet.fromByteGet byteGet 8
+ src/lib/Rattletrap/Type/U8.hs view
@@ -0,0 +1,44 @@+module Rattletrap.Type.U8 where++import qualified Data.Word as Word+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Utility.Json as Json++newtype U8+ = U8 Word.Word8+ deriving (Eq, Show)++instance Json.FromJSON U8 where+ parseJSON = fmap fromWord8 . Json.parseJSON++instance Json.ToJSON U8 where+ toJSON = Json.toJSON . toWord8++schema :: Schema.Schema+schema = Schema.named "u8" $ Json.object+ [ Json.pair "type" "integer"+ , Json.pair "minimum" (minBound :: Word.Word8)+ , Json.pair "maximum" (maxBound :: Word.Word8)+ ]++fromWord8 :: Word.Word8 -> U8+fromWord8 = U8++toWord8 :: U8 -> Word.Word8+toWord8 (U8 x) = x++bytePut :: U8 -> BytePut.BytePut+bytePut = BytePut.word8 . toWord8++bitPut :: U8 -> BitPut.BitPut+bitPut = BitPut.fromBytePut . bytePut++byteGet :: ByteGet.ByteGet U8+byteGet = fromWord8 <$> ByteGet.word8++bitGet :: BitGet.BitGet U8+bitGet = BitGet.fromByteGet byteGet 1
− src/lib/Rattletrap/Type/UniqueIdAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/UpdatedReplication.hs
@@ -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)
src/lib/Rattletrap/Type/Vector.hs view
@@ -1,26 +1,91 @@-{-# LANGUAGE TemplateHaskell #-}--module Rattletrap.Type.Vector- ( Vector(..)- )-where+module Rattletrap.Type.Vector where -import Rattletrap.Type.Common-import Rattletrap.Type.CompressedWord+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.CompressedWord as CompressedWord+import qualified Rattletrap.Type.Version as Version+import qualified Rattletrap.Utility.Json as Json data Vector = Vector- { vectorSize :: CompressedWord- , vectorBias :: Word+ { size :: CompressedWord.CompressedWord+ , bias :: 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)+ , x :: Int+ -- ^ See 'bias'.+ , y :: Int+ -- ^ See 'bias'.+ , z :: Int+ -- ^ See 'bias'.+ }+ deriving (Eq, Show) -$(deriveJson ''Vector)+instance Json.FromJSON Vector where+ parseJSON = Json.withObject "Vector" $ \object -> do+ size <- Json.required object "size"+ bias <- Json.required object "bias"+ x <- Json.required object "x"+ y <- Json.required object "y"+ z <- Json.required object "z"+ pure Vector { size, bias, x, y, z }++instance Json.ToJSON Vector where+ toJSON a = Json.object+ [ Json.pair "size" $ size a+ , Json.pair "bias" $ bias a+ , Json.pair "x" $ x a+ , Json.pair "y" $ y a+ , Json.pair "z" $ z a+ ]++schema :: Schema.Schema+schema = Schema.named "vector" $ Schema.object+ [ (Json.pair "size" $ Schema.ref CompressedWord.schema, True)+ , (Json.pair "bias" $ Schema.ref Schema.integer, True)+ , (Json.pair "x" $ Schema.ref Schema.integer, True)+ , (Json.pair "y" $ Schema.ref Schema.integer, True)+ , (Json.pair "z" $ Schema.ref Schema.integer, True)+ ]++bitPut :: Vector -> BitPut.BitPut+bitPut vector =+ let+ bitSize =+ round (logBase (2 :: Float) (fromIntegral (bias vector))) - 1 :: Word+ dx = fromIntegral (x vector + fromIntegral (bias vector)) :: Word+ dy = fromIntegral (y vector + fromIntegral (bias vector)) :: Word+ dz = fromIntegral (z vector + fromIntegral (bias vector)) :: Word+ limit = 2 ^ (bitSize + 2) :: Word+ in+ CompressedWord.bitPut (size vector)+ <> CompressedWord.bitPut (CompressedWord.CompressedWord limit dx)+ <> CompressedWord.bitPut (CompressedWord.CompressedWord limit dy)+ <> CompressedWord.bitPut (CompressedWord.CompressedWord limit dz)++bitGet :: Version.Version -> BitGet.BitGet Vector+bitGet version = do+ size_ <- CompressedWord.bitGet (if has21Bits version then 21 else 19)+ let+ limit = getLimit size_+ bias_ = getBias size_+ Vector size_ bias_+ <$> fmap (fromDelta bias_) (CompressedWord.bitGet limit)+ <*> fmap (fromDelta bias_) (CompressedWord.bitGet limit)+ <*> fmap (fromDelta bias_) (CompressedWord.bitGet limit)++has21Bits :: Version.Version -> Bool+has21Bits v =+ Version.major v >= 868 && Version.minor v >= 22 && Version.patch v >= 7++getLimit :: CompressedWord.CompressedWord -> Word+getLimit = (2 ^) . (+ 2) . CompressedWord.value++getBias :: CompressedWord.CompressedWord -> Word+getBias = (2 ^) . (+ 1) . CompressedWord.value++fromDelta :: Word -> CompressedWord.CompressedWord -> Int+fromDelta bias_ x_ =+ fromIntegral (CompressedWord.value x_) - fromIntegral bias_
+ src/lib/Rattletrap/Type/Version.hs view
@@ -0,0 +1,8 @@+module Rattletrap.Type.Version where++data Version = Version+ { major :: Int+ , minor :: Int+ , patch :: Int+ }+ deriving (Eq, Show)
− src/lib/Rattletrap/Type/WeldedInfoAttribute.hs
@@ -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)
− src/lib/Rattletrap/Type/Word32le.hs
@@ -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)
− src/lib/Rattletrap/Type/Word64le.hs
@@ -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
− src/lib/Rattletrap/Type/Word8le.hs
@@ -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)
src/lib/Rattletrap/Utility/Bytes.hs view
@@ -2,8 +2,7 @@ ( encodeLatin1 , padBytes , reverseBytes- )-where+ ) where import qualified Data.Bits as Bits import qualified Data.ByteString as Bytes
src/lib/Rattletrap/Utility/Crc.hs view
@@ -1,47 +1,295 @@ module Rattletrap.Utility.Crc- ( getCrc32- )-where--import Rattletrap.Data+ ( compute+ ) where +import qualified Data.Array.Unboxed as Array 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])+-- compute ('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+compute :: Bytes.ByteString -> Word.Word32+compute = Bits.complement . Bytes.foldl' update initial -crc32Update- :: IntMap.IntMap Word.Word32 -> Word.Word32 -> Word.Word8 -> Word.Word32-crc32Update table crc byte = do+update :: Word.Word32 -> Word.Word8 -> Word.Word32+update crc byte = 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+ index = Bits.xor byte . unsafeWord32ToWord8 $ Bits.shiftR crc 24+ left = table Array.! index right = Bits.shiftL crc 8- Bits.xor left right+ in Bits.xor left right -crc32Initial :: Word.Word32-crc32Initial = 0xefcbf201+unsafeWord32ToWord8 :: Word.Word32 -> Word.Word8+unsafeWord32ToWord8 = fromIntegral -crc32Table :: IntMap.IntMap Word.Word32-crc32Table = IntMap.fromDistinctAscList (zip [0 ..] rawCrc32Table)+initial :: Word.Word32+initial = Bits.complement 0xefcbf201++table :: Array.Array Word.Word8 Word.Word32+table = Array.listArray+ (0, 255)+ [ 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+ ]
src/lib/Rattletrap/Utility/Helper.hs view
@@ -5,42 +5,41 @@ , encodeReplayJson , decodeReplayJson , encodeReplayFile- )-where+ ) 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 Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Type.Content as Content+import qualified Rattletrap.Type.Replay as Replay+import qualified Rattletrap.Type.Section as Section -import qualified Data.Aeson as Json-import qualified Data.Aeson.Encode.Pretty as Json-import qualified Data.Binary.Put as Binary+import qualified Data.Aeson as Aeson+import qualified Data.Aeson.Encode.Pretty as Aeson import qualified Data.ByteString as Bytes import qualified Data.ByteString.Lazy as LazyBytes -- | Parses a raw replay.-decodeReplayFile :: Bool -> Bytes.ByteString -> Either String FullReplay-decodeReplayFile fast = runDecode $ decodeReplay fast+decodeReplayFile+ :: Bool -> Bool -> Bytes.ByteString -> Either String Replay.Replay+decodeReplayFile fast = ByteGet.run . Replay.byteGet fast -- | Encodes a replay as JSON.-encodeReplayJson :: FullReplay -> Bytes.ByteString-encodeReplayJson = LazyBytes.toStrict . Json.encodePretty' Json.defConfig- { Json.confCompare = compare- , Json.confIndent = Json.Spaces 2- , Json.confTrailingNewline = True+encodeReplayJson :: Replay.Replay -> LazyBytes.ByteString+encodeReplayJson = Aeson.encodePretty' Aeson.defConfig+ { Aeson.confCompare = compare+ , Aeson.confIndent = Aeson.Tab+ , Aeson.confTrailingNewline = True } -- | Parses a JSON replay.-decodeReplayJson :: Bytes.ByteString -> Either String FullReplay-decodeReplayJson = Json.eitherDecodeStrict'+decodeReplayJson :: Bytes.ByteString -> Either String Replay.Replay+decodeReplayJson = Aeson.eitherDecodeStrict' -- | Encodes a raw replay.-encodeReplayFile :: Bool -> FullReplay -> Bytes.ByteString+encodeReplayFile :: Bool -> Replay.Replay -> LazyBytes.ByteString encodeReplayFile fast replay =- LazyBytes.toStrict . Binary.runPut . putReplay $ if fast- then replay { replayContent = toSection putContent defaultContent }+ BytePut.toLazyByteString . Replay.bytePut $ if fast+ then replay+ { Replay.content = Section.create Content.bytePut Content.empty+ } else replay
+ src/lib/Rattletrap/Utility/Json.hs view
@@ -0,0 +1,23 @@+module Rattletrap.Utility.Json+ ( module Rattletrap.Utility.Json+ , Aeson.FromJSON(parseJSON)+ , Aeson.ToJSON(toJSON)+ , Aeson.Value+ , Aeson.object+ , Aeson.withObject+ , Aeson.withText+ ) where++import qualified Data.Aeson as Aeson+import qualified Data.Aeson.Types as Aeson+import qualified Data.Text as Text++required+ :: Aeson.FromJSON value => Aeson.Object -> String -> Aeson.Parser value+required object key = object Aeson..: Text.pack key++optional :: Aeson.FromJSON value => Aeson.Object -> String -> Aeson.Parser (Maybe value)+optional object key = object Aeson..:? Text.pack key++pair :: (Aeson.ToJSON value, Aeson.KeyValue pair) => String -> value -> pair+pair key value = Text.pack key Aeson..= value
+ src/lib/Rattletrap/Utility/Monad.hs view
@@ -0,0 +1,4 @@+module Rattletrap.Utility.Monad where++whenMaybe :: Applicative m => Bool -> m a -> m (Maybe a)+whenMaybe p f = if p then Just <$> f else pure Nothing
+ src/lib/Rattletrap/Version.hs view
@@ -0,0 +1,7 @@+module Rattletrap.Version where++import qualified Data.Version as Version+import qualified Paths_rattletrap as Package++string :: String+string = Version.showVersion Package.version
src/test/Main.hs view
@@ -1,76 +1,54 @@ module Main ( main- )-where+ ) 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 Data.ByteString as Bytes 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)+main = runTests makeTests runTests :: Test.Test -> IO () runTests test = do- result <- Test.runTestTT test+ Rattletrap.rattletrap+ ""+ ["--schema", "--output", Path.combine directory "schema.json"]+ (result, elapsed) <- withElapsed $ Test.runTestTT test+ Printf.printf "Total time: %.3f seconds\n" elapsed Monad.when (Test.errors result > 0 || Test.failures result > 0) Exit.exitFailure -toTests :: FilePath -> Test.Test-toTests directory = Test.TestList (fmap (toTest directory) replays)+makeTests :: Test.Test+makeTests = Test.TestList $ fmap toTest replays -toTest :: FilePath -> (String, String) -> Test.Test-toTest directory (uuid, name) = Test.TestLabel- (toLabel uuid name)- (Test.TestCase (toAssertion directory uuid))+toTest :: (String, String) -> Test.Test+toTest (uuid, name) =+ Test.TestLabel (toLabel uuid name) . Test.TestCase $ toAssertion uuid toLabel :: String -> String -> String toLabel uuid name = uuid <> ": " <> name -toAssertion :: FilePath -> String -> Test.Assertion-toAssertion directory uuid = do+toAssertion :: String -> Test.Assertion+toAssertion 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"]+ inputFile = Path.combine "replays" $ uuid <> ".replay"+ jsonFile = Path.combine directory $ uuid <> ".json"+ outputFile = Path.combine directory $ 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+ decode inputFile jsonFile+ encode jsonFile outputFile 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]@@ -79,19 +57,15 @@ 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 :: IO a -> IO (a, Double) withElapsed action = do- before <- Clock.getMonotonicTimeNSec+ before <- Clock.getMonotonicTime result <- action- after <- Clock.getMonotonicTimeNSec+ after <- Clock.getMonotonicTime pure (result, after - before)++directory :: FilePath+directory = "output" replays :: [(String, String)] replays =