diff --git a/CXMLCli/CXMLBuilder.cs b/CXMLCli/CXMLBuilder.cs index ac5683d..7979ae5 100644 --- a/CXMLCli/CXMLBuilder.cs +++ b/CXMLCli/CXMLBuilder.cs @@ -1,687 +1,687 @@ -using CXML; -using General; -using Ionic.Zlib; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Xml; - -namespace CXMLDecompiler -{ - class CXMLBuilder - { - String MainDir = ""; - String XMLFilename = ""; - String MagicNumber = ""; - - Endianness FileEndainness; - bool ps3; - Tools tools; - - Int32 Version; - FileStream InfoFile; - - MemoryStream TreeTable; - MemoryStream IDTable; - MemoryStream HashIDTable; - MemoryStream StringTable; - MemoryStream WStringTable; - MemoryStream HashTable; - MemoryStream IntArrayTable; - MemoryStream FloatArrayTable; - MemoryStream FileTable; - - Boolean IsInitalized = false; - - - String SilicaTypingInformation = ""; - public void Init(string XMLFile, string CxmlFile) - { - GetSilicaTypingInformation(XMLFile); - MagicNumber = GetTypingInformation("MAGIC"); - Version = Int32.Parse(GetTypingInformation("VERSION").Replace("0x", ""), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); - - // Determine filetype. - FileEndainness = (Endianness)Enum.Parse(typeof(Endianness), GetTypingInformation("ENDAINESS")); - ps3 = GetTypingInformation("PS3") == "true"; - tools = new Tools((FileEndainness == Endianness.BIG_ENDIAN)); - - InfoFile = File.Open(CxmlFile, FileMode.OpenOrCreate, FileAccess.ReadWrite); - InfoFile.SetLength(0); - - TreeTable = new MemoryStream(); - IDTable = new MemoryStream(); - StringTable = new MemoryStream(); - IntArrayTable = new MemoryStream(); - FloatArrayTable = new MemoryStream(); - FileTable = new MemoryStream(); - - WStringTable = new MemoryStream(); - HashIDTable = new MemoryStream(); +using CXML; +using General; +using Ionic.Zlib; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; + +namespace CXMLDecompiler +{ + class CXMLBuilder + { + String MainDir = ""; + String XMLFilename = ""; + String MagicNumber = ""; + + Endianness FileEndainness; + bool ps3; + Tools tools; + + Int32 Version; + FileStream InfoFile; + + MemoryStream TreeTable; + MemoryStream IDTable; + MemoryStream HashIDTable; + MemoryStream StringTable; + MemoryStream WStringTable; + MemoryStream HashTable; + MemoryStream IntArrayTable; + MemoryStream FloatArrayTable; + MemoryStream FileTable; + + Boolean IsInitalized = false; + + + String SilicaTypingInformation = ""; + public void Init(string XMLFile, string CxmlFile) + { + GetSilicaTypingInformation(XMLFile); + MagicNumber = GetTypingInformation("MAGIC"); + Version = Int32.Parse(GetTypingInformation("VERSION").Replace("0x", ""), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); + + // Determine filetype. + FileEndainness = (Endianness)Enum.Parse(typeof(Endianness), GetTypingInformation("ENDAINESS")); + ps3 = GetTypingInformation("PS3") == "true"; + tools = new Tools((FileEndainness == Endianness.BIG_ENDIAN)); + + InfoFile = File.Open(CxmlFile, FileMode.OpenOrCreate, FileAccess.ReadWrite); + InfoFile.SetLength(0); + + TreeTable = new MemoryStream(); + IDTable = new MemoryStream(); + StringTable = new MemoryStream(); + IntArrayTable = new MemoryStream(); + FloatArrayTable = new MemoryStream(); + FileTable = new MemoryStream(); + + WStringTable = new MemoryStream(); + HashIDTable = new MemoryStream(); HashTable = new MemoryStream(); - XMLFilename = XMLFile; - MainDir = Path.GetDirectoryName(XMLFilename); - - IsInitalized = true; - - return; - } - public void GetSilicaTypingInformation(string XmlFileName) - { - if (XmlFileName.Contains(""; - string xmlData = File.ReadAllText(XmlFileName); - int ind1 = xmlData.IndexOf(SearchFor); - xmlData = xmlData.Substring(ind1 + SearchFor.Length); - int ind2 = xmlData.IndexOf(SearchFor2); - xmlData = xmlData.Substring(0, ind2); - SilicaTypingInformation = xmlData; - } - public string GetTypingInformation(string Key) - { - string[] typeinf = SilicaTypingInformation.Split(','); - foreach(string type in typeinf) - { - string[] keyValuePair = type.Split('='); - if (keyValuePair[0] == Key) - return keyValuePair[1]; - } - return "0"; - } - public class StringTableEntry - { - public int offset; - public string name; - } - public class HashTableEntry - { - public int offset; - public int value; - } - public class IDTableEntry - { - public int offset; - public string value; - public int loopbackOffset; - } - public class HashIDTableEntry - { - public int offset; - public int value; - public int loopbackOffset; - } - - public class TreeTableEntry - { - public int offset; - public XmlNode node; - } - List TreeTableEntries = new List(); - List StringTableEntries = new List(); - List WStringTableEntries = new List(); - List HashTableEntries = new List(); - List IntArrayTableEntries = new List(); - List FloatArrayTableEntries = new List(); - List FileTableEntries = new List(); - List IDTableEntries = new List(); - List HashIDTableEntries = new List(); - public int AddGetTreeTable(XmlNode node) - { - if (!(node.NodeType == XmlNodeType.Element || node.NodeType == XmlNodeType.EndElement || node.NodeType == XmlNodeType.Attribute)) - return -1; - foreach (TreeTableEntry entry in TreeTableEntries) - if (entry.node == node) - return entry.offset; - - TreeTableEntry ent = new TreeTableEntry(); - ent.node = node; - ent.offset = Convert.ToInt32(TreeTable.Position); - TreeTableEntries.Add(ent); - WriteElement(node); - - return ent.offset; - } - - public int AddGetHashIdTable(int value, int loopbackPtr) - { - foreach (HashIDTableEntry entry in HashIDTableEntries) - { - - if (entry.loopbackOffset == loopbackPtr && loopbackPtr != -1) - { - return entry.offset; - } - else if (entry.value == value) - { - if (loopbackPtr == -1) - return entry.offset; - entry.loopbackOffset = loopbackPtr; - long position1 = HashIDTable.Position; - HashIDTable.Seek(entry.offset, SeekOrigin.Begin); - tools.WriteInt32(HashIDTable, loopbackPtr); - HashIDTable.Seek(position1, SeekOrigin.Begin); - return entry.offset; - } - } - HashIDTableEntry ent = new HashIDTableEntry(); - ent.value = value; - ent.loopbackOffset = loopbackPtr; - ent.offset = Convert.ToInt32(HashIDTable.Position); - HashIDTableEntries.Add(ent); - - tools.WriteInt32(HashIDTable, loopbackPtr); - tools.WriteInt32(HashIDTable, value); - - return ent.offset; - } - public int AddGetIdTable(string value, int loopbackPtr) - { - foreach (IDTableEntry entry in IDTableEntries) - { - if (entry.loopbackOffset == loopbackPtr && loopbackPtr != -1) - { - return entry.offset; - } - else if (entry.value == value) - { - if (loopbackPtr == -1) - return entry.offset; - entry.loopbackOffset = loopbackPtr; - long position1 = IDTable.Position; - IDTable.Seek(entry.offset, SeekOrigin.Begin); - tools.WriteInt32(IDTable, loopbackPtr); - IDTable.Seek(position1, SeekOrigin.Begin); - return entry.offset; - } - } - IDTableEntry ent = new IDTableEntry(); - ent.value = value; - ent.loopbackOffset = loopbackPtr; - ent.offset = Convert.ToInt32(IDTable.Position); + XMLFilename = XMLFile; + MainDir = Path.GetDirectoryName(XMLFilename); + + IsInitalized = true; + + return; + } + public void GetSilicaTypingInformation(string XmlFileName) + { + if (XmlFileName.Contains(""; + string xmlData = File.ReadAllText(XmlFileName); + int ind1 = xmlData.IndexOf(SearchFor); + xmlData = xmlData.Substring(ind1 + SearchFor.Length); + int ind2 = xmlData.IndexOf(SearchFor2); + xmlData = xmlData.Substring(0, ind2); + SilicaTypingInformation = xmlData; + } + public string GetTypingInformation(string Key) + { + string[] typeinf = SilicaTypingInformation.Split(','); + foreach(string type in typeinf) + { + string[] keyValuePair = type.Split('='); + if (keyValuePair[0] == Key) + return keyValuePair[1]; + } + return "0"; + } + public class StringTableEntry + { + public int offset; + public string name; + } + public class HashTableEntry + { + public int offset; + public int value; + } + public class IDTableEntry + { + public int offset; + public string value; + public int loopbackOffset; + } + public class HashIDTableEntry + { + public int offset; + public int value; + public int loopbackOffset; + } + + public class TreeTableEntry + { + public int offset; + public XmlNode node; + } + List TreeTableEntries = new List(); + List StringTableEntries = new List(); + List WStringTableEntries = new List(); + List HashTableEntries = new List(); + List IntArrayTableEntries = new List(); + List FloatArrayTableEntries = new List(); + List FileTableEntries = new List(); + List IDTableEntries = new List(); + List HashIDTableEntries = new List(); + public int AddGetTreeTable(XmlNode node) + { + if (!(node.NodeType == XmlNodeType.Element || node.NodeType == XmlNodeType.EndElement || node.NodeType == XmlNodeType.Attribute)) + return -1; + foreach (TreeTableEntry entry in TreeTableEntries) + if (entry.node == node) + return entry.offset; + + TreeTableEntry ent = new TreeTableEntry(); + ent.node = node; + ent.offset = Convert.ToInt32(TreeTable.Position); + TreeTableEntries.Add(ent); + WriteElement(node); + + return ent.offset; + } + + public int AddGetHashIdTable(int value, int loopbackPtr) + { + foreach (HashIDTableEntry entry in HashIDTableEntries) + { + + if (entry.loopbackOffset == loopbackPtr && loopbackPtr != -1) + { + return entry.offset; + } + else if (entry.value == value) + { + if (loopbackPtr == -1) + return entry.offset; + entry.loopbackOffset = loopbackPtr; + long position1 = HashIDTable.Position; + HashIDTable.Seek(entry.offset, SeekOrigin.Begin); + tools.WriteInt32(HashIDTable, loopbackPtr); + HashIDTable.Seek(position1, SeekOrigin.Begin); + return entry.offset; + } + } + HashIDTableEntry ent = new HashIDTableEntry(); + ent.value = value; + ent.loopbackOffset = loopbackPtr; + ent.offset = Convert.ToInt32(HashIDTable.Position); + HashIDTableEntries.Add(ent); + + tools.WriteInt32(HashIDTable, loopbackPtr); + tools.WriteInt32(HashIDTable, value); + + return ent.offset; + } + public int AddGetIdTable(string value, int loopbackPtr) + { + foreach (IDTableEntry entry in IDTableEntries) + { + if (entry.loopbackOffset == loopbackPtr && loopbackPtr != -1) + { + return entry.offset; + } + else if (entry.value == value) + { + if (loopbackPtr == -1) + return entry.offset; + entry.loopbackOffset = loopbackPtr; + long position1 = IDTable.Position; + IDTable.Seek(entry.offset, SeekOrigin.Begin); + tools.WriteInt32(IDTable, loopbackPtr); + IDTable.Seek(position1, SeekOrigin.Begin); + return entry.offset; + } + } + IDTableEntry ent = new IDTableEntry(); + ent.value = value; + ent.loopbackOffset = loopbackPtr; + ent.offset = Convert.ToInt32(IDTable.Position); IDTableEntries.Add(ent); - tools.WriteInt32(IDTable, loopbackPtr); - Tools.WriteStringToStream(IDTable, value); - IDTable.WriteByte(0x00); - - - if (loopbackPtr != -1 && !ps3) - { - Align(IDTable, 4); - } - - return ent.offset; - } - public int AddGetFileTable(byte[] value, string filename) - { - foreach (StringTableEntry entry in FileTableEntries) - if (entry.name == filename) - return entry.offset; - - StringTableEntry ent = new StringTableEntry(); - ent.name = filename; - ent.offset = Convert.ToInt32(FileTable.Position); - FileTableEntries.Add(ent); - - FileTable.Write(value, 0x00, value.Length); - Align(FileTable, 0x10); - - return ent.offset; - } - public int AddGetFloatArrayTable(float[] value) - { - float[] Test = new float[value.Length]; - float[] TestAgainst = FloatArrayTableEntries.ToArray(); - for (int i = 0; i < TestAgainst.Length; i += 1) - { - if (i + value.Length > TestAgainst.Length) - break; - Array.ConstrainedCopy(TestAgainst, i, Test, 0, value.Length); - if(value.SequenceEqual(Test)) - return i; - } - int offset = Convert.ToInt32(FloatArrayTable.Position) / 4; - - foreach (float i in value) - { - tools.WriteSingle(FloatArrayTable, i); - FloatArrayTableEntries.Add(i); - } - - return offset; - } - public int AddGetIntArrayTable(int[] value) - { - int[] Test = new int[value.Length]; - int[] TestAgainst = IntArrayTableEntries.ToArray(); - for (int i = 0; i < TestAgainst.Length; i += 1) - { - if (i + value.Length > TestAgainst.Length) - break; - Array.ConstrainedCopy(TestAgainst, i, Test, 0, value.Length); - if (value.SequenceEqual(Test)) - return i; - } - int offset = Convert.ToInt32(IntArrayTable.Position) / 4; - - foreach (int i in value) - { - tools.WriteInt32(IntArrayTable, i); - IntArrayTableEntries.Add(i); - } - - return offset; - } - public int AddGetHashTable(int value) - { - foreach (HashTableEntry entry in HashTableEntries) - if (entry.value == value) - return entry.offset/4; - - HashTableEntry ent = new HashTableEntry(); - ent.value = value; - ent.offset = Convert.ToInt32(HashTable.Position); - HashTableEntries.Add(ent); - - tools.WriteInt32(HashTable, value); - - return ent.offset/4; - } - public int AddGetStringTable(string elementName) - { - foreach(StringTableEntry entry in StringTableEntries) - if (entry.name == elementName) - return entry.offset; - - StringTableEntry ent = new StringTableEntry(); - ent.name = elementName; - ent.offset = Convert.ToInt32(StringTable.Position); - StringTableEntries.Add(ent); - - Tools.WriteStringToStream(StringTable, elementName); - StringTable.WriteByte(0x00); - - return ent.offset; - } - public int AddGetWstringTable(string elementName) - { - foreach (StringTableEntry entry in WStringTableEntries) - if (entry.name == elementName) - return entry.offset; - - StringTableEntry ent = new StringTableEntry(); - ent.name = elementName; - ent.offset = Convert.ToInt32(WStringTable.Position)/2; - WStringTableEntries.Add(ent); - - Tools.WriteUtf16StringToStream(WStringTable, elementName); - WStringTable.WriteByte(0x00); - WStringTable.WriteByte(0x00); - - return ent.offset; - } + tools.WriteInt32(IDTable, loopbackPtr); + Tools.WriteStringToStream(IDTable, value); + IDTable.WriteByte(0x00); + + + if (loopbackPtr != -1 && !ps3) + { + Align(IDTable, 4); + } + + return ent.offset; + } + public int AddGetFileTable(byte[] value, string hash) + { + foreach (StringTableEntry entry in FileTableEntries) + if (entry.name == hash) + return entry.offset; + + StringTableEntry ent = new StringTableEntry(); + ent.name = Tools.GenerateHash(value); + ent.offset = Convert.ToInt32(FileTable.Position); + FileTableEntries.Add(ent); + + FileTable.Write(value, 0x00, value.Length); + Align(FileTable, 0x10); + + return ent.offset; + } + public int AddGetFloatArrayTable(float[] value) + { + float[] Test = new float[value.Length]; + float[] TestAgainst = FloatArrayTableEntries.ToArray(); + for (int i = 0; i < TestAgainst.Length; i += 1) + { + if (i + value.Length > TestAgainst.Length) + break; + Array.ConstrainedCopy(TestAgainst, i, Test, 0, value.Length); + if(value.SequenceEqual(Test)) + return i; + } + int offset = Convert.ToInt32(FloatArrayTable.Position) / 4; + + foreach (float i in value) + { + tools.WriteSingle(FloatArrayTable, i); + FloatArrayTableEntries.Add(i); + } + + return offset; + } + public int AddGetIntArrayTable(int[] value) + { + int[] Test = new int[value.Length]; + int[] TestAgainst = IntArrayTableEntries.ToArray(); + for (int i = 0; i < TestAgainst.Length; i += 1) + { + if (i + value.Length > TestAgainst.Length) + break; + Array.ConstrainedCopy(TestAgainst, i, Test, 0, value.Length); + if (value.SequenceEqual(Test)) + return i; + } + int offset = Convert.ToInt32(IntArrayTable.Position) / 4; + + foreach (int i in value) + { + tools.WriteInt32(IntArrayTable, i); + IntArrayTableEntries.Add(i); + } + + return offset; + } + public int AddGetHashTable(int value) + { + foreach (HashTableEntry entry in HashTableEntries) + if (entry.value == value) + return entry.offset/4; + + HashTableEntry ent = new HashTableEntry(); + ent.value = value; + ent.offset = Convert.ToInt32(HashTable.Position); + HashTableEntries.Add(ent); + + tools.WriteInt32(HashTable, value); + + return ent.offset/4; + } + public int AddGetStringTable(string elementName) + { + foreach(StringTableEntry entry in StringTableEntries) + if (entry.name == elementName) + return entry.offset; + + StringTableEntry ent = new StringTableEntry(); + ent.name = elementName; + ent.offset = Convert.ToInt32(StringTable.Position); + StringTableEntries.Add(ent); + + Tools.WriteStringToStream(StringTable, elementName); + StringTable.WriteByte(0x00); + + return ent.offset; + } + public int AddGetWstringTable(string elementName) + { + foreach (StringTableEntry entry in WStringTableEntries) + if (entry.name == elementName) + return entry.offset; + + StringTableEntry ent = new StringTableEntry(); + ent.name = elementName; + ent.offset = Convert.ToInt32(WStringTable.Position)/2; + WStringTableEntries.Add(ent); + + Tools.WriteUtf16StringToStream(WStringTable, elementName); + WStringTable.WriteByte(0x00); + WStringTable.WriteByte(0x00); + + return ent.offset; + } public int ConvertAttributeTypeToInt(AttributeType type) { if (!ps3) return (int) type; else return (int) (AttributeTypePs3)Enum.Parse(typeof(AttributeTypePs3), type.ToString()); - } - public AttributeType DetermineType(string ElementName, string AttributeName) - { - return (AttributeType)Enum.Parse(typeof(AttributeType), GetTypingInformation(ElementName + ":" + AttributeName)); - } - public void WriteAttribute(XmlAttribute attribute, MemoryStream WorkRam, string ElementName) - { - int AttributePtr = AddGetStringTable(attribute.Name); - AttributeType Type = DetermineType(ElementName, attribute.Name); - tools.WriteInt32(WorkRam, AttributePtr); - tools.WriteInt32(WorkRam, ConvertAttributeTypeToInt(Type)); - Console.WriteLine("AttributeType: " + Type.ToString()); - switch (Type) - { - case AttributeType.TYPE_INT: - int intWrite = Int32.Parse(attribute.Value, CultureInfo.InvariantCulture); - tools.WriteInt32(WorkRam, intWrite); - tools.WriteInt32(WorkRam, 0x00); - Console.WriteLine("Int: " + intWrite.ToString()); - break; - case AttributeType.TYPE_FLOAT: - float FloatValue = Single.Parse(attribute.Value.Replace("f", ""), CultureInfo.InvariantCulture); - tools.WriteSingle(WorkRam, FloatValue); - tools.WriteInt32(WorkRam, 0x00); - Console.WriteLine("Float: " + FloatValue.ToString()); - break; - case AttributeType.TYPE_STRING: - int StringOffset = AddGetStringTable(attribute.Value); - int StringLen = Encoding.UTF8.GetBytes(attribute.Value).Length; - tools.WriteInt32(WorkRam, StringOffset); - tools.WriteInt32(WorkRam, StringLen); - Console.WriteLine("String: " + attribute.Value); - break; - case AttributeType.TYPE_WSTRING: - int WStringOffset = AddGetWstringTable(attribute.Value); - int WStringLength = Encoding.Unicode.GetBytes(attribute.Value).Length; - tools.WriteInt32(WorkRam, WStringOffset); - tools.WriteInt32(WorkRam, WStringLength); - Console.WriteLine("WString: " + attribute.Value); - break; - case AttributeType.TYPE_HASH: - int hashId = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture); - int HashTableOffset = AddGetHashTable(hashId); - int HashTableSize = 4; - tools.WriteInt32(WorkRam, HashTableOffset); - tools.WriteInt32(WorkRam, HashTableSize); - Console.WriteLine("Hash Offset:" + HashTableOffset.ToString() + " size: " + HashTableSize); - break; - case AttributeType.TYPE_INTEGER_ARRAY: - string[] arr = attribute.Value.Replace("[", "").Replace("]", "").Replace(" ", "").Split(','); - int[] intArr = new int[arr.Length]; - for (int i = 0; i < intArr.Length; i++) - intArr[i] = Int32.Parse(arr[i], CultureInfo.InvariantCulture); - - int IntArrayOffset = AddGetIntArrayTable(intArr); - int IntArraySize = intArr.Length; - tools.WriteInt32(WorkRam, IntArrayOffset); - tools.WriteInt32(WorkRam, IntArraySize); - - Console.WriteLine("Int Array: " + attribute.Value); - break; - case AttributeType.TYPE_FLOAT_ARRAY: - arr = attribute.Value.Replace("[", "").Replace("]", "").Replace(" ", "").Replace("f", "").Split(','); - float[] floatArr = new float[arr.Length]; - for (int i = 0; i < floatArr.Length; i++) - floatArr[i] = Single.Parse(arr[i], CultureInfo.InvariantCulture); - - int FloatArrayOffset = AddGetFloatArrayTable(floatArr); - int FloatArraySize = floatArr.Length; - tools.WriteInt32(WorkRam, FloatArrayOffset); - tools.WriteInt32(WorkRam, FloatArraySize); - - Console.WriteLine("Float Array: " + attribute.Value); - break; - case AttributeType.TYPE_FILE: - string fPath = Path.Combine(MainDir, attribute.Value); - byte[] data = File.ReadAllBytes(fPath); - int FilePtr = AddGetFileTable(data, Path.Combine(Environment.CurrentDirectory, fPath)); - int FileSz = data.Length; - tools.WriteInt32(WorkRam, FilePtr); - tools.WriteInt32(WorkRam, FileSz); - Console.WriteLine("Reading File: " + fPath); - break; - case AttributeType.TYPE_ID_REF: - int IdTableOffset = AddGetIdTable(attribute.Value, Convert.ToInt32(TreeTable.Position)); - tools.WriteInt32(WorkRam, IdTableOffset); - tools.WriteInt32(WorkRam, 0x00); - Console.WriteLine("ID Ref: " + ElementName + " " + TreeTable.Position.ToString("X") + " (" + TreeTable.Position.ToString("X") + ")"); - Console.WriteLine("ID Ref Offset: " + IdTableOffset + " sz: 0"); - break; - case AttributeType.TYPE_ID: - IdTableOffset = AddGetIdTable(attribute.Value, -1); - tools.WriteInt32(WorkRam, IdTableOffset); - tools.WriteInt32(WorkRam, 0x00); - Console.WriteLine("ID : " + IdTableOffset + " sz: 0"); - break; - case AttributeType.TYPE_ID_HASH_REF: - int hash = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture); - int HashIdTableOffset = AddGetHashIdTable(hash, Convert.ToInt32(TreeTable.Position)); - tools.WriteInt32(WorkRam, HashIdTableOffset); - tools.WriteInt32(WorkRam, 0x00); - Console.WriteLine("Hash ID Ref: " + ElementName + " " + TreeTable.Position.ToString("X") + " (" + TreeTable.Position.ToString("X") + ")"); - Console.WriteLine("Hash ID REF offset: " + HashIdTableOffset + " sz: 0"); - break; - case AttributeType.TYPE_ID_HASH: - hash = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture); - HashIdTableOffset = AddGetHashIdTable(hash, -1); - - tools.WriteInt32(WorkRam, HashIdTableOffset); - tools.WriteInt32(WorkRam, 0x00); - Console.WriteLine("Hash ID: " + HashIdTableOffset + " sz: 0"); + } + public AttributeType DetermineType(string ElementName, string AttributeName) + { + return (AttributeType)Enum.Parse(typeof(AttributeType), GetTypingInformation(ElementName + ":" + AttributeName)); + } + public void WriteAttribute(XmlAttribute attribute, MemoryStream WorkRam, string ElementName) + { + int AttributePtr = AddGetStringTable(attribute.Name); + AttributeType Type = DetermineType(ElementName, attribute.Name); + tools.WriteInt32(WorkRam, AttributePtr); + tools.WriteInt32(WorkRam, ConvertAttributeTypeToInt(Type)); + Console.WriteLine("AttributeType: " + Type.ToString()); + switch (Type) + { + case AttributeType.TYPE_INT: + int intWrite = Int32.Parse(attribute.Value, CultureInfo.InvariantCulture); + tools.WriteInt32(WorkRam, intWrite); + tools.WriteInt32(WorkRam, 0x00); + Console.WriteLine("Int: " + intWrite.ToString()); break; - case AttributeType.TYPE_NONE: - break; - default: - throw new NotImplementedException("UNKNOWN TYPE @ " + TreeTable.Position); - break; - } - Console.WriteLine(attribute.Name + "=" + attribute.Value); - } - public void WriteElement(XmlNode node) - { - MemoryStream WorkRam = new MemoryStream(); - - int ElementPtr = AddGetStringTable(node.Name); - int NumAttributes = 0; - int ParentPtr = -1; - int PrevSibling = -1; - int NextSibling = -1; - - int FirstChild = -1; - int LastChild = -1; - long Position = TreeTable.Position; - tools.WriteInt32(WorkRam, ElementPtr); - tools.WriteInt32(WorkRam, NumAttributes); - tools.WriteInt32(WorkRam, ParentPtr); - tools.WriteInt32(WorkRam, PrevSibling); - tools.WriteInt32(WorkRam, NextSibling); - tools.WriteInt32(WorkRam, FirstChild); - tools.WriteInt32(WorkRam, LastChild); - - foreach (XmlAttribute attribute in node.Attributes) - { - WriteAttribute(attribute, WorkRam, node.Name); - } - - - WorkRam.Seek(0x00, SeekOrigin.Begin); - WorkRam.CopyTo(TreeTable); - - foreach (XmlNode childNode in node.ChildNodes) - { - if(childNode != null) - AddGetTreeTable(childNode); - } - // Rewrite header now - - if (node.Attributes != null) - NumAttributes = node.Attributes.Count; - if (node.ParentNode != null) - ParentPtr = AddGetTreeTable(node.ParentNode); - if (node.PreviousSibling != null) - PrevSibling = AddGetTreeTable(node.PreviousSibling); - if (node.NextSibling != null) - NextSibling = AddGetTreeTable(node.NextSibling); - if (node.FirstChild != null) - FirstChild = AddGetTreeTable(node.FirstChild); - if (node.LastChild != null) - LastChild = AddGetTreeTable(node.LastChild); - - long Position2 = TreeTable.Position; + case AttributeType.TYPE_FLOAT: + float FloatValue = Single.Parse(attribute.Value.Replace("f", ""), CultureInfo.InvariantCulture); + tools.WriteSingle(WorkRam, FloatValue); + tools.WriteInt32(WorkRam, 0x00); + Console.WriteLine("Float: " + FloatValue.ToString()); + break; + case AttributeType.TYPE_STRING: + int StringOffset = AddGetStringTable(attribute.Value); + int StringLen = Encoding.UTF8.GetBytes(attribute.Value).Length; + tools.WriteInt32(WorkRam, StringOffset); + tools.WriteInt32(WorkRam, StringLen); + Console.WriteLine("String: " + attribute.Value); + break; + case AttributeType.TYPE_WSTRING: + int WStringOffset = AddGetWstringTable(attribute.Value); + int WStringLength = Encoding.Unicode.GetBytes(attribute.Value).Length; + tools.WriteInt32(WorkRam, WStringOffset); + tools.WriteInt32(WorkRam, WStringLength); + Console.WriteLine("WString: " + attribute.Value); + break; + case AttributeType.TYPE_HASH: + int hashId = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + int HashTableOffset = AddGetHashTable(hashId); + int HashTableSize = 4; + tools.WriteInt32(WorkRam, HashTableOffset); + tools.WriteInt32(WorkRam, HashTableSize); + Console.WriteLine("Hash Offset:" + HashTableOffset.ToString() + " size: " + HashTableSize); + break; + case AttributeType.TYPE_INTEGER_ARRAY: + string[] arr = attribute.Value.Replace("[", "").Replace("]", "").Replace(" ", "").Split(','); + int[] intArr = new int[arr.Length]; + for (int i = 0; i < intArr.Length; i++) + intArr[i] = Int32.Parse(arr[i], CultureInfo.InvariantCulture); + + int IntArrayOffset = AddGetIntArrayTable(intArr); + int IntArraySize = intArr.Length; + tools.WriteInt32(WorkRam, IntArrayOffset); + tools.WriteInt32(WorkRam, IntArraySize); + + Console.WriteLine("Int Array: " + attribute.Value); + break; + case AttributeType.TYPE_FLOAT_ARRAY: + arr = attribute.Value.Replace("[", "").Replace("]", "").Replace(" ", "").Replace("f", "").Split(','); + float[] floatArr = new float[arr.Length]; + for (int i = 0; i < floatArr.Length; i++) + floatArr[i] = Single.Parse(arr[i], CultureInfo.InvariantCulture); + + int FloatArrayOffset = AddGetFloatArrayTable(floatArr); + int FloatArraySize = floatArr.Length; + tools.WriteInt32(WorkRam, FloatArrayOffset); + tools.WriteInt32(WorkRam, FloatArraySize); + + Console.WriteLine("Float Array: " + attribute.Value); + break; + case AttributeType.TYPE_FILE: + string fPath = Path.Combine(MainDir, attribute.Value); + byte[] data = File.ReadAllBytes(fPath); + int FilePtr = AddGetFileTable(data, Tools.GenerateHash(data)); + int FileSz = data.Length; + tools.WriteInt32(WorkRam, FilePtr); + tools.WriteInt32(WorkRam, FileSz); + Console.WriteLine("Reading File: " + fPath); + break; + case AttributeType.TYPE_ID_REF: + int IdTableOffset = AddGetIdTable(attribute.Value, Convert.ToInt32(TreeTable.Position)); + tools.WriteInt32(WorkRam, IdTableOffset); + tools.WriteInt32(WorkRam, 0x00); + Console.WriteLine("ID Ref: " + ElementName + " " + TreeTable.Position.ToString("X") + " (" + TreeTable.Position.ToString("X") + ")"); + Console.WriteLine("ID Ref Offset: " + IdTableOffset + " sz: 0"); + break; + case AttributeType.TYPE_ID: + IdTableOffset = AddGetIdTable(attribute.Value, -1); + tools.WriteInt32(WorkRam, IdTableOffset); + tools.WriteInt32(WorkRam, 0x00); + Console.WriteLine("ID : " + IdTableOffset + " sz: 0"); + break; + case AttributeType.TYPE_ID_HASH_REF: + int hash = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + int HashIdTableOffset = AddGetHashIdTable(hash, Convert.ToInt32(TreeTable.Position)); + tools.WriteInt32(WorkRam, HashIdTableOffset); + tools.WriteInt32(WorkRam, 0x00); + Console.WriteLine("Hash ID Ref: " + ElementName + " " + TreeTable.Position.ToString("X") + " (" + TreeTable.Position.ToString("X") + ")"); + Console.WriteLine("Hash ID REF offset: " + HashIdTableOffset + " sz: 0"); + break; + case AttributeType.TYPE_ID_HASH: + hash = Int32.Parse(CXMLSymbols.LookupId(attribute.Value), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + HashIdTableOffset = AddGetHashIdTable(hash, -1); + + tools.WriteInt32(WorkRam, HashIdTableOffset); + tools.WriteInt32(WorkRam, 0x00); + Console.WriteLine("Hash ID: " + HashIdTableOffset + " sz: 0"); + break; + case AttributeType.TYPE_NONE: + break; + default: + throw new NotImplementedException("UNKNOWN TYPE @ " + TreeTable.Position); + break; + } + Console.WriteLine(attribute.Name + "=" + attribute.Value); + } + public void WriteElement(XmlNode node) + { + MemoryStream WorkRam = new MemoryStream(); + + int ElementPtr = AddGetStringTable(node.Name); + int NumAttributes = 0; + int ParentPtr = -1; + int PrevSibling = -1; + int NextSibling = -1; + + int FirstChild = -1; + int LastChild = -1; + long Position = TreeTable.Position; + tools.WriteInt32(WorkRam, ElementPtr); + tools.WriteInt32(WorkRam, NumAttributes); + tools.WriteInt32(WorkRam, ParentPtr); + tools.WriteInt32(WorkRam, PrevSibling); + tools.WriteInt32(WorkRam, NextSibling); + tools.WriteInt32(WorkRam, FirstChild); + tools.WriteInt32(WorkRam, LastChild); + + foreach (XmlAttribute attribute in node.Attributes) + { + WriteAttribute(attribute, WorkRam, node.Name); + } + + + WorkRam.Seek(0x00, SeekOrigin.Begin); + WorkRam.CopyTo(TreeTable); + + foreach (XmlNode childNode in node.ChildNodes) + { + if(childNode != null) + AddGetTreeTable(childNode); + } + // Rewrite header now + + if (node.Attributes != null) + NumAttributes = node.Attributes.Count; + if (node.ParentNode != null) + ParentPtr = AddGetTreeTable(node.ParentNode); + if (node.PreviousSibling != null) + PrevSibling = AddGetTreeTable(node.PreviousSibling); + if (node.NextSibling != null) + NextSibling = AddGetTreeTable(node.NextSibling); + if (node.FirstChild != null) + FirstChild = AddGetTreeTable(node.FirstChild); + if (node.LastChild != null) + LastChild = AddGetTreeTable(node.LastChild); + + long Position2 = TreeTable.Position; TreeTable.Seek(Position, SeekOrigin.Begin); - tools.WriteInt32(TreeTable, ElementPtr); - tools.WriteInt32(TreeTable, NumAttributes); - tools.WriteInt32(TreeTable, ParentPtr); - tools.WriteInt32(TreeTable, PrevSibling); - tools.WriteInt32(TreeTable, NextSibling); - tools.WriteInt32(TreeTable, FirstChild); - tools.WriteInt32(TreeTable, LastChild); - TreeTable.Seek(Position2, SeekOrigin.Begin); - } - - public void Align(Stream s, int align) - { - - int size = Convert.ToInt32(s.Length); - - if (size % align != 0) - { - int totalAlign = (align - (size % align)); - for (int i = 0; i < totalAlign; i++) - { - s.WriteByte(0x00); - } - } - } - - public void Term() - { - InfoFile.Close(); - TreeTable.Close(); - IDTable.Close(); - HashIDTable.Close(); - StringTable.Close(); - WStringTable.Close(); - HashTable.Close(); - IntArrayTable.Close(); - FloatArrayTable.Close(); - FileTable.Close(); - - - TreeTableEntries.Clear(); - StringTableEntries.Clear(); - WStringTableEntries.Clear(); - HashTableEntries.Clear(); - IntArrayTableEntries.Clear(); - FloatArrayTableEntries.Clear(); - FileTableEntries.Clear(); - IDTableEntries.Clear(); - HashIDTableEntries.Clear(); - - IsInitalized = false; - } - - public void BuildCXML(string XmlFile, string CxmlFile) - { - if (!IsInitalized) - Init(XmlFile, CxmlFile); - Console.WriteLine("Magic Number: " + MagicNumber); - Console.WriteLine("Version: " + Version.ToString("X")); - - XmlDocument XMLFile = new XmlDocument(); - XMLFile.Load(XmlFile); - - Tools.WriteStringToStream(InfoFile, MagicNumber); - Tools.WriteLittleEndainInt(InfoFile, Version); - byte[] headerPlaceholder; + tools.WriteInt32(TreeTable, ElementPtr); + tools.WriteInt32(TreeTable, NumAttributes); + tools.WriteInt32(TreeTable, ParentPtr); + tools.WriteInt32(TreeTable, PrevSibling); + tools.WriteInt32(TreeTable, NextSibling); + tools.WriteInt32(TreeTable, FirstChild); + tools.WriteInt32(TreeTable, LastChild); + TreeTable.Seek(Position2, SeekOrigin.Begin); + } + + public void Align(Stream s, int align) + { + + int size = Convert.ToInt32(s.Length); + + if (size % align != 0) + { + int totalAlign = (align - (size % align)); + for (int i = 0; i < totalAlign; i++) + { + s.WriteByte(0x00); + } + } + } + + public void Term() + { + InfoFile.Close(); + TreeTable.Close(); + IDTable.Close(); + HashIDTable.Close(); + StringTable.Close(); + WStringTable.Close(); + HashTable.Close(); + IntArrayTable.Close(); + FloatArrayTable.Close(); + FileTable.Close(); + + + TreeTableEntries.Clear(); + StringTableEntries.Clear(); + WStringTableEntries.Clear(); + HashTableEntries.Clear(); + IntArrayTableEntries.Clear(); + FloatArrayTableEntries.Clear(); + FileTableEntries.Clear(); + IDTableEntries.Clear(); + HashIDTableEntries.Clear(); + + IsInitalized = false; + } + + public void BuildCXML(string XmlFile, string CxmlFile) + { + if (!IsInitalized) + Init(XmlFile, CxmlFile); + Console.WriteLine("Magic Number: " + MagicNumber); + Console.WriteLine("Version: " + Version.ToString("X")); + + XmlDocument XMLFile = new XmlDocument(); + XMLFile.Load(XmlFile); + + Tools.WriteStringToStream(InfoFile, MagicNumber); + Tools.WriteLittleEndainInt(InfoFile, Version); + byte[] headerPlaceholder; if (!ps3) headerPlaceholder = new byte[0x48]; else headerPlaceholder = new byte[0x30]; - InfoFile.Write(headerPlaceholder, 0x00, headerPlaceholder.Length); - Align(InfoFile, 0x10); - - foreach (XmlNode childNode in XMLFile.ChildNodes) - { - AddGetTreeTable(childNode); - } - - int TreeTableOffset = Convert.ToInt32(InfoFile.Position); - int TreeTableSize = Convert.ToInt32(TreeTable.Length); - Align(TreeTable, 0x10); - TreeTable.Seek(0x00, SeekOrigin.Begin); - TreeTable.CopyTo(InfoFile); - - - int IdTableOffset = Convert.ToInt32(InfoFile.Position); - int IdTableSize = Convert.ToInt32(IDTable.Length); - Align(IDTable, 0x10); - IDTable.Seek(0x00, SeekOrigin.Begin); - IDTable.CopyTo(InfoFile); - - int HashIdTableOffset = Convert.ToInt32(InfoFile.Position); - int HashIdTableSize = Convert.ToInt32(HashIDTable.Length); - Align(HashIDTable, 0x10); - HashIDTable.Seek(0x00, SeekOrigin.Begin); - HashIDTable.CopyTo(InfoFile); - - int StringTableOffset = Convert.ToInt32(InfoFile.Position); - int StringTableSize = Convert.ToInt32(StringTable.Length); - Align(StringTable, 0x10); - StringTable.Seek(0x00, SeekOrigin.Begin); + InfoFile.Write(headerPlaceholder, 0x00, headerPlaceholder.Length); + Align(InfoFile, 0x10); + + foreach (XmlNode childNode in XMLFile.ChildNodes) + { + AddGetTreeTable(childNode); + } + + int TreeTableOffset = Convert.ToInt32(InfoFile.Position); + int TreeTableSize = Convert.ToInt32(TreeTable.Length); + Align(TreeTable, 0x10); + TreeTable.Seek(0x00, SeekOrigin.Begin); + TreeTable.CopyTo(InfoFile); + + + int IdTableOffset = Convert.ToInt32(InfoFile.Position); + int IdTableSize = Convert.ToInt32(IDTable.Length); + Align(IDTable, 0x10); + IDTable.Seek(0x00, SeekOrigin.Begin); + IDTable.CopyTo(InfoFile); + + int HashIdTableOffset = Convert.ToInt32(InfoFile.Position); + int HashIdTableSize = Convert.ToInt32(HashIDTable.Length); + Align(HashIDTable, 0x10); + HashIDTable.Seek(0x00, SeekOrigin.Begin); + HashIDTable.CopyTo(InfoFile); + + int StringTableOffset = Convert.ToInt32(InfoFile.Position); + int StringTableSize = Convert.ToInt32(StringTable.Length); + Align(StringTable, 0x10); + StringTable.Seek(0x00, SeekOrigin.Begin); StringTable.CopyTo(InfoFile); - - int WStringTableOffset = Convert.ToInt32(InfoFile.Position); - int WStringTableSize = Convert.ToInt32(WStringTable.Length); - Align(WStringTable, 0x10); - WStringTable.Seek(0x00, SeekOrigin.Begin); - WStringTable.CopyTo(InfoFile); - - int HashTableOffset = Convert.ToInt32(InfoFile.Position); - int HashTableSize = Convert.ToInt32(HashTable.Length); - Align(HashTable, 0x10); - HashTable.Seek(0x00, SeekOrigin.Begin); + + int WStringTableOffset = Convert.ToInt32(InfoFile.Position); + int WStringTableSize = Convert.ToInt32(WStringTable.Length); + Align(WStringTable, 0x10); + WStringTable.Seek(0x00, SeekOrigin.Begin); + WStringTable.CopyTo(InfoFile); + + int HashTableOffset = Convert.ToInt32(InfoFile.Position); + int HashTableSize = Convert.ToInt32(HashTable.Length); + Align(HashTable, 0x10); + HashTable.Seek(0x00, SeekOrigin.Begin); HashTable.CopyTo(InfoFile); - - int IntArrayTableOffset = Convert.ToInt32(InfoFile.Position); - int IntArrayTableSize = Convert.ToInt32(IntArrayTable.Length); - Align(IntArrayTable, 0x10); - IntArrayTable.Seek(0x00, SeekOrigin.Begin); - IntArrayTable.CopyTo(InfoFile); - - int FloatArrayTableOffset = Convert.ToInt32(InfoFile.Position); - int FloatArrayTableSize = Convert.ToInt32(FloatArrayTable.Length); - Align(FloatArrayTable, 0x10); - FloatArrayTable.Seek(0x00, SeekOrigin.Begin); - FloatArrayTable.CopyTo(InfoFile); - - int FileTableOffset = Convert.ToInt32(InfoFile.Position); - int FileTableSize = Convert.ToInt32(FileTable.Length); - Align(FileTable, 0x10); - FileTable.Seek(0x00, SeekOrigin.Begin); - FileTable.CopyTo(InfoFile); - - string excessData = GetTypingInformation("EXCESS"); - if (excessData != "0") - { - Console.WriteLine("Excess Data Found, Writing to end."); - byte[] ExcessData = Convert.FromBase64String(excessData.Replace("*", "=")); - InfoFile.Read(ExcessData, 0x00, ExcessData.Length); - byte[] UnCompressed = ZlibStream.UncompressBuffer(ExcessData); - InfoFile.Write(UnCompressed, 0x00, UnCompressed.Length); - } - - InfoFile.Seek(0x8, SeekOrigin.Begin); - tools.WriteInt32(InfoFile, TreeTableOffset); - tools.WriteInt32(InfoFile, TreeTableSize); - tools.WriteInt32(InfoFile, IdTableOffset); - tools.WriteInt32(InfoFile, IdTableSize); + + int IntArrayTableOffset = Convert.ToInt32(InfoFile.Position); + int IntArrayTableSize = Convert.ToInt32(IntArrayTable.Length); + Align(IntArrayTable, 0x10); + IntArrayTable.Seek(0x00, SeekOrigin.Begin); + IntArrayTable.CopyTo(InfoFile); + + int FloatArrayTableOffset = Convert.ToInt32(InfoFile.Position); + int FloatArrayTableSize = Convert.ToInt32(FloatArrayTable.Length); + Align(FloatArrayTable, 0x10); + FloatArrayTable.Seek(0x00, SeekOrigin.Begin); + FloatArrayTable.CopyTo(InfoFile); + + int FileTableOffset = Convert.ToInt32(InfoFile.Position); + int FileTableSize = Convert.ToInt32(FileTable.Length); + Align(FileTable, 0x10); + FileTable.Seek(0x00, SeekOrigin.Begin); + FileTable.CopyTo(InfoFile); + + string excessData = GetTypingInformation("EXCESS"); + if (excessData != "0") + { + Console.WriteLine("Excess Data Found, Writing to end."); + byte[] ExcessData = Convert.FromBase64String(excessData.Replace("*", "=")); + InfoFile.Read(ExcessData, 0x00, ExcessData.Length); + byte[] UnCompressed = ZlibStream.UncompressBuffer(ExcessData); + InfoFile.Write(UnCompressed, 0x00, UnCompressed.Length); + } + + InfoFile.Seek(0x8, SeekOrigin.Begin); + tools.WriteInt32(InfoFile, TreeTableOffset); + tools.WriteInt32(InfoFile, TreeTableSize); + tools.WriteInt32(InfoFile, IdTableOffset); + tools.WriteInt32(InfoFile, IdTableSize); if (!ps3) { tools.WriteInt32(InfoFile, HashIdTableOffset); tools.WriteInt32(InfoFile, HashIdTableSize); - } - - tools.WriteInt32(InfoFile, StringTableOffset); - tools.WriteInt32(InfoFile, StringTableSize); + } + + tools.WriteInt32(InfoFile, StringTableOffset); + tools.WriteInt32(InfoFile, StringTableSize); if (!ps3) { tools.WriteInt32(InfoFile, WStringTableOffset); tools.WriteInt32(InfoFile, WStringTableSize); tools.WriteInt32(InfoFile, HashTableOffset); - tools.WriteInt32(InfoFile, HashTableSize); - } - - tools.WriteInt32(InfoFile, IntArrayTableOffset); - tools.WriteInt32(InfoFile, IntArrayTableSize); - tools.WriteInt32(InfoFile, FloatArrayTableOffset); - tools.WriteInt32(InfoFile, FloatArrayTableSize); - tools.WriteInt32(InfoFile, FileTableOffset); - tools.WriteInt32(InfoFile, FileTableSize); - - Term(); - } - } -} + tools.WriteInt32(InfoFile, HashTableSize); + } + + tools.WriteInt32(InfoFile, IntArrayTableOffset); + tools.WriteInt32(InfoFile, IntArrayTableSize); + tools.WriteInt32(InfoFile, FloatArrayTableOffset); + tools.WriteInt32(InfoFile, FloatArrayTableSize); + tools.WriteInt32(InfoFile, FileTableOffset); + tools.WriteInt32(InfoFile, FileTableSize); + + Term(); + } + } +}