public NblLoader() { NblChunk newChunk = new NblChunk(); newChunk.encryptionKey = decryptKey; newChunk.encrypted = decryptKey != 0; newChunk.compressed = false; newChunk.chunkID = "NMLL"; newChunk.versionNumber = (short)2; chunks.Insert(0, newChunk); }
public void addTmllFile(RawFile file) { if (chunks.Count < 2 || chunks[1].chunkID != "TMLL") { NblChunk newChunk = new NblChunk(); newChunk.encryptionKey = 0; newChunk.encrypted = false; newChunk.compressed = false; newChunk.chunkID = "TMLL"; newChunk.versionNumber = (short)2; chunks.Insert(1, newChunk); } chunks[1].addFile(file); }
public NblLoader(List <RawFile> nmllFiles, List <RawFile> tmllFiles) { if (nmllFiles != null && nmllFiles.Count > 0) { NblChunk nmllChunk = new NblChunk { chunkID = "NMLL", versionNumber = 2, fileContents = nmllFiles }; chunks.Add(nmllChunk); } if (tmllFiles != null && tmllFiles.Count > 0) { NblChunk tmllChunk = new NblChunk { chunkID = "TMLL", versionNumber = 2, fileContents = tmllFiles }; chunks.Add(tmllChunk); } }
public NblLoader(Stream fileToLoad) { fileToLoad.Seek(0x3, SeekOrigin.Begin); int endian = fileToLoad.ReadByte(); isBigEndian = (endian == 0x42); BinaryReader fileLoader = getBinaryReader(fileToLoad); fileToLoad.Seek(0, SeekOrigin.Begin); NblChunk firstChunk = loadGroup(fileToLoad, fileLoader); chunks.Add(firstChunk); if (tmllHeaderLoc != 0) { fileToLoad.Seek(tmllHeaderLoc, SeekOrigin.Begin); NblChunk tmllChunk = loadGroup(fileToLoad, fileLoader); chunks.Add(tmllChunk); } fileLoader.Close(); fileLoader.Dispose(); }
private NblChunk loadGroup(Stream fileToLoad, BinaryReader fileLoader) { NblChunk toRet = new NblChunk(); toRet.bigEndian = isBigEndian; long offset = fileToLoad.Position; string formatName = new String(fileLoader.ReadChars(4)); ushort fileVersion = fileLoader.ReadUInt16(); int paddingAmount = fileVersion == 0x1002 ? 0x3F : 0x7FF; uint mask = fileVersion == 0x1002 ? 0xFFFFFFC0 : 0xFFFFF800; ushort chunkFilenameLength = fileLoader.ReadUInt16(); int headerSize = fileLoader.ReadInt32(); int numFiles = fileLoader.ReadInt32(); uint uncompressedSize = fileLoader.ReadUInt32(); uint compressedSize = fileLoader.ReadUInt32(); uint pointerLength = fileLoader.ReadUInt32() / 4; if (formatName.StartsWith("NML")) { decryptKey = fileLoader.ReadUInt32(); } else { fileLoader.ReadUInt32(); } uint size = compressedSize == 0 ? uncompressedSize : compressedSize; uint nmllDataLoc = (uint)((headerSize + paddingAmount) & mask); uint pointerLoc = (uint)(nmllDataLoc + size + paddingAmount) & mask; uint mainHeaderSize = 0x20; if (formatName.StartsWith("NML")) { mainHeaderSize = 0x30; uint tmllHeaderSize = fileLoader.ReadUInt32(); uint tmllDataSizeUncomp = fileLoader.ReadUInt32(); uint tmllDataSizeComp = fileLoader.ReadUInt32(); uint tmllCount = fileLoader.ReadUInt32(); if (tmllCount > 0) { tmllHeaderLoc = (uint)(pointerLoc + pointerLength * 4 + paddingAmount) & mask; } } decryptor = new BlewFish(decryptKey, isBigEndian); FileHeader[] groupHeaders = new FileHeader[numFiles]; for (int i = 0; i < numFiles; i++) { fileToLoad.Seek(mainHeaderSize + 0x60 * i + offset, SeekOrigin.Begin); FileHeader currentHeader = readHeader(fileLoader.ReadBytes(0x60)); groupHeaders[i] = currentHeader; } fileToLoad.Seek(nmllDataLoc + offset, SeekOrigin.Begin); int encryptedSectionSize; if (fileVersion == 0x1002) { //Obfuscation stuff from sega. int rawEncryptedSectionSize = (int)((((compressedSize >> 0xB) ^ compressedSize) & 0xE0) + 0x20); encryptedSectionSize = Math.Min(rawEncryptedSectionSize, (int)compressedSize); } else { encryptedSectionSize = (int)size; } if (encryptedSectionSize % 8 != 0) { encryptedSectionSize -= (encryptedSectionSize % 8); } byte[] decryptedFiles; if (decryptKey != 0 && formatName.StartsWith("NML")) { byte[] encryptedFiles = fileLoader.ReadBytes((int)size); decryptedFiles = decryptor.decryptBlock(encryptedFiles, encryptedSectionSize); } else { decryptedFiles = fileLoader.ReadBytes((int)size + 7); } if (compressedSize != 0) { if (fileVersion == 0x1002) { DeflateStream ds = new DeflateStream(new MemoryStream(decryptedFiles), CompressionMode.Decompress); MemoryStream decompressedStream = new MemoryStream((int)uncompressedSize); ds.CopyTo(decompressedStream); decompressedFiles = decompressedStream.ToArray(); } else { decompressedFiles = PrsCompDecomp.Decompress(decryptedFiles, uncompressedSize); } } else { decompressedFiles = decryptedFiles; } List <int> pointers = new List <int>((int)pointerLength); if (pointerLength > 0) { fileToLoad.Seek(pointerLoc + offset, SeekOrigin.Begin); for (int i = 0; i < pointerLength; i++) { pointers.Add(fileLoader.ReadInt32()); } } List <RawFile> files = new List <RawFile>(numFiles); for (int i = 0; i < numFiles; i++) { RawFile tempFile = new RawFile(); tempFile.filename = groupHeaders[i].fileName; tempFile.subHeader = groupHeaders[i].subHeader; tempFile.chunkSize = groupHeaders[i].chunkSize; tempFile.fileOffset = groupHeaders[i].filePosition; tempFile.fileContents = new byte[groupHeaders[i].fileSize]; Array.Copy(decompressedFiles, groupHeaders[i].filePosition, tempFile.fileContents, 0, groupHeaders[i].fileSize); if (tempFile.fileContents.Length > 0) { tempFile.fileheader = new String(ASCIIEncoding.ASCII.GetChars(tempFile.fileContents, 0, 4)); } if (groupHeaders[i].pointerSize > 0) { tempFile.pointers = pointers.GetRange((int)groupHeaders[i].pointerPosition / 4, (int)groupHeaders[i].pointerSize / 4); } files.Add(tempFile); } toRet.encryptionKey = decryptKey; toRet.encrypted = decryptKey != 0; toRet.compressed = compressedSize != 0; toRet.chunkID = formatName; toRet.versionNumber = (short)fileVersion; toRet.fileContents = files; return(toRet); }