V1.1 - FULL RCO & RCS SUPPORT

This commit is contained in:
AtelierWindows 2019-05-04 08:18:55 +12:00
parent ca14e988f1
commit 1d153b9040
14 changed files with 37405 additions and 372 deletions

View File

@ -1,345 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Xml;
namespace AppInfo
{
class Types
{
public static int TYPE_STRING = 3;
public static int TYPE_FLOAT = 2;
public static int TYPE_INT = 1;
public static int TYPE_FILE = 8;
}
class Tools
{
public static MemoryStream ByteToStream(byte[] Array)
{
MemoryStream ms = new MemoryStream();
ms.Write(Array, 0x00, Array.Length);
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
public static bool IsImage(byte[] Bytes)
{
try
{
GetBitmap(Bytes);
}
catch(Exception)
{
return false;
}
return true;
}
public static Bitmap GetBitmap(byte[] BitmapBytes)
{
MemoryStream ms = ByteToStream(BitmapBytes);
Bitmap bmp = new Bitmap(ms);
ms.Dispose();
return bmp;
}
public static String ReadStringAt(Stream ms, int location)
{
long ogPos = ms.Position;
ms.Seek(location, SeekOrigin.Begin);
String str = ReadString(ms);
ms.Seek(ogPos, SeekOrigin.Begin);
return str;
}
public static int ReadIntAt(Stream ms, int location)
{
BinaryReader BinReader = new BinaryReader(ms);
long ogPos = ms.Position;
ms.Seek(location, SeekOrigin.Begin);
int i = BinReader.ReadInt32();
ms.Seek(ogPos, SeekOrigin.Begin);
return i;
}
public static int ReadInt(Stream ms)
{
BinaryReader BinReader = new BinaryReader(ms);
int i = BinReader.ReadInt32();
return i;
}
public static String ReadString(Stream ms)
{
int i = 0xFF;
MemoryStream StringStream = new MemoryStream();
do
{
i = ms.ReadByte();
if (i == 0)
break;
StringStream.WriteByte((byte)i);
}
while (true);
byte[] StringData = StringStream.ToArray();
String str = Encoding.UTF8.GetString(StringData);
return str;
}
}
class Parser
{
private static bool _checkMagicNumber()
{
String Magic = Tools.ReadStringAt(InfoFile, 0x00);
if (Magic.StartsWith("PSMA"))
{
return true;
}
else if(Magic.StartsWith("RCOF"))
{
Console.WriteLine("WARNING: .RCO files probably wont work!!\nThis tool was made for PSM's \"app.info\" files.");
return true;
}
else
{
return false;
}
}
static FileStream InfoFile;
static MemoryStream StringTable;
static MemoryStream TreeTable;
static MemoryStream FileTable;
static BinaryReader BinaryTree;
static XmlWriter XMLFile;
public static void Init(string Path, bool CheckMagic = true)
{
InfoFile = File.Open(Path, FileMode.Open, FileAccess.Read);
if(CheckMagic)
{
if (!_checkMagicNumber())
{
throw new Exception("Incorrect magic number.");
}
}
StringTable = Tools.ByteToStream(GetStringTable());
TreeTable = Tools.ByteToStream(GetTreeTable());
FileTable = Tools.ByteToStream(GetFileTable());
BinaryTree = new BinaryReader(TreeTable);
return;
}
public static void Term()
{
InfoFile.Close();
StringTable.Close();
TreeTable.Close();
FileTable.Close();
BinaryTree.Dispose();
}
public static int GetTableOffset()
{
return Tools.ReadIntAt(InfoFile,0x8);
}
public static int GetTableSize()
{
return Tools.ReadIntAt(InfoFile, 0xC);
}
public static int GetFileTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x48);
}
public static int GetFileTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x4C);
}
public static int GetStringTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x20);
}
public static int GetStringTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x24);
}
public static byte[] GetStringTable()
{
int StringTableOffset = GetStringTableOffset();
int StringTableSize = GetStringTableSize();
InfoFile.Seek(StringTableOffset, SeekOrigin.Begin);
byte[] StringTable = new byte[StringTableSize];
InfoFile.Read(StringTable, 0x00, StringTableSize);
return StringTable;
}
public static byte[] GetTreeTable()
{
int TableOffset = GetTableOffset();
int TableSize = GetTableSize();
InfoFile.Seek(TableOffset, SeekOrigin.Begin);
byte[] Table = new byte[TableSize];
InfoFile.Read(Table, 0x00, TableSize);
return Table;
}
public static byte[] GetFileTable()
{
int DataOffset = GetFileTableOffset();
int DataLength = GetFileTableSize();
InfoFile.Seek(DataOffset, SeekOrigin.Begin);
byte[] FileTable = new byte[DataLength];
InfoFile.Read(FileTable, 0x00, DataLength);
return FileTable;
}
public static void DecompileCXML(String CXMLFile, bool force = false)
{
Init(CXMLFile,force);
XmlWriterSettings XMLSettings = new XmlWriterSettings();
XMLSettings.Indent = true;
XMLFile = XmlWriter.Create(Path.GetFileNameWithoutExtension(CXMLFile)+".xml", XMLSettings);
XMLFile.WriteStartDocument();
ReadElement();
XMLFile.WriteEndDocument();
XMLFile.Flush();
Term();
}
public static void ReadAttribute()
{
int AttributePtr = BinaryTree.ReadInt32();
int AttributeType = BinaryTree.ReadInt32();
String AttributeName = Tools.ReadStringAt(StringTable, AttributePtr);
object AttributeValue;
Console.WriteLine("AttributeType: " + AttributeType);
if (AttributeType == Types.TYPE_STRING)
{
int ValuePtr = BinaryTree.ReadInt32();
AttributeValue = Tools.ReadStringAt(StringTable, ValuePtr);
TreeTable.Seek(4, SeekOrigin.Current);
}
else if(AttributeType == Types.TYPE_FLOAT)
{
AttributeValue = BinaryTree.ReadSingle();
TreeTable.Seek(4, SeekOrigin.Current);
}
else if(AttributeType == Types.TYPE_INT)
{
AttributeValue = BinaryTree.ReadInt32();
TreeTable.Seek(4, SeekOrigin.Current);
}
else if(AttributeType == Types.TYPE_FILE)
{
int FilePtr = BinaryTree.ReadInt32();
int FileSz = BinaryTree.ReadInt32();
String FileName = "";
Byte[] FileData = new Byte[FileSz];
FileTable.Seek(FilePtr,SeekOrigin.Begin);
FileTable.Read(FileData, 0, FileSz);
if (Tools.IsImage(FileData))
FileName = AttributeName + ".png";
else
FileName = AttributeName + ".txt";
Console.WriteLine("Writing: " + FileName);
File.WriteAllBytes(FileName, FileData);
AttributeValue = FileName;
}
else
{
Console.WriteLine("ERROR: Unknown Type '"+AttributeType+"' @ " + (TreeTable.Position - 4).ToString());
Environment.Exit(-1);
return;
}
Console.WriteLine(AttributeName + "=" + AttributeValue.ToString());
XMLFile.WriteAttributeString(AttributeName, AttributeValue.ToString());
XMLFile.Flush();
}
public static void ReadElement()
{
int ElementPtr = BinaryTree.ReadInt32();
int NumAttributes = BinaryTree.ReadInt32();
int ParentPtr = BinaryTree.ReadInt32();
int PrevSibling = BinaryTree.ReadInt32();
int NextSibling = BinaryTree.ReadInt32();
int FirstChild = BinaryTree.ReadInt32();
int LastChild = BinaryTree.ReadInt32();
String ElementName = Tools.ReadStringAt(StringTable, ElementPtr);
Console.WriteLine("Creating Element: " + ElementName);
Console.WriteLine("Attribute Count: " + NumAttributes);
Console.WriteLine("ParentPtr: " + ParentPtr);
Console.WriteLine("PrevSibling: " + PrevSibling);
Console.WriteLine("NextSibling: " + NextSibling);
Console.WriteLine("FirstChild: " + FirstChild);
Console.WriteLine("LastChild: " + LastChild);
XMLFile.WriteStartElement(ElementName);
if(NumAttributes > 0)
{
for (int i = 0; i < NumAttributes; i++)
{
ReadAttribute();
}
}
if (FirstChild != -1)
{
TreeTable.Seek(FirstChild, SeekOrigin.Begin);
ReadElement();
}
XMLFile.WriteEndElement();
XMLFile.Flush();
if (NextSibling != -1)
{
TreeTable.Seek(NextSibling, SeekOrigin.Begin);
ReadElement();
}
}
}
}

