packages feed

rattletrap 3.1.0 → 3.1.1

raw patch · 46 files changed

+888/−1022 lines, 46 filesdep ~aesondep ~basedep ~bimapsetup-changedbinary-addedPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: aeson, base, bimap, binary, containers, hspec, template-haskell, temporary, vector

API changes (from Hackage documentation)

- Rattletrap.Attribute.ProductAttribute: ProductAttribute :: Bool -> Word32 -> Maybe Text -> Maybe (Either CompressedWord Word32) -> ProductAttribute
- Rattletrap.Attribute.ProductAttribute: [productAttributeObjectId] :: ProductAttribute -> Word32
- Rattletrap.Attribute.ProductAttribute: [productAttributeObjectName] :: ProductAttribute -> Maybe Text
- Rattletrap.Attribute.ProductAttribute: [productAttributeUnknown] :: ProductAttribute -> Bool
- Rattletrap.Attribute.ProductAttribute: [productAttributeValue] :: ProductAttribute -> Maybe (Either CompressedWord Word32)
- Rattletrap.Attribute.ProductAttribute: data ProductAttribute
- Rattletrap.Attribute.ProductAttribute: getProductAttribute :: (Int, Int) -> Map Word32 Text -> BitGet ProductAttribute
- Rattletrap.Attribute.ProductAttribute: getProductAttributes :: (Int, Int) -> Map Word32 Text -> BitGet [ProductAttribute]
- Rattletrap.Attribute.ProductAttribute: instance GHC.Classes.Eq Rattletrap.Attribute.ProductAttribute.ProductAttribute
- Rattletrap.Attribute.ProductAttribute: instance GHC.Classes.Ord Rattletrap.Attribute.ProductAttribute.ProductAttribute
- Rattletrap.Attribute.ProductAttribute: instance GHC.Show.Show Rattletrap.Attribute.ProductAttribute.ProductAttribute
- Rattletrap.Attribute.ProductAttribute: putProductAttribute :: ProductAttribute -> BitPut ()
- Rattletrap.Attribute.ProductAttribute: putProductAttributes :: [ProductAttribute] -> BitPut ()
- Rattletrap.Header: getMajorVersion :: Header -> Int
- Rattletrap.Header: getMinorVersion :: Header -> Int
- Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Attribute.ProductAttribute.ProductAttribute
- Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a0 => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Primitive.Dictionary.Dictionary a0)
- Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a0 => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Primitive.List.List a0)
- Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a0 => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Primitive.Section.Section a0)
- Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a0 => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.PropertyValue.PropertyValue a0)
- Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Attribute.ProductAttribute.ProductAttribute
- Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a0 => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Primitive.Dictionary.Dictionary a0)
- Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a0 => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Primitive.List.List a0)
- Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a0 => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Primitive.Section.Section a0)
- Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a0 => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.PropertyValue.PropertyValue a0)
+ Rattletrap.Attribute.Product: ProductAttribute :: Bool -> Word32 -> Maybe Text -> Maybe (Either CompressedWord Word32) -> ProductAttribute
+ Rattletrap.Attribute.Product: [productAttributeObjectId] :: ProductAttribute -> Word32
+ Rattletrap.Attribute.Product: [productAttributeObjectName] :: ProductAttribute -> Maybe Text
+ Rattletrap.Attribute.Product: [productAttributeUnknown] :: ProductAttribute -> Bool
+ Rattletrap.Attribute.Product: [productAttributeValue] :: ProductAttribute -> Maybe (Either CompressedWord Word32)
+ Rattletrap.Attribute.Product: data ProductAttribute
+ Rattletrap.Attribute.Product: getProductAttribute :: (Int, Int, Int) -> Map Word32 Text -> BitGet ProductAttribute
+ Rattletrap.Attribute.Product: getProductAttributes :: (Int, Int, Int) -> Map Word32 Text -> BitGet [ProductAttribute]
+ Rattletrap.Attribute.Product: instance GHC.Classes.Eq Rattletrap.Attribute.Product.ProductAttribute
+ Rattletrap.Attribute.Product: instance GHC.Classes.Ord Rattletrap.Attribute.Product.ProductAttribute
+ Rattletrap.Attribute.Product: instance GHC.Show.Show Rattletrap.Attribute.Product.ProductAttribute
+ Rattletrap.Attribute.Product: putProductAttribute :: ProductAttribute -> BitPut ()
+ Rattletrap.Attribute.Product: putProductAttributes :: [ProductAttribute] -> BitPut ()
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Attribute.Product.ProductAttribute
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Primitive.Dictionary.Dictionary a)
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Primitive.List.List a)
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.Primitive.Section.Section a)
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rattletrap.PropertyValue.PropertyValue a)
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Attribute.Product.ProductAttribute
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Primitive.Dictionary.Dictionary a)
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Primitive.List.List a)
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.Primitive.Section.Section a)
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Rattletrap.PropertyValue.PropertyValue a)
- Rattletrap.Attribute: getAttribute :: (Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet Attribute
+ Rattletrap.Attribute: getAttribute :: (Int, Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet Attribute
- Rattletrap.Attribute: getAttributes :: (Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet [Attribute]
+ Rattletrap.Attribute: getAttributes :: (Int, Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet [Attribute]
- Rattletrap.Attribute.CamSettings: getCamSettingsAttribute :: (Int, Int) -> BitGet CamSettingsAttribute
+ Rattletrap.Attribute.CamSettings: getCamSettingsAttribute :: (Int, Int, Int) -> BitGet CamSettingsAttribute
- Rattletrap.Attribute.GameMode: getGameModeAttribute :: (Int, Int) -> BitGet GameModeAttribute
+ Rattletrap.Attribute.GameMode: getGameModeAttribute :: (Int, Int, Int) -> BitGet GameModeAttribute
- Rattletrap.Attribute.LoadoutOnline: getLoadoutOnlineAttribute :: (Int, Int) -> Map Word32 Text -> BitGet LoadoutOnlineAttribute
+ Rattletrap.Attribute.LoadoutOnline: getLoadoutOnlineAttribute :: (Int, Int, Int) -> Map Word32 Text -> BitGet LoadoutOnlineAttribute
- Rattletrap.Attribute.LoadoutsOnline: getLoadoutsOnlineAttribute :: (Int, Int) -> Map Word32 Text -> BitGet LoadoutsOnlineAttribute
+ Rattletrap.Attribute.LoadoutsOnline: getLoadoutsOnlineAttribute :: (Int, Int, Int) -> Map Word32 Text -> BitGet LoadoutsOnlineAttribute
- Rattletrap.Attribute.PartyLeader: getPartyLeaderAttribute :: BitGet PartyLeaderAttribute
+ Rattletrap.Attribute.PartyLeader: getPartyLeaderAttribute :: (Int, Int, Int) -> BitGet PartyLeaderAttribute
- Rattletrap.Attribute.Reservation: getReservationAttribute :: (Int, Int) -> BitGet ReservationAttribute
+ Rattletrap.Attribute.Reservation: getReservationAttribute :: (Int, Int, Int) -> BitGet ReservationAttribute
- Rattletrap.Attribute.UniqueId: getUniqueIdAttribute :: BitGet UniqueIdAttribute
+ Rattletrap.Attribute.UniqueId: getUniqueIdAttribute :: (Int, Int, Int) -> BitGet UniqueIdAttribute
- Rattletrap.AttributeValue: getAttributeValue :: (Int, Int) -> Map Word32 Text -> Text -> BitGet AttributeValue
+ Rattletrap.AttributeValue: getAttributeValue :: (Int, Int, Int) -> Map Word32 Text -> Text -> BitGet AttributeValue
- Rattletrap.Content: getContent :: (Int, Int) -> Int -> Word -> Get Content
+ Rattletrap.Content: getContent :: (Int, Int, Int) -> Int -> Word -> Get Content
- Rattletrap.Frame: getFrame :: (Int, Int) -> Word -> ClassAttributeMap -> ActorMap -> BitGet (Frame, ActorMap)
+ Rattletrap.Frame: getFrame :: (Int, Int, Int) -> Word -> ClassAttributeMap -> ActorMap -> BitGet (Frame, ActorMap)
- Rattletrap.Frame: getFrames :: (Int, Int) -> Int -> Word -> ClassAttributeMap -> ActorMap -> BitGet ([Frame], ActorMap)
+ Rattletrap.Frame: getFrames :: (Int, Int, Int) -> Int -> Word -> ClassAttributeMap -> ActorMap -> BitGet ([Frame], ActorMap)
- Rattletrap.Header: getVersion :: Header -> (Int, Int)
+ Rattletrap.Header: getVersion :: Header -> (Int, Int, Int)
- Rattletrap.RemoteId: getRemoteId :: Word8 -> BitGet RemoteId
+ Rattletrap.RemoteId: getRemoteId :: (Int, Int, Int) -> Word8 -> BitGet RemoteId
- Rattletrap.Replication: getReplication :: (Int, Int) -> Word -> ClassAttributeMap -> ActorMap -> BitGet (Maybe (Replication, ActorMap))
+ Rattletrap.Replication: getReplication :: (Int, Int, Int) -> Word -> ClassAttributeMap -> ActorMap -> BitGet (Maybe (Replication, ActorMap))
- Rattletrap.Replication: getReplications :: (Int, Int) -> Word -> ClassAttributeMap -> ActorMap -> BitGet ([Replication], ActorMap)
+ Rattletrap.Replication: getReplications :: (Int, Int, Int) -> Word -> ClassAttributeMap -> ActorMap -> BitGet ([Replication], ActorMap)
- Rattletrap.Replication.Spawned: getSpawnedReplication :: (Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet (SpawnedReplication, ActorMap)
+ Rattletrap.Replication.Spawned: getSpawnedReplication :: (Int, Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet (SpawnedReplication, ActorMap)
- Rattletrap.Replication.Updated: getUpdatedReplication :: (Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet UpdatedReplication
+ Rattletrap.Replication.Updated: getUpdatedReplication :: (Int, Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet UpdatedReplication
- Rattletrap.ReplicationValue: getReplicationValue :: (Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet (ReplicationValue, ActorMap)
+ Rattletrap.ReplicationValue: getReplicationValue :: (Int, Int, Int) -> ClassAttributeMap -> ActorMap -> CompressedWord -> BitGet (ReplicationValue, ActorMap)

Files

README.markdown view
@@ -27,13 +27,15 @@ Rattletrap can parse (decode) Rocket League replays and output them as JSON.  ``` sh-> rattletrap decode input.replay output.json+> rattletrap decode http://example.com/input.replay output.json # or > rattletrap decode input.replay > output.json # or > rattletrap.decode < input.replay > output.json ``` +The input argument can either be a local path or a URL.+ The resulting JSON is minified, but extremely large. The output can be up to 50 times larger than the input. @@ -42,12 +44,14 @@ Rattletrap can also generate (encode) Rocket League replays from JSON files.  ``` sh-> rattletrap encode input.json output.replay+> rattletrap encode http://example.com/input.json output.replay # or > rattletrap encode input.json > output.replay # or > rattletrap.encode < input.json > output.replay ```++The input argument can either be a local path or a URL.  If the JSON was generated by Rattletrap, the resulting replay should be identical to the original.
Setup.hs view
@@ -1,4 +1,4 @@-import qualified Distribution.Simple+import qualified Distribution.Simple as Cabal  main :: IO ()-main = Distribution.Simple.defaultMain+main = Cabal.defaultMain
library/Rattletrap/Attribute.hs view
@@ -16,8 +16,8 @@   , attributeValue :: AttributeValue   } deriving (Eq, Ord, Show) -getAttributes ::-     (Int, Int)+getAttributes+  :: (Int, Int, Int)   -> ClassAttributeMap   -> ActorMap   -> CompressedWord@@ -36,8 +36,8 @@   mapM_ putAttribute attributes   BinaryBit.putBool False -getAttribute ::-     (Int, Int)+getAttribute+  :: (Int, Int, Int)   -> ClassAttributeMap   -> ActorMap   -> CompressedWord@@ -45,21 +45,18 @@ getAttribute version classAttributeMap actorMap actorId =   case getAttributeMap classAttributeMap actorMap actorId of     Nothing -> fail ("could not get attribute map for " ++ show actorId)-    Just attributeMap ->-      case getAttributeIdLimit attributeMap of-        Nothing ->-          fail ("could not get attribute ID limit for " ++ show actorId)-        Just limit -> do-          id_ <- getCompressedWord limit-          case getAttributeName classAttributeMap attributeMap id_ of-            Nothing -> fail ("could not get attribute name for " ++ show id_)-            Just name -> do-              value <--                getAttributeValue-                  version-                  (classAttributeMapObjectMap classAttributeMap)-                  name-              pure (Attribute id_ name value)+    Just attributeMap -> case getAttributeIdLimit attributeMap of+      Nothing -> fail ("could not get attribute ID limit for " ++ show actorId)+      Just limit -> do+        id_ <- getCompressedWord limit+        case getAttributeName classAttributeMap attributeMap id_ of+          Nothing -> fail ("could not get attribute name for " ++ show id_)+          Just name -> do+            value <- getAttributeValue+              version+              (classAttributeMapObjectMap classAttributeMap)+              name+            pure (Attribute id_ name value)  putAttribute :: Attribute -> BinaryBit.BitPut () putAttribute attribute = do
library/Rattletrap/Attribute/CamSettings.hs view
@@ -15,7 +15,7 @@   , camSettingsAttributeTransitionSpeed :: Maybe Float32   } deriving (Eq, Ord, Show) -getCamSettingsAttribute :: (Int, Int) -> BinaryBit.BitGet CamSettingsAttribute+getCamSettingsAttribute :: (Int, Int, Int) -> BinaryBit.BitGet CamSettingsAttribute getCamSettingsAttribute version = do   fov <- getFloat32Bits   height <- getFloat32Bits@@ -23,21 +23,21 @@   distance <- getFloat32Bits   stiffness <- getFloat32Bits   swivelSpeed <- getFloat32Bits-  transitionSpeed <--    if version >= (868, 20)-      then do-        x <- getFloat32Bits-        pure (Just x)-      else pure Nothing+  transitionSpeed <- if version >= (868, 20, 0)+    then do+      x <- getFloat32Bits+      pure (Just x)+    else pure Nothing   pure-    (CamSettingsAttribute-       fov-       height-       angle-       distance-       stiffness-       swivelSpeed-       transitionSpeed)+    ( CamSettingsAttribute+      fov+      height+      angle+      distance+      stiffness+      swivelSpeed+      transitionSpeed+    )  putCamSettingsAttribute :: CamSettingsAttribute -> BinaryBit.BitPut () putCamSettingsAttribute camSettingsAttribute = do
library/Rattletrap/Attribute/Demolish.hs view
@@ -23,13 +23,14 @@   attackerVelocity <- getVector   victimVelocity <- getVector   pure-    (DemolishAttribute-       attackerFlag-       attackerActorId-       victimFlag-       victimActorId-       attackerVelocity-       victimVelocity)+    ( DemolishAttribute+      attackerFlag+      attackerActorId+      victimFlag+      victimActorId+      attackerVelocity+      victimVelocity+    )  putDemolishAttribute :: DemolishAttribute -> BinaryBit.BitPut () putDemolishAttribute demolishAttribute = do
library/Rattletrap/Attribute/ExtendedExplosion.hs view
@@ -21,8 +21,8 @@   unknown2 <- getInt32Bits   pure (ExtendedExplosionAttribute actorId location unknown1 unknown2) -putExtendedExplosionAttribute ::-     ExtendedExplosionAttribute -> BinaryBit.BitPut ()+putExtendedExplosionAttribute+  :: ExtendedExplosionAttribute -> BinaryBit.BitPut () putExtendedExplosionAttribute extendedExplosionAttribute = do   BinaryBit.putBool False   putInt32Bits (extendedExplosionAttributeActorId extendedExplosionAttribute)
library/Rattletrap/Attribute/GameMode.hs view
@@ -9,12 +9,9 @@   , gameModeAttributeWord :: Word.Word8   } deriving (Eq, Ord, Show) -getGameModeAttribute :: (Int, Int) -> BinaryBit.BitGet GameModeAttribute+getGameModeAttribute :: (Int, Int, Int) -> BinaryBit.BitGet GameModeAttribute getGameModeAttribute version = do-  let numBits =-        if version < (868, 12)-          then 2-          else 8+  let numBits = if version < (868, 12, 0) then 2 else 8   word <- BinaryBit.getWord8 numBits   pure (GameModeAttribute numBits word) 
library/Rattletrap/Attribute/Loadout.hs view
@@ -38,28 +38,28 @@   goalExplosion <- getOptional (version >= Word8 16) getWord32Bits   banner <- getOptional (version >= Word8 17) getWord32Bits   pure-    (LoadoutAttribute-       version-       body-       decal-       wheels-       rocketTrail-       antenna-       topper-       unknown1-       unknown2-       engineAudio-       trail-       goalExplosion-       banner)+    ( LoadoutAttribute+      version+      body+      decal+      wheels+      rocketTrail+      antenna+      topper+      unknown1+      unknown2+      engineAudio+      trail+      goalExplosion+      banner+    )  getOptional :: Bool -> BinaryBit.BitGet a -> BinaryBit.BitGet (Maybe a)-getOptional p f =-  if p-    then do-      x <- f-      pure (Just x)-    else pure Nothing+getOptional p f = if p+  then do+    x <- f+    pure (Just x)+  else pure Nothing  putLoadoutAttribute :: LoadoutAttribute -> BinaryBit.BitPut () putLoadoutAttribute loadoutAttribute = do@@ -78,7 +78,6 @@   putOptional (loadoutAttributeBanner loadoutAttribute) putWord32Bits  putOptional :: Maybe a -> (a -> BinaryBit.BitPut ()) -> BinaryBit.BitPut ()-putOptional m f =-  case m of-    Just x -> f x-    Nothing -> pure ()+putOptional m f = case m of+  Just x -> f x+  Nothing -> pure ()
library/Rattletrap/Attribute/LoadoutOnline.hs view
@@ -1,6 +1,6 @@ module Rattletrap.Attribute.LoadoutOnline where -import Rattletrap.Attribute.ProductAttribute+import Rattletrap.Attribute.Product import Rattletrap.Primitive  import qualified Control.Monad as Monad@@ -12,16 +12,15 @@   { loadoutAttributeValue :: [[ProductAttribute]]   } deriving (Eq, Ord, Show) -getLoadoutOnlineAttribute ::-     (Int, Int)+getLoadoutOnlineAttribute+  :: (Int, Int, Int)   -> Map.Map Word32 Text   -> BinaryBit.BitGet LoadoutOnlineAttribute getLoadoutOnlineAttribute version objectMap = do   size <- getWord8Bits-  values <--    Monad.replicateM-      (fromIntegral (word8Value size))-      (getProductAttributes version objectMap)+  values <- Monad.replicateM+    (fromIntegral (word8Value size))+    (getProductAttributes version objectMap)   pure (LoadoutOnlineAttribute values)  putLoadoutOnlineAttribute :: LoadoutOnlineAttribute -> BinaryBit.BitPut ()
library/Rattletrap/Attribute/LoadoutsOnline.hs view
@@ -14,8 +14,8 @@   , loadoutsOnlineAttributeUnknown2 :: Bool   } deriving (Eq, Ord, Show) -getLoadoutsOnlineAttribute ::-     (Int, Int)+getLoadoutsOnlineAttribute+  :: (Int, Int, Int)   -> Map.Map Word32 Text   -> BinaryBit.BitGet LoadoutsOnlineAttribute getLoadoutsOnlineAttribute version objectMap = do
library/Rattletrap/Attribute/PartyLeader.hs view
@@ -11,16 +11,15 @@   , partyLeaderAttributeId :: Maybe (RemoteId, Word8)   } deriving (Eq, Ord, Show) -getPartyLeaderAttribute :: BinaryBit.BitGet PartyLeaderAttribute-getPartyLeaderAttribute = do+getPartyLeaderAttribute :: (Int, Int, Int) -> BinaryBit.BitGet PartyLeaderAttribute+getPartyLeaderAttribute version = do   systemId <- getWord8Bits-  maybeRemoteAndLocalId <--    if systemId == Word8 0-      then pure Nothing-      else do-        remoteId <- getRemoteId systemId-        localId <- getWord8Bits-        pure (Just (remoteId, localId))+  maybeRemoteAndLocalId <- if systemId == Word8 0+    then pure Nothing+    else do+      remoteId <- getRemoteId version systemId+      localId <- getWord8Bits+      pure (Just (remoteId, localId))   pure (PartyLeaderAttribute systemId maybeRemoteAndLocalId)  putPartyLeaderAttribute :: PartyLeaderAttribute -> BinaryBit.BitPut ()
library/Rattletrap/Attribute/Pickup.hs view
@@ -13,12 +13,11 @@ getPickupAttribute :: BinaryBit.BitGet PickupAttribute getPickupAttribute = do   instigator <- BinaryBit.getBool-  maybeInstigatorId <--    if instigator-      then do-        instigatorId <- getWord32Bits-        pure (Just instigatorId)-      else pure Nothing+  maybeInstigatorId <- if instigator+    then do+      instigatorId <- getWord32Bits+      pure (Just instigatorId)+    else pure Nothing   pickedUp <- BinaryBit.getBool   pure (PickupAttribute maybeInstigatorId pickedUp) 
library/Rattletrap/Attribute/PrivateMatchSettings.hs view
@@ -14,8 +14,8 @@   , privateMatchSettingsAttributeFlag :: Bool   } deriving (Eq, Ord, Show) -getPrivateMatchSettingsAttribute ::-     BinaryBit.BitGet PrivateMatchSettingsAttribute+getPrivateMatchSettingsAttribute+  :: BinaryBit.BitGet PrivateMatchSettingsAttribute getPrivateMatchSettingsAttribute = do   mutators <- getTextBits   joinableBy <- getWord32Bits@@ -24,16 +24,17 @@   password <- getTextBits   flag <- BinaryBit.getBool   pure-    (PrivateMatchSettingsAttribute-       mutators-       joinableBy-       maxPlayers-       gameName-       password-       flag)+    ( PrivateMatchSettingsAttribute+      mutators+      joinableBy+      maxPlayers+      gameName+      password+      flag+    ) -putPrivateMatchSettingsAttribute ::-     PrivateMatchSettingsAttribute -> BinaryBit.BitPut ()+putPrivateMatchSettingsAttribute+  :: PrivateMatchSettingsAttribute -> BinaryBit.BitPut () putPrivateMatchSettingsAttribute privateMatchSettingsAttribute = do   putTextBits     (privateMatchSettingsAttributeMutators privateMatchSettingsAttribute)
+ library/Rattletrap/Attribute/Product.hs view
@@ -0,0 +1,87 @@+module Rattletrap.Attribute.Product where++import Rattletrap.Primitive++import qualified Control.Monad as Monad+import qualified Data.Binary.Bits.Get as BinaryBit+import qualified Data.Binary.Bits.Put as BinaryBit+import qualified Data.Map as Map+import qualified Data.Word as Word++data ProductAttribute = ProductAttribute+  { productAttributeUnknown :: Bool+  , productAttributeObjectId :: Word32+  , productAttributeObjectName :: Maybe Text+  -- ^ read-only+  , productAttributeValue :: Maybe (Either CompressedWord Word.Word32)+  } deriving (Eq, Ord, Show)++getProductAttributes+  :: (Int, Int, Int) -> Map.Map Word32 Text -> BinaryBit.BitGet [ProductAttribute]+getProductAttributes version objectMap = do+  size <- getWord8Bits+  Monad.replicateM+    (fromIntegral (word8Value size))+    (getProductAttribute version objectMap)++getProductAttribute+  :: (Int, Int, Int) -> Map.Map Word32 Text -> BinaryBit.BitGet ProductAttribute+getProductAttribute version objectMap = do+  flag <- BinaryBit.getBool+  objectId <- getWord32Bits+  let objectName = Map.lookup objectId objectMap+  value <- case objectName of+    Just name -> case textToString name of+      "TAGame.ProductAttribute_Painted_TA" -> if version >= (868, 18, 0)+        then do+          x <- BinaryBit.getWord32be 31+          pure (Just (Right x))+        else do+          x <- getCompressedWord 14+          pure (Just (Left x))+      "TAGame.ProductAttribute_UserColor_TA" -> do+        hasValue <- BinaryBit.getBool+        value <- if hasValue+          then do+            x <- BinaryBit.getWord32be 31+            pure (Just (Right x))+          else pure Nothing+        pure value+      _ ->+        fail+          ( "unknown object name "+          ++ show objectName+          ++ " for ID "+          ++ show objectId+          )+    Nothing -> fail ("missing object name for ID " ++ show objectId)+  pure (ProductAttribute flag objectId objectName value)++putProductAttributes :: [ProductAttribute] -> BinaryBit.BitPut ()+putProductAttributes attributes = do+  putWord8Bits (Word8 (fromIntegral (length attributes)))+  mapM_ putProductAttribute attributes++putProductAttribute :: ProductAttribute -> BinaryBit.BitPut ()+putProductAttribute attribute = do+  BinaryBit.putBool (productAttributeUnknown attribute)+  putWord32Bits (productAttributeObjectId attribute)+  case productAttributeObjectName attribute of+    Just name -> case textToString name of+      "TAGame.ProductAttribute_Painted_TA" ->+        case productAttributeValue attribute of+          Nothing -> pure ()+          Just (Left x) -> putCompressedWord x+          Just (Right x) -> BinaryBit.putWord32be 31 x+      "TAGame.ProductAttribute_UserColor_TA" ->+        case productAttributeValue attribute of+          Nothing -> BinaryBit.putBool False+          Just value -> do+            BinaryBit.putBool True+            case value of+              Left x -> putCompressedWord x+              Right x -> BinaryBit.putWord32be 31 x+      _ ->+        fail ("unknown object name for product attribute " ++ show attribute)+    Nothing ->+      fail ("missing object name for product attribute " ++ show attribute)
− library/Rattletrap/Attribute/ProductAttribute.hs
@@ -1,89 +0,0 @@-module Rattletrap.Attribute.ProductAttribute where--import Rattletrap.Primitive--import qualified Control.Monad as Monad-import qualified Data.Binary.Bits.Get as BinaryBit-import qualified Data.Binary.Bits.Put as BinaryBit-import qualified Data.Map as Map-import qualified Data.Word as Word--data ProductAttribute = ProductAttribute-  { productAttributeUnknown :: Bool-  , productAttributeObjectId :: Word32-  , productAttributeObjectName :: Maybe Text-  -- ^ read-only-  , productAttributeValue :: Maybe (Either CompressedWord Word.Word32)-  } deriving (Eq, Ord, Show)--getProductAttributes ::-     (Int, Int) -> Map.Map Word32 Text -> BinaryBit.BitGet [ProductAttribute]-getProductAttributes version objectMap = do-  size <- getWord8Bits-  Monad.replicateM-    (fromIntegral (word8Value size))-    (getProductAttribute version objectMap)--getProductAttribute ::-     (Int, Int) -> Map.Map Word32 Text -> BinaryBit.BitGet ProductAttribute-getProductAttribute version objectMap = do-  flag <- BinaryBit.getBool-  objectId <- getWord32Bits-  let objectName = Map.lookup objectId objectMap-  value <--    case objectName of-      Just name ->-        case textToString name of-          "TAGame.ProductAttribute_Painted_TA" ->-            if version >= (868, 18)-              then do-                x <- BinaryBit.getWord32be 31-                pure (Just (Right x))-              else do-                x <- getCompressedWord 14-                pure (Just (Left x))-          "TAGame.ProductAttribute_UserColor_TA" -> do-            hasValue <- BinaryBit.getBool-            value <--              if hasValue-                then do-                  x <- BinaryBit.getWord32be 31-                  pure (Just (Right x))-                else pure Nothing-            pure value-          _ ->-            fail-              ("unknown object name " ++-               show objectName ++ " for ID " ++ show objectId)-      Nothing -> fail ("missing object name for ID " ++ show objectId)-  pure (ProductAttribute flag objectId objectName value)--putProductAttributes :: [ProductAttribute] -> BinaryBit.BitPut ()-putProductAttributes attributes = do-  putWord8Bits (Word8 (fromIntegral (length attributes)))-  mapM_ putProductAttribute attributes--putProductAttribute :: ProductAttribute -> BinaryBit.BitPut ()-putProductAttribute attribute = do-  BinaryBit.putBool (productAttributeUnknown attribute)-  putWord32Bits (productAttributeObjectId attribute)-  case productAttributeObjectName attribute of-    Just name ->-      case textToString name of-        "TAGame.ProductAttribute_Painted_TA" ->-          case productAttributeValue attribute of-            Nothing -> pure ()-            Just (Left x) -> putCompressedWord x-            Just (Right x) -> BinaryBit.putWord32be 31 x-        "TAGame.ProductAttribute_UserColor_TA" ->-          case productAttributeValue attribute of-            Nothing -> BinaryBit.putBool False-            Just value -> do-              BinaryBit.putBool True-              case value of-                Left x -> putCompressedWord x-                Right x -> BinaryBit.putWord32be 31 x-        _ ->-          fail ("unknown object name for product attribute " ++ show attribute)-    Nothing ->-      fail ("missing object name for product attribute " ++ show attribute)
library/Rattletrap/Attribute/Reservation.hs view
@@ -16,24 +16,22 @@   , reservationAttributeUnknown3 :: Maybe Word.Word8   } deriving (Eq, Ord, Show) -getReservationAttribute :: (Int, Int) -> BinaryBit.BitGet ReservationAttribute+getReservationAttribute :: (Int, Int, Int) -> BinaryBit.BitGet ReservationAttribute getReservationAttribute version = do   number <- getCompressedWord 7-  uniqueId <- getUniqueIdAttribute-  name <--    if uniqueIdAttributeSystemId uniqueId == Word8 0-      then pure Nothing-      else do-        name <- getTextBits-        pure (Just name)+  uniqueId <- getUniqueIdAttribute version+  name <- if uniqueIdAttributeSystemId uniqueId == Word8 0+    then pure Nothing+    else do+      name <- getTextBits+      pure (Just name)   a <- BinaryBit.getBool   b <- BinaryBit.getBool-  mc <--    if version < (868, 12)-      then pure Nothing-      else do-        c <- BinaryBit.getWord8 6-        pure (Just c)+  mc <- if version < (868, 12, 0)+    then pure Nothing+    else do+      c <- BinaryBit.getWord8 6+      pure (Just c)   pure (ReservationAttribute number uniqueId name a b mc)  putReservationAttribute :: ReservationAttribute -> BinaryBit.BitPut ()
library/Rattletrap/Attribute/RigidBodyState.hs view
@@ -18,25 +18,24 @@   sleeping <- BinaryBit.getBool   location <- getVector   rotation <- getCompressedWordVector-  linearVelocity <--    if sleeping-      then pure Nothing-      else do-        linearVelocity <- getVector-        pure (Just linearVelocity)-  angularVelocity <--    if sleeping-      then pure Nothing-      else do-        angularVelocity <- getVector-        pure (Just angularVelocity)+  linearVelocity <- if sleeping+    then pure Nothing+    else do+      linearVelocity <- getVector+      pure (Just linearVelocity)+  angularVelocity <- if sleeping+    then pure Nothing+    else do+      angularVelocity <- getVector+      pure (Just angularVelocity)   pure-    (RigidBodyStateAttribute-       sleeping-       location-       rotation-       linearVelocity-       angularVelocity)+    ( RigidBodyStateAttribute+      sleeping+      location+      rotation+      linearVelocity+      angularVelocity+    )  putRigidBodyStateAttribute :: RigidBodyStateAttribute -> BinaryBit.BitPut () putRigidBodyStateAttribute rigidBodyStateAttribute = do
library/Rattletrap/Attribute/TeamPaint.hs view
@@ -21,12 +21,13 @@   primaryFinish <- getWord32Bits   accentFinish <- getWord32Bits   pure-    (TeamPaintAttribute-       team-       primaryColor-       accentColor-       primaryFinish-       accentFinish)+    ( TeamPaintAttribute+      team+      primaryColor+      accentColor+      primaryFinish+      accentFinish+    )  putTeamPaintAttribute :: TeamPaintAttribute -> BinaryBit.BitPut () putTeamPaintAttribute teamPaintAttribute = do
library/Rattletrap/Attribute/UniqueId.hs view
@@ -12,10 +12,10 @@   , uniqueIdAttributeLocalId :: Word8   } deriving (Eq, Ord, Show) -getUniqueIdAttribute :: BinaryBit.BitGet UniqueIdAttribute-getUniqueIdAttribute = do+getUniqueIdAttribute :: (Int, Int, Int) -> BinaryBit.BitGet UniqueIdAttribute+getUniqueIdAttribute version = do   systemId <- getWord8Bits-  remoteId <- getRemoteId systemId+  remoteId <- getRemoteId version systemId   localId <- getWord8Bits   pure (UniqueIdAttribute systemId remoteId localId) 
library/Rattletrap/AttributeValue.hs view
@@ -23,7 +23,7 @@   , module Rattletrap.Attribute.PartyLeader   , module Rattletrap.Attribute.Pickup   , module Rattletrap.Attribute.PrivateMatchSettings-  , module Rattletrap.Attribute.ProductAttribute+  , module Rattletrap.Attribute.Product   , module Rattletrap.Attribute.QWord   , module Rattletrap.Attribute.Reservation   , module Rattletrap.Attribute.RigidBodyState@@ -56,7 +56,7 @@ import Rattletrap.Attribute.PartyLeader import Rattletrap.Attribute.Pickup import Rattletrap.Attribute.PrivateMatchSettings-import Rattletrap.Attribute.ProductAttribute+import Rattletrap.Attribute.Product import Rattletrap.Attribute.QWord import Rattletrap.Attribute.Reservation import Rattletrap.Attribute.RigidBodyState@@ -105,140 +105,138 @@   | WeldedInfoAttributeValue WeldedInfoAttribute   deriving (Eq, Ord, Show) -getAttributeValue ::-     (Int, Int)+getAttributeValue+  :: (Int, Int, Int)   -> Map.Map Word32 Text   -> Text   -> BinaryBit.BitGet AttributeValue getAttributeValue version objectMap name =   case Map.lookup name attributeTypes of-    Just constructor ->-      case constructor of-        AppliedDamageAttributeType -> do-          x <- getAppliedDamageAttribute-          pure (AppliedDamageAttributeValue x)-        BooleanAttributeType -> do-          x <- getBooleanAttribute-          pure (BooleanAttributeValue x)-        ByteAttributeType -> do-          x <- getByteAttribute-          pure (ByteAttributeValue x)-        CamSettingsAttributeType -> do-          x <- getCamSettingsAttribute version-          pure (CamSettingsAttributeValue x)-        ClubColorsAttributeType -> do-          x <- getClubColorsAttribute-          pure (ClubColorsAttributeValue x)-        DamageStateAttributeType -> do-          x <- getDamageStateAttribute-          pure (DamageStateAttributeValue x)-        DemolishAttributeType -> do-          x <- getDemolishAttribute-          pure (DemolishAttributeValue x)-        EnumAttributeType -> do-          x <- getEnumAttribute-          pure (EnumAttributeValue x)-        ExplosionAttributeType -> do-          x <- getExplosionAttribute-          pure (ExplosionAttributeValue x)-        ExtendedExplosionAttributeType -> do-          x <- getExtendedExplosionAttribute-          pure (ExtendedExplosionAttributeValue x)-        FlaggedIntAttributeType -> do-          x <- getFlaggedIntAttribute-          pure (FlaggedIntAttributeValue x)-        FloatAttributeType -> do-          x <- getFloatAttribute-          pure (FloatAttributeValue x)-        GameModeAttributeType -> do-          x <- getGameModeAttribute version-          pure (GameModeAttributeValue x)-        IntAttributeType -> do-          x <- getIntAttribute-          pure (IntAttributeValue x)-        LoadoutAttributeType -> do-          x <- getLoadoutAttribute-          pure (LoadoutAttributeValue x)-        LoadoutOnlineAttributeType -> do-          x <- getLoadoutOnlineAttribute version objectMap-          pure (LoadoutOnlineAttributeValue x)-        LoadoutsAttributeType -> do-          x <- getLoadoutsAttribute-          pure (LoadoutsAttributeValue x)-        LoadoutsOnlineAttributeType -> do-          x <- getLoadoutsOnlineAttribute version objectMap-          pure (LoadoutsOnlineAttributeValue x)-        LocationAttributeType -> do-          x <- getLocationAttribute-          pure (LocationAttributeValue x)-        MusicStingerAttributeType -> do-          x <- getMusicStingerAttribute-          pure (MusicStingerAttributeValue x)-        PartyLeaderAttributeType -> do-          x <- getPartyLeaderAttribute-          pure (PartyLeaderAttributeValue x)-        PickupAttributeType -> do-          x <- getPickupAttribute-          pure (PickupAttributeValue x)-        PrivateMatchSettingsAttributeType -> do-          x <- getPrivateMatchSettingsAttribute-          pure (PrivateMatchSettingsAttributeValue x)-        QWordAttributeType -> do-          x <- getQWordAttribute-          pure (QWordAttributeValue x)-        ReservationAttributeType -> do-          x <- getReservationAttribute version-          pure (ReservationAttributeValue x)-        RigidBodyStateAttributeType -> do-          x <- getRigidBodyStateAttribute-          pure (RigidBodyStateAttributeValue x)-        StringAttributeType -> do-          x <- getStringAttribute-          pure (StringAttributeValue x)-        TeamPaintAttributeType -> do-          x <- getTeamPaintAttribute-          pure (TeamPaintAttributeValue x)-        UniqueIdAttributeType -> do-          x <- getUniqueIdAttribute-          pure (UniqueIdAttributeValue x)-        WeldedInfoAttributeType -> do-          x <- getWeldedInfoAttribute-          pure (WeldedInfoAttributeValue x)+    Just constructor -> case constructor of+      AppliedDamageAttributeType -> do+        x <- getAppliedDamageAttribute+        pure (AppliedDamageAttributeValue x)+      BooleanAttributeType -> do+        x <- getBooleanAttribute+        pure (BooleanAttributeValue x)+      ByteAttributeType -> do+        x <- getByteAttribute+        pure (ByteAttributeValue x)+      CamSettingsAttributeType -> do+        x <- getCamSettingsAttribute version+        pure (CamSettingsAttributeValue x)+      ClubColorsAttributeType -> do+        x <- getClubColorsAttribute+        pure (ClubColorsAttributeValue x)+      DamageStateAttributeType -> do+        x <- getDamageStateAttribute+        pure (DamageStateAttributeValue x)+      DemolishAttributeType -> do+        x <- getDemolishAttribute+        pure (DemolishAttributeValue x)+      EnumAttributeType -> do+        x <- getEnumAttribute+        pure (EnumAttributeValue x)+      ExplosionAttributeType -> do+        x <- getExplosionAttribute+        pure (ExplosionAttributeValue x)+      ExtendedExplosionAttributeType -> do+        x <- getExtendedExplosionAttribute+        pure (ExtendedExplosionAttributeValue x)+      FlaggedIntAttributeType -> do+        x <- getFlaggedIntAttribute+        pure (FlaggedIntAttributeValue x)+      FloatAttributeType -> do+        x <- getFloatAttribute+        pure (FloatAttributeValue x)+      GameModeAttributeType -> do+        x <- getGameModeAttribute version+        pure (GameModeAttributeValue x)+      IntAttributeType -> do+        x <- getIntAttribute+        pure (IntAttributeValue x)+      LoadoutAttributeType -> do+        x <- getLoadoutAttribute+        pure (LoadoutAttributeValue x)+      LoadoutOnlineAttributeType -> do+        x <- getLoadoutOnlineAttribute version objectMap+        pure (LoadoutOnlineAttributeValue x)+      LoadoutsAttributeType -> do+        x <- getLoadoutsAttribute+        pure (LoadoutsAttributeValue x)+      LoadoutsOnlineAttributeType -> do+        x <- getLoadoutsOnlineAttribute version objectMap+        pure (LoadoutsOnlineAttributeValue x)+      LocationAttributeType -> do+        x <- getLocationAttribute+        pure (LocationAttributeValue x)+      MusicStingerAttributeType -> do+        x <- getMusicStingerAttribute+        pure (MusicStingerAttributeValue x)+      PartyLeaderAttributeType -> do+        x <- getPartyLeaderAttribute version+        pure (PartyLeaderAttributeValue x)+      PickupAttributeType -> do+        x <- getPickupAttribute+        pure (PickupAttributeValue x)+      PrivateMatchSettingsAttributeType -> do+        x <- getPrivateMatchSettingsAttribute+        pure (PrivateMatchSettingsAttributeValue x)+      QWordAttributeType -> do+        x <- getQWordAttribute+        pure (QWordAttributeValue x)+      ReservationAttributeType -> do+        x <- getReservationAttribute version+        pure (ReservationAttributeValue x)+      RigidBodyStateAttributeType -> do+        x <- getRigidBodyStateAttribute+        pure (RigidBodyStateAttributeValue x)+      StringAttributeType -> do+        x <- getStringAttribute+        pure (StringAttributeValue x)+      TeamPaintAttributeType -> do+        x <- getTeamPaintAttribute+        pure (TeamPaintAttributeValue x)+      UniqueIdAttributeType -> do+        x <- getUniqueIdAttribute version+        pure (UniqueIdAttributeValue x)+      WeldedInfoAttributeType -> do+        x <- getWeldedInfoAttribute+        pure (WeldedInfoAttributeValue x)     Nothing -> fail ("don't know how to get attribute value " ++ show name)  attributeTypes :: Map.Map Text AttributeType attributeTypes = Map.mapKeys stringToText (Map.fromList rawAttributeTypes)  putAttributeValue :: AttributeValue -> BinaryBit.BitPut ()-putAttributeValue value =-  case value of-    AppliedDamageAttributeValue x -> putAppliedDamageAttribute x-    BooleanAttributeValue x -> putBooleanAttribute x-    ByteAttributeValue x -> putByteAttribute x-    CamSettingsAttributeValue x -> putCamSettingsAttribute x-    ClubColorsAttributeValue x -> putClubColorsAttribute x-    DamageStateAttributeValue x -> putDamageStateAttribute x-    DemolishAttributeValue x -> putDemolishAttribute x-    EnumAttributeValue x -> putEnumAttribute x-    ExplosionAttributeValue x -> putExplosionAttribute x-    ExtendedExplosionAttributeValue x -> putExtendedExplosionAttribute x-    FlaggedIntAttributeValue x -> putFlaggedIntAttribute x-    FloatAttributeValue x -> putFloatAttribute x-    GameModeAttributeValue x -> putGameModeAttribute x-    IntAttributeValue x -> putIntAttribute x-    LoadoutAttributeValue x -> putLoadoutAttribute x-    LoadoutOnlineAttributeValue x -> putLoadoutOnlineAttribute x-    LoadoutsAttributeValue x -> putLoadoutsAttribute x-    LoadoutsOnlineAttributeValue x -> putLoadoutsOnlineAttribute x-    LocationAttributeValue x -> putLocationAttribute x-    MusicStingerAttributeValue x -> putMusicStingerAttribute x-    PartyLeaderAttributeValue x -> putPartyLeaderAttribute x-    PickupAttributeValue x -> putPickupAttribute x-    PrivateMatchSettingsAttributeValue x -> putPrivateMatchSettingsAttribute x-    QWordAttributeValue x -> putQWordAttribute x-    ReservationAttributeValue x -> putReservationAttribute x-    RigidBodyStateAttributeValue x -> putRigidBodyStateAttribute x-    StringAttributeValue x -> putStringAttribute x-    TeamPaintAttributeValue x -> putTeamPaintAttribute x-    UniqueIdAttributeValue x -> putUniqueIdAttribute x-    WeldedInfoAttributeValue x -> putWeldedInfoAttribute x+putAttributeValue value = case value of+  AppliedDamageAttributeValue x -> putAppliedDamageAttribute x+  BooleanAttributeValue x -> putBooleanAttribute x+  ByteAttributeValue x -> putByteAttribute x+  CamSettingsAttributeValue x -> putCamSettingsAttribute x+  ClubColorsAttributeValue x -> putClubColorsAttribute x+  DamageStateAttributeValue x -> putDamageStateAttribute x+  DemolishAttributeValue x -> putDemolishAttribute x+  EnumAttributeValue x -> putEnumAttribute x+  ExplosionAttributeValue x -> putExplosionAttribute x+  ExtendedExplosionAttributeValue x -> putExtendedExplosionAttribute x+  FlaggedIntAttributeValue x -> putFlaggedIntAttribute x+  FloatAttributeValue x -> putFloatAttribute x+  GameModeAttributeValue x -> putGameModeAttribute x+  IntAttributeValue x -> putIntAttribute x+  LoadoutAttributeValue x -> putLoadoutAttribute x+  LoadoutOnlineAttributeValue x -> putLoadoutOnlineAttribute x+  LoadoutsAttributeValue x -> putLoadoutsAttribute x+  LoadoutsOnlineAttributeValue x -> putLoadoutsOnlineAttribute x+  LocationAttributeValue x -> putLocationAttribute x+  MusicStingerAttributeValue x -> putMusicStingerAttribute x+  PartyLeaderAttributeValue x -> putPartyLeaderAttribute x+  PickupAttributeValue x -> putPickupAttribute x+  PrivateMatchSettingsAttributeValue x -> putPrivateMatchSettingsAttribute x+  QWordAttributeValue x -> putQWordAttribute x+  ReservationAttributeValue x -> putReservationAttribute x+  RigidBodyStateAttributeValue x -> putRigidBodyStateAttribute x+  StringAttributeValue x -> putStringAttribute x+  TeamPaintAttributeValue x -> putTeamPaintAttribute x+  UniqueIdAttributeValue x -> putUniqueIdAttribute x+  WeldedInfoAttributeValue x -> putWeldedInfoAttribute x
library/Rattletrap/ClassAttributeMap.hs view
@@ -33,8 +33,8 @@  -- | Makes a 'ClassAttributeMap' given the necessary fields from the -- 'Rattletrap.Content.Content'.-makeClassAttributeMap ::-     List Text+makeClassAttributeMap+  :: List Text   -- ^ From 'Rattletrap.Content.contentObjects'.   -> List ClassMapping   -- ^ From 'Rattletrap.Content.contentClassMappings'.@@ -44,35 +44,34 @@   -- ^ From 'Rattletrap.Content.contentNames'.   -> ClassAttributeMap makeClassAttributeMap objects classMappings caches names =-  let objectMap = makeObjectMap objects-      classMap = makeClassMap classMappings-      objectClassMap = makeObjectClassMap objectMap classMap-      classCache = makeClassCache classMap caches-      attributeMap = makeAttributeMap caches-      classIds = map (\(_, classId, _, _) -> classId) classCache-      parentMap = makeParentMap classCache-      value =-        Map.fromList-          (map-             (\classId ->-                let ownAttributes =-                      Maybe.fromMaybe-                        Map.empty-                        (Map.lookup classId attributeMap)-                    parentsAttributes =-                      case Map.lookup classId parentMap of-                        Nothing -> []-                        Just parentClassIds ->-                          map-                            (\parentClassId ->-                               Maybe.fromMaybe-                                 Map.empty-                                 (Map.lookup parentClassId attributeMap))-                            parentClassIds-                    attributes = ownAttributes : parentsAttributes-                in (classId, Map.fromList (concatMap Map.toList attributes)))-             classIds)-      nameMap = makeNameMap names+  let+    objectMap = makeObjectMap objects+    classMap = makeClassMap classMappings+    objectClassMap = makeObjectClassMap objectMap classMap+    classCache = makeClassCache classMap caches+    attributeMap = makeAttributeMap caches+    classIds = map (\(_, classId, _, _) -> classId) classCache+    parentMap = makeParentMap classCache+    value = Map.fromList+      ( map+        ( \classId ->+          let+            ownAttributes =+              Maybe.fromMaybe Map.empty (Map.lookup classId attributeMap)+            parentsAttributes = case Map.lookup classId parentMap of+              Nothing -> []+              Just parentClassIds -> map+                ( \parentClassId -> Maybe.fromMaybe+                  Map.empty+                  (Map.lookup parentClassId attributeMap)+                )+                parentClassIds+            attributes = ownAttributes : parentsAttributes+          in (classId, Map.fromList (concatMap Map.toList attributes))+        )+        classIds+      )+    nameMap = makeNameMap names   in ClassAttributeMap objectMap objectClassMap value nameMap  makeNameMap :: List Text -> IntMap.IntMap Text@@ -82,84 +81,95 @@ getName nameMap nameIndex =   IntMap.lookup (fromIntegral (word32Value nameIndex)) nameMap -makeObjectClassMap ::-     Map.Map Word32 Text -> Bimap.Bimap Word32 Text -> Map.Map Word32 Word32+makeObjectClassMap+  :: Map.Map Word32 Text -> Bimap.Bimap Word32 Text -> Map.Map Word32 Word32 makeObjectClassMap objectMap classMap = do   let objectIds = Map.keys objectMap   let classIds = map (getClassId objectMap classMap) objectIds   let rawPairs = zip objectIds classIds-  let pairs =-        Maybe.mapMaybe-          (\(objectId, maybeClassId) ->-             case maybeClassId of-               Nothing -> Nothing-               Just classId -> Just (objectId, classId))-          rawPairs+  let+    pairs = Maybe.mapMaybe+      ( \(objectId, maybeClassId) -> case maybeClassId of+        Nothing -> Nothing+        Just classId -> Just (objectId, classId)+      )+      rawPairs   Map.fromList pairs -getClassId ::-     Map.Map Word32 Text -> Bimap.Bimap Word32 Text -> Word32 -> Maybe Word32+getClassId+  :: Map.Map Word32 Text -> Bimap.Bimap Word32 Text -> Word32 -> Maybe Word32 getClassId objectMap classMap objectId = do   objectName <- getObjectName objectMap objectId   className <- getClassName objectName   Bimap.lookupR className classMap -makeClassCache ::-     Bimap.Bimap Word32 Text+makeClassCache+  :: Bimap.Bimap Word32 Text   -> List Cache   -> [(Maybe Text, Word32, Word32, Word32)]-makeClassCache classMap caches =-  map-    (\cache ->-       let classId = cacheClassId cache-       in ( Bimap.lookup classId classMap-          , classId-          , cacheCacheId cache-          , cacheParentCacheId cache))-    (listValue caches)+makeClassCache classMap caches = map+  ( \cache ->+    let+      classId = cacheClassId cache+    in+      ( Bimap.lookup classId classMap+      , classId+      , cacheCacheId cache+      , cacheParentCacheId cache+      )+  )+  (listValue caches)  makeClassMap :: List ClassMapping -> Bimap.Bimap Word32 Text-makeClassMap classMappings =-  Bimap.fromList-    (map-       (\classMapping ->-          (classMappingStreamId classMapping, classMappingName classMapping))-       (listValue classMappings))+makeClassMap classMappings = Bimap.fromList+  ( map+    ( \classMapping ->+      (classMappingStreamId classMapping, classMappingName classMapping)+    )+    (listValue classMappings)+  )  makeAttributeMap :: List Cache -> Map.Map Word32 (Map.Map Word32 Word32)-makeAttributeMap caches =-  Map.fromList-    (map-       (\cache ->-          ( cacheClassId cache-          , Map.fromList-              (map-                 (\attributeMapping ->-                    ( attributeMappingStreamId attributeMapping-                    , attributeMappingObjectId attributeMapping))-                 (listValue (cacheAttributeMappings cache)))))-       (listValue caches))+makeAttributeMap caches = Map.fromList+  ( map+    ( \cache ->+      ( cacheClassId cache+      , Map.fromList+        ( map+          ( \attributeMapping ->+            ( attributeMappingStreamId attributeMapping+            , attributeMappingObjectId attributeMapping+            )+          )+          (listValue (cacheAttributeMappings cache))+        )+      )+    )+    (listValue caches)+  ) -makeShallowParentMap ::-     [(Maybe Text, Word32, Word32, Word32)] -> Map.Map Word32 Word32-makeShallowParentMap classCache =-  Map.fromList-    (Maybe.mapMaybe-       (\xs ->-          case xs of-            [] -> Nothing-            (maybeClassName, classId, _, parentCacheId):rest -> do-              parentClassId <- getParentClass maybeClassName parentCacheId rest-              pure (classId, parentClassId))-       (List.tails (reverse classCache)))+makeShallowParentMap+  :: [(Maybe Text, Word32, Word32, Word32)] -> Map.Map Word32 Word32+makeShallowParentMap classCache = Map.fromList+  ( Maybe.mapMaybe+    ( \xs -> case xs of+      [] -> Nothing+      (maybeClassName, classId, _, parentCacheId):rest -> do+        parentClassId <- getParentClass maybeClassName parentCacheId rest+        pure (classId, parentClassId)+    )+    (List.tails (reverse classCache))+  ) -makeParentMap ::-     [(Maybe Text, Word32, Word32, Word32)] -> Map.Map Word32 [Word32]+makeParentMap+  :: [(Maybe Text, Word32, Word32, Word32)] -> Map.Map Word32 [Word32] makeParentMap classCache =-  let shallowParentMap = makeShallowParentMap classCache-  in Map.mapWithKey-       (\classId _ -> getParentClasses shallowParentMap classId)-       shallowParentMap+  let+    shallowParentMap = makeShallowParentMap classCache+  in+    Map.mapWithKey+      (\classId _ -> getParentClasses shallowParentMap classId)+      shallowParentMap  getParentClasses :: Map.Map Word32 Word32 -> Word32 -> [Word32] getParentClasses shallowParentMap classId =@@ -168,50 +178,51 @@     Just parentClassId ->       parentClassId : getParentClasses shallowParentMap parentClassId -getParentClass ::-     Maybe Text+getParentClass+  :: Maybe Text   -> Word32   -> [(Maybe Text, Word32, Word32, Word32)]   -> Maybe Word32-getParentClass maybeClassName parentCacheId xs =-  case maybeClassName of-    Nothing -> getParentClassById parentCacheId xs-    Just className -> getParentClassByName className parentCacheId xs+getParentClass maybeClassName parentCacheId xs = case maybeClassName of+  Nothing -> getParentClassById parentCacheId xs+  Just className -> getParentClassByName className parentCacheId xs -getParentClassById ::-     Word32 -> [(Maybe Text, Word32, Word32, Word32)] -> Maybe Word32+getParentClassById+  :: Word32 -> [(Maybe Text, Word32, Word32, Word32)] -> Maybe Word32 getParentClassById parentCacheId xs =   case dropWhile (\(_, _, cacheId, _) -> cacheId /= parentCacheId) xs of-    [] ->-      if parentCacheId == Word32 0-        then Nothing-        else getParentClassById (Word32 (word32Value parentCacheId - 1)) xs+    [] -> if parentCacheId == Word32 0+      then Nothing+      else getParentClassById (Word32 (word32Value parentCacheId - 1)) xs     (_, parentClassId, _, _):_ -> Just parentClassId -getParentClassByName ::-     Text -> Word32 -> [(Maybe Text, Word32, Word32, Word32)] -> Maybe Word32+getParentClassByName+  :: Text -> Word32 -> [(Maybe Text, Word32, Word32, Word32)] -> Maybe Word32 getParentClassByName className parentCacheId xs =   case Map.lookup className parentClasses of     Nothing -> getParentClassById parentCacheId xs-    Just parentClassName ->-      Maybe.maybe-        (getParentClassById parentCacheId xs)-        Just-        (Maybe.listToMaybe-           (map-              (\(_, parentClassId, _, _) -> parentClassId)-              (filter-                 (\(_, _, cacheId, _) -> cacheId <= parentCacheId)-                 (filter-                    (\(maybeClassName, _, _, _) ->-                       maybeClassName == Just parentClassName)-                    xs))))+    Just parentClassName -> Maybe.maybe+      (getParentClassById parentCacheId xs)+      Just+      ( Maybe.listToMaybe+        ( map+          (\(_, parentClassId, _, _) -> parentClassId)+          ( filter+            (\(_, _, cacheId, _) -> cacheId <= parentCacheId)+            ( filter+              ( \(maybeClassName, _, _, _) ->+                maybeClassName == Just parentClassName+              )+              xs+            )+          )+        )+      )  parentClasses :: Map.Map Text Text-parentClasses =-  Map.map-    stringToText-    (Map.mapKeys stringToText (Map.fromList rawParentClasses))+parentClasses = Map.map+  stringToText+  (Map.mapKeys stringToText (Map.fromList rawParentClasses))  makeObjectMap :: List Text -> Map.Map Word32 Text makeObjectMap objects =@@ -226,29 +237,29 @@  normalizeObjectName :: Text -> Text normalizeObjectName objectName =-  let name = textValue objectName-      crowdActor = Text.pack "TheWorld:PersistentLevel.CrowdActor_TA"-      crowdManager = Text.pack "TheWorld:PersistentLevel.CrowdManager_TA"-      boostPickup = Text.pack "TheWorld:PersistentLevel.VehiclePickup_Boost_TA"-      mapScoreboard = Text.pack "TheWorld:PersistentLevel.InMapScoreboard_TA"-      breakout = Text.pack "TheWorld:PersistentLevel.BreakOutActor_Platform_TA"+  let+    name = textValue objectName+    crowdActor = Text.pack "TheWorld:PersistentLevel.CrowdActor_TA"+    crowdManager = Text.pack "TheWorld:PersistentLevel.CrowdManager_TA"+    boostPickup = Text.pack "TheWorld:PersistentLevel.VehiclePickup_Boost_TA"+    mapScoreboard = Text.pack "TheWorld:PersistentLevel.InMapScoreboard_TA"+    breakout = Text.pack "TheWorld:PersistentLevel.BreakOutActor_Platform_TA"   in if Text.isInfixOf crowdActor name-       then Text crowdActor-       else if Text.isInfixOf crowdManager name-              then Text crowdManager-              else if Text.isInfixOf boostPickup name-                     then Text boostPickup-                     else if Text.isInfixOf mapScoreboard name-                            then Text mapScoreboard-                            else if Text.isInfixOf breakout name-                                   then Text breakout-                                   else objectName+    then Text crowdActor+    else if Text.isInfixOf crowdManager name+      then Text crowdManager+      else if Text.isInfixOf boostPickup name+        then Text boostPickup+        else if Text.isInfixOf mapScoreboard name+          then Text mapScoreboard+          else if Text.isInfixOf breakout name+            then Text breakout+            else objectName  objectClasses :: Map.Map Text Text-objectClasses =-  Map.map-    stringToText-    (Map.mapKeys stringToText (Map.fromList rawObjectClasses))+objectClasses = Map.map+  stringToText+  (Map.mapKeys stringToText (Map.fromList rawObjectClasses))  classHasLocation :: Text -> Bool classHasLocation className = Set.member className classesWithLocation@@ -268,16 +279,16 @@   let limit = fromIntegral (word32Value streamId)   pure limit -getAttributeName ::-     ClassAttributeMap -> Map.Map Word32 Word32 -> CompressedWord -> Maybe Text+getAttributeName+  :: ClassAttributeMap -> Map.Map Word32 Word32 -> CompressedWord -> Maybe Text getAttributeName classAttributeMap attributeMap streamId = do   let key = Word32 (fromIntegral (compressedWordValue streamId))   attributeId <- Map.lookup key attributeMap   let objectMap = classAttributeMapObjectMap classAttributeMap   Map.lookup attributeId objectMap -getAttributeMap ::-     ClassAttributeMap+getAttributeMap+  :: ClassAttributeMap   -> ActorMap   -> CompressedWord   -> Maybe (Map.Map Word32 Word32)
library/Rattletrap/Content.hs view
@@ -51,10 +51,9 @@   -- for the 'Rattletrap.ClassAttributeMap.ClassAttributeMap'.   } deriving (Eq, Ord, Show) -getContent ::-     (Int, Int)-  -- ^ Major and minor version numbers, usually from-  -- 'Rattletrap.Header.getVersion'.+getContent+  :: (Int, Int, Int)+  -- ^ Version numbers, usually from 'Rattletrap.Header.getVersion'.   -> Int   -- ^ The number of frames in the stream, usually from   -- 'Rattletrap.Header.getNumFrames'.@@ -74,33 +73,37 @@   names <- getList getText   classMappings <- getList getClassMapping   caches <- getList getCache-  let classAttributeMap =-        makeClassAttributeMap objects classMappings caches names-  let frames =-        Binary.runGet-          (BinaryBit.runBitGet-             (do (theFrames, _) <--                   getFrames-                     version-                     numFrames-                     maxChannels-                     classAttributeMap-                     Map.empty-                 pure theFrames))-          (reverseBytes stream)+  let+    classAttributeMap =+      makeClassAttributeMap objects classMappings caches names+  let+    frames = Binary.runGet+      ( BinaryBit.runBitGet+        ( do+          (theFrames, _) <- getFrames+            version+            numFrames+            maxChannels+            classAttributeMap+            Map.empty+          pure theFrames+        )+      )+      (reverseBytes stream)   pure-    (Content-       levels-       keyFrames-       streamSize-       frames-       messages-       marks-       packages-       objects-       names-       classMappings-       caches)+    ( Content+      levels+      keyFrames+      streamSize+      frames+      messages+      marks+      packages+      objects+      names+      classMappings+      caches+    )  putContent :: Content -> Binary.Put putContent content = do@@ -108,8 +111,9 @@   putList putKeyFrame (contentKeyFrames content)   let streamSize = contentStreamSize content   putWord32 streamSize-  let stream =-        Binary.runPut (BinaryBit.runBitPut (putFrames (contentFrames content)))+  let+    stream =+      Binary.runPut (BinaryBit.runBitPut (putFrames (contentFrames content)))   Binary.putLazyByteString     (reverseBytes (padBytes (word32Value streamSize) stream))   putList putMessage (contentMessages content)
library/Rattletrap/Crc.hs view
@@ -23,15 +23,11 @@   let crc = ByteString.foldl update initial bytes   Bits.complement crc -crc32Update ::-     Vector.Vector Word.Word32 -> Word.Word32 -> Word.Word8 -> Word.Word32+crc32Update+  :: Vector.Vector Word.Word32 -> Word.Word32 -> Word.Word8 -> Word.Word32 crc32Update table crc byte = do-  let toWord8 =-        fromIntegral :: (Integral a) =>-                          a -> Word.Word8-  let toInt =-        fromIntegral :: (Integral a) =>-                          a -> Int+  let toWord8 = fromIntegral :: (Integral a) => a -> Word.Word8+  let toInt = fromIntegral :: (Integral a) => a -> Int   let index = toInt (Bits.xor byte (toWord8 (Bits.shiftR crc 24)))   let left = Vector.unsafeIndex table index   let right = Bits.shiftL crc 8
library/Rattletrap/Frame.hs view
@@ -17,8 +17,8 @@   , frameReplications :: [Replication]   } deriving (Eq, Ord, Show) -getFrames ::-     (Int, Int)+getFrames+  :: (Int, Int, Int)   -> Int   -> Word   -> ClassAttributeMap@@ -28,22 +28,24 @@   if numFrames <= 0     then pure ([], actorMap)     else do-      (frame, newActorMap) <--        getFrame version maxChannels classAttributeMap actorMap-      (frames, newerActorMap) <--        getFrames-          version-          (numFrames - 1)-          maxChannels-          classAttributeMap-          newActorMap+      (frame, newActorMap) <- getFrame+        version+        maxChannels+        classAttributeMap+        actorMap+      (frames, newerActorMap) <- getFrames+        version+        (numFrames - 1)+        maxChannels+        classAttributeMap+        newActorMap       pure (frame : frames, newerActorMap)  putFrames :: [Frame] -> BinaryBit.BitPut () putFrames = mapM_ putFrame -getFrame ::-     (Int, Int)+getFrame+  :: (Int, Int, Int)   -> Word   -> ClassAttributeMap   -> ActorMap@@ -51,8 +53,11 @@ getFrame version maxChannels classAttributeMap actorMap = do   time <- getFloat32Bits   delta <- getFloat32Bits-  (replications, newActorMap) <--    getReplications version maxChannels classAttributeMap actorMap+  (replications, newActorMap) <- getReplications+    version+    maxChannels+    classAttributeMap+    actorMap   pure (Frame time delta replications, newActorMap)  putFrame :: Frame -> BinaryBit.BitPut ()
library/Rattletrap/Header.hs view
@@ -6,15 +6,16 @@  import qualified Data.Binary as Binary import qualified Data.Map as Map+import qualified Data.Maybe as Maybe  -- | Contains high-level metadata about a 'Rattletrap.Replay.Replay'. data Header = Header   { headerEngineVersion :: Word32-  -- ^ The "major" version number.+  -- ^ The "major" ("engine") version number.   , headerLicenseeVersion :: Word32-  -- ^ The "minor" version number.+  -- ^ The "minor" ("licensee") version number.   , headerPatchVersion :: Maybe Word32-  -- ^ The "patch" version number.+  -- ^ The "patch" ("net") version number.   , headerLabel :: Text   -- ^ Always @TAGame.Replay_Soccar_TA@.   , headerProperties :: Dictionary Property@@ -64,12 +65,11 @@   pure (Header engineVersion licenseeVersion patchVersion label properties)  getPatchVersion :: Word32 -> Word32 -> Binary.Get (Maybe Word32)-getPatchVersion major minor =-  if hasPatchVersion major minor-    then do-      patchVersion <- getWord32-      pure (Just patchVersion)-    else pure Nothing+getPatchVersion major minor = if hasPatchVersion major minor+  then do+    patchVersion <- getWord32+    pure (Just patchVersion)+  else pure Nothing  hasPatchVersion :: Word32 -> Word32 -> Bool hasPatchVersion major minor = major >= Word32 868 && minor >= Word32 18@@ -84,34 +84,29 @@   putText (headerLabel header)   putDictionary putProperty (headerProperties header) -getVersion :: Header -> (Int, Int)+getVersion :: Header -> (Int, Int, Int) getVersion header =-  let major = getMajorVersion header-      minor = getMinorVersion header-  in (major, minor)--getMajorVersion :: Header -> Int-getMajorVersion header =-  fromIntegral (word32Value (headerEngineVersion header))--getMinorVersion :: Header -> Int-getMinorVersion header =-  fromIntegral (word32Value (headerLicenseeVersion header))+  ( fromIntegral (word32Value (headerEngineVersion header))+  , fromIntegral (word32Value (headerLicenseeVersion header))+  , Maybe.fromMaybe 0 (fmap (\ v -> fromIntegral (word32Value v)) (headerPatchVersion header))+  )  getNumFrames :: Header -> Int getNumFrames header =-  let key = textValue (stringToText "NumFrames")-      properties = dictionaryValue (headerProperties header)+  let+    key = textValue (stringToText "NumFrames")+    properties = dictionaryValue (headerProperties header)   in case Map.lookup key properties of-       Just (Property _ _ (IntProperty numFrames)) ->-         fromIntegral (int32Value numFrames)-       _ -> 0+    Just (Property _ _ (IntProperty numFrames)) ->+      fromIntegral (int32Value numFrames)+    _ -> 0  getMaxChannels :: Header -> Word getMaxChannels header =-  let key = textValue (stringToText "MaxChannels")-      properties = dictionaryValue (headerProperties header)+  let+    key = textValue (stringToText "MaxChannels")+    properties = dictionaryValue (headerProperties header)   in case Map.lookup key properties of-       Just (Property _ _ (IntProperty numFrames)) ->-         fromIntegral (int32Value numFrames)-       _ -> 1023+    Just (Property _ _ (IntProperty numFrames)) ->+      fromIntegral (int32Value numFrames)+    _ -> 1023
library/Rattletrap/Helper.hs view
@@ -14,10 +14,9 @@ -- * Lazy byte strings -- | Parses a raw replay. decodeReplay :: ByteString.ByteString -> Either String Replay-decodeReplay contents =-  case Binary.runGetOrFail getReplay contents of-    Left (_, _, message) -> fail message-    Right (_, _, replay) -> pure replay+decodeReplay contents = case Binary.runGetOrFail getReplay contents of+  Left (_, _, message) -> fail message+  Right (_, _, replay) -> pure replay  -- | Encodes a replay as JSON. encodeJson :: Replay -> ByteString.ByteString
library/Rattletrap/Initialization.hs view
@@ -16,18 +16,16 @@  getInitialization :: Bool -> Bool -> BinaryBit.BitGet Initialization getInitialization hasLocation hasRotation = do-  location <--    if hasLocation-      then do-        location <- getVector-        pure (Just location)-      else pure Nothing-  rotation <--    if hasRotation-      then do-        rotation <- getInt8Vector-        pure (Just rotation)-      else pure Nothing+  location <- if hasLocation+    then do+      location <- getVector+      pure (Just location)+    else pure Nothing+  rotation <- if hasRotation+    then do+      rotation <- getInt8Vector+      pure (Just rotation)+    else pure Nothing   pure (Initialization location rotation)  putInitialization :: Initialization -> BinaryBit.BitPut ()
library/Rattletrap/Main.hs view
@@ -27,35 +27,29 @@ -- 3. @mainWithArgs ["encode"]@: Generates a raw replay from JSON. The --    handling of input and output is the same as decoding. mainWithArgs :: [String] -> IO ()-mainWithArgs args =-  case args of-    ["version"] -> putStrLn (Version.showVersion version)-    action:files -> do-      (getInput, putOutput) <- getIO files-      input <- getInput-      output <--        case action of-          "decode" ->-            case decodeReplay input of-              Left message -> fail message-              Right replay -> pure (encodeJson replay)-          "encode" ->-            case decodeJson input of-              Left message -> fail message-              Right replay -> pure (encodeReplay replay)-          _ -> fail ("unknown action: " ++ show action)-      putOutput output-    _ -> fail ("unknown arguments: " ++ show args)+mainWithArgs args = case args of+  ["version"] -> putStrLn (Version.showVersion version)+  action:files -> do+    (getInput, putOutput) <- getIO files+    input <- getInput+    output <- case action of+      "decode" -> case decodeReplay input of+        Left message -> fail message+        Right replay -> pure (encodeJson replay)+      "encode" -> case decodeJson input of+        Left message -> fail message+        Right replay -> pure (encodeReplay replay)+      _ -> fail ("unknown action: " ++ show action)+    putOutput output+  _ -> fail ("unknown arguments: " ++ show args) -getIO ::-     [FilePath]-  -> IO (IO ByteString.ByteString, ByteString.ByteString -> IO ())-getIO files =-  case files of-    [] -> pure (ByteString.getContents, ByteString.putStr)-    [i] -> pure (readUrlOrFile i, ByteString.putStr)-    [i, o] -> pure (readUrlOrFile i, ByteString.writeFile o)-    _ -> fail ("unknown files: " ++ show files)+getIO+  :: [FilePath] -> IO (IO ByteString.ByteString, ByteString.ByteString -> IO ())+getIO files = case files of+  [] -> pure (ByteString.getContents, ByteString.putStr)+  [i] -> pure (readUrlOrFile i, ByteString.putStr)+  [i, o] -> pure (readUrlOrFile i, ByteString.writeFile o)+  _ -> fail ("unknown files: " ++ show files)  readUrlOrFile :: FilePath -> IO ByteString.ByteString readUrlOrFile i = case Client.parseUrlThrow i of
library/Rattletrap/Primitive/CompressedWord.hs view
@@ -19,29 +19,24 @@   let limit = compressedWordLimit compressedWord   let value = compressedWordValue compressedWord   let maxBits = getMaxBits limit-  let go position soFar =-        if position < maxBits-          then do-            let x = Bits.shiftL 1 position-            if maxBits > 1 && position == maxBits - 1 && soFar + x > limit-              then pure ()-              else do-                let bit = Bits.testBit value position-                BinaryBit.putBool bit-                let delta =-                      if bit-                        then x-                        else 0-                go (position + 1) (soFar + delta)-          else pure ()+  let+    go position soFar = if position < maxBits+      then do+        let x = Bits.shiftL 1 position+        if maxBits > 1 && position == maxBits - 1 && soFar + x > limit+          then pure ()+          else do+            let bit = Bits.testBit value position+            BinaryBit.putBool bit+            let delta = if bit then x else 0+            go (position + 1) (soFar + delta)+      else pure ()   go 0 0  getMaxBits :: (Integral a, Integral b) => a -> b getMaxBits x = do   let n = max 1 (ceiling (logBase (2 :: Double) (fromIntegral (max 1 x))))-  if x < 1024 && x == 2 ^ n-    then n + 1-    else n+  if x < 1024 && x == 2 ^ n then n + 1 else n  getCompressedWordStep :: Word -> Word -> Word -> Word -> BinaryBit.BitGet Word getCompressedWordStep limit maxBits position value = do@@ -49,9 +44,6 @@   if position < maxBits && value + x <= limit     then do       bit <- BinaryBit.getBool-      let newValue =-            if bit-              then value + x-              else value+      let newValue = if bit then value + x else value       getCompressedWordStep limit maxBits (position + 1) newValue     else pure value
library/Rattletrap/Primitive/Dictionary.hs view
@@ -50,10 +50,11 @@ putDictionary putValue dictionary = do   let elements = dictionaryValue dictionary   mapM_-    (\key -> do-       putText key-       case Map.lookup (textValue key) elements of-         Nothing -> fail ("could not find key " ++ textToString key)-         Just value -> putValue value)+    ( \key -> do+      putText key+      case Map.lookup (textValue key) elements of+        Nothing -> fail ("could not find key " ++ textToString key)+        Just value -> putValue value+    )     (dictionaryKeys dictionary)   putText (dictionaryLastKey dictionary)
library/Rattletrap/Primitive/Int8Vector.hs view
@@ -34,9 +34,8 @@     else pure Nothing  putInt8VectorField :: Maybe Int8 -> BinaryBit.BitPut ()-putInt8VectorField maybeField =-  case maybeField of-    Nothing -> BinaryBit.putBool False-    Just field -> do-      BinaryBit.putBool True-      putInt8Bits field+putInt8VectorField maybeField = case maybeField of+  Nothing -> BinaryBit.putBool False+  Just field -> do+    BinaryBit.putBool True+    putInt8Bits field
library/Rattletrap/Primitive/Section.hs view
@@ -50,6 +50,5 @@   Binary.putLazyByteString rawBody  crcMessage :: Word32 -> Word32 -> String-crcMessage actual expected =-  unwords-    ["actual CRC", show actual, "does not match expected CRC", show expected]+crcMessage actual expected = unwords+  ["actual CRC", show actual, "does not match expected CRC", show expected]
library/Rattletrap/Primitive/Text.hs view
@@ -58,49 +58,37 @@  getTextSize :: Text -> Int32 getTextSize text =-  let value = textValue text-      scale =-        if Text.all Char.isLatin1 value-          then 1-          else -1-      rawSize =-        if Text.null value-          then 0-          else fromIntegral (Text.length value) + 1-      size =-        if value == Text.pack "\x00\x00\x00None"-          then 0x05000000-          else scale * rawSize-  in Int32 size+  let+    value = textValue text+    scale = if Text.all Char.isLatin1 value then 1 else -1+    rawSize =+      if Text.null value then 0 else fromIntegral (Text.length value) + 1+    size = if value == Text.pack "\x00\x00\x00None"+      then 0x05000000+      else scale * rawSize+  in+    Int32 size  normalizeTextSize :: Integral a => Int32 -> a-normalizeTextSize size =-  case int32Value size of-    0x05000000 -> 8-    x ->-      if x < 0-        then (-2 * fromIntegral x)-        else fromIntegral x+normalizeTextSize size = case int32Value size of+  0x05000000 -> 8+  x -> if x < 0 then (-2 * fromIntegral x) else fromIntegral x  getTextDecoder :: Int32 -> ByteString.ByteString -> Text.Text getTextDecoder size bytes =-  let decode =-        if size < Int32 0-          then Encoding.decodeUtf16LE-          else Encoding.decodeLatin1-  in decode (ByteString.toStrict bytes)+  let+    decode =+      if size < Int32 0 then Encoding.decodeUtf16LE else Encoding.decodeLatin1+  in+    decode (ByteString.toStrict bytes)  getTextEncoder :: Int32 -> Text.Text -> ByteString.ByteString-getTextEncoder size text =-  if size < Int32 0-    then ByteString.fromStrict (Encoding.encodeUtf16LE text)-    else encodeLatin1 text+getTextEncoder size text = if size < Int32 0+  then ByteString.fromStrict (Encoding.encodeUtf16LE text)+  else encodeLatin1 text  dropNull :: Text.Text -> Text.Text dropNull = Text.dropWhileEnd (== '\x00')  addNull :: Text.Text -> Text.Text-addNull text =-  if Text.null text-    then text-    else Text.snoc text '\x00'+addNull text = if Text.null text then text else Text.snoc text '\x00'
library/Rattletrap/Primitive/Vector.hs view
@@ -28,8 +28,9 @@  putVector :: Vector -> BinaryBit.BitPut () putVector vector = do-  let bitSize =-        round (logBase (2 :: Float) (fromIntegral (vectorBias vector))) - 1+  let+    bitSize =+      round (logBase (2 :: Float) (fromIntegral (vectorBias vector))) - 1   putCompressedWord (CompressedWord 19 bitSize)   let dx = fromIntegral (vectorX vector + fromIntegral (vectorBias vector))   let dy = fromIntegral (vectorY vector + fromIntegral (vectorBias vector))
library/Rattletrap/PropertyValue.hs view
@@ -21,52 +21,49 @@   deriving (Eq, Ord, Show)  getPropertyValue :: Binary.Get a -> Text -> Binary.Get (PropertyValue a)-getPropertyValue getProperty kind =-  case textToString kind of-    "ArrayProperty" -> do-      list <- getList (getDictionary getProperty)-      pure (ArrayProperty list)-    "BoolProperty" -> do-      word8 <- getWord8-      pure (BoolProperty word8)-    "ByteProperty" -> do-      k <- getText-      v <--        if textToString k == "OnlinePlatform_Steam"-          then pure Nothing-          else do-            v <- getText-            pure (Just v)-      pure (ByteProperty k v)-    "FloatProperty" -> do-      float32 <- getFloat32-      pure (FloatProperty float32)-    "IntProperty" -> do-      int32 <- getInt32-      pure (IntProperty int32)-    "NameProperty" -> do-      text <- getText-      pure (NameProperty text)-    "QWordProperty" -> do-      word64 <- getWord64-      pure (QWordProperty word64)-    "StrProperty" -> do-      text <- getText-      pure (StrProperty text)-    _ -> fail ("don't know how to read property value " ++ show kind)+getPropertyValue getProperty kind = case textToString kind of+  "ArrayProperty" -> do+    list <- getList (getDictionary getProperty)+    pure (ArrayProperty list)+  "BoolProperty" -> do+    word8 <- getWord8+    pure (BoolProperty word8)+  "ByteProperty" -> do+    k <- getText+    v <- if textToString k == "OnlinePlatform_Steam"+      then pure Nothing+      else do+        v <- getText+        pure (Just v)+    pure (ByteProperty k v)+  "FloatProperty" -> do+    float32 <- getFloat32+    pure (FloatProperty float32)+  "IntProperty" -> do+    int32 <- getInt32+    pure (IntProperty int32)+  "NameProperty" -> do+    text <- getText+    pure (NameProperty text)+  "QWordProperty" -> do+    word64 <- getWord64+    pure (QWordProperty word64)+  "StrProperty" -> do+    text <- getText+    pure (StrProperty text)+  _ -> fail ("don't know how to read property value " ++ show kind)  putPropertyValue :: (a -> Binary.Put) -> PropertyValue a -> Binary.Put-putPropertyValue putProperty value =-  case value of-    ArrayProperty list -> putList (putDictionary putProperty) list-    BoolProperty word8 -> putWord8 word8-    ByteProperty k mv -> do-      putText k-      case mv of-        Nothing -> pure ()-        Just v -> putText v-    FloatProperty float32 -> putFloat32 float32-    IntProperty int32 -> putInt32 int32-    NameProperty text -> putText text-    QWordProperty word64 -> putWord64 word64-    StrProperty text -> putText text+putPropertyValue putProperty value = case value of+  ArrayProperty list -> putList (putDictionary putProperty) list+  BoolProperty word8 -> putWord8 word8+  ByteProperty k mv -> do+    putText k+    case mv of+      Nothing -> pure ()+      Just v -> putText v+  FloatProperty float32 -> putFloat32 float32+  IntProperty int32 -> putInt32 int32+  NameProperty text -> putText text+  QWordProperty word64 -> putWord64 word64+  StrProperty text -> putText text
library/Rattletrap/RemoteId.hs view
@@ -18,38 +18,36 @@   | XboxId Word64   deriving (Eq, Ord, Show) -getRemoteId :: Word8 -> BinaryBit.BitGet RemoteId-getRemoteId systemId =-  case word8Value systemId of-    0 -> do-      word24 <- BinaryBit.getWord32be 24-      pure (SplitscreenId word24)-    1 -> do-      word64 <- getWord64Bits-      pure (SteamId word64)-    2 -> do-      rawName <- BinaryBit.getLazyByteString 16-      let name =-            Text.dropWhileEnd-              (== '\x00')-              (Encoding.decodeLatin1-                 (ByteString.toStrict (reverseBytes rawName)))-      bytes <- BinaryBit.getLazyByteString 16-      pure (PlayStationId name (ByteString.unpack bytes))-    4 -> do-      word64 <- getWord64Bits-      pure (XboxId word64)-    _ -> fail ("unknown system id " ++ show systemId)+getRemoteId :: (Int, Int, Int) -> Word8 -> BinaryBit.BitGet RemoteId+getRemoteId (_, _, patchVersion) systemId = case word8Value systemId of+  0 -> do+    word24 <- BinaryBit.getWord32be 24+    pure (SplitscreenId word24)+  1 -> do+    word64 <- getWord64Bits+    pure (SteamId word64)+  2 -> do+    rawName <- BinaryBit.getLazyByteString 16+    let+      name = Text.dropWhileEnd+        (== '\x00')+        (Encoding.decodeLatin1 (ByteString.toStrict (reverseBytes rawName)))+      numBytes = if patchVersion >= 1 then 24 else 16+    bytes <- BinaryBit.getLazyByteString numBytes+    pure (PlayStationId name (ByteString.unpack bytes))+  4 -> do+    word64 <- getWord64Bits+    pure (XboxId word64)+  _ -> fail ("unknown system id " ++ show systemId)  putRemoteId :: RemoteId -> BinaryBit.BitPut ()-putRemoteId remoteId =-  case remoteId of-    PlayStationId name bytes -> do-      let rawName =-            ByteString.toStrict-              (reverseBytes (padBytes (16 :: Int) (encodeLatin1 name)))-      BinaryBit.putByteString rawName-      BinaryBit.putByteString (ByteString.toStrict (ByteString.pack bytes))-    SplitscreenId word24 -> BinaryBit.putWord32be 24 word24-    SteamId word64 -> putWord64Bits word64-    XboxId word64 -> putWord64Bits word64+putRemoteId remoteId = case remoteId of+  PlayStationId name bytes -> do+    let+      rawName = ByteString.toStrict+        (reverseBytes (padBytes (16 :: Int) (encodeLatin1 name)))+    BinaryBit.putByteString rawName+    BinaryBit.putByteString (ByteString.toStrict (ByteString.pack bytes))+  SplitscreenId word24 -> BinaryBit.putWord32be 24 word24+  SteamId word64 -> putWord64Bits word64+  XboxId word64 -> putWord64Bits word64
library/Rattletrap/Replication.hs view
@@ -13,20 +13,26 @@   , replicationValue :: ReplicationValue   } deriving (Eq, Ord, Show) -getReplications ::-     (Int, Int)+getReplications+  :: (Int, Int, Int)   -> Word   -> ClassAttributeMap   -> ActorMap   -> BinaryBit.BitGet ([Replication], ActorMap) getReplications version maxChannels classAttributeMap actorMap = do-  maybeReplication <--    getReplication version maxChannels classAttributeMap actorMap+  maybeReplication <- getReplication+    version+    maxChannels+    classAttributeMap+    actorMap   case maybeReplication of     Nothing -> pure ([], actorMap)     Just (replication, newActorMap) -> do-      (replications, newerActorMap) <--        getReplications version maxChannels classAttributeMap newActorMap+      (replications, newerActorMap) <- getReplications+        version+        maxChannels+        classAttributeMap+        newActorMap       pure (replication : replications, newerActorMap)  putReplications :: [Replication] -> BinaryBit.BitPut ()@@ -34,8 +40,8 @@   mapM_ putReplication replications   BinaryBit.putBool False -getReplication ::-     (Int, Int)+getReplication+  :: (Int, Int, Int)   -> Word   -> ClassAttributeMap   -> ActorMap@@ -46,8 +52,11 @@     then pure Nothing     else do       actorId <- getCompressedWord maxChannels-      (value, newActorMap) <--        getReplicationValue version classAttributeMap actorMap actorId+      (value, newActorMap) <- getReplicationValue+        version+        classAttributeMap+        actorMap+        actorId       pure (Just (Replication actorId value, newActorMap))  putReplication :: Replication -> BinaryBit.BitPut ()
library/Rattletrap/Replication/Spawned.hs view
@@ -26,20 +26,19 @@   , spawnedReplicationInitialization :: Initialization   } deriving (Eq, Ord, Show) -getSpawnedReplication ::-     (Int, Int)+getSpawnedReplication+  :: (Int, Int, Int)   -> ClassAttributeMap   -> ActorMap   -> CompressedWord   -> BinaryBit.BitGet (SpawnedReplication, ActorMap) getSpawnedReplication version classAttributeMap actorMap actorId = do   flag <- BinaryBit.getBool-  nameIndex <--    if version < (868, 14)-      then pure Nothing-      else do-        nameIndex <- getWord32Bits-        pure (Just nameIndex)+  nameIndex <- if version < (868, 14, 0)+    then pure Nothing+    else do+      nameIndex <- getWord32Bits+      pure (Just nameIndex)   name <- lookupName classAttributeMap nameIndex   objectId <- getWord32Bits   let newActorMap = Map.insert actorId objectId actorMap@@ -50,14 +49,15 @@   initialization <- getInitialization hasLocation hasRotation   pure     ( SpawnedReplication-        flag-        nameIndex-        name-        objectId-        objectName-        className-        initialization-    , newActorMap)+      flag+      nameIndex+      name+      objectId+      objectName+      className+      initialization+    , newActorMap+    )  putSpawnedReplication :: SpawnedReplication -> BinaryBit.BitPut () putSpawnedReplication spawnedReplication = do@@ -69,13 +69,12 @@   putInitialization (spawnedReplicationInitialization spawnedReplication)  lookupName :: Monad m => ClassAttributeMap -> Maybe Word32 -> m (Maybe Text)-lookupName classAttributeMap maybeNameIndex =-  case maybeNameIndex of-    Nothing -> pure Nothing-    Just nameIndex ->-      case getName (classAttributeMapNameMap classAttributeMap) nameIndex of-        Nothing -> fail ("could not get name for index " ++ show nameIndex)-        Just name -> pure (Just name)+lookupName classAttributeMap maybeNameIndex = case maybeNameIndex of+  Nothing -> pure Nothing+  Just nameIndex ->+    case getName (classAttributeMapNameMap classAttributeMap) nameIndex of+      Nothing -> fail ("could not get name for index " ++ show nameIndex)+      Just name -> pure (Just name)  lookupObjectName :: Monad m => ClassAttributeMap -> Word32 -> m Text lookupObjectName classAttributeMap objectId =@@ -84,7 +83,6 @@     Just objectName -> pure objectName  lookupClassName :: Monad m => Text -> m Text-lookupClassName objectName =-  case getClassName objectName of-    Nothing -> fail ("could not get class name for object " ++ show objectName)-    Just className -> pure className+lookupClassName objectName = case getClassName objectName of+  Nothing -> fail ("could not get class name for object " ++ show objectName)+  Just className -> pure className
library/Rattletrap/Replication/Updated.hs view
@@ -12,8 +12,8 @@   { updatedReplicationAttributes :: [Attribute]   } deriving (Eq, Ord, Show) -getUpdatedReplication ::-     (Int, Int)+getUpdatedReplication+  :: (Int, Int, Int)   -> ClassAttributeMap   -> ActorMap   -> CompressedWord
library/Rattletrap/ReplicationValue.hs view
@@ -24,8 +24,8 @@   -- ^ Destroys an existing actor.   deriving (Eq, Ord, Show) -getReplicationValue ::-     (Int, Int)+getReplicationValue+  :: (Int, Int, Int)   -> ClassAttributeMap   -> ActorMap   -> CompressedWord@@ -37,8 +37,11 @@       isNew <- BinaryBit.getBool       if isNew         then do-          (x, newActorMap) <--            getSpawnedReplication version classAttributeMap actorMap actorId+          (x, newActorMap) <- getSpawnedReplication+            version+            classAttributeMap+            actorMap+            actorId           pure (SpawnedReplicationValue x, newActorMap)         else do           x <- getUpdatedReplication version classAttributeMap actorMap actorId@@ -48,16 +51,15 @@       pure (DestroyedReplicationValue x, actorMap)  putReplicationValue :: ReplicationValue -> BinaryBit.BitPut ()-putReplicationValue value =-  case value of-    SpawnedReplicationValue x -> do-      BinaryBit.putBool True-      BinaryBit.putBool True-      putSpawnedReplication x-    UpdatedReplicationValue x -> do-      BinaryBit.putBool True-      BinaryBit.putBool False-      putUpdatedReplication x-    DestroyedReplicationValue x -> do-      BinaryBit.putBool False-      putDestroyedReplication x+putReplicationValue value = case value of+  SpawnedReplicationValue x -> do+    BinaryBit.putBool True+    BinaryBit.putBool True+    putSpawnedReplication x+  UpdatedReplicationValue x -> do+    BinaryBit.putBool True+    BinaryBit.putBool False+    putUpdatedReplication x+  DestroyedReplicationValue x -> do+    BinaryBit.putBool False+    putDestroyedReplication x
library/Rattletrap/Utility.hs view
@@ -10,22 +10,21 @@ encodeLatin1 text = ByteString8.pack (Text.unpack text)  padBytes :: Integral a => a -> ByteString.ByteString -> ByteString.ByteString-padBytes size bytes =-  ByteString.concat-    [ bytes-    , ByteString.replicate (fromIntegral size - ByteString.length bytes) 0x00-    ]+padBytes size bytes = ByteString.concat+  [ bytes+  , ByteString.replicate (fromIntegral size - ByteString.length bytes) 0x00+  ]  reverseByte :: Word.Word8 -> Word.Word8 reverseByte byte =-  Bits.shiftR (byte Bits..&. Bits.bit 7) 7 +-  Bits.shiftR (byte Bits..&. Bits.bit 6) 5 +-  Bits.shiftR (byte Bits..&. Bits.bit 5) 3 +-  Bits.shiftR (byte Bits..&. Bits.bit 4) 1 +-  Bits.shiftL (byte Bits..&. Bits.bit 3) 1 +-  Bits.shiftL (byte Bits..&. Bits.bit 2) 3 +-  Bits.shiftL (byte Bits..&. Bits.bit 1) 5 +-  Bits.shiftL (byte Bits..&. Bits.bit 0) 7+  Bits.shiftR (byte Bits..&. Bits.bit 7) 7+    + Bits.shiftR (byte Bits..&. Bits.bit 6) 5+    + Bits.shiftR (byte Bits..&. Bits.bit 5) 3+    + Bits.shiftR (byte Bits..&. Bits.bit 4) 1+    + Bits.shiftL (byte Bits..&. Bits.bit 3) 1+    + Bits.shiftL (byte Bits..&. Bits.bit 2) 3+    + Bits.shiftL (byte Bits..&. Bits.bit 1) 5+    + Bits.shiftL (byte Bits..&. Bits.bit 0) 7  reverseBytes :: ByteString.ByteString -> ByteString.ByteString reverseBytes = ByteString.map reverseByte
package.yaml view
@@ -1,5 +1,5 @@ name: rattletrap-version: 3.1.0+version: 3.1.1  category: Game description: Rattletrap parses and generates Rocket League replays.@@ -16,19 +16,19 @@ synopsis: Parse and generate Rocket League replays.  dependencies:-  - aeson >= 1.0.2 && < 1.3-  - base >= 4.9.1 && < 4.11-  - bimap >= 0.3.2 && < 0.4-  - binary >= 0.8.3 && < 0.9+  - aeson >= 1.2.3 && < 1.3+  - base >= 4.10.1 && < 4.11+  - bimap >= 0.3.3 && < 0.4+  - binary >= 0.8.5 && < 0.9   - binary-bits >= 0.5 && < 0.6   - bytestring >= 0.10.8 && < 0.11-  - containers >= 0.5.7 && < 0.6+  - containers >= 0.5.10 && < 0.6   - data-binary-ieee754 >= 0.4.4 && < 0.5   - http-client >= 0.5.7 && < 0.6   - http-client-tls >= 0.3.5 && < 0.4-  - template-haskell >= 2.11.0 && < 2.13+  - template-haskell >= 2.12.0 && < 2.13   - text >= 1.2.2 && < 1.3-  - vector >= 0.11.0 && < 0.13+  - vector >= 0.12.0 && < 0.13 ghc-options: -Wall  library:@@ -52,9 +52,9 @@   test:     dependencies:       - filepath >= 1.4.1 && < 1.5-      - hspec >= 2.4.1 && < 2.5+      - hspec >= 2.4.4 && < 2.5       - rattletrap-      - temporary >= 1.2.0 && < 1.3+      - temporary >= 1.2.1 && < 1.3     ghc-options:       - -rtsopts       - -threaded
rattletrap.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.17.1. -- -- see: https://github.com/sol/hpack  name:           rattletrap-version:        3.1.0+version:        3.1.1 synopsis:       Parse and generate Rocket League replays. description:    Rattletrap parses and generates Rocket League replays. category:       Game@@ -37,6 +37,7 @@     replays/22BACD794ABE7B92E50E9CBDBD9C59CE.replay     replays/27B6A7B64553F0F685874584F96BAB1B.replay     replays/29F582C34A65EB34D358A784CBE3C189.replay+    replays/2CFE577044E651D3FA9DBF83ECA8BCC3.replay     replays/338173964F9F71EBDD31058A1936CBB4.replay     replays/372DBFCA4BDB340E4357B6BD43032802.replay     replays/387F059C47C09E253C875CA990EFD9F2.replay@@ -91,19 +92,19 @@   default-extensions: Strict   ghc-options: -Wall   build-depends:-      aeson >= 1.0.2 && < 1.3-    , base >= 4.9.1 && < 4.11-    , bimap >= 0.3.2 && < 0.4-    , binary >= 0.8.3 && < 0.9+      aeson >= 1.2.3 && < 1.3+    , base >= 4.10.1 && < 4.11+    , bimap >= 0.3.3 && < 0.4+    , binary >= 0.8.5 && < 0.9     , binary-bits >= 0.5 && < 0.6     , bytestring >= 0.10.8 && < 0.11-    , containers >= 0.5.7 && < 0.6+    , containers >= 0.5.10 && < 0.6     , data-binary-ieee754 >= 0.4.4 && < 0.5     , http-client >= 0.5.7 && < 0.6     , http-client-tls >= 0.3.5 && < 0.4-    , template-haskell >= 2.11.0 && < 2.13+    , template-haskell >= 2.12.0 && < 2.13     , text >= 1.2.2 && < 1.3-    , vector >= 0.11.0 && < 0.13+    , vector >= 0.12.0 && < 0.13   exposed-modules:       Rattletrap       Rattletrap.ActorMap@@ -131,7 +132,7 @@       Rattletrap.Attribute.PartyLeader       Rattletrap.Attribute.Pickup       Rattletrap.Attribute.PrivateMatchSettings-      Rattletrap.Attribute.ProductAttribute+      Rattletrap.Attribute.Product       Rattletrap.Attribute.QWord       Rattletrap.Attribute.Reservation       Rattletrap.Attribute.RigidBodyState@@ -193,19 +194,19 @@       executables   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N   build-depends:-      aeson >= 1.0.2 && < 1.3-    , base >= 4.9.1 && < 4.11-    , bimap >= 0.3.2 && < 0.4-    , binary >= 0.8.3 && < 0.9+      aeson >= 1.2.3 && < 1.3+    , base >= 4.10.1 && < 4.11+    , bimap >= 0.3.3 && < 0.4+    , binary >= 0.8.5 && < 0.9     , binary-bits >= 0.5 && < 0.6     , bytestring >= 0.10.8 && < 0.11-    , containers >= 0.5.7 && < 0.6+    , containers >= 0.5.10 && < 0.6     , data-binary-ieee754 >= 0.4.4 && < 0.5     , http-client >= 0.5.7 && < 0.6     , http-client-tls >= 0.3.5 && < 0.4-    , template-haskell >= 2.11.0 && < 2.13+    , template-haskell >= 2.12.0 && < 2.13     , text >= 1.2.2 && < 1.3-    , vector >= 0.11.0 && < 0.13+    , vector >= 0.12.0 && < 0.13     , rattletrap   default-language: Haskell2010 @@ -216,21 +217,21 @@       tests   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N   build-depends:-      aeson >= 1.0.2 && < 1.3-    , base >= 4.9.1 && < 4.11-    , bimap >= 0.3.2 && < 0.4-    , binary >= 0.8.3 && < 0.9+      aeson >= 1.2.3 && < 1.3+    , base >= 4.10.1 && < 4.11+    , bimap >= 0.3.3 && < 0.4+    , binary >= 0.8.5 && < 0.9     , binary-bits >= 0.5 && < 0.6     , bytestring >= 0.10.8 && < 0.11-    , containers >= 0.5.7 && < 0.6+    , containers >= 0.5.10 && < 0.6     , data-binary-ieee754 >= 0.4.4 && < 0.5     , http-client >= 0.5.7 && < 0.6     , http-client-tls >= 0.3.5 && < 0.4-    , template-haskell >= 2.11.0 && < 2.13+    , template-haskell >= 2.12.0 && < 2.13     , text >= 1.2.2 && < 1.3-    , vector >= 0.11.0 && < 0.13+    , vector >= 0.12.0 && < 0.13     , filepath >= 1.4.1 && < 1.5-    , hspec >= 2.4.1 && < 2.5+    , hspec >= 2.4.4 && < 2.5     , rattletrap-    , temporary >= 1.2.0 && < 1.3+    , temporary >= 1.2.1 && < 1.3   default-language: Haskell2010
+ replays/2CFE577044E651D3FA9DBF83ECA8BCC3.replay view

