public void Pack(VirtualFolder root, EndianBinaryWriter writer) { Header = new RARCHeader(); Header.Magic = "RARC"; Header.Unknown1 = 0x20; Header.Unknown6 = 0x20; Nodes = new List <RARCNode>(); Entries = new List <RARCFileEntry>(); StringTable = new List <char>(); Data = new List <byte>(); StringTable.Add('.'); StringTable.Add('\0'); StringTable.Add('.'); StringTable.Add('.'); StringTable.Add('\0'); RARCNode rootNode = new RARCNode(); rootNode.Type = "ROOT"; rootNode.NameOffset = 5; rootNode.NameHash = HashName(root.Name); foreach (char c in root.Name) { StringTable.Add(c); } StringTable.Add('\0'); rootNode.FileEntryCount = (short)(root.Subdirs.Count + root.Files.Count + 2); rootNode.FirstFileEntryIndex = 0; Nodes.Add(rootNode); EntryCount = rootNode.FileEntryCount; foreach (VirtualFolder folder in root.Subdirs) { RecursiveDir(folder, rootNode); } foreach (FileData file in root.Files) { Entries.Add(AddFileFileEntry(file)); } #region Add first two period entries. Not using the method I created because of course these two have a slightly different format.... RARCFileEntry singlePeriod = new RARCFileEntry(); singlePeriod.FileId = -1; singlePeriod.NameHash = 0x2E; singlePeriod.Type = 2; singlePeriod.Padding = 0; singlePeriod.NameOffset = 0; singlePeriod.DataOffset = 0; singlePeriod.DataSize = 0x10; singlePeriod.Zero = 0; Entries.Add(singlePeriod); RARCFileEntry doublePeriod = new RARCFileEntry(); doublePeriod.FileId = -1; doublePeriod.NameHash = 0xB8; doublePeriod.Type = 2; doublePeriod.Padding = 0; doublePeriod.NameOffset = 2; doublePeriod.DataOffset = -1; doublePeriod.DataSize = 0x10; doublePeriod.Zero = 0; Entries.Add(doublePeriod); #endregion foreach (VirtualFolder folder in root.Subdirs) { RecursiveFile(folder); } Header.NodeCount = Nodes.Count; Header.Unknown2 = Data.Count; Header.Unknown3 = Data.Count; Header.Unknown7 = Entries.Count; Header.FileEntryCount = (short)Entries.Count; Header.UnknownBool1 = 1; int headerLength = 64; int unalignedData = (headerLength + (Nodes.Count * 16) + (Entries.Count * 20) + StringTable.Count); int alignedEntries = ((Entries.Count * 0x14) + 0x1F) & ~0x1F; int alignedNodes = ((Nodes.Count * 0x10) + 0x1F) & ~0x1F; int alignedTable = alignedNodes + alignedEntries + headerLength; int alignedStringTableSize = (StringTable.Count + 0x1F) & ~0x1F; int alignedData = (alignedTable + alignedStringTableSize + 0x1F) & ~0x1F; Header.Unknown8 = alignedStringTableSize; Header.FileEntriesOffset = alignedNodes + 64 - 0x20; Header.StringTableOffset = alignedTable - 0x20; Header.DataOffset = alignedData - 0x20; Header.FileSize = (alignedData + Data.Count + 0x1F) & ~0x1F; Write(writer); }
public void Pack(VirtualFolder root, EndianBinaryWriter writer) { Header = new RARCHeader(); Header.Magic = "RARC"; Header.Unknown1 = 0x20; Header.Unknown6 = 0x20; Nodes = new List<RARCNode>(); Entries = new List<RARCFileEntry>(); StringTable = new List<char>(); Data = new List<byte>(); StringTable.Add('.'); StringTable.Add('\0'); StringTable.Add('.'); StringTable.Add('.'); StringTable.Add('\0'); RARCNode rootNode = new RARCNode(); rootNode.Type = "ROOT"; rootNode.NameOffset = 5; rootNode.NameHash = HashName(root.Name); foreach (char c in root.Name) { StringTable.Add(c); } StringTable.Add('\0'); rootNode.FileEntryCount = (short)(root.Subdirs.Count + root.Files.Count + 2); rootNode.FirstFileEntryIndex = 0; Nodes.Add(rootNode); EntryCount = rootNode.FileEntryCount; foreach (VirtualFolder folder in root.Subdirs) { RecursiveDir(folder, rootNode); } foreach (FileData file in root.Files) { Entries.Add(AddFileFileEntry(file)); } #region Add first two period entries. Not using the method I created because of course these two have a slightly different format.... RARCFileEntry singlePeriod = new RARCFileEntry(); singlePeriod.FileId = -1; singlePeriod.NameHash = 0x2E; singlePeriod.Type = 2; singlePeriod.Padding = 0; singlePeriod.NameOffset = 0; singlePeriod.DataOffset = 0; singlePeriod.DataSize = 0x10; singlePeriod.Zero = 0; Entries.Add(singlePeriod); RARCFileEntry doublePeriod = new RARCFileEntry(); doublePeriod.FileId = -1; doublePeriod.NameHash = 0xB8; doublePeriod.Type = 2; doublePeriod.Padding = 0; doublePeriod.NameOffset = 2; doublePeriod.DataOffset = -1; doublePeriod.DataSize = 0x10; doublePeriod.Zero = 0; Entries.Add(doublePeriod); #endregion foreach (VirtualFolder folder in root.Subdirs) { RecursiveFile(folder); } Header.NodeCount = Nodes.Count; Header.Unknown2 = Data.Count; Header.Unknown3 = Data.Count; Header.Unknown7 = Entries.Count; Header.FileEntryCount = (short)Entries.Count; Header.UnknownBool1 = 1; int headerLength = 64; int unalignedData = (headerLength + (Nodes.Count * 16) + (Entries.Count * 20) + StringTable.Count); int alignedEntries = ((Entries.Count * 0x14) + 0x1F) & ~0x1F; int alignedNodes = ((Nodes.Count * 0x10) + 0x1F) & ~0x1F; int alignedTable = alignedNodes + alignedEntries + headerLength; int alignedStringTableSize = (StringTable.Count + 0x1F) & ~0x1F; int alignedData = (alignedTable + alignedStringTableSize + 0x1F) & ~0x1F; Header.Unknown8 = alignedStringTableSize; Header.FileEntriesOffset = alignedNodes + 64 - 0x20; Header.StringTableOffset = alignedTable - 0x20; Header.DataOffset = alignedData - 0x20; Header.FileSize = (alignedData + Data.Count + 0x1F) & ~0x1F; Write(writer); }