From eddc66e958edff780410a38e4b2a7109c9c2dd07 Mon Sep 17 00:00:00 2001 From: scientificworld Date: Tue, 23 Dec 2025 11:34:26 +0800 Subject: [PATCH] fix: improve Sas5 formats handling --- ArcFormats/Sas5/ArcGAR.cs | 21 ++++++----------- ArcFormats/Sas5/ArcSec5.cs | 47 ++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/ArcFormats/Sas5/ArcGAR.cs b/ArcFormats/Sas5/ArcGAR.cs index f52ef04f..c3537274 100644 --- a/ArcFormats/Sas5/ArcGAR.cs +++ b/ArcFormats/Sas5/ArcGAR.cs @@ -59,21 +59,14 @@ namespace GameRes.Formats.Sas5 var GetEntryName = CreateEntryNameDelegate (file.Name); index_offset += 0x20; - int real_count = 0; - for (int i = 0; i < count; ++i) - { - int block = file.View.ReadInt32 (index_offset + i * 0x14); - real_count += Convert.ToInt32 (block != block_start); - } - - var dir = new List (real_count); + var dir = new List (); for (int i = 0; i < count; ++i) { int block = file.View.ReadInt32 (index_offset); if (block == block_start) continue; var entry = new Entry { - Name = GetEntryName (i), + Name = GetEntryName (i, block - block_start - 1), Offset = file.View.ReadUInt32 (index_offset + 4), Size = file.View.ReadUInt32 (index_offset + 12), }; @@ -89,17 +82,17 @@ namespace GameRes.Formats.Sas5 return new ArcFile (file, this, dir); } - internal Func CreateEntryNameDelegate (string arc_name) + internal Func CreateEntryNameDelegate (string arc_name) { var index = Sec5Opener.LookupIndex (arc_name); string base_name = Path.GetFileNameWithoutExtension (arc_name); if (null == index) - return n => GetDefaultName (base_name, n); + return (n, m) => GetDefaultName (base_name, n); else - return (n) => { + return (n, m) => { Entry entry; - if (index.TryGetValue (n, out entry)) - return entry.Name; + if (index.TryGetValue (m, out entry)) + return entry.Name.Substring (1); // remove leading slash return GetDefaultName (base_name, n); }; } diff --git a/ArcFormats/Sas5/ArcSec5.cs b/ArcFormats/Sas5/ArcSec5.cs index 011abf5f..0ea8034c 100644 --- a/ArcFormats/Sas5/ArcSec5.cs +++ b/ArcFormats/Sas5/ArcSec5.cs @@ -112,29 +112,32 @@ namespace GameRes.Formats.Sas5 } if (0 == match.Length) return null; - using (var sec5 = new ArcView (match[0])) + foreach (var m in match) { - if (!sec5.View.AsciiEqual (0, "SEC5")) - return null; - uint offset = 8; - while (offset < sec5.MaxOffset) + using (var sec5 = new ArcView (m)) { - string id = sec5.View.ReadString (offset, 4, Encoding.ASCII); - if ("ENDS" == id) - break; - uint section_size = sec5.View.ReadUInt32 (offset+4); - offset += 8; - if ("RESR" == id) + if (!sec5.View.AsciiEqual (0, "SEC5")) + continue; + uint offset = 8; + while (offset < sec5.MaxOffset) { - using (var resr = sec5.CreateStream (offset, section_size)) - return ReadResrSection (resr); + string id = sec5.View.ReadString (offset, 4, Encoding.ASCII); + if ("ENDS" == id) + break; + uint section_size = sec5.View.ReadUInt32 (offset+4); + offset += 8; + if ("RESR" == id) + { + using (var resr = sec5.CreateStream (offset, section_size)) + return ReadResrSection (resr); + } + if ("RES2" == id) + { + using (var res2 = sec5.CreateStream (offset, section_size)) + return ReadRes2Section (res2); + } + offset += section_size; } - if ("RES2" == id) - { - using (var res2 = sec5.CreateStream (offset, section_size)) - return ReadRes2Section (res2); - } - offset += section_size; } } return null; @@ -413,10 +416,12 @@ namespace GameRes.Formats.Sas5 arc_name = ReadString(); else if ("arc-index" == param_name) arc_index = ReadInteger(); + else if ("arc-path" == param_name) + name = ReadString(); else SkipObject(); } - if (!string.IsNullOrEmpty (arc_name) && arc_index != null) + if (!string.IsNullOrEmpty (arc_name)) { arc_name = Path.GetFileName (arc_name); if (!map.ContainsKey (arc_name)) @@ -426,6 +431,8 @@ namespace GameRes.Formats.Sas5 Name = name, Type = type, }; + if (arc_index == null) + arc_index = map[arc_name].Count; map[arc_name][arc_index.Value] = entry; } }