Example #1
0
        private void WriteFileSet(Stream stream, FileSet fileSet)
        {
            PACKFSHD fileSetHeader    = new PACKFSHD();
            GENESTRT fileSetNameTable = new GENESTRT();

            fileSetHeader.Unknown    = 0x10000;
            fileSetHeader.DataOffset = 0; // Filled in later.

            foreach (File file in fileSet.Files)
            {
                PACKFSHD.FileEntry fileEntry = new PACKFSHD.FileEntry();
                fileEntry.NameIndex        = fileSetNameTable.AddString(file.Name);
                fileEntry.Unknown          = 0x2;
                fileEntry.Offset           = 0; // Filled in later.
                fileEntry.UncompressedSize = file.UncompressedSize;
                fileEntry.CompressedSize   = (uint)file.RawData.Length;

                fileSetHeader.Files.Add(fileEntry);
            }

            SectionSet fileSetSections = new SectionSet();

            fileSetSections.Add(new ENDILTLE());
            fileSetSections.Add(fileSetHeader);
            fileSetSections.Add(fileSetNameTable);
            fileSetSections.Add(new GENEEOF());

            ulong headersSize;

            using (MemoryStream sizeTestStream = new MemoryStream()) {
                SectionIO.WriteAll(sizeTestStream, fileSetSections);
                headersSize = (ulong)sizeTestStream.Length;
            }

            ulong currOffset = NumberUtil.Align(headersSize, 0x10);

            fileSetHeader.DataOffset = (uint)currOffset - 0x10;  // Offset excludes ENDILTLE.
            foreach (PACKFSHD.FileEntry fileEntry in fileSetHeader.Files)
            {
                fileEntry.Offset = currOffset;
                currOffset       = NumberUtil.Align(currOffset + fileEntry.CompressedSize, 0x10);
            }

            SectionIO.WriteAll(stream, fileSetSections);

            foreach (File file in fileSet.Files)
            {
                stream.Write(file.RawData);
                stream.PadTo(0x10);
            }
        }
Example #2
0
        public void Write(Stream stream)
        {
            SectionSet sections = new SectionSet();

            GOPGFIN fin = new GOPGFIN();

            fin.Unknown1 = 0x2;
            fin.Unknown2 = 0x1;
            sections.Add(fin);

            GOPGMET  met  = new GOPGMET();
            GOPGREC  rec  = new GOPGREC();
            GENESTRT strt = new GENESTRT();
            GOPGDAT  dat  = new GOPGDAT();

            strt.AddString("");

            uint currElementPos = 0;

            foreach (Element element in this.Elements)
            {
                uint padTo = ELEMENT_PAD_TO[element.Type];
                currElementPos = (currElementPos + (padTo - 1)) & ~(padTo - 1);

                GOPGREC.ElementInfo info = new GOPGREC.ElementInfo();
                info.Type      = element.Type;
                info.Offset    = currElementPos;
                info.NameIndex = (ushort)strt.AddString(element.Name);
                info.Unknown   = element.Unknown;

                rec.Elements.Add(info);
                currElementPos += ELEMENT_LENGTH[element.Type];
            }

            for (int recordIndex = 0; recordIndex < this.Records.GetLength(0); recordIndex++)
            {
                using (MemoryStream dataStream = new MemoryStream()) {
                    using (BinaryWriter dataWriter = new BinaryWriter(dataStream)) {
                        for (int elementIndex = 0; elementIndex < this.Elements.Count; elementIndex++)
                        {
                            string element = this.Records[recordIndex, elementIndex + 1];
                            GOPGREC.ElementInfo elementInfo = rec.Elements[elementIndex];

                            dataWriter.PadTo((int)ELEMENT_PAD_TO[elementInfo.Type]);
                            WriteElement(dataWriter, elementInfo, strt, element);
                        }

                        dataWriter.PadTo(0x4);
                    }

                    GOPGDAT.Record record = new GOPGDAT.Record();
                    record.Index = uint.Parse(this.Records[recordIndex, 0]);
                    record.Data  = dataStream.ToArray();

                    dat.Records.Add(record);
                }
            }

            met.Root = ConvertToRawMetric(this.RootMetric, strt);

            sections.Add(met);
            sections.Add(rec);
            sections.Add(strt);
            sections.Add(dat);
            sections.Add(new GENEEOF());

            SectionIO.WriteAll(stream, sections);
        }
