public void ExtractData(string path, string name, int size, string onlyExt) { int magic = reader.ReadInt32BE (); // BLTE (raw) if (magic != 0x424c5445) { Console.WriteLine ("Wrong Magic pos: {0}, start: {1} ", reader.BaseStream.Position, startPos); throw new Exception (); return; } int compDataOffset = reader.ReadInt32BE (); int chunkCount = 0; if (compDataOffset != 0) { int unk1 = reader.ReadInt16BE (); chunkCount = reader.ReadInt16BE (); } BLTEChunk[] chunks; if (compDataOffset == 0) { //if this is 0 there's just one chunk with no chunk-headers chunkCount = 1; chunks = new BLTEChunk[chunkCount]; chunks [0] = new BLTEChunk (); chunks [0].compSize = size - 38; // no idea why. chunks [0].hash = null; chunks [0].decompSize = Int32.MaxValue; // we need to find a way to properly handle these :/ No idea about the file size } else { if (chunkCount < 0) { Console.WriteLine ("No chunks found, compDataOffset: {0}, unk1: {1}, chunkCount: {2}, pos: {3}, start: {4}", compDataOffset, false, chunkCount, reader.BaseStream.Position, startPos); return; } chunks = new BLTEChunk[chunkCount]; for (int i = 0; i < chunkCount; ++i) { chunks [i] = new BLTEChunk (); chunks [i].compSize = reader.ReadInt32BE (); chunks [i].decompSize = reader.ReadInt32BE (); chunks [i].hash = reader.ReadBytes (16); } } if (!Directory.Exists(path)) Directory.CreateDirectory(path); string ext = ".tmp"; string tmpName = path + "/" + name + ext; var f = File.Open (tmpName, FileMode.Create); for (int i = 0; i < chunkCount; ++i) { chunks [i].data = reader.ReadBytes (chunks [i].compSize); byte[] hh = md5.ComputeHash (chunks [i].data); if (compDataOffset != 0 && !hh.VerifyHash (chunks [i].hash)) { Console.WriteLine ("MD5 missmatch!"); return; } switch (chunks [i].data [0]) { case 0x4E: // Not compressed; { if ((i == 0 || i == 0)) { ext = GetFileExt (chunks [i].data, 1); } if (chunks [i].data.Length - 1 != chunks [i].decompSize) { Console.WriteLine ("Possible error (1) !"); } f.Write (chunks [i].data, 1, chunks [i].decompSize); } break; case 0x5A: { byte[] dec = Decompress (chunks [i].data); if ((i == 0 || i == 0)) { ext = GetFileExt (dec, 0); } f.Write (dec, 0, dec.Length); } break; default: Console.WriteLine ("Unknown byte {0:X2} at {1:X8}", chunks [i].data [0], reader.BaseStream.Position - chunks [i].data.Length); break; } } string finalName = path + "/" + name + "." + ext; if (onlyExt == null || ext == onlyExt) { Console.WriteLine ("Writing file {0}", finalName); f.Close (); if (File.Exists (finalName)) File.Delete (finalName); File.Move (tmpName, finalName); } else { f.Close (); if (File.Exists (tmpName)) File.Delete (tmpName); } }
public void ExtractData(string path, string name, int size, string onlyExt) { int magic = reader.ReadInt32BE(); // BLTE (raw) if (magic != 0x424c5445) { Console.WriteLine("Wrong Magic,name: {3} size: {2} pos: {0}, start: {1}", reader.BaseStream.Position, startPos, size, name); throw new Exception(); return; } int compDataOffset = reader.ReadInt32BE(); int chunkCount = 0; if (compDataOffset != 0) { int unk1 = reader.ReadInt16BE(); chunkCount = reader.ReadInt16BE(); } BLTEChunk[] chunks; if (compDataOffset == 0) //if this is 0 there's just one chunk with no chunk-headers { chunkCount = 1; chunks = new BLTEChunk[chunkCount]; chunks [0] = new BLTEChunk(); chunks [0].compSize = size - 38; // no idea why. chunks [0].hash = null; chunks [0].decompSize = Int32.MaxValue; // we need to find a way to properly handle these :/ No idea about the file size } else { if (chunkCount < 0) { Console.WriteLine("No chunks found, compDataOffset: {0}, unk1: {1}, chunkCount: {2}, pos: {3}, start: {4}", compDataOffset, false, chunkCount, reader.BaseStream.Position, startPos); return; } chunks = new BLTEChunk[chunkCount]; for (int i = 0; i < chunkCount; ++i) { chunks [i] = new BLTEChunk(); chunks [i].compSize = reader.ReadInt32BE(); chunks [i].decompSize = reader.ReadInt32BE(); chunks [i].hash = reader.ReadBytes(16); } } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string ext = ".tmp"; string tmpName = path + "/" + name + ext; var f = File.Open(tmpName, FileMode.Create); for (int i = 0; i < chunkCount; ++i) { chunks [i].data = reader.ReadBytes(chunks [i].compSize); byte[] hh = md5.ComputeHash(chunks [i].data); if (compDataOffset != 0 && !hh.VerifyHash(chunks [i].hash)) { Console.WriteLine("MD5 missmatch!"); return; } switch (chunks [i].data [0]) { case 0x4E: // Not compressed; { if ((i == 0 || i == 0)) { ext = GetFileExt(chunks [i].data, 1); } if (chunks [i].data.Length - 1 != chunks [i].decompSize) { Console.WriteLine("Possible error (1) !"); } if (onlyExt == null || ext == onlyExt) { f.Write(chunks [i].data, 1, chunks [i].decompSize); } } break; case 0x5A: { byte[] dec = Decompress(chunks [i].data); if ((i == 0 || i == 0)) { ext = GetFileExt(dec, 0); } if (onlyExt == null || ext == onlyExt) { f.Write(dec, 0, dec.Length); } } break; default: Console.WriteLine("Unknown byte {0:X2} at {1:X8}", chunks [i].data [0], reader.BaseStream.Position - chunks [i].data.Length); break; } } string finalName = path + "/" + name + "." + ext; if (onlyExt == null || ext == onlyExt) { Console.WriteLine("Writing file {0}", finalName); f.Close(); if (File.Exists(finalName)) { File.Delete(finalName); } File.Move(tmpName, finalName); } else { f.Close(); if (File.Exists(tmpName)) { File.Delete(tmpName); } } }