binary file changed (absent → 1060102 bytes)

stack.yaml view
@@ -1,117 +1,5 @@-resolver: ghc-8.2.1+resolver: nightly-2017-11-25  packages:   - .   - tools--extra-deps:-  - aeson-1.2.1.0-  - ansi-terminal-0.6.3.1-  - async-2.1.1.1-  - attoparsec-0.13.1.0-  - base-compat-0.9.3-  - bimap-0.3.3-  - binary-bits-0.5-  - call-stack-0.1.0-  - data-binary-ieee754-0.4.4-  - dlist-0.8.0.3-  - exceptions-0.8.3-  - hashable-1.2.6.1-  - hspec-2.4.4-  - hspec-core-2.4.4-  - hspec-discover-2.4.4-  - hspec-expectations-0.8.2-  - HUnit-1.6.0.0-  - integer-logarithms-1.0.2-  - mtl-2.2.1-  - old-locale-1.0.0.7-  - primitive-0.6.2.0-  - QuickCheck-2.10.0.1-  - quickcheck-io-0.2.0-  - random-1.1-  - scientific-0.3.5.1-  - setenv-0.1.1.3-  - stm-2.4.4.1-  - tagged-0.8.5-  - temporary-1.2.1-  - text-1.2.2.2-  - tf-random-0.5-  - time-locale-compat-0.1.1.3-  - transformers-compat-0.5.1.4-  - unordered-containers-0.2.8.0-  - uuid-types-1.0.3-  - vector-0.12.0.1--  # tools-  - adjunctions-4.3-  - ansi-wl-pprint-0.6.7.3-  - asn1-encoding-0.9.5-  - asn1-parse-0.9.4-  - asn1-types-0.3.2-  - base-orphans-0.6-  - base64-bytestring-1.0.0.1-  - bifunctors-5.4.2-  - blaze-builder-0.4.0.2-  - blaze-html-0.9.0.1-  - blaze-markup-0.8.0.0-  - byteable-0.1.1-  - cabal-doctest-1.0.2-  - case-insensitive-1.2.0.10-  - cereal-0.5.4.0-  - charset-0.3.7.1-  - comonad-5.0.1-  - connection-0.2.8-  - contravariant-1.4-  - cookie-0.4.2.1-  - cryptonite-0.24-  - data-default-class-0.1.2.0-  - distributive-0.5.2-  - fail-4.9.0.0-  - fingertree-0.1.1.0-  - foundation-0.0.13-  - free-4.12.4-  - github-release-1.0.4-  - hourglass-0.2.10-  - HTTP-4000.3.7-  - http-client-0.5.7.0-  - http-client-tls-0.3.5.1-  - http-types-0.9.1-  - kan-extensions-5.0.2-  - lens-4.15.3-  - memory-0.14.6-  - mime-types-0.1.0.7-  - network-2.6.3.2-  - network-uri-2.6.1.0-  - Only-0.1-  - optparse-applicative-0.14.0.0-  - optparse-generic-1.2.2-  - parallel-3.2.1.1-  - parsec-3.1.11-  - parsers-0.12.5-  - pem-0.2.2-  - prelude-extras-0.4.0.3-  - profunctors-5.2-  - reducers-3.12.1-  - reflection-2.1.2-  - safe-0.3.15-  - semigroupoids-5.2-  - semigroups-0.18.3-  - socks-0.5.5-  - StateVar-1.1.0.4-  - streaming-commons-0.1.18-  - system-filepath-0.4.13.4-  - th-abstraction-0.2.3.0-  - tls-1.3.11-  - trifecta-1.7-  - uri-templater-0.2.1.0-  - utf8-string-1.0.1.1-  - void-0.7.2-  - x509-1.7.1-  - x509-store-1.6.3-  - x509-system-1.6.5-  - x509-validation-1.6.8-  - zlib-0.6.1.2--flags:-  time-locale-compat:-    old-locale: false
tests/Main.hs view
@@ -24,15 +24,16 @@   input <- ByteString.readFile inputFile   Temp.withSystemTempDirectory     "replay-"-    (\directory -> do-       let jsonFile = FilePath.combine directory "replay.json"-       Rattletrap.mainWithArgs ["decode", inputFile, jsonFile]-       let outputFile = FilePath.combine directory "output.replay"-       Rattletrap.mainWithArgs ["encode", jsonFile, outputFile]-       output <- ByteString.readFile outputFile-       Monad.unless-         (output == input)-         (Hspec.expectationFailure "output does not match input"))+    ( \directory -> do+      let jsonFile = FilePath.combine directory "replay.json"+      Rattletrap.mainWithArgs ["decode", inputFile, jsonFile]+      let outputFile = FilePath.combine directory "output.replay"+      Rattletrap.mainWithArgs ["encode", jsonFile, outputFile]+      output <- ByteString.readFile outputFile+      Monad.unless+        (output == input)+        (Hspec.expectationFailure "output does not match input")+    )  pathToReplay :: String -> FilePath pathToReplay uuid =@@ -58,6 +59,7 @@   , ("22BACD794ABE7B92E50E9CBDBD9C59CE", "a vote to forfeit")   , ("27B6A7B64553F0F685874584F96BAB1B", "some UTF-16 text")   , ("29F582C34A65EB34D358A784CBE3C189", "frames")+  , ("2CFE577044E651D3FA9DBF83ECA8BCC3", "a new playstation id")   , ("338173964F9F71EBDD31058A1936CBB4", "patch 1.37")   , ("372DBFCA4BDB340E4357B6BD43032802", "a camera yaw attribute")   , ("387F059C47C09E253C875CA990EFD9F2", "a frozen attribute")