Example #3
0
        public void Write(Stream stream)
        {
            GENESTRT nameTable = new GENESTRT();

            nameTable.Strings.Add(this.Name);

            PACKHEDR packhedr = new PACKHEDR();

            packhedr.Unknown1   = 0x10000;
            packhedr.NameIndex  = 0;
            packhedr.DataOffset = 0;            // Filled in later.
            packhedr.Unknown3   = 1;
            packhedr.Hash       = new byte[16]; // TODO

            PACKTOC toc = new PACKTOC();

            byte[] fileData;
            using (MemoryStream fileStream = new MemoryStream()) {
                this.WriteFiles(fileStream, toc, nameTable);
                fileData = fileStream.ToArray();
            }

            PACKFSLS      fsls         = new PACKFSLS();
            List <byte[]> fileSetDatas = new List <byte[]>();
            uint          nameIndex    = (uint)nameTable.Strings.Count;

            foreach (FileSet fileSet in this.FileSets)
            {
                byte[] fileSetData;
                using (MemoryStream fileSetStream = new MemoryStream()) {
                    this.WriteFileSet(fileSetStream, fileSet);
                    fileSetData = fileSetStream.ToArray();
                }

                PACKFSLS.FileSetEntry entry = new PACKFSLS.FileSetEntry();
                entry.NameIndex    = nameTable.AddString(fileSet.Name);
                entry.PackageIndex = 0;
                entry.Offset       = 0; // Filled in later.
                entry.Size         = (ulong)fileSetData.Length;
                entry.Hash         = new MD5CryptoServiceProvider().ComputeHash(fileSetData);

                fsls.FileSets.Add(entry);
                fileSetDatas.Add(fileSetData);
            }

            SectionSet set = new SectionSet();

            set.Add(new ENDILTLE());
            set.Add(packhedr);
            set.Add(toc);
            set.Add(fsls);
            set.Add(nameTable);
            set.Add(new GENEEOF());

            ulong headersSize;

            using (MemoryStream sizeTestStream = new MemoryStream()) {
                SectionIO.WriteAll(sizeTestStream, set);
                headersSize = (ulong)sizeTestStream.Length;
            }

            ulong currOffset = NumberUtil.Align(headersSize, 0x800);

            packhedr.DataOffset = (uint)currOffset;
            foreach (PACKTOC.Entry entry in toc.Entries)
            {
                if (entry is PACKTOC.UncompressedFileEntry uFileEntry)
                {
                    uFileEntry.Offset = currOffset;
                    currOffset        = NumberUtil.Align(currOffset + uFileEntry.Size, 0x200);
                }
                else if (entry is PACKTOC.CompressedFileEntry cFileEntry)
                {
                    cFileEntry.Offset = currOffset;
                    currOffset        = NumberUtil.Align(currOffset + cFileEntry.CompressedSize, 0x200);
                }
            }

            currOffset = NumberUtil.Align(currOffset, 0x800);
            foreach (PACKFSLS.FileSetEntry fileSetEntry in fsls.FileSets)
            {
                fileSetEntry.Offset = currOffset;
                currOffset          = NumberUtil.Align(currOffset + fileSetEntry.Size, 0x800);
            }

            SectionIO.WriteAll(stream, set);
            stream.PadTo(0x800);

            stream.Write(fileData);

            foreach (byte[] fileSetData in fileSetDatas)
            {
                stream.PadTo(0x800);
                stream.Write(fileSetData);
            }
        }