Add support for reading RCO symbol files (.rcd)
This commit is contained in:
parent
4591a7c049
commit
308edb6c3c
|
@ -35,7 +35,6 @@ namespace CXMLDecompiler
|
|||
MemoryStream FileTable;
|
||||
|
||||
Boolean IsInitalized = false;
|
||||
public Boolean HashStrings = false;
|
||||
|
||||
|
||||
String SilicaTypingInformation = "";
|
||||
|
@ -378,11 +377,7 @@ namespace CXMLDecompiler
|
|||
Console.WriteLine("WString: " + attribute.Value);
|
||||
break;
|
||||
case AttributeType.TYPE_HASH:
|
||||
int hashId = Int32.Parse(attribute.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
|
||||
if (HashStrings)
|
||||
hashId = Int32.Parse(Tools.GenerateShortHash(Encoding.UTF8.GetBytes(attribute.Value)), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
|
||||
int hashId = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
int HashTableOffset = AddGetHashTable(hashId);
|
||||
int HashTableSize = 4;
|
||||
tools.WriteInt32(WorkRam, HashTableOffset);
|
||||
|
@ -438,9 +433,7 @@ namespace CXMLDecompiler
|
|||
Console.WriteLine("ID : " + IdTableOffset + " sz: 0");
|
||||
break;
|
||||
case AttributeType.TYPE_ID_HASH_REF:
|
||||
int hash = Int32.Parse(attribute.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
if (HashStrings)
|
||||
hash = Int32.Parse(Tools.GenerateShortHash(Encoding.UTF8.GetBytes(attribute.Value)), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
int hash = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
int HashIdTableOffset = AddGetHashIdTable(hash, Convert.ToInt32(TreeTable.Position));
|
||||
tools.WriteInt32(WorkRam, HashIdTableOffset);
|
||||
tools.WriteInt32(WorkRam, 0x00);
|
||||
|
@ -448,9 +441,7 @@ namespace CXMLDecompiler
|
|||
Console.WriteLine("Hash ID REF offset: " + HashIdTableOffset + " sz: 0");
|
||||
break;
|
||||
case AttributeType.TYPE_ID_HASH:
|
||||
hash = Int32.Parse(attribute.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
if (HashStrings)
|
||||
hash = Int32.Parse(Tools.GenerateShortHash(Encoding.UTF8.GetBytes(attribute.Value)), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
hash = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
HashIdTableOffset = AddGetHashIdTable(hash, -1);
|
||||
|
||||
tools.WriteInt32(WorkRam, HashIdTableOffset);
|
||||
|
@ -468,7 +459,7 @@ namespace CXMLDecompiler
|
|||
public void WriteElement(XmlNode node)
|
||||
{
|
||||
MemoryStream WorkRam = new MemoryStream();
|
||||
//BinaryWriter bWorkRam = new BinaryWriter(WorkRam);
|
||||
|
||||
int ElementPtr = AddGetStringTable(node.Name);
|
||||
int NumAttributes = 0;
|
||||
int ParentPtr = -1;
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<Compile Include="CXML.cs" />
|
||||
<Compile Include="CXMLReader.cs" />
|
||||
<Compile Include="CXMLBuilder.cs" />
|
||||
<Compile Include="CXMLSymbols.cs" />
|
||||
<Compile Include="GimConv.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<StartArguments>PvrResource.cxml -ps3 -le -f -d</StartArguments>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartWorkingDirectory>C:\Users\Li\Documents\git\cxml-decompiler\CXMLCli\bin\x64\Debug</StartWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -4,7 +4,6 @@ using CXML;
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
@ -14,7 +13,7 @@ namespace CXMLDecompiler
|
|||
{
|
||||
class CXMLReader
|
||||
{
|
||||
private bool _checkMagicNumber()
|
||||
private bool CheckMagicNumber()
|
||||
{
|
||||
|
||||
String Magic = Tools.ReadStringAt(InfoFile, 0x00);
|
||||
|
@ -86,12 +85,11 @@ namespace CXMLDecompiler
|
|||
|
||||
public bool ps3 = false;
|
||||
public bool ProcessFiles = false;
|
||||
public bool WaitExit = false;
|
||||
public bool NoRecursive = false;
|
||||
public void Init(string path, bool CheckMagic = true, bool forcePs3 = false, Endianness forceEndainness = Endianness.UNCHANGED)
|
||||
public void Init(string path, string outPath, bool CheckMagic = true, bool forcePs3 = false, Endianness forceEndainness = Endianness.UNCHANGED)
|
||||
{
|
||||
InfoFile = File.Open(path, FileMode.Open, FileAccess.Read);
|
||||
bool MagicValid = _checkMagicNumber();
|
||||
bool MagicValid = CheckMagicNumber();
|
||||
if (CheckMagic)
|
||||
{
|
||||
if (!MagicValid)
|
||||
|
@ -141,9 +139,9 @@ namespace CXMLDecompiler
|
|||
WStringTable = new MemoryStream();
|
||||
}
|
||||
|
||||
MainDir = Path.GetFileNameWithoutExtension(path);
|
||||
FileDir = Path.Combine(MainDir, "files");
|
||||
XMLFilename = Path.GetFileNameWithoutExtension(path) + ".xml";
|
||||
MainDir = Path.GetDirectoryName(outPath);
|
||||
FileDir = Path.Combine(MainDir, Path.GetFileNameWithoutExtension(outPath) + "_files");
|
||||
XMLFilename = Path.GetFileName(outPath);
|
||||
|
||||
IsInitalized = true;
|
||||
|
||||
|
@ -420,18 +418,11 @@ namespace CXMLDecompiler
|
|||
Align(InfoFile, 0x10);
|
||||
}
|
||||
|
||||
public void DecompileCXML(String CXMLFile)
|
||||
public void DecompileCXML(String CXMLFile, String XMLOutputFile)
|
||||
{
|
||||
|
||||
if (!IsInitalized)
|
||||
Init(CXMLFile);
|
||||
|
||||
|
||||
if (Directory.Exists(MainDir))
|
||||
Directory.Delete(MainDir, true);
|
||||
|
||||
if (!Directory.Exists(FileDir))
|
||||
Directory.CreateDirectory(FileDir);
|
||||
Init(CXMLFile, XMLOutputFile);
|
||||
|
||||
XmlWriterSettings XMLSettings = new XmlWriterSettings();
|
||||
XMLSettings.Indent = true;
|
||||
|
@ -486,9 +477,10 @@ namespace CXMLDecompiler
|
|||
string XMLData = Encoding.UTF8.GetString(XMLBytes);
|
||||
|
||||
// Resolve Replace Patterns
|
||||
|
||||
Console.WriteLine("Resolving Patterns ...");
|
||||
XMLData = XMLData.Replace(MagicReplacePattern, SilicaTypingInformation);
|
||||
foreach(LoopbackHandler lpHandler in FileList)
|
||||
|
||||
foreach (LoopbackHandler lpHandler in FileList)
|
||||
{
|
||||
if (lpHandler.ReplacePattern != null && lpHandler.OldFileName != null)
|
||||
{
|
||||
|
@ -504,26 +496,29 @@ namespace CXMLDecompiler
|
|||
|
||||
string newPath = Path.ChangeExtension(Path.Combine(folderPath, lpHandler.FileName), extension);
|
||||
|
||||
if (!Directory.Exists(folderPath))
|
||||
Directory.CreateDirectory(folderPath);
|
||||
if (!Directory.Exists(Path.GetDirectoryName(newPath)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(newPath));
|
||||
|
||||
if (!File.Exists(newPath))
|
||||
{
|
||||
File.WriteAllBytes(newPath, fileData);
|
||||
string xmlRelNewPath = newPath.Substring(Tools.GetRootFolder(newPath).Length + 1);
|
||||
Console.WriteLine("Resolved " + replacePattern + " => " + xmlRelNewPath);
|
||||
XMLData = XMLData.Replace(replacePattern, xmlRelNewPath);
|
||||
}
|
||||
string XMLRelNewPath = Path.Combine(Path.GetFileName(FileDir), "original", Path.GetFileName(newPath));
|
||||
Console.WriteLine("Resolved " + replacePattern + " => " + XMLRelNewPath);
|
||||
XMLData = XMLData.Replace(replacePattern, XMLRelNewPath);
|
||||
|
||||
if (ProcessFiles)
|
||||
ProcessFile(newPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unable to resolve: " + oldName);
|
||||
if (!File.Exists(oldName))
|
||||
if (!Directory.Exists(Path.GetDirectoryName(oldName)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(oldName));
|
||||
|
||||
File.WriteAllBytes(oldName, fileData);
|
||||
|
||||
string xmlRelNewPath = Path.Combine(Path.GetFileName(FileDir), "original", Path.GetFileName(oldName));
|
||||
Console.WriteLine("Resolved " + replacePattern + " => " + xmlRelNewPath);
|
||||
XMLData = XMLData.Replace(replacePattern, xmlRelNewPath);
|
||||
|
||||
|
||||
if (ProcessFiles)
|
||||
ProcessFile(oldName);
|
||||
}
|
||||
|
@ -545,18 +540,17 @@ namespace CXMLDecompiler
|
|||
return;
|
||||
|
||||
Console.WriteLine("Decompiling " + Path.GetFileName(FileName));
|
||||
string DirectoryName = Path.Combine(FileDir, "converted", "RCStoXML", Path.GetFileNameWithoutExtension(FileName));
|
||||
string DirectoryName = Path.Combine(FileDir, "converted", "RCStoXML");
|
||||
if (!Directory.Exists(DirectoryName))
|
||||
Directory.CreateDirectory(DirectoryName);
|
||||
|
||||
try
|
||||
{
|
||||
string outputXML = Path.ChangeExtension(Path.GetFileNameWithoutExtension(FileName), ".xml");
|
||||
CXMLReader cxmlParser = new CXMLReader();
|
||||
cxmlParser.Init(FileName);
|
||||
cxmlParser.Init(FileName, Path.Combine(DirectoryName, outputXML));
|
||||
cxmlParser.ProcessFiles = this.ProcessFiles;
|
||||
cxmlParser.MainDir = DirectoryName;
|
||||
cxmlParser.FileDir = Path.Combine(cxmlParser.MainDir, "files");
|
||||
cxmlParser.DecompileCXML(FileName);
|
||||
cxmlParser.DecompileCXML(FileName, outputXML);
|
||||
}
|
||||
catch (Exception) { };
|
||||
}
|
||||
|
@ -573,30 +567,15 @@ namespace CXMLDecompiler
|
|||
File.WriteAllBytes(Path.Combine(DirectoryName, WaveName), WaveData);
|
||||
Console.WriteLine("Decoded file written to: " + WaveName);
|
||||
}
|
||||
if (Extension == ".gim") //Remove this IF statement if you dont want GIM Conversion.
|
||||
{
|
||||
if (File.Exists(Path.Combine("GimConv", "GimConv.exe")))
|
||||
if (Extension == ".gim")
|
||||
{
|
||||
String DirectoryName = Path.Combine(FileDir, "converted", "GIMtoPNG");
|
||||
|
||||
if (!Directory.Exists(DirectoryName))
|
||||
Directory.CreateDirectory(DirectoryName);
|
||||
|
||||
Console.WriteLine("Decoding GIM.");
|
||||
|
||||
Process Proc = new Process();
|
||||
Proc.StartInfo.FileName = Path.Combine("GimConv", "GimConv.exe");
|
||||
Proc.StartInfo.Arguments = "\"" + Path.GetFileName(FileName) + "\" -o \"" + Path.Combine(Environment.CurrentDirectory, DirectoryName, Path.GetFileName(Path.ChangeExtension(FileName, "png"))) + "\"";
|
||||
Proc.StartInfo.RedirectStandardOutput = true;
|
||||
Proc.StartInfo.RedirectStandardError = true;
|
||||
Proc.StartInfo.UseShellExecute = false;
|
||||
Proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(FileName);
|
||||
Proc.Start();
|
||||
Proc.WaitForExit();
|
||||
Console.WriteLine(Proc.StandardOutput.ReadToEnd());
|
||||
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
String OutputGim = Path.Combine(DirectoryName, Path.GetFileName(Path.ChangeExtension(FileName, "png")));
|
||||
GimConv.ConvertGimToPng(FileName, OutputGim);
|
||||
}
|
||||
if (Extension == ".z")
|
||||
{
|
||||
|
@ -640,6 +619,7 @@ namespace CXMLDecompiler
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
LoopbackHandler lpHandler = new LoopbackHandler();
|
||||
if (FileEntry)
|
||||
{
|
||||
|
@ -725,7 +705,7 @@ namespace CXMLDecompiler
|
|||
|
||||
int Hash = tools.ReadInt32(HashTable);
|
||||
|
||||
AttributeValue = Hash.ToString("X8", CultureInfo.InvariantCulture);
|
||||
AttributeValue = CXMLSymbols.LookupKey(Hash.ToString("X8", CultureInfo.InvariantCulture));
|
||||
|
||||
Console.WriteLine("Hash: " + AttributeValue.ToString() + " sz: " + HashTableSize);
|
||||
break;
|
||||
|
@ -779,7 +759,6 @@ namespace CXMLDecompiler
|
|||
String IdealName = ElementName + "-" + AttributeName + "-" + FileSmallHash + Extension;
|
||||
String ReplacePattern = Tools.GenerateReplacePattern();
|
||||
|
||||
//File.WriteAllBytes(FileName, FileData);
|
||||
RegisterFile(ElementPtr, FileName, true, ReplacePattern, FileData, IdealName);
|
||||
|
||||
AttributeValue = ReplacePattern;
|
||||
|
@ -806,7 +785,6 @@ namespace CXMLDecompiler
|
|||
IDTable.Seek(StringIdTableOffset + 4, SeekOrigin.Begin);
|
||||
|
||||
AttributeValue = Tools.ReadString(IDTable);
|
||||
|
||||
sz = tools.ReadInt32(TreeTable);
|
||||
Console.WriteLine("ID : " + StringIdTableOffset + " sz: " + sz);
|
||||
break;
|
||||
|
@ -822,7 +800,7 @@ namespace CXMLDecompiler
|
|||
LoopbackAttribute = Tools.ReadStringAt(StringTable, StringPtr);
|
||||
Console.WriteLine("Int Loopback: " + LoopbackAttribute + " " + LoopbackPtr.ToString("X", CultureInfo.InvariantCulture) + " (" + ElementPtr.ToString("X") + ")");
|
||||
|
||||
AttributeValue = IDValue.ToString("X8", CultureInfo.InvariantCulture);
|
||||
AttributeValue = CXMLSymbols.LookupKey(IDValue.ToString("X8", CultureInfo.InvariantCulture));
|
||||
RegisterFile(LoopbackPtr, AttributeValue.ToString(), false);
|
||||
|
||||
sz = tools.ReadInt32(TreeTable);
|
||||
|
@ -833,7 +811,7 @@ namespace CXMLDecompiler
|
|||
HashIDTable.Seek(IntIdTableOffset + 4, SeekOrigin.Begin);
|
||||
IDValue = tools.ReadInt32(HashIDTable);
|
||||
|
||||
AttributeValue = IDValue.ToString("X8", CultureInfo.InvariantCulture);
|
||||
AttributeValue = CXMLSymbols.LookupKey(IDValue.ToString("X8", CultureInfo.InvariantCulture));
|
||||
sz = tools.ReadInt32(TreeTable);
|
||||
Console.WriteLine("Hash Id: " + IntIdTableOffset + " sz: " + sz);
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
using General;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace CXMLDecompiler
|
||||
{
|
||||
public static class CXMLSymbols
|
||||
{
|
||||
private static Dictionary<string, string> Symbols = new Dictionary<string, string>();
|
||||
|
||||
public static string LookupKey(string key)
|
||||
{
|
||||
if (!Symbols.ContainsKey(key.ToLowerInvariant()))
|
||||
return key.ToLowerInvariant();
|
||||
else
|
||||
return Symbols[key.ToLowerInvariant()];
|
||||
}
|
||||
|
||||
public static string LookupId(string id)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> Symbol in Symbols)
|
||||
{
|
||||
if (Symbol.Value == id)
|
||||
{
|
||||
return Symbol.Key;
|
||||
}
|
||||
}
|
||||
|
||||
if (id.Length == 8)
|
||||
{
|
||||
try
|
||||
{
|
||||
Int32.Parse(id, NumberStyles.HexNumber);
|
||||
return id;
|
||||
}
|
||||
catch (Exception) { };
|
||||
}
|
||||
|
||||
|
||||
return Tools.GenerateShortHash(Encoding.UTF8.GetBytes(id));
|
||||
|
||||
}
|
||||
|
||||
public static void Init(string SymbolFile)
|
||||
{
|
||||
string[] lines = File.ReadAllText(SymbolFile).Replace("\r", "").Split('\n');
|
||||
|
||||
foreach(string line in lines)
|
||||
{
|
||||
if (line.StartsWith("#"))
|
||||
continue;
|
||||
if (line == "")
|
||||
continue;
|
||||
|
||||
if(line.Contains(' '))
|
||||
{
|
||||
string key = "";
|
||||
string id = "";
|
||||
|
||||
foreach (string opt in line.Split(' '))
|
||||
{
|
||||
if (opt.Contains(":"))
|
||||
{
|
||||
string[] kv = opt.Split(':');
|
||||
if (kv[0].ToLowerInvariant().StartsWith("key"))
|
||||
key = kv[1];
|
||||
if (kv[0].ToLowerInvariant().StartsWith("id"))
|
||||
id = kv[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (key.Contains("("))
|
||||
key = key.Substring(0, key.IndexOf("("));
|
||||
if (id.Contains(","))
|
||||
id = id.Substring(0, id.IndexOf(","));
|
||||
|
||||
Console.WriteLine("Reading Symbol .. key: " + key + " id: " + id);
|
||||
|
||||
Symbols.Add(key.ToLowerInvariant(), id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,46 @@
|
|||
using Ionic.Zip;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CXMLDecompiler
|
||||
{
|
||||
class GimConv
|
||||
{
|
||||
|
||||
public static string GIMCONV_FOLDER = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "GimConv");
|
||||
|
||||
static WebClient wc = new WebClient();
|
||||
static bool DownloadCompleted = true;
|
||||
|
||||
public static void ConvertGimToPng(string inputGim, string outputGim)
|
||||
{
|
||||
if (HasGimConv())
|
||||
{
|
||||
if (!Path.IsPathRooted(inputGim))
|
||||
inputGim = Path.Combine(Environment.CurrentDirectory, inputGim);
|
||||
|
||||
if (!Path.IsPathRooted(outputGim))
|
||||
outputGim = Path.Combine(Environment.CurrentDirectory, outputGim);
|
||||
|
||||
Console.WriteLine("Decoding GIM.");
|
||||
Process Proc = new Process();
|
||||
Proc.StartInfo.FileName = Path.Combine(GIMCONV_FOLDER, "GimConv.exe");
|
||||
Proc.StartInfo.Arguments = "\"" + inputGim + "\" -o \"" + outputGim + "\"";
|
||||
Proc.StartInfo.RedirectStandardOutput = true;
|
||||
Proc.StartInfo.RedirectStandardError = true;
|
||||
Proc.StartInfo.UseShellExecute = false;
|
||||
Proc.Start();
|
||||
Proc.WaitForExit();
|
||||
Console.Write(Proc.StandardOutput.ReadToEnd());
|
||||
}
|
||||
}
|
||||
public static bool HasGimConv()
|
||||
{
|
||||
return File.Exists(Path.Combine(GIMCONV_FOLDER, "GimConv.exe"));
|
||||
}
|
||||
public static void DownloadGimConv()
|
||||
{
|
||||
wc.DownloadProgressChanged += Wc_DownloadProgressChanged;
|
||||
|
@ -25,24 +56,27 @@ namespace CXMLDecompiler
|
|||
Console.Write("\r\n");
|
||||
MemoryStream zipStream = new MemoryStream(e.Result);
|
||||
ZipFile zip = ZipFile.Read(zipStream);
|
||||
foreach(ZipEntry zEntry in zip.Entries)
|
||||
foreach(ZipEntry zEntry in zip.Entries) // Read downloaded zip and extract stuff relating to GimConv .
|
||||
{
|
||||
string filename = Path.GetFileName(zEntry.FileName);
|
||||
if (filename == "msvcp71.dll" || filename == "msvcr71.dll" || zEntry.FileName.Contains("GimConv"))
|
||||
if (filename == "msvcp71.dll" || filename == "msvcr71.dll" || zEntry.FileName.Contains("GimConv")) // if it is a required DLL or inside the GimConv folder
|
||||
{
|
||||
string outputFilename = zEntry.FileName;
|
||||
if (outputFilename.Contains("GimConv"))
|
||||
outputFilename = outputFilename.Substring(outputFilename.IndexOf("GimConv"));
|
||||
else
|
||||
outputFilename = Path.Combine("GimConv", filename);
|
||||
if (outputFilename.Contains("GimConv")) // if the filename is inside the GimConv folder
|
||||
outputFilename = outputFilename.Substring(outputFilename.IndexOf("GimConv") + "GimConv".Length); // Extract filename after the "GimConv/" part
|
||||
|
||||
outputFilename = outputFilename.Replace("/", "\\");
|
||||
outputFilename = Path.Combine(GIMCONV_FOLDER, outputFilename); // set output path to GimConv folder
|
||||
Console.WriteLine("Extracting: " + outputFilename);
|
||||
|
||||
// If folder is directory, create it
|
||||
if (zEntry.IsDirectory)
|
||||
{
|
||||
Directory.CreateDirectory(outputFilename);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract the file to output path
|
||||
FileStream fs = File.Open(outputFilename, FileMode.CreateNew, FileAccess.ReadWrite);
|
||||
zEntry.Extract(fs);
|
||||
fs.Close();
|
||||
|
@ -51,7 +85,7 @@ namespace CXMLDecompiler
|
|||
zip.Dispose();
|
||||
zipStream.Dispose();
|
||||
|
||||
File.AppendAllText("GimConv\\GimConv.cfg", "option -psvrgba8888 {\r\n format_endian = little\r\n format_style = psp\r\n image_format = rgba8888\r\n pixel_order = normal\r\n pixel_channel = rgba\r\n limit_image_width = 4096\r\n limit_image_height = 4096\r\n}\r\noption -psvindex4 {\r\n format_endian = little\r\n format_style = psp\r\n image_format = index4\r\n pixel_order = normal\r\n pixel_channel = rgba\r\n limit_image_width = 4096\r\n limit_image_height = 4096\r\n}\r\noption -psvindex8 {\r\n format_endian = little\r\n format_style = psp\r\n image_format = index8\r\n pixel_order = normal\r\n pixel_channel = rgba\r\n limit_image_width = 4096\r\n limit_image_height = 4096\r\n}");
|
||||
File.AppendAllText(Path.Combine(GIMCONV_FOLDER, "GimConv.cfg"), "option -psvrgba8888 {\r\n format_endian = little\r\n format_style = psp\r\n image_format = rgba8888\r\n pixel_order = normal\r\n pixel_channel = rgba\r\n limit_image_width = 4096\r\n limit_image_height = 4096\r\n}\r\noption -psvindex4 {\r\n format_endian = little\r\n format_style = psp\r\n image_format = index4\r\n pixel_order = normal\r\n pixel_channel = rgba\r\n limit_image_width = 4096\r\n limit_image_height = 4096\r\n}\r\noption -psvindex8 {\r\n format_endian = little\r\n format_style = psp\r\n image_format = index8\r\n pixel_order = normal\r\n pixel_channel = rgba\r\n limit_image_width = 4096\r\n limit_image_height = 4096\r\n}");
|
||||
DownloadCompleted = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,30 +2,59 @@
|
|||
using General;
|
||||
using Ionic.Zlib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CXMLCli
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static bool HasArg(string argsfull, string argcheck)
|
||||
|
||||
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)
|
||||
{
|
||||
string[] args = argsfull.Split(' ');
|
||||
foreach(string arg in args)
|
||||
{
|
||||
if(arg == argcheck)
|
||||
if(arg.ToLowerInvariant() == argcheck.ToLowerInvariant())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static string GetTablesFolder()
|
||||
{
|
||||
string tablesFolder = Path.GetFileNameWithoutExtension(OutputFilePath) + "_tables";
|
||||
if (!Directory.Exists(tablesFolder))
|
||||
Directory.CreateDirectory(tablesFolder);
|
||||
return tablesFolder;
|
||||
}
|
||||
static int Main(string[] args)
|
||||
{
|
||||
|
||||
// Do you have gimconv?
|
||||
// Check if the user has GimConv and download it if not present
|
||||
// (only do this on windows)
|
||||
|
||||
bool windowsNT = Environment.OSVersion.Platform.Equals(PlatformID.Win32NT);
|
||||
bool windows32 = Environment.OSVersion.Platform.Equals(PlatformID.Win32Windows);
|
||||
|
@ -34,23 +63,23 @@ namespace CXMLCli
|
|||
|
||||
if (windowsNT || windows32 || windows32S || windowsCE)
|
||||
{
|
||||
if (!File.Exists(Path.Combine("GimConv", "GimConv.exe")))
|
||||
if (!GimConv.HasGimConv())
|
||||
{
|
||||
GimConv.DownloadGimConv(); // Politely ask sony to give it to us.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("NOTE: GimConv is windows binary, so you cant use it on this OS!\n.GIM Decoding will be disabled!");
|
||||
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!");
|
||||
}
|
||||
|
||||
bool Check = true;
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("-- CXML Decompiler --");
|
||||
Console.WriteLine("Required Arguments:");
|
||||
Console.WriteLine("\t<input_filename>");
|
||||
Console.WriteLine("\t-i --input Input file or folder");
|
||||
Console.WriteLine("\t-o --output Output file or folder");
|
||||
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");
|
||||
|
@ -74,182 +103,208 @@ namespace CXMLCli
|
|||
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");
|
||||
Console.WriteLine("\t-h --hash-string When Compiling, Generate new hashes");
|
||||
Console.WriteLine("Example Decompile: " + Path.GetFileName(Assembly.GetEntryAssembly().Location) + " app.info -d -p");
|
||||
Console.WriteLine("Example Compile: " + Path.GetFileName(Assembly.GetEntryAssembly().Location) + " app.xml app.info -c");
|
||||
Console.WriteLine("\t-s --symbols Use Symbol File (.rcd)");
|
||||
Console.WriteLine("Example Decompile: -i " + Path.GetFileName(Assembly.GetEntryAssembly().Location) + " common_resource.rco -o common_resource.xml -d -p");
|
||||
Console.WriteLine("Example Compile: -i " + Path.GetFileName(Assembly.GetEntryAssembly().Location) + " common_resource.xml -o common_resource.rco -c");
|
||||
Console.WriteLine("Default functonality is to Decompile,\nThis is canceled if any other arguments passed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
String ArgsFull = String.Join(" ", args);
|
||||
String ProcessFilePath = args[0];
|
||||
|
||||
bool ForcePs3 = false;
|
||||
Endianness FileEndianness = Endianness.UNCHANGED;
|
||||
|
||||
if (args.Length == 1)
|
||||
{
|
||||
ArgsFull += " -d -p -w";
|
||||
List<string> argsCopy = args.ToList();
|
||||
|
||||
argsCopy.AddRange(new string[] { "--input", args[0], "--output", Path.ChangeExtension(args[0], ".xml"), "--decompile", "--process-files", "--wait-exit" });
|
||||
|
||||
if (File.Exists(Path.ChangeExtension(args[0], ".rcd")))
|
||||
argsCopy.AddRange(new string[] { "--symbols", Path.ChangeExtension(args[0], ".rcd") });
|
||||
|
||||
args = argsCopy.ToArray();
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-le") || HasArg(ArgsFull, "--little-endian"))
|
||||
if(HasArg(args, "-i") || HasArg(args, "--input"))
|
||||
{
|
||||
int i = ArgIndex(args, "-i", "--input");
|
||||
InputFilePath = args[i + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("Missing required -i or --input argument.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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"))
|
||||
{
|
||||
FileEndianness = Endianness.LITTLE_ENDIAN;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-be") || HasArg(ArgsFull, "--big-endian"))
|
||||
if (HasArg(args, "-be") || HasArg(args, "--big-endian"))
|
||||
{
|
||||
FileEndianness = Endianness.LITTLE_ENDIAN;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-ps3") || HasArg(ArgsFull, "--playstation-3"))
|
||||
if (HasArg(args, "-ps3") || HasArg(args, "--playstation-3"))
|
||||
{
|
||||
ForcePs3 = true;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-iv") || HasArg(ArgsFull, "--is-vag"))
|
||||
if (HasArg(args, "-iv") || HasArg(args, "--is-vag"))
|
||||
{
|
||||
byte[] WaveData = VAG.VAGAudio.Vag2Wav(ProcessFilePath);
|
||||
string FileName = Path.GetFileNameWithoutExtension(ProcessFilePath) + "-" + VAG.VAGAudio.GetFilename(ProcessFilePath) + ".wav";
|
||||
Console.WriteLine("Writing "+FileName);
|
||||
File.WriteAllBytes(FileName, WaveData);
|
||||
byte[] WaveData = VAG.VAGAudio.Vag2Wav(InputFilePath);
|
||||
Console.WriteLine("Writing "+ OutputFilePath);
|
||||
File.WriteAllBytes(OutputFilePath, WaveData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-f") || HasArg(ArgsFull, "--force"))
|
||||
if (HasArg(args, "-f") || HasArg(args, "--force"))
|
||||
{
|
||||
Check = false;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-dc") || HasArg(ArgsFull, "--decompress"))
|
||||
if (HasArg(args, "-dc") || HasArg(args, "--decompress"))
|
||||
{
|
||||
Console.WriteLine("Decompressing " + ProcessFilePath);
|
||||
Byte[] FileData = File.ReadAllBytes(ProcessFilePath);
|
||||
Console.WriteLine("Decompressing " + InputFilePath);
|
||||
Byte[] FileData = File.ReadAllBytes(InputFilePath);
|
||||
Byte[] DecompressedData = ZlibStream.UncompressBuffer(FileData);
|
||||
string Extension = Tools.GetFileExtension(DecompressedData);
|
||||
string OutPath = Path.ChangeExtension(ProcessFilePath, Extension);
|
||||
File.WriteAllBytes(OutPath, DecompressedData);
|
||||
File.WriteAllBytes(OutputFilePath, DecompressedData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-cc") || HasArg(ArgsFull, "--compress"))
|
||||
if (HasArg(args, "-cc") || HasArg(args, "--compress"))
|
||||
{
|
||||
Console.WriteLine("Compressing " + ProcessFilePath);
|
||||
Byte[] FileData = File.ReadAllBytes(ProcessFilePath);
|
||||
Console.WriteLine("Compressing " + InputFilePath);
|
||||
Byte[] FileData = File.ReadAllBytes(InputFilePath);
|
||||
Byte[] CompressedData = ZlibStream.CompressBuffer(FileData);
|
||||
string Extension = Tools.GetFileExtension(CompressedData);
|
||||
string OutPath = Path.ChangeExtension(ProcessFilePath, Extension);
|
||||
File.WriteAllBytes(OutPath, CompressedData);
|
||||
File.WriteAllBytes(OutputFilePath, CompressedData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CXMLReader cxmlParser = new CXMLReader();
|
||||
if(!HasArg(ArgsFull, "-c") && !HasArg(ArgsFull, "--compile"))
|
||||
if(!HasArg(args, "-c") && !HasArg(args, "--compile")) // If not Compiling
|
||||
{
|
||||
Console.WriteLine("Initalizing: " + ProcessFilePath);
|
||||
cxmlParser.Init(ProcessFilePath, Check, ForcePs3, FileEndianness);
|
||||
Console.WriteLine("Initalizing: " + InputFilePath);
|
||||
cxmlParser.Init(InputFilePath, OutputFilePath, Check, ForcePs3, FileEndianness);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (HasArg(ArgsFull, "-dt") || HasArg(ArgsFull, "--dump-tables"))
|
||||
if (HasArg(args, "-dt") || HasArg(args, "--dump-tables"))
|
||||
{
|
||||
ArgsFull += " --dump-tree --dump-id --dump-hash-id --dump-string --dump-wstring --dump-hash --dump-int-array --dump-float-array --dump-file ";
|
||||
List<string> argsCopy = args.ToList();
|
||||
|
||||
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" });
|
||||
|
||||
args = argsCopy.ToArray();
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-tt") || HasArg(ArgsFull, "--dump-tree"))
|
||||
if (HasArg(args, "-tt") || HasArg(args, "--dump-tree"))
|
||||
{
|
||||
|
||||
Console.WriteLine("Dumping tree table.");
|
||||
File.WriteAllBytes("tree-table.bin", cxmlParser.GetTreeTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "tree-table.bin"), cxmlParser.GetTreeTable());
|
||||
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-idt") || HasArg(ArgsFull, "--dump-id"))
|
||||
if (HasArg(args, "-idt") || HasArg(args, "--dump-id"))
|
||||
{
|
||||
|
||||
Console.WriteLine("Dumping ID table.");
|
||||
File.WriteAllBytes("id-table.bin", cxmlParser.GetIDTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "id-table.bin"), cxmlParser.GetIDTable());
|
||||
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-iht") || HasArg(ArgsFull, "--dump-hash-id"))
|
||||
if (HasArg(args, "-iht") || HasArg(args, "--dump-hash-id"))
|
||||
{
|
||||
Console.WriteLine("Dumping hash ID table.");
|
||||
File.WriteAllBytes("hash-id-table.bin", cxmlParser.GetHashIDTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "hash-id-table.bin"), cxmlParser.GetHashIDTable());
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-st") || HasArg(ArgsFull, "--dump-string"))
|
||||
if (HasArg(args, "-st") || HasArg(args, "--dump-string"))
|
||||
{
|
||||
Console.WriteLine("Dumping string table.");
|
||||
File.WriteAllBytes("string-table.bin",cxmlParser.GetStringTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "string-table.bin"),cxmlParser.GetStringTable());
|
||||
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-wt") || HasArg(ArgsFull, "--dump-wstring"))
|
||||
if (HasArg(args, "-wt") || HasArg(args, "--dump-wstring"))
|
||||
{
|
||||
Console.WriteLine("Dumping wstring table.");
|
||||
File.WriteAllBytes("wstring-table.bin", cxmlParser.GetWStringTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "wstring-table.bin"), cxmlParser.GetWStringTable());
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-ht") || HasArg(ArgsFull, "--dump-hash"))
|
||||
if (HasArg(args, "-ht") || HasArg(args, "--dump-hash"))
|
||||
{
|
||||
Console.WriteLine("Dumping hash table.");
|
||||
File.WriteAllBytes("hash-table.bin", cxmlParser.GetHashTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "hash-table.bin"), cxmlParser.GetHashTable());
|
||||
}
|
||||
|
||||
|
||||
if (HasArg(ArgsFull, "-iat") || HasArg(ArgsFull, "--dump-int-array"))
|
||||
if (HasArg(args, "-iat") || HasArg(args, "--dump-int-array"))
|
||||
{
|
||||
Console.WriteLine("Dumping int array table.");
|
||||
File.WriteAllBytes("int-array-table.bin", cxmlParser.GetIntArrayTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "int-array-table.bin"), cxmlParser.GetIntArrayTable());
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-fat") || HasArg(ArgsFull, "--dump-float-array"))
|
||||
if (HasArg(args, "-fat") || HasArg(args, "--dump-float-array"))
|
||||
{
|
||||
Console.WriteLine("Dumping float array table.");
|
||||
File.WriteAllBytes("float-array-table.bin", cxmlParser.GetFloatArrayTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "float-array-table.bin"), cxmlParser.GetFloatArrayTable());
|
||||
}
|
||||
|
||||
|
||||
if (HasArg(ArgsFull, "-ft") || HasArg(ArgsFull, "--dump-tree"))
|
||||
if (HasArg(args, "-ft") || HasArg(args, "--dump-tree"))
|
||||
{
|
||||
Console.WriteLine("Dumping file table.");
|
||||
File.WriteAllBytes("file-table.bin", cxmlParser.GetFileTable());
|
||||
File.WriteAllBytes(Path.Combine(GetTablesFolder(), "file-table.bin"), cxmlParser.GetFileTable());
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-p") || HasArg(ArgsFull, "--process-files"))
|
||||
if (HasArg(args, "-p") || HasArg(args, "--process-files"))
|
||||
{
|
||||
cxmlParser.ProcessFiles = true;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-w") || HasArg(ArgsFull, "--wait-exit"))
|
||||
if (HasArg(args, "-w") || HasArg(args, "--wait-exit"))
|
||||
{
|
||||
cxmlParser.WaitExit = true;
|
||||
WaitExit = true;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-nr") || HasArg(ArgsFull, "--no-recursive"))
|
||||
if (HasArg(args, "-nr") || HasArg(args, "--no-recursive"))
|
||||
{
|
||||
cxmlParser.NoRecursive = true;
|
||||
}
|
||||
|
||||
if (HasArg(ArgsFull, "-d") || HasArg(ArgsFull, "--decompile") && !HasArg(ArgsFull, "-dt"))
|
||||
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"))
|
||||
{
|
||||
Console.WriteLine("Decompiling.");
|
||||
cxmlParser.DecompileCXML(ProcessFilePath);
|
||||
cxmlParser.DecompileCXML(InputFilePath, OutputFilePath);
|
||||
Console.WriteLine("\n\nDECOMPILATION COMPLETE!");
|
||||
if(cxmlParser.WaitExit)
|
||||
if(WaitExit)
|
||||
Console.ReadKey();
|
||||
}
|
||||
else if (HasArg(ArgsFull, "-c") || HasArg(ArgsFull, "--compile"))
|
||||
else if (HasArg(args, "-c") || HasArg(args, "--compile"))
|
||||
{
|
||||
Console.WriteLine("Compiling: " + ProcessFilePath);
|
||||
Console.WriteLine("Compiling: " + InputFilePath);
|
||||
CXMLBuilder builder = new CXMLBuilder();
|
||||
if (HasArg(ArgsFull, "-h") || HasArg(ArgsFull, "----hash-string"))
|
||||
builder.HashStrings = true;
|
||||
|
||||
builder.Init(ProcessFilePath, args[1]);
|
||||
builder.BuildCXML(ProcessFilePath, args[1]);
|
||||
builder.BuildCXML(InputFilePath, OutputFilePath);
|
||||
Console.WriteLine("\n\nCOMPILATION COMPLETE!");
|
||||
if (cxmlParser.WaitExit)
|
||||
if (WaitExit)
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
|
|
|
@ -351,7 +351,10 @@ namespace General
|
|||
{
|
||||
SHA1 sha = SHA1.Create();
|
||||
byte[] ShaBytes = sha.ComputeHash(Data);
|
||||
return BitConverter.ToInt32(ShaBytes, 0).ToString("X8");
|
||||
byte[] First4 = new byte[0x4];
|
||||
Array.Copy(ShaBytes, 0, First4, 0, First4.Length);
|
||||
First4 = First4.Reverse().ToArray();
|
||||
return BitConverter.ToInt32(First4, 0).ToString("X8").ToLowerInvariant();
|
||||
}
|
||||
|
||||
public static String ReadString(Stream ms, int limit = -1)
|
||||
|
|
Loading…
Reference in New Issue