packages feed

octane 0.5.0 → 0.5.1

raw patch · 13 files changed

+239/−125 lines, 13 files

Files

library/Octane/Main.hs view
@@ -1,5 +1,6 @@ module Octane.Main (main) where +import qualified Control.DeepSeq as DeepSeq import qualified Control.Monad as Monad import qualified Control.Newtype as Newtype import qualified Data.Aeson.Encode.Pretty as Aeson@@ -32,6 +33,7 @@                 IO.stderr                 (file ++ " @ byte " ++ show offset ++ " - " ++ message)         Right replay -> do+            DeepSeq.deepseq replay (IO.hPutStrLn IO.stderr "evaluated replay")             let inputSize = contents & BS.length & fromIntegral             let outputSize = replay & Binary.encode & BSL.length             Monad.when (inputSize /= outputSize) $@@ -45,9 +47,14 @@                     Aeson.defConfig                     { Aeson.confCompare = compare                     }+            putStrLn "{\"meta\":\n"             replay & Aeson.encodePretty' config & BSL8.putStrLn +            putStrLn ",\"frames\":\n"             let frames = Parser.parseFrames replay+            DeepSeq.deepseq frames (IO.hPutStrLn IO.stderr "evaluated frames")             let expectedFrames = replay & Type.replayProperties & Newtype.unpack & Map.lookup ("NumFrames" & Text.pack & Newtype.pack)             let actualFrames = frames & length & fromIntegral & Newtype.pack & Type.IntProperty (Newtype.pack 4) & Just             Monad.when (expectedFrames /= actualFrames) $ IO.hPutStrLn IO.stderr ("expected " ++ show expectedFrames ++ " frames but found " ++ show actualFrames ++ " frames!")+            frames & Aeson.encodePretty' config & BSL8.putStrLn+            putStrLn "}"
library/Octane/Parser.hs view
@@ -1,24 +1,28 @@ {-# LANGUAGE DeriveGeneric #-} -module Octane.Parser (parseFrames) where+module Octane.Parser where  import Data.Function ((&)) +import qualified Control.DeepSeq as DeepSeq import qualified Control.Newtype as Newtype+import qualified Data.Aeson as Aeson+import qualified Data.Aeson.Types as Aeson import qualified Data.Binary.Bits.Get as Bits import qualified Data.Binary.IEEE754 as IEEE754 import qualified Data.Binary.Get as Binary import qualified Data.Bits as Bits import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BSL-import qualified Data.IntMap as IntMap+import qualified Data.IntMap.Strict as IntMap import qualified Data.List as List-import qualified Data.Map as Map+import qualified Data.Map.Strict as Map import qualified Data.Maybe as Maybe import qualified Data.Set as Set import qualified Data.Text as Text import qualified Data.Text.Encoding as Encoding import qualified Data.Word as Word+import qualified Debug.Trace as Trace import qualified GHC.Generics as Generics import qualified Octane.Type as Type import qualified Text.Regex as Regex@@ -129,6 +133,7 @@           { replicationActorId = actorId           , replicationIsOpen = True           , replicationIsNew = Just True+          , replicationClassInit = Just classInit           , replicationProps = []           }) @@ -144,6 +149,7 @@         { replicationActorId = actorId         , replicationIsOpen = True         , replicationIsNew = Just False+        , replicationClassInit = Nothing         , replicationProps = props         }) @@ -159,6 +165,7 @@           { replicationActorId = actorId           , replicationIsOpen = False           , replicationIsNew = Nothing+          , replicationClassInit = Nothing           , replicationProps = []           }) @@ -184,7 +191,12 @@ getProp context thing = do     let classId = thing & thingClassId     let props = case context & contextClassPropertyMap & IntMap.lookup classId of-            Nothing -> error ("could not find property map for class id " ++ show classId)+            Nothing ->+                Trace.trace (context & contextObjectMap & IntMap.toAscList & map (\ (k, v) -> "\t" ++ show k ++ "\t=> " ++ show v) & ("OBJECTS:" :) & unlines) $+                Trace.trace (context & contextArchetypeMap & Map.toList & map (\ (k, v) -> "\t" ++ show k ++ "\t=> " ++ show v) & ("ARCHETYPES:" :) & unlines) $+                Trace.trace (context & contextClassMap & Map.toList & map (\ (k, v) -> "\t" ++ show k ++ "\t=> " ++ show v) & ("CLASSES:" :) & unlines) $+                Trace.trace (context & contextClassPropertyMap & IntMap.toAscList & map (\ (k1, v1) -> "\t" ++ show k1 ++ "\t=>\n" ++ (v1 & IntMap.toAscList & map (\ (k2, v2) -> "\t\t" ++ show k2 ++ "\t=>" ++ show v2) & unlines)) & ("CLASS PROPERTIES:" :) & unlines) $+                error ("could not find property map for class id " ++ show classId)             Just x -> x     let maxId = props & IntMap.keys & maximum     pid <- getInt maxId@@ -237,6 +249,9 @@     _ | Set.member name propsWithLocation -> do         vector <- getVector         return (PLocation vector)+    _ | Set.member name propsWithFloat -> do+        float <- getFloat32+        return (PFloat float)     "ProjectX.GRI_X:Reservations" -> do         -- I think this is the connection order. The first player to connect         -- gets number 0, and it goes up from there. The maximum is 8, which@@ -300,6 +315,14 @@         cue <- getInt32         trigger <- getInt8         return (PMusicStinger flag cue trigger)+    "TAGame.Car_TA:ReplicatedDemolish" -> do+        hasAtk <- Bits.getBool+        atk <- if hasAtk then fmap Just getInt32 else return Nothing+        hasVic <- Bits.getBool+        vic <- if hasVic then fmap Just getInt32 else return Nothing+        vec1 <- getVector+        vec2 <- getVector+        return (PDemolish hasAtk atk hasVic vic vec1 vec2)     -- TODO: Parse other prop types.     _ -> fail ("don't know how to read property " ++ show name) @@ -351,6 +374,10 @@     , "TAGame.Ball_TA:GameEvent"     , "TAGame.CameraSettingsActor_TA:PRI"     , "TAGame.CarComponent_TA:Vehicle"+    , "TAGame.CrowdActor_TA:GameEvent"+    , "TAGame.CrowdActor_TA:ReplicatedOneShotSound"+    , "TAGame.CrowdManager_TA:GameEvent"+    , "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound"     , "TAGame.PRI_TA:PersistentCamera"     , "TAGame.PRI_TA:ReplicatedGameEvent"     , "TAGame.Team_TA:GameEvent"@@ -364,18 +391,24 @@  propsWithBoolean :: Set.Set Text.Text propsWithBoolean =-    [ "Engine.PlayerReplicationInfo:bReadyToPlay"+    [ "Engine.Actor:bBlockActors"+    , "Engine.Actor:bCollideActors"+    , "Engine.Actor:bHidden"+    , "Engine.PlayerReplicationInfo:bReadyToPlay"     , "ProjectX.GRI_X:bGameStarted"+    , "TAGame.CameraSettingsActor_TA:bUsingBehindView"     , "TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera"+    , "TAGame.CarComponent_FlipCar_TA:bFlipRight"+    , "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit"+    , "TAGame.GameEvent_Soccar_TA:bOverTime"     , "TAGame.GameEvent_TA:bHasLeaveMatchPenalty"     , "TAGame.GameEvent_Team_TA:bDisableMutingOtherTeam"     , "TAGame.PRI_TA:bOnlineLoadoutSet"+    , "TAGame.PRI_TA:bUsingBehindView"+    , "TAGame.PRI_TA:bUsingSecondaryCamera"+    , "TAGame.RBActor_TA:bReplayActor"     , "TAGame.Vehicle_TA:bDriving"-    , "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit"     , "TAGame.Vehicle_TA:bReplicatedHandbrake"-    , "Engine.Actor:bCollideActors"-    , "Engine.Actor:bBlockActors"-    , "TAGame.CameraSettingsActor_TA:bUsingBehindView"     ] & map Text.pack & Set.fromList  propsWithQWord :: Set.Set Text.Text@@ -386,35 +419,39 @@ propsWithInt :: Set.Set Text.Text propsWithInt =     [ "Engine.PlayerReplicationInfo:PlayerID"+    , "Engine.PlayerReplicationInfo:Score"+    , "Engine.TeamInfo:Score"     , "ProjectX.GRI_X:ReplicatedGamePlaylist"+    , "TAGame.CrowdActor_TA:ReplicatedCountDownNumber"+    , "TAGame.GameEvent_Soccar_TA:RoundNum"     , "TAGame.GameEvent_Soccar_TA:SecondsRemaining"     , "TAGame.GameEvent_TA:BotSkill"     , "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining"-    , "TAGame.GameEvent_Soccar_TA:RoundNum"     , "TAGame.GameEvent_TA:ReplicatedStateName"     , "TAGame.GameEvent_Team_TA:MaxTeamSize"-    , "TAGame.PRI_TA:Title"-    , "TAGame.PRI_TA:TotalXP"+    , "TAGame.PRI_TA:MatchAssists"+    , "TAGame.PRI_TA:MatchGoals"+    , "TAGame.PRI_TA:MatchSaves"     , "TAGame.PRI_TA:MatchScore"     , "TAGame.PRI_TA:MatchShots"-    , "TAGame.PRI_TA:MatchSaves"-    , "Engine.TeamInfo:Score"-    , "Engine.PlayerReplicationInfo:Score"-    , "TAGame.PRI_TA:MatchGoals"-    , "TAGame.PRI_TA:MatchAssists"+    , "TAGame.PRI_TA:Title"+    , "TAGame.PRI_TA:TotalXP"     ] & map Text.pack & Set.fromList  propsWithByte :: Set.Set Text.Text propsWithByte =     [ "Engine.PlayerReplicationInfo:Ping"+    , "TAGame.Ball_TA:HitTeamNum"+    , "TAGame.CameraSettingsActor_TA:CameraPitch"+    , "TAGame.CameraSettingsActor_TA:CameraYaw"     , "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount"-    , "TAGame.Vehicle_TA:ReplicatedThrottle"     , "TAGame.CarComponent_TA:ReplicatedActive"-    , "TAGame.Vehicle_TA:ReplicatedSteer"-    , "TAGame.Ball_TA:HitTeamNum"     , "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam"-    , "TAGame.CameraSettingsActor_TA:CameraYaw"-    , "TAGame.CameraSettingsActor_TA:CameraPitch"+    , "TAGame.GameEvent_TA:ReplicatedStateIndex"+    , "TAGame.PRI_TA:CameraPitch"+    , "TAGame.PRI_TA:CameraYaw"+    , "TAGame.Vehicle_TA:ReplicatedSteer"+    , "TAGame.Vehicle_TA:ReplicatedThrottle"     ] & map Text.pack & Set.fromList  propsWithUniqueId :: Set.Set Text.Text@@ -426,6 +463,7 @@ propsWithCamSettings :: Set.Set Text.Text propsWithCamSettings =     [ "TAGame.CameraSettingsActor_TA:ProfileSettings"+    , "TAGame.PRI_TA:CameraSettings"     ] & map Text.pack & Set.fromList  propsWithLocation :: Set.Set Text.Text@@ -433,6 +471,13 @@     [ "TAGame.CarComponent_Dodge_TA:DodgeTorque"     ] & map Text.pack & Set.fromList +propsWithFloat :: Set.Set Text.Text+propsWithFloat =+    [ "Engine.Actor:DrawScale"+    , "TAGame.CarComponent_FlipCar_TA:FlipCarTime"+    , "TAGame.CrowdActor_TA:ModifiedNoise"+    ] & map Text.pack & Set.fromList+ type SystemId = Word.Word8  -- This is the number associated with a splitscreen player. So the first player@@ -442,59 +487,103 @@ type LocalId = Word.Word8  data RemoteId-    = SteamId BS.ByteString -- TODO: This is an integer.-    | PlayStationId BS.ByteString -- TODO: I think this is a string?-    deriving (Eq, Show)+    = SteamId !BS.ByteString -- TODO: This is an integer.+    | PlayStationId !BS.ByteString -- TODO: I think this is a string?+    deriving (Eq, Generics.Generic, Show) +instance DeepSeq.NFData RemoteId++-- TODO: This is a dumb instance. It's only necessary because there's no ToJSON+-- instance for ByteString.+instance Aeson.ToJSON RemoteId where+    toJSON remoteId = case remoteId of+        SteamId bytes -> bytes & show & Aeson.toJSON+        PlayStationId bytes -> bytes & show & Aeson.toJSON+ data Prop = Prop-    { propId :: Int-    , propValue :: PropValue-    } deriving (Eq, Show)+    { propId :: !Int+    , propValue :: !PropValue+    } deriving (Eq, Generics.Generic, Show) +instance DeepSeq.NFData Prop+instance Aeson.ToJSON Prop where+    toJSON =+        Aeson.genericToJSON+            Aeson.defaultOptions+            { Aeson.fieldLabelModifier = drop 4+            }+ data PropValue-    = PRigidBodyState Bool (Vector Int) (Vector Float) (Maybe (Vector Int)) (Maybe (Vector Int))-    | PFlaggedInt Bool Int-    | PString Text.Text-    | PBoolean Bool-    | PQWord Int Int-    | PReservation Int SystemId RemoteId LocalId (Maybe Text.Text) Bool Bool-    | PInt Int-    | PByte Int-    | PUniqueId SystemId RemoteId LocalId-    | PLoadoutOnline Int Int Int (Maybe Int)-    | PLoadout Int Int Int Int Int Int Int Int (Maybe Int)-    | PCamSettings Float Float Float Float Float Float-    | PTeamPaint Int Int Int Int Int-    | PLocation (Vector Int)-    | PPickup Bool (Maybe Int) Bool-    | PEnum Word.Word16 -- TODO: This isn't the right data type.-    | PExplosion Bool (Maybe Int) (Vector Int)-    | PMusicStinger Bool Int Int-    deriving (Eq, Show)+    = PRigidBodyState !Bool !(Vector Int) !(Vector Float) !(Maybe (Vector Int)) !(Maybe (Vector Int))+    | PFlaggedInt !Bool !Int+    | PString !Text.Text+    | PBoolean !Bool+    | PQWord Int !Int+    | PReservation !Int !SystemId !RemoteId !LocalId !(Maybe Text.Text) !Bool !Bool+    | PInt !Int+    | PByte !Int+    | PUniqueId !SystemId !RemoteId !LocalId+    | PLoadoutOnline !Int !Int !Int !(Maybe Int)+    | PLoadout !Int !Int !Int !Int !Int !Int !Int !Int !(Maybe Int)+    | PCamSettings !Float !Float !Float !Float !Float !Float+    | PTeamPaint !Int !Int !Int !Int !Int+    | PLocation !(Vector Int)+    | PPickup !Bool !(Maybe Int) !Bool+    | PEnum !Word.Word16 -- TODO: This isn't the right data type.+    | PExplosion !Bool !(Maybe Int) !(Vector Int)+    | PMusicStinger !Bool !Int !Int+    | PFloat !Float+    | PDemolish !Bool !(Maybe Int) !Bool !(Maybe Int) !(Vector Int) !(Vector Int)+    deriving (Eq, Generics.Generic, Show) +instance DeepSeq.NFData PropValue+instance Aeson.ToJSON PropValue where+    toJSON =+        Aeson.genericToJSON+            Aeson.defaultOptions+            { Aeson.fieldLabelModifier = drop 9+            }+ -- | A frame in the net stream. Each frame has the time since the beginning of -- | the match, the time since the last frame, and a list of replications. data Frame = Frame-    { frameTime :: Float-    , frameDelta :: Float-    , frameReplications :: [Replication]+    { frameTime :: !Float+    , frameDelta :: !Float+    , frameReplications :: ![Replication]     } deriving (Eq,Generics.Generic,Show) +instance DeepSeq.NFData Frame+instance Aeson.ToJSON Frame where+    toJSON =+        Aeson.genericToJSON+            Aeson.defaultOptions+            { Aeson.fieldLabelModifier = drop 5+            }+ -- | Replication information about an actor in the net stream. data Replication = Replication-    { replicationActorId :: Int-    , replicationIsOpen :: Bool-    , replicationIsNew :: Maybe Bool-    , replicationProps :: [Prop]+    { replicationActorId :: !Int+    , replicationIsOpen :: !Bool+    , replicationIsNew :: !(Maybe Bool)+    , replicationClassInit :: !(Maybe ClassInit)+    , replicationProps :: ![Prop]     } deriving (Eq,Generics.Generic,Show) +instance DeepSeq.NFData Replication+instance Aeson.ToJSON Replication where+    toJSON =+        Aeson.genericToJSON+            Aeson.defaultOptions+            { Aeson.fieldLabelModifier = drop 11+            }+ data Thing = Thing-    { thingFlag :: Bool-    , thingObjectId :: Int-    , thingObjectName :: Text.Text-    , thingClassId :: Int-    , thingClassName :: Text.Text-    , thingClassInit :: ClassInit+    { thingFlag :: !Bool+    , thingObjectId :: !Int+    , thingObjectName :: !Text.Text+    , thingClassId :: !Int+    , thingClassName :: !Text.Text+    , thingClassInit :: !ClassInit     } deriving (Show)  type Time = Float@@ -504,16 +593,32 @@ type ActorId = Int  data Vector a = Vector-    { vectorX :: a-    , vectorY :: a-    , vectorZ :: a-    } deriving (Eq, Show)+    { vectorX :: !a+    , vectorY :: !a+    , vectorZ :: !a+    } deriving (Eq, Generics.Generic, Show) +instance (DeepSeq.NFData a) => DeepSeq.NFData (Vector a)+instance (Aeson.ToJSON a) => Aeson.ToJSON (Vector a) where+    toJSON =+        Aeson.genericToJSON+            Aeson.defaultOptions+            { Aeson.fieldLabelModifier = drop 6+            }+ data ClassInit = ClassInit-    { classInitLocation :: Maybe (Vector Int)-    , classInitRotation :: Maybe (Vector Int)-    } deriving (Show)+    { classInitLocation :: !(Maybe (Vector Int))+    , classInitRotation :: !(Maybe (Vector Int))+    } deriving (Eq, Generics.Generic, Show) +instance DeepSeq.NFData ClassInit+instance Aeson.ToJSON ClassInit where+    toJSON =+        Aeson.genericToJSON+            Aeson.defaultOptions+            { Aeson.fieldLabelModifier = drop 6+            }+ -- { class stream id => { property stream id => name } } type ClassPropertyMap = IntMap.IntMap (IntMap.IntMap Text.Text) @@ -527,11 +632,11 @@ type ClassMap = Map.Map Text.Text Int  data Context = Context-    { contextObjectMap :: ObjectMap-    , contextClassPropertyMap :: ClassPropertyMap-    , contextThings :: IntMap.IntMap Thing-    , contextArchetypeMap :: ArchetypeMap-    , contextClassMap :: ClassMap+    { contextObjectMap :: !ObjectMap+    , contextClassPropertyMap :: !ClassPropertyMap+    , contextThings :: !(IntMap.IntMap Thing)+    , contextArchetypeMap :: !ArchetypeMap+    , contextClassMap :: !ClassMap     } deriving (Show)  buildObjectMap :: Type.Replay -> ObjectMap@@ -565,6 +670,8 @@     & Newtype.unpack     & map Newtype.unpack     & zip [0 ..]+    & filter (\ (_, objectName) ->+        not (Text.isInfixOf (Text.pack ":") objectName))     & map (\ (objectId, objectName) -> let         k = archetypeToClass objectName         v = objectId
library/Octane/Type/Actor.hs view
@@ -13,8 +13,8 @@ -- | A class (like "Core.Object") and it's associated ID in the net stream -- | (like 0). data Actor = Actor-    { actorName :: PCString.PCString-    , actorStreamId :: Word32LE.Word32LE+    { actorName :: !PCString.PCString+    , actorStreamId :: !Word32LE.Word32LE     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary Actor where
library/Octane/Type/CacheItem.hs view
@@ -13,10 +13,10 @@  -- | An item in the class net cache map. data CacheItem = CacheItem-    { cacheItemClassId :: Word32LE.Word32LE-    , cacheItemParentCacheId :: Word32LE.Word32LE-    , cacheItemCacheId :: Word32LE.Word32LE-    , cacheItemCacheProperties :: List.List CacheProperty.CacheProperty+    { cacheItemClassId :: !Word32LE.Word32LE+    , cacheItemParentCacheId :: !Word32LE.Word32LE+    , cacheItemCacheId :: !Word32LE.Word32LE+    , cacheItemCacheProperties :: !(List.List CacheProperty.CacheProperty)     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary CacheItem where
library/Octane/Type/CacheProperty.hs view
@@ -11,8 +11,8 @@  -- | A property on an item in the class net cache map. data CacheProperty = CacheProperty-    { cachePropertyObjectId :: Word32LE.Word32LE-    , cachePropertyStreamId :: Word32LE.Word32LE+    { cachePropertyObjectId :: !Word32LE.Word32LE+    , cachePropertyStreamId :: !Word32LE.Word32LE     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary CacheProperty where
library/Octane/Type/KeyFrame.hs view
@@ -14,9 +14,9 @@ -- | the frame it corresponds to, and that frame's bit position in the network -- | stream. data KeyFrame = KeyFrame-    { keyFrameTime :: Float32LE.Float32LE-    , keyFrameFrame :: Word32LE.Word32LE-    , keyFramePosition :: Word32LE.Word32LE+    { keyFrameTime :: !Float32LE.Float32LE+    , keyFrameFrame :: !Word32LE.Word32LE+    , keyFramePosition :: !Word32LE.Word32LE     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary KeyFrame where
library/Octane/Type/Mark.hs view
@@ -12,8 +12,8 @@  -- | A tick mark on the replay. Both goals and saves make tick marks. data Mark = Mark-    { markLabel :: PCString.PCString-    , markFrame :: Word32LE.Word32LE+    { markLabel :: !PCString.PCString+    , markFrame :: !Word32LE.Word32LE     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary Mark where
library/Octane/Type/Message.hs view
@@ -12,9 +12,9 @@  -- | A debugging message. Replays do not have any of these anymore. data Message = Message-    { messageFrame :: Word32LE.Word32LE-    , messageName :: PCString.PCString-    , messageContent :: PCString.PCString+    { messageFrame :: !Word32LE.Word32LE+    , messageName :: !PCString.PCString+    , messageContent :: !PCString.PCString     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary Message where
library/Octane/Type/Primitive/Dictionary.hs view
@@ -8,7 +8,7 @@ import qualified Data.Aeson as Aeson import qualified Data.Binary as Binary import Data.Function ((&))-import qualified Data.Map as Map+import qualified Data.Map.Strict as Map import qualified GHC.Generics as Generics import qualified Octane.Type.Primitive.PCString as PCString 
library/Octane/Type/Property.hs view
@@ -21,22 +21,22 @@ -- | use it. The value stored in the property can be an array, a boolean, and -- | so on. data Property-    = ArrayProperty Word64LE.Word64LE-                    (List.List (Dictionary.Dictionary Property))-    | BoolProperty Word64LE.Word64LE-                   Boolean.Boolean-    | ByteProperty Word64LE.Word64LE-                   (PCString.PCString, PCString.PCString)-    | FloatProperty Word64LE.Word64LE-                    Float32LE.Float32LE-    | IntProperty Word64LE.Word64LE-                  Word32LE.Word32LE-    | NameProperty Word64LE.Word64LE-                   PCString.PCString-    | QWordProperty Word64LE.Word64LE-                    Word64LE.Word64LE-    | StrProperty Word64LE.Word64LE-                  PCString.PCString+    = ArrayProperty !Word64LE.Word64LE+                    !(List.List (Dictionary.Dictionary Property))+    | BoolProperty !Word64LE.Word64LE+                   !Boolean.Boolean+    | ByteProperty !Word64LE.Word64LE+                   !(PCString.PCString, PCString.PCString)+    | FloatProperty !Word64LE.Word64LE+                    !Float32LE.Float32LE+    | IntProperty !Word64LE.Word64LE+                  !Word32LE.Word32LE+    | NameProperty !Word64LE.Word64LE+                   !PCString.PCString+    | QWordProperty !Word64LE.Word64LE+                    !Word64LE.Word64LE+    | StrProperty !Word64LE.Word64LE+                  !PCString.PCString     deriving (Eq,Generics.Generic,Show)  instance Binary.Binary Property where
library/Octane/Type/Replay.hs view
@@ -23,52 +23,52 @@ -- | stream has not. data Replay = Replay     -- Number of bytes in the first section.-    { replaySize1 :: Word32LE.Word32LE+    { replaySize1 :: !Word32LE.Word32LE     -- CRC to check the first section.-    , replayCRC1 :: Word32LE.Word32LE+    , replayCRC1 :: !Word32LE.Word32LE     -- Major replay version number.-    , replayVersion1 :: Word32LE.Word32LE+    , replayVersion1 :: !Word32LE.Word32LE     -- Minor replay version number.-    , replayVersion2 :: Word32LE.Word32LE+    , replayVersion2 :: !Word32LE.Word32LE     -- Label, which is always "TAGame.Replay_Soccar_TA".-    , replayLabel :: PCString.PCString+    , replayLabel :: !PCString.PCString     -- High-level metadata about the replay.-    , replayProperties :: Dictionary.Dictionary Property.Property+    , replayProperties :: !(Dictionary.Dictionary Property.Property)     -- Number of bytes in the last section.-    , replaySize2 :: Word32LE.Word32LE+    , replaySize2 :: !Word32LE.Word32LE     -- CRC to check the last section.-    , replayCRC2 :: Word32LE.Word32LE+    , replayCRC2 :: !Word32LE.Word32LE     -- Array of strings for all of the levels that need to be loaded (array     -- length followed by each string)-    , replayLevels :: List.List PCString.PCString+    , replayLevels :: !(List.List PCString.PCString)     -- Array of Keyframe information used for timeline scrubbing (array     -- length followed by each keyframe struct) (Time, Frame, File Position)-    , replayKeyFrames :: List.List KeyFrame.KeyFrame+    , replayKeyFrames :: !(List.List KeyFrame.KeyFrame)     -- Array of bytes that is the bulk of the data. This is the raw network     -- stream. (array length followed by a bunch of bytes)-    , replayStream :: Stream.Stream+    , replayStream :: !Stream.Stream     -- Array of debugging logs (strings). This reminds me that I should     -- probably turn these off to make the replays smaller. (array length     -- followed by each string)-    , replayMessages :: List.List Message.Message+    , replayMessages :: !(List.List Message.Message)     -- Array of information used to display the Tick marks in the replay (goal     -- scores). (array length followed by each tick struct) (Type, Frame)-    , replayMarks :: List.List Mark.Mark+    , replayMarks :: !(List.List Mark.Mark)     -- Array of strings of replicated Packages-    , replayPackages :: List.List PCString.PCString+    , replayPackages :: !(List.List PCString.PCString)     -- Array of strings for the Object table. Whenever a persistent object gets     -- referenced in the network stream its path gets added to this array. Then     -- its index in this array is used in the network stream.-    , replayObjects :: List.List PCString.PCString+    , replayObjects :: !(List.List PCString.PCString)     -- Array of strings for the Name table. "Names" are commonly used strings     -- that get assigned an integer for use in the network stream.-    , replayNames :: List.List PCString.PCString+    , replayNames :: !(List.List PCString.PCString)     -- Map of string, integer pairs for the Class Index Map. Whenever a class     -- is used in the network stream it is given an integer id by this map.-    , replayActors :: List.List Actor.Actor+    , replayActors :: !(List.List Actor.Actor)     -- "Class Net Cache Map" maps each replicated property in a class to an     -- integer id used in the network stream.-    , replayCacheItems :: List.List CacheItem.CacheItem+    , replayCacheItems :: !(List.List CacheItem.CacheItem)     } deriving (Eq,Generics.Generic,Show)  instance Binary.Binary Replay where
octane.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           octane-version:        0.5.0+version:        0.5.1 synopsis:       Parse Rocket League replays. description:    Octane parses Rocket League replays. category:       Game
package.yaml view
@@ -71,4 +71,4 @@     - -with-rtsopts=-N     main: TestSuite.hs     source-dirs: test-suite-version: '0.5.0'+version: '0.5.1'