packages feed

rattletrap 11.2.5 → 11.2.6

raw patch · 13 files changed

+189/−22 lines, 13 files

Files

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