dtab 1.1.0.1 → 1.1.1.1
raw patch · 7 files changed
+88/−40 lines, 7 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Data.DTA: hFromDTBv2 :: Handle -> IO DTA
Files
- CHANGES.md +10/−0
- Main.hs +12/−5
- dtab.cabal +3/−3
- src/Data/DTA.hs +6/−1
- src/Data/DTA/Base.hs +45/−22
- src/Data/DTA/Lex.x +11/−8
- src/Data/DTA/PrettyPrint.hs +1/−1
CHANGES.md view
@@ -1,3 +1,13 @@+1.1.1.1++* Fix variables with certain characters being incorrectly parsed as symbols+* Fix description of new-style encryption in usage text++1.1.1++* Fix parsing various non-alphanumeric characters in unquoted keywords+* Add separate binary->text mode for new DTBs seen in Fantasia: Music Evolved+ 1.1.0.1 * Fix handling of newlines in printing and lexing `.dta`
Main.hs view
@@ -15,8 +15,9 @@ (mode : fin : fout : rest) -> withHandleIn fin $ \hin -> withHandleOut fout $ \hout -> case mode of- "-a" -> hFromDTB hin >>= hToDTA hout- "-b" -> hFromDTA hin >>= hToDTB hout . renumberFrom 1+ "-a" -> hFromDTB hin >>= hToDTA hout+ "-A" -> hFromDTBv2 hin >>= hToDTA hout+ "-b" -> hFromDTA hin >>= hToDTB hout . renumberFrom 1 "-d" -> decryptHandle newCrypt hin hout "-e" -> encryptHandle newCrypt key hin hout "-D" -> decryptHandle oldCrypt hin hout@@ -39,13 +40,19 @@ printUsage = do let v = showVersion version mapM_ (IO.hPutStrLn IO.stderr)- [ "dtab v"++v++", by onyxite. Built on earlier work by xorloser and deimos."+ [ "dtab v"++v++", by onyxite. Built on earlier work by xorloser, deimos, and maxton." , "Usage: dtab mode file-in file-out [encrypt-key]"- , "Modes: -a converts DTB (binary) to DTA (text)"+ , ""+ , "RB3 and earlier text/binary conversion:"+ , " -a converts DTB (binary) to DTA (text)" , " -b converts DTA (text) to DTB (binary)"+ , "Post-RB3 text/binary conversion:"+ , " -A converts new format DTB (binary) to DTA (text)"+ , "GH2 360 and later encryption:" , " -d decrypts new-style DTB" , " -e encrypts new-style DTB, with optional key"+ , "Pre-360 encryption:" , " -D decrypts old-style DTB" , " -E encrypts old-style DTB, with optional key"- , "Old-style is used in early PS2 games, new-style otherwise."+ , "" , "Use a hyphen (-) for stdin (file-in) or stdout (file-out)." ]
dtab.cabal view
@@ -1,5 +1,5 @@ name: dtab-version: 1.1.0.1+version: 1.1.1.1 synopsis: Harmonix (Guitar Hero, Rock Band) DTA/DTB metadata library description: @@ -18,7 +18,7 @@ library build-depends:- base >= 4.6 && < 4.12+ base >= 4.6 && < 5 , bytestring >= 0.10.0.2 , transformers >= 0.3.0.0 , data-binary-ieee754 >= 0.4.4@@ -41,7 +41,7 @@ Executable dtab build-depends:- base >= 4.6 && < 4.12+ base >= 4.6 && < 5 , bytestring >= 0.10.0.2 , dtab other-modules: Paths_dtab
src/Data/DTA.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE CPP #-} module Data.DTA ( DTA(..), Tree(..), Chunk(..)-, lFromDTB, hFromDTB, fromDTB+, lFromDTB, hFromDTB, hFromDTBv2, fromDTB , lToDTB, hToDTB, toDTB , sFromDTA, hFromDTA, fromDTA , sToDTA, hToDTA, toDTA@@ -17,6 +17,7 @@ withFile) import Data.Binary (decode, encode)+import Data.Binary.Get (runGet) import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as BL@@ -37,6 +38,10 @@ hFromDTB :: Handle -> IO DTA hFromDTB h = decode . strictToLazy <$> B.hGetContents h+ where strictToLazy b = BL.fromChunks [b]++hFromDTBv2 :: Handle -> IO DTA+hFromDTBv2 h = runGet (binaryDTA DTAVersion2) . strictToLazy <$> B.hGetContents h where strictToLazy b = BL.fromChunks [b] toDTB :: FilePath -> DTA -> IO ()
src/Data/DTA/Base.hs view
@@ -3,6 +3,7 @@ module Data.DTA.Base ( DTA(..), Tree(..), Chunk(..) , renumberFrom+, binaryDTA, DTAVersion(..) ) where #if __GLASGOW_HASKELL__ < 710@@ -61,21 +62,60 @@ -- Binary (DTB) instances -- +data DTAVersion+ = DTAVersion1 -- ^ everything before and including RB3 AFAIK+ | DTAVersion2 -- ^ seen in Fantasia: Music Evolved++binaryDTA :: DTAVersion -> Get DTA+binaryDTA version = liftA2 DTA get (binaryTree version)+ -- Single byte, then a tree. instance Binary DTA where put (DTA b t) = put b >> put t- get = liftA2 DTA get get+ get = binaryDTA DTAVersion1 +binaryTree :: DTAVersion -> Get Tree+binaryTree version = case version of+ DTAVersion1 -> do+ len <- getWord16le+ nid <- getWord32le+ xs <- replicateM (fromIntegral len) (binaryChunk version)+ return $ Tree nid xs+ DTAVersion2 -> do+ _unk <- getWord32le -- always zero?+ len <- getWord32le+ nid <- fromIntegral <$> getWord16le+ xs <- replicateM (fromIntegral len) (binaryChunk version)+ return $ Tree nid xs+ -- 2-byte length, 4-byte node ID, then each element in sequence. instance Binary Tree where put (Tree nid chks) = do putWord16le $ fromIntegral $ length chks putWord32le nid mapM_ put chks- get = do- len <- getWord16le- liftA2 Tree getWord32le $ replicateM (fromIntegral len) get+ get = binaryTree DTAVersion1 +binaryChunk :: DTAVersion -> Get Chunk+binaryChunk version = getWord32le >>= \cid -> case cid of+ 0x0 -> Int . fromIntegral <$> getWord32le+ 0x1 -> Float <$> getFloat32le+ 0x2 -> Var <$> getLenStr+ 0x5 -> Key <$> getLenStr+ 0x6 -> skip 4 >> return Unhandled+ 0x7 -> IfDef <$> getLenStr+ 0x8 -> skip 4 >> return Else+ 0x9 -> skip 4 >> return EndIf+ 0x10 -> Parens <$> binaryTree version+ 0x11 -> Braces <$> binaryTree version+ 0x12 -> String <$> getLenStr+ 0x13 -> Brackets <$> binaryTree version+ 0x20 -> Define <$> getLenStr+ 0x21 -> Include <$> getLenStr+ 0x22 -> Merge <$> getLenStr+ 0x23 -> IfNDef <$> getLenStr+ _ -> fail $ "Unidentified DTB chunk with ID " ++ show cid+ -- 4-byte chunk type ID, then at least 4 bytes of chunk data. instance Binary Chunk where put c = case c of@@ -95,24 +135,7 @@ Include b -> putWord32le 0x21 >> putLenStr b Merge b -> putWord32le 0x22 >> putLenStr b IfNDef b -> putWord32le 0x23 >> putLenStr b- get = getWord32le >>= \cid -> case cid of- 0x0 -> Int . fromIntegral <$> getWord32le- 0x1 -> Float <$> getFloat32le- 0x2 -> Var <$> getLenStr- 0x5 -> Key <$> getLenStr- 0x6 -> skip 4 >> return Unhandled- 0x7 -> IfDef <$> getLenStr- 0x8 -> skip 4 >> return Else- 0x9 -> skip 4 >> return EndIf- 0x10 -> Parens <$> get- 0x11 -> Braces <$> get- 0x12 -> String <$> getLenStr- 0x13 -> Brackets <$> get- 0x20 -> Define <$> getLenStr- 0x21 -> Include <$> getLenStr- 0x22 -> Merge <$> getLenStr- 0x23 -> IfNDef <$> getLenStr- _ -> fail $ "Unidentified DTB chunk with ID " ++ show cid+ get = binaryChunk DTAVersion1 -- | DTB string format: 4-byte length, then a string in latin-1. putLenStr :: B.ByteString -> Put
src/Data/DTA/Lex.x view
@@ -10,7 +10,6 @@ %wrapper "posn" $digit = 0-9-$alpha = [a-zA-Z] tokens :- @@ -30,20 +29,24 @@ -- Numbers. Longest match rule means N.N is float, not int. (\+ | \-)? $digit+ { \pn str -> (pn, Int $ read $ dropWhile (== '+') str) } (\+ | \-)? $digit+ (\. $digit+)? (e \-? $digit+)? { \pn str -> (pn, Float $ read $ dropWhile (== '+') str) }+(\+ | \-)? \. $digit+ (e \-? $digit+)? { \pn str -> (pn, Float $ read $ case dropWhile (== '+') str of+ '-' : rest -> '-' : '0' : rest+ s -> '0' : s+ )+} -- Variable names.-\$ ($alpha | $digit | _)+ { \pn str -> (pn, Var $ B8.pack $ tail str) }+\$ (. # $white # [ \( \) \{ \} \[ \] ])+ { \pn str -> (pn, Var $ B8.pack $ tail str) } -- This reserved word needs to come before the general keyword rule. "kDataUnhandled" { \pn _ -> (pn, Unhandled) }--- Raw keywords. Note: these can start with digits, like "3sand7s", as long as--- they also have letters in them.-($alpha | $digit | _ | \/ | \. | \- | \= | \# | \< | \>)+ { \pn str -> (pn, Key $ B8.pack str) }--- Quoted keywords.-' ([^'] | \\')* ' { \pn str -> (pn, Key $ B8.pack $ readKey str) }- -- Quoted strings. \" ([^\"] | \n)* \" { \pn str -> (pn, String $ B8.pack $ readString str) }+-- Quoted keywords.+' ([^'] | \\')* ' { \pn str -> (pn, Key $ B8.pack $ readKey str) }+-- Raw keywords. Note: these can start with digits, like "3sand7s", as long as+-- they also have letters in them.+(. # $white # [ \( \) \{ \} \[ \] ])+ { \pn str -> (pn, Key $ B8.pack str) } -- Subtrees. \( { \pn _ -> (pn, LParen) }
src/Data/DTA/PrettyPrint.hs view
@@ -48,7 +48,7 @@ -- | Produces a raw keyword or single-quoted string literal. ppKey :: String -> PP.Doc ppKey s- | all (\c -> isAlphaNum c || elem c "_/.-=#<>") s = PP.text s+ | all (\c -> isAlphaNum c || elem c "_/.-=#<>&!") s && not (null s) = PP.text s | otherwise = let -- simply convert a double-quoted string to single-quoted string f "" = ""