Пример #1
0
        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);
        }
Пример #2
0
 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);
 }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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();
        }
Пример #5
0
        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);
        }