2025-08-26 04:29:30 +03:00
|
|
|
|
using System.Buffers.Binary;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using NResLib;
|
|
|
|
|
|
|
2026-05-17 15:40:16 +03:00
|
|
|
|
namespace MshLib;
|
2025-08-26 04:29:30 +03:00
|
|
|
|
|
2026-05-09 20:36:43 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// MSH-компонент 0x0A: строки узлов.
|
|
|
|
|
|
/// У FParkan: Res10 / Node strings. Старое локальное имя: ExternalRefs.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class Msh0x0A
|
2025-08-26 04:29:30 +03:00
|
|
|
|
{
|
|
|
|
|
|
public static List<string> ReadComponent(FileStream mshFs, NResArchive archive)
|
|
|
|
|
|
{
|
|
|
|
|
|
var aFileEntry = archive.Files.FirstOrDefault(x => x.FileType == "0A 00 00 00");
|
|
|
|
|
|
|
|
|
|
|
|
if (aFileEntry is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("Archive doesn't contain 0A component");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var data = new byte[aFileEntry.FileLength];
|
|
|
|
|
|
mshFs.Seek(aFileEntry.OffsetInFile, SeekOrigin.Begin);
|
|
|
|
|
|
mshFs.ReadExactly(data, 0, data.Length);
|
|
|
|
|
|
|
|
|
|
|
|
int pos = 0;
|
|
|
|
|
|
var strings = new List<string>();
|
|
|
|
|
|
while (pos < data.Length)
|
|
|
|
|
|
{
|
2026-05-09 20:36:43 +03:00
|
|
|
|
if (pos + 4 > data.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("Node strings component (0x0A) has truncated length prefix");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-26 04:29:30 +03:00
|
|
|
|
var len = BinaryPrimitives.ReadInt32LittleEndian(data.AsSpan(pos));
|
2026-05-09 20:36:43 +03:00
|
|
|
|
if (len < 0 || pos + 4 + len > data.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("Node strings component (0x0A) has invalid string length");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-26 04:29:30 +03:00
|
|
|
|
if (len == 0)
|
|
|
|
|
|
{
|
2026-05-09 20:36:43 +03:00
|
|
|
|
pos += 4;
|
|
|
|
|
|
strings.Add("");
|
2025-08-26 04:29:30 +03:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var strBytes = data.AsSpan(pos + 4, len);
|
2026-05-09 20:36:43 +03:00
|
|
|
|
var str = Encoding.ASCII.GetString(strBytes);
|
2025-08-26 04:29:30 +03:00
|
|
|
|
strings.Add(str);
|
2026-05-09 20:36:43 +03:00
|
|
|
|
pos += len + 4;
|
|
|
|
|
|
if (pos < data.Length && data[pos] == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
pos++;
|
|
|
|
|
|
}
|
2025-08-26 04:29:30 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (strings.Count != aFileEntry.ElementCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("String count mismatch in 0A component");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return strings;
|
|
|
|
|
|
}
|
2026-05-09 20:36:43 +03:00
|
|
|
|
}
|