rattletrap 11.0.0 → 11.0.1
raw patch · 116 files changed
+884/−536 lines, 116 filesdep −transformersPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: transformers
API changes (from Hackage documentation)
+ Rattletrap.BitGet: label :: String -> BitGet a -> BitGet a
+ Rattletrap.BitGet: throw :: Exception e => e -> BitGet a
+ Rattletrap.ByteGet: embed :: ByteGet a -> ByteString -> ByteGet a
+ Rattletrap.ByteGet: label :: String -> ByteGet a -> ByteGet a
+ Rattletrap.ByteGet: throw :: Exception e => e -> ByteGet a
+ Rattletrap.Exception.CrcMismatch: CrcMismatch :: Word32 -> Word32 -> CrcMismatch
+ Rattletrap.Exception.CrcMismatch: data CrcMismatch
+ Rattletrap.Exception.CrcMismatch: instance GHC.Classes.Eq Rattletrap.Exception.CrcMismatch.CrcMismatch
+ Rattletrap.Exception.CrcMismatch: instance GHC.Exception.Type.Exception Rattletrap.Exception.CrcMismatch.CrcMismatch
+ Rattletrap.Exception.CrcMismatch: instance GHC.Show.Show Rattletrap.Exception.CrcMismatch.CrcMismatch
+ Rattletrap.Exception.Empty: Empty :: Empty
+ Rattletrap.Exception.Empty: data Empty
+ Rattletrap.Exception.Empty: instance GHC.Classes.Eq Rattletrap.Exception.Empty.Empty
+ Rattletrap.Exception.Empty: instance GHC.Exception.Type.Exception Rattletrap.Exception.Empty.Empty
+ Rattletrap.Exception.Empty: instance GHC.Show.Show Rattletrap.Exception.Empty.Empty
+ Rattletrap.Exception.Fail: Fail :: String -> Fail
+ Rattletrap.Exception.Fail: instance GHC.Classes.Eq Rattletrap.Exception.Fail.Fail
+ Rattletrap.Exception.Fail: instance GHC.Exception.Type.Exception Rattletrap.Exception.Fail.Fail
+ Rattletrap.Exception.Fail: instance GHC.Show.Show Rattletrap.Exception.Fail.Fail
+ Rattletrap.Exception.Fail: newtype Fail
+ Rattletrap.Exception.InvalidComponent: InvalidComponent :: Word -> InvalidComponent
+ Rattletrap.Exception.InvalidComponent: instance GHC.Classes.Eq Rattletrap.Exception.InvalidComponent.InvalidComponent
+ Rattletrap.Exception.InvalidComponent: instance GHC.Exception.Type.Exception Rattletrap.Exception.InvalidComponent.InvalidComponent
+ Rattletrap.Exception.InvalidComponent: instance GHC.Show.Show Rattletrap.Exception.InvalidComponent.InvalidComponent
+ Rattletrap.Exception.InvalidComponent: newtype InvalidComponent
+ Rattletrap.Exception.InvalidJson: InvalidJson :: String -> InvalidJson
+ Rattletrap.Exception.InvalidJson: instance GHC.Classes.Eq Rattletrap.Exception.InvalidJson.InvalidJson
+ Rattletrap.Exception.InvalidJson: instance GHC.Exception.Type.Exception Rattletrap.Exception.InvalidJson.InvalidJson
+ Rattletrap.Exception.InvalidJson: instance GHC.Show.Show Rattletrap.Exception.InvalidJson.InvalidJson
+ Rattletrap.Exception.InvalidJson: newtype InvalidJson
+ Rattletrap.Exception.MissingAttributeLimit: MissingAttributeLimit :: Word -> MissingAttributeLimit
+ Rattletrap.Exception.MissingAttributeLimit: instance GHC.Classes.Eq Rattletrap.Exception.MissingAttributeLimit.MissingAttributeLimit
+ Rattletrap.Exception.MissingAttributeLimit: instance GHC.Exception.Type.Exception Rattletrap.Exception.MissingAttributeLimit.MissingAttributeLimit
+ Rattletrap.Exception.MissingAttributeLimit: instance GHC.Show.Show Rattletrap.Exception.MissingAttributeLimit.MissingAttributeLimit
+ Rattletrap.Exception.MissingAttributeLimit: newtype MissingAttributeLimit
+ Rattletrap.Exception.MissingAttributeName: MissingAttributeName :: Word -> MissingAttributeName
+ Rattletrap.Exception.MissingAttributeName: instance GHC.Classes.Eq Rattletrap.Exception.MissingAttributeName.MissingAttributeName
+ Rattletrap.Exception.MissingAttributeName: instance GHC.Exception.Type.Exception Rattletrap.Exception.MissingAttributeName.MissingAttributeName
+ Rattletrap.Exception.MissingAttributeName: instance GHC.Show.Show Rattletrap.Exception.MissingAttributeName.MissingAttributeName
+ Rattletrap.Exception.MissingAttributeName: newtype MissingAttributeName
+ Rattletrap.Exception.MissingClassName: MissingClassName :: String -> MissingClassName
+ Rattletrap.Exception.MissingClassName: instance GHC.Classes.Eq Rattletrap.Exception.MissingClassName.MissingClassName
+ Rattletrap.Exception.MissingClassName: instance GHC.Exception.Type.Exception Rattletrap.Exception.MissingClassName.MissingClassName
+ Rattletrap.Exception.MissingClassName: instance GHC.Show.Show Rattletrap.Exception.MissingClassName.MissingClassName
+ Rattletrap.Exception.MissingClassName: newtype MissingClassName
+ Rattletrap.Exception.MissingObjectName: MissingObjectName :: Word32 -> MissingObjectName
+ Rattletrap.Exception.MissingObjectName: instance GHC.Classes.Eq Rattletrap.Exception.MissingObjectName.MissingObjectName
+ Rattletrap.Exception.MissingObjectName: instance GHC.Exception.Type.Exception Rattletrap.Exception.MissingObjectName.MissingObjectName
+ Rattletrap.Exception.MissingObjectName: instance GHC.Show.Show Rattletrap.Exception.MissingObjectName.MissingObjectName
+ Rattletrap.Exception.MissingObjectName: newtype MissingObjectName
+ Rattletrap.Exception.MissingProductName: MissingProductName :: Word32 -> MissingProductName
+ Rattletrap.Exception.MissingProductName: instance GHC.Classes.Eq Rattletrap.Exception.MissingProductName.MissingProductName
+ Rattletrap.Exception.MissingProductName: instance GHC.Exception.Type.Exception Rattletrap.Exception.MissingProductName.MissingProductName
+ Rattletrap.Exception.MissingProductName: instance GHC.Show.Show Rattletrap.Exception.MissingProductName.MissingProductName
+ Rattletrap.Exception.MissingProductName: newtype MissingProductName
+ Rattletrap.Exception.NotEnoughInput: NotEnoughInput :: NotEnoughInput
+ Rattletrap.Exception.NotEnoughInput: data NotEnoughInput
+ Rattletrap.Exception.NotEnoughInput: instance GHC.Classes.Eq Rattletrap.Exception.NotEnoughInput.NotEnoughInput
+ Rattletrap.Exception.NotEnoughInput: instance GHC.Exception.Type.Exception Rattletrap.Exception.NotEnoughInput.NotEnoughInput
+ Rattletrap.Exception.NotEnoughInput: instance GHC.Show.Show Rattletrap.Exception.NotEnoughInput.NotEnoughInput
+ Rattletrap.Exception.UnknownActor: UnknownActor :: Word -> UnknownActor
+ Rattletrap.Exception.UnknownActor: instance GHC.Classes.Eq Rattletrap.Exception.UnknownActor.UnknownActor
+ Rattletrap.Exception.UnknownActor: instance GHC.Exception.Type.Exception Rattletrap.Exception.UnknownActor.UnknownActor
+ Rattletrap.Exception.UnknownActor: instance GHC.Show.Show Rattletrap.Exception.UnknownActor.UnknownActor
+ Rattletrap.Exception.UnknownActor: newtype UnknownActor
+ Rattletrap.Exception.UnknownAttribute: UnknownAttribute :: String -> UnknownAttribute
+ Rattletrap.Exception.UnknownAttribute: instance GHC.Classes.Eq Rattletrap.Exception.UnknownAttribute.UnknownAttribute
+ Rattletrap.Exception.UnknownAttribute: instance GHC.Exception.Type.Exception Rattletrap.Exception.UnknownAttribute.UnknownAttribute
+ Rattletrap.Exception.UnknownAttribute: instance GHC.Show.Show Rattletrap.Exception.UnknownAttribute.UnknownAttribute
+ Rattletrap.Exception.UnknownAttribute: newtype UnknownAttribute
+ Rattletrap.Exception.UnknownName: UnknownName :: Word32 -> UnknownName
+ Rattletrap.Exception.UnknownName: instance GHC.Classes.Eq Rattletrap.Exception.UnknownName.UnknownName
+ Rattletrap.Exception.UnknownName: instance GHC.Exception.Type.Exception Rattletrap.Exception.UnknownName.UnknownName
+ Rattletrap.Exception.UnknownName: instance GHC.Show.Show Rattletrap.Exception.UnknownName.UnknownName
+ Rattletrap.Exception.UnknownName: newtype UnknownName
+ Rattletrap.Exception.UnknownProduct: UnknownProduct :: String -> UnknownProduct
+ Rattletrap.Exception.UnknownProduct: instance GHC.Classes.Eq Rattletrap.Exception.UnknownProduct.UnknownProduct
+ Rattletrap.Exception.UnknownProduct: instance GHC.Exception.Type.Exception Rattletrap.Exception.UnknownProduct.UnknownProduct
+ Rattletrap.Exception.UnknownProduct: instance GHC.Show.Show Rattletrap.Exception.UnknownProduct.UnknownProduct
+ Rattletrap.Exception.UnknownProduct: newtype UnknownProduct
+ Rattletrap.Exception.UnknownProperty: UnknownProperty :: String -> UnknownProperty
+ Rattletrap.Exception.UnknownProperty: instance GHC.Classes.Eq Rattletrap.Exception.UnknownProperty.UnknownProperty
+ Rattletrap.Exception.UnknownProperty: instance GHC.Exception.Type.Exception Rattletrap.Exception.UnknownProperty.UnknownProperty
+ Rattletrap.Exception.UnknownProperty: instance GHC.Show.Show Rattletrap.Exception.UnknownProperty.UnknownProperty
+ Rattletrap.Exception.UnknownProperty: newtype UnknownProperty
+ Rattletrap.Exception.UnknownSystemId: UnknownSystemId :: Word8 -> UnknownSystemId
+ Rattletrap.Exception.UnknownSystemId: instance GHC.Classes.Eq Rattletrap.Exception.UnknownSystemId.UnknownSystemId
+ Rattletrap.Exception.UnknownSystemId: instance GHC.Exception.Type.Exception Rattletrap.Exception.UnknownSystemId.UnknownSystemId
+ Rattletrap.Exception.UnknownSystemId: instance GHC.Show.Show Rattletrap.Exception.UnknownSystemId.UnknownSystemId
+ Rattletrap.Exception.UnknownSystemId: newtype UnknownSystemId
+ Rattletrap.Get: embed :: Monad m => Get s m a -> s -> Get t m a
+ Rattletrap.Get: label :: Functor m => String -> Get s m a -> Get s m a
+ Rattletrap.Get: labels :: Functor m => [String] -> Get s m a -> Get s m a
+ Rattletrap.Get: throw :: (Exception e, Applicative m) => e -> Get s m a
+ Rattletrap.Type.Frame: decodeFramesBitsWith :: Maybe Str -> Version -> Int -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> Int -> [Frame] -> BitGet (Map CompressedWord U32, List Frame)
+ Rattletrap.Type.List: generateM :: Monad m => Int -> (Int -> m a) -> m (List a)
+ Rattletrap.Type.Replication: decodeReplicationsBitsWith :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> Int -> [Replication] -> BitGet (Map CompressedWord U32, List Replication)
- Rattletrap: decodeReplayFile :: Bool -> Bool -> ByteString -> Either String Replay
+ Rattletrap: decodeReplayFile :: Bool -> Bool -> ByteString -> Either ([String], SomeException) Replay
- Rattletrap: decodeReplayJson :: ByteString -> Either String Replay
+ Rattletrap: decodeReplayJson :: ByteString -> Either ([String], SomeException) Replay
- Rattletrap.ByteGet: run :: ByteGet a -> ByteString -> Either String a
+ Rattletrap.ByteGet: run :: ByteGet a -> ByteString -> Either ([String], SomeException) a
- Rattletrap.Console.Main: getDecoder :: Config -> ByteString -> Either String Replay
+ Rattletrap.Console.Main: getDecoder :: Config -> ByteString -> Either ([String], SomeException) Replay
- Rattletrap.Get: Get :: (s -> m (Either String (s, a))) -> Get s m a
+ Rattletrap.Get: Get :: (s -> m (Either ([String], SomeException) (s, a))) -> Get s m a
- Rattletrap.Get: run :: Get s m a -> s -> m (Either String (s, a))
+ Rattletrap.Get: run :: Get s m a -> s -> m (Either ([String], SomeException) (s, a))
- Rattletrap.Type.Attribute: fromMaybe :: String -> Maybe a -> BitGet a
+ Rattletrap.Type.Attribute: fromMaybe :: Exception e => e -> Maybe a -> BitGet a
- Rattletrap.Type.Frame: bitGet :: Maybe Str -> Version -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet Frame
+ Rattletrap.Type.Frame: bitGet :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Frame)
- Rattletrap.Type.Frame: decodeFramesBits :: Maybe Str -> Version -> Int -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet (List Frame)
+ Rattletrap.Type.Frame: decodeFramesBits :: Maybe Str -> Version -> Int -> Word -> ClassAttributeMap -> BitGet (List Frame)
- Rattletrap.Type.Replication: bitGet :: Maybe Str -> Version -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet Replication
+ Rattletrap.Type.Replication: bitGet :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Replication)
- Rattletrap.Type.Replication: decodeReplicationsBits :: Maybe Str -> Version -> Word -> ClassAttributeMap -> StateT (Map CompressedWord U32) BitGet (List Replication)
+ Rattletrap.Type.Replication: decodeReplicationsBits :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, List Replication)
- Rattletrap.Type.Replication.Spawned: bitGet :: Maybe Str -> Version -> ClassAttributeMap -> CompressedWord -> StateT (Map CompressedWord U32) BitGet Spawned
+ Rattletrap.Type.Replication.Spawned: bitGet :: Maybe Str -> Version -> ClassAttributeMap -> CompressedWord -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Spawned)
- Rattletrap.Type.Replication.Spawned: lookupClassName :: Str -> Either String Str
+ Rattletrap.Type.Replication.Spawned: lookupClassName :: Str -> BitGet Str
- Rattletrap.Type.Replication.Spawned: lookupName :: ClassAttributeMap -> Maybe U32 -> Either String (Maybe Str)
+ Rattletrap.Type.Replication.Spawned: lookupName :: ClassAttributeMap -> Maybe U32 -> BitGet (Maybe Str)
- Rattletrap.Type.Replication.Spawned: lookupObjectName :: ClassAttributeMap -> U32 -> Either String Str
+ Rattletrap.Type.Replication.Spawned: lookupObjectName :: ClassAttributeMap -> U32 -> BitGet Str
- Rattletrap.Type.ReplicationValue: bitGet :: Maybe Str -> Version -> ClassAttributeMap -> CompressedWord -> StateT (Map CompressedWord U32) BitGet ReplicationValue
+ Rattletrap.Type.ReplicationValue: bitGet :: Maybe Str -> Version -> ClassAttributeMap -> CompressedWord -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, ReplicationValue)
- Rattletrap.Utility.Helper: decodeReplayFile :: Bool -> Bool -> ByteString -> Either String Replay
+ Rattletrap.Utility.Helper: decodeReplayFile :: Bool -> Bool -> ByteString -> Either ([String], SomeException) Replay
- Rattletrap.Utility.Helper: decodeReplayJson :: ByteString -> Either String Replay
+ Rattletrap.Utility.Helper: decodeReplayJson :: ByteString -> Either ([String], SomeException) Replay
Files
- rattletrap.cabal +18/−2
- src/lib/Rattletrap/BitGet.hs +11/−3
- src/lib/Rattletrap/ByteGet.hs +20/−3
- src/lib/Rattletrap/Console/Main.hs +15/−2
- src/lib/Rattletrap/Data.hs +1/−2
- src/lib/Rattletrap/Exception/CrcMismatch.hs +11/−0
- src/lib/Rattletrap/Exception/Empty.hs +8/−0
- src/lib/Rattletrap/Exception/Fail.hs +10/−0
- src/lib/Rattletrap/Exception/InvalidComponent.hs +9/−0
- src/lib/Rattletrap/Exception/InvalidJson.hs +9/−0
- src/lib/Rattletrap/Exception/MissingAttributeLimit.hs +9/−0
- src/lib/Rattletrap/Exception/MissingAttributeName.hs +9/−0
- src/lib/Rattletrap/Exception/MissingClassName.hs +9/−0
- src/lib/Rattletrap/Exception/MissingObjectName.hs +10/−0
- src/lib/Rattletrap/Exception/MissingProductName.hs +10/−0
- src/lib/Rattletrap/Exception/NotEnoughInput.hs +8/−0
- src/lib/Rattletrap/Exception/UnknownActor.hs +9/−0
- src/lib/Rattletrap/Exception/UnknownAttribute.hs +9/−0
- src/lib/Rattletrap/Exception/UnknownName.hs +10/−0
- src/lib/Rattletrap/Exception/UnknownProduct.hs +9/−0
- src/lib/Rattletrap/Exception/UnknownProperty.hs +9/−0
- src/lib/Rattletrap/Exception/UnknownSystemId.hs +10/−0
- src/lib/Rattletrap/Get.hs +24/−4
- src/lib/Rattletrap/Type/Attribute.hs +12/−8
- src/lib/Rattletrap/Type/Attribute/AppliedDamage.hs +5/−5
- src/lib/Rattletrap/Type/Attribute/Boolean.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/Byte.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/CamSettings.hs +9/−10
- src/lib/Rattletrap/Type/Attribute/ClubColors.hs +5/−5
- src/lib/Rattletrap/Type/Attribute/CustomDemolish.hs +4/−4
- src/lib/Rattletrap/Type/Attribute/DamageState.hs +7/−7
- src/lib/Rattletrap/Type/Attribute/Demolish.hs +7/−7
- src/lib/Rattletrap/Type/Attribute/Enum.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/Explosion.hs +4/−4
- src/lib/Rattletrap/Type/Attribute/ExtendedExplosion.hs +3/−3
- src/lib/Rattletrap/Type/Attribute/FlaggedByte.hs +3/−3
- src/lib/Rattletrap/Type/Attribute/FlaggedInt.hs +3/−3
- src/lib/Rattletrap/Type/Attribute/Float.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/GameMode.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/Int.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/Int64.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/Loadout.hs +27/−18
- src/lib/Rattletrap/Type/Attribute/LoadoutOnline.hs +6/−6
- src/lib/Rattletrap/Type/Attribute/Loadouts.hs +3/−3
- src/lib/Rattletrap/Type/Attribute/LoadoutsOnline.hs +6/−7
- src/lib/Rattletrap/Type/Attribute/Location.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/MusicStinger.hs +4/−4
- src/lib/Rattletrap/Type/Attribute/PartyLeader.hs +4/−4
- src/lib/Rattletrap/Type/Attribute/Pickup.hs +5/−4
- src/lib/Rattletrap/Type/Attribute/PickupNew.hs +5/−4
- src/lib/Rattletrap/Type/Attribute/PlayerHistoryKey.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/PrivateMatchSettings.hs +7/−7
- src/lib/Rattletrap/Type/Attribute/Product.hs +8/−8
- src/lib/Rattletrap/Type/Attribute/ProductValue.hs +21/−19
- src/lib/Rattletrap/Type/Attribute/QWord.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/Reservation.hs +9/−7
- src/lib/Rattletrap/Type/Attribute/RigidBodyState.hs +8/−6
- src/lib/Rattletrap/Type/Attribute/StatEvent.hs +3/−3
- src/lib/Rattletrap/Type/Attribute/String.hs +2/−2
- src/lib/Rattletrap/Type/Attribute/TeamPaint.hs +6/−6
- src/lib/Rattletrap/Type/Attribute/Title.hs +9/−9
- src/lib/Rattletrap/Type/Attribute/UniqueId.hs +4/−4
- src/lib/Rattletrap/Type/Attribute/WeldedInfo.hs +6/−6
- src/lib/Rattletrap/Type/AttributeMapping.hs +3/−3
- src/lib/Rattletrap/Type/AttributeValue.hs +8/−8
- src/lib/Rattletrap/Type/Cache.hs +6/−5
- src/lib/Rattletrap/Type/ClassAttributeMap.hs +7/−8
- src/lib/Rattletrap/Type/ClassMapping.hs +3/−3
- src/lib/Rattletrap/Type/CompressedWord.hs +1/−2
- src/lib/Rattletrap/Type/Content.hs +27/−28
- src/lib/Rattletrap/Type/Dictionary.hs +6/−7
- src/lib/Rattletrap/Type/F32.hs +1/−1
- src/lib/Rattletrap/Type/Frame.hs +56/−22
- src/lib/Rattletrap/Type/Header.hs +5/−4
- src/lib/Rattletrap/Type/I32.hs +1/−1
- src/lib/Rattletrap/Type/I64.hs +2/−3
- src/lib/Rattletrap/Type/I8.hs +1/−1
- src/lib/Rattletrap/Type/Initialization.hs +5/−3
- src/lib/Rattletrap/Type/Int8Vector.hs +4/−4
- src/lib/Rattletrap/Type/Keyframe.hs +4/−4
- src/lib/Rattletrap/Type/List.hs +8/−5
- src/lib/Rattletrap/Type/Mark.hs +3/−3
- src/lib/Rattletrap/Type/Message.hs +4/−4
- src/lib/Rattletrap/Type/Property.hs +4/−4
- src/lib/Rattletrap/Type/Property/Array.hs +2/−1
- src/lib/Rattletrap/Type/Property/Bool.hs +1/−1
- src/lib/Rattletrap/Type/Property/Byte.hs +3/−3
- src/lib/Rattletrap/Type/Property/Float.hs +1/−1
- src/lib/Rattletrap/Type/Property/Int.hs +1/−1
- src/lib/Rattletrap/Type/Property/Name.hs +1/−1
- src/lib/Rattletrap/Type/Property/QWord.hs +1/−1
- src/lib/Rattletrap/Type/Property/Str.hs +1/−1
- src/lib/Rattletrap/Type/PropertyValue.hs +12/−10
- src/lib/Rattletrap/Type/Quaternion.hs +5/−5
- src/lib/Rattletrap/Type/RemoteId.hs +3/−3
- src/lib/Rattletrap/Type/RemoteId/Epic.hs +1/−1
- src/lib/Rattletrap/Type/RemoteId/PlayStation.hs +3/−3
- src/lib/Rattletrap/Type/RemoteId/PsyNet.hs +11/−8
- src/lib/Rattletrap/Type/RemoteId/Splitscreen.hs +1/−1
- src/lib/Rattletrap/Type/RemoteId/Steam.hs +1/−1
- src/lib/Rattletrap/Type/RemoteId/Switch.hs +1/−1
- src/lib/Rattletrap/Type/RemoteId/Xbox.hs +1/−1
- src/lib/Rattletrap/Type/Replay.hs +15/−11
- src/lib/Rattletrap/Type/Replication.hs +50/−20
- src/lib/Rattletrap/Type/Replication/Destroyed.hs +1/−1
- src/lib/Rattletrap/Type/Replication/Spawned.hs +43/−44
- src/lib/Rattletrap/Type/Replication/Updated.hs +5/−5
- src/lib/Rattletrap/Type/ReplicationValue.hs +32/−24
- src/lib/Rattletrap/Type/Section.hs +18/−13
- src/lib/Rattletrap/Type/Str.hs +10/−11
- src/lib/Rattletrap/Type/U32.hs +1/−1
- src/lib/Rattletrap/Type/U64.hs +3/−4
- src/lib/Rattletrap/Type/U8.hs +1/−1
- src/lib/Rattletrap/Type/Vector.hs +7/−5
- src/lib/Rattletrap/Type/Version.hs +4/−4
- src/lib/Rattletrap/Utility/Helper.hs +13/−3
rattletrap.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0 name: rattletrap-version: 11.0.0+version: 11.0.1 synopsis: Parse and generate Rocket League replays. description: Rattletrap parses and generates Rocket League replays. @@ -29,7 +29,6 @@ , http-client >= 0.6.4 && < 0.8 , http-client-tls >= 0.3.5 && < 0.4 , text >= 1.2.4 && < 1.3- , transformers >= 0.5.6 && < 0.6 default-extensions: NamedFieldPuns default-language: Haskell2010 exposed-modules:@@ -47,6 +46,23 @@ Rattletrap.Console.Mode Rattletrap.Console.Option Rattletrap.Data+ Rattletrap.Exception.CrcMismatch+ Rattletrap.Exception.Empty+ Rattletrap.Exception.Fail+ Rattletrap.Exception.InvalidComponent+ Rattletrap.Exception.InvalidJson+ Rattletrap.Exception.MissingAttributeLimit+ Rattletrap.Exception.MissingAttributeName+ Rattletrap.Exception.MissingClassName+ Rattletrap.Exception.MissingObjectName+ Rattletrap.Exception.MissingProductName+ Rattletrap.Exception.NotEnoughInput+ Rattletrap.Exception.UnknownActor+ Rattletrap.Exception.UnknownAttribute+ Rattletrap.Exception.UnknownName+ Rattletrap.Exception.UnknownProduct+ Rattletrap.Exception.UnknownProperty+ Rattletrap.Exception.UnknownSystemId Rattletrap.Get Rattletrap.Schema Rattletrap.Type.Attribute
src/lib/Rattletrap/BitGet.hs view
@@ -1,11 +1,13 @@ module Rattletrap.BitGet where +import qualified Control.Exception as Exception import qualified Control.Monad as Monad import qualified Data.Bits as Bits import qualified Data.ByteString as ByteString import qualified Data.Functor.Identity as Identity import qualified Rattletrap.BitString as BitString import qualified Rattletrap.ByteGet as ByteGet+import qualified Rattletrap.Exception.NotEnoughInput as NotEnoughInput import qualified Rattletrap.Get as Get type BitGet = Get.Get BitString.BitString Identity.Identity@@ -14,7 +16,7 @@ toByteGet g = do s1 <- Get.get case Identity.runIdentity . Get.run g $ BitString.fromByteString s1 of- Left e -> fail e+ Left (ls, e) -> Get.labels ls $ ByteGet.throw e Right (s2, x) -> do Get.put $ BitString.byteString s2 pure x@@ -22,7 +24,7 @@ fromByteGet :: ByteGet.ByteGet a -> Int -> BitGet a fromByteGet f n = do x <- byteString n- either fail pure $ ByteGet.run f x+ Get.embed f x bits :: Bits.Bits a => Int -> BitGet a bits n = do@@ -36,10 +38,16 @@ bool = do s1 <- Get.get case BitString.pop s1 of- Nothing -> fail "BitGet.bool"+ Nothing -> throw NotEnoughInput.NotEnoughInput Just (x, s2) -> do Get.put s2 pure x byteString :: Int -> BitGet ByteString.ByteString byteString n = fmap ByteString.pack . Monad.replicateM n $ bits 8++throw :: Exception.Exception e => e -> BitGet a+throw = Get.throw++label :: String -> BitGet a -> BitGet a+label = Get.label
src/lib/Rattletrap/ByteGet.hs view
@@ -1,5 +1,6 @@ module Rattletrap.ByteGet where +import qualified Control.Exception as Exception import qualified Data.Bits as Bits import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as LazyByteString@@ -7,19 +8,26 @@ import qualified Data.Int as Int import qualified Data.Word as Word import qualified GHC.Float as Float+import qualified Rattletrap.Exception.NotEnoughInput as NotEnoughInput import qualified Rattletrap.Get as Get type ByteGet = Get.Get ByteString.ByteString Identity.Identity -run :: ByteGet a -> ByteString.ByteString -> Either String a+run+ :: ByteGet a+ -> ByteString.ByteString+ -> Either ([String], Exception.SomeException) 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+ if ByteString.length x == n+ then do+ Get.put s2+ pure x+ else throw NotEnoughInput.NotEnoughInput float :: ByteGet Float float = fmap Float.castWord32ToFloat word32@@ -63,3 +71,12 @@ + Bits.shiftL (fromIntegral $ ByteString.index x 5) 40 + Bits.shiftL (fromIntegral $ ByteString.index x 6) 48 + Bits.shiftL (fromIntegral $ ByteString.index x 7) 56++throw :: Exception.Exception e => e -> ByteGet a+throw = Get.throw++embed :: ByteGet a -> ByteString.ByteString -> ByteGet a+embed = Get.embed++label :: String -> ByteGet a -> ByteGet a+label = Get.label
src/lib/Rattletrap/Console/Main.hs view
@@ -1,9 +1,11 @@ module Rattletrap.Console.Main where +import qualified Control.Exception as Exception import qualified Control.Monad as Monad import qualified Data.Bool as Bool import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as LazyByteString+import qualified Data.List as List import qualified Data.Text as Text import qualified Network.HTTP.Client as Client import qualified Network.HTTP.Client.TLS as Client@@ -135,7 +137,16 @@ defaultMain config = do input <- getInput config let decode = getDecoder config- replay <- either fail pure (decode input)+ replay <- case decode input of+ Left (ls, e) -> do+ IO.hPutStr IO.stderr $ unlines+ [ "ERROR: " <> Exception.displayException e+ , "# Context: " <> List.intercalate " -> " ls+ , "# You are using Rattletrap version " <> Version.string+ , "# Please report this problem at https://github.com/tfausak/rattletrap/issues/new"+ ]+ Exit.exitFailure+ Right x -> pure x let encode = getEncoder config putOutput config (encode replay) @@ -243,7 +254,9 @@ ] getDecoder- :: Config.Config -> ByteString.ByteString -> Either String Replay.Replay+ :: Config.Config+ -> ByteString.ByteString+ -> Either ([String], Exception.SomeException) Replay.Replay getDecoder config = case Config.getMode config of Mode.Decode -> Rattletrap.decodeReplayFile (Config.fast config) (Config.skipCrc config)
src/lib/Rattletrap/Data.hs view
@@ -1,12 +1,11 @@ -- brittany --columns 120 module Rattletrap.Data where -import qualified Rattletrap.Type.AttributeType as AttributeType- import qualified Data.Bifunctor as Bifunctor import qualified Data.Map as Map import qualified Data.Set as Set import qualified Data.Text as Text+import qualified Rattletrap.Type.AttributeType as AttributeType parentClasses :: Map.Map Text.Text Text.Text parentClasses = Map.fromList $ fmap
+ src/lib/Rattletrap/Exception/CrcMismatch.hs view
@@ -0,0 +1,11 @@+module Rattletrap.Exception.CrcMismatch where++import qualified Control.Exception as Exception+import qualified Data.Word as Word++data CrcMismatch = CrcMismatch Word.Word32 Word.Word32+ deriving (Eq, Show)++instance Exception.Exception CrcMismatch where+ displayException (CrcMismatch x y) =+ unwords ["invalid CRC: expected", show x, "but got", show y]
+ src/lib/Rattletrap/Exception/Empty.hs view
@@ -0,0 +1,8 @@+module Rattletrap.Exception.Empty where++import qualified Control.Exception as Exception++data Empty = Empty+ deriving (Eq, Show)++instance Exception.Exception Empty
+ src/lib/Rattletrap/Exception/Fail.hs view
@@ -0,0 +1,10 @@+module Rattletrap.Exception.Fail where++import qualified Control.Exception as Exception++newtype Fail+ = Fail String+ deriving (Eq, Show)++instance Exception.Exception Fail where+ displayException (Fail x) = x
+ src/lib/Rattletrap/Exception/InvalidComponent.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.InvalidComponent where++import qualified Control.Exception as Exception++newtype InvalidComponent+ = InvalidComponent Word+ deriving (Eq, Show)++instance Exception.Exception InvalidComponent
+ src/lib/Rattletrap/Exception/InvalidJson.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.InvalidJson where++import qualified Control.Exception as Exception++newtype InvalidJson+ = InvalidJson String+ deriving (Eq, Show)++instance Exception.Exception InvalidJson
+ src/lib/Rattletrap/Exception/MissingAttributeLimit.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.MissingAttributeLimit where++import qualified Control.Exception as Exception++newtype MissingAttributeLimit+ = MissingAttributeLimit Word+ deriving (Eq, Show)++instance Exception.Exception MissingAttributeLimit
+ src/lib/Rattletrap/Exception/MissingAttributeName.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.MissingAttributeName where++import qualified Control.Exception as Exception++newtype MissingAttributeName+ = MissingAttributeName Word+ deriving (Eq, Show)++instance Exception.Exception MissingAttributeName
+ src/lib/Rattletrap/Exception/MissingClassName.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.MissingClassName where++import qualified Control.Exception as Exception++newtype MissingClassName+ = MissingClassName String+ deriving (Eq, Show)++instance Exception.Exception MissingClassName
+ src/lib/Rattletrap/Exception/MissingObjectName.hs view
@@ -0,0 +1,10 @@+module Rattletrap.Exception.MissingObjectName where++import qualified Control.Exception as Exception+import qualified Data.Word as Word++newtype MissingObjectName+ = MissingObjectName Word.Word32+ deriving (Eq, Show)++instance Exception.Exception MissingObjectName
+ src/lib/Rattletrap/Exception/MissingProductName.hs view
@@ -0,0 +1,10 @@+module Rattletrap.Exception.MissingProductName where++import qualified Control.Exception as Exception+import qualified Data.Word as Word++newtype MissingProductName+ = MissingProductName Word.Word32+ deriving (Eq, Show)++instance Exception.Exception MissingProductName
+ src/lib/Rattletrap/Exception/NotEnoughInput.hs view
@@ -0,0 +1,8 @@+module Rattletrap.Exception.NotEnoughInput where++import qualified Control.Exception as Exception++data NotEnoughInput = NotEnoughInput+ deriving (Eq, Show)++instance Exception.Exception NotEnoughInput
+ src/lib/Rattletrap/Exception/UnknownActor.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.UnknownActor where++import qualified Control.Exception as Exception++newtype UnknownActor+ = UnknownActor Word+ deriving (Eq, Show)++instance Exception.Exception UnknownActor
+ src/lib/Rattletrap/Exception/UnknownAttribute.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.UnknownAttribute where++import qualified Control.Exception as Exception++newtype UnknownAttribute+ = UnknownAttribute String+ deriving (Eq, Show)++instance Exception.Exception UnknownAttribute
+ src/lib/Rattletrap/Exception/UnknownName.hs view
@@ -0,0 +1,10 @@+module Rattletrap.Exception.UnknownName where++import qualified Control.Exception as Exception+import qualified Data.Word as Word++newtype UnknownName+ = UnknownName Word.Word32+ deriving (Eq, Show)++instance Exception.Exception UnknownName
+ src/lib/Rattletrap/Exception/UnknownProduct.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.UnknownProduct where++import qualified Control.Exception as Exception++newtype UnknownProduct+ = UnknownProduct String+ deriving (Eq, Show)++instance Exception.Exception UnknownProduct
+ src/lib/Rattletrap/Exception/UnknownProperty.hs view
@@ -0,0 +1,9 @@+module Rattletrap.Exception.UnknownProperty where++import qualified Control.Exception as Exception++newtype UnknownProperty+ = UnknownProperty String+ deriving (Eq, Show)++instance Exception.Exception UnknownProperty
+ src/lib/Rattletrap/Exception/UnknownSystemId.hs view
@@ -0,0 +1,10 @@+module Rattletrap.Exception.UnknownSystemId where++import qualified Control.Exception as Exception+import qualified Data.Word as Word++newtype UnknownSystemId+ = UnknownSystemId Word.Word8+ deriving (Eq, Show)++instance Exception.Exception UnknownSystemId
src/lib/Rattletrap/Get.hs view
@@ -1,8 +1,12 @@ module Rattletrap.Get where import qualified Control.Applicative as Applicative+import qualified Control.Exception as Exception+import qualified Data.Bifunctor as Bifunctor+import qualified Rattletrap.Exception.Empty as Empty+import qualified Rattletrap.Exception.Fail as Fail -newtype Get s m a = Get (s -> m (Either String (s, a)))+newtype Get s m a = Get (s -> m (Either ([String], Exception.SomeException) (s, a))) instance Functor m => Functor (Get s m) where fmap f g = Get $ fmap (fmap (fmap f)) . run g@@ -24,10 +28,10 @@ Right (s2, x) -> run (f x) s2 instance Monad m => MonadFail (Get s m) where- fail = Get . const . pure . Left+ fail = throw . Fail.Fail instance Monad m => Applicative.Alternative (Get s m) where- empty = fail "empty"+ empty = throw Empty.Empty gx <|> gy = Get $ \s -> do r <- run gx s@@ -35,7 +39,7 @@ Left _ -> run gy s Right x -> pure $ Right x -run :: Get s m a -> s -> m (Either String (s, a))+run :: Get s m a -> s -> m (Either ([String], Exception.SomeException) (s, a)) run (Get f) = f get :: Applicative m => Get s m s@@ -46,3 +50,19 @@ lift :: Functor m => m a -> Get s m a lift m = Get $ \s -> fmap (\x -> Right (s, x)) m++throw :: (Exception.Exception e, Applicative m) => e -> Get s m a+throw = Get . const . pure . Left . (,) [] . Exception.toException++embed :: Monad m => Get s m a -> s -> Get t m a+embed g s = do+ r <- lift $ run g s+ case r of+ Left (ls, e) -> labels ls $ throw e+ Right (_, x) -> pure x++labels :: Functor m => [String] -> Get s m a -> Get s m a+labels ls g = Get $ fmap (Bifunctor.first $ Bifunctor.first (ls <>)) . run g++label :: Functor m => String -> Get s m a -> Get s m a+label = labels . pure
src/lib/Rattletrap/Type/Attribute.hs view
@@ -1,9 +1,13 @@ module Rattletrap.Type.Attribute where +import qualified Control.Exception as Exception 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.Exception.MissingAttributeLimit as MissingAttributeLimit+import qualified Rattletrap.Exception.MissingAttributeName as MissingAttributeName+import qualified Rattletrap.Exception.UnknownActor as UnknownActor import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.AttributeValue as AttributeValue import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap@@ -54,12 +58,12 @@ -> Map.Map CompressedWord.CompressedWord U32.U32 -> CompressedWord.CompressedWord -> BitGet.BitGet Attribute-bitGet version classes actors actor = do+bitGet version classes actors actor = BitGet.label "Attribute" $ do attributes <- lookupAttributeMap classes actors actor limit <- lookupAttributeIdLimit attributes actor- id <- CompressedWord.bitGet limit+ id <- BitGet.label "id" $ CompressedWord.bitGet limit name <- lookupAttributeName classes attributes id- value <- AttributeValue.bitGet+ value <- BitGet.label "value" $ AttributeValue.bitGet version (ClassAttributeMap.objectMap classes) name@@ -71,7 +75,7 @@ -> CompressedWord.CompressedWord -> BitGet.BitGet (Map.Map U32.U32 U32.U32) lookupAttributeMap classes actors actor = fromMaybe- ("[RT01] could not get attribute map for " <> show actor)+ (UnknownActor.UnknownActor $ CompressedWord.value actor) (ClassAttributeMap.getAttributeMap classes actors actor) lookupAttributeIdLimit@@ -79,7 +83,7 @@ -> CompressedWord.CompressedWord -> BitGet.BitGet Word lookupAttributeIdLimit attributes actor = fromMaybe- ("[RT02] could not get attribute ID limit for " <> show actor)+ (MissingAttributeLimit.MissingAttributeLimit $ CompressedWord.value actor) (ClassAttributeMap.getAttributeIdLimit attributes) lookupAttributeName@@ -88,8 +92,8 @@ -> CompressedWord.CompressedWord -> BitGet.BitGet Str.Str lookupAttributeName classes attributes attribute = fromMaybe- ("[RT03] could not get attribute name for " <> show attribute)+ (MissingAttributeName.MissingAttributeName $ CompressedWord.value attribute) (ClassAttributeMap.getAttributeName classes attributes attribute) -fromMaybe :: String -> Maybe a -> BitGet.BitGet a-fromMaybe message = maybe (fail message) pure+fromMaybe :: Exception.Exception e => e -> Maybe a -> BitGet.BitGet a+fromMaybe message = maybe (BitGet.throw message) pure
src/lib/Rattletrap/Type/Attribute/AppliedDamage.hs view
@@ -49,9 +49,9 @@ <> I32.bitPut (unknown4 appliedDamageAttribute) bitGet :: Version.Version -> BitGet.BitGet AppliedDamage-bitGet version = do- unknown1 <- U8.bitGet- location <- Vector.bitGet version- unknown3 <- I32.bitGet- unknown4 <- I32.bitGet+bitGet version = BitGet.label "AppliedDamage" $ do+ unknown1 <- BitGet.label "unknown1" U8.bitGet+ location <- BitGet.label "location" $ Vector.bitGet version+ unknown3 <- BitGet.label "unknown3" I32.bitGet+ unknown4 <- BitGet.label "unknown4" I32.bitGet pure AppliedDamage { unknown1, location, unknown3, unknown4 }
src/lib/Rattletrap/Type/Attribute/Boolean.hs view
@@ -22,6 +22,6 @@ bitPut booleanAttribute = BitPut.bool (value booleanAttribute) bitGet :: BitGet.BitGet Boolean-bitGet = do- value <- BitGet.bool+bitGet = BitGet.label "Boolean" $ do+ value <- BitGet.label "value" BitGet.bool pure Boolean { value }
src/lib/Rattletrap/Type/Attribute/Byte.hs view
@@ -23,6 +23,6 @@ bitPut byteAttribute = U8.bitPut (value byteAttribute) bitGet :: BitGet.BitGet Byte-bitGet = do- value <- U8.bitGet+bitGet = BitGet.label "Byte" $ do+ value <- BitGet.label "value" U8.bitGet pure Byte { value }
src/lib/Rattletrap/Type/Attribute/CamSettings.hs view
@@ -73,16 +73,15 @@ <> foldMap F32.bitPut (transitionSpeed camSettingsAttribute) bitGet :: Version.Version -> BitGet.BitGet CamSettings-bitGet version = do- fov <- F32.bitGet- height <- F32.bitGet- angle <- F32.bitGet- distance <- F32.bitGet- stiffness <- F32.bitGet- swivelSpeed <- F32.bitGet- transitionSpeed <- Monad.whenMaybe- (Version.atLeast 868 20 0 version)- F32.bitGet+bitGet version = BitGet.label "CamSettings" $ do+ fov <- BitGet.label "fov" F32.bitGet+ height <- BitGet.label "height" F32.bitGet+ angle <- BitGet.label "angle" F32.bitGet+ distance <- BitGet.label "distance" F32.bitGet+ stiffness <- BitGet.label "stiffness" F32.bitGet+ swivelSpeed <- BitGet.label "swivelSpeed" F32.bitGet+ transitionSpeed <- BitGet.label "transitionSpeed"+ $ Monad.whenMaybe (Version.atLeast 868 20 0 version) F32.bitGet pure CamSettings { fov , height
src/lib/Rattletrap/Type/Attribute/ClubColors.hs view
@@ -46,9 +46,9 @@ <> U8.bitPut (orangeColor clubColorsAttribute) bitGet :: BitGet.BitGet ClubColors-bitGet = do- blueFlag <- BitGet.bool- blueColor <- U8.bitGet- orangeFlag <- BitGet.bool- orangeColor <- U8.bitGet+bitGet = BitGet.label "ClubColors" $ do+ blueFlag <- BitGet.label "blueFlag" BitGet.bool+ blueColor <- BitGet.label "blueColor" U8.bitGet+ orangeFlag <- BitGet.label "orangeFlag" BitGet.bool+ orangeColor <- BitGet.label "orangeColor" U8.bitGet pure ClubColors { blueFlag, blueColor, orangeFlag, orangeColor }
src/lib/Rattletrap/Type/Attribute/CustomDemolish.hs view
@@ -44,10 +44,10 @@ <> Demolish.bitPut (demolish x) bitGet :: Version.Version -> BitGet.BitGet CustomDemolish-bitGet version = do- flag <- BitGet.bool- id <- I32.bitGet- demolish <- Demolish.bitGet version+bitGet version = BitGet.label "CustomDemolish" $ do+ flag <- BitGet.label "flag" BitGet.bool+ id <- BitGet.label "id" I32.bitGet+ demolish <- BitGet.label "demolish" $ Demolish.bitGet version pure CustomDemolish { flag , Rattletrap.Type.Attribute.CustomDemolish.id
src/lib/Rattletrap/Type/Attribute/DamageState.hs view
@@ -66,13 +66,13 @@ <> BitPut.bool (unknown6 damageStateAttribute) bitGet :: Version.Version -> BitGet.BitGet DamageState-bitGet version = do- unknown1 <- U8.bitGet- unknown2 <- BitGet.bool- unknown3 <- I32.bitGet- unknown4 <- Vector.bitGet version- unknown5 <- BitGet.bool- unknown6 <- BitGet.bool+bitGet version = BitGet.label "CustomDemolish" $ do+ unknown1 <- BitGet.label "unknown1" U8.bitGet+ unknown2 <- BitGet.label "unknown2" BitGet.bool+ unknown3 <- BitGet.label "unknown3" I32.bitGet+ unknown4 <- BitGet.label "unknown4" $ Vector.bitGet version+ unknown5 <- BitGet.label "unknown5" BitGet.bool+ unknown6 <- BitGet.label "unknown6" BitGet.bool pure DamageState { unknown1 , unknown2
src/lib/Rattletrap/Type/Attribute/Demolish.hs view
@@ -65,13 +65,13 @@ <> Vector.bitPut (victimVelocity demolishAttribute) bitGet :: Version.Version -> BitGet.BitGet Demolish-bitGet version = do- attackerFlag <- BitGet.bool- attackerActorId <- U32.bitGet- victimFlag <- BitGet.bool- victimActorId <- U32.bitGet- attackerVelocity <- Vector.bitGet version- victimVelocity <- Vector.bitGet version+bitGet version = BitGet.label "Demolish" $ do+ attackerFlag <- BitGet.label "attackerFlag" BitGet.bool+ attackerActorId <- BitGet.label "attackerActorId" U32.bitGet+ victimFlag <- BitGet.label "victimFlag" BitGet.bool+ victimActorId <- BitGet.label "victimActorId" U32.bitGet+ attackerVelocity <- BitGet.label "attackerVelocity" $ Vector.bitGet version+ victimVelocity <- BitGet.label "victimVelocity" $ Vector.bitGet version pure Demolish { attackerFlag , attackerActorId
src/lib/Rattletrap/Type/Attribute/Enum.hs view
@@ -24,6 +24,6 @@ bitPut enumAttribute = BitPut.bits 11 (value enumAttribute) bitGet :: BitGet.BitGet Enum-bitGet = do- value <- BitGet.bits 11+bitGet = BitGet.label "Enum" $ do+ value <- BitGet.label "value" $ BitGet.bits 11 pure Enum { value }
src/lib/Rattletrap/Type/Attribute/Explosion.hs view
@@ -43,8 +43,8 @@ <> Vector.bitPut (location explosionAttribute) bitGet :: Version.Version -> BitGet.BitGet Explosion-bitGet version = do- flag <- BitGet.bool- actorId <- I32.bitGet- location <- Vector.bitGet version+bitGet version = BitGet.label "Explosion" $ do+ flag <- BitGet.label "flag" BitGet.bool+ actorId <- BitGet.label "actorId" I32.bitGet+ location <- BitGet.label "location" $ Vector.bitGet version pure Explosion { flag, actorId, location }
src/lib/Rattletrap/Type/Attribute/ExtendedExplosion.hs view
@@ -34,7 +34,7 @@ bitPut x = Explosion.bitPut (explosion x) <> FlaggedInt.bitPut (unknown x) bitGet :: Version.Version -> BitGet.BitGet ExtendedExplosion-bitGet version = do- explosion <- Explosion.bitGet version- unknown <- FlaggedInt.bitGet+bitGet version = BitGet.label "ExtendedExplosion" $ do+ explosion <- BitGet.label "explosion" $ Explosion.bitGet version+ unknown <- BitGet.label "unknown" FlaggedInt.bitGet pure ExtendedExplosion { explosion, unknown }
src/lib/Rattletrap/Type/Attribute/FlaggedByte.hs view
@@ -33,7 +33,7 @@ <> U8.bitPut (byte flaggedByteAttribute) bitGet :: BitGet.BitGet FlaggedByte-bitGet = do- flag <- BitGet.bool- byte <- U8.bitGet+bitGet = BitGet.label "FlaggedByte" $ do+ flag <- BitGet.label "flag" BitGet.bool+ byte <- BitGet.label "byte" U8.bitGet pure FlaggedByte { flag, byte }
src/lib/Rattletrap/Type/Attribute/FlaggedInt.hs view
@@ -32,7 +32,7 @@ <> I32.bitPut (int flaggedIntAttribute) bitGet :: BitGet.BitGet FlaggedInt-bitGet = do- flag <- BitGet.bool- int <- I32.bitGet+bitGet = BitGet.label "FlaggedInt" $ do+ flag <- BitGet.label "flag" BitGet.bool+ int <- BitGet.label "int" I32.bitGet pure FlaggedInt { flag, int }
src/lib/Rattletrap/Type/Attribute/Float.hs view
@@ -24,6 +24,6 @@ bitPut floatAttribute = F32.bitPut (value floatAttribute) bitGet :: BitGet.BitGet Float-bitGet = do- value <- F32.bitGet+bitGet = BitGet.label "Float" $ do+ value <- BitGet.label "value" F32.bitGet pure Float { value }
src/lib/Rattletrap/Type/Attribute/GameMode.hs view
@@ -38,7 +38,7 @@ BitPut.bits (numBits gameModeAttribute) (word gameModeAttribute) bitGet :: Version.Version -> BitGet.BitGet GameMode-bitGet version = do+bitGet version = BitGet.label "GameMode" $ do let numBits = if Version.atLeast 868 12 0 version then 8 else 2 :: Int- word <- BitGet.bits numBits+ word <- BitGet.label "word" $ BitGet.bits numBits pure GameMode { numBits, word }
src/lib/Rattletrap/Type/Attribute/Int.hs view
@@ -24,6 +24,6 @@ bitPut intAttribute = I32.bitPut (value intAttribute) bitGet :: BitGet.BitGet Int-bitGet = do- value <- I32.bitGet+bitGet = BitGet.label "Int" $ do+ value <- BitGet.label "value" I32.bitGet pure Int { value }
src/lib/Rattletrap/Type/Attribute/Int64.hs view
@@ -23,6 +23,6 @@ putInt64Attribute int64Attribute = I64.bitPut (value int64Attribute) bitGet :: BitGet.BitGet Int64-bitGet = do- value <- I64.bitGet+bitGet = BitGet.label "Int64" $ do+ value <- BitGet.label "value" I64.bitGet pure Int64 { value }
src/lib/Rattletrap/Type/Attribute/Loadout.hs view
@@ -132,24 +132,33 @@ <> foldMap U32.bitPut (unknown6 loadoutAttribute) bitGet :: BitGet.BitGet Loadout-bitGet = do- version <- U8.bitGet- body <- U32.bitGet- decal <- U32.bitGet- wheels <- U32.bitGet- rocketTrail <- U32.bitGet- antenna <- U32.bitGet- topper <- U32.bitGet- unknown1 <- U32.bitGet- unknown2 <- Monad.whenMaybe (U8.toWord8 version >= 11) U32.bitGet- engineAudio <- Monad.whenMaybe (U8.toWord8 version >= 16) U32.bitGet- trail <- Monad.whenMaybe (U8.toWord8 version >= 16) U32.bitGet- goalExplosion <- Monad.whenMaybe (U8.toWord8 version >= 16) U32.bitGet- banner <- Monad.whenMaybe (U8.toWord8 version >= 17) U32.bitGet- unknown3 <- Monad.whenMaybe (U8.toWord8 version >= 19) U32.bitGet- unknown4 <- Monad.whenMaybe (U8.toWord8 version >= 22) U32.bitGet- unknown5 <- Monad.whenMaybe (U8.toWord8 version >= 22) U32.bitGet- unknown6 <- Monad.whenMaybe (U8.toWord8 version >= 22) U32.bitGet+bitGet = BitGet.label "Loadout" $ do+ version <- BitGet.label "version" U8.bitGet+ body <- BitGet.label "body" U32.bitGet+ decal <- BitGet.label "decal" U32.bitGet+ wheels <- BitGet.label "wheels" U32.bitGet+ rocketTrail <- BitGet.label "rocketTrail" U32.bitGet+ antenna <- BitGet.label "antenna" U32.bitGet+ topper <- BitGet.label "topper" U32.bitGet+ unknown1 <- BitGet.label "unknown1" U32.bitGet+ unknown2 <- BitGet.label "unknown2"+ $ Monad.whenMaybe (U8.toWord8 version >= 11) U32.bitGet+ engineAudio <- BitGet.label "engineAudio"+ $ Monad.whenMaybe (U8.toWord8 version >= 16) U32.bitGet+ trail <- BitGet.label "trail"+ $ Monad.whenMaybe (U8.toWord8 version >= 16) U32.bitGet+ goalExplosion <- BitGet.label "goalExplosion"+ $ Monad.whenMaybe (U8.toWord8 version >= 16) U32.bitGet+ banner <- BitGet.label "banner"+ $ Monad.whenMaybe (U8.toWord8 version >= 17) U32.bitGet+ unknown3 <- BitGet.label "unknown3"+ $ Monad.whenMaybe (U8.toWord8 version >= 19) U32.bitGet+ unknown4 <- BitGet.label "unknown4"+ $ Monad.whenMaybe (U8.toWord8 version >= 22) U32.bitGet+ unknown5 <- BitGet.label "unknown5"+ $ Monad.whenMaybe (U8.toWord8 version >= 22) U32.bitGet+ unknown6 <- BitGet.label "unknown6"+ $ Monad.whenMaybe (U8.toWord8 version >= 22) U32.bitGet pure Loadout { version , body
src/lib/Rattletrap/Type/Attribute/LoadoutOnline.hs view
@@ -1,5 +1,6 @@ module Rattletrap.Type.Attribute.LoadoutOnline where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -11,8 +12,6 @@ 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)@@ -39,9 +38,10 @@ bitGet :: Version.Version -> Map.Map U32.U32 Str.Str -> BitGet.BitGet LoadoutOnline-bitGet version objectMap = do- size <- U8.bitGet+bitGet version objectMap = BitGet.label "LoadoutOnline" $ do+ size <- BitGet.label "size" U8.bitGet value <-- List.replicateM (fromIntegral $ U8.toWord8 size)- $ Product.decodeProductAttributesBits version objectMap+ BitGet.label "value"+ . List.replicateM (fromIntegral $ U8.toWord8 size)+ $ Product.decodeProductAttributesBits version objectMap pure LoadoutOnline { value }
src/lib/Rattletrap/Type/Attribute/Loadouts.hs view
@@ -33,7 +33,7 @@ <> Loadout.bitPut (orange loadoutsAttribute) bitGet :: BitGet.BitGet Loadouts-bitGet = do- blue <- Loadout.bitGet- orange <- Loadout.bitGet+bitGet = BitGet.label "Loadouts" $ do+ blue <- BitGet.label "blue" Loadout.bitGet+ orange <- BitGet.label "orange" Loadout.bitGet pure Loadouts { blue, orange }
src/lib/Rattletrap/Type/Attribute/LoadoutsOnline.hs view
@@ -1,5 +1,6 @@ module Rattletrap.Type.Attribute.LoadoutsOnline where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -9,8 +10,6 @@ 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@@ -52,9 +51,9 @@ bitGet :: Version.Version -> Map.Map U32.U32 Str.Str -> BitGet.BitGet LoadoutsOnline-bitGet version objectMap = do- blue <- LoadoutOnline.bitGet version objectMap- orange <- LoadoutOnline.bitGet version objectMap- unknown1 <- BitGet.bool- unknown2 <- BitGet.bool+bitGet version objectMap = BitGet.label "LoadoutsOnline" $ do+ blue <- BitGet.label "blue" $ LoadoutOnline.bitGet version objectMap+ orange <- BitGet.label "orange" $ LoadoutOnline.bitGet version objectMap+ unknown1 <- BitGet.label "unknown1" BitGet.bool+ unknown2 <- BitGet.label "unknown2" BitGet.bool pure LoadoutsOnline { blue, orange, unknown1, unknown2 }
src/lib/Rattletrap/Type/Attribute/Location.hs view
@@ -24,6 +24,6 @@ bitPut locationAttribute = Vector.bitPut (value locationAttribute) bitGet :: Version.Version -> BitGet.BitGet Location-bitGet version = do- value <- Vector.bitGet version+bitGet version = BitGet.label "Location" $ do+ value <- BitGet.label "value" $ Vector.bitGet version pure Location { value }
src/lib/Rattletrap/Type/Attribute/MusicStinger.hs view
@@ -42,8 +42,8 @@ <> U8.bitPut (trigger musicStingerAttribute) bitGet :: BitGet.BitGet MusicStinger-bitGet = do- flag <- BitGet.bool- cue <- U32.bitGet- trigger <- U8.bitGet+bitGet = BitGet.label "MusicStinger" $ do+ flag <- BitGet.label "flag" BitGet.bool+ cue <- BitGet.label "cue" U32.bitGet+ trigger <- BitGet.label "trigger" U8.bitGet pure MusicStinger { flag, cue, trigger }
src/lib/Rattletrap/Type/Attribute/PartyLeader.hs view
@@ -51,12 +51,12 @@ (localId x) bitGet :: Version.Version -> BitGet.BitGet PartyLeader-bitGet version = do- systemId <- U8.bitGet+bitGet version = BitGet.label "PartyLeader" $ do+ systemId <- BitGet.label "systemId" U8.bitGet (remoteId, localId) <- if systemId == U8.fromWord8 0 then pure (Nothing, Nothing) else do- remoteId <- RemoteId.bitGet version systemId- localId <- U8.bitGet+ remoteId <- BitGet.label "remoteId" $ RemoteId.bitGet version systemId+ localId <- BitGet.label "localId" U8.bitGet pure (Just remoteId, Just localId) pure PartyLeader { systemId, remoteId, localId }
src/lib/Rattletrap/Type/Attribute/Pickup.hs view
@@ -40,8 +40,9 @@ <> BitPut.bool (pickedUp x) bitGet :: BitGet.BitGet Pickup-bitGet = do- instigator <- BitGet.bool- instigatorId <- Monad.whenMaybe instigator U32.bitGet- pickedUp <- BitGet.bool+bitGet = BitGet.label "Pickup" $ do+ instigator <- BitGet.label "instigator" BitGet.bool+ instigatorId <- BitGet.label "instigatorId"+ $ Monad.whenMaybe instigator U32.bitGet+ pickedUp <- BitGet.label "pickedUp" BitGet.bool pure Pickup { instigatorId, pickedUp }
src/lib/Rattletrap/Type/Attribute/PickupNew.hs view
@@ -41,8 +41,9 @@ <> U8.bitPut (pickedUp x) bitGet :: BitGet.BitGet PickupNew-bitGet = do- instigator <- BitGet.bool- instigatorId <- Monad.whenMaybe instigator U32.bitGet- pickedUp <- U8.bitGet+bitGet = BitGet.label "PickupNew" $ do+ instigator <- BitGet.label "instigator" BitGet.bool+ instigatorId <- BitGet.label "instigatorId"+ $ Monad.whenMaybe instigator U32.bitGet+ pickedUp <- BitGet.label "pickedUp" U8.bitGet pure PickupNew { instigatorId, pickedUp }
src/lib/Rattletrap/Type/Attribute/PlayerHistoryKey.hs view
@@ -24,6 +24,6 @@ bitPut = BitPut.bits 14 . unknown bitGet :: BitGet.BitGet PlayerHistoryKey-bitGet = do- unknown <- BitGet.bits 14+bitGet = BitGet.label "PlayerHistoryKey" $ do+ unknown <- BitGet.label "unknown" $ BitGet.bits 14 pure PlayerHistoryKey { unknown }
src/lib/Rattletrap/Type/Attribute/PrivateMatchSettings.hs view
@@ -64,13 +64,13 @@ <> BitPut.bool (flag privateMatchSettingsAttribute) bitGet :: BitGet.BitGet PrivateMatchSettings-bitGet = do- mutators <- Str.bitGet- joinableBy <- U32.bitGet- maxPlayers <- U32.bitGet- gameName <- Str.bitGet- password <- Str.bitGet- flag <- BitGet.bool+bitGet = BitGet.label "PrivateMatchSettings" $ do+ mutators <- BitGet.label "mutators" Str.bitGet+ joinableBy <- BitGet.label "joinableBy" U32.bitGet+ maxPlayers <- BitGet.label "maxPlayers" U32.bitGet+ gameName <- BitGet.label "gameName" Str.bitGet+ password <- BitGet.label "password" Str.bitGet+ flag <- BitGet.label "flag" BitGet.bool pure PrivateMatchSettings { mutators , joinableBy
src/lib/Rattletrap/Type/Attribute/Product.hs view
@@ -1,5 +1,6 @@ module Rattletrap.Type.Attribute.Product where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -11,8 +12,6 @@ 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@@ -66,9 +65,10 @@ 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_)+bitGet version objectMap = BitGet.label "Product" $ do+ unknown <- BitGet.label "unknown" BitGet.bool+ objectId <- BitGet.label "objectId" U32.bitGet+ let objectName = Map.lookup objectId objectMap+ value <- BitGet.label "value"+ $ ProductValue.bitGet version objectId objectName+ pure Product { unknown, objectId, objectName, value }
src/lib/Rattletrap/Type/Attribute/ProductValue.hs view
@@ -4,6 +4,8 @@ import qualified Data.Word as Word import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Exception.MissingProductName as MissingProductName+import qualified Rattletrap.Exception.UnknownProduct as UnknownProduct import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.CompressedWord as CompressedWord import qualified Rattletrap.Type.Str as Str@@ -75,42 +77,42 @@ bitGet :: Version.Version -> U32.U32 -> Maybe Str.Str -> BitGet.BitGet ProductValue bitGet version objectId maybeObjectName =- case fmap Str.toString maybeObjectName of+ BitGet.label "ProductValue" $ case fmap 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)+ Just x -> BitGet.throw $ UnknownProduct.UnknownProduct x+ Nothing ->+ BitGet.throw . MissingProductName.MissingProductName $ U32.toWord32+ objectId decodeSpecialEdition :: BitGet.BitGet ProductValue-decodeSpecialEdition = fmap SpecialEdition $ BitGet.bits 31+decodeSpecialEdition =+ BitGet.label "SpecialEdition" . fmap SpecialEdition $ BitGet.bits 31 decodePainted :: Version.Version -> BitGet.BitGet ProductValue-decodePainted version = if hasNewPainted version+decodePainted version = BitGet.label "Painted" $ if hasNewPainted version then fmap PaintedNew $ BitGet.bits 31 else fmap PaintedOld $ CompressedWord.bitGet 13 decodeTeamEdition :: Version.Version -> BitGet.BitGet ProductValue-decodeTeamEdition version = if hasNewPainted version- then fmap TeamEditionNew $ BitGet.bits 31- else fmap TeamEditionOld $ CompressedWord.bitGet 13+decodeTeamEdition version =+ BitGet.label "TeamEdition" $ if hasNewPainted version+ then fmap TeamEditionNew $ BitGet.bits 31+ else fmap TeamEditionOld $ CompressedWord.bitGet 13 decodeColor :: Version.Version -> BitGet.BitGet ProductValue-decodeColor version = if Version.atLeast 868 23 8 version- then fmap UserColorNew U32.bitGet- else do- hasValue <- BitGet.bool- fmap UserColorOld $ Monad.whenMaybe hasValue (BitGet.bits 31)+decodeColor version =+ BitGet.label "UserColor" $ if Version.atLeast 868 23 8 version+ then fmap UserColorNew U32.bitGet+ else do+ hasValue <- BitGet.bool+ fmap UserColorOld $ Monad.whenMaybe hasValue (BitGet.bits 31) hasNewPainted :: Version.Version -> Bool hasNewPainted = Version.atLeast 868 18 0 decodeTitle :: BitGet.BitGet ProductValue-decodeTitle = fmap TitleId Str.bitGet+decodeTitle = BitGet.label "Title" $ fmap TitleId Str.bitGet
src/lib/Rattletrap/Type/Attribute/QWord.hs view
@@ -23,6 +23,6 @@ bitPut qWordAttribute = U64.bitPut (value qWordAttribute) bitGet :: BitGet.BitGet QWord-bitGet = do- value <- U64.bitGet+bitGet = BitGet.label "QWord" $ do+ value <- BitGet.label "value" U64.bitGet pure QWord { value }
src/lib/Rattletrap/Type/Attribute/Reservation.hs view
@@ -62,14 +62,16 @@ <> foldMap (BitPut.bits 6) (unknown3 reservationAttribute) bitGet :: Version.Version -> BitGet.BitGet Reservation-bitGet version = do- number <- CompressedWord.bitGet 7- uniqueId <- UniqueId.bitGet version- name <- Monad.whenMaybe+bitGet version = BitGet.label "Reservation" $ do+ number <- BitGet.label "number" $ CompressedWord.bitGet 7+ uniqueId <- BitGet.label "uniqueId" $ UniqueId.bitGet version+ name <- BitGet.label "name" $ Monad.whenMaybe (UniqueId.systemId uniqueId /= U8.fromWord8 0) Str.bitGet- unknown1 <- BitGet.bool- unknown2 <- BitGet.bool- unknown3 <- Monad.whenMaybe (Version.atLeast 868 12 0 version)+ unknown1 <- BitGet.label "unknown1" BitGet.bool+ unknown2 <- BitGet.label "unknown2" BitGet.bool+ unknown3 <-+ BitGet.label "unknown3"+ . Monad.whenMaybe (Version.atLeast 868 12 0 version) $ BitGet.bits 6 pure Reservation { number, uniqueId, name, unknown1, unknown2, unknown3 }
src/lib/Rattletrap/Type/Attribute/RigidBodyState.hs view
@@ -64,12 +64,14 @@ <> foldMap Vector.bitPut (angularVelocity rigidBodyStateAttribute) bitGet :: Version.Version -> BitGet.BitGet RigidBodyState-bitGet version = do- sleeping <- BitGet.bool- location <- Vector.bitGet version- rotation <- Rotation.bitGet version- linearVelocity <- Monad.whenMaybe (not sleeping) (Vector.bitGet version)- angularVelocity <- Monad.whenMaybe (not sleeping) (Vector.bitGet version)+bitGet version = BitGet.label "RigidBodyState" $ do+ sleeping <- BitGet.label "sleeping" BitGet.bool+ location <- BitGet.label "location" $ Vector.bitGet version+ rotation <- BitGet.label "rotation" $ Rotation.bitGet version+ linearVelocity <- BitGet.label "linearVelocity"+ $ Monad.whenMaybe (not sleeping) (Vector.bitGet version)+ angularVelocity <- BitGet.label "angularVelocity"+ $ Monad.whenMaybe (not sleeping) (Vector.bitGet version) pure RigidBodyState { sleeping , location
src/lib/Rattletrap/Type/Attribute/StatEvent.hs view
@@ -33,7 +33,7 @@ <> I32.bitPut (objectId statEventAttribute) bitGet :: BitGet.BitGet StatEvent-bitGet = do- unknown <- BitGet.bool- objectId <- I32.bitGet+bitGet = BitGet.label "StatEvent" $ do+ unknown <- BitGet.label "unknown" BitGet.bool+ objectId <- BitGet.label "objectId" I32.bitGet pure StatEvent { unknown, objectId }
src/lib/Rattletrap/Type/Attribute/String.hs view
@@ -24,6 +24,6 @@ bitPut stringAttribute = Str.bitPut (value stringAttribute) bitGet :: BitGet.BitGet String-bitGet = do- value <- Str.bitGet+bitGet = BitGet.label "String" $ do+ value <- BitGet.label "value" Str.bitGet pure String { value }
src/lib/Rattletrap/Type/Attribute/TeamPaint.hs view
@@ -58,12 +58,12 @@ <> U32.bitPut (accentFinish teamPaintAttribute) bitGet :: BitGet.BitGet TeamPaint-bitGet = do- team <- U8.bitGet- primaryColor <- U8.bitGet- accentColor <- U8.bitGet- primaryFinish <- U32.bitGet- accentFinish <- U32.bitGet+bitGet = BitGet.label "TeamPaint" $ do+ team <- BitGet.label "team" U8.bitGet+ primaryColor <- BitGet.label "primaryColor" U8.bitGet+ accentColor <- BitGet.label "accentColor" U8.bitGet+ primaryFinish <- BitGet.label "primaryFinish" U32.bitGet+ accentFinish <- BitGet.label "accentFinish" U32.bitGet pure TeamPaint { team , primaryColor
src/lib/Rattletrap/Type/Attribute/Title.hs view
@@ -75,15 +75,15 @@ <> BitPut.bool (unknown8 titleAttribute) bitGet :: BitGet.BitGet Title-bitGet = do- unknown1 <- BitGet.bool- unknown2 <- BitGet.bool- unknown3 <- U32.bitGet- unknown4 <- U32.bitGet- unknown5 <- U32.bitGet- unknown6 <- U32.bitGet- unknown7 <- U32.bitGet- unknown8 <- BitGet.bool+bitGet = BitGet.label "Title" $ do+ unknown1 <- BitGet.label "unknown1" BitGet.bool+ unknown2 <- BitGet.label "unknown2" BitGet.bool+ unknown3 <- BitGet.label "unknown3" U32.bitGet+ unknown4 <- BitGet.label "unknown4" U32.bitGet+ unknown5 <- BitGet.label "unknown5" U32.bitGet+ unknown6 <- BitGet.label "unknown6" U32.bitGet+ unknown7 <- BitGet.label "unknown7" U32.bitGet+ unknown8 <- BitGet.label "unknown8" BitGet.bool pure Title { unknown1 , unknown2
src/lib/Rattletrap/Type/Attribute/UniqueId.hs view
@@ -43,8 +43,8 @@ <> U8.bitPut (localId uniqueIdAttribute) bitGet :: Version.Version -> BitGet.BitGet UniqueId-bitGet version = do- systemId <- U8.bitGet- remoteId <- RemoteId.bitGet version systemId- localId <- U8.bitGet+bitGet version = BitGet.label "UniqueId" $ do+ systemId <- BitGet.label "systemId" U8.bitGet+ remoteId <- BitGet.label "remoteId" $ RemoteId.bitGet version systemId+ localId <- BitGet.label "localId" U8.bitGet pure UniqueId { systemId, remoteId, localId }
src/lib/Rattletrap/Type/Attribute/WeldedInfo.hs view
@@ -55,10 +55,10 @@ <> Int8Vector.bitPut (rotation weldedInfoAttribute) bitGet :: Version.Version -> BitGet.BitGet WeldedInfo-bitGet version = do- active <- BitGet.bool- actorId <- I32.bitGet- offset <- Vector.bitGet version- mass <- F32.bitGet- rotation <- Int8Vector.bitGet+bitGet version = BitGet.label "WeldedInfo" $ do+ active <- BitGet.label "active" BitGet.bool+ actorId <- BitGet.label "actorId" I32.bitGet+ offset <- BitGet.label "offset" $ Vector.bitGet version+ mass <- BitGet.label "mass" F32.bitGet+ rotation <- BitGet.label "rotation" Int8Vector.bitGet pure WeldedInfo { active, actorId, offset, mass, rotation }
src/lib/Rattletrap/Type/AttributeMapping.hs view
@@ -32,7 +32,7 @@ bytePut x = U32.bytePut (objectId x) <> U32.bytePut (streamId x) byteGet :: ByteGet.ByteGet AttributeMapping-byteGet = do- objectId <- U32.byteGet- streamId <- U32.byteGet+byteGet = ByteGet.label "AttributeMapping" $ do+ objectId <- ByteGet.label "objectId" U32.byteGet+ streamId <- ByteGet.label "streamId" U32.byteGet pure AttributeMapping { objectId, streamId }
src/lib/Rattletrap/Type/AttributeValue.hs view
@@ -1,8 +1,11 @@ module Rattletrap.Type.AttributeValue where +import qualified Data.Foldable as Foldable+import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Data as Data+import qualified Rattletrap.Exception.UnknownAttribute as UnknownAttribute import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.Attribute.AppliedDamage as AppliedDamage import qualified Rattletrap.Type.Attribute.Boolean as Boolean@@ -47,9 +50,6 @@ import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json -import qualified Data.Foldable as Foldable-import qualified Data.Map as Map- data AttributeValue = AppliedDamage AppliedDamage.AppliedDamage | Boolean Boolean.Boolean@@ -259,11 +259,11 @@ -> 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)+bitGet version objectMap name = BitGet.label "AttributeValue" $ do+ constructor <- case Map.lookup (Str.toText name) Data.attributeTypes of+ Nothing ->+ BitGet.throw . UnknownAttribute.UnknownAttribute $ Str.toString name+ Just x -> pure x case constructor of AttributeType.AppliedDamage -> fmap AppliedDamage $ AppliedDamage.bitGet version
src/lib/Rattletrap/Type/Cache.hs view
@@ -51,9 +51,10 @@ <> List.bytePut AttributeMapping.bytePut (attributeMappings x) byteGet :: ByteGet.ByteGet Cache-byteGet = do- classId <- U32.byteGet- parentCacheId <- U32.byteGet- cacheId <- U32.byteGet- attributeMappings <- List.byteGet AttributeMapping.byteGet+byteGet = ByteGet.label "Cache" $ do+ classId <- ByteGet.label "classId" U32.byteGet+ parentCacheId <- ByteGet.label "parentCacheId" U32.byteGet+ cacheId <- ByteGet.label "cacheId" U32.byteGet+ attributeMappings <- ByteGet.label "attributeMappings"+ $ List.byteGet AttributeMapping.byteGet pure Cache { classId, parentCacheId, cacheId, attributeMappings }
src/lib/Rattletrap/Type/ClassAttributeMap.hs view
@@ -1,5 +1,12 @@ module Rattletrap.Type.ClassAttributeMap where +import qualified Data.IntMap as IntMap+import qualified Data.List as List+import qualified Data.Map as Map+import qualified Data.Maybe as Maybe+import qualified Data.Set as Set+import qualified Data.Text as Text+import qualified Data.Tuple as Tuple import qualified Rattletrap.Data as Data import qualified Rattletrap.Type.AttributeMapping as AttributeMapping import qualified Rattletrap.Type.Cache as Cache@@ -8,14 +15,6 @@ 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-import qualified Data.Map as Map-import qualified Data.Maybe as Maybe-import qualified Data.Set as Set-import qualified Data.Text as Text-import qualified Data.Tuple as Tuple -- | This data structure holds all the information about classes, objects, and -- attributes in the replay. The class hierarchy is not fixed; it is encoded
src/lib/Rattletrap/Type/ClassMapping.hs view
@@ -33,7 +33,7 @@ bytePut x = Str.bytePut (name x) <> U32.bytePut (streamId x) byteGet :: ByteGet.ByteGet ClassMapping-byteGet = do- name <- Str.byteGet- streamId <- U32.byteGet+byteGet = ByteGet.label "ClassMapping" $ do+ name <- ByteGet.label "name" Str.byteGet+ streamId <- ByteGet.label "streamId" U32.byteGet pure ClassMapping { name, streamId }
src/lib/Rattletrap/Type/CompressedWord.hs view
@@ -1,11 +1,10 @@ module Rattletrap.Type.CompressedWord where +import qualified Data.Bits as Bits 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 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.
src/lib/Rattletrap/Type/Content.hs view
@@ -1,5 +1,8 @@ module Rattletrap.Type.Content where +import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Lazy as LazyByteString+import qualified Data.Word as Word import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.ByteGet as ByteGet@@ -20,11 +23,6 @@ import qualified Rattletrap.Utility.Bytes as Bytes import qualified Rattletrap.Utility.Json as Json -import qualified Control.Monad.Trans.State as State-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Lazy as LazyByteString-import qualified Data.Word as Word- type Content = ContentWith (List.List Frame.Frame) -- | Contains low-level game data about a 'Rattletrap.Replay.Replay'.@@ -191,32 +189,33 @@ -- ^ The maximum number of channels in the stream, usually from -- 'Rattletrap.Header.getMaxChannels'. -> ByteGet.ByteGet Content-byteGet matchType version numFrames maxChannels = do- levels <- List.byteGet Str.byteGet- keyframes <- List.byteGet Keyframe.byteGet- streamSize <- U32.byteGet- stream <- ByteGet.byteString . fromIntegral $ U32.toWord32 streamSize- messages <- List.byteGet Message.byteGet- marks <- List.byteGet Mark.byteGet- packages <- List.byteGet Str.byteGet- objects <- List.byteGet Str.byteGet- names <- List.byteGet Str.byteGet- classMappings <- List.byteGet ClassMapping.byteGet- caches <- List.byteGet Cache.byteGet+byteGet matchType version numFrames maxChannels = ByteGet.label "Content" $ do+ levels <- ByteGet.label "levels" $ List.byteGet Str.byteGet+ keyframes <- ByteGet.label "keyframes" $ List.byteGet Keyframe.byteGet+ streamSize <- ByteGet.label "streamSize" U32.byteGet+ stream <-+ ByteGet.label "stream" . ByteGet.byteString . fromIntegral $ U32.toWord32+ streamSize+ messages <- ByteGet.label "messages" $ List.byteGet Message.byteGet+ marks <- ByteGet.label "marks" $ List.byteGet Mark.byteGet+ packages <- ByteGet.label "packages" $ List.byteGet Str.byteGet+ objects <- ByteGet.label "objects" $ List.byteGet Str.byteGet+ names <- ByteGet.label "names" $ List.byteGet Str.byteGet+ classMappings <- ByteGet.label "classMappings"+ $ List.byteGet ClassMapping.byteGet+ caches <- ByteGet.label "caches" $ List.byteGet Cache.byteGet let classAttributeMap = ClassAttributeMap.make objects classMappings caches names- bitGet = State.evalStateT- (Frame.decodeFramesBits- matchType- version- numFrames- maxChannels- classAttributeMap- )- mempty- frames <- either fail pure $ ByteGet.run (BitGet.toByteGet bitGet) stream- unknown <- fmap LazyByteString.unpack ByteGet.remaining+ getFrames = BitGet.toByteGet $ Frame.decodeFramesBits+ matchType+ version+ numFrames+ maxChannels+ classAttributeMap+ frames <- ByteGet.label "frames" $ ByteGet.embed getFrames stream+ unknown <- ByteGet.label "unknown"+ $ fmap LazyByteString.unpack ByteGet.remaining pure Content { levels , keyframes
src/lib/Rattletrap/Type/Dictionary.hs view
@@ -1,5 +1,8 @@ module Rattletrap.Type.Dictionary where +import qualified Data.Bifunctor as Bifunctor+import qualified Data.Map as Map+import qualified Data.Text as Text import qualified Rattletrap.ByteGet as ByteGet import qualified Rattletrap.BytePut as BytePut import qualified Rattletrap.Schema as Schema@@ -7,10 +10,6 @@ import qualified Rattletrap.Type.Str as Str import qualified Rattletrap.Utility.Json as Json -import qualified Data.Bifunctor as Bifunctor-import qualified Data.Map as Map-import qualified Data.Text as Text- data Dictionary a = Dictionary { elements :: List.List (Str.Str, a) , lastKey :: Str.Str@@ -71,7 +70,7 @@ <> Str.bytePut (lastKey x) byteGet :: ByteGet.ByteGet a -> ByteGet.ByteGet (Dictionary a)-byteGet = byteGetWith 0 []+byteGet = ByteGet.label "Dictionary" . byteGetWith 0 [] byteGetWith :: Int@@ -79,14 +78,14 @@ -> ByteGet.ByteGet a -> ByteGet.ByteGet (Dictionary a) byteGetWith i xs f = do- k <- Str.byteGet+ k <- ByteGet.label ("key (" <> show i <> ")") Str.byteGet if isNone k then pure Dictionary { elements = List.fromList . reverse $ fmap snd xs , lastKey = k } else do- v <- f+ v <- ByteGet.label ("value (" <> Str.toString k <> ")") f byteGetWith (i + 1) ((i, (k, v)) : xs) f isNone :: Str.Str -> Bool
src/lib/Rattletrap/Type/F32.hs view
@@ -33,7 +33,7 @@ bitPut = BitPut.fromBytePut . bytePut byteGet :: ByteGet.ByteGet F32-byteGet = fmap fromFloat ByteGet.float+byteGet = ByteGet.label "F32" $ fmap fromFloat ByteGet.float bitGet :: BitGet.BitGet F32 bitGet = BitGet.fromByteGet byteGet 4
src/lib/Rattletrap/Type/Frame.hs view
@@ -1,5 +1,6 @@ module Rattletrap.Type.Frame where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -13,10 +14,6 @@ import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json -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 { time :: F32.F32 -- ^ Time in seconds since the beginning of the match.@@ -65,28 +62,65 @@ -> Int -> Word -> ClassAttributeMap.ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord.CompressedWord U32.U32)- BitGet.BitGet- (List.List Frame)+ -> BitGet.BitGet (List.List Frame) decodeFramesBits matchType version count limit classes =- List.replicateM count $ bitGet matchType version limit classes+ fmap snd $ decodeFramesBitsWith+ matchType+ version+ count+ limit+ classes+ Map.empty+ 0+ [] +decodeFramesBitsWith+ :: Maybe Str.Str+ -> Version.Version+ -> Int+ -> Word+ -> ClassAttributeMap.ClassAttributeMap+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> Int+ -> [Frame]+ -> BitGet.BitGet+ ( Map.Map CompressedWord.CompressedWord U32.U32+ , List.List Frame+ )+decodeFramesBitsWith matchType version count limit classes actorMap index frames+ = if index >= count+ then pure (actorMap, List.fromList $ reverse frames)+ else do+ (newActorMap, frame) <-+ BitGet.label ("element (" <> show index <> ")")+ $ bitGet matchType version limit classes actorMap+ decodeFramesBitsWith+ matchType+ version+ count+ limit+ classes+ newActorMap+ (index + 1)+ $ frame+ : frames+ bitGet :: Maybe Str.Str -> Version.Version -> Word -> ClassAttributeMap.ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord.CompressedWord U32.U32)- BitGet.BitGet- Frame-bitGet matchType version limit classes = do- time <- Trans.lift F32.bitGet- delta <- Trans.lift F32.bitGet- replications <- Replication.decodeReplicationsBits- matchType- version- limit- classes- pure Frame { time, delta, replications }+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> BitGet.BitGet+ (Map.Map CompressedWord.CompressedWord U32.U32, Frame)+bitGet matchType version limit classes actorMap = BitGet.label "Frame" $ do+ time <- BitGet.label "time" F32.bitGet+ delta <- BitGet.label "delta" F32.bitGet+ (newActorMap, replications) <-+ BitGet.label "replications" $ Replication.decodeReplicationsBits+ matchType+ version+ limit+ classes+ actorMap+ pure (newActorMap, Frame { time, delta, replications })
src/lib/Rattletrap/Type/Header.hs view
@@ -97,8 +97,9 @@ (properties x) byteGet :: ByteGet.ByteGet Header-byteGet = do- version <- Version.byteGet- label <- Str.byteGet- properties <- Dictionary.byteGet Property.byteGet+byteGet = ByteGet.label "Header" $ do+ version <- ByteGet.label "version" Version.byteGet+ label <- ByteGet.label "label" Str.byteGet+ properties <- ByteGet.label "properties"+ $ Dictionary.byteGet Property.byteGet pure Header { version, label, properties }
src/lib/Rattletrap/Type/I32.hs view
@@ -38,7 +38,7 @@ bitPut = BitPut.fromBytePut . bytePut byteGet :: ByteGet.ByteGet I32-byteGet = fmap fromInt32 ByteGet.int32+byteGet = ByteGet.label "I32" $ fmap fromInt32 ByteGet.int32 bitGet :: BitGet.BitGet I32 bitGet = BitGet.fromByteGet byteGet 4
src/lib/Rattletrap/Type/I64.hs view
@@ -1,14 +1,13 @@ module Rattletrap.Type.I64 where +import qualified Data.Int as Int+import qualified Data.Text as Text 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
src/lib/Rattletrap/Type/I8.hs view
@@ -38,7 +38,7 @@ bitPut = BitPut.fromBytePut . bytePut byteGet :: ByteGet.ByteGet I8-byteGet = fmap fromInt8 ByteGet.int8+byteGet = ByteGet.label "I8" $ fmap fromInt8 ByteGet.int8 bitGet :: BitGet.BitGet I8 bitGet = BitGet.fromByteGet byteGet 1
src/lib/Rattletrap/Type/Initialization.hs view
@@ -43,7 +43,9 @@ <> foldMap Int8Vector.bitPut (rotation initialization) bitGet :: Version.Version -> Bool -> Bool -> BitGet.BitGet Initialization-bitGet version hasLocation hasRotation = do- location <- Monad.whenMaybe hasLocation (Vector.bitGet version)- rotation <- Monad.whenMaybe hasRotation Int8Vector.bitGet+bitGet version hasLocation hasRotation = BitGet.label "Initialization" $ do+ location <- BitGet.label "location"+ $ Monad.whenMaybe hasLocation (Vector.bitGet version)+ rotation <- BitGet.label "rotation"+ $ Monad.whenMaybe hasRotation Int8Vector.bitGet pure Initialization { location, rotation }
src/lib/Rattletrap/Type/Int8Vector.hs view
@@ -44,10 +44,10 @@ Just field -> BitPut.bool True <> I8.bitPut field bitGet :: BitGet.BitGet Int8Vector-bitGet = do- x <- decodeFieldBits- y <- decodeFieldBits- z <- decodeFieldBits+bitGet = BitGet.label "Int8Vector" $ do+ x <- BitGet.label "x" decodeFieldBits+ y <- BitGet.label "y" decodeFieldBits+ z <- BitGet.label "z" decodeFieldBits pure Int8Vector { x, y, z } decodeFieldBits :: BitGet.BitGet (Maybe I8.I8)
src/lib/Rattletrap/Type/Keyframe.hs view
@@ -43,8 +43,8 @@ F32.bytePut (time x) <> U32.bytePut (frame x) <> U32.bytePut (position x) byteGet :: ByteGet.ByteGet Keyframe-byteGet = do- time <- F32.byteGet- frame <- U32.byteGet- position <- U32.byteGet+byteGet = ByteGet.label "Keyframe" $ do+ time <- ByteGet.label "time" F32.byteGet+ frame <- ByteGet.label "frame" U32.byteGet+ position <- ByteGet.label "position" U32.byteGet pure Keyframe { time, frame, position }
src/lib/Rattletrap/Type/List.hs view
@@ -1,13 +1,12 @@ module Rattletrap.Type.List where +import qualified Control.Monad as Monad 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 qualified Control.Monad as Monad- newtype List a = List [a] deriving (Eq, Show)@@ -36,9 +35,13 @@ 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+byteGet f = ByteGet.label "List" $ do+ size <- ByteGet.label "size" U32.byteGet+ generateM (fromIntegral $ U32.toWord32 size)+ $ \i -> ByteGet.label ("element (" <> show i <> ")") f++generateM :: Monad m => Int -> (Int -> m a) -> m (List a)+generateM n f = fmap fromList $ mapM f [0 .. n - 1] replicateM :: Monad m => Int -> m a -> m (List a) replicateM n = fmap fromList . Monad.replicateM n
src/lib/Rattletrap/Type/Mark.hs view
@@ -35,7 +35,7 @@ bytePut x = Str.bytePut (value x) <> U32.bytePut (frame x) byteGet :: ByteGet.ByteGet Mark-byteGet = do- value <- Str.byteGet- frame <- U32.byteGet+byteGet = ByteGet.label "Mark" $ do+ value <- ByteGet.label "value" Str.byteGet+ frame <- ByteGet.label "frame" U32.byteGet pure Mark { value, frame }
src/lib/Rattletrap/Type/Message.hs view
@@ -43,8 +43,8 @@ U32.bytePut (frame x) <> Str.bytePut (name x) <> Str.bytePut (value x) byteGet :: ByteGet.ByteGet Message-byteGet = do- frame <- U32.byteGet- name <- Str.byteGet- value <- Str.byteGet+byteGet = ByteGet.label "Message" $ do+ frame <- ByteGet.label "frame" U32.byteGet+ name <- ByteGet.label "name" Str.byteGet+ value <- ByteGet.label "value" Str.byteGet pure Message { frame, name, value }
src/lib/Rattletrap/Type/Property.hs view
@@ -44,8 +44,8 @@ (value x) byteGet :: ByteGet.ByteGet Property-byteGet = do- kind <- Str.byteGet- size <- U64.byteGet- value <- PropertyValue.byteGet byteGet kind+byteGet = ByteGet.label "Property" $ do+ kind <- ByteGet.label "kind" Str.byteGet+ size <- ByteGet.label "size" U64.byteGet+ value <- ByteGet.label "value" $ PropertyValue.byteGet byteGet kind pure Property { kind, size, value }
src/lib/Rattletrap/Type/Property/Array.hs view
@@ -32,4 +32,5 @@ bytePut f = List.bytePut (Dictionary.bytePut f) . toList byteGet :: ByteGet.ByteGet a -> ByteGet.ByteGet (Array a)-byteGet f = fmap fromList $ List.byteGet (Dictionary.byteGet f)+byteGet =+ ByteGet.label "Array" . fmap fromList . List.byteGet . Dictionary.byteGet
src/lib/Rattletrap/Type/Property/Bool.hs view
@@ -30,4 +30,4 @@ bytePut = U8.bytePut . toU8 byteGet :: ByteGet.ByteGet Bool-byteGet = fmap fromU8 U8.byteGet+byteGet = ByteGet.label "Bool" $ fmap fromU8 U8.byteGet
src/lib/Rattletrap/Type/Property/Byte.hs view
@@ -29,9 +29,9 @@ bytePut byte = Str.bytePut (key byte) <> foldMap Str.bytePut (value byte) byteGet :: ByteGet.ByteGet Byte-byteGet = do- key <- Str.byteGet- value <- Monad.whenMaybe+byteGet = ByteGet.label "Byte" $ do+ key <- ByteGet.label "key" Str.byteGet+ value <- ByteGet.label "value" $ Monad.whenMaybe (Str.toString key /= "OnlinePlatform_Steam") Str.byteGet pure Byte { key, value }
src/lib/Rattletrap/Type/Property/Float.hs view
@@ -30,4 +30,4 @@ bytePut = F32.bytePut . toF32 byteGet :: ByteGet.ByteGet Float-byteGet = fmap fromF32 F32.byteGet+byteGet = ByteGet.label "Float" $ fmap fromF32 F32.byteGet
src/lib/Rattletrap/Type/Property/Int.hs view
@@ -30,4 +30,4 @@ bytePut = I32.bytePut . toI32 byteGet :: ByteGet.ByteGet Int-byteGet = fmap fromI32 I32.byteGet+byteGet = ByteGet.label "I32" $ fmap fromI32 I32.byteGet
src/lib/Rattletrap/Type/Property/Name.hs view
@@ -29,4 +29,4 @@ bytePut = Str.bytePut . toStr byteGet :: ByteGet.ByteGet Name-byteGet = fmap fromStr Str.byteGet+byteGet = ByteGet.label "Name" $ fmap fromStr Str.byteGet
src/lib/Rattletrap/Type/Property/QWord.hs view
@@ -29,4 +29,4 @@ bytePut = U64.bytePut . toU64 byteGet :: ByteGet.ByteGet QWord-byteGet = fmap fromU64 U64.byteGet+byteGet = ByteGet.label "QWord" $ fmap fromU64 U64.byteGet
src/lib/Rattletrap/Type/Property/Str.hs view
@@ -29,4 +29,4 @@ bytePut = Str.bytePut . toStr byteGet :: ByteGet.ByteGet Str-byteGet = fmap fromStr Str.byteGet+byteGet = ByteGet.label "Str" $ fmap fromStr Str.byteGet
src/lib/Rattletrap/Type/PropertyValue.hs view
@@ -3,6 +3,7 @@ import qualified Data.Foldable as Foldable import qualified Rattletrap.ByteGet as ByteGet import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Exception.UnknownProperty as UnknownProperty import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.Property.Array as Property.Array import qualified Rattletrap.Type.Property.Bool as Property.Bool@@ -78,13 +79,14 @@ Str x -> Property.Str.bytePut x byteGet :: ByteGet.ByteGet a -> Str.Str -> ByteGet.ByteGet (PropertyValue a)-byteGet getProperty kind = case Str.toString kind of- "ArrayProperty" -> fmap Array $ Property.Array.byteGet getProperty- "BoolProperty" -> fmap Bool Property.Bool.byteGet- "ByteProperty" -> fmap Byte Property.Byte.byteGet- "FloatProperty" -> fmap Float Property.Float.byteGet- "IntProperty" -> fmap Int Property.Int.byteGet- "NameProperty" -> fmap Name Property.Name.byteGet- "QWordProperty" -> fmap QWord Property.QWord.byteGet- "StrProperty" -> fmap Str Property.Str.byteGet- _ -> fail ("[RT07] don't know how to read property value " <> show kind)+byteGet getProperty kind =+ ByteGet.label "PropertyValue" $ case Str.toString kind of+ "ArrayProperty" -> fmap Array $ Property.Array.byteGet getProperty+ "BoolProperty" -> fmap Bool Property.Bool.byteGet+ "ByteProperty" -> fmap Byte Property.Byte.byteGet+ "FloatProperty" -> fmap Float Property.Float.byteGet+ "IntProperty" -> fmap Int Property.Int.byteGet+ "NameProperty" -> fmap Name Property.Name.byteGet+ "QWordProperty" -> fmap QWord Property.QWord.byteGet+ "StrProperty" -> fmap Str Property.Str.byteGet+ x -> ByteGet.throw $ UnknownProperty.UnknownProperty x
src/lib/Rattletrap/Type/Quaternion.hs view
@@ -1,15 +1,15 @@ module Rattletrap.Type.Quaternion where +import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Data.Ord as Ord import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Exception.InvalidComponent as InvalidComponent 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 { x :: Double , y :: Double@@ -159,7 +159,7 @@ 1 -> pure Y 2 -> pure Z 3 -> pure W- y_ -> fail ("[RT08] invalid component: " <> show y_)+ y_ -> BitGet.throw $ InvalidComponent.InvalidComponent y_ decodePart :: BitGet.BitGet Double decodePart = fmap decompressPart $ CompressedWord.bitGet maxCompressedValue
src/lib/Rattletrap/Type/RemoteId.hs view
@@ -1,7 +1,9 @@ module Rattletrap.Type.RemoteId where +import qualified Data.Foldable as Foldable import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Exception.UnknownSystemId as UnknownSystemId import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.RemoteId.Epic as Epic import qualified Rattletrap.Type.RemoteId.PlayStation as PlayStation@@ -14,8 +16,6 @@ import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json -import qualified Data.Foldable as Foldable- data RemoteId = PlayStation PlayStation.PlayStation | PsyNet PsyNet.PsyNet@@ -79,4 +79,4 @@ 6 -> fmap Switch Switch.bitGet 7 -> fmap PsyNet $ PsyNet.bitGet version 11 -> fmap Epic Epic.bitGet- _ -> fail ("[RT09] unknown system id " <> show systemId)+ x -> BitGet.throw $ UnknownSystemId.UnknownSystemId x
src/lib/Rattletrap/Type/RemoteId/Epic.hs view
@@ -29,4 +29,4 @@ bitPut = Str.bitPut . toStr bitGet :: BitGet.BitGet Epic-bitGet = fmap fromStr Str.bitGet+bitGet = BitGet.label "Epic" $ fmap fromStr Str.bitGet
src/lib/Rattletrap/Type/RemoteId/PlayStation.hs view
@@ -37,9 +37,9 @@ in BitPut.byteString nameBytes <> BitPut.byteString codeBytes bitGet :: Version.Version -> BitGet.BitGet PlayStation-bitGet version = do- name <- getCode- code <- getName version+bitGet version = BitGet.label "PlayStation" $ do+ name <- BitGet.label "name" getCode+ code <- BitGet.label "code" $ getName version pure PlayStation { name, code } getCode :: BitGet.BitGet Text.Text
src/lib/Rattletrap/Type/RemoteId/PsyNet.hs view
@@ -40,11 +40,14 @@ U64.bitPut a <> U64.bitPut b <> U64.bitPut c <> U64.bitPut d bitGet :: Version.Version -> BitGet.BitGet PsyNet-bitGet version = fmap fromEither $ if Version.atLeast 868 24 10 version- then fmap Left U64.bitGet- else fmap Right $ do- a <- U64.bitGet- b <- U64.bitGet- c <- U64.bitGet- d <- U64.bitGet- pure (a, b, c, d)+bitGet version =+ BitGet.label "PsyNet"+ . fmap fromEither+ $ if Version.atLeast 868 24 10 version+ then BitGet.label "new" $ fmap Left U64.bitGet+ else BitGet.label "old" . fmap Right $ do+ a <- U64.bitGet+ b <- U64.bitGet+ c <- U64.bitGet+ d <- U64.bitGet+ pure (a, b, c, d)
src/lib/Rattletrap/Type/RemoteId/Splitscreen.hs view
@@ -29,4 +29,4 @@ bitPut = BitPut.bits 24 . toWord32 bitGet :: BitGet.BitGet Splitscreen-bitGet = fmap fromWord32 $ BitGet.bits 24+bitGet = BitGet.label "Splitscreen" . fmap fromWord32 $ BitGet.bits 24
src/lib/Rattletrap/Type/RemoteId/Steam.hs view
@@ -29,4 +29,4 @@ bitPut = U64.bitPut . toU64 bitGet :: BitGet.BitGet Steam-bitGet = fmap fromU64 U64.bitGet+bitGet = BitGet.label "Steam" $ fmap fromU64 U64.bitGet
src/lib/Rattletrap/Type/RemoteId/Switch.hs view
@@ -32,7 +32,7 @@ U64.bitPut (a x) <> U64.bitPut (b x) <> U64.bitPut (c x) <> U64.bitPut (d x) bitGet :: BitGet.BitGet Switch-bitGet = do+bitGet = BitGet.label "Switch" $ do a <- U64.bitGet b <- U64.bitGet c <- U64.bitGet
src/lib/Rattletrap/Type/RemoteId/Xbox.hs view
@@ -29,4 +29,4 @@ bitPut = U64.bitPut . toU64 bitGet :: BitGet.BitGet Xbox-bitGet = fmap fromU64 U64.bitGet+bitGet = BitGet.label "Xbox" $ fmap fromU64 U64.bitGet
src/lib/Rattletrap/Type/Replay.hs view
@@ -64,17 +64,21 @@ <> 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 }- }+byteGet fast skip = ByteGet.label "Replay" $ do+ header <- ByteGet.label "header" $ do+ section <-+ Section.byteGet skip $ ByteGet.byteString . fromIntegral . U32.toWord32+ body <- ByteGet.embed Header.byteGet $ Section.body section+ pure section { Section.body }+ content <- ByteGet.label "content" $ do+ section <-+ Section.byteGet skip $ ByteGet.byteString . fromIntegral . U32.toWord32+ body <- if fast+ then pure Content.empty+ else ByteGet.embed (getContent $ Section.body header)+ $ Section.body section+ pure section { Section.body }+ pure Replay { header, content } getContent :: Header.Header -> ByteGet.ByteGet Content.Content getContent h = Content.byteGet
src/lib/Rattletrap/Type/Replication.hs view
@@ -1,5 +1,6 @@ module Rattletrap.Type.Replication where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -11,12 +12,7 @@ import qualified Rattletrap.Type.U32 as U32 import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json-import qualified Rattletrap.Utility.Monad as Monad -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 { actorId :: CompressedWord.CompressedWord , value :: ReplicationValue.ReplicationValue@@ -53,24 +49,58 @@ -> Version.Version -> Word -> ClassAttributeMap.ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord.CompressedWord U32.U32)- BitGet.BitGet- (List.List Replication)-decodeReplicationsBits matchType version limit classes = List.untilM $ do- p <- Trans.lift BitGet.bool- Monad.whenMaybe p $ bitGet matchType version limit classes+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> BitGet.BitGet+ ( Map.Map CompressedWord.CompressedWord U32.U32+ , List.List Replication+ )+decodeReplicationsBits matchType version limit classes actorMap =+ decodeReplicationsBitsWith matchType version limit classes actorMap 0 [] +decodeReplicationsBitsWith+ :: Maybe Str.Str+ -> Version.Version+ -> Word+ -> ClassAttributeMap.ClassAttributeMap+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> Int+ -> [Replication]+ -> BitGet.BitGet+ ( Map.Map CompressedWord.CompressedWord U32.U32+ , List.List Replication+ )+decodeReplicationsBitsWith matchType version limit classes actorMap index replications+ = do+ hasReplication <- BitGet.bool+ if hasReplication+ then do+ (newActorMap, replication) <-+ BitGet.label ("element (" <> show index <> ")")+ $ bitGet matchType version limit classes actorMap+ decodeReplicationsBitsWith+ matchType+ version+ limit+ classes+ newActorMap+ (index + 1)+ $ replication+ : replications+ else pure (actorMap, List.fromList $ reverse replications)+ bitGet :: Maybe Str.Str -> Version.Version -> Word -> ClassAttributeMap.ClassAttributeMap- -> State.StateT- (Map.Map CompressedWord.CompressedWord U32.U32)- BitGet.BitGet- Replication-bitGet matchType version limit classes = do- actor <- Trans.lift (CompressedWord.bitGet limit)- fmap (Replication actor)- $ ReplicationValue.bitGet matchType version classes actor+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> BitGet.BitGet+ ( Map.Map CompressedWord.CompressedWord U32.U32+ , Replication+ )+bitGet matchType version limit classes actorMap =+ BitGet.label "Replication" $ do+ actorId <- BitGet.label "actorId" $ CompressedWord.bitGet limit+ (newActorMap, value) <- BitGet.label "value"+ $ ReplicationValue.bitGet matchType version classes actorId actorMap+ pure (newActorMap, Replication { actorId, value })
src/lib/Rattletrap/Type/Replication/Destroyed.hs view
@@ -27,4 +27,4 @@ bitPut _ = mempty bitGet :: BitGet.BitGet Destroyed-bitGet = pure Destroyed+bitGet = BitGet.label "Destroyed" $ pure Destroyed
src/lib/Rattletrap/Type/Replication/Spawned.hs view
@@ -1,7 +1,11 @@ module Rattletrap.Type.Replication.Spawned where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Exception.MissingClassName as MissingClassName+import qualified Rattletrap.Exception.MissingObjectName as MissingObjectName+import qualified Rattletrap.Exception.UnknownName as UnknownName import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap import qualified Rattletrap.Type.CompressedWord as CompressedWord@@ -12,10 +16,6 @@ import qualified Rattletrap.Utility.Json as Json import qualified Rattletrap.Utility.Monad as 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.@@ -87,36 +87,34 @@ -> Version.Version -> ClassAttributeMap.ClassAttributeMap -> CompressedWord.CompressedWord- -> State.StateT- (Map.Map CompressedWord.CompressedWord U32.U32)- BitGet.BitGet- Spawned-bitGet matchType version classAttributeMap actorId = do- flag_ <- Trans.lift BitGet.bool- nameIndex_ <- Monad.whenMaybe (hasNameIndex matchType 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+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> BitGet.BitGet+ (Map.Map CompressedWord.CompressedWord U32.U32, Spawned)+bitGet matchType version classAttributeMap actorId actorMap =+ BitGet.label "Spawned" $ do+ flag <- BitGet.label "flag" BitGet.bool+ nameIndex <- BitGet.label "nameIndex"+ $ Monad.whenMaybe (hasNameIndex matchType version) U32.bitGet+ name <- lookupName classAttributeMap nameIndex+ objectId <- BitGet.label "objectId" U32.bitGet+ objectName <- lookupObjectName classAttributeMap objectId+ className <- lookupClassName objectName+ let hasLocation = ClassAttributeMap.classHasLocation className+ let hasRotation = ClassAttributeMap.classHasRotation className+ initialization <- BitGet.label "initialization"+ $ Initialization.bitGet version hasLocation hasRotation 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_- )+ ( Map.insert actorId objectId actorMap+ , Spawned+ { flag+ , nameIndex+ , name+ , objectId+ , objectName+ , className+ , initialization+ }+ ) hasNameIndex :: Maybe Str.Str -> Version.Version -> Bool hasNameIndex matchType version =@@ -125,9 +123,9 @@ lookupName :: ClassAttributeMap.ClassAttributeMap -> Maybe U32.U32- -> Either String (Maybe Str.Str)+ -> BitGet.BitGet (Maybe Str.Str) lookupName classAttributeMap maybeNameIndex = case maybeNameIndex of- Nothing -> Right Nothing+ Nothing -> pure Nothing Just nameIndex_ -> case ClassAttributeMap.getName@@ -135,11 +133,11 @@ nameIndex_ of Nothing ->- Left ("[RT11] could not get name for index " <> show nameIndex_)- Just name_ -> Right (Just name_)+ BitGet.throw . UnknownName.UnknownName $ U32.toWord32 nameIndex_+ Just name_ -> pure (Just name_) lookupObjectName- :: ClassAttributeMap.ClassAttributeMap -> U32.U32 -> Either String Str.Str+ :: ClassAttributeMap.ClassAttributeMap -> U32.U32 -> BitGet.BitGet Str.Str lookupObjectName classAttributeMap objectId_ = case ClassAttributeMap.getObjectName@@ -147,12 +145,13 @@ objectId_ of Nothing ->- Left ("[RT12] could not get object name for id " <> show objectId_)- Just objectName_ -> Right objectName_+ BitGet.throw . MissingObjectName.MissingObjectName $ U32.toWord32+ objectId_+ Just objectName_ -> pure objectName_ -lookupClassName :: Str.Str -> Either String Str.Str+lookupClassName :: Str.Str -> BitGet.BitGet 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_+ Nothing -> BitGet.throw . MissingClassName.MissingClassName $ Str.toString+ objectName_+ Just className_ -> pure className_
src/lib/Rattletrap/Type/Replication/Updated.hs view
@@ -1,5 +1,6 @@ module Rattletrap.Type.Replication.Updated where +import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -12,8 +13,6 @@ import qualified Rattletrap.Utility.Json as Json import qualified Rattletrap.Utility.Monad as Monad -import qualified Data.Map as Map- newtype Updated = Updated { attributes :: List.List Attribute.Attribute } deriving (Eq, Show)@@ -41,6 +40,7 @@ -> Map.Map CompressedWord.CompressedWord U32.U32 -> CompressedWord.CompressedWord -> BitGet.BitGet Updated-bitGet version classes actors actor = fmap Updated . List.untilM $ do- p <- BitGet.bool- Monad.whenMaybe p $ Attribute.bitGet version classes actors actor+bitGet version classes actors actor =+ BitGet.label "Updated" . fmap Updated . List.untilM $ do+ p <- BitGet.bool+ Monad.whenMaybe p $ Attribute.bitGet version classes actors actor
src/lib/Rattletrap/Type/ReplicationValue.hs view
@@ -1,5 +1,7 @@ module Rattletrap.Type.ReplicationValue where +import qualified Data.Foldable as Foldable+import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema@@ -13,11 +15,6 @@ import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json -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 = Spawned Spawned.Spawned -- ^ Creates a new actor.@@ -59,22 +56,33 @@ -> Version.Version -> ClassAttributeMap.ClassAttributeMap -> CompressedWord.CompressedWord- -> State.StateT- (Map.Map CompressedWord.CompressedWord U32.U32)- BitGet.BitGet- ReplicationValue-bitGet matchType version classAttributeMap actorId = do- actorMap <- State.get- isOpen <- Trans.lift BitGet.bool- if isOpen- then do- isNew <- Trans.lift BitGet.bool- if isNew- then fmap Spawned- $ Spawned.bitGet matchType version classAttributeMap actorId- else fmap Updated . Trans.lift $ Updated.bitGet- version- classAttributeMap- actorMap- actorId- else fmap Destroyed $ Trans.lift Destroyed.bitGet+ -> Map.Map CompressedWord.CompressedWord U32.U32+ -> BitGet.BitGet+ ( Map.Map CompressedWord.CompressedWord U32.U32+ , ReplicationValue+ )+bitGet matchType version classAttributeMap actorId actorMap =+ BitGet.label "ReplicationValue" $ do+ isOpen <- BitGet.bool+ if isOpen+ then do+ isNew <- BitGet.bool+ if isNew+ then do+ (newActorMap, spawned) <- Spawned.bitGet+ matchType+ version+ classAttributeMap+ actorId+ actorMap+ pure (newActorMap, Spawned spawned)+ else do+ updated <- Updated.bitGet+ version+ classAttributeMap+ actorMap+ actorId+ pure (actorMap, Updated updated)+ else do+ destroyed <- Destroyed.bitGet+ pure (actorMap, Destroyed destroyed)
src/lib/Rattletrap/Type/Section.hs view
@@ -1,16 +1,16 @@ module Rattletrap.Type.Section where +import qualified Control.Monad as Monad+import qualified Data.ByteString as ByteString+import qualified Data.Text as Text import qualified Rattletrap.ByteGet as ByteGet import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Exception.CrcMismatch as CrcMismatch 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 Control.Monad as Monad-import qualified Data.ByteString as ByteString-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@@ -72,15 +72,20 @@ 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_)+byteGet skip getBody = ByteGet.label "Section" $ do+ size <- ByteGet.label "size" U32.byteGet+ crc <- ByteGet.label "crc" U32.byteGet+ body <- ByteGet.label "body" $ do+ rawBody <- ByteGet.byteString . fromIntegral $ U32.toWord32 size+ Monad.unless skip $ do+ let+ expected = U32.toWord32 crc+ actual = Crc.compute rawBody+ Monad.when (actual /= expected) . ByteGet.throw $ CrcMismatch.CrcMismatch+ expected+ actual+ ByteGet.embed (getBody size) rawBody+ pure Section { size, crc, body } crcMessage :: U32.U32 -> U32.U32 -> String crcMessage actual expected = unwords
src/lib/Rattletrap/Type/Str.hs view
@@ -1,5 +1,11 @@ module Rattletrap.Type.Str where +import qualified Data.ByteString as ByteString+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 Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.ByteGet as ByteGet@@ -9,13 +15,6 @@ import qualified Rattletrap.Utility.Bytes as Bytes import qualified Rattletrap.Utility.Json as Json -import qualified Data.ByteString as ByteString-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- newtype Str = Str Text.Text deriving (Eq, Ord, Show)@@ -73,10 +72,10 @@ 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)))+byteGet = ByteGet.label "Str" $ do+ size <- ByteGet.label "size" I32.byteGet+ bytes <- ByteGet.label "value" . ByteGet.byteString $ normalizeTextSize size+ pure . fromText . dropNull $ getTextDecoder size bytes bitGet :: BitGet.BitGet Str bitGet = do
src/lib/Rattletrap/Type/U32.hs view
@@ -38,7 +38,7 @@ bitPut = BitPut.fromBytePut . bytePut byteGet :: ByteGet.ByteGet U32-byteGet = fmap fromWord32 ByteGet.word32+byteGet = ByteGet.label "U32" $ fmap fromWord32 ByteGet.word32 bitGet :: BitGet.BitGet U32 bitGet = BitGet.fromByteGet byteGet 4
src/lib/Rattletrap/Type/U64.hs view
@@ -1,14 +1,13 @@ module Rattletrap.Type.U64 where +import qualified Data.Text as Text+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--import qualified Data.Text as Text-import qualified Data.Word as Word import qualified Text.Read as Read newtype U64@@ -42,7 +41,7 @@ bitPut = BitPut.fromBytePut . bytePut byteGet :: ByteGet.ByteGet U64-byteGet = fmap fromWord64 ByteGet.word64+byteGet = ByteGet.label "U64" $ fmap fromWord64 ByteGet.word64 bitGet :: BitGet.BitGet U64 bitGet = BitGet.fromByteGet byteGet 8
src/lib/Rattletrap/Type/U8.hs view
@@ -38,7 +38,7 @@ bitPut = BitPut.fromBytePut . bytePut byteGet :: ByteGet.ByteGet U8-byteGet = fmap fromWord8 ByteGet.word8+byteGet = ByteGet.label "U8" $ fmap fromWord8 ByteGet.word8 bitGet :: BitGet.BitGet U8 bitGet = BitGet.fromByteGet byteGet 1
src/lib/Rattletrap/Type/Vector.hs view
@@ -66,15 +66,17 @@ <> CompressedWord.bitPut (CompressedWord.CompressedWord limit dz) bitGet :: Version.Version -> BitGet.BitGet Vector-bitGet version = do- size <- CompressedWord.bitGet+bitGet version = BitGet.label "Vector" $ do+ size <-+ BitGet.label "size"+ . CompressedWord.bitGet $ if Version.atLeast 868 22 7 version then 21 else 19 let limit = getLimit size bias = getBias size- x <- getPart limit bias- y <- getPart limit bias- z <- getPart limit bias+ x <- BitGet.label "x" $ getPart limit bias+ y <- BitGet.label "y" $ getPart limit bias+ z <- BitGet.label "z" $ getPart limit bias pure Vector { size, bias, x, y, z } getPart :: Word -> Word -> BitGet.BitGet Int
src/lib/Rattletrap/Type/Version.hs view
@@ -24,10 +24,10 @@ (patch x) byteGet :: ByteGet.ByteGet Version-byteGet = do- major <- U32.byteGet- minor <- U32.byteGet- patch <- Monad.whenMaybe+byteGet = ByteGet.label "Version" $ do+ major <- ByteGet.label "major" U32.byteGet+ minor <- ByteGet.label "minor" U32.byteGet+ patch <- ByteGet.label "patch" $ Monad.whenMaybe (U32.toWord32 major >= 868 && U32.toWord32 minor >= 18) U32.byteGet pure Version { major, minor, patch }
src/lib/Rattletrap/Utility/Helper.hs view
@@ -4,17 +4,23 @@ import qualified Rattletrap.ByteGet as ByteGet import qualified Rattletrap.BytePut as BytePut+import qualified Rattletrap.Exception.InvalidJson as InvalidJson import qualified Rattletrap.Type.Content as Content import qualified Rattletrap.Type.Replay as Replay import qualified Rattletrap.Type.Section as Section import qualified Rattletrap.Utility.Json as Json +import qualified Control.Exception as Exception+import qualified Data.Bifunctor as Bifunctor import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as LazyByteString -- | Parses a raw replay. decodeReplayFile- :: Bool -> Bool -> ByteString.ByteString -> Either String Replay.Replay+ :: Bool+ -> Bool+ -> ByteString.ByteString+ -> Either ([String], Exception.SomeException) Replay.Replay decodeReplayFile fast = ByteGet.run . Replay.byteGet fast -- | Encodes a replay as JSON.@@ -22,8 +28,12 @@ encodeReplayJson = Json.encodePretty -- | Parses a JSON replay.-decodeReplayJson :: ByteString.ByteString -> Either String Replay.Replay-decodeReplayJson = Json.decode+decodeReplayJson+ :: ByteString.ByteString+ -> Either ([String], Exception.SomeException) Replay.Replay+decodeReplayJson =+ Bifunctor.first ((,) [] . Exception.toException . InvalidJson.InvalidJson)+ . Json.decode -- | Encodes a raw replay. encodeReplayFile :: Bool -> Replay.Replay -> LazyByteString.ByteString