packages feed

rattletrap 2.1.5 → 2.2.0

raw patch · 21 files changed

+236/−89 lines, 21 filesbinary-addedPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Rattletrap.Attribute.AppliedDamage: AppliedDamageAttribute :: Word8 -> Vector -> Int32 -> Int32 -> AppliedDamageAttribute
+ Rattletrap.Attribute.AppliedDamage: [appliedDamageAttributeLocation] :: AppliedDamageAttribute -> Vector
+ Rattletrap.Attribute.AppliedDamage: [appliedDamageAttributeUnknown1] :: AppliedDamageAttribute -> Word8
+ Rattletrap.Attribute.AppliedDamage: [appliedDamageAttributeUnknown3] :: AppliedDamageAttribute -> Int32
+ Rattletrap.Attribute.AppliedDamage: [appliedDamageAttributeUnknown4] :: AppliedDamageAttribute -> Int32
+ Rattletrap.Attribute.AppliedDamage: data AppliedDamageAttribute
+ Rattletrap.Attribute.AppliedDamage: getAppliedDamageAttribute :: BitGet AppliedDamageAttribute
+ Rattletrap.Attribute.AppliedDamage: instance GHC.Classes.Eq Rattletrap.Attribute.AppliedDamage.AppliedDamageAttribute
+ Rattletrap.Attribute.AppliedDamage: instance GHC.Classes.Ord Rattletrap.Attribute.AppliedDamage.AppliedDamageAttribute
+ Rattletrap.Attribute.AppliedDamage: instance GHC.Show.Show Rattletrap.Attribute.AppliedDamage.AppliedDamageAttribute
+ Rattletrap.Attribute.AppliedDamage: putAppliedDamageAttribute :: AppliedDamageAttribute -> BitPut ()
+ Rattletrap.Attribute.DamageState: DamageStateAttribute :: Word8 -> Bool -> Int32 -> Vector -> Bool -> Bool -> DamageStateAttribute
+ Rattletrap.Attribute.DamageState: [damageStateAttributeUnknown1] :: DamageStateAttribute -> Word8
+ Rattletrap.Attribute.DamageState: [damageStateAttributeUnknown2] :: DamageStateAttribute -> Bool
+ Rattletrap.Attribute.DamageState: [damageStateAttributeUnknown3] :: DamageStateAttribute -> Int32
+ Rattletrap.Attribute.DamageState: [damageStateAttributeUnknown4] :: DamageStateAttribute -> Vector
+ Rattletrap.Attribute.DamageState: [damageStateAttributeUnknown5] :: DamageStateAttribute -> Bool
+ Rattletrap.Attribute.DamageState: [damageStateAttributeUnknown6] :: DamageStateAttribute -> Bool
+ Rattletrap.Attribute.DamageState: data DamageStateAttribute
+ Rattletrap.Attribute.DamageState: getDamageStateAttribute :: BitGet DamageStateAttribute
+ Rattletrap.Attribute.DamageState: instance GHC.Classes.Eq Rattletrap.Attribute.DamageState.DamageStateAttribute
+ Rattletrap.Attribute.DamageState: instance GHC.Classes.Ord Rattletrap.Attribute.DamageState.DamageStateAttribute
+ Rattletrap.Attribute.DamageState: instance GHC.Show.Show Rattletrap.Attribute.DamageState.DamageStateAttribute
+ Rattletrap.Attribute.DamageState: putDamageStateAttribute :: DamageStateAttribute -> BitPut ()
+ Rattletrap.AttributeType: AppliedDamageAttributeType :: AttributeType
+ Rattletrap.AttributeType: DamageStateAttributeType :: AttributeType
+ Rattletrap.AttributeValue: AppliedDamageAttributeValue :: AppliedDamageAttribute -> AttributeValue
+ Rattletrap.AttributeValue: DamageStateAttributeValue :: DamageStateAttribute -> AttributeValue
+ Rattletrap.ClassAttributeMap: instance GHC.Classes.Ord Rattletrap.ClassAttributeMap.ClassAttributeMap
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Attribute.AppliedDamage.AppliedDamageAttribute
+ Rattletrap.Json: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Attribute.DamageState.DamageStateAttribute
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Attribute.AppliedDamage.AppliedDamageAttribute
+ Rattletrap.Json: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Attribute.DamageState.DamageStateAttribute

Files

LICENSE.markdown view
@@ -1,6 +1,6 @@ # [The MIT License (MIT)][] -Copyright (c) 2016 Taylor Fausak <taylor@fausak.me>+Copyright (c) Taylor Fausak  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
README.markdown view
@@ -3,7 +3,6 @@ [![Version badge][]][version] [![Windows build badge][]][windows build] [![Build badge][]][build]-[![Code Climate badge][]][code climate]  Rattletrap parses and generates [Rocket League][] replays. @@ -73,8 +72,6 @@ [Windows build badge]: https://ci.appveyor.com/api/projects/status/github/tfausak/rattletrap?branch=master&svg=true [windows build]: https://ci.appveyor.com/project/TaylorFausak/rattletrap [Build badge]: https://travis-ci.org/tfausak/rattletrap.svg?branch=master-[Code Climate badge]: https://codeclimate.com/github/tfausak/rattletrap/badges/gpa.svg-[code climate]: https://codeclimate.com/github/tfausak/rattletrap [build]: https://travis-ci.org/tfausak/rattletrap [Rocket League]: https://www.rocketleaguegame.com [Octane]: https://github.com/tfausak/octane
+ data/replays/22660E3649FC7971E5653692473D4318.replay view

binary file changed (absent → 1259407 bytes)

+ data/replays/D0449F5F4AA775B86FFA7DA2B5A3204E.replay view

binary file changed (absent → 640433 bytes)

package.yaml view
@@ -58,4 +58,4 @@     - -with-rtsopts=-N     main: Main.hs     source-dirs: source/tests-version: '2.1.5'+version: '2.2.0'
rattletrap.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           rattletrap-version:        2.1.5+version:        2.2.0 synopsis:       Parse and generate Rocket League replays. description:    Rattletrap parses and generates Rocket League replays. category:       Game@@ -30,6 +30,7 @@     data/replays/1EF90FCC4F719F606A5327B3CDD782A4.replay     data/replays/1F3798E540B0C37A946561ABBB3037F9.replay     data/replays/211466D04B983F5A33CC2FA1D5928672.replay+    data/replays/22660E3649FC7971E5653692473D4318.replay     data/replays/22BACD794ABE7B92E50E9CBDBD9C59CE.replay     data/replays/27B6A7B64553F0F685874584F96BAB1B.replay     data/replays/29F582C34A65EB34D358A784CBE3C189.replay@@ -59,6 +60,7 @@     data/replays/C14F7E0E4D9B5E6BE9AD5D8ED56B174C.replay     data/replays/C8372B1345B1803DEF039F815DBD802D.replay     data/replays/CC4CA70D4F7A67EBAD0ED9B9923106F7.replay+    data/replays/D0449F5F4AA775B86FFA7DA2B5A3204E.replay     data/replays/D428F81646A98C25902CE988AE5C14C8.replay     data/replays/D7FB197A451D69075A0C99A2F49A4053.replay     data/replays/DCB3A6B94A9DBE46FDE5EAA9B012F6C8.replay@@ -98,10 +100,12 @@       Rattletrap       Rattletrap.ActorMap       Rattletrap.Attribute+      Rattletrap.Attribute.AppliedDamage       Rattletrap.Attribute.Boolean       Rattletrap.Attribute.Byte       Rattletrap.Attribute.CamSettings       Rattletrap.Attribute.ClubColors+      Rattletrap.Attribute.DamageState       Rattletrap.Attribute.Demolish       Rattletrap.Attribute.Enum       Rattletrap.Attribute.Explosion
source/library/Rattletrap/ActorMap.hs view
@@ -6,8 +6,16 @@  type ActorMap = Map.Map CompressedWord Word32 +{-# DEPRECATED+makeActorMap "use Data.Map.Strict.empty"+ #-}+ makeActorMap :: ActorMap makeActorMap = Map.empty++{-# DEPRECATED+updateActorMap "use Data.Map.Strict.insert"+ #-}  updateActorMap :: CompressedWord -> Word32 -> ActorMap -> ActorMap updateActorMap = Map.insert
+ source/library/Rattletrap/Attribute/AppliedDamage.hs view
@@ -0,0 +1,33 @@+module Rattletrap.Attribute.AppliedDamage where++import Rattletrap.Primitive++import qualified Data.Binary.Bits.Get as BinaryBit+import qualified Data.Binary.Bits.Put as BinaryBit++data AppliedDamageAttribute = AppliedDamageAttribute+  { appliedDamageAttributeUnknown1 :: Word8+  , appliedDamageAttributeLocation :: Vector+  , appliedDamageAttributeUnknown3 :: Int32+  , appliedDamageAttributeUnknown4 :: Int32+  } deriving (Eq, Ord, Show)++getAppliedDamageAttribute :: BinaryBit.BitGet AppliedDamageAttribute+getAppliedDamageAttribute = do+  unknown1 <- getWord8Bits+  location <- getVector+  unknown3 <- getInt32Bits+  unknown4 <- getInt32Bits+  pure+    (AppliedDamageAttribute+       unknown1+       location+       unknown3+       unknown4)++putAppliedDamageAttribute :: AppliedDamageAttribute -> BinaryBit.BitPut ()+putAppliedDamageAttribute appliedDamageAttribute = do+  putWord8Bits (appliedDamageAttributeUnknown1 appliedDamageAttribute)+  putVector (appliedDamageAttributeLocation appliedDamageAttribute)+  putInt32Bits (appliedDamageAttributeUnknown3 appliedDamageAttribute)+  putInt32Bits (appliedDamageAttributeUnknown4 appliedDamageAttribute)
+ source/library/Rattletrap/Attribute/DamageState.hs view
@@ -0,0 +1,41 @@+module Rattletrap.Attribute.DamageState where++import Rattletrap.Primitive++import qualified Data.Binary.Bits.Get as BinaryBit+import qualified Data.Binary.Bits.Put as BinaryBit++data DamageStateAttribute = DamageStateAttribute+  { damageStateAttributeUnknown1 :: Word8+  , damageStateAttributeUnknown2 :: Bool+  , damageStateAttributeUnknown3 :: Int32+  , damageStateAttributeUnknown4 :: Vector+  , damageStateAttributeUnknown5 :: Bool+  , damageStateAttributeUnknown6 :: Bool+  } deriving (Eq, Ord, Show)++getDamageStateAttribute :: BinaryBit.BitGet DamageStateAttribute+getDamageStateAttribute = do+  unknown1 <- getWord8Bits+  unknown2 <- BinaryBit.getBool+  unknown3 <- getInt32Bits+  unknown4 <- getVector+  unknown5 <- BinaryBit.getBool+  unknown6 <- BinaryBit.getBool+  pure+    (DamageStateAttribute+       unknown1+       unknown2+       unknown3+       unknown4+       unknown5+       unknown6)++putDamageStateAttribute :: DamageStateAttribute -> BinaryBit.BitPut ()+putDamageStateAttribute damageStateAttribute = do+  putWord8Bits (damageStateAttributeUnknown1 damageStateAttribute)+  BinaryBit.putBool (damageStateAttributeUnknown2 damageStateAttribute)+  putInt32Bits (damageStateAttributeUnknown3 damageStateAttribute)+  putVector (damageStateAttributeUnknown4 damageStateAttribute)+  BinaryBit.putBool (damageStateAttributeUnknown5 damageStateAttribute)+  BinaryBit.putBool (damageStateAttributeUnknown6 damageStateAttribute)
source/library/Rattletrap/AttributeType.hs view
@@ -1,10 +1,12 @@ module Rattletrap.AttributeType where  data AttributeType-  = BooleanAttributeType+  = AppliedDamageAttributeType+  | BooleanAttributeType   | ByteAttributeType   | CamSettingsAttributeType   | ClubColorsAttributeType+  | DamageStateAttributeType   | DemolishAttributeType   | EnumAttributeType   | ExplosionAttributeType
source/library/Rattletrap/AttributeValue.hs view
@@ -1,9 +1,11 @@ module Rattletrap.AttributeValue   ( module Rattletrap.AttributeValue+  , module Rattletrap.Attribute.AppliedDamage   , module Rattletrap.Attribute.Boolean   , module Rattletrap.Attribute.Byte   , module Rattletrap.Attribute.CamSettings   , module Rattletrap.Attribute.ClubColors+  , module Rattletrap.Attribute.DamageState   , module Rattletrap.Attribute.Demolish   , module Rattletrap.Attribute.Enum   , module Rattletrap.Attribute.Explosion@@ -29,10 +31,12 @@   , module Rattletrap.Attribute.WeldedInfo   ) where +import Rattletrap.Attribute.AppliedDamage import Rattletrap.Attribute.Boolean import Rattletrap.Attribute.Byte import Rattletrap.Attribute.CamSettings import Rattletrap.Attribute.ClubColors+import Rattletrap.Attribute.DamageState import Rattletrap.Attribute.Demolish import Rattletrap.Attribute.Enum import Rattletrap.Attribute.Explosion@@ -65,10 +69,12 @@ import qualified Data.Map.Strict as Map  data AttributeValue-  = BooleanAttributeValue BooleanAttribute+  = AppliedDamageAttributeValue AppliedDamageAttribute+  | BooleanAttributeValue BooleanAttribute   | ByteAttributeValue ByteAttribute   | CamSettingsAttributeValue CamSettingsAttribute   | ClubColorsAttributeValue ClubColorsAttribute+  | DamageStateAttributeValue DamageStateAttribute   | DemolishAttributeValue DemolishAttribute   | EnumAttributeValue EnumAttribute   | ExplosionAttributeValue ExplosionAttribute@@ -99,6 +105,9 @@   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)@@ -111,6 +120,9 @@         ClubColorsAttributeType -> do           x <- getClubColorsAttribute           pure (ClubColorsAttributeValue x)+        DamageStateAttributeType -> do+          x <- getDamageStateAttribute+          pure (DamageStateAttributeValue x)         DemolishAttributeType -> do           x <- getDemolishAttribute           pure (DemolishAttributeValue x)@@ -188,10 +200,12 @@ 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
source/library/Rattletrap/ClassAttributeMap.hs view
@@ -29,7 +29,7 @@   -- ^ A map from class IDs to a map from attribute stream IDs to attribute   -- IDs.   , classAttributeMapNameMap :: IntMap.IntMap Text-  } deriving (Eq, Show)+  } deriving (Eq, Ord, Show)  -- | Makes a 'ClassAttributeMap' given the necessary fields from the -- 'Rattletrap.Content.Content'.@@ -235,6 +235,7 @@       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@@ -243,7 +244,9 @@                      then Text boostPickup                      else if Text.isInfixOf mapScoreboard name                             then Text mapScoreboard-                            else objectName+                            else if Text.isInfixOf breakout name+                              then Text breakout+                              else objectName  objectClasses :: Map.Map Text Text objectClasses =
source/library/Rattletrap/Content.hs view
@@ -1,6 +1,5 @@ module Rattletrap.Content where -import Rattletrap.ActorMap import Rattletrap.Cache import Rattletrap.ClassAttributeMap import Rattletrap.ClassMapping@@ -16,6 +15,7 @@ import qualified Data.Binary.Bits.Put as BinaryBit import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary+import qualified Data.Map as Map  -- | Contains low-level game data about a 'Rattletrap.Replay.Replay'. data Content = Content@@ -85,7 +85,7 @@                      numFrames                      maxChannels                      classAttributeMap-                     makeActorMap+                     Map.empty                  pure theFrames))           (reverseBytes stream)   pure
source/library/Rattletrap/Data.hs view
@@ -12,27 +12,27 @@   , ("Engine.ReplicationInfo", "Engine.Info")   , ("Engine.TeamInfo", "Engine.ReplicationInfo")   , ("ProjectX.GRI_X", "Engine.GameReplicationInfo")-  , ("ProjectX.PRI_X", "Engine.PlayerReplicationInfo")   , ("ProjectX.Pawn_X", "Engine.Pawn")+  , ("ProjectX.PRI_X", "Engine.PlayerReplicationInfo")   , ("TAGame.Ball_TA", "TAGame.RBActor_TA")   , ("TAGame.CameraSettingsActor_TA", "Engine.ReplicationInfo")+  , ("TAGame.Car_Season_TA", "TAGame.PRI_TA")+  , ("TAGame.Car_TA", "TAGame.Vehicle_TA")   , ("TAGame.CarComponent_Boost_TA", "TAGame.CarComponent_TA")   , ("TAGame.CarComponent_Dodge_TA", "TAGame.CarComponent_TA")   , ("TAGame.CarComponent_DoubleJump_TA", "TAGame.CarComponent_TA")   , ("TAGame.CarComponent_FlipCar_TA", "TAGame.CarComponent_TA")   , ("TAGame.CarComponent_Jump_TA", "TAGame.CarComponent_TA")   , ("TAGame.CarComponent_TA", "Engine.ReplicationInfo")-  , ("TAGame.Car_Season_TA", "TAGame.PRI_TA")-  , ("TAGame.Car_TA", "TAGame.Vehicle_TA")   , ("TAGame.CrowdActor_TA", "Engine.ReplicationInfo")   , ("TAGame.CrowdManager_TA", "Engine.ReplicationInfo")-  , ("TAGame.GRI_TA", "ProjectX.GRI_X")   , ("TAGame.GameEvent_Season_TA", "TAGame.GameEvent_Soccar_TA")+  , ("TAGame.GameEvent_Soccar_TA", "TAGame.GameEvent_Team_TA")   , ("TAGame.GameEvent_SoccarPrivate_TA", "TAGame.GameEvent_Soccar_TA")   , ("TAGame.GameEvent_SoccarSplitscreen_TA", "TAGame.GameEvent_SoccarPrivate_TA")-  , ("TAGame.GameEvent_Soccar_TA", "TAGame.GameEvent_Team_TA")   , ("TAGame.GameEvent_TA", "Engine.ReplicationInfo")   , ("TAGame.GameEvent_Team_TA", "TAGame.GameEvent_TA")+  , ("TAGame.GRI_TA", "ProjectX.GRI_X")   , ("TAGame.InMapScoreboard_TA", "Engine.Actor")   , ("TAGame.PRI_TA", "ProjectX.PRI_X")   , ("TAGame.RBActor_TA", "ProjectX.Pawn_X")@@ -52,27 +52,28 @@   , ("TAGame.SpecialPickup_Tornado_TA", "TAGame.SpecialPickup_TA")   , ("TAGame.Team_Soccar_TA", "TAGame.Team_TA")   , ("TAGame.Team_TA", "Engine.TeamInfo")+  , ("TAGame.Vehicle_TA", "TAGame.RBActor_TA")   , ("TAGame.VehiclePickup_Boost_TA", "TAGame.VehiclePickup_TA")   , ("TAGame.VehiclePickup_TA", "Engine.ReplicationInfo")-  , ("TAGame.Vehicle_TA", "TAGame.RBActor_TA")   ]  rawClassesWithLocation :: [String] rawClassesWithLocation =-  [ "TAGame.Ball_TA"+  [ "TAGame.Ball_Breakout_TA"+  , "TAGame.Ball_TA"   , "TAGame.CameraSettingsActor_TA"+  , "TAGame.Car_Season_TA"+  , "TAGame.Car_TA"   , "TAGame.CarComponent_Boost_TA"   , "TAGame.CarComponent_Dodge_TA"   , "TAGame.CarComponent_DoubleJump_TA"   , "TAGame.CarComponent_FlipCar_TA"   , "TAGame.CarComponent_Jump_TA"-  , "TAGame.Car_Season_TA"-  , "TAGame.Car_TA"-  , "TAGame.GRI_TA"   , "TAGame.GameEvent_Season_TA"+  , "TAGame.GameEvent_Soccar_TA"   , "TAGame.GameEvent_SoccarPrivate_TA"   , "TAGame.GameEvent_SoccarSplitscreen_TA"-  , "TAGame.GameEvent_Soccar_TA"+  , "TAGame.GRI_TA"   , "TAGame.PRI_TA"   , "TAGame.SpecialPickup_BallCarSpring_TA"   , "TAGame.SpecialPickup_BallFreeze_TA"@@ -91,14 +92,17 @@  rawClassesWithRotation :: [String] rawClassesWithRotation =-  [ "TAGame.Ball_TA"+  [ "TAGame.Ball_Breakout_TA"+  , "TAGame.Ball_TA"   , "TAGame.Car_Season_TA"   , "TAGame.Car_TA"   ]  rawObjectClasses :: [(String, String)] rawObjectClasses =-  [ ("Archetypes.Ball.Ball_Basketball", "TAGame.Ball_TA")+  [ ("Archetypes.Ball.Ball_BasketBall_Mutator", "TAGame.Ball_TA")+  , ("Archetypes.Ball.Ball_Basketball", "TAGame.Ball_TA")+  , ("Archetypes.Ball.Ball_Breakout", "TAGame.Ball_Breakout_TA")   , ("Archetypes.Ball.Ball_Default", "TAGame.Ball_TA")   , ("Archetypes.Ball.Ball_Puck", "TAGame.Ball_TA")   , ("Archetypes.Ball.CubeBall", "TAGame.Ball_TA")@@ -111,12 +115,13 @@   , ("Archetypes.GameEvent.GameEvent_Basketball", "TAGame.GameEvent_Soccar_TA")   , ("Archetypes.GameEvent.GameEvent_BasketballPrivate", "TAGame.GameEvent_SoccarPrivate_TA")   , ("Archetypes.GameEvent.GameEvent_BasketballSplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")+  , ("Archetypes.GameEvent.GameEvent_Breakout", "TAGame.GameEvent_Soccar_TA")   , ("Archetypes.GameEvent.GameEvent_Hockey", "TAGame.GameEvent_Soccar_TA")   , ("Archetypes.GameEvent.GameEvent_HockeyPrivate", "TAGame.GameEvent_SoccarPrivate_TA")   , ("Archetypes.GameEvent.GameEvent_HockeySplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")   , ("Archetypes.GameEvent.GameEvent_Items", "TAGame.GameEvent_Soccar_TA")-  , ("Archetypes.GameEvent.GameEvent_Season", "TAGame.GameEvent_Season_TA")   , ("Archetypes.GameEvent.GameEvent_Season:CarArchetype", "TAGame.Car_TA")+  , ("Archetypes.GameEvent.GameEvent_Season", "TAGame.GameEvent_Season_TA")   , ("Archetypes.GameEvent.GameEvent_Soccar", "TAGame.GameEvent_Soccar_TA")   , ("Archetypes.GameEvent.GameEvent_SoccarPrivate", "TAGame.GameEvent_SoccarPrivate_TA")   , ("Archetypes.GameEvent.GameEvent_SoccarSplitscreen", "TAGame.GameEvent_SoccarSplitscreen_TA")@@ -135,12 +140,14 @@   , ("Archetypes.Teams.Team0", "TAGame.Team_Soccar_TA")   , ("Archetypes.Teams.Team1", "TAGame.Team_Soccar_TA")   , ("GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype", "TAGame.GRI_TA")+  , ("GameInfo_Breakout.GameInfo.GameInfo_Breakout:GameReplicationInfoArchetype", "TAGame.GRI_TA")+  , ("Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype", "TAGame.GRI_TA")   , ("GameInfo_Items.GameInfo.GameInfo_Items:GameReplicationInfoArchetype", "TAGame.GRI_TA")   , ("GameInfo_Season.GameInfo.GameInfo_Season:GameReplicationInfoArchetype", "TAGame.GRI_TA")   , ("GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype", "TAGame.GRI_TA")-  , ("Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype", "TAGame.GRI_TA")   , ("TAGame.Default__CameraSettingsActor_TA", "TAGame.CameraSettingsActor_TA")   , ("TAGame.Default__PRI_TA", "TAGame.PRI_TA")+  , ("TheWorld:PersistentLevel.BreakOutActor_Platform_TA", "TAGame.BreakOutActor_Platform_TA")   , ("TheWorld:PersistentLevel.CrowdActor_TA", "TAGame.CrowdActor_TA")   , ("TheWorld:PersistentLevel.CrowdManager_TA", "TAGame.CrowdManager_TA")   , ("TheWorld:PersistentLevel.InMapScoreboard_TA", "TAGame.InMapScoreboard_TA")@@ -149,15 +156,19 @@  rawAttributeTypes :: [(String, AttributeType)] rawAttributeTypes =-  [ ("Engine.Actor:DrawScale", FloatAttributeType)-  , ("Engine.Actor:Role", EnumAttributeType)-  , ("Engine.Actor:bBlockActors", BooleanAttributeType)+  [ ("Engine.Actor:bBlockActors", BooleanAttributeType)   , ("Engine.Actor:bCollideActors", BooleanAttributeType)   , ("Engine.Actor:bHidden", BooleanAttributeType)+  , ("Engine.Actor:DrawScale", FloatAttributeType)+  , ("Engine.Actor:Role", EnumAttributeType)+  , ("Engine.GameReplicationInfo:bMatchIsOver", BooleanAttributeType)   , ("Engine.GameReplicationInfo:GameClass", FlaggedIntAttributeType)   , ("Engine.GameReplicationInfo:ServerName", StringAttributeType)-  , ("Engine.GameReplicationInfo:bMatchIsOver", BooleanAttributeType)   , ("Engine.Pawn:PlayerReplicationInfo", FlaggedIntAttributeType)+  , ("Engine.PlayerReplicationInfo:bBot", BooleanAttributeType)+  , ("Engine.PlayerReplicationInfo:bIsSpectator", BooleanAttributeType)+  , ("Engine.PlayerReplicationInfo:bReadyToPlay", BooleanAttributeType)+  , ("Engine.PlayerReplicationInfo:bWaitingPlayer", BooleanAttributeType)   , ("Engine.PlayerReplicationInfo:Ping", ByteAttributeType)   , ("Engine.PlayerReplicationInfo:PlayerID", IntAttributeType)   , ("Engine.PlayerReplicationInfo:PlayerName", StringAttributeType)@@ -165,16 +176,15 @@   , ("Engine.PlayerReplicationInfo:Score", IntAttributeType)   , ("Engine.PlayerReplicationInfo:Team", FlaggedIntAttributeType)   , ("Engine.PlayerReplicationInfo:UniqueId", UniqueIdAttributeType)-  , ("Engine.PlayerReplicationInfo:bBot", BooleanAttributeType)-  , ("Engine.PlayerReplicationInfo:bIsSpectator", BooleanAttributeType)-  , ("Engine.PlayerReplicationInfo:bReadyToPlay", BooleanAttributeType)-  , ("Engine.PlayerReplicationInfo:bWaitingPlayer", BooleanAttributeType)   , ("Engine.TeamInfo:Score", IntAttributeType)+  , ("ProjectX.GRI_X:bGameStarted", BooleanAttributeType)   , ("ProjectX.GRI_X:GameServerID", QWordAttributeType)   , ("ProjectX.GRI_X:ReplicatedGameMutatorIndex", IntAttributeType)   , ("ProjectX.GRI_X:ReplicatedGamePlaylist", IntAttributeType)   , ("ProjectX.GRI_X:Reservations", ReservationAttributeType)-  , ("ProjectX.GRI_X:bGameStarted", BooleanAttributeType)+  , ("TAGame.Ball_Breakout_TA:AppliedDamage", AppliedDamageAttributeType)+  , ("TAGame.Ball_Breakout_TA:DamageIndex", IntAttributeType)+  , ("TAGame.Ball_Breakout_TA:LastTeamTouch", ByteAttributeType)   , ("TAGame.Ball_TA:GameEvent", FlaggedIntAttributeType)   , ("TAGame.Ball_TA:HitTeamNum", ByteAttributeType)   , ("TAGame.Ball_TA:ReplicatedAddedCarBounceScale", FloatAttributeType)@@ -182,31 +192,32 @@   , ("TAGame.Ball_TA:ReplicatedBallScale", FloatAttributeType)   , ("TAGame.Ball_TA:ReplicatedExplosionData", ExplosionAttributeType)   , ("TAGame.Ball_TA:ReplicatedWorldBounceScale", FloatAttributeType)+  , ("TAGame.BreakOutActor_Platform_TA:DamageState", DamageStateAttributeType)+  , ("TAGame.CameraSettingsActor_TA:bUsingBehindView", BooleanAttributeType)+  , ("TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera", BooleanAttributeType)   , ("TAGame.CameraSettingsActor_TA:CameraPitch", ByteAttributeType)   , ("TAGame.CameraSettingsActor_TA:CameraYaw", ByteAttributeType)   , ("TAGame.CameraSettingsActor_TA:PRI", FlaggedIntAttributeType)   , ("TAGame.CameraSettingsActor_TA:ProfileSettings", CamSettingsAttributeType)-  , ("TAGame.CameraSettingsActor_TA:bUsingBehindView", BooleanAttributeType)-  , ("TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera", BooleanAttributeType)+  , ("TAGame.Car_TA:AddedBallForceMultiplier", FloatAttributeType)+  , ("TAGame.Car_TA:AddedCarForceMultiplier", FloatAttributeType)+  , ("TAGame.Car_TA:AttachedPickup", FlaggedIntAttributeType)+  , ("TAGame.Car_TA:ClubColors", ClubColorsAttributeType)+  , ("TAGame.Car_TA:ReplicatedDemolish", DemolishAttributeType)+  , ("TAGame.Car_TA:TeamPaint", TeamPaintAttributeType)+  , ("TAGame.CarComponent_Boost_TA:bNoBoost", BooleanAttributeType)   , ("TAGame.CarComponent_Boost_TA:BoostModifier", FloatAttributeType)+  , ("TAGame.CarComponent_Boost_TA:bUnlimitedBoost", BooleanAttributeType)   , ("TAGame.CarComponent_Boost_TA:RechargeDelay", FloatAttributeType)   , ("TAGame.CarComponent_Boost_TA:RechargeRate", FloatAttributeType)   , ("TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount", ByteAttributeType)   , ("TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount", IntAttributeType)-  , ("TAGame.CarComponent_Boost_TA:bNoBoost", BooleanAttributeType)-  , ("TAGame.CarComponent_Boost_TA:bUnlimitedBoost", BooleanAttributeType)   , ("TAGame.CarComponent_Dodge_TA:DodgeTorque", LocationAttributeType)-  , ("TAGame.CarComponent_FlipCar_TA:FlipCarTime", FloatAttributeType)   , ("TAGame.CarComponent_FlipCar_TA:bFlipRight", BooleanAttributeType)+  , ("TAGame.CarComponent_FlipCar_TA:FlipCarTime", FloatAttributeType)   , ("TAGame.CarComponent_TA:ReplicatedActive", ByteAttributeType)   , ("TAGame.CarComponent_TA:ReplicatedActivityTime", FloatAttributeType)   , ("TAGame.CarComponent_TA:Vehicle", FlaggedIntAttributeType)-  , ("TAGame.Car_TA:AddedBallForceMultiplier", FloatAttributeType)-  , ("TAGame.Car_TA:AddedCarForceMultiplier", FloatAttributeType)-  , ("TAGame.Car_TA:AttachedPickup", FlaggedIntAttributeType)-  , ("TAGame.Car_TA:ClubColors", ClubColorsAttributeType)-  , ("TAGame.Car_TA:ReplicatedDemolish", DemolishAttributeType)-  , ("TAGame.Car_TA:TeamPaint", TeamPaintAttributeType)   , ("TAGame.CrowdActor_TA:GameEvent", FlaggedIntAttributeType)   , ("TAGame.CrowdActor_TA:ModifiedNoise", FloatAttributeType)   , ("TAGame.CrowdActor_TA:ReplicatedCountDownNumber", IntAttributeType)@@ -214,26 +225,33 @@   , ("TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber", IntAttributeType)   , ("TAGame.CrowdManager_TA:GameEvent", FlaggedIntAttributeType)   , ("TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound", FlaggedIntAttributeType)-  , ("TAGame.GRI_TA:NewDedicatedServerIP", StringAttributeType)-  , ("TAGame.GameEvent_SoccarPrivate_TA:MatchSettings", PrivateMatchSettingsAttributeType)+  , ("TAGame.GameEvent_Soccar_TA:bBallHasBeenHit", BooleanAttributeType)+  , ("TAGame.GameEvent_Soccar_TA:bOverTime", BooleanAttributeType)   , ("TAGame.GameEvent_Soccar_TA:GameTime", IntAttributeType)   , ("TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger", MusicStingerAttributeType)   , ("TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam", ByteAttributeType)   , ("TAGame.GameEvent_Soccar_TA:RoundNum", IntAttributeType)   , ("TAGame.GameEvent_Soccar_TA:SecondsRemaining", IntAttributeType)   , ("TAGame.GameEvent_Soccar_TA:SubRulesArchetype", FlaggedIntAttributeType)-  , ("TAGame.GameEvent_Soccar_TA:bBallHasBeenHit", BooleanAttributeType)-  , ("TAGame.GameEvent_Soccar_TA:bOverTime", BooleanAttributeType)+  , ("TAGame.GameEvent_SoccarPrivate_TA:MatchSettings", PrivateMatchSettingsAttributeType)+  , ("TAGame.GameEvent_TA:bCanVoteToForfeit", BooleanAttributeType)+  , ("TAGame.GameEvent_TA:bHasLeaveMatchPenalty", BooleanAttributeType)   , ("TAGame.GameEvent_TA:BotSkill", IntAttributeType)   , ("TAGame.GameEvent_TA:GameMode", GameModeAttributeType)   , ("TAGame.GameEvent_TA:MatchTypeClass", FlaggedIntAttributeType)   , ("TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining", IntAttributeType)   , ("TAGame.GameEvent_TA:ReplicatedStateIndex", ByteAttributeType)   , ("TAGame.GameEvent_TA:ReplicatedStateName", IntAttributeType)-  , ("TAGame.GameEvent_TA:bCanVoteToForfeit", BooleanAttributeType)-  , ("TAGame.GameEvent_TA:bHasLeaveMatchPenalty", BooleanAttributeType)   , ("TAGame.GameEvent_Team_TA:bForfeit", BooleanAttributeType)   , ("TAGame.GameEvent_Team_TA:MaxTeamSize", IntAttributeType)+  , ("TAGame.GRI_TA:NewDedicatedServerIP", StringAttributeType)+  , ("TAGame.PRI_TA:bIsInSplitScreen", BooleanAttributeType)+  , ("TAGame.PRI_TA:bMatchMVP", BooleanAttributeType)+  , ("TAGame.PRI_TA:bOnlineLoadoutSet", BooleanAttributeType)+  , ("TAGame.PRI_TA:bOnlineLoadoutsSet", BooleanAttributeType)+  , ("TAGame.PRI_TA:bReady", BooleanAttributeType)+  , ("TAGame.PRI_TA:bUsingBehindView", BooleanAttributeType)+  , ("TAGame.PRI_TA:bUsingSecondaryCamera", BooleanAttributeType)   , ("TAGame.PRI_TA:CameraPitch", ByteAttributeType)   , ("TAGame.PRI_TA:CameraSettings", CamSettingsAttributeType)   , ("TAGame.PRI_TA:CameraYaw", ByteAttributeType)@@ -242,6 +260,7 @@   , ("TAGame.PRI_TA:ClientLoadouts", LoadoutsAttributeType)   , ("TAGame.PRI_TA:ClientLoadoutsOnline", LoadoutsOnlineAttributeType)   , ("TAGame.PRI_TA:MatchAssists", IntAttributeType)+  , ("TAGame.PRI_TA:MatchBreakoutDamage", IntAttributeType)   , ("TAGame.PRI_TA:MatchGoals", IntAttributeType)   , ("TAGame.PRI_TA:MatchSaves", IntAttributeType)   , ("TAGame.PRI_TA:MatchScore", IntAttributeType)@@ -252,34 +271,27 @@   , ("TAGame.PRI_TA:ReplicatedGameEvent", FlaggedIntAttributeType)   , ("TAGame.PRI_TA:Title", IntAttributeType)   , ("TAGame.PRI_TA:TotalXP", IntAttributeType)-  , ("TAGame.PRI_TA:bIsInSplitScreen", BooleanAttributeType)-  , ("TAGame.PRI_TA:bMatchMVP", BooleanAttributeType)-  , ("TAGame.PRI_TA:bOnlineLoadoutSet", BooleanAttributeType)-  , ("TAGame.PRI_TA:bOnlineLoadoutsSet", BooleanAttributeType)-  , ("TAGame.PRI_TA:bReady", BooleanAttributeType)-  , ("TAGame.PRI_TA:bUsingBehindView", BooleanAttributeType)-  , ("TAGame.PRI_TA:bUsingSecondaryCamera", BooleanAttributeType)-  , ("TAGame.RBActor_TA:ReplicatedRBState", RigidBodyStateAttributeType)-  , ("TAGame.RBActor_TA:WeldedInfo", WeldedInfoAttributeType)   , ("TAGame.RBActor_TA:bFrozen", BooleanAttributeType)   , ("TAGame.RBActor_TA:bIgnoreSyncing", BooleanAttributeType)   , ("TAGame.RBActor_TA:bReplayActor", BooleanAttributeType)+  , ("TAGame.RBActor_TA:ReplicatedRBState", RigidBodyStateAttributeType)+  , ("TAGame.RBActor_TA:WeldedInfo", WeldedInfoAttributeType)   , ("TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed", FloatAttributeType)   , ("TAGame.SpecialPickup_BallVelcro_TA:AttachTime", FloatAttributeType)-  , ("TAGame.SpecialPickup_BallVelcro_TA:BreakTime", FloatAttributeType)   , ("TAGame.SpecialPickup_BallVelcro_TA:bBroken", BooleanAttributeType)   , ("TAGame.SpecialPickup_BallVelcro_TA:bHit", BooleanAttributeType)+  , ("TAGame.SpecialPickup_BallVelcro_TA:BreakTime", FloatAttributeType)   , ("TAGame.SpecialPickup_Targeted_TA:Targeted", FlaggedIntAttributeType)   , ("TAGame.Team_Soccar_TA:GameScore", IntAttributeType)   , ("TAGame.Team_TA:ClubColors", ClubColorsAttributeType)   , ("TAGame.Team_TA:CustomTeamName", StringAttributeType)   , ("TAGame.Team_TA:GameEvent", FlaggedIntAttributeType)   , ("TAGame.Team_TA:LogoData", FlaggedIntAttributeType)-  , ("TAGame.VehiclePickup_TA:ReplicatedPickupData", PickupAttributeType)-  , ("TAGame.Vehicle_TA:ReplicatedSteer", ByteAttributeType)-  , ("TAGame.Vehicle_TA:ReplicatedThrottle", ByteAttributeType)   , ("TAGame.Vehicle_TA:bDriving", BooleanAttributeType)   , ("TAGame.Vehicle_TA:bReplicatedHandbrake", BooleanAttributeType)+  , ("TAGame.Vehicle_TA:ReplicatedSteer", ByteAttributeType)+  , ("TAGame.Vehicle_TA:ReplicatedThrottle", ByteAttributeType)+  , ("TAGame.VehiclePickup_TA:ReplicatedPickupData", PickupAttributeType)   ]  rawCrc32Table :: Integral a => [a]
source/library/Rattletrap/Helper.hs view
@@ -33,40 +33,72 @@  -- * File paths -- | 'decodeReplay'+{-# DEPRECATED+decodeReplayFile "use Data.ByteString.Lazy.readFile"+ #-}+ decodeReplayFile :: FilePath -> IO (Either String Replay) decodeReplayFile file = IO.withBinaryFile file IO.ReadMode decodeReplayHandle  -- | 'encodeJson'+{-# DEPRECATED+encodeJsonFile "use Data.ByteString.Lazy.writeFile"+ #-}+ encodeJsonFile :: Replay -> FilePath -> IO () encodeJsonFile replay file =   IO.withBinaryFile file IO.WriteMode (encodeJsonHandle replay)  -- | 'decodeJson'+{-# DEPRECATED+decodeJsonFile "use Data.ByteString.Lazy.readFile"+ #-}+ decodeJsonFile :: FilePath -> IO (Either String Replay) decodeJsonFile file = IO.withBinaryFile file IO.ReadMode decodeJsonHandle  -- | 'encodeReplay'+{-# DEPRECATED+encodeReplayFile "use Data.ByteString.Lazy.writeFile"+ #-}+ encodeReplayFile :: Replay -> FilePath -> IO () encodeReplayFile replay file =   IO.withBinaryFile file IO.WriteMode (encodeReplayHandle replay)  -- * Handles -- | 'decodeReplay'+{-# DEPRECATED+decodeReplayHandle "use Data.ByteString.Lazy.hGetContents"+ #-}+ decodeReplayHandle :: IO.Handle -> IO (Either String Replay) decodeReplayHandle handle = do   contents <- ByteString.hGetContents handle   pure (decodeReplay contents)  -- | 'encodeJson'+{-# DEPRECATED+encodeJsonHandle "use Data.ByteString.Lazy.hPut"+ #-}+ encodeJsonHandle :: Replay -> IO.Handle -> IO () encodeJsonHandle replay handle = ByteString.hPut handle (encodeJson replay)  -- | 'decodeJson'+{-# DEPRECATED+decodeJsonHandle "use Data.ByteString.Lazy.hGetContents"+ #-}+ decodeJsonHandle :: IO.Handle -> IO (Either String Replay) decodeJsonHandle handle = do   contents <- ByteString.hGetContents handle   pure (decodeJson contents)  -- | 'encodeReplay'+{-# DEPRECATED+encodeReplayHandle "use Data.ByteString.Lazy.hPut"+ #-}+ encodeReplayHandle :: Replay -> IO.Handle -> IO () encodeReplayHandle replay handle = ByteString.hPut handle (encodeReplay replay)
source/library/Rattletrap/Json.hs view
@@ -39,7 +39,8 @@         newDeclarations <- Aeson.deriveJSON (optionsFor name) name         pure (newDeclarations ++ declarations)       names =-        [ ''Attribute+        [ ''AppliedDamageAttribute+        , ''Attribute         , ''AttributeMapping         , ''AttributeValue         , ''BooleanAttribute@@ -51,6 +52,7 @@         , ''CompressedWord         , ''CompressedWordVector         , ''Content+        , ''DamageStateAttribute         , ''DemolishAttribute         , ''DestroyedReplication         , ''Dictionary
source/library/Rattletrap/Main.hs view
@@ -1,12 +1,8 @@ module Rattletrap.Main where -import Rattletrap.Json ()-import Rattletrap.Replay+import Rattletrap.Helper import Rattletrap.Version -import qualified Data.Aeson as Aeson-import qualified Data.Binary.Get as Binary-import qualified Data.Binary.Put as Binary import qualified Data.ByteString.Lazy as ByteString import qualified Data.Version as Version import qualified System.Environment as Environment@@ -32,21 +28,22 @@ mainWithArgs args =   case args of     ["version"] -> putStrLn (Version.showVersion version)-    "decode":files -> do+    action:files -> do       (getInput, putOutput) <- getIO files       input <- getInput-      let replay = Binary.runGet getReplay input-      let output = Aeson.encode replay+      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-    "encode":files -> do-      (getInput, putOutput) <- getIO files-      input <- getInput-      case Aeson.eitherDecode input of-        Left message -> fail ("could not parse JSON: " ++ message)-        Right replay -> do-          let output = Binary.runPut (putReplay replay)-          putOutput output-    _ -> fail ("unexpected arguments " ++ show args)+    _ -> fail ("unknown arguments: " ++ show args)  getIO :: [FilePath]       -> IO (IO ByteString.ByteString, ByteString.ByteString -> IO ())@@ -55,4 +52,4 @@     [] -> pure (ByteString.getContents, ByteString.putStr)     [i] -> pure (ByteString.readFile i, ByteString.putStr)     [i, o] -> pure (ByteString.readFile i, ByteString.writeFile o)-    _ -> fail ("unexpected arguments " ++ show files)+    _ -> fail ("unknown files: " ++ show files)
source/library/Rattletrap/Primitive/Text.hs view
@@ -8,7 +8,7 @@ import qualified Data.Binary.Bits.Put as BinaryBit import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary-import qualified Data.ByteString.Lazy.Char8 as ByteString+import qualified Data.ByteString.Lazy as ByteString import qualified Data.Char as Char import qualified Data.Text as Text import qualified Data.Text.Encoding as Encoding
source/library/Rattletrap/Replication/Spawned.hs view
@@ -7,6 +7,7 @@  import qualified Data.Binary.Bits.Get as BinaryBit import qualified Data.Binary.Bits.Put as BinaryBit+import qualified Data.Map as Map  data SpawnedReplication = SpawnedReplication   { spawnedReplicationFlag :: Bool@@ -41,7 +42,7 @@         pure (Just nameIndex)   name <- lookupName classAttributeMap nameIndex   objectId <- getWord32Bits-  let newActorMap = updateActorMap actorId objectId actorMap+  let newActorMap = Map.insert actorId objectId actorMap   objectName <- lookupObjectName classAttributeMap objectId   className <- lookupClassName objectName   let hasLocation = classHasLocation className
source/tests/Main.hs view
@@ -56,6 +56,7 @@   , ("1EF90FCC4F719F606A5327B3CDD782A4", "a private hoops match")   , ("1F3798E540B0C37A946561ABBB3037F9", "splitscreen players")   , ("211466D04B983F5A33CC2FA1D5928672", "a match save")+  , ("22660E3649FC7971E5653692473D4318", "dropshot")   , ("22BACD794ABE7B92E50E9CBDBD9C59CE", "a vote to forfeit")   , ("27B6A7B64553F0F685874584F96BAB1B", "some UTF-16 text")   , ("29F582C34A65EB34D358A784CBE3C189", "frames")@@ -85,6 +86,7 @@   , ("C14F7E0E4D9B5E6BE9AD5D8ED56B174C", "some mutators")   , ("C8372B1345B1803DEF039F815DBD802D", "a spectator")   , ("CC4CA70D4F7A67EBAD0ED9B9923106F7", "after Starbase ARC")+  , ("D0449F5F4AA775B86FFA7DA2B5A3204E", "hoops mutators")   , ("D428F81646A98C25902CE988AE5C14C8", "a private hockey match")   , ("D7FB197A451D69075A0C99A2F49A4053", "an explosion attribute")   , ("DCB3A6B94A9DBE46FDE5EAA9B012F6C8", "a pawn type attribute")
stack.yaml view
@@ -1,2 +1,1 @@-compiler: ghc-8.0.2-resolver: nightly-2016-12-31+resolver: lts-8.0