fixed GSA writing, added always-edit button and search in file and for file

This commit is contained in:
2026-07-21 15:50:52 +02:00
parent cbf0891ba4
commit d171c34236
42 changed files with 538 additions and 61 deletions

View File

@ -1,4 +1,4 @@
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace GsaEditor.Core.IO;
@ -34,10 +34,20 @@ public class GsaIndexEntry
}
/// <summary>
/// Parses .idx NML index files (XML-compatible format) into a list of <see cref="GsaIndexEntry"/>.
/// Parses .idx NML index files into a list of <see cref="GsaIndexEntry"/>.
/// NML is the engine's own tag syntax (&lt;Name=value&gt; blocks, see <see cref="GsaIndexWriter"/>),
/// not standard XML.
/// </summary>
public static class GsaIndexReader
{
private static readonly Regex EntryRegex = new(
@"<Entry=(?<body>.*?)\n\s*>",
RegexOptions.Singleline | RegexOptions.Compiled);
private static readonly Regex TagRegex = new(
@"<(?<name>\w+)=""?(?<value>[^"">]*)""?>",
RegexOptions.Compiled);
/// <summary>
/// Reads index entries from the specified .idx file.
/// </summary>
@ -45,23 +55,36 @@ public static class GsaIndexReader
/// <returns>A list of parsed index entries.</returns>
public static List<GsaIndexEntry> Read(string filePath)
{
var doc = XDocument.Load(filePath);
var text = File.ReadAllText(filePath);
var entries = new List<GsaIndexEntry>();
var root = doc.Root;
if (root == null || root.Name.LocalName != "Index")
return entries;
foreach (var entryEl in root.Elements("Entry"))
foreach (Match entryMatch in EntryRegex.Matches(text))
{
var entry = new GsaIndexEntry
var entry = new GsaIndexEntry();
foreach (Match tag in TagRegex.Matches(entryMatch.Groups["body"].Value))
{
Id = entryEl.Element("Id")?.Value ?? string.Empty,
Method = int.TryParse(entryEl.Element("Method")?.Value, out var m) ? m : 0,
Length = uint.TryParse(entryEl.Element("Len")?.Value, out var l) ? l : 0,
CompressedLength = uint.TryParse(entryEl.Element("CompLen")?.Value, out var cl) ? cl : 0,
Offset = long.TryParse(entryEl.Element("Offset")?.Value, out var o) ? o : 0
};
var value = tag.Groups["value"].Value;
switch (tag.Groups["name"].Value)
{
case "ID":
entry.Id = value;
break;
case "Method":
entry.Method = value.Equals("Zlib", StringComparison.OrdinalIgnoreCase) ? 1 : 0;
break;
case "Len":
entry.Length = uint.TryParse(value, out var l) ? l : 0;
break;
case "CompLen":
entry.CompressedLength = uint.TryParse(value, out var cl) ? cl : 0;
break;
case "Offset":
entry.Offset = long.TryParse(value, out var o) ? o : 0;
break;
}
}
entries.Add(entry);
}