void RecursiveDir(VirtualFolder folder, RARCNode rootNode) { RARCNode subdirNode = new RARCNode(); subdirNode.Type = folder.NodeName; subdirNode.NameOffset = StringTable.Count; foreach (char c in folder.Name) { StringTable.Add(c); } subdirNode.NameHash = HashName(folder.Name); subdirNode.FirstFileEntryIndex = EntryCount; subdirNode.FileEntryCount = (short)(folder.Subdirs.Count + folder.Files.Count + 2); EntryCount += (folder.Subdirs.Count + folder.Files.Count + 2); StringTable.Add('\0'); Nodes.Add(subdirNode); RARCFileEntry subdirEntry = new RARCFileEntry(); subdirEntry.FileId = -1; subdirEntry.NameHash = HashName(folder.Name); subdirEntry.Type = 2; subdirEntry.Padding = 0; subdirEntry.NameOffset = (short)subdirNode.NameOffset; subdirEntry.DataOffset = Nodes.IndexOf(subdirNode); subdirEntry.DataSize = 0x10; subdirEntry.Zero = 0; Entries.Add(subdirEntry); foreach (VirtualFolder dir in folder.Subdirs) { RecursiveDir(dir, subdirNode); } }
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); }