diff --git a/NResUI/App.cs b/NResUI/App.cs index 2e413f0..fa01212 100644 --- a/NResUI/App.cs +++ b/NResUI/App.cs @@ -55,6 +55,7 @@ public class App serviceCollection.AddSingleton(new MissionTmaViewModel()); serviceCollection.AddSingleton(new BinaryExplorerViewModel()); serviceCollection.AddSingleton(new ScrViewModel()); + serviceCollection.AddSingleton(new VarsetViewModel()); var serviceProvider = serviceCollection.BuildServiceProvider(); diff --git a/NResUI/ImGuiUI/MainMenuBar.cs b/NResUI/ImGuiUI/MainMenuBar.cs index 000eb05..c005e54 100644 --- a/NResUI/ImGuiUI/MainMenuBar.cs +++ b/NResUI/ImGuiUI/MainMenuBar.cs @@ -8,6 +8,7 @@ using NResUI.Abstractions; using NResUI.Models; using ScrLib; using TexmLib; +using VarsetLib; namespace NResUI.ImGuiUI { @@ -16,6 +17,7 @@ namespace NResUI.ImGuiUI TexmExplorerViewModel texmExplorerViewModel, ScrViewModel scrViewModel, MissionTmaViewModel missionTmaViewModel, + VarsetViewModel varsetViewModel, MessageBoxModalPanel messageBox) : IImGuiPanel { @@ -104,6 +106,21 @@ namespace NResUI.ImGuiUI } } + if (ImGui.MenuItem("Open Varset File")) + { + var result = Dialog.FileOpen("var"); + + if (result.IsOk) + { + var path = result.Path; + var parseResult = VarsetParser.Parse(path); + + varsetViewModel.Items = parseResult; + + Console.WriteLine("Read VARSET"); + } + } + if (nResExplorerViewModel.HasFile) { if (ImGui.MenuItem("Экспортировать NRes")) diff --git a/NResUI/ImGuiUI/VarsetExplorerPanel.cs b/NResUI/ImGuiUI/VarsetExplorerPanel.cs new file mode 100644 index 0000000..9818f4a --- /dev/null +++ b/NResUI/ImGuiUI/VarsetExplorerPanel.cs @@ -0,0 +1,57 @@ +using ImGuiNET; +using NResUI.Abstractions; +using NResUI.Models; + +namespace NResUI.ImGuiUI; + +public class VarsetExplorerPanel : IImGuiPanel +{ + private readonly VarsetViewModel _viewModel; + + public VarsetExplorerPanel(VarsetViewModel viewModel) + { + _viewModel = viewModel; + } + + public void OnImGuiRender() + { + if (ImGui.Begin("VARSET Explorer")) + { + if (_viewModel.Items.Count == 0) + { + ImGui.Text("VARSET не загружен"); + } + else + { + if (ImGui.BeginTable($"varset", 4, ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoHostExtendX)) + { + ImGui.TableSetupColumn("Индекс"); + ImGui.TableSetupColumn("Тип"); + ImGui.TableSetupColumn("Имя"); + ImGui.TableSetupColumn("Значение"); + ImGui.TableHeadersRow(); + + for (int j = 0; j < _viewModel.Items.Count; j++) + { + var item = _viewModel.Items[j]; + ImGui.TableNextRow(); + ImGui.TableNextColumn(); + ImGui.Text(j.ToString()); + ImGui.TableNextColumn(); + ImGui.Text(item.Type); + ImGui.TableNextColumn(); + ImGui.Text(item.Name); + ImGui.TableNextColumn(); + ImGui.Text(item.Value); + } + + ImGui.EndTable(); + } + + ImGui.TreePop(); + } + + ImGui.End(); + } + } +} \ No newline at end of file diff --git a/NResUI/Models/VarsetViewModel.cs b/NResUI/Models/VarsetViewModel.cs new file mode 100644 index 0000000..c4c6fbe --- /dev/null +++ b/NResUI/Models/VarsetViewModel.cs @@ -0,0 +1,8 @@ +using VarsetLib; + +namespace NResUI.Models; + +public class VarsetViewModel +{ + public List Items { get; set; } = []; +} \ No newline at end of file diff --git a/NResUI/NResUI.csproj b/NResUI/NResUI.csproj index 1656b84..17ac16d 100644 --- a/NResUI/NResUI.csproj +++ b/NResUI/NResUI.csproj @@ -23,6 +23,7 @@ + diff --git a/ParkanPlayground.sln b/ParkanPlayground.sln index 1a55c8f..c09d3a1 100644 --- a/ParkanPlayground.sln +++ b/ParkanPlayground.sln @@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MissionTmaLib", "MissionTma EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScrLib", "ScrLib\ScrLib.csproj", "{C445359B-97D4-4432-9331-708B5A14887A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VarsetLib", "VarsetLib\VarsetLib.csproj", "{0EC800E2-1444-40D5-9EDD-93276F4D1FF5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,5 +73,9 @@ Global {C445359B-97D4-4432-9331-708B5A14887A}.Debug|Any CPU.Build.0 = Debug|Any CPU {C445359B-97D4-4432-9331-708B5A14887A}.Release|Any CPU.ActiveCfg = Release|Any CPU {C445359B-97D4-4432-9331-708B5A14887A}.Release|Any CPU.Build.0 = Release|Any CPU + {0EC800E2-1444-40D5-9EDD-93276F4D1FF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0EC800E2-1444-40D5-9EDD-93276F4D1FF5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0EC800E2-1444-40D5-9EDD-93276F4D1FF5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0EC800E2-1444-40D5-9EDD-93276F4D1FF5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/ParkanPlayground/ParkanPlayground.csproj b/ParkanPlayground/ParkanPlayground.csproj index d8e0c53..a0a96e4 100644 --- a/ParkanPlayground/ParkanPlayground.csproj +++ b/ParkanPlayground/ParkanPlayground.csproj @@ -9,6 +9,8 @@ + + diff --git a/ParkanPlayground/Program.cs b/ParkanPlayground/Program.cs index 78a4b2f..289364b 100644 --- a/ParkanPlayground/Program.cs +++ b/ParkanPlayground/Program.cs @@ -1,64 +1,29 @@ -using System.Buffers.Binary; -using System.Text; -using NResLib; -using ParkanPlayground; +using VarsetLib; + // var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS\\default.scr"; // var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS\\scr_pl_1.scr"; // var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS\\scream.scr"; -var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS\\scream1.scr"; +// var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS\\scream1.scr"; +// var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS"; +var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\MISSIONS\\SCRIPTS\\varset.var"; +// var path = "C:\\Program Files (x86)\\Nikita\\Iron Strategy\\preload.lda"; +// +// var fs = new FileStream(path, FileMode.Open); +// +// var count = fs.ReadInt32LittleEndian(); +// +// Span data = stackalloc byte[0x124]; +// +// for (var i = 0; i < count; i++) +// { +// fs.ReadExactly(data); +// } +// +// Console.WriteLine( +// fs.Position == fs.Length +// ); -using var fs = new FileStream(path, FileMode.Open); +var items = VarsetParser.Parse(path); -// тут всегда число 59 (0x3b) - это число известных игре скриптов -var magic = fs.ReadInt32LittleEndian(); - -Console.WriteLine($"Count: {magic}"); - -var entryCount = fs.ReadInt32LittleEndian(); - -Console.WriteLine($"EntryCount: {entryCount}"); - -for (var i = 0; i < entryCount; i++) -{ - Console.WriteLine($"Entry: {i}"); - var str = fs.ReadLengthPrefixedString(); - - Console.WriteLine($"\tStr: {str}"); - - // тут игра дополнительно вычитывает ещё 1 байт, видимо как \0 для char* - fs.ReadByte(); - - var index = fs.ReadInt32LittleEndian(); - Console.WriteLine($"\tIndex: {index}"); - var innerCount = fs.ReadInt32LittleEndian(); - Console.WriteLine($"\tInnerCount: {innerCount}"); - for (var i1 = 0; i1 < innerCount; i1++) - { - var scriptIndex = fs.ReadInt32LittleEndian(); - var unkInner2 = fs.ReadInt32LittleEndian(); - var unkInner3 = fs.ReadInt32LittleEndian(); - var unkInner4 = fs.ReadInt32LittleEndian(); - var unkInner5 = fs.ReadInt32LittleEndian(); - - Console.WriteLine($"\t\tScriptIndex: {scriptIndex}"); - Console.WriteLine($"\t\tUnkInner2: {unkInner2}"); - Console.WriteLine($"\t\tUnkInner3: {unkInner3}"); - Console.WriteLine($"\t\tUnkInner4: {unkInner4}"); - Console.WriteLine($"\t\tUnkInner5: {unkInner5}"); - - var scriptArgumentsCount = fs.ReadInt32LittleEndian(); - Console.WriteLine($"\t\tScript Arguments Count: {scriptArgumentsCount}"); - - for (var i2 = 0; i2 < scriptArgumentsCount; i2++) - { - var scriptArgument = fs.ReadInt32LittleEndian(); - Console.WriteLine($"\t\t\t{scriptArgument}"); - } - - var unkInner7 = fs.ReadInt32LittleEndian(); - - Console.WriteLine($"\t\tUnkInner7 {unkInner7}"); - Console.WriteLine("---"); - } -} +Console.WriteLine(items.Count); \ No newline at end of file diff --git a/VarsetLib/VarsetItem.cs b/VarsetLib/VarsetItem.cs new file mode 100644 index 0000000..1cc1078 --- /dev/null +++ b/VarsetLib/VarsetItem.cs @@ -0,0 +1,3 @@ +namespace VarsetLib; + +public record VarsetItem(string Type, string Name, string Value); \ No newline at end of file diff --git a/VarsetLib/VarsetLib.csproj b/VarsetLib/VarsetLib.csproj new file mode 100644 index 0000000..3a63532 --- /dev/null +++ b/VarsetLib/VarsetLib.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/VarsetLib/VarsetParser.cs b/VarsetLib/VarsetParser.cs new file mode 100644 index 0000000..019b4eb --- /dev/null +++ b/VarsetLib/VarsetParser.cs @@ -0,0 +1,68 @@ +namespace VarsetLib; + +public class VarsetParser +{ + public static List Parse(string path) + { + FileStream fs = new FileStream(path, FileMode.Open); + + var reader = new StreamReader(fs); + + List varsetItems = []; + + var lineIndex = 1; + while (!reader.EndOfStream) + { + var line = reader.ReadLine()!; + if (line.Length == 0) + { + lineIndex++; + continue; + } + + if (line.StartsWith("//") || line.Trim().StartsWith("//")) + { + lineIndex++; + continue; + } + + if (!line.StartsWith("VAR")) + { + Console.WriteLine($"Error on line: {lineIndex}! Not starting with VAR"); + lineIndex++; + continue; + } + + var openParenthesisIndex = line.IndexOf("("); + var closeParenthesisIndex = line.IndexOf(")"); + + if (openParenthesisIndex == -1 || closeParenthesisIndex == -1 || closeParenthesisIndex <= openParenthesisIndex) + { + Console.WriteLine($"Error on line: {lineIndex}! VAR() format invalid"); + lineIndex++; + continue; + } + + var arguments = line.Substring(openParenthesisIndex + 1, closeParenthesisIndex - openParenthesisIndex - 1); + + var parts = arguments.Trim() + .Split(','); + + var type = parts[0] + .Trim(); + + var name = parts[1] + .Trim(); + + var value = parts[2] + .Trim(); + + var item = new VarsetItem(type, name, value); + varsetItems.Add(item); + + lineIndex++; + } + + return varsetItems; + } +} \ No newline at end of file