public void ReadRootPac(byte[] buffer, string splitName = "") { using (var reader = new FileReader(new System.IO.MemoryStream(buffer))) { var header3 = reader.ReadStruct <HeaderV3>(); PacNodeTree tree = new PacNodeTree(); tree.Read(reader, header3); var rootNode = tree.RootNode; LoadTree(rootNode, splitName); if (header3.SplitCount != 0) { //Read the split data if present reader.SeekBegin(48 + header3.NodesSize); ulong splitCount = reader.ReadUInt64(); ulong splitEntriesOffset = reader.ReadUInt64(); reader.SeekBegin(splitEntriesOffset); for (int i = 0; i < (int)splitCount; i++) { SplitEntry entry = new SplitEntry(); entry.SplitNameOffset = reader.ReadUInt64(); entry.SplitCompressedSize = reader.ReadUInt32(); entry.SplitUncompressedSize = reader.ReadUInt32(); entry.SplitOffset = reader.ReadUInt32(); entry.SplitChunkCount = reader.ReadUInt32(); entry.SplitChunksOffset = reader.ReadUInt64(); using (reader.TemporarySeek((long)entry.SplitNameOffset, System.IO.SeekOrigin.Begin)) { entry.Name = reader.ReadZeroTerminatedString(); } using (reader.TemporarySeek((long)entry.SplitChunksOffset, System.IO.SeekOrigin.Begin)) { entry.Chunks = reader.ReadMultipleStructs <Chunk>(entry.SplitChunkCount); } SplitEntries.Add(entry); Console.WriteLine("SplitName " + entry.Name); Console.WriteLine("SplitCompressedSize " + entry.SplitCompressedSize); Console.WriteLine("SplitUncompressedSize " + entry.SplitUncompressedSize); Console.WriteLine("SplitOffset " + entry.SplitOffset); Console.WriteLine("SplitChunkCount " + entry.SplitChunkCount); Console.WriteLine("SplitChunksOffset " + entry.SplitChunksOffset); } } } }
private void AddSplitEntryToCategories(SplitEntry entry, string categoryName) { if (Categories.ContainsKey(categoryName)) { Categories[categoryName].Add(entry); } else { List <SplitEntry> splitlist = new List <SplitEntry>(); splitlist.Add(entry); Categories.Add(categoryName, splitlist); comboCategories.Items.Add(categoryName); } }
public bool MoveNext() { var span = chars; if (span.Length == 0) // Reach the end of the string return false; var index = span.IndexOfAny(separators); if (index == -1) // The string is composed of only one line { chars = ReadOnlySpan<char>.Empty; // The remaining string is an empty string current = new SplitEntry(span, ReadOnlySpan<char>.Empty); return true; } if (index < span.Length - 1) { // Try to consume the '\n' associated to the '\r' var next = span[index + 1]; if (separators.Contains(next)) { current = new SplitEntry(span.Slice(0, index), span.Slice(index, 2)); chars = span[(index + 2)..];
public void ReadSplitPac(FileReader reader, SplitEntry entry) { reader.SeekBegin(entry.SplitOffset); ReadRootPac(DecompressChunks(reader, entry.Chunks), entry.Name); }
public SplitEnumerator(ReadOnlySpan<char> str, ReadOnlySpan<char> separators) { this.chars = str; this.separators = separators; this.current = default; }
private bool CheckIfIniFileHasModels(SplitEntry split) { // Returns true if the split INI file for the entry has models string inipath = Path.Combine(modFolder, split.IniFile + "_data.ini"); if (!File.Exists(inipath)) { return(false); } // Check source file extension to determine what kind of split INI data is used with it switch (Path.GetExtension(split.SourceFile).ToLowerInvariant()) { case ".nb": Dictionary <int, string> nbFilenames = IniSerializer.Deserialize <Dictionary <int, string> >(inipath); foreach (var nbitem in nbFilenames) { string entryFilename = nbitem.Value; if (nbitem.Value.Contains("|")) { string[] nbMeta = nbitem.Value.Split('|'); entryFilename = nbMeta[0]; } switch (Path.GetExtension(entryFilename).ToLowerInvariant()) { case ".sa1mdl": case ".sa2mdl": case ".sa2bmdl": return(true); default: break; } } break; default: IniDictionary iniFile = SplitTools.IniFile.Load(inipath); foreach (var key in iniFile) { // If this section exists in the file, it's a DLL split if (key.Key == "SAMDLData") { if (key.Value.Count > 0) { return(true); } } // Regular binary split if (key.Value.ContainsKey("type")) { switch (key.Value["type"]) { case "model": case "basicmodel": case "basicdxmodel": case "chunkmodel": case "gcmodel": return(true); default: break; } } } break; } return(false); }