diff --git a/RszTool/EnumParser.cs b/RszTool/EnumParser.cs index 27248e2..309f27f 100644 --- a/RszTool/EnumParser.cs +++ b/RszTool/EnumParser.cs @@ -21,6 +21,16 @@ public static EnumParser GetInstance(string jsonPath) public EnumDict EnumDict { get; } + public static EnumParser FromJson(string json) + { + return new EnumParser(new EnumDict(JsonSerializer.Deserialize>(json) ?? [])); + } + + public EnumParser(EnumDict enumDict) + { + EnumDict = enumDict; + } + public EnumParser(string jsonPath) { if (File.Exists(jsonPath)) diff --git a/RszTool/RszFile/PfbFile.cs b/RszTool/RszFile/PfbFile.cs index 4fa6abc..18151cc 100644 --- a/RszTool/RszFile/PfbFile.cs +++ b/RszTool/RszFile/PfbFile.cs @@ -113,7 +113,17 @@ public GameObjectData? Parent set => parentRef = value != null ? new(value) : null; } - public string? Name => (Instance?.GetFieldValue("v0") ?? Instance?.GetFieldValue("Name")) as string; + public string? Name + { + get => (Instance?.GetFieldValue("v0") ?? Instance?.GetFieldValue("Name")) as string; + set + { + if (Instance != null && value != null) + { + Instance?.SetFieldValue("Name", value); + } + } + } public int? ObjectId => Info?.Data.objectId; diff --git a/RszTool/RszFile/RSZFile.cs b/RszTool/RszFile/RSZFile.cs index 9d11ceb..e4e673c 100644 --- a/RszTool/RszFile/RSZFile.cs +++ b/RszTool/RszFile/RSZFile.cs @@ -1,5 +1,4 @@ using System.Text; -using RszTool.Common; namespace RszTool { @@ -31,7 +30,7 @@ public struct ObjectTable /// 基于InstanceInfoList生成的实例列表 /// 一般第一个项是NULL,手动构建时需要注意 /// - public List InstanceList { get; } = new(); + public RszInstanceList InstanceList { get; } = new(); /// /// 基于ObjectTableList生成的实例列表,是对外公开的实例, /// InstanceList中包括里面依赖的成员实例或者实例数组的项 @@ -344,12 +343,6 @@ public void InstanceUnflatten(RszInstance instance) { if (items[j] is int instanceId) { - if (instanceId >= instance.Index && field.IsTypeInferred) - { - // TODO: may detect error, should roll back - field.type = RszFieldType.S32; - throw new RszRetryOpenException($"Detected {instance.RszClass.name}.{field.name} as Object before, but seems wrong"); - } items[j] = InstanceList[instanceId]; InstanceUnflatten(InstanceList[instanceId]); } @@ -357,12 +350,6 @@ public void InstanceUnflatten(RszInstance instance) } else if (instance.Values[i] is int instanceId) { - if (instanceId >= instance.Index && field.IsTypeInferred) - { - // TODO: may detect error, should roll back - field.type = RszFieldType.S32; - throw new RszRetryOpenException($"Detected {instance.RszClass.name}.{field.name} as Object before, but seems wrong"); - } instance.Values[i] = InstanceList[instanceId]; InstanceUnflatten(InstanceList[instanceId]); } diff --git a/RszTool/RszFile/RszFileOption.cs b/RszTool/RszFile/RszFileOption.cs index e519602..89a4260 100644 --- a/RszTool/RszFile/RszFileOption.cs +++ b/RszTool/RszFile/RszFileOption.cs @@ -7,6 +7,14 @@ public class RszFileOption public RszParser RszParser { get; set; } public EnumParser EnumParser { get; set; } + public RszFileOption(GameName gameName, GameVersion version, RszParser rszParser, EnumParser enumParser) + { + GameName = gameName; + Version = version; + RszParser = rszParser; + EnumParser = enumParser; + } + public RszFileOption(GameName gameName) { GameName = gameName; diff --git a/RszTool/RszFile/RszInstance.cs b/RszTool/RszFile/RszInstance.cs index 7ef9067..819862e 100644 --- a/RszTool/RszFile/RszInstance.cs +++ b/RszTool/RszFile/RszInstance.cs @@ -370,6 +370,7 @@ public static Type RszFieldTypeToCSharpType(RszFieldType type) RszFieldType.Cone => typeof(via.Cone), RszFieldType.Line => typeof(via.Line), RszFieldType.LineSegment => typeof(via.LineSegment), + RszFieldType.OBB => typeof(via.OBB), RszFieldType.Plane => typeof(via.Plane), RszFieldType.PlaneXZ => typeof(via.PlaneXZ), RszFieldType.Size => typeof(via.Size), diff --git a/RszTool/RszFile/RszInstanceList.cs b/RszTool/RszFile/RszInstanceList.cs new file mode 100644 index 0000000..fee434b --- /dev/null +++ b/RszTool/RszFile/RszInstanceList.cs @@ -0,0 +1,55 @@ +using System.Collections; + +namespace RszTool +{ + public class RszInstanceList : IEnumerable, IList + { + private readonly List _list = new(); + private readonly Dictionary _indexMap = new(); + + public RszInstance this[int index] + { + get => _list[index]; + set => throw new NotSupportedException(); + } + + RszInstance IList.this[int index] + { + get => this[index]; + set => this[index] = value; + } + + public int Count => _list.Count; + public bool IsReadOnly => false; + + public void Add(RszInstance item) + { + _list.Add(item); + _indexMap.Add(item, 0); + } + + public void Clear() + { + _list.Clear(); + _indexMap.Clear(); + } + + public int IndexOf(RszInstance item) + { + var result = -1; + if (_indexMap.TryGetValue(item, out var index)) + result = index; + return result; + } + + public bool Contains(RszInstance item) => _list.IndexOf(item) != -1; + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public void CopyTo(RszInstance[] array, int arrayIndex) => throw new NotImplementedException(); + public void Insert(int index, RszInstance item) => throw new NotImplementedException(); + public bool Remove(RszInstance item) => throw new NotImplementedException(); + public void RemoveAt(int index) => throw new NotImplementedException(); + } +} diff --git a/RszTool/RszFile/ScnFile.cs b/RszTool/RszFile/ScnFile.cs index 500a744..05c3302 100644 --- a/RszTool/RszFile/ScnFile.cs +++ b/RszTool/RszFile/ScnFile.cs @@ -167,7 +167,17 @@ public GameObjectData? Parent set => parentRef = value != null ? new(value) : null; } - public string? Name => (Instance?.GetFieldValue("v0") ?? Instance?.GetFieldValue("Name")) as string; + public string? Name + { + get => (Instance?.GetFieldValue("v0") ?? Instance?.GetFieldValue("Name")) as string; + set + { + if (Instance != null && value != null) + { + Instance?.SetFieldValue("Name", value); + } + } + } public int? ObjectId => Info?.Data.objectId; diff --git a/RszTool/RszParser.cs b/RszTool/RszParser.cs index 675458d..83c1132 100644 --- a/RszTool/RszParser.cs +++ b/RszTool/RszParser.cs @@ -27,6 +27,22 @@ public static RszParser GetInstance(string jsonPath) public Dictionary ClassDict => classDict; + public RszParser(IEnumerable classes) + { + classDict = classes.ToDictionary(x => x.typeId); + classNameDict = classes.ToDictionary(x => x.name); + foreach (var c in classes) + { + foreach (var field in c.fields) + { + if (field.type == RszFieldType.Data) + { + field.GuessDataType(); + } + } + } + } + public RszParser(string jsonPath) { classDict = new(); diff --git a/RszTool/RszTool.csproj b/RszTool/RszTool.csproj index 3339f60..d99f1cb 100644 --- a/RszTool/RszTool.csproj +++ b/RszTool/RszTool.csproj @@ -10,7 +10,7 @@ - +