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 +1/−1
- README.markdown +0/−3
- data/replays/22660E3649FC7971E5653692473D4318.replay binary
- data/replays/D0449F5F4AA775B86FFA7DA2B5A3204E.replay binary
- package.yaml +1/−1
- rattletrap.cabal +5/−1
- source/library/Rattletrap/ActorMap.hs +8/−0
- source/library/Rattletrap/Attribute/AppliedDamage.hs +33/−0
- source/library/Rattletrap/Attribute/DamageState.hs +41/−0
- source/library/Rattletrap/AttributeType.hs +3/−1
- source/library/Rattletrap/AttributeValue.hs +15/−1
- source/library/Rattletrap/ClassAttributeMap.hs +5/−2
- source/library/Rattletrap/Content.hs +2/−2
- source/library/Rattletrap/Data.hs +66/−54
- source/library/Rattletrap/Helper.hs +32/−0
- source/library/Rattletrap/Json.hs +3/−1
- source/library/Rattletrap/Main.hs +15/−18
- source/library/Rattletrap/Primitive/Text.hs +1/−1
- source/library/Rattletrap/Replication/Spawned.hs +2/−1
- source/tests/Main.hs +2/−0
- stack.yaml +1/−2
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