780
AppInfoCli/CXML.cs Normal file
View File

@ -0,0 +1,780 @@
using Ionic.Zlib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Xml;
namespace CXML
{
enum AttributeType
{
TYPE_NONE,
TYPE_INT,
TYPE_FLOAT,
TYPE_STRING,
TYPE_CHAR,
TYPE_STYLE_ID,
TYPE_INTEGER_ARRAY,
TYPE_FLOAT_ARRAY,
TYPE_FILE,
TYPE_ID_STRING_LOOPBACK,
TYPE_ID_STRING,
TYPE_ID_INT_LOOPBACK,
TYPE_ID_INT
};
class Tools
{
public static String RemoveDecimals(float FloatValue)
{
String FloatStr = FloatValue.ToString();
String[] FloatParts = FloatStr.Split('.');
if (FloatParts.Length > 1)
if(FloatParts[1].Length > 2)
FloatParts[1] = FloatParts[1].Substring(0, 2);
FloatStr = String.Join(".", FloatParts);
return FloatStr;
}
public static MemoryStream ByteToStream(byte[] Array)
{
MemoryStream ms = new MemoryStream();
ms.Write(Array, 0x00, Array.Length);
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
public static byte[] StreamToByte(Stream stream)
{
int StreamLen = (int)stream.Length;
byte[] Bytes = new byte[StreamLen];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(Bytes, 0x00, StreamLen);
return Bytes;
}
public static string GetFileExtension(byte[] Bytes)
{
if(IsImage(Bytes))
{
return ".png";
}
else if(IsZlib(Bytes))
{
return ".zlib";
}
else if(IsGim(Bytes))
{
return ".gim";
}
else if(IsRcf(Bytes))
{
return ".rcs";
}
else if(IsDDS(Bytes))
{
return ".dds";
}
else if (IsVAG(Bytes))
{
return ".vag";
}
else
{
return ".bin";
}
}
public static bool IsVAG(byte[] Bytes)
{
MemoryStream Data = ByteToStream(Bytes);
String header = ReadString(Data, 4);
if (header.StartsWith("VAG"))
{
return true;
}
else
{
return false;
}
}
public static bool IsDDS(byte[] Bytes)
{
MemoryStream Data = ByteToStream(Bytes);
String header = ReadString(Data, 4);
if (header.StartsWith("DDS"))
{
return true;
}
else
{
return false;
}
}
public static bool IsRcf(byte[] Bytes)
{
MemoryStream Data = ByteToStream(Bytes);
String header = ReadString(Data, 5);
if (header.StartsWith("RCSF"))
{
return true;
}
else
{
return false;
}
}
public static bool IsGim(byte[] Bytes)
{
MemoryStream Data = ByteToStream(Bytes);
String header = ReadString(Data,4);
if(header.StartsWith("MIG"))
{
return true;
}
else
{
return false;
}
}
public static bool IsZlib(byte[] Bytes)
{
if(Bytes[0] == 0x78)
{
if (Bytes[1] == 0x01)
return true;
if (Bytes[1] == 0x9C)
return true;
if (Bytes[1] == 0xDA)
return true;
}
return false;
}
public static bool IsImage(byte[] Bytes)
{
try
{
GetBitmap(Bytes);
}
catch(Exception)
{
return false;
}
return true;
}
public static Bitmap GetBitmap(byte[] BitmapBytes)
{
MemoryStream ms = ByteToStream(BitmapBytes);
Bitmap bmp = new Bitmap(ms);
ms.Dispose();
return bmp;
}
public static String ReadStringAt(Stream ms, int location)
{
long ogPos = ms.Position;
ms.Seek(location, SeekOrigin.Begin);
String str = ReadString(ms);
ms.Seek(ogPos, SeekOrigin.Begin);
return str;
}
public static int ReadIntAt(Stream ms, int location)
{
BinaryReader BinReader = new BinaryReader(ms);
long ogPos = ms.Position;
ms.Seek(location, SeekOrigin.Begin);
int i = BinReader.ReadInt32();
ms.Seek(ogPos, SeekOrigin.Begin);
return i;
}
public static int ReadInt(Stream ms)
{
BinaryReader BinReader = new BinaryReader(ms);
int i = BinReader.ReadInt32();
return i;
}
public static String ReadString(Stream ms, int limit = -1)
{
int i = 0xFF;
MemoryStream StringStream = new MemoryStream();
do
{
i = ms.ReadByte();
if (i == 0 && i != limit)
break;
StringStream.WriteByte((byte)i);
}
while (true);
byte[] StringData = StringStream.ToArray();
String str = Encoding.UTF8.GetString(StringData);
return str;
}
}
class Parser
{
private static bool _checkMagicNumber()
{
String Magic = Tools.ReadStringAt(InfoFile, 0x00);
if (Magic.StartsWith("PSMA"))
{
return true;
}
else if(Magic.StartsWith("RCOF"))
{
return true;
}
else if (Magic.StartsWith("RCSF"))
{
return true;
}
else
{
return false;
}
}
static FileStream InfoFile;
static MemoryStream TreeTable;
static MemoryStream StringIDTable;
static MemoryStream IntIDTable;
static MemoryStream StringTable;
static MemoryStream CharTable;
static MemoryStream StylesIDTable;
static MemoryStream IntArrayTable;
static MemoryStream FloatArrayTable;
static MemoryStream FileTable;
static BinaryReader bTreeTable;
static BinaryReader bIntIDTable;
static BinaryReader bFloatArrayTable;
static BinaryReader bIntArrayTable;
static BinaryReader bStylesIDTable;
static XmlWriter XMLFile;
public static void Init(string Path, bool CheckMagic = true)
{
InfoFile = File.Open(Path, FileMode.Open, FileAccess.Read);
if(CheckMagic)
{
if (!_checkMagicNumber())
{
throw new Exception("Incorrect magic number.");
}
}
TreeTable = Tools.ByteToStream(GetTreeTable());
StringIDTable = Tools.ByteToStream(GetStringIDTable());
IntIDTable = Tools.ByteToStream(GetIntIDTable());
StringTable = Tools.ByteToStream(GetStringTable());
CharTable = Tools.ByteToStream(GetCharTable());
StylesIDTable = Tools.ByteToStream(GetStyleIDTable());
IntArrayTable = Tools.ByteToStream(GetIntArrayTable());
FloatArrayTable = Tools.ByteToStream(GetFloatArrayTable());
FileTable = Tools.ByteToStream(GetFileTable());
bTreeTable = new BinaryReader(TreeTable);
bIntIDTable = new BinaryReader(IntIDTable);
bFloatArrayTable = new BinaryReader(FloatArrayTable);
bIntArrayTable = new BinaryReader(IntArrayTable);
bStylesIDTable = new BinaryReader(StylesIDTable);
return;
}
public static void Term()
{
InfoFile.Close();
TreeTable.Close();
StringIDTable.Close();
IntIDTable.Close();
StringTable.Close();
CharTable.Close();
StylesIDTable.Close();
IntArrayTable.Close();
FloatArrayTable.Close();
FileTable.Close();
bTreeTable.Close();
bIntIDTable.Close();
bFloatArrayTable.Close();
bIntArrayTable.Close();
bStylesIDTable.Close();
}
public static int GetTreeTableOffset()
{
return Tools.ReadIntAt(InfoFile,0x8);
}
public static int GetTreeTableSize()
{
return Tools.ReadIntAt(InfoFile, 0xC);
}
public static int GetIDStringTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x10);
}
public static int GetIDStringTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x14);
}
public static int GetIDIntTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x18);
}
public static int GetIDIntTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x1C);
}
public static int GetStringTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x20);
}
public static int GetStringTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x24);
}
public static int GetCharTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x28);
}
public static int GetCharTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x2C);
}
public static int GetStyleIDTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x30);
}
public static int GetStyleIDTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x34);
}
public static int GetIntArrayTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x38);
}
public static int GetIntArrayTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x3C);
}
public static int GetFloatArrayTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x40);
}
public static int GetFloatArrayTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x44);
}
public static int GetFileTableOffset()
{
return Tools.ReadIntAt(InfoFile, 0x48);
}
public static int GetFileTableSize()
{
return Tools.ReadIntAt(InfoFile, 0x4C);
}
public static byte[] GetTreeTable()
{
int TableOffset = GetTreeTableOffset();
int TableSize = GetTreeTableSize();
InfoFile.Seek(TableOffset, SeekOrigin.Begin);
byte[] Table = new byte[TableSize];
InfoFile.Read(Table, 0x00, TableSize);
return Table;
}
public static byte[] GetStringIDTable()
{
int IDStrTableOffset = GetIDStringTableOffset();
int IDStrTableSize = GetIDStringTableSize();
InfoFile.Seek(IDStrTableOffset, SeekOrigin.Begin);
byte[] IDStringTable = new byte[IDStrTableSize];
InfoFile.Read(IDStringTable, 0x00, IDStrTableSize);
return IDStringTable;
}
public static byte[] GetIntIDTable()
{
int IDIntTableOffset = GetIDIntTableOffset();
int IDIntTableSize = GetIDIntTableSize();
InfoFile.Seek(IDIntTableOffset, SeekOrigin.Begin);
byte[] IDIntTable = new byte[IDIntTableSize];
InfoFile.Read(IDIntTable, 0x00, IDIntTableSize);
return IDIntTable;
}
public static byte[] GetStringTable()
{
int StringTableOffset = GetStringTableOffset();
int StringTableSize = GetStringTableSize();
InfoFile.Seek(StringTableOffset, SeekOrigin.Begin);
byte[] StringTable = new byte[StringTableSize];
InfoFile.Read(StringTable, 0x00, StringTableSize);
return StringTable;
}
public static byte[] GetCharTable()
{
int CharTableOffset = GetCharTableOffset();
int CharTableSize = GetCharTableSize();
InfoFile.Seek(CharTableOffset, SeekOrigin.Begin);
byte[] CharTable = new byte[CharTableSize];
InfoFile.Read(CharTable, 0x00, CharTableSize);
return CharTable;
}
public static byte[] GetStyleIDTable()
{
int StyleIDTableOffset = GetStyleIDTableOffset();
int StyleIDTableSize = GetStyleIDTableSize();
InfoFile.Seek(StyleIDTableOffset, SeekOrigin.Begin);
byte[] StyleIDTable = new byte[StyleIDTableSize];
InfoFile.Read(StyleIDTable, 0x00, StyleIDTableSize);
return StyleIDTable;
}
public static byte[] GetIntArrayTable()
{
int IntArrayTableOffset = GetIntArrayTableOffset();
int IntArrayTableSize = GetIntArrayTableSize();
InfoFile.Seek(IntArrayTableOffset, SeekOrigin.Begin);
byte[] IntArrayTable = new byte[IntArrayTableSize];
InfoFile.Read(IntArrayTable, 0x00, IntArrayTableSize);
return IntArrayTable;
}
public static byte[] GetFloatArrayTable()
{
int FloatArrayTableOffset = GetFloatArrayTableOffset();
int FloatArrayTableSize = GetFloatArrayTableSize();
InfoFile.Seek(FloatArrayTableOffset, SeekOrigin.Begin);
byte[] FloatArrayTable = new byte[FloatArrayTableSize];
InfoFile.Read(FloatArrayTable, 0x00, FloatArrayTableSize);
return FloatArrayTable;
}
public static byte[] GetFileTable()
{
int DataOffset = GetFileTableOffset();
int DataLength = GetFileTableSize();
InfoFile.Seek(DataOffset, SeekOrigin.Begin);
byte[] FileTable = new byte[DataLength];
InfoFile.Read(FileTable, 0x00, DataLength);
return FileTable;
}
public static void DecompileCXML(String CXMLFile, bool force = false)
{
if(Directory.Exists("files"))
Directory.Delete("files", true);
Term();
Init(CXMLFile,force);
XmlWriterSettings XMLSettings = new XmlWriterSettings();
XMLSettings.Indent = true;
XMLFile = XmlWriter.Create(Path.GetFileNameWithoutExtension(CXMLFile)+".xml", XMLSettings);
XMLFile.WriteStartDocument();
ReadElement();
XMLFile.WriteEndDocument();
XMLFile.Flush();
Term();
}
public static void ReadAttribute(String ElementName = "")
{
int AttributePtr = bTreeTable.ReadInt32();
AttributeType Type = (AttributeType)bTreeTable.ReadInt32();
String AttributeName = Tools.ReadStringAt(StringTable, AttributePtr);
object AttributeValue = "";
Console.WriteLine("AttributeType: " + Type.ToString() + " - "+ TreeTable.Position.ToString());
switch (Type)
{
case AttributeType.TYPE_NONE:
Console.WriteLine("UNSUPPORTED TYPE @ " + TreeTable.Position);
Console.ReadKey();
break;
case AttributeType.TYPE_INT:
AttributeValue = bTreeTable.ReadInt32();
TreeTable.Seek(4, SeekOrigin.Current);
break;
case AttributeType.TYPE_FLOAT:
float FloatValue = bTreeTable.ReadSingle();
AttributeValue = Tools.RemoveDecimals(FloatValue);
TreeTable.Seek(4, SeekOrigin.Current);
break;
case AttributeType.TYPE_STRING:
int StringOffset = bTreeTable.ReadInt32();
int StringLen = bTreeTable.ReadInt32();
byte[] StringBytes = new byte[StringLen];
StringTable.Seek(StringOffset, 0x00);
StringTable.Read(StringBytes, 0x00, StringLen);
AttributeValue = Encoding.UTF8.GetString(StringBytes);
break;
case AttributeType.TYPE_CHAR:
int CharOffset = bTreeTable.ReadInt32() * 2;
int CharLen = bTreeTable.ReadInt32();
byte[] CharBytes = new byte[CharLen];
CharTable.Seek(CharOffset, 0x00);
CharTable.Read(CharBytes, 0x00, CharLen);
AttributeValue = Encoding.Unicode.GetString(CharBytes);
break;
case AttributeType.TYPE_STYLE_ID:
int StyleTableOffset = bTreeTable.ReadInt32();
int StyleTableSize = bTreeTable.ReadInt32();
byte[] StyleTableData = new byte[StyleTableSize];
StylesIDTable.Seek(StyleTableOffset, SeekOrigin.Begin);
StylesIDTable.Read(StyleTableData, 0x00, StyleTableSize);
AttributeValue = BitConverter.ToString(StyleTableData).Replace("-","");
break;
case AttributeType.TYPE_INTEGER_ARRAY:
int IntArrayOffset = bTreeTable.ReadInt32();
int IntArraySize = bTreeTable.ReadInt32();
IntArrayTable.Seek(IntArrayOffset, SeekOrigin.Begin);
List<int> IntList = new List<int>();
for (int i = 0; i < IntArraySize; i++)
{
int IntValue = bIntArrayTable.ReadInt32();
IntList.Add(IntValue);
}
int[] IntArray = IntList.ToArray();
AttributeValue = String.Join(", ", IntArray);
break;
case AttributeType.TYPE_FLOAT_ARRAY:
int FloatArrayOffset = bTreeTable.ReadInt32();
int FloatArraySize = bTreeTable.ReadInt32();
FloatArrayTable.Seek(FloatArrayOffset, SeekOrigin.Begin);
List<string> StrList = new List<string>();
for(int i = 0; i < FloatArraySize; i++)
{
FloatValue = bFloatArrayTable.ReadSingle();
StrList.Add(Tools.RemoveDecimals(FloatValue));
}
string[] StrArray = StrList.ToArray();
AttributeValue = String.Join(", ", StrArray);
break;
case AttributeType.TYPE_FILE:
int FilePtr = bTreeTable.ReadInt32();
int FileSz = bTreeTable.ReadInt32();
String FileName = "";
Byte[] FileData = new Byte[FileSz];
FileTable.Seek(FilePtr, SeekOrigin.Begin);
FileTable.Read(FileData, 0, FileSz);
if (!Directory.Exists("files"))
Directory.CreateDirectory("files");
int count = 0;
string CounterStr = count.ToString();
do
{
String Extension = Tools.GetFileExtension(FileData);
CounterStr = count.ToString();
if (count == 0)
CounterStr = "";
FileName = "files/" + ElementName + "-" + AttributeName + CounterStr + Extension;
count++;
}
while (File.Exists(FileName));
Console.WriteLine("Writing: " + FileName);
if(Path.GetExtension(FileName) == ".zlib")
{
Console.WriteLine("Decompressing " + FileName);
Byte[] DecompressedData = ZlibStream.UncompressBuffer(FileData);
String Extension = Tools.GetFileExtension(DecompressedData);
if (!Directory.Exists("files/decompressed"))
Directory.CreateDirectory("files/decompressed");
String DecompressedFilename = "files/decompressed/" + ElementName + "-" + AttributeName + CounterStr + Extension;
Console.WriteLine("Decompressed file written to: " + DecompressedFilename);
File.WriteAllBytes(DecompressedFilename, DecompressedData);
if(Extension == ".gim")
{
if(File.Exists("GimConv/GimConv.exe"))
{
if (!Directory.Exists("files/converted"))
Directory.CreateDirectory("files/converted");
Console.WriteLine("Decoding GIM.");
Process Proc = new Process();
Proc.StartInfo.FileName = "GimConv/GimConv.exe";
Proc.StartInfo.Arguments = Path.GetFileName(DecompressedFilename) + " -o " + "../converted/" + ElementName + "-" + AttributeName + CounterStr + ".png";
Proc.StartInfo.RedirectStandardOutput = true;
Proc.StartInfo.RedirectStandardError = true;
Proc.StartInfo.UseShellExecute = false;
Proc.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory()+ "/files/decompressed";
Proc.Start();
Proc.WaitForExit();
Console.WriteLine(Proc.StandardOutput.ReadToEnd());
Console.WriteLine("Done!");
}
}
}
File.WriteAllBytes(FileName, FileData);
AttributeValue = FileName;
break;
case AttributeType.TYPE_ID_STRING_LOOPBACK:
int StringIdTableOffset = bTreeTable.ReadInt32();
AttributeValue = Tools.ReadStringAt(StringIDTable, StringIdTableOffset + 0x4);
TreeTable.Seek(4, SeekOrigin.Current);
break;
case AttributeType.TYPE_ID_STRING:
Console.WriteLine("UNSUPPORTED TYPE @ " + TreeTable.Position);
Console.ReadKey();
break;
case AttributeType.TYPE_ID_INT_LOOPBACK:
int IntIdTableOffset = bTreeTable.ReadInt32();
IntIDTable.Seek(IntIdTableOffset, SeekOrigin.Begin);
int Loopback = bIntIDTable.ReadInt32();
int IDValue = bIntIDTable.ReadInt32();
int StringPtr = Tools.ReadIntAt(TreeTable, Loopback);
String LoopbackAttribute = Tools.ReadStringAt(StringTable, StringPtr);
Console.WriteLine("Loopback: " + LoopbackAttribute);
AttributeValue = IDValue.ToString("X8");
TreeTable.Seek(4, SeekOrigin.Current);
break;
case AttributeType.TYPE_ID_INT:
IntIdTableOffset = bTreeTable.ReadInt32();
IntIDTable.Seek(IntIdTableOffset + 4, SeekOrigin.Begin);
IDValue = bIntIDTable.ReadInt32();
AttributeValue = IDValue.ToString("X8");
TreeTable.Seek(4, SeekOrigin.Current);
break;
default:
Console.WriteLine("UNKNOWN TYPE @ " + TreeTable.Position);
break;
};
Console.WriteLine(AttributeName + "=" + AttributeValue.ToString());
XMLFile.WriteAttributeString(AttributeName, AttributeValue.ToString());
XMLFile.Flush();
}
public static void ReadElement()
{
int ElementPtr = bTreeTable.ReadInt32();
int NumAttributes = bTreeTable.ReadInt32();
int ParentPtr = bTreeTable.ReadInt32();
int PrevSibling = bTreeTable.ReadInt32();
int NextSibling = bTreeTable.ReadInt32();
int FirstChild = bTreeTable.ReadInt32();
int LastChild = bTreeTable.ReadInt32();
String ElementName = Tools.ReadStringAt(StringTable, ElementPtr);
Console.WriteLine("Creating Element: " + ElementName);
Console.WriteLine("Attribute Count: " + NumAttributes);
Console.WriteLine("ParentPtr: " + ParentPtr);
Console.WriteLine("PrevSibling: " + PrevSibling);
Console.WriteLine("NextSibling: " + NextSibling);
Console.WriteLine("FirstChild: " + FirstChild);
Console.WriteLine("LastChild: " + LastChild);
XMLFile.WriteStartElement(ElementName);
if(NumAttributes > 0)
{
for (int i = 0; i < NumAttributes; i++)
{
ReadAttribute(ElementName);
}
}
if (FirstChild != -1)
{
TreeTable.Seek(FirstChild, SeekOrigin.Begin);
ReadElement();
}
XMLFile.WriteEndElement();
XMLFile.Flush();
if (NextSibling != -1)
{
TreeTable.Seek(NextSibling, SeekOrigin.Begin);
ReadElement();
}
}
}
}

