rattletrap 11.2.14 → 12.0.0
raw patch · 15 files changed
+242/−135 lines, 15 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Rattletrap.Type.Attribute.GameServer: New :: Str -> GameServer
+ Rattletrap.Type.Attribute.GameServer: Old :: QWord -> GameServer
+ Rattletrap.Type.Attribute.GameServer: bitGet :: Maybe Str -> BitGet GameServer
+ Rattletrap.Type.Attribute.GameServer: bitPut :: GameServer -> BitPut
+ Rattletrap.Type.Attribute.GameServer: data GameServer
+ Rattletrap.Type.Attribute.GameServer: instance Data.Aeson.Types.FromJSON.FromJSON Rattletrap.Type.Attribute.GameServer.GameServer
+ Rattletrap.Type.Attribute.GameServer: instance Data.Aeson.Types.ToJSON.ToJSON Rattletrap.Type.Attribute.GameServer.GameServer
+ Rattletrap.Type.Attribute.GameServer: instance GHC.Classes.Eq Rattletrap.Type.Attribute.GameServer.GameServer
+ Rattletrap.Type.Attribute.GameServer: instance GHC.Show.Show Rattletrap.Type.Attribute.GameServer.GameServer
+ Rattletrap.Type.Attribute.GameServer: schema :: Schema
+ Rattletrap.Type.AttributeType: GameServer :: AttributeType
+ Rattletrap.Type.AttributeValue: GameServer :: GameServer -> AttributeValue
+ Rattletrap.Type.Replay: getBuildVersion :: Header -> Maybe Str
- Rattletrap.Type.Attribute: bitGet :: Version -> ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet Attribute
+ Rattletrap.Type.Attribute: bitGet :: Version -> Maybe Str -> ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet Attribute
- Rattletrap.Type.AttributeValue: bitGet :: Version -> Map U32 Str -> Str -> BitGet AttributeValue
+ Rattletrap.Type.AttributeValue: bitGet :: Version -> Maybe Str -> Map U32 Str -> Str -> BitGet AttributeValue
- Rattletrap.Type.Content: byteGet :: Maybe Str -> Version -> Int -> Word -> ByteGet Content
+ Rattletrap.Type.Content: byteGet :: Maybe Str -> Version -> Int -> Word -> Maybe Str -> ByteGet Content
- Rattletrap.Type.Frame: bitGet :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Frame)
+ Rattletrap.Type.Frame: bitGet :: Maybe Str -> Version -> Maybe Str -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Frame)
- Rattletrap.Type.Frame: decodeFramesBits :: Maybe Str -> Version -> Int -> Word -> ClassAttributeMap -> BitGet (List Frame)
+ Rattletrap.Type.Frame: decodeFramesBits :: Maybe Str -> Version -> Maybe Str -> Int -> Word -> ClassAttributeMap -> BitGet (List Frame)
- Rattletrap.Type.Frame: decodeFramesBitsWith :: Maybe Str -> Version -> Int -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> Int -> [Frame] -> BitGet (Map CompressedWord U32, List Frame)
+ Rattletrap.Type.Frame: decodeFramesBitsWith :: Maybe Str -> Version -> Maybe Str -> Int -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> Int -> [Frame] -> BitGet (Map CompressedWord U32, List Frame)
- Rattletrap.Type.Replication: bitGet :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Replication)
+ Rattletrap.Type.Replication: bitGet :: Maybe Str -> Version -> Maybe Str -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, Replication)
- Rattletrap.Type.Replication: decodeReplicationsBits :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, List Replication)
+ Rattletrap.Type.Replication: decodeReplicationsBits :: Maybe Str -> Version -> Maybe Str -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, List Replication)
- Rattletrap.Type.Replication: decodeReplicationsBitsWith :: Maybe Str -> Version -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> Int -> [Replication] -> BitGet (Map CompressedWord U32, List Replication)
+ Rattletrap.Type.Replication: decodeReplicationsBitsWith :: Maybe Str -> Version -> Maybe Str -> Word -> ClassAttributeMap -> Map CompressedWord U32 -> Int -> [Replication] -> BitGet (Map CompressedWord U32, List Replication)
- Rattletrap.Type.Replication.Updated: bitGet :: Version -> ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet Updated
+ Rattletrap.Type.Replication.Updated: bitGet :: Version -> Maybe Str -> ClassAttributeMap -> Map CompressedWord U32 -> CompressedWord -> BitGet Updated
- Rattletrap.Type.ReplicationValue: bitGet :: Maybe Str -> Version -> ClassAttributeMap -> CompressedWord -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, ReplicationValue)
+ Rattletrap.Type.ReplicationValue: bitGet :: Maybe Str -> Version -> Maybe Str -> ClassAttributeMap -> CompressedWord -> Map CompressedWord U32 -> BitGet (Map CompressedWord U32, ReplicationValue)
Files
- README.markdown +3/−3
- rattletrap.cabal +2/−1
- src/lib/Rattletrap/Console/Main.hs +2/−0
- src/lib/Rattletrap/Data.hs +1/−1
- src/lib/Rattletrap/Type/Attribute.hs +13/−10
- src/lib/Rattletrap/Type/Attribute/GameServer.hs +40/−0
- src/lib/Rattletrap/Type/AttributeType.hs +1/−0
- src/lib/Rattletrap/Type/AttributeValue.hs +68/−54
- src/lib/Rattletrap/Type/Content.hs +45/−41
- src/lib/Rattletrap/Type/Frame.hs +24/−15
- src/lib/Rattletrap/Type/Replay.hs +10/−0
- src/lib/Rattletrap/Type/Replication.hs +24/−7
- src/lib/Rattletrap/Type/Replication/Updated.hs +5/−2
- src/lib/Rattletrap/Type/ReplicationValue.hs +3/−1
- src/test/Main.hs +1/−0
README.markdown view
@@ -10,8 +10,8 @@ can be used to modify replays in order to force everyone into the same car or change the map a game was played on. -Rattletrap supports every version of Rocket League up to [2.21][], which was-released on 2022-10-11. If a replay can be played by the Rocket League client,+Rattletrap supports every version of Rocket League up to [2.23][], which was+released on 2022-11-29. If a replay can be played by the Rocket League client, it can be parsed by Rattletrap. (If not, that's a bug. Please report it!) ## Install@@ -136,7 +136,7 @@ [Docker badge]: https://img.shields.io/docker/v/taylorfausak/rattletrap?label=docker&logo=docker&logoColor=white [docker]: https://hub.docker.com/r/taylorfausak/rattletrap [Rocket League]: https://www.rocketleague.com-[2.21]: https://www.rocketleague.com/news/patch-notes-v2-21/+[2.23]: https://www.rocketleague.com/news/patch-notes-v2-23/ [Ball Chasing]: https://ballchasing.com [Haskell]: https://www.haskell.org [the latest release]: https://github.com/tfausak/rattletrap/releases/latest
rattletrap.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: rattletrap-version: 11.2.14+version: 12.0.0 synopsis: Parse and generate Rocket League replays. description: Rattletrap parses and generates Rocket League replays. @@ -114,6 +114,7 @@ Rattletrap.Type.Attribute.FlaggedInt Rattletrap.Type.Attribute.Float Rattletrap.Type.Attribute.GameMode+ Rattletrap.Type.Attribute.GameServer Rattletrap.Type.Attribute.Int Rattletrap.Type.Attribute.Int64 Rattletrap.Type.Attribute.Loadout
src/lib/Rattletrap/Console/Main.hs view
@@ -29,6 +29,7 @@ import qualified Rattletrap.Type.Attribute.FlaggedInt as Attribute.FlaggedInt import qualified Rattletrap.Type.Attribute.Float as Attribute.Float import qualified Rattletrap.Type.Attribute.GameMode as Attribute.GameMode+import qualified Rattletrap.Type.Attribute.GameServer as Attribute.GameServer import qualified Rattletrap.Type.Attribute.Int as Attribute.Int import qualified Rattletrap.Type.Attribute.Int64 as Attribute.Int64 import qualified Rattletrap.Type.Attribute.Loadout as Attribute.Loadout@@ -181,6 +182,7 @@ , Attribute.FlaggedInt.schema , Attribute.Float.schema , Attribute.GameMode.schema+ , Attribute.GameServer.schema , Attribute.Int.schema , Attribute.Int64.schema , Attribute.Loadout.schema
src/lib/Rattletrap/Data.hs view
@@ -273,7 +273,7 @@ , ("Engine.ReplicatedActor_ORS:ReplicatedOwner", AttributeType.FlaggedInt) , ("Engine.TeamInfo:Score", AttributeType.Int) , ("ProjectX.GRI_X:bGameStarted", AttributeType.Boolean)- , ("ProjectX.GRI_X:GameServerID", AttributeType.QWord)+ , ("ProjectX.GRI_X:GameServerID", AttributeType.GameServer) , ("ProjectX.GRI_X:MatchGuid", AttributeType.String) , ("ProjectX.GRI_X:MatchGUID", AttributeType.String) , ("ProjectX.GRI_X:ReplicatedGameMutatorIndex", AttributeType.Int)
src/lib/Rattletrap/Type/Attribute.hs view
@@ -54,20 +54,23 @@ bitGet :: Version.Version+ -> Maybe Str.Str -> ClassAttributeMap.ClassAttributeMap -> Map.Map CompressedWord.CompressedWord U32.U32 -> CompressedWord.CompressedWord -> BitGet.BitGet Attribute-bitGet version classes actors actor = BitGet.label "Attribute" $ do- attributes <- lookupAttributeMap classes actors actor- limit <- lookupAttributeIdLimit attributes actor- id <- BitGet.label "id" $ CompressedWord.bitGet limit- name <- lookupAttributeName classes attributes id- value <- BitGet.label "value" $ AttributeValue.bitGet- version- (ClassAttributeMap.objectMap classes)- name- pure Attribute { id, name, value }+bitGet version buildVersion classes actors actor =+ BitGet.label "Attribute" $ do+ attributes <- lookupAttributeMap classes actors actor+ limit <- lookupAttributeIdLimit attributes actor+ id <- BitGet.label "id" $ CompressedWord.bitGet limit+ name <- lookupAttributeName classes attributes id+ value <- BitGet.label "value" $ AttributeValue.bitGet+ version+ buildVersion+ (ClassAttributeMap.objectMap classes)+ name+ pure Attribute { id, name, value } lookupAttributeMap :: ClassAttributeMap.ClassAttributeMap
+ src/lib/Rattletrap/Type/Attribute/GameServer.hs view
@@ -0,0 +1,40 @@+module Rattletrap.Type.Attribute.GameServer where++import qualified Data.Foldable as Foldable+import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.QWord as QWord+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Utility.Json as Json++data GameServer+ = Old QWord.QWord+ | New Str.Str+ deriving (Eq, Show)++instance Json.FromJSON GameServer where+ parseJSON = Json.withObject "GameServer" $ \x -> Foldable.asum+ [fmap Old $ Json.required x "old", fmap New $ Json.required x "new"]++instance Json.ToJSON GameServer where+ toJSON x = case x of+ Old y -> Json.object [Json.pair "old" $ Json.toJSON y]+ New y -> Json.object [Json.pair "new" $ Json.toJSON y]++schema :: Schema.Schema+schema = Schema.named "attribute-game-server" . Schema.oneOf $ fmap+ (\(k, v) -> Schema.object [(Json.pair k v, True)])+ [("old", Schema.ref QWord.schema), ("new", Schema.ref Str.schema)]++bitPut :: GameServer -> BitPut.BitPut+bitPut x = case x of+ Old y -> QWord.bitPut y+ New y -> Str.bitPut y++bitGet :: Maybe Str.Str -> BitGet.BitGet GameServer+bitGet buildVersion =+ BitGet.label "GameServer"+ $ if buildVersion >= Just (Str.fromString "221120.42953.406184")+ then BitGet.label "New" $ fmap New Str.bitGet+ else BitGet.label "Old" $ fmap Old QWord.bitGet
src/lib/Rattletrap/Type/AttributeType.hs view
@@ -16,6 +16,7 @@ | FlaggedByte | Float | GameMode+ | GameServer | Int | Int64 | Loadout
src/lib/Rattletrap/Type/AttributeValue.hs view
@@ -22,6 +22,7 @@ import qualified Rattletrap.Type.Attribute.FlaggedInt as FlaggedInt import qualified Rattletrap.Type.Attribute.Float as Float import qualified Rattletrap.Type.Attribute.GameMode as GameMode+import qualified Rattletrap.Type.Attribute.GameServer as GameServer import qualified Rattletrap.Type.Attribute.Int as Int import qualified Rattletrap.Type.Attribute.Int64 as Int64 import qualified Rattletrap.Type.Attribute.Loadout as Loadout@@ -69,6 +70,7 @@ | FlaggedByte FlaggedByte.FlaggedByte | Float Float.Float | GameMode GameMode.GameMode+ | GameServer GameServer.GameServer | Int Int.Int | Int64 Int64.Int64 | Loadout Loadout.Loadout@@ -113,6 +115,7 @@ , fmap FlaggedInt $ Json.required object "flagged_int" , fmap Float $ Json.required object "float" , fmap GameMode $ Json.required object "game_mode"+ , fmap GameServer $ Json.required object "game_server" , fmap Int $ Json.required object "int" , fmap Int64 $ Json.required object "int64" , fmap Loadout $ Json.required object "loadout"@@ -157,6 +160,7 @@ FlaggedInt y -> Json.object [Json.pair "flagged_int" y] Float y -> Json.object [Json.pair "float" y] GameMode y -> Json.object [Json.pair "game_mode" y]+ GameServer y -> Json.object [Json.pair "game_server" y] Int y -> Json.object [Json.pair "int" y] Int64 y -> Json.object [Json.pair "int64" y] Loadout y -> Json.object [Json.pair "loadout" y]@@ -202,6 +206,7 @@ , ("flagged_int", FlaggedInt.schema) , ("float", Float.schema) , ("game_mode", GameMode.schema)+ , ("game_server", GameServer.schema) , ("int", Int.schema) , ("int64", Int64.schema) , ("loadout_online", LoadoutOnline.schema)@@ -246,6 +251,7 @@ FlaggedByte x -> FlaggedByte.bitPut x Float x -> Float.bitPut x GameMode x -> GameMode.bitPut x+ GameServer x -> GameServer.bitPut x Int x -> Int.bitPut x Int64 x -> Int64.putInt64Attribute x Loadout x -> Loadout.bitPut x@@ -274,60 +280,68 @@ bitGet :: Version.Version+ -> Maybe Str.Str -> Map.Map U32.U32 Str.Str -> Str.Str -> BitGet.BitGet AttributeValue-bitGet version objectMap name = BitGet.label "AttributeValue" $ do- constructor <- case Map.lookup (Str.toText name) Data.attributeTypes of- Nothing ->- BitGet.throw . UnknownAttribute.UnknownAttribute $ Str.toString name- Just x -> pure x- case constructor of- AttributeType.AppliedDamage ->- fmap AppliedDamage $ AppliedDamage.bitGet version- AttributeType.Boolean -> fmap Boolean Boolean.bitGet- AttributeType.Byte -> fmap Byte Byte.bitGet- AttributeType.CamSettings -> fmap CamSettings $ CamSettings.bitGet version- AttributeType.ClubColors -> fmap ClubColors ClubColors.bitGet- AttributeType.CustomDemolish ->- fmap CustomDemolish $ CustomDemolish.bitGet version- AttributeType.DamageState -> fmap DamageState $ DamageState.bitGet version- AttributeType.Demolish -> fmap Demolish $ Demolish.bitGet version- AttributeType.Enum -> fmap Enum Enum.bitGet- AttributeType.Explosion -> fmap Explosion $ Explosion.bitGet version- AttributeType.ExtendedExplosion ->- fmap ExtendedExplosion $ ExtendedExplosion.bitGet version- AttributeType.FlaggedInt -> fmap FlaggedInt FlaggedInt.bitGet- AttributeType.FlaggedByte -> fmap FlaggedByte FlaggedByte.bitGet- AttributeType.Float -> fmap Float Float.bitGet- AttributeType.GameMode -> fmap GameMode $ GameMode.bitGet version- AttributeType.Int -> fmap Int Int.bitGet- AttributeType.Int64 -> fmap Int64 Int64.bitGet- AttributeType.Loadout -> fmap Loadout Loadout.bitGet- AttributeType.LoadoutOnline ->- fmap LoadoutOnline $ LoadoutOnline.bitGet version objectMap- AttributeType.Loadouts -> fmap Loadouts Loadouts.bitGet- AttributeType.LoadoutsOnline ->- fmap LoadoutsOnline $ LoadoutsOnline.bitGet version objectMap- AttributeType.Location -> fmap Location $ Location.bitGet version- AttributeType.MusicStinger -> fmap MusicStinger MusicStinger.bitGet- AttributeType.PartyLeader -> fmap PartyLeader $ PartyLeader.bitGet version- AttributeType.Pickup -> fmap Pickup Pickup.bitGet- AttributeType.PickupInfo -> fmap PickupInfo PickupInfo.bitGet- AttributeType.PickupNew -> fmap PickupNew PickupNew.bitGet- AttributeType.PlayerHistoryKey ->- fmap PlayerHistoryKey PlayerHistoryKey.bitGet- AttributeType.PrivateMatchSettings ->- fmap PrivateMatchSettings PrivateMatchSettings.bitGet- AttributeType.QWord -> fmap QWord QWord.bitGet- AttributeType.RepStatTitle -> fmap RepStatTitle RepStatTitle.bitGet- AttributeType.Reservation -> fmap Reservation $ Reservation.bitGet version- AttributeType.RigidBodyState ->- fmap RigidBodyState $ RigidBodyState.bitGet version- AttributeType.Rotation -> fmap Rotation Rotation.bitGet- AttributeType.StatEvent -> fmap StatEvent StatEvent.bitGet- AttributeType.String -> fmap String String.bitGet- AttributeType.TeamPaint -> fmap TeamPaint TeamPaint.bitGet- AttributeType.Title -> fmap Title Title.bitGet- AttributeType.UniqueId -> fmap UniqueId $ UniqueId.bitGet version- AttributeType.WeldedInfo -> fmap WeldedInfo $ WeldedInfo.bitGet version+bitGet version buildVersion objectMap name =+ BitGet.label "AttributeValue" $ do+ constructor <- case Map.lookup (Str.toText name) Data.attributeTypes of+ Nothing ->+ BitGet.throw . UnknownAttribute.UnknownAttribute $ Str.toString name+ Just x -> pure x+ case constructor of+ AttributeType.AppliedDamage ->+ fmap AppliedDamage $ AppliedDamage.bitGet version+ AttributeType.Boolean -> fmap Boolean Boolean.bitGet+ AttributeType.Byte -> fmap Byte Byte.bitGet+ AttributeType.CamSettings ->+ fmap CamSettings $ CamSettings.bitGet version+ AttributeType.ClubColors -> fmap ClubColors ClubColors.bitGet+ AttributeType.CustomDemolish ->+ fmap CustomDemolish $ CustomDemolish.bitGet version+ AttributeType.DamageState ->+ fmap DamageState $ DamageState.bitGet version+ AttributeType.Demolish -> fmap Demolish $ Demolish.bitGet version+ AttributeType.Enum -> fmap Enum Enum.bitGet+ AttributeType.Explosion -> fmap Explosion $ Explosion.bitGet version+ AttributeType.ExtendedExplosion ->+ fmap ExtendedExplosion $ ExtendedExplosion.bitGet version+ AttributeType.FlaggedInt -> fmap FlaggedInt FlaggedInt.bitGet+ AttributeType.FlaggedByte -> fmap FlaggedByte FlaggedByte.bitGet+ AttributeType.Float -> fmap Float Float.bitGet+ AttributeType.GameMode -> fmap GameMode $ GameMode.bitGet version+ AttributeType.GameServer ->+ fmap GameServer $ GameServer.bitGet buildVersion+ AttributeType.Int -> fmap Int Int.bitGet+ AttributeType.Int64 -> fmap Int64 Int64.bitGet+ AttributeType.Loadout -> fmap Loadout Loadout.bitGet+ AttributeType.LoadoutOnline ->+ fmap LoadoutOnline $ LoadoutOnline.bitGet version objectMap+ AttributeType.Loadouts -> fmap Loadouts Loadouts.bitGet+ AttributeType.LoadoutsOnline ->+ fmap LoadoutsOnline $ LoadoutsOnline.bitGet version objectMap+ AttributeType.Location -> fmap Location $ Location.bitGet version+ AttributeType.MusicStinger -> fmap MusicStinger MusicStinger.bitGet+ AttributeType.PartyLeader ->+ fmap PartyLeader $ PartyLeader.bitGet version+ AttributeType.Pickup -> fmap Pickup Pickup.bitGet+ AttributeType.PickupInfo -> fmap PickupInfo PickupInfo.bitGet+ AttributeType.PickupNew -> fmap PickupNew PickupNew.bitGet+ AttributeType.PlayerHistoryKey ->+ fmap PlayerHistoryKey PlayerHistoryKey.bitGet+ AttributeType.PrivateMatchSettings ->+ fmap PrivateMatchSettings PrivateMatchSettings.bitGet+ AttributeType.QWord -> fmap QWord QWord.bitGet+ AttributeType.RepStatTitle -> fmap RepStatTitle RepStatTitle.bitGet+ AttributeType.Reservation ->+ fmap Reservation $ Reservation.bitGet version+ AttributeType.RigidBodyState ->+ fmap RigidBodyState $ RigidBodyState.bitGet version+ AttributeType.Rotation -> fmap Rotation Rotation.bitGet+ AttributeType.StatEvent -> fmap StatEvent StatEvent.bitGet+ AttributeType.String -> fmap String String.bitGet+ AttributeType.TeamPaint -> fmap TeamPaint TeamPaint.bitGet+ AttributeType.Title -> fmap Title Title.bitGet+ AttributeType.UniqueId -> fmap UniqueId $ UniqueId.bitGet version+ AttributeType.WeldedInfo -> fmap WeldedInfo $ WeldedInfo.bitGet version
src/lib/Rattletrap/Type/Content.hs view
@@ -188,45 +188,49 @@ -> Word -- ^ The maximum number of channels in the stream, usually from -- 'Rattletrap.Header.getMaxChannels'.+ -> Maybe Str.Str+ -- ^ 'Rattletrap.Header.getBuildVersion' -> ByteGet.ByteGet Content-byteGet matchType version numFrames maxChannels = ByteGet.label "Content" $ do- levels <- ByteGet.label "levels" $ List.byteGet Str.byteGet- keyframes <- ByteGet.label "keyframes" $ List.byteGet Keyframe.byteGet- streamSize <- ByteGet.label "streamSize" U32.byteGet- stream <-- ByteGet.label "stream" . ByteGet.byteString . fromIntegral $ U32.toWord32- streamSize- messages <- ByteGet.label "messages" $ List.byteGet Message.byteGet- marks <- ByteGet.label "marks" $ List.byteGet Mark.byteGet- packages <- ByteGet.label "packages" $ List.byteGet Str.byteGet- objects <- ByteGet.label "objects" $ List.byteGet Str.byteGet- names <- ByteGet.label "names" $ List.byteGet Str.byteGet- classMappings <- ByteGet.label "classMappings"- $ List.byteGet ClassMapping.byteGet- caches <- ByteGet.label "caches" $ List.byteGet Cache.byteGet- let- classAttributeMap =- ClassAttributeMap.make objects classMappings caches names- getFrames = BitGet.toByteGet $ Frame.decodeFramesBits- matchType- version- numFrames- maxChannels- classAttributeMap- frames <- ByteGet.label "frames" $ ByteGet.embed getFrames stream- unknown <- ByteGet.label "unknown"- $ fmap LazyByteString.unpack ByteGet.remaining- pure Content- { levels- , keyframes- , streamSize- , frames- , messages- , marks- , packages- , objects- , names- , classMappings- , caches- , unknown- }+byteGet matchType version numFrames maxChannels buildVersion =+ ByteGet.label "Content" $ do+ levels <- ByteGet.label "levels" $ List.byteGet Str.byteGet+ keyframes <- ByteGet.label "keyframes" $ List.byteGet Keyframe.byteGet+ streamSize <- ByteGet.label "streamSize" U32.byteGet+ stream <-+ ByteGet.label "stream" . ByteGet.byteString . fromIntegral $ U32.toWord32+ streamSize+ messages <- ByteGet.label "messages" $ List.byteGet Message.byteGet+ marks <- ByteGet.label "marks" $ List.byteGet Mark.byteGet+ packages <- ByteGet.label "packages" $ List.byteGet Str.byteGet+ objects <- ByteGet.label "objects" $ List.byteGet Str.byteGet+ names <- ByteGet.label "names" $ List.byteGet Str.byteGet+ classMappings <- ByteGet.label "classMappings"+ $ List.byteGet ClassMapping.byteGet+ caches <- ByteGet.label "caches" $ List.byteGet Cache.byteGet+ let+ classAttributeMap =+ ClassAttributeMap.make objects classMappings caches names+ getFrames = BitGet.toByteGet $ Frame.decodeFramesBits+ matchType+ version+ buildVersion+ numFrames+ maxChannels+ classAttributeMap+ frames <- ByteGet.label "frames" $ ByteGet.embed getFrames stream+ unknown <- ByteGet.label "unknown"+ $ fmap LazyByteString.unpack ByteGet.remaining+ pure Content+ { levels+ , keyframes+ , streamSize+ , frames+ , messages+ , marks+ , packages+ , objects+ , names+ , classMappings+ , caches+ , unknown+ }
src/lib/Rattletrap/Type/Frame.hs view
@@ -59,14 +59,16 @@ decodeFramesBits :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> Int -> Word -> ClassAttributeMap.ClassAttributeMap -> BitGet.BitGet (List.List Frame)-decodeFramesBits matchType version count limit classes =+decodeFramesBits matchType version buildVersion count limit classes = fmap snd $ decodeFramesBitsWith matchType version+ buildVersion count limit classes@@ -77,6 +79,7 @@ decodeFramesBitsWith :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> Int -> Word -> ClassAttributeMap.ClassAttributeMap@@ -84,19 +87,22 @@ -> Int -> [Frame] -> BitGet.BitGet- ( Map.Map CompressedWord.CompressedWord U32.U32+ ( Map.Map+ CompressedWord.CompressedWord+ U32.U32 , List.List Frame )-decodeFramesBitsWith matchType version count limit classes actorMap index frames+decodeFramesBitsWith matchType version buildVersion count limit classes actorMap index frames = if index >= count then pure (actorMap, List.fromList $ reverse frames) else do (newActorMap, frame) <- BitGet.label ("element (" <> show index <> ")")- $ bitGet matchType version limit classes actorMap+ $ bitGet matchType version buildVersion limit classes actorMap decodeFramesBitsWith matchType version+ buildVersion count limit classes@@ -108,19 +114,22 @@ bitGet :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> Word -> ClassAttributeMap.ClassAttributeMap -> Map.Map CompressedWord.CompressedWord U32.U32 -> BitGet.BitGet (Map.Map CompressedWord.CompressedWord U32.U32, Frame)-bitGet matchType version limit classes actorMap = BitGet.label "Frame" $ do- time <- BitGet.label "time" F32.bitGet- delta <- BitGet.label "delta" F32.bitGet- (newActorMap, replications) <-- BitGet.label "replications" $ Replication.decodeReplicationsBits- matchType- version- limit- classes- actorMap- pure (newActorMap, Frame { time, delta, replications })+bitGet matchType version buildVersion limit classes actorMap =+ BitGet.label "Frame" $ do+ time <- BitGet.label "time" F32.bitGet+ delta <- BitGet.label "delta" F32.bitGet+ (newActorMap, replications) <-+ BitGet.label "replications" $ Replication.decodeReplicationsBits+ matchType+ version+ buildVersion+ limit+ classes+ actorMap+ pure (newActorMap, Frame { time, delta, replications })
src/lib/Rattletrap/Type/Replay.hs view
@@ -10,6 +10,7 @@ import qualified Rattletrap.Type.Property as Property import qualified Rattletrap.Type.Property.Int as Property.Int import qualified Rattletrap.Type.Property.Name as Property.Name+import qualified Rattletrap.Type.Property.Str as Property.Str import qualified Rattletrap.Type.PropertyValue as PropertyValue import qualified Rattletrap.Type.Section as Section import qualified Rattletrap.Type.Str as Str@@ -86,6 +87,7 @@ (Header.version h) (getNumFrames h) (getMaxChannels h)+ (getBuildVersion h) getMatchType :: Header.Header -> Maybe Str.Str getMatchType header = do@@ -117,3 +119,11 @@ Just (Property.Property _ _ (PropertyValue.Int maxChannels)) -> fromIntegral (I32.toInt32 (Property.Int.toI32 maxChannels)) _ -> 1023++getBuildVersion :: Header.Header -> Maybe Str.Str+getBuildVersion header = do+ property <- Dictionary.lookup (Str.fromString "BuildVersion")+ $ Header.properties header+ case Property.value property of+ PropertyValue.Str x -> Just $ Property.Str.toStr x+ _ -> Nothing
src/lib/Rattletrap/Type/Replication.hs view
@@ -47,6 +47,7 @@ decodeReplicationsBits :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> Word -> ClassAttributeMap.ClassAttributeMap -> Map.Map CompressedWord.CompressedWord U32.U32@@ -54,12 +55,21 @@ ( Map.Map CompressedWord.CompressedWord U32.U32 , List.List Replication )-decodeReplicationsBits matchType version limit classes actorMap =- decodeReplicationsBitsWith matchType version limit classes actorMap 0 []+decodeReplicationsBits matchType version buildVersion limit classes actorMap =+ decodeReplicationsBitsWith+ matchType+ version+ buildVersion+ limit+ classes+ actorMap+ 0+ [] decodeReplicationsBitsWith :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> Word -> ClassAttributeMap.ClassAttributeMap -> Map.Map CompressedWord.CompressedWord U32.U32@@ -69,17 +79,18 @@ ( Map.Map CompressedWord.CompressedWord U32.U32 , List.List Replication )-decodeReplicationsBitsWith matchType version limit classes actorMap index replications+decodeReplicationsBitsWith matchType version buildVersion limit classes actorMap index replications = do hasReplication <- BitGet.bool if hasReplication then do (newActorMap, replication) <- BitGet.label ("element (" <> show index <> ")")- $ bitGet matchType version limit classes actorMap+ $ bitGet matchType version buildVersion limit classes actorMap decodeReplicationsBitsWith matchType version+ buildVersion limit classes newActorMap@@ -91,6 +102,7 @@ bitGet :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> Word -> ClassAttributeMap.ClassAttributeMap -> Map.Map CompressedWord.CompressedWord U32.U32@@ -98,9 +110,14 @@ ( Map.Map CompressedWord.CompressedWord U32.U32 , Replication )-bitGet matchType version limit classes actorMap =+bitGet matchType version buildVersion limit classes actorMap = BitGet.label "Replication" $ do actorId <- BitGet.label "actorId" $ CompressedWord.bitGet limit- (newActorMap, value) <- BitGet.label "value"- $ ReplicationValue.bitGet matchType version classes actorId actorMap+ (newActorMap, value) <- BitGet.label "value" $ ReplicationValue.bitGet+ matchType+ version+ buildVersion+ classes+ actorId+ actorMap pure (newActorMap, Replication { actorId, value })
src/lib/Rattletrap/Type/Replication/Updated.hs view
@@ -8,6 +8,7 @@ import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap import qualified Rattletrap.Type.CompressedWord as CompressedWord import qualified Rattletrap.Type.List as List+import qualified Rattletrap.Type.Str as Str import qualified Rattletrap.Type.U32 as U32 import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json@@ -36,11 +37,13 @@ bitGet :: Version.Version+ -> Maybe Str.Str -> ClassAttributeMap.ClassAttributeMap -> Map.Map CompressedWord.CompressedWord U32.U32 -> CompressedWord.CompressedWord -> BitGet.BitGet Updated-bitGet version classes actors actor =+bitGet version buildVersion classes actors actor = BitGet.label "Updated" . fmap Updated . List.untilM $ do p <- BitGet.bool- Monad.whenMaybe p $ Attribute.bitGet version classes actors actor+ Monad.whenMaybe p+ $ Attribute.bitGet version buildVersion classes actors actor
src/lib/Rattletrap/Type/ReplicationValue.hs view
@@ -54,6 +54,7 @@ bitGet :: Maybe Str.Str -> Version.Version+ -> Maybe Str.Str -> ClassAttributeMap.ClassAttributeMap -> CompressedWord.CompressedWord -> Map.Map CompressedWord.CompressedWord U32.U32@@ -61,7 +62,7 @@ ( Map.Map CompressedWord.CompressedWord U32.U32 , ReplicationValue )-bitGet matchType version classAttributeMap actorId actorMap =+bitGet matchType version buildVersion classAttributeMap actorId actorMap = BitGet.label "ReplicationValue" $ do isOpen <- BitGet.bool if isOpen@@ -79,6 +80,7 @@ else do updated <- Updated.bitGet version+ buildVersion classAttributeMap actorMap actorId
src/test/Main.hs view
@@ -99,6 +99,7 @@ , ("540d", "a demolish attribute") -- https://github.com/tfausak/rattletrap/commit/65ce033 , ("54ae", "replicated car scale") -- https://github.com/nickbabcock/boxcars/pull/79 , ("551c", "private match settings") -- https://github.com/tfausak/rattletrap/commit/5c9ebfc+ , ("59d3", "v2.23") -- https://github.com/tfausak/rattletrap/issues/274 , ("5a06", "esports items") -- https://github.com/tfausak/rattletrap/pull/114 , ("5e0b", "max channels") -- https://github.com/tfausak/rattletrap/issues/254 , ("6210", "different player history key") -- https://github.com/tfausak/rattletrap/pull/63