Пример #1
0
        public IList <IArchiveFileInfo> Load(Stream incStream, Stream datStream, string version)
        {
            using var incBr = new BinaryReaderX(incStream);

            var entryCount = (int)(incStream.Length / FileEntrySize);
            var entries    = incBr.ReadMultiple <AAPackFileEntry>(entryCount);

            var nameMapping = AAPackSupport.GetMapping(version);

            var result = new IArchiveFileInfo[entryCount];

            for (var i = 0; i < entryCount; i++)
            {
                var subStream = new SubStream(datStream, entries[i].offset, entries[i].compSize);

                var compressionMethod = NintendoCompressor.PeekCompressionMethod(subStream);

                var fileName = $"{i:00000000}.bin";
                if (nameMapping.ContainsKey(entries[i].hash))
                {
                    fileName = nameMapping[entries[i].hash];
                }

                result[i] = new AAPackArchiveFileInfo(subStream, fileName,
                                                      NintendoCompressor.GetConfiguration(compressionMethod), entries[i].uncompSize, entries[i]);
            }

            return(result);
        }
Пример #2
0
        public static ArchiveFileInfo CreateAfi(Stream file, string fileName)
        {
            var compressionIdent = file.ReadByte();
            var isCompressed     = compressionIdent == 0x10 ||
                                   compressionIdent == 0x11 ||
                                   compressionIdent == 0x24 ||
                                   compressionIdent == 0x28 ||
                                   compressionIdent == 0x30;

            file.Position--;
            if (!isCompressed)
            {
                return(new ArchiveFileInfo(file, fileName));
            }

            var sizeBuffer = new byte[4];

            file.Read(sizeBuffer, 0, 4);
            file.Position = 0;

            var method           = (NintendoCompressionMethod)(BinaryPrimitives.ReadUInt32LittleEndian(sizeBuffer) & 0xFF);
            var decompressedSize = BinaryPrimitives.ReadUInt32LittleEndian(sizeBuffer) >> 8;

            if (decompressedSize <= file.Length)
            {
                return(new ArchiveFileInfo(file, fileName));
            }

            return(new ArchiveFileInfo(file, fileName, NintendoCompressor.GetConfiguration(method), decompressedSize));
        }
Пример #3
0
        private IArchiveFileInfo CreateAfi(Stream file, string name)
        {
            file.Position = 0;

            var method = NintendoCompressor.PeekCompressionMethod(file);
            var size   = NintendoCompressor.PeekDecompressedSize(file);

            return(new ArchiveFileInfo(file, name, NintendoCompressor.GetConfiguration(method), size));
        }
Пример #4
0
        private IArchiveFileInfo CreateAfi(Stream file, string name, TarcEntry entry)
        {
            if (entry.compSize != 0 && entry.compSize != entry.decompSize)
            {
                var method = NintendoCompressor.PeekCompressionMethod(file);
                return(new TarcArchiveFileInfo(file, name, entry, NintendoCompressor.GetConfiguration(method), entry.decompSize));
            }

            return(new TarcArchiveFileInfo(file, name, entry));
        }
Пример #5
0
        private IArchiveFileInfo CreateAfi(Stream input, string fileName, PackEntry entry)
        {
            var method = NintendoCompressor.PeekCompressionMethod(input);

            if (!NintendoCompressor.IsValidCompressionMethod(method))
            {
                return(new PackArchiveFileInfo(input, fileName, entry));
            }

            return(new PackArchiveFileInfo(input, fileName, entry, NintendoCompressor.GetConfiguration(method), NintendoCompressor.PeekDecompressedSize(input)));
        }
Пример #6
0
        private IArchiveFileInfo CreateAfi(Stream file, string fileName, Gk2Arc1Entry entry)
        {
            if (!entry.IsCompressed)
            {
                return(new Gk2Arc1ArchiveFileInfo(file, fileName, entry));
            }

            file.Position = 0;
            var compression      = NintendoCompressor.PeekCompressionMethod(file);
            var decompressedSize = NintendoCompressor.PeekDecompressedSize(file);

            return(new Gk2Arc1ArchiveFileInfo(file, fileName, entry, NintendoCompressor.GetConfiguration(compression), decompressedSize));
        }
Пример #7
0
        public IList <IArchiveFileInfo> Load(Stream dataStream, Stream matStream)
        {
            using var br    = new BinaryReaderX(dataStream, true);
            using var matBr = new BinaryReaderX(matStream);

            // Read entries
            var entries = matBr.ReadMultiple <SarEntry>((int)(matStream.Length / EntrySize));

            // Read header
            _header = br.ReadType <SarContainerHeader>();

            // Add files
            var result = new List <IArchiveFileInfo>();

            for (var i = 0; i < entries.Count; i++)
            {
                var entry = entries[i];
                dataStream.Position = entry.offset;

                // Read compression header
                var compHeader = br.ReadType <SarContainerHeader>();
                if (compHeader.magic != "cmp ")
                {
                    result.Add(new SarArchiveFileInfo(new SubStream(dataStream, entry.offset, entry.size), $"{i:00000000}.bin"));
                    continue;
                }

                compHeader = br.ReadType <SarContainerHeader>();
                if (compHeader.magic != "lz7 ")
                {
                    throw new InvalidOperationException($"Unknown compression container detected for file at index {i}.");
                }

                var fileStream = new SubStream(dataStream, entry.offset + 0x18, SarSupport.GetCompressedSize(dataStream, entry.offset + 0x18, compHeader.data2));
                var name       = $"{i:00000000}.bin";

                var compMethod = NintendoCompressor.PeekCompressionMethod(fileStream);
                result.Add(new SarArchiveFileInfo(fileStream, name, NintendoCompressor.GetConfiguration(compMethod), NintendoCompressor.PeekDecompressedSize(fileStream)));
            }

            return(result);
        }
Пример #8
0
        public IList <IArchiveFileInfo> Load(Stream input)
        {
            using var br = new BinaryReaderX(input, true);

            var offsets = new List <long>();

            while (br.BaseStream.Position < br.BaseStream.Length)
            {
                var headerMagic = br.ReadString(6);
                if (headerMagic == "3DS-LZ")
                {
                    offsets.Add(br.BaseStream.Position + 2);
                }

                br.BaseStream.Position += 0x3A;
            }

            _sizes = new int[offsets.Count];
            for (var i = 0; i < offsets.Count; i++)
            {
                var endOffset = i + 1 == offsets.Count ? input.Length : (offsets[i + 1] - 8);
                _sizes[i] = (int)(endOffset - offsets[i]);
            }

            // Add files
            var result = new ArchiveFileInfo[offsets.Count];

            for (var i = 0; i < offsets.Count; i++)
            {
                var subStream = new SubStream(input, offsets[i], _sizes[i]);

                var compressionMethod = NintendoCompressor.PeekCompressionMethod(subStream);
                var decompressedSize  = NintendoCompressor.PeekDecompressedSize(subStream);

                result[i] = new ArchiveFileInfo(subStream, $"{i:00000000}{_3dsLzSupport.DetermineExtension(subStream)}",
                                                NintendoCompressor.GetConfiguration(compressionMethod), decompressedSize);
            }

            return(result);
        }