protected virtual void Dispose(bool disposing) { if (disposing && !isDisposed) { header = null; u8Header = null; rootNode = null; u8Nodes.Clear(); u8Nodes = null; stringTable.Clear(); stringTable = null; data.Clear(); data = null; } isDisposed = true; }
private void createFromDir(string path) { fireDebug("Creating U8 File from: {0}", path); if (path[path.Length - 1] != Path.DirectorySeparatorChar) path += Path.DirectorySeparatorChar; fireDebug(" Collecting Content..."); string[] dirEntries = getDirContent(path, true); int offsetToName = 1; int offsetToData = 0; fireDebug(" Creating U8 Header..."); u8Header = new U8_Header(); rootNode = new U8_Node(); u8Nodes = new List<U8_Node>(); stringTable = new List<string>(); data = new List<byte[]>(); //Create Rootnode fireDebug(" Creating Rootnode..."); rootNode.Type = U8_NodeType.Directory; rootNode.OffsetToName = 0; rootNode.OffsetToData = 0; rootNode.SizeOfData = (uint)dirEntries.Length + 1; //Create Nodes for (int i = 0; i < dirEntries.Length; i++) { fireDebug(" Creating Node #{0} of {1}", i + 1, dirEntries.Length); fireProgress((i + 1) * 100 / dirEntries.Length); U8_Node tempNode = new U8_Node(); byte[] tempData = new byte[0]; string tempDirEntry = dirEntries[i].Remove(0, path.Length - 1); if (Directory.Exists(dirEntries[i])) //It's a dir { fireDebug(" -> Directory"); tempNode.Type = U8_NodeType.Directory; tempNode.OffsetToData = (uint)Shared.CountCharsInString(tempDirEntry, Path.DirectorySeparatorChar); //Recursion int size = u8Nodes.Count + 2; for (int j = 0; j < dirEntries.Length; j++) if (dirEntries[j].Contains(dirEntries[i] + System.IO.Path.DirectorySeparatorChar.ToString())) size++; tempNode.SizeOfData = (uint)size; } else //It's a file { fireDebug(" -> File"); fireDebug(" -> Reading File Data..."); tempData = File.ReadAllBytes(dirEntries[i]); tempNode.Type = U8_NodeType.File; tempNode.OffsetToData = (uint)offsetToData; tempNode.SizeOfData = (uint)tempData.Length; offsetToData += Shared.AddPadding(offsetToData + tempData.Length, dataPadding); } tempNode.OffsetToName = (ushort)offsetToName; offsetToName += (Path.GetFileName(dirEntries[i])).Length + 1; fireDebug(" -> Reading Name..."); string tempName = Path.GetFileName(dirEntries[i]); if (tempName.ToLower() == "icon.bin") iconSize = getRealSize(tempData); else if (tempName.ToLower() == "banner.bin") bannerSize = getRealSize(tempData); else if (tempName.ToLower() == "sound.bin") soundSize = getRealSize(tempData); u8Nodes.Add(tempNode); stringTable.Add(tempName); data.Add(tempData); } //Update U8 Header fireDebug(" Updating U8 Header..."); u8Header.HeaderSize = (uint)(((u8Nodes.Count + 1) * 12) + offsetToName); u8Header.OffsetToData = (uint)Shared.AddPadding((int)u8Header.OffsetToRootNode + (int)u8Header.HeaderSize, dataPadding); //Update dataOffsets fireDebug(" Calculating Data Offsets..."); for (int i = 0; i < u8Nodes.Count; i++) { fireDebug(" -> Node #{0} of {1}...", i + 1, u8Nodes.Count); int tempOffset = (int)u8Nodes[i].OffsetToData; u8Nodes[i].OffsetToData = (uint)(u8Header.OffsetToData + tempOffset); } fireDebug("Creating U8 File Finished..."); }
private void parseU8(Stream u8File) { fireDebug("Pasing U8 File..."); u8Header = new U8_Header(); rootNode = new U8_Node(); u8Nodes = new List<U8_Node>(); stringTable = new List<string>(); data = new List<byte[]>(); fireDebug(" Detecting Header..."); headerType = Headers.DetectHeader(u8File); Headers.HeaderType tempType = headerType; fireDebug(" -> {0}", headerType.ToString()); if (headerType == Headers.HeaderType.IMD5) { fireDebug(" Reading IMD5 Header..."); header = Headers.IMD5.Load(u8File); byte[] file = new byte[u8File.Length]; u8File.Read(file, 0, file.Length); MD5 m = MD5.Create(); byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType); m.Clear(); if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash)) { fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\"); fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!")); } } else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET) { fireDebug(" Reading IMET Header..."); header = Headers.IMET.Load(u8File); if (!((Headers.IMET)header).HashesMatch) { fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\"); fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!")); } } fireDebug(" Checking for Lz77 Compression..."); if (Lz77.IsLz77Compressed(u8File)) { fireDebug(" -> Lz77 Compression Found..."); fireDebug(" Decompressing U8 Data..."); Lz77 l = new Lz77(); Stream decompressedFile = l.Decompress(u8File); tempType = Headers.DetectHeader(decompressedFile); u8File = decompressedFile; lz77 = true; } u8File.Seek((int)tempType, SeekOrigin.Begin); byte[] temp = new byte[4]; //Read U8 Header fireDebug(" Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic) { fireDebug(" -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!"); } fireDebug(" Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode) { fireDebug(" -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!"); } fireDebug(" Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); u8File.Seek(16, SeekOrigin.Current); //Read Rootnode fireDebug(" Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); rootNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0)); rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2)); u8File.Read(temp, 0, 4); rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); u8File.Read(temp, 0, 4); rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12); int nodePosition = (int)u8File.Position; //Read Nodes for (int i = 0; i < rootNode.SizeOfData - 1; i++) { fireDebug(" Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1); fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1))); U8_Node tempNode = new U8_Node(); string tempName = string.Empty; byte[] tempData = new byte[0]; //Read Node Entry u8File.Seek(nodePosition, SeekOrigin.Begin); fireDebug(" -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); tempNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0)); tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2)); u8File.Read(temp, 0, 4); tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); u8File.Read(temp, 0, 4); tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); nodePosition = (int)u8File.Position; fireDebug(" -> {0}", tempNode.Type.ToString()); //Read Node Name u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin); fireDebug(" -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); for (;;) { char tempChar = (char)u8File.ReadByte(); if (tempChar == 0x00) break; tempName += tempChar; if (tempName.Length > 255) break; } fireDebug(" -> {0}", tempName); //Read Node Data if (tempNode.Type == U8_NodeType.File) { u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin); fireDebug(" -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); tempData = new byte[tempNode.SizeOfData]; u8File.Read(tempData, 0, tempData.Length); } if (tempName.ToLower() == "icon.bin") iconSize = getRealSize(tempData); else if (tempName.ToLower() == "banner.bin") bannerSize = getRealSize(tempData); else if (tempName.ToLower() == "sound.bin") soundSize = getRealSize(tempData); u8Nodes.Add(tempNode); stringTable.Add(tempName); data.Add(tempData); } fireDebug("Pasing U8 File Finished..."); }
private void createFromDir(string path) { fireDebug("Creating U8 File from: {0}", path); if (path[path.Length - 1] != Path.DirectorySeparatorChar) { path += Path.DirectorySeparatorChar; } fireDebug(" Collecting Content..."); string[] dirEntries = getDirContent(path, true); int offsetToName = 1; int offsetToData = 0; fireDebug(" Creating U8 Header..."); u8Header = new U8_Header(); rootNode = new U8_Node(); u8Nodes = new List <U8_Node>(); stringTable = new List <string>(); data = new List <byte[]>(); //Create Rootnode fireDebug(" Creating Rootnode..."); rootNode.Type = U8_NodeType.Directory; rootNode.OffsetToName = 0; rootNode.OffsetToData = 0; rootNode.SizeOfData = (uint)dirEntries.Length + 1; //Create Nodes for (int i = 0; i < dirEntries.Length; i++) { fireDebug(" Creating Node #{0} of {1}", i + 1, dirEntries.Length); fireProgress((i + 1) * 100 / dirEntries.Length); U8_Node tempNode = new U8_Node(); byte[] tempData = new byte[0]; string tempDirEntry = dirEntries[i].Remove(0, path.Length - 1); if (Directory.Exists(dirEntries[i])) //It's a dir { fireDebug(" -> Directory"); tempNode.Type = U8_NodeType.Directory; tempNode.OffsetToData = (uint)Shared.CountCharsInString(tempDirEntry, Path.DirectorySeparatorChar); //Recursion int size = u8Nodes.Count + 2; for (int j = 0; j < dirEntries.Length; j++) { if (dirEntries[j].Contains(dirEntries[i] + System.IO.Path.DirectorySeparatorChar.ToString())) { size++; } } tempNode.SizeOfData = (uint)size; } else //It's a file { fireDebug(" -> File"); fireDebug(" -> Reading File Data..."); tempData = File.ReadAllBytes(dirEntries[i]); tempNode.Type = U8_NodeType.File; tempNode.OffsetToData = (uint)offsetToData; tempNode.SizeOfData = (uint)tempData.Length; offsetToData += Shared.AddPadding(offsetToData + tempData.Length, dataPadding); } tempNode.OffsetToName = (ushort)offsetToName; offsetToName += (Path.GetFileName(dirEntries[i])).Length + 1; fireDebug(" -> Reading Name..."); string tempName = Path.GetFileName(dirEntries[i]); if (tempName.ToLower() == "icon.bin") { iconSize = getRealSize(tempData); } else if (tempName.ToLower() == "banner.bin") { bannerSize = getRealSize(tempData); } else if (tempName.ToLower() == "sound.bin") { soundSize = getRealSize(tempData); } u8Nodes.Add(tempNode); stringTable.Add(tempName); data.Add(tempData); } //Update U8 Header fireDebug(" Updating U8 Header..."); u8Header.HeaderSize = (uint)(((u8Nodes.Count + 1) * 12) + offsetToName); u8Header.OffsetToData = (uint)Shared.AddPadding((int)u8Header.OffsetToRootNode + (int)u8Header.HeaderSize, dataPadding); //Update dataOffsets fireDebug(" Calculating Data Offsets..."); for (int i = 0; i < u8Nodes.Count; i++) { fireDebug(" -> Node #{0} of {1}...", i + 1, u8Nodes.Count); int tempOffset = (int)u8Nodes[i].OffsetToData; u8Nodes[i].OffsetToData = (uint)(u8Header.OffsetToData + tempOffset); } fireDebug("Creating U8 File Finished..."); }
private void parseU8(Stream u8File) { fireDebug("Pasing U8 File..."); u8Header = new U8_Header(); rootNode = new U8_Node(); u8Nodes = new List <U8_Node>(); stringTable = new List <string>(); data = new List <byte[]>(); fireDebug(" Detecting Header..."); headerType = Headers.DetectHeader(u8File); Headers.HeaderType tempType = headerType; fireDebug(" -> {0}", headerType.ToString()); if (headerType == Headers.HeaderType.IMD5) { fireDebug(" Reading IMD5 Header..."); header = Headers.IMD5.Load(u8File); byte[] file = new byte[u8File.Length]; u8File.Read(file, 0, file.Length); MD5 m = MD5.Create(); byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType); m.Clear(); if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash)) { fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\"); fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!")); } } else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET) { fireDebug(" Reading IMET Header..."); header = Headers.IMET.Load(u8File); if (!((Headers.IMET)header).HashesMatch) { fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\"); fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!")); } } fireDebug(" Checking for Lz77 Compression..."); if (Lz77.IsLz77Compressed(u8File)) { fireDebug(" -> Lz77 Compression Found..."); fireDebug(" Decompressing U8 Data..."); Lz77 l = new Lz77(); Stream decompressedFile = l.Decompress(u8File); tempType = Headers.DetectHeader(decompressedFile); u8File = decompressedFile; lz77 = true; } u8File.Seek((int)tempType, SeekOrigin.Begin); byte[] temp = new byte[4]; //Read U8 Header fireDebug(" Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic) { fireDebug(" -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!"); } fireDebug(" Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode) { fireDebug(" -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!"); } fireDebug(" Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); u8File.Seek(16, SeekOrigin.Current); //Read Rootnode fireDebug(" Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); rootNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0)); rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2)); u8File.Read(temp, 0, 4); rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); u8File.Read(temp, 0, 4); rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12); int nodePosition = (int)u8File.Position; //Read Nodes for (int i = 0; i < rootNode.SizeOfData - 1; i++) { fireDebug(" Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1); fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1))); U8_Node tempNode = new U8_Node(); string tempName = string.Empty; byte[] tempData = new byte[0]; //Read Node Entry u8File.Seek(nodePosition, SeekOrigin.Begin); fireDebug(" -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); u8File.Read(temp, 0, 4); tempNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0)); tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2)); u8File.Read(temp, 0, 4); tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); u8File.Read(temp, 0, 4); tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0)); nodePosition = (int)u8File.Position; fireDebug(" -> {0}", tempNode.Type.ToString()); //Read Node Name u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin); fireDebug(" -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); for (;;) { char tempChar = (char)u8File.ReadByte(); if (tempChar == 0x00) { break; } tempName += tempChar; if (tempName.Length > 255) { break; } } fireDebug(" -> {0}", tempName); //Read Node Data if (tempNode.Type == U8_NodeType.File) { u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin); fireDebug(" -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper()); tempData = new byte[tempNode.SizeOfData]; u8File.Read(tempData, 0, tempData.Length); } if (tempName.ToLower() == "icon.bin") { iconSize = getRealSize(tempData); } else if (tempName.ToLower() == "banner.bin") { bannerSize = getRealSize(tempData); } else if (tempName.ToLower() == "sound.bin") { soundSize = getRealSize(tempData); } u8Nodes.Add(tempNode); stringTable.Add(tempName); data.Add(tempData); } fireDebug("Pasing U8 File Finished..."); }