View File

@ -6,8 +6,8 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BE72E673-25FF-47AB-AF5B-9448B69E3990}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>AppInfoCli</RootNamespace>
<AssemblyName>AppInfoCli</AssemblyName>
<RootNamespace>CXMLDecompiler</RootNamespace>
<AssemblyName>CXMLDecompiler</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@ -33,6 +33,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="DotNetZip, Version=1.13.3.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
<HintPath>..\packages\DotNetZip.1.13.3\lib\net40\DotNetZip.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
@ -44,12 +47,13 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AppInfo.cs" />
<Compile Include="CXML.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -2,14 +2,15 @@
using System.IO;
using System.Reflection;
namespace AppInfoCli
namespace CXMLCli
{
class Program
{
static void Main(string[] args)
{
bool Check = true;
bool Check = true;
if (args.Length == 0)
{
Console.WriteLine("-- app.info/CXML Decompiler --");
@ -17,11 +18,18 @@ namespace AppInfoCli
Console.WriteLine("Required Arguments:");
Console.WriteLine("\t<file>");
Console.WriteLine("Optional Arguments:");
Console.WriteLine("\t-f --force Dont check magic number.");
Console.WriteLine("\t-s --dump-strings Dump string table.");
Console.WriteLine("\t-t --dump-tree Dump tree table.");
Console.WriteLine("\t-ft --dump-file Dump file table.");
Console.WriteLine("\t-d --decompile Decompile CXML.");
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-ist --dump-string-id Dump string ID table.");
Console.WriteLine("\t-iit --dump-int-id Dump int ID table.");
Console.WriteLine("\t-st --dump-string Dump string table.");
Console.WriteLine("\t-ct --dump-char Dump char table.");
Console.WriteLine("\t-sit --dump-style-id Dump style ID 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-d --decompile Decompile CXML.");
Console.WriteLine("Example: " + Path.GetFileName(Assembly.GetEntryAssembly().Location) + " app.info -f -s -t -f -d");
Console.WriteLine("Default functonality is to Decompile,\ntThis is canceled if any other arguments passed.");
return;
@ -29,43 +37,83 @@ namespace AppInfoCli
String ArgsFull = String.Join(" ", args);
String path = args[0];
CXML.Parser.Init(path, Check);
if (ArgsFull.Contains("-f") || ArgsFull.Contains("--force"))
{
Check = false;
}
if (ArgsFull.Contains("-s") || ArgsFull.Contains("--dump-strings"))
if (ArgsFull.Contains("-dt") || ArgsFull.Contains("--dump-tables"))
{
Console.WriteLine("Dumping string table.");
AppInfo.Parser.Init(path, Check);
File.WriteAllBytes("string-table.bin",AppInfo.Parser.GetStringTable());
AppInfo.Parser.Term();
ArgsFull += "-tt -ist -iit -st -ct -sit -iat -fat -ft";
}
if (ArgsFull.Contains("-t") || ArgsFull.Contains("--dump-tree"))
if (ArgsFull.Contains("-tt") || ArgsFull.Contains("--dump-tree"))
{
Console.WriteLine("Dumping tree table.");
AppInfo.Parser.Init(path, Check);
File.WriteAllBytes("tree-table.bin", AppInfo.Parser.GetTreeTable());
AppInfo.Parser.Term();
File.WriteAllBytes("tree-table.bin", CXML.Parser.GetTreeTable());
}
if (ArgsFull.Contains("-ist") || ArgsFull.Contains("--dump-string-id"))
{
Console.WriteLine("Dumping string ID table.");
File.WriteAllBytes("string-id-table.bin", CXML.Parser.GetStringIDTable());
}
if (ArgsFull.Contains("-iit") || ArgsFull.Contains("--dump-int-id"))
{
Console.WriteLine("Dumping int ID table.");
File.WriteAllBytes("int-id-table.bin", CXML.Parser.GetIntIDTable());
}
if (ArgsFull.Contains("-st") || ArgsFull.Contains("--dump-string"))
{
Console.WriteLine("Dumping string table.");
File.WriteAllBytes("string-table.bin",CXML.Parser.GetStringTable());
}
if (ArgsFull.Contains("-ct") || ArgsFull.Contains("--dump-char"))
{
Console.WriteLine("Dumping char table.");
File.WriteAllBytes("char-table.bin", CXML.Parser.GetCharTable());
}
if (ArgsFull.Contains("-sit") || ArgsFull.Contains("--dump-style-id"))
{
Console.WriteLine("Dumping style ID table.");
File.WriteAllBytes("style-id-table.bin", CXML.Parser.GetStyleIDTable());
}
if (ArgsFull.Contains("-iat") || ArgsFull.Contains("--dump-int-array"))
{
Console.WriteLine("Dumping int array table.");
File.WriteAllBytes("int-array-table.bin", CXML.Parser.GetIntArrayTable());
}
if (ArgsFull.Contains("-fat") || ArgsFull.Contains("--dump-float-array"))
{
Console.WriteLine("Dumping float array table.");
File.WriteAllBytes("float-array-table.bin", CXML.Parser.GetFloatArrayTable());
}
if (ArgsFull.Contains("-ft") || ArgsFull.Contains("--dump-tree"))
{
Console.WriteLine("Dumping file table.");
AppInfo.Parser.Init(path, Check);
File.WriteAllBytes("file-table.bin", AppInfo.Parser.GetTreeTable());
AppInfo.Parser.Term();
File.WriteAllBytes("file-table.bin", CXML.Parser.GetTreeTable());
}
if (ArgsFull.Contains("-d") || ArgsFull.Contains("--decompile") || args.Length == 1)
{
Console.WriteLine("Decompiling.");
AppInfo.Parser.DecompileCXML(path, Check);
CXML.Parser.DecompileCXML(path, Check);
Console.WriteLine("\n\nDECOMPILATION COMPLETE!");
Console.ReadKey();
}
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DotNetZip" version="1.13.3" targetFramework="net461" />
</packages>

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2003
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppInfoCli", "AppInfoCli\AppInfoCli.csproj", "{BE72E673-25FF-47AB-AF5B-9448B69E3990}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CXMLCli", "AppInfoCli\CXMLCli.csproj", "{BE72E673-25FF-47AB-AF5B-9448B69E3990}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

BIN
packages/DotNetZip.1.13.3/.signature.p7s vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff