V1.1 - FULL RCO & RCS SUPPORT
This commit is contained in:
parent
ca14e988f1
commit
1d153b9040
|
@ -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
780
AppInfoCli/CXML.cs
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,8 @@
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{BE72E673-25FF-47AB-AF5B-9448B69E3990}</ProjectGuid>
|
<ProjectGuid>{BE72E673-25FF-47AB-AF5B-9448B69E3990}</ProjectGuid>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RootNamespace>AppInfoCli</RootNamespace>
|
<RootNamespace>CXMLDecompiler</RootNamespace>
|
||||||
<AssemblyName>AppInfoCli</AssemblyName>
|
<AssemblyName>CXMLDecompiler</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
@ -33,6 +33,9 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<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" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
|
@ -44,12 +47,13 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AppInfo.cs" />
|
<Compile Include="CXML.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
|
@ -2,12 +2,13 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace AppInfoCli
|
namespace CXMLCli
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool Check = true;
|
bool Check = true;
|
||||||
|
|
||||||
if (args.Length == 0)
|
if (args.Length == 0)
|
||||||
|
@ -17,11 +18,18 @@ namespace AppInfoCli
|
||||||
Console.WriteLine("Required Arguments:");
|
Console.WriteLine("Required Arguments:");
|
||||||
Console.WriteLine("\t<file>");
|
Console.WriteLine("\t<file>");
|
||||||
Console.WriteLine("Optional Arguments:");
|
Console.WriteLine("Optional Arguments:");
|
||||||
Console.WriteLine("\t-f --force Dont check magic number.");
|
Console.WriteLine("\t-f --force Dont check magic number.");
|
||||||
Console.WriteLine("\t-s --dump-strings Dump string table.");
|
Console.WriteLine("\t-dt --dump-tables Dump ALL tables.");
|
||||||
Console.WriteLine("\t-t --dump-tree Dump tree table.");
|
Console.WriteLine("\t-tt --dump-tree Dump tree table.");
|
||||||
Console.WriteLine("\t-ft --dump-file Dump file table.");
|
Console.WriteLine("\t-ist --dump-string-id Dump string ID table.");
|
||||||
Console.WriteLine("\t-d --decompile Decompile CXML.");
|
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("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.");
|
Console.WriteLine("Default functonality is to Decompile,\ntThis is canceled if any other arguments passed.");
|
||||||
return;
|
return;
|
||||||
|
@ -29,43 +37,83 @@ namespace AppInfoCli
|
||||||
|
|
||||||
String ArgsFull = String.Join(" ", args);
|
String ArgsFull = String.Join(" ", args);
|
||||||
String path = args[0];
|
String path = args[0];
|
||||||
|
CXML.Parser.Init(path, Check);
|
||||||
|
|
||||||
if (ArgsFull.Contains("-f") || ArgsFull.Contains("--force"))
|
if (ArgsFull.Contains("-f") || ArgsFull.Contains("--force"))
|
||||||
{
|
{
|
||||||
Check = false;
|
Check = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ArgsFull.Contains("-dt") || ArgsFull.Contains("--dump-tables"))
|
||||||
if (ArgsFull.Contains("-s") || ArgsFull.Contains("--dump-strings"))
|
|
||||||
{
|
{
|
||||||
Console.WriteLine("Dumping string table.");
|
ArgsFull += "-tt -ist -iit -st -ct -sit -iat -fat -ft";
|
||||||
AppInfo.Parser.Init(path, Check);
|
|
||||||
File.WriteAllBytes("string-table.bin",AppInfo.Parser.GetStringTable());
|
|
||||||
AppInfo.Parser.Term();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ArgsFull.Contains("-tt") || ArgsFull.Contains("--dump-tree"))
|
||||||
if (ArgsFull.Contains("-t") || ArgsFull.Contains("--dump-tree"))
|
|
||||||
{
|
{
|
||||||
Console.WriteLine("Dumping tree table.");
|
Console.WriteLine("Dumping tree table.");
|
||||||
AppInfo.Parser.Init(path, Check);
|
File.WriteAllBytes("tree-table.bin", CXML.Parser.GetTreeTable());
|
||||||
File.WriteAllBytes("tree-table.bin", AppInfo.Parser.GetTreeTable());
|
|
||||||
AppInfo.Parser.Term();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"))
|
if (ArgsFull.Contains("-ft") || ArgsFull.Contains("--dump-tree"))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Dumping file table.");
|
Console.WriteLine("Dumping file table.");
|
||||||
AppInfo.Parser.Init(path, Check);
|
File.WriteAllBytes("file-table.bin", CXML.Parser.GetTreeTable());
|
||||||
File.WriteAllBytes("file-table.bin", AppInfo.Parser.GetTreeTable());
|
|
||||||
AppInfo.Parser.Term();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ArgsFull.Contains("-d") || ArgsFull.Contains("--decompile") || args.Length == 1)
|
if (ArgsFull.Contains("-d") || ArgsFull.Contains("--decompile") || args.Length == 1)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Decompiling.");
|
Console.WriteLine("Decompiling.");
|
||||||
AppInfo.Parser.DecompileCXML(path, Check);
|
CXML.Parser.DecompileCXML(path, Check);
|
||||||
|
Console.WriteLine("\n\nDECOMPILATION COMPLETE!");
|
||||||
|
Console.ReadKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
AppInfoCli/packages.config
Normal file
4
AppInfoCli/packages.config
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="DotNetZip" version="1.13.3" targetFramework="net461" />
|
||||||
|
</packages>
|
|
@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.28010.2003
|
VisualStudioVersion = 15.0.28010.2003
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
BIN
packages/DotNetZip.1.13.3/.signature.p7s
vendored
Normal file
BIN
packages/DotNetZip.1.13.3/.signature.p7s
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.3/DotNetZip.1.13.3.nupkg
vendored
Normal file
BIN
packages/DotNetZip.1.13.3/DotNetZip.1.13.3.nupkg
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.3/lib/net40/DotNetZip.dll
vendored
Normal file
BIN
packages/DotNetZip.1.13.3/lib/net40/DotNetZip.dll
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.3/lib/net40/DotNetZip.pdb
vendored
Normal file
BIN
packages/DotNetZip.1.13.3/lib/net40/DotNetZip.pdb
vendored
Normal file
Binary file not shown.
18520
packages/DotNetZip.1.13.3/lib/net40/DotNetZip.xml
vendored
Normal file
18520
packages/DotNetZip.1.13.3/lib/net40/DotNetZip.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/DotNetZip.1.13.3/lib/netstandard2.0/DotNetZip.dll
vendored
Normal file
BIN
packages/DotNetZip.1.13.3/lib/netstandard2.0/DotNetZip.dll
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.3/lib/netstandard2.0/DotNetZip.pdb
vendored
Normal file
BIN
packages/DotNetZip.1.13.3/lib/netstandard2.0/DotNetZip.pdb
vendored
Normal file
Binary file not shown.
18022
packages/DotNetZip.1.13.3/lib/netstandard2.0/DotNetZip.xml
vendored
Normal file
18022
packages/DotNetZip.1.13.3/lib/netstandard2.0/DotNetZip.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user