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); } }
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); }
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); } }