rattletrap 11.2.5 → 11.2.6
raw patch · 13 files changed
+189/−22 lines, 13 files
Files
- rattletrap.cabal +4/−1
- src/lib/Rattletrap/Console/Main.hs +4/−0
- src/lib/Rattletrap/Data.hs +23/−0
- src/lib/Rattletrap/Type/Attribute/RepStatTitle.hs +56/−0
- src/lib/Rattletrap/Type/Attribute/Rotation.hs +28/−0
- src/lib/Rattletrap/Type/AttributeType.hs +2/−0
- src/lib/Rattletrap/Type/AttributeValue.hs +14/−0
- src/lib/Rattletrap/Type/Property/Byte.hs +5/−3
- src/lib/Rattletrap/Type/RemoteId.hs +7/−0
- src/lib/Rattletrap/Type/RemoteId/QQ.hs +32/−0
- src/lib/Rattletrap/Type/Replication/Spawned.hs +3/−1
- src/lib/Rattletrap/Utility/Json.hs +1/−17
- src/test/Main.hs +10/−0
rattletrap.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: rattletrap-version: 11.2.5+version: 11.2.6 synopsis: Parse and generate Rocket League replays. description: Rattletrap parses and generates Rocket League replays. @@ -129,8 +129,10 @@ Rattletrap.Type.Attribute.Product Rattletrap.Type.Attribute.ProductValue Rattletrap.Type.Attribute.QWord+ Rattletrap.Type.Attribute.RepStatTitle Rattletrap.Type.Attribute.Reservation Rattletrap.Type.Attribute.RigidBodyState+ Rattletrap.Type.Attribute.Rotation Rattletrap.Type.Attribute.StatEvent Rattletrap.Type.Attribute.String Rattletrap.Type.Attribute.TeamPaint@@ -174,6 +176,7 @@ Rattletrap.Type.RemoteId.Epic Rattletrap.Type.RemoteId.PlayStation Rattletrap.Type.RemoteId.PsyNet+ Rattletrap.Type.RemoteId.QQ Rattletrap.Type.RemoteId.Splitscreen Rattletrap.Type.RemoteId.Steam Rattletrap.Type.RemoteId.Switch
src/lib/Rattletrap/Console/Main.hs view
@@ -46,8 +46,10 @@ import qualified Rattletrap.Type.Attribute.Product as Attribute.Product import qualified Rattletrap.Type.Attribute.ProductValue as Attribute.ProductValue import qualified Rattletrap.Type.Attribute.QWord as Attribute.QWord+import qualified Rattletrap.Type.Attribute.RepStatTitle as Attribute.RepStatTitle import qualified Rattletrap.Type.Attribute.Reservation as Attribute.Reservation import qualified Rattletrap.Type.Attribute.RigidBodyState as Attribute.RigidBodyState+import qualified Rattletrap.Type.Attribute.Rotation as Attribute.Rotation import qualified Rattletrap.Type.Attribute.StatEvent as Attribute.StatEvent import qualified Rattletrap.Type.Attribute.String as Attribute.String import qualified Rattletrap.Type.Attribute.TeamPaint as Attribute.TeamPaint@@ -195,8 +197,10 @@ , Attribute.Product.schema , Attribute.ProductValue.schema , Attribute.QWord.schema+ , Attribute.RepStatTitle.schema , Attribute.Reservation.schema , Attribute.RigidBodyState.schema+ , Attribute.Rotation.schema , Attribute.StatEvent.schema , Attribute.String.schema , Attribute.TeamPaint.schema
src/lib/Rattletrap/Data.hs view
@@ -80,6 +80,7 @@ , "Archetypes.Ball.Ball_Breakout" , "Archetypes.Ball.Ball_Default" , "Archetypes.Ball.Ball_Puck"+ , "Archetypes.Ball.Ball_Trajectory" , "Archetypes.Ball.CubeBall" , "Archetypes.Car.Car_Default" , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"@@ -90,6 +91,7 @@ , "TAGame.Ball_Haunted_TA" , "TAGame.Ball_TA" , "TAGame.CameraSettingsActor_TA"+ , "TAGame.Cannon_TA" , "TAGame.Car_Season_TA" , "TAGame.Car_TA" , "TAGame.CarComponent_Boost_TA"@@ -105,6 +107,7 @@ , "TAGame.GameEvent_Soccar_TA" , "TAGame.GameEvent_SoccarPrivate_TA" , "TAGame.GameEvent_SoccarSplitscreen_TA"+ , "TAGame.GameEvent_Tutorial_TA" , "TAGame.GRI_TA" , "TAGame.MaxTimeWarningData_TA" , "TAGame.PickupTimer_TA"@@ -141,6 +144,7 @@ , "Archetypes.Ball.Ball_Breakout" , "Archetypes.Ball.Ball_Default" , "Archetypes.Ball.Ball_Puck"+ , "Archetypes.Ball.Ball_Trajectory" , "Archetypes.Ball.CubeBall" , "Archetypes.Car.Car_Default" , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"@@ -167,6 +171,8 @@ , ("Archetypes.Ball.Ball_God", "TAGame.Ball_God_TA") , ("Archetypes.Ball.Ball_Haunted", "TAGame.Ball_Haunted_TA") , ("Archetypes.Ball.Ball_Puck", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_Training", "TAGame.Ball_TA")+ , ("Archetypes.Ball.Ball_Trajectory", "TAGame.Ball_TA") , ("Archetypes.Ball.CubeBall", "TAGame.Ball_TA") , ("Archetypes.Car.Car_Default", "TAGame.Car_TA") , ("Archetypes.CarComponents.CarComponent_Boost", "TAGame.CarComponent_Boost_TA")@@ -205,6 +211,7 @@ , ("Archetypes.SpecialPickups.SpecialPickup_Tornado", "TAGame.SpecialPickup_Tornado_TA") , ("Archetypes.Teams.Team0", "TAGame.Team_Soccar_TA") , ("Archetypes.Teams.Team1", "TAGame.Team_Soccar_TA")+ , ("Archetypes.Tutorial.Cannon", "TAGame.Cannon_TA") , ("GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype", "TAGame.GRI_TA") , ("GameInfo_Breakout.GameInfo.GameInfo_Breakout:GameReplicationInfoArchetype", "TAGame.GRI_TA") , ("GameInfo_FootBall.GameInfo.GameInfo_FootBall:Archetype", "TAGame.GameEvent_Football_TA")@@ -217,6 +224,8 @@ , ("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_Tutorial.GameEvent.GameEvent_Tutorial_Aerial", "TAGame.GameEvent_Tutorial_TA")+ , ("GameInfo_Tutorial.GameInfo.GameInfo_Tutorial:GameReplicationInfoArchetype", "TAGame.GRI_TA") , ("Haunted_TrainStation_P.TheWorld:PersistentLevel.HauntedBallTrapTrigger_TA_0", "TAGame.HauntedBallTrapTrigger_TA") , ("Haunted_TrainStation_P.TheWorld:PersistentLevel.HauntedBallTrapTrigger_TA_1", "TAGame.HauntedBallTrapTrigger_TA") , ("ProjectX.Default__NetModeReplicator_X", "ProjectX.NetModeReplicator")@@ -238,12 +247,15 @@ [ ("Engine.Actor:bBlockActors", AttributeType.Boolean) , ("Engine.Actor:bCollideActors", AttributeType.Boolean) , ("Engine.Actor:bHidden", AttributeType.Boolean)+ , ("Engine.Actor:bTearOff", AttributeType.Boolean) , ("Engine.Actor:DrawScale", AttributeType.Float) , ("Engine.Actor:RemoteRole", AttributeType.Enum) , ("Engine.Actor:Role", AttributeType.Enum)+ , ("Engine.Actor:Rotation", AttributeType.Rotation) , ("Engine.GameReplicationInfo:bMatchIsOver", AttributeType.Boolean) , ("Engine.GameReplicationInfo:GameClass", AttributeType.FlaggedInt) , ("Engine.GameReplicationInfo:ServerName", AttributeType.String)+ , ("Engine.Pawn:HealthMax", AttributeType.Int) , ("Engine.Pawn:PlayerReplicationInfo", AttributeType.FlaggedInt) , ("Engine.PlayerReplicationInfo:bBot", AttributeType.Boolean) , ("Engine.PlayerReplicationInfo:bIsSpectator", AttributeType.Boolean)@@ -292,10 +304,13 @@ , ("TAGame.CameraSettingsActor_TA:CameraYaw", AttributeType.Byte) , ("TAGame.CameraSettingsActor_TA:PRI", AttributeType.FlaggedInt) , ("TAGame.CameraSettingsActor_TA:ProfileSettings", AttributeType.CamSettings)+ , ("TAGame.Cannon_TA:FireCount", AttributeType.Byte)+ , ("TAGame.Cannon_TA:Pitch", AttributeType.Float) , ("TAGame.Car_TA:AddedBallForceMultiplier", AttributeType.Float) , ("TAGame.Car_TA:AddedCarForceMultiplier", AttributeType.Float) , ("TAGame.Car_TA:AttachedPickup", AttributeType.FlaggedInt) , ("TAGame.Car_TA:ClubColors", AttributeType.ClubColors)+ , ("TAGame.Car_TA:ReplicatedCarScale", AttributeType.Float) , ("TAGame.Car_TA:ReplicatedDemolish_CustomFX", AttributeType.CustomDemolish) , ("TAGame.Car_TA:ReplicatedDemolish", AttributeType.Demolish) , ("TAGame.Car_TA:ReplicatedDemolishGoalExplosion", AttributeType.CustomDemolish)@@ -325,10 +340,15 @@ , ("TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound", AttributeType.FlaggedInt) , ("TAGame.GameEvent_Soccar_TA:bBallHasBeenHit", AttributeType.Boolean) , ("TAGame.GameEvent_Soccar_TA:bClubMatch", AttributeType.Boolean)+ , ("TAGame.GameEvent_Soccar_TA:bMatchEnded", AttributeType.Boolean)+ , ("TAGame.GameEvent_Soccar_TA:bNoContest", AttributeType.Boolean) , ("TAGame.GameEvent_Soccar_TA:bOverTime", AttributeType.Boolean) , ("TAGame.GameEvent_Soccar_TA:bUnlimitedTime", AttributeType.Boolean) , ("TAGame.GameEvent_Soccar_TA:GameTime", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:GameWinner", AttributeType.FlaggedInt)+ , ("TAGame.GameEvent_Soccar_TA:MatchWinner", AttributeType.FlaggedInt) , ("TAGame.GameEvent_Soccar_TA:MaxScore", AttributeType.Int)+ , ("TAGame.GameEvent_Soccar_TA:MVP", AttributeType.FlaggedInt) , ("TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger", AttributeType.MusicStinger) , ("TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam", AttributeType.Byte) , ("TAGame.GameEvent_Soccar_TA:ReplicatedServerPerformanceState", AttributeType.Byte)@@ -338,6 +358,7 @@ , ("TAGame.GameEvent_Soccar_TA:SeriesLength", AttributeType.Int) , ("TAGame.GameEvent_Soccar_TA:SubRulesArchetype", AttributeType.FlaggedInt) , ("TAGame.GameEvent_SoccarPrivate_TA:MatchSettings", AttributeType.PrivateMatchSettings)+ , ("TAGame.GameEvent_TA:bAllowReadyUp", AttributeType.Boolean) , ("TAGame.GameEvent_TA:bCanVoteToForfeit", AttributeType.Boolean) , ("TAGame.GameEvent_TA:bHasLeaveMatchPenalty", AttributeType.Boolean) , ("TAGame.GameEvent_TA:BotSkill", AttributeType.Int)@@ -385,6 +406,7 @@ , ("TAGame.PRI_TA:PrimaryTitle", AttributeType.Title) , ("TAGame.PRI_TA:ReplicatedGameEvent", AttributeType.FlaggedInt) , ("TAGame.PRI_TA:ReplicatedWorstNetQualityBeyondLatency", AttributeType.Byte)+ , ("TAGame.PRI_TA:RepStatTitles", AttributeType.RepStatTitle) , ("TAGame.PRI_TA:SecondaryTitle", AttributeType.Title) , ("TAGame.PRI_TA:SkillTier", AttributeType.FlaggedByte) , ("TAGame.PRI_TA:SpectatorShortcut", AttributeType.Int)@@ -416,6 +438,7 @@ , ("TAGame.Team_TA:GameEvent", AttributeType.FlaggedInt) , ("TAGame.Team_TA:LogoData", AttributeType.FlaggedInt) , ("TAGame.Vehicle_TA:bDriving", AttributeType.Boolean)+ , ("TAGame.Vehicle_TA:bPodiumMode", AttributeType.Boolean) , ("TAGame.Vehicle_TA:bReplicatedHandbrake", AttributeType.Boolean) , ("TAGame.Vehicle_TA:ReplicatedSteer", AttributeType.Byte) , ("TAGame.Vehicle_TA:ReplicatedThrottle", AttributeType.Byte)
+ src/lib/Rattletrap/Type/Attribute/RepStatTitle.hs view
@@ -0,0 +1,56 @@+module Rattletrap.Type.Attribute.RepStatTitle where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Attribute.FlaggedInt as FlaggedInt+import qualified Rattletrap.Type.Str as Str+import qualified Rattletrap.Type.U32 as U32+import qualified Rattletrap.Utility.Json as Json++data RepStatTitle = RepStatTitle+ { unknown :: Bool+ , name :: Str.Str+ , target :: FlaggedInt.FlaggedInt+ , value :: U32.U32+ }+ deriving (Eq, Show)++instance Json.FromJSON RepStatTitle where+ parseJSON = Json.withObject "RepStatTitle" $ \object -> do+ unknown <- Json.required object "unknown"+ name <- Json.required object "name"+ target <- Json.required object "target"+ value <- Json.required object "value"+ pure RepStatTitle { unknown, name, target, value }++instance Json.ToJSON RepStatTitle where+ toJSON x = Json.object+ [ Json.pair "unknown" $ unknown x+ , Json.pair "name" $ name x+ , Json.pair "target" $ target x+ , Json.pair "value" $ value x+ ]++schema :: Schema.Schema+schema = Schema.named "attribute-rep-stat-title" $ Schema.object+ [ (Json.pair "unknown" $ Schema.ref Schema.boolean, True)+ , (Json.pair "name" $ Schema.ref Str.schema, True)+ , (Json.pair "target" $ Schema.ref FlaggedInt.schema, True)+ , (Json.pair "value" $ Schema.ref U32.schema, True)+ ]++bitPut :: RepStatTitle -> BitPut.BitPut+bitPut x =+ BitPut.bool (unknown x)+ <> Str.bitPut (name x)+ <> FlaggedInt.bitPut (target x)+ <> U32.bitPut (value x)++bitGet :: BitGet.BitGet RepStatTitle+bitGet = BitGet.label "RepStatTitle" $ do+ unknown <- BitGet.label "unknown" BitGet.bool+ name <- BitGet.label "name" Str.bitGet+ target <- BitGet.label "target" FlaggedInt.bitGet+ value <- BitGet.label "value" U32.bitGet+ pure RepStatTitle { unknown, name, target, value }
+ src/lib/Rattletrap/Type/Attribute/Rotation.hs view
@@ -0,0 +1,28 @@+module Rattletrap.Type.Attribute.Rotation where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.Int8Vector as Int8Vector+import qualified Rattletrap.Utility.Json as Json++newtype Rotation = Rotation+ { value :: Int8Vector.Int8Vector+ } deriving (Eq, Show)++instance Json.FromJSON Rotation where+ parseJSON = fmap Rotation . Json.parseJSON++instance Json.ToJSON Rotation where+ toJSON = Json.toJSON . value++schema :: Schema.Schema+schema = Schema.named "attribute-rotation" $ Schema.ref Int8Vector.schema++bitPut :: Rotation -> BitPut.BitPut+bitPut = Int8Vector.bitPut . value++bitGet :: BitGet.BitGet Rotation+bitGet = BitGet.label "Rotation" $ do+ value <- BitGet.label "value" Int8Vector.bitGet+ pure Rotation { value }
src/lib/Rattletrap/Type/AttributeType.hs view
@@ -31,8 +31,10 @@ | PlayerHistoryKey | PrivateMatchSettings | QWord+ | RepStatTitle | Reservation | RigidBodyState+ | Rotation | StatEvent | String | TeamPaint
src/lib/Rattletrap/Type/AttributeValue.hs view
@@ -37,8 +37,10 @@ import qualified Rattletrap.Type.Attribute.PlayerHistoryKey as PlayerHistoryKey import qualified Rattletrap.Type.Attribute.PrivateMatchSettings as PrivateMatchSettings import qualified Rattletrap.Type.Attribute.QWord as QWord+import qualified Rattletrap.Type.Attribute.RepStatTitle as RepStatTitle import qualified Rattletrap.Type.Attribute.Reservation as Reservation import qualified Rattletrap.Type.Attribute.RigidBodyState as RigidBodyState+import qualified Rattletrap.Type.Attribute.Rotation as Rotation import qualified Rattletrap.Type.Attribute.StatEvent as StatEvent import qualified Rattletrap.Type.Attribute.String as String import qualified Rattletrap.Type.Attribute.TeamPaint as TeamPaint@@ -82,8 +84,10 @@ | PlayerHistoryKey PlayerHistoryKey.PlayerHistoryKey | PrivateMatchSettings PrivateMatchSettings.PrivateMatchSettings | QWord QWord.QWord+ | RepStatTitle RepStatTitle.RepStatTitle | Reservation Reservation.Reservation | RigidBodyState RigidBodyState.RigidBodyState+ | Rotation Rotation.Rotation | StatEvent StatEvent.StatEvent | String String.String | TeamPaint TeamPaint.TeamPaint@@ -124,8 +128,10 @@ , fmap PlayerHistoryKey $ Json.required object "player_history_key" , fmap PrivateMatchSettings $ Json.required object "private_match_settings" , fmap QWord $ Json.required object "q_word"+ , fmap RepStatTitle $ Json.required object "rep_stat_title" , fmap Reservation $ Json.required object "reservation" , fmap RigidBodyState $ Json.required object "rigid_body_state"+ , fmap Rotation $ Json.required object "rotation" , fmap StatEvent $ Json.required object "stat_event" , fmap String $ Json.required object "string" , fmap TeamPaint $ Json.required object "team_paint"@@ -167,8 +173,10 @@ PrivateMatchSettings y -> Json.object [Json.pair "private_match_settings" y] QWord y -> Json.object [Json.pair "q_word" y]+ RepStatTitle y -> Json.object [Json.pair "rep_stat_title" y] Reservation y -> Json.object [Json.pair "reservation" y] RigidBodyState y -> Json.object [Json.pair "rigid_body_state" y]+ Rotation y -> Json.object [Json.pair "rotation" y] StatEvent y -> Json.object [Json.pair "stat_event" y] String y -> Json.object [Json.pair "string" y] TeamPaint y -> Json.object [Json.pair "team_paint" y]@@ -209,8 +217,10 @@ , ("player_history_key", PlayerHistoryKey.schema) , ("private_match_settings", PrivateMatchSettings.schema) , ("q_word", QWord.schema)+ , ("rep_stat_title", RepStatTitle.schema) , ("reservation", Reservation.schema) , ("rigid_body_state", RigidBodyState.schema)+ , ("rotation", Rotation.schema) , ("stat_event", StatEvent.schema) , ("string", String.schema) , ("team_paint", TeamPaint.schema)@@ -251,8 +261,10 @@ PlayerHistoryKey x -> PlayerHistoryKey.bitPut x PrivateMatchSettings x -> PrivateMatchSettings.bitPut x QWord x -> QWord.bitPut x+ RepStatTitle x -> RepStatTitle.bitPut x Reservation x -> Reservation.bitPut x RigidBodyState x -> RigidBodyState.bitPut x+ Rotation x -> Rotation.bitPut x StatEvent x -> StatEvent.bitPut x String x -> String.bitPut x TeamPaint x -> TeamPaint.bitPut x@@ -308,9 +320,11 @@ 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
src/lib/Rattletrap/Type/Property/Byte.hs view
@@ -31,7 +31,9 @@ byteGet :: ByteGet.ByteGet Byte byteGet = ByteGet.label "Byte" $ do key <- ByteGet.label "key" Str.byteGet- value <- ByteGet.label "value" $ Monad.whenMaybe- (Str.toString key /= "OnlinePlatform_Steam")- Str.byteGet+ let+ isSteam = key == Str.fromString "OnlinePlatform_Steam"+ isPlayStation = key == Str.fromString "OnlinePlatform_PS4"+ value <- ByteGet.label "value"+ $ Monad.whenMaybe (not $ isSteam || isPlayStation) Str.byteGet pure Byte { key, value }
src/lib/Rattletrap/Type/RemoteId.hs view
@@ -8,6 +8,7 @@ import qualified Rattletrap.Type.RemoteId.Epic as Epic import qualified Rattletrap.Type.RemoteId.PlayStation as PlayStation import qualified Rattletrap.Type.RemoteId.PsyNet as PsyNet+import qualified Rattletrap.Type.RemoteId.QQ as QQ import qualified Rattletrap.Type.RemoteId.Splitscreen as Splitscreen import qualified Rattletrap.Type.RemoteId.Steam as Steam import qualified Rattletrap.Type.RemoteId.Switch as Switch@@ -19,6 +20,7 @@ data RemoteId = PlayStation PlayStation.PlayStation | PsyNet PsyNet.PsyNet+ | QQ QQ.QQ | Splitscreen Splitscreen.Splitscreen -- ^ Really only 24 bits. | Steam Steam.Steam@@ -31,6 +33,7 @@ parseJSON = Json.withObject "RemoteId" $ \object -> Foldable.asum [ fmap PlayStation $ Json.required object "play_station" , fmap PsyNet $ Json.required object "psy_net"+ , fmap QQ $ Json.required object "qq" , fmap Splitscreen $ Json.required object "splitscreen" , fmap Steam $ Json.required object "steam" , fmap Switch $ Json.required object "switch"@@ -42,6 +45,7 @@ toJSON x = case x of PlayStation y -> Json.object [Json.pair "play_station" y] PsyNet y -> Json.object [Json.pair "psy_net" y]+ QQ y -> Json.object [Json.pair "qq" y] Splitscreen y -> Json.object [Json.pair "splitscreen" y] Steam y -> Json.object [Json.pair "steam" y] Switch y -> Json.object [Json.pair "switch" y]@@ -53,6 +57,7 @@ (\(k, v) -> Schema.object [(Json.pair k v, True)]) [ ("play_station", Schema.ref PlayStation.schema) , ("psy_net", Schema.ref PsyNet.schema)+ , ("qq", Schema.ref QQ.schema) , ("splitscreen", Schema.ref Splitscreen.schema) , ("steam", Schema.ref Steam.schema) , ("switch", Schema.ref Switch.schema)@@ -64,6 +69,7 @@ bitPut remoteId = case remoteId of PlayStation x -> PlayStation.bitPut x PsyNet x -> PsyNet.bitPut x+ QQ x -> QQ.bitPut x Splitscreen x -> Splitscreen.bitPut x Steam x -> Steam.bitPut x Switch x -> Switch.bitPut x@@ -76,6 +82,7 @@ 1 -> fmap Steam Steam.bitGet 2 -> fmap PlayStation $ PlayStation.bitGet version 4 -> fmap Xbox Xbox.bitGet+ 5 -> fmap QQ QQ.bitGet 6 -> fmap Switch Switch.bitGet 7 -> fmap PsyNet $ PsyNet.bitGet version 11 -> fmap Epic Epic.bitGet
+ src/lib/Rattletrap/Type/RemoteId/QQ.hs view
@@ -0,0 +1,32 @@+module Rattletrap.Type.RemoteId.QQ where++import qualified Rattletrap.BitGet as BitGet+import qualified Rattletrap.BitPut as BitPut+import qualified Rattletrap.Schema as Schema+import qualified Rattletrap.Type.U64 as U64+import qualified Rattletrap.Utility.Json as Json++newtype QQ+ = QQ U64.U64+ deriving (Eq, Show)++instance Json.FromJSON QQ where+ parseJSON = fmap fromU64 . Json.parseJSON++instance Json.ToJSON QQ where+ toJSON = Json.toJSON . toU64++fromU64 :: U64.U64 -> QQ+fromU64 = QQ++toU64 :: QQ -> U64.U64+toU64 (QQ x) = x++schema :: Schema.Schema+schema = U64.schema++bitPut :: QQ -> BitPut.BitPut+bitPut = U64.bitPut . toU64++bitGet :: BitGet.BitGet QQ+bitGet = BitGet.label "QQ" $ fmap fromU64 U64.bitGet
src/lib/Rattletrap/Type/Replication/Spawned.hs view
@@ -118,7 +118,9 @@ hasNameIndex :: Maybe Str.Str -> Version.Version -> Bool hasNameIndex matchType version =- Version.atLeast 868 14 0 version && matchType /= Just (Str.fromString "Lan")+ Version.atLeast 868 20 0 version+ || Version.atLeast 868 14 0 version+ && (matchType /= Just (Str.fromString "Lan")) lookupName :: ClassAttributeMap.ClassAttributeMap
src/lib/Rattletrap/Utility/Json.hs view
@@ -2,7 +2,6 @@ {-# OPTIONS_GHC -Wno-orphans #-} {- hlint ignore "Avoid restricted extensions" -}-{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} module Rattletrap.Utility.Json@@ -18,31 +17,16 @@ import qualified Data.Aeson as Aeson import qualified Data.Aeson.Encode.Pretty as Aeson+import qualified Data.Aeson.Key as Key import qualified Data.Aeson.Types as Aeson import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as LazyByteString -# if MIN_VERSION_aeson(2, 0, 0)--import qualified Data.Aeson.Key as Key- toKey :: String -> Key.Key toKey = Key.fromString fromKey :: Key.Key -> String fromKey = Key.toString--# else--import qualified Data.Text as Text--toKey :: String -> Text.Text-toKey = Text.pack--fromKey :: Text.Text -> String-fromKey = Text.unpack--# endif instance Aeson.KeyValue (String, Aeson.Value) where k .= v = (fromKey k, Aeson.toJSON v)
src/test/Main.hs view
@@ -52,9 +52,11 @@ replays = [ ("0008", "a flip time") -- https://github.com/tfausak/rattletrap/commit/ee7afa0 , ("000b", "nintendo switch") -- https://github.com/tfausak/rattletrap/pull/60+ , ("0121", "RLCS 2") -- https://github.com/nickbabcock/boxcars/pull/120 , ("0416", "v1.78 demolition") -- https://github.com/tfausak/rattletrap/pull/164 , ("07e9", "a game mode before Neo Tokyo") -- https://github.com/tfausak/rattletrap/commit/b806f9b , ("0ad2", "some Latin-1 text") -- https://github.com/tfausak/rattletrap/commit/13a8b2d+ , ("0ca5", "with QQ remote ID") -- https://github.com/nickbabcock/boxcars/pull/69 , ("0e76", "v1.95 rumble") -- https://github.com/tfausak/rattletrap/pull/237 , ("1205", "rumble mode") -- https://github.com/tfausak/rattletrap/commit/5256500 , ("160c", "a dedicated server IP") -- https://github.com/tfausak/rattletrap/commit/5c64a6d@@ -87,12 +89,15 @@ , ("419a", "a club match") -- https://github.com/tfausak/rattletrap/commit/8e35043 , ("42f0", "reservations after Neo Tokyo") -- https://github.com/tfausak/rattletrap/commit/163684f , ("42f2", "anniversary ball") -- https://github.com/tfausak/rattletrap/issues/147+ , ("43a9", "tutorial") -- https://github.com/nickbabcock/boxcars/pull/70 , ("4bc3", "with timed out attribute") -- https://github.com/tfausak/rattletrap/pull/98 , ("504e", "some messages") -- https://github.com/tfausak/rattletrap/commit/1d4a538+ , ("5123", "rep stat title") -- https://github.com/nickbabcock/boxcars/pull/78 , ("520e", "no pickup attribute") -- https://github.com/tfausak/rattletrap/pull/38 , ("524f", "quat edge case") -- https://github.com/tfausak/rattletrap/pull/87 , ("52aa", "a match-ending attribute") -- https://github.com/tfausak/rattletrap/commit/5c64a6d , ("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 , ("5a06", "esports items") -- https://github.com/tfausak/rattletrap/pull/114 , ("5e0b", "max channels") -- https://github.com/tfausak/rattletrap/issues/254@@ -105,6 +110,7 @@ , ("7083", "weird basketball capitalization") -- https://github.com/tfausak/rattletrap/pull/63 , ("7109", "a boost modifier") -- https://github.com/tfausak/rattletrap/commit/ee7afa0 , ("7256", "special edition") -- https://github.com/tfausak/rattletrap/pull/103+ , ("7588", "another malformed byte property") -- https://github.com/nickbabcock/boxcars/pull/68 , ("75ce", "primary and secondary titles") -- https://github.com/tfausak/rattletrap/pull/69 , ("7bf6", "an online loadouts attribute") -- https://github.com/tfausak/rattletrap/commit/89d02f7 , ("81d1", "gridiron") -- https://github.com/tfausak/rattletrap/pull/180@@ -128,10 +134,12 @@ , ("a7f0", "a ready attribute") -- https://github.com/tfausak/rattletrap/commit/78af1fd , ("a9df", "salty shores patch 1.45") -- https://github.com/tfausak/rattletrap/pull/78 , ("aa70", "patch 1.50 - TitleID attribute") -- https://github.com/tfausak/rattletrap/pull/93+ , ("ae46", "mvp") -- https://github.com/nickbabcock/boxcars/pull/80 , ("afb1", "patch 1.37") -- https://github.com/tfausak/rattletrap/pull/48 , ("b9f9", "a party leader") -- https://github.com/tfausak/rattletrap/commit/bba2cfd , ("c14f", "some mutators") -- https://github.com/tfausak/rattletrap/commit/bba2cfd , ("c23b", "new psynet id") -- https://github.com/tfausak/rattletrap/pull/118+ , ("c62c", "more boolean attributes") -- https://github.com/nickbabcock/boxcars/pull/77 , ("c837", "a spectator") -- https://github.com/tfausak/rattletrap/commit/bba2cfd , ("cc4c", "after Starbase ARC") -- https://github.com/tfausak/rattletrap/pull/20 , ("d044", "hoops mutators") -- https://github.com/tfausak/rattletrap/pull/34@@ -140,6 +148,7 @@ , ("d428", "a private hockey match") -- https://github.com/tfausak/rattletrap/commit/4c104b2 , ("d44c", "ranked tournament") -- https://github.com/tfausak/rattletrap/pull/167 , ("d52e", "psynet system id") -- https://github.com/tfausak/rattletrap/pull/99+ , ("d5d6", "health max") -- https://github.com/nickbabcock/boxcars/pull/80 , ("d7fb", "an explosion attribute") -- https://github.com/tfausak/rattletrap/commit/c554e3e , ("d818", "heatseeker") -- https://github.com/tfausak/rattletrap/pull/160 , ("db70", "new lag indicator") -- https://github.com/tfausak/rattletrap/pull/69@@ -147,6 +156,7 @@ , ("dcb3", "a pawn type attribute") -- https://github.com/tfausak/rattletrap/commit/7d7f438 , ("dd14", "v1.88") -- https://github.com/tfausak/rattletrap/pull/170 , ("de56", "a problematic product attribute") -- https://github.com/tfausak/rattletrap/issues/51+ , ("e2f9", "bTearOff") -- https://github.com/nickbabcock/boxcars/pull/76 , ("e80d", "unlimited time") -- https://github.com/tfausak/rattletrap/pull/76 , ("e978", "distracted") -- https://github.com/tfausak/rattletrap/issues/156 , ("eae3", "an actor/object ID collision") -- https://github.com/tfausak/rattletrap/commit/d8fad06