Last active
July 8, 2018 21:34
-
-
Save tfausak/c39fce5768727305e21a19e8e2ed9f6a to your computer and use it in GitHub Desktop.
Changes every car in a Rocket League replay to be Octane with the striped decal. Uses Rattletrap: https://github.com/tfausak/rattletrap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
-- stack --resolver nightly-2018-06-01 script --compile | |
-- To run this, first install Stack: <https://haskellstack.org>. | |
-- Then run this from the command line: `stack edit-replay.hs input.replay output.replay` | |
module Main ( main ) where | |
import qualified Data.ByteString.Lazy as L | |
import qualified Data.Map as M | |
import qualified Data.Word as W | |
import qualified Rattletrap as R | |
import qualified Rattletrap.Type.Str as R | |
import qualified System.Directory as D | |
import qualified System.Environment as E | |
import qualified System.FilePath as F | |
data Team = Blue | Orange deriving (Eq, Ord) | |
replacements :: M.Map Team (M.Map W.Word32 W.Word32) | |
replacements = M.fromList | |
[ (Blue, M.fromList | |
[ (23, 306) -- For the blue team, body 23 (Octane) should end up with decal 306 (Stripes). | |
, (403, 508) -- Add more replacements to the blue team like this. | |
]) | |
, (Orange, M.fromList | |
[ (23, 305) -- For the orange team, body 23 (Octane) should end up with decal 305 (Stars). | |
, (403, 510) -- Add more replacements to the orange team like this. | |
]) | |
] | |
-- This code is hideous. Don't judge me. | |
main :: IO () | |
main = do | |
[inputDirectory, outputDirectory] <- E.getArgs | |
inputFiles <- D.listDirectory inputDirectory | |
flip mapM_ inputFiles $ \ inputFile -> do | |
let inputPath = F.combine inputDirectory inputFile | |
let outputPath = F.combine outputDirectory inputFile | |
putStrLn $ unwords [ inputPath, "=>", outputPath ] | |
inputBytes <- L.readFile inputPath | |
inputReplay <- either fail pure $ R.decodeReplayFile inputBytes | |
let outputReplay = editReplay inputReplay | |
let outputBytes = R.encodeReplayFile outputReplay | |
L.writeFile outputPath outputBytes | |
editReplay :: R.Replay -> R.Replay | |
editReplay replay = replay | |
{ R.replayHeader = let section = R.replayHeader replay in section | |
{ R.sectionBody = let header = R.sectionBody section in header | |
{ R.headerProperties = let | |
properties = R.headerProperties header | |
editDictionary k f dictionary = case dictionary of | |
R.DictionaryElement k2 v e -> R.DictionaryElement | |
k2 | |
(if R.toStr k == k2 then f v else v) | |
(editDictionary k f e) | |
R.DictionaryEnd l -> R.DictionaryEnd l | |
editProperty property = property | |
{ R.propertyValue = case R.propertyValue property of | |
R.PropertyValueStr str -> R.PropertyValueStr (R.toStr (R.fromStr str ++ " [edit]")) | |
value -> value | |
} | |
in editDictionary "ReplayName" editProperty properties | |
} | |
} | |
, R.replayContent = let section = R.replayContent replay in section | |
{ R.sectionBody = let content = R.sectionBody section in content | |
{ R.contentFrames = let | |
editFrame frame = frame | |
{ R.frameReplications = let | |
editReplication replication = replication | |
{ R.replicationValue = case R.replicationValue replication of | |
R.ReplicationValueUpdated updated -> R.ReplicationValueUpdated updated | |
{ R.updatedReplicationAttributes = let | |
editAttribute attribute = attribute | |
{ R.attributeValue = case R.attributeValue attribute of | |
R.AttributeValueLoadouts loadouts -> let | |
editLoadout team loadout = case M.lookup team replacements of | |
Nothing -> loadout | |
Just teamReplacements -> case M.lookup (R.word32leValue (R.loadoutAttributeBody loadout)) teamReplacements of | |
Nothing -> loadout | |
Just decal -> loadout { R.loadoutAttributeDecal = R.Word32le decal } | |
in R.AttributeValueLoadouts loadouts | |
{ R.loadoutsAttributeBlue = editLoadout Blue (R.loadoutsAttributeBlue loadouts) | |
, R.loadoutsAttributeOrange = editLoadout Orange (R.loadoutsAttributeOrange loadouts) | |
} | |
value -> value | |
} | |
in map editAttribute (R.updatedReplicationAttributes updated) | |
} | |
value -> value | |
} | |
in map editReplication (R.frameReplications frame) | |
} | |
in map editFrame (R.contentFrames content) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment