781 lines
26 KiB
C#
781 lines
26 KiB
C#
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();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|