2022-06-19 13:20:50 +00:00
using CXMLDecompiler ;
using General ;
using Ionic.Zlib ;
using System ;
2022-09-07 05:38:41 +00:00
using System.Collections.Generic ;
2022-06-19 13:20:50 +00:00
using System.IO ;
2022-09-07 05:38:41 +00:00
using System.Linq ;
2022-06-19 13:20:50 +00:00
using System.Reflection ;
namespace CXMLCli
{
class Program
{
2022-09-07 05:38:41 +00:00
static string InputFilePath ;
static string OutputFilePath ;
static bool WaitExit = false ;
static bool ForcePs3 = false ;
static Endianness FileEndianness = Endianness . UNCHANGED ;
static bool Check = true ;
static int ArgIndex ( string [ ] args , string argshort , string arglong )
{
for ( int i = 0 ; i < args . Length ; i + + )
{
string arg = args [ i ] ;
if ( arg . ToLowerInvariant ( ) = = argshort . ToLowerInvariant ( ) | | arg . ToLowerInvariant ( ) = = arglong . ToLowerInvariant ( ) )
{
return i ;
}
}
return - 1 ;
}
static bool HasArg ( string [ ] args , string argcheck )
2022-06-19 13:20:50 +00:00
{
foreach ( string arg in args )
{
2022-09-07 05:38:41 +00:00
if ( arg . ToLowerInvariant ( ) = = argcheck . ToLowerInvariant ( ) )
2022-06-19 13:20:50 +00:00
{
return true ;
}
}
return false ;
}
2022-09-07 05:38:41 +00:00
static string GetTablesFolder ( )
{
string tablesFolder = Path . GetFileNameWithoutExtension ( OutputFilePath ) + "_tables" ;
if ( ! Directory . Exists ( tablesFolder ) )
Directory . CreateDirectory ( tablesFolder ) ;
return tablesFolder ;
}
2022-06-19 13:20:50 +00:00
static int Main ( string [ ] args )
{
2022-09-07 05:38:41 +00:00
// Check if the user has GimConv and download it if not present
// (only do this on windows)
2022-06-19 13:20:50 +00:00
bool windowsNT = Environment . OSVersion . Platform . Equals ( PlatformID . Win32NT ) ;
bool windows32 = Environment . OSVersion . Platform . Equals ( PlatformID . Win32Windows ) ;
bool windows32S = Environment . OSVersion . Platform . Equals ( PlatformID . Win32S ) ;
bool windowsCE = Environment . OSVersion . Platform . Equals ( PlatformID . WinCE ) ;
if ( windowsNT | | windows32 | | windows32S | | windowsCE )
{
2022-09-07 05:38:41 +00:00
if ( ! GimConv . HasGimConv ( ) )
{
GimConv . DownloadGimConv ( ) ; // Politely ask sony to give it to us.
}
}
else
{
Console . WriteLine ( "NOTE: GimConv is windows binary (provided by Sony Computer Entertainment), so you cant use it on this OS!\n.GIM Decoding will be disabled!" ) ;
}
2022-06-19 13:20:50 +00:00
if ( args . Length = = 0 )
{
Console . WriteLine ( "-- CXML Decompiler --" ) ;
Console . WriteLine ( "Required Arguments:" ) ;
2022-09-07 05:38:41 +00:00
Console . WriteLine ( "\t-i --input Input file or folder" ) ;
Console . WriteLine ( "\t-o --output Output file or folder" ) ;
2022-06-19 13:20:50 +00:00
Console . WriteLine ( "Optional Arguments:" ) ;
Console . WriteLine ( "\t-iv --is-vag File is HE-VAG audio and NOT CXML" ) ;
Console . WriteLine ( "\t-dc --decompress Decompress .Z File" ) ;
Console . WriteLine ( "\t-cc --compress Compress back to .Z File" ) ;
Console . WriteLine ( "\t-f --force Dont check magic number." ) ;
Console . WriteLine ( "\t-dt --dump-tables Dump ALL tables." ) ;
Console . WriteLine ( "\t-tt --dump-tree Dump tree table." ) ;
Console . WriteLine ( "\t-idt --dump-id Dump id ID table." ) ;
Console . WriteLine ( "\t-iht --dump-hash-id Dump hash ID table." ) ;
Console . WriteLine ( "\t-st --dump-string Dump string table." ) ;
Console . WriteLine ( "\t-wt --dump-wstring Dump wstring table." ) ;
Console . WriteLine ( "\t-ht --dump-hash Dump hash table." ) ;
Console . WriteLine ( "\t-iat --dump-int-array Dump int array table." ) ;
Console . WriteLine ( "\t-fat --dump-float-array Dump float array table." ) ;
Console . WriteLine ( "\t-ft --dump-file Dump file table." ) ;
Console . WriteLine ( "\t-le --little-endian Decode ints as Little Endian" ) ;
Console . WriteLine ( "\t-be --big-endian Decode ints as Big Endian" ) ;
Console . WriteLine ( "\t-ps3 --playstation-3 Use the old CXML Format used back on PS3." ) ;
Console . WriteLine ( "\t-p --process-files Process Extracted Files" ) ;
Console . WriteLine ( "\t-nr --no-recursive Do not recursively decompile .RCS to XML" ) ;
Console . WriteLine ( "\t-w --wait-exit Wait for keypress before exiting" ) ;
Console . WriteLine ( "\t-d --decompile Decompile CXML to XML." ) ;
Console . WriteLine ( "\t-c --compile Compile XML to CXML" ) ;
2022-09-07 05:38:41 +00:00
Console . WriteLine ( "\t-s --symbols Use Symbol File (.rcd)" ) ;
2022-09-07 07:26:53 +00:00
Console . WriteLine ( "Example Decompile: " + Path . GetFileName ( Assembly . GetEntryAssembly ( ) . Location ) + " -i common_resource.rco -o common_resource.xml -d -p" ) ;
Console . WriteLine ( "Example Compile: " + Path . GetFileName ( Assembly . GetEntryAssembly ( ) . Location ) + " -i common_resource.xml -o common_resource.rco -c" ) ;
2022-06-19 13:20:50 +00:00
return 0 ;
}
2022-09-07 05:38:41 +00:00
if ( args . Length = = 1 )
{
List < string > argsCopy = args . ToList ( ) ;
2022-06-19 13:20:50 +00:00
2022-09-07 05:38:41 +00:00
argsCopy . AddRange ( new string [ ] { "--input" , args [ 0 ] , "--output" , Path . ChangeExtension ( args [ 0 ] , ".xml" ) , "--decompile" , "--process-files" , "--wait-exit" } ) ;
2022-06-19 13:20:50 +00:00
2022-09-07 05:38:41 +00:00
if ( File . Exists ( Path . ChangeExtension ( args [ 0 ] , ".rcd" ) ) )
argsCopy . AddRange ( new string [ ] { "--symbols" , Path . ChangeExtension ( args [ 0 ] , ".rcd" ) } ) ;
args = argsCopy . ToArray ( ) ;
}
if ( HasArg ( args , "-i" ) | | HasArg ( args , "--input" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
int i = ArgIndex ( args , "-i" , "--input" ) ;
InputFilePath = args [ i + 1 ] ;
}
else
{
Console . Error . WriteLine ( "Missing required -i or --input argument." ) ;
return 1 ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-o" ) | | HasArg ( args , "--output" ) )
{
int i = ArgIndex ( args , "-o" , "--output" ) ;
OutputFilePath = args [ i + 1 ] ;
}
else
{
Console . Error . WriteLine ( "Missing required -o or --output." ) ;
return 1 ;
}
if ( HasArg ( args , "-le" ) | | HasArg ( args , "--little-endian" ) )
2022-06-19 13:20:50 +00:00
{
FileEndianness = Endianness . LITTLE_ENDIAN ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-be" ) | | HasArg ( args , "--big-endian" ) )
2022-06-19 13:20:50 +00:00
{
FileEndianness = Endianness . LITTLE_ENDIAN ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-ps3" ) | | HasArg ( args , "--playstation-3" ) )
2022-06-19 13:20:50 +00:00
{
ForcePs3 = true ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-iv" ) | | HasArg ( args , "--is-vag" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
byte [ ] WaveData = VAG . VAGAudio . Vag2Wav ( InputFilePath ) ;
Console . WriteLine ( "Writing " + OutputFilePath ) ;
File . WriteAllBytes ( OutputFilePath , WaveData ) ;
2022-06-19 13:20:50 +00:00
return 0 ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-f" ) | | HasArg ( args , "--force" ) )
2022-06-19 13:20:50 +00:00
{
Check = false ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-dc" ) | | HasArg ( args , "--decompress" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
Console . WriteLine ( "Decompressing " + InputFilePath ) ;
Byte [ ] FileData = File . ReadAllBytes ( InputFilePath ) ;
2022-06-19 13:20:50 +00:00
Byte [ ] DecompressedData = ZlibStream . UncompressBuffer ( FileData ) ;
string Extension = Tools . GetFileExtension ( DecompressedData ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( OutputFilePath , DecompressedData ) ;
2022-06-19 13:20:50 +00:00
return 0 ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-cc" ) | | HasArg ( args , "--compress" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
Console . WriteLine ( "Compressing " + InputFilePath ) ;
Byte [ ] FileData = File . ReadAllBytes ( InputFilePath ) ;
2022-06-19 13:20:50 +00:00
Byte [ ] CompressedData = ZlibStream . CompressBuffer ( FileData ) ;
string Extension = Tools . GetFileExtension ( CompressedData ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( OutputFilePath , CompressedData ) ;
2022-06-19 13:20:50 +00:00
return 0 ;
}
CXMLReader cxmlParser = new CXMLReader ( ) ;
2022-09-07 05:38:41 +00:00
if ( ! HasArg ( args , "-c" ) & & ! HasArg ( args , "--compile" ) ) // If not Compiling
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
Console . WriteLine ( "Initalizing: " + InputFilePath ) ;
cxmlParser . Init ( InputFilePath , OutputFilePath , Check , ForcePs3 , FileEndianness ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-dt" ) | | HasArg ( args , "--dump-tables" ) )
{
List < string > argsCopy = args . ToList ( ) ;
2022-06-19 13:20:50 +00:00
2022-09-07 05:38:41 +00:00
argsCopy . AddRange ( new string [ ] { "--dump-tree" , "--dump-id" , "--dump-hash-id" , "--dump-string" , "--dump-wstring" , "--dump-hash" , "--dump-int-array" , "--dump-float-array" , "--dump-file" } ) ;
2022-06-19 13:20:50 +00:00
2022-09-07 05:38:41 +00:00
args = argsCopy . ToArray ( ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-tt" ) | | HasArg ( args , "--dump-tree" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
2022-06-19 13:20:50 +00:00
Console . WriteLine ( "Dumping tree table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "tree-table.bin" ) , cxmlParser . GetTreeTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-idt" ) | | HasArg ( args , "--dump-id" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
2022-06-19 13:20:50 +00:00
Console . WriteLine ( "Dumping ID table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "id-table.bin" ) , cxmlParser . GetIDTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-iht" ) | | HasArg ( args , "--dump-hash-id" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping hash ID table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "hash-id-table.bin" ) , cxmlParser . GetHashIDTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-st" ) | | HasArg ( args , "--dump-string" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping string table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "string-table.bin" ) , cxmlParser . GetStringTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-wt" ) | | HasArg ( args , "--dump-wstring" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping wstring table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "wstring-table.bin" ) , cxmlParser . GetWStringTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-ht" ) | | HasArg ( args , "--dump-hash" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping hash table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "hash-table.bin" ) , cxmlParser . GetHashTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-iat" ) | | HasArg ( args , "--dump-int-array" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping int array table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "int-array-table.bin" ) , cxmlParser . GetIntArrayTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-fat" ) | | HasArg ( args , "--dump-float-array" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping float array table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "float-array-table.bin" ) , cxmlParser . GetFloatArrayTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-ft" ) | | HasArg ( args , "--dump-tree" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Dumping file table." ) ;
2022-09-07 05:38:41 +00:00
File . WriteAllBytes ( Path . Combine ( GetTablesFolder ( ) , "file-table.bin" ) , cxmlParser . GetFileTable ( ) ) ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-p" ) | | HasArg ( args , "--process-files" ) )
2022-06-19 13:20:50 +00:00
{
cxmlParser . ProcessFiles = true ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-w" ) | | HasArg ( args , "--wait-exit" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
WaitExit = true ;
2022-06-19 13:20:50 +00:00
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-nr" ) | | HasArg ( args , "--no-recursive" ) )
2022-06-19 13:20:50 +00:00
{
cxmlParser . NoRecursive = true ;
}
2022-09-07 05:38:41 +00:00
if ( HasArg ( args , "-s" ) | | HasArg ( args , "--symbols" ) )
{
int i = ArgIndex ( args , "-s" , "--symbols" ) ;
CXMLSymbols . Init ( args [ i + 1 ] ) ;
}
if ( HasArg ( args , "-d" ) | | HasArg ( args , "--decompile" ) & & ! HasArg ( args , "-dt" ) )
2022-06-19 13:20:50 +00:00
{
Console . WriteLine ( "Decompiling." ) ;
2022-09-07 05:38:41 +00:00
cxmlParser . DecompileCXML ( InputFilePath , OutputFilePath ) ;
2022-06-19 13:20:50 +00:00
Console . WriteLine ( "\n\nDECOMPILATION COMPLETE!" ) ;
2022-09-07 05:38:41 +00:00
if ( WaitExit )
2022-06-19 13:20:50 +00:00
Console . ReadKey ( ) ;
}
2022-09-07 05:38:41 +00:00
else if ( HasArg ( args , "-c" ) | | HasArg ( args , "--compile" ) )
2022-06-19 13:20:50 +00:00
{
2022-09-07 05:38:41 +00:00
Console . WriteLine ( "Compiling: " + InputFilePath ) ;
2022-06-19 13:20:50 +00:00
CXMLBuilder builder = new CXMLBuilder ( ) ;
2022-09-07 05:38:41 +00:00
builder . BuildCXML ( InputFilePath , OutputFilePath ) ;
2022-06-19 13:20:50 +00:00
Console . WriteLine ( "\n\nCOMPILATION COMPLETE!" ) ;
2022-09-07 05:38:41 +00:00
if ( WaitExit )
2022-06-19 13:20:50 +00:00
Console . ReadKey ( ) ;
}
return 0 ;
}
}
}