From 2c72d47422d313b2755616be4cc6cace02e0810b Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Tue, 21 Apr 2026 12:34:01 +0200 Subject: [PATCH 1/7] feat: migrate to .NET 10.0 --- .github/workflows/build-and-release.yml | 6 +- JUSToolkit.slnx | 19 ++++++ build.cs | 2 +- src/Directory.Packages.props | 41 ++++++------ src/JUS.CLI/JUS.CLI.csproj | 2 +- .../JUS.SceneGatePlugin.csproj | 21 ++++++ src/JUS.Tests/JUS.Tests.csproj | 2 +- src/JUS.Tool/JUS.Tool.csproj | 2 +- src/JUSToolkit.sln | 67 ------------------- 9 files changed, 65 insertions(+), 97 deletions(-) create mode 100644 JUSToolkit.slnx create mode 100644 src/JUS.SceneGatePlugin/JUS.SceneGatePlugin.csproj delete mode 100644 src/JUSToolkit.sln diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index d21330f..7ff1bee 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -6,14 +6,12 @@ on: pull_request: push: # Preview - branches: [ main ] + branches: [ master ] # Stable tags: [ "v*" ] env: - DOTNET_VERSIONS: | - 8.0.420 - 10.0.202 + DOTNET_VERSIONS: 10.0.202 DOTNET_INSTALL_DIR: '/tmp/dotnet/' jobs: diff --git a/JUSToolkit.slnx b/JUSToolkit.slnx new file mode 100644 index 0000000..4594463 --- /dev/null +++ b/JUSToolkit.slnx @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/build.cs b/build.cs index 422ee7e..f3ca44a 100644 --- a/build.cs +++ b/build.cs @@ -57,7 +57,7 @@ public override void Setup(BuildContext context, ISetupContext info) new ProjectPublicationInfo( "./src/JUS.CLI", [ "win-x64", "linux-x64", "osx-x64" ], - "net8.0")); + "net10.0")); context.ReadArguments(); diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 47d8dc3..c1d8d0e 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -1,24 +1,21 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/JUS.CLI/JUS.CLI.csproj b/src/JUS.CLI/JUS.CLI.csproj index 8014701..6200e3f 100644 --- a/src/JUS.CLI/JUS.CLI.csproj +++ b/src/JUS.CLI/JUS.CLI.csproj @@ -3,7 +3,7 @@ Exe - net8.0 + net10.0 diff --git a/src/JUS.SceneGatePlugin/JUS.SceneGatePlugin.csproj b/src/JUS.SceneGatePlugin/JUS.SceneGatePlugin.csproj new file mode 100644 index 0000000..3984ea7 --- /dev/null +++ b/src/JUS.SceneGatePlugin/JUS.SceneGatePlugin.csproj @@ -0,0 +1,21 @@ + + + + SceneGate UI plugin for the JUS game formats. + + net10.0 + + enable + enable + false + + + + + + + + + + + diff --git a/src/JUS.Tests/JUS.Tests.csproj b/src/JUS.Tests/JUS.Tests.csproj index c84113c..2fd1cf5 100644 --- a/src/JUS.Tests/JUS.Tests.csproj +++ b/src/JUS.Tests/JUS.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 false diff --git a/src/JUS.Tool/JUS.Tool.csproj b/src/JUS.Tool/JUS.Tool.csproj index 4781fa1..7f2775f 100644 --- a/src/JUS.Tool/JUS.Tool.csproj +++ b/src/JUS.Tool/JUS.Tool.csproj @@ -3,7 +3,7 @@ true - net8.0 + net10.0 diff --git a/src/JUSToolkit.sln b/src/JUSToolkit.sln deleted file mode 100644 index a84beaf..0000000 --- a/src/JUSToolkit.sln +++ /dev/null @@ -1,67 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 -MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUS.Tool", "JUS.Tool\JUS.Tool.csproj", "{07E6EBB9-380D-4813-AFCD-E5856501929A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUS.CLI", "JUS.CLI\JUS.CLI.csproj", "{CB7B12D4-90B6-4564-8ECC-B6954E61A11F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUS.Tests", "JUS.Tests\JUS.Tests.csproj", "{276997DA-06FC-4C8A-AA82-92C3373C69A3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build system", "Build system", "{BF9E80B5-BC37-4F7E-8A4A-DEF982318B94}" - ProjectSection(SolutionItems) = preProject - ..\build.cs = ..\build.cs - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|x64.ActiveCfg = Debug|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|x64.Build.0 = Debug|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|x86.ActiveCfg = Debug|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|x86.Build.0 = Debug|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Release|Any CPU.Build.0 = Release|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Release|x64.ActiveCfg = Release|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Release|x64.Build.0 = Release|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Release|x86.ActiveCfg = Release|Any CPU - {07E6EBB9-380D-4813-AFCD-E5856501929A}.Release|x86.Build.0 = Release|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Debug|x64.ActiveCfg = Debug|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Debug|x64.Build.0 = Debug|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Debug|x86.ActiveCfg = Debug|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Debug|x86.Build.0 = Debug|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Release|Any CPU.Build.0 = Release|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Release|x64.ActiveCfg = Release|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Release|x64.Build.0 = Release|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Release|x86.ActiveCfg = Release|Any CPU - {CB7B12D4-90B6-4564-8ECC-B6954E61A11F}.Release|x86.Build.0 = Release|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Debug|x64.ActiveCfg = Debug|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Debug|x64.Build.0 = Debug|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Debug|x86.ActiveCfg = Debug|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Debug|x86.Build.0 = Debug|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|Any CPU.Build.0 = Release|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|x64.ActiveCfg = Release|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|x64.Build.0 = Release|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|x86.ActiveCfg = Release|Any CPU - {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal From 016444d683ca7054dc9cc589dce0e2b3b51b3958 Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Tue, 21 Apr 2026 12:39:41 +0200 Subject: [PATCH 2/7] chore: update dependencies --- .idea/.idea.JUSToolkit/.idea/.gitignore | 15 ++++++++++ .idea/.idea.JUSToolkit/.idea/.name | 1 + .idea/.idea.JUSToolkit/.idea/indexLayout.xml | 8 ++++++ .idea/.idea.JUSToolkit/.idea/vcs.xml | 6 ++++ nuget.config | 2 +- src/Directory.Packages.props | 30 ++++++++++---------- src/JUS.Tests/JUS.Tests.csproj | 10 +++++-- 7 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 .idea/.idea.JUSToolkit/.idea/.gitignore create mode 100644 .idea/.idea.JUSToolkit/.idea/.name create mode 100644 .idea/.idea.JUSToolkit/.idea/indexLayout.xml create mode 100644 .idea/.idea.JUSToolkit/.idea/vcs.xml diff --git a/.idea/.idea.JUSToolkit/.idea/.gitignore b/.idea/.idea.JUSToolkit/.idea/.gitignore new file mode 100644 index 0000000..f7634cc --- /dev/null +++ b/.idea/.idea.JUSToolkit/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/.idea.JUSToolkit.iml +/contentModel.xml +/modules.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.JUSToolkit/.idea/.name b/.idea/.idea.JUSToolkit/.idea/.name new file mode 100644 index 0000000..2499244 --- /dev/null +++ b/.idea/.idea.JUSToolkit/.idea/.name @@ -0,0 +1 @@ +JUSToolkit \ No newline at end of file diff --git a/.idea/.idea.JUSToolkit/.idea/indexLayout.xml b/.idea/.idea.JUSToolkit/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.JUSToolkit/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.JUSToolkit/.idea/vcs.xml b/.idea/.idea.JUSToolkit/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/.idea.JUSToolkit/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/nuget.config b/nuget.config index 8292bd9..9cc47fe 100644 --- a/nuget.config +++ b/nuget.config @@ -14,7 +14,7 @@ - + diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index c1d8d0e..d9137e6 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -2,20 +2,20 @@ - - - - - - + + + + + + - - - - - - - - + + + + + + + + - + \ No newline at end of file diff --git a/src/JUS.Tests/JUS.Tests.csproj b/src/JUS.Tests/JUS.Tests.csproj index 2fd1cf5..aaed41d 100644 --- a/src/JUS.Tests/JUS.Tests.csproj +++ b/src/JUS.Tests/JUS.Tests.csproj @@ -9,11 +9,17 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From 6db688c7f129be07754637a63ed86fe8ff7bca84 Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Tue, 21 Apr 2026 15:56:29 +0200 Subject: [PATCH 3/7] feat: scenegate UI plugin --- .editorconfig | 3 +- .../Containers/BinaryAlarConverterMatcher.cs | 12 ++++ .../Graphics/BinaryAlmtConverterMatcher.cs | 8 +++ .../Graphics/BinaryDsigConverterMatcher.cs | 8 +++ .../HeaderBasedBinaryMatcher.cs | 60 +++++++++++++++++++ src/JUS.SceneGatePlugin/PathBasedMatcher.cs | 41 +++++++++++++ src/JUS.SceneGatePlugin/SupportedSoftware.cs | 25 ++++++++ .../Texts/BinaryAbilityConverterMatcher.cs | 7 +++ 8 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/PathBasedMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/SupportedSoftware.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs diff --git a/.editorconfig b/.editorconfig index 9e9cc12..8232ce9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -131,7 +131,7 @@ csharp_style_throw_expression = true:warning csharp_style_conditional_delegate_call = true:warning ### Code-block preferences -csharp_prefer_braces = when_multiline:warning +csharp_prefer_braces = when_multiline:suggestion dotnet_diagnostic.SA1503.severity = warning # Doesn't follow above value csharp_prefer_simple_using_statement = true:suggestion csharp_style_prefer_tuple_swap = true:suggestion @@ -216,6 +216,7 @@ dotnet_diagnostic.IDE1006.severity = warning ### .NET SDK dotnet_diagnostic.CA1303.severity = none # We don't translate exception and log messages from English dotnet_diagnostic.SA1025.severity = none # Allow spaces in comments to structure info +dotnet_diagnostic.IDE0019.severity = suggestion # Use pattern matching dotnet_diagnostic.IDE0045.severity = suggestion # Simplify ifs dotnet_diagnostic.IDE0046.severity = suggestion # Simplify ifs dotnet_diagnostic.IDE0057.severity = suggestion # Slice can be simplified diff --git a/src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs b/src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs new file mode 100644 index 0000000..9a91597 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs @@ -0,0 +1,12 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Containers.Converters; + +namespace JUS.SceneGatePlugin.Containers; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryAlar2ConverterMatcher() + : HeaderBasedBinaryMatcher("ALAR", 2); + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryAlar3ConverterMatcher() + : HeaderBasedBinaryMatcher("ALAR", 3); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs new file mode 100644 index 0000000..cd7c73f --- /dev/null +++ b/src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs @@ -0,0 +1,8 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; + +namespace JUS.SceneGatePlugin.Graphics; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryAlmtConverterMatcher() + : HeaderBasedBinaryMatcher("ALMT"); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs new file mode 100644 index 0000000..43414c4 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs @@ -0,0 +1,8 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; + +namespace JUS.SceneGatePlugin.Graphics; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryDsigConverterMatcher() + : HeaderBasedBinaryMatcher("DSIG"); diff --git a/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs b/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs new file mode 100644 index 0000000..3008834 --- /dev/null +++ b/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs @@ -0,0 +1,60 @@ +using SceneGate.UI.Formats.Discovery; +using Yarhl.FileSystem; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin; + +public abstract class HeaderBasedBinaryMatcher : IConverterMatcher + where T : new() +{ + private readonly string expectedFormatId; + private readonly byte? expectedVersion; + + protected HeaderBasedBinaryMatcher(string formatId) + { + ArgumentNullException.ThrowIfNull(formatId); + expectedFormatId = formatId; + } + + protected HeaderBasedBinaryMatcher(string formatId, byte version) + { + ArgumentNullException.ThrowIfNull(formatId); + expectedFormatId = formatId; + expectedVersion = version; + } + + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) + { + if (input.Format is not IBinary) { + return ConverterMatcherResult.Incompatible(); + } + + MatchingConfidence level = MatchingConfidence.CannotDetermine; + if (context.Header.Length >= 4) { + string formatId = context.Header.ReadAsciiString(0, 4); + if (formatId != expectedFormatId) { + return ConverterMatcherResult.Incompatible(); + } + + if (expectedVersion.HasValue && context.Header.Length >= 5) { + byte version = context.Header.Span[4]; + if (version != expectedVersion.Value) { + return ConverterMatcherResult.Incompatible(); + } + } + + level = MatchingConfidence.CouldBe; + } + + bool? fromCompatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out _); + if (fromCompatibleSoftware == false) { + return ConverterMatcherResult.Incompatible(); + } + + if (fromCompatibleSoftware == true && level >= MatchingConfidence.CouldBe) { + level = MatchingConfidence.Confident; + } + + return ConverterMatcherResult.Create(level, new T()); + } +} diff --git a/src/JUS.SceneGatePlugin/PathBasedMatcher.cs b/src/JUS.SceneGatePlugin/PathBasedMatcher.cs new file mode 100644 index 0000000..1d70175 --- /dev/null +++ b/src/JUS.SceneGatePlugin/PathBasedMatcher.cs @@ -0,0 +1,41 @@ +using SceneGate.UI.Formats.Discovery; +using Yarhl.FileFormat; +using Yarhl.FileSystem; + +namespace JUS.SceneGatePlugin; + +public abstract class PathBasedMatcher : IConverterMatcher + where TFormat : IFormat + where TConverter : IConverter, new() +{ + private readonly string assetsPath; + + protected PathBasedMatcher(string assetsPath) + { + ArgumentException.ThrowIfNullOrEmpty(assetsPath); + this.assetsPath = assetsPath; + } + + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) + { + if (input.Format is not TFormat) { + return ConverterMatcherResult.Incompatible(); + } + + bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out Node? root); + bool isInExpectedPath = $"{root?.Path}/{assetsPath}" == input.Path; + + MatchingConfidence level = MatchingConfidence.Incompatible; + if (compatibleSoftware == true && isInExpectedPath) { + level = MatchingConfidence.Confident; + } else if (compatibleSoftware is null && isInExpectedPath) { + level = MatchingConfidence.CouldBe; + } + + if (level is MatchingConfidence.Incompatible) { + return ConverterMatcherResult.Incompatible(); + } + + return ConverterMatcherResult.Create(level, new TConverter()); + } +} diff --git a/src/JUS.SceneGatePlugin/SupportedSoftware.cs b/src/JUS.SceneGatePlugin/SupportedSoftware.cs new file mode 100644 index 0000000..07aa0fd --- /dev/null +++ b/src/JUS.SceneGatePlugin/SupportedSoftware.cs @@ -0,0 +1,25 @@ +using System.Diagnostics.CodeAnalysis; +using SceneGate.Ekona.Containers.Rom; +using Yarhl.FileSystem; + +namespace JUS.SceneGatePlugin; + +public static class SupportedSoftware +{ + public static string GameCode => "AJUJ"; + + public static bool? IsFromCompatibleSoftware(Node assetNode, [NotNullWhen(true)] out Node? root) + { + ProgramInfo? info = GetProgramInfo(assetNode); + root = assetNode; + while (root is not null && info is not null) { + root = root.Parent; + info = GetProgramInfo(root); + } + + return info is null ? null : GameCode == info.GameCode; + + static ProgramInfo? GetProgramInfo(Node? node) => + node?.Children["system"]?.Children["info"]?.Format as ProgramInfo; + } +} diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs new file mode 100644 index 0000000..b073ea2 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs @@ -0,0 +1,7 @@ +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +public class BinaryAbilityConverterMatcher(): + PathBasedMatcher("data/bin/ability_t.bin"); From bf15ec7480e4aa8de6180dda7e1fc6d80d7aedd5 Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Wed, 22 Apr 2026 13:11:13 +0200 Subject: [PATCH 4/7] feat: implement SG converter matchers by header and path --- .idea/.idea.JUSToolkit/.idea/.name | 1 - JUSToolkit.sln.DotSettings | 2 ++ build.cs | 2 +- src/Directory.Packages.props | 4 ++-- .../Graphics/BinaryDstx3ConverterMatcher.cs | 8 ++++++++ .../Graphics/BinaryDstx4ConverterMatcher.cs | 8 ++++++++ .../Graphics/BinaryKShapeConverterMatcher.cs | 9 +++++++++ .../Graphics/BinaryKomaConverterMatcher.cs | 9 +++++++++ .../HeaderBasedBinaryMatcher.cs | 16 ++++++++++++++++ src/JUS.SceneGatePlugin/PathBasedMatcher.cs | 10 +++++----- src/JUS.SceneGatePlugin/SupportedSoftware.cs | 2 +- .../Texts/BinaryAbilityConverterMatcher.cs | 4 +++- .../Texts/BinaryBgmConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryBtlCharConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryCommwinConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryDemoConverterMatcher.cs | 9 +++++++++ .../BinaryJGalaxyComplexConverterMatcher.cs | 10 ++++++++++ .../Texts/BinaryJGalaxySimpleConverterMatcher.cs | 11 +++++++++++ .../Texts/BinaryJQuizConverterMatcher.cs | 10 ++++++++++ .../Texts/BinaryKomatxtConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryLocationConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryPieceConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryPnameConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryRulemessConverterMatcher.cs | 9 +++++++++ .../Texts/BinarySimpleBinConverterMatcher.cs | 12 ++++++++++++ .../Texts/BinaryStageConverterMatcher.cs | 9 +++++++++ .../Texts/BinarySuppChrConverterMatcher.cs | 9 +++++++++ .../Texts/BinaryTutorialConverterMatcher.cs | 16 ++++++++++++++++ .../Texts/Converters/Binary2JGalaxyComplex.cs | 4 ++-- .../Texts/Converters/Binary2JGalaxySimple.cs | 4 ++-- src/JUS.Tool/Texts/Converters/Binary2JQuiz.cs | 4 ++-- 31 files changed, 228 insertions(+), 17 deletions(-) delete mode 100644 .idea/.idea.JUSToolkit/.idea/.name create mode 100644 JUSToolkit.sln.DotSettings create mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs diff --git a/.idea/.idea.JUSToolkit/.idea/.name b/.idea/.idea.JUSToolkit/.idea/.name deleted file mode 100644 index 2499244..0000000 --- a/.idea/.idea.JUSToolkit/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -JUSToolkit \ No newline at end of file diff --git a/JUSToolkit.sln.DotSettings b/JUSToolkit.sln.DotSettings new file mode 100644 index 0000000..58e4866 --- /dev/null +++ b/JUSToolkit.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/build.cs b/build.cs index f3ca44a..f31dd25 100644 --- a/build.cs +++ b/build.cs @@ -1,6 +1,6 @@ #!/usr/bin/env dotnet run #:property PublishAot=false -#:package Cake.Frosting.PleOps.Recipe@1.0.4-preview.33 +#:package Cake.Frosting.PleOps.Recipe@1.0.4-preview.37 using System.Diagnostics.CodeAnalysis; using Cake.Common.IO; diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index d9137e6..d3fb91f 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -1,7 +1,7 @@ - + @@ -18,4 +18,4 @@ - \ No newline at end of file + diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs new file mode 100644 index 0000000..e65b632 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs @@ -0,0 +1,8 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; + +namespace JUS.SceneGatePlugin.Graphics; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryDstx3ConverterMatcher() + : HeaderBasedBinaryMatcher("DSTX", 1, 3); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs new file mode 100644 index 0000000..f2301c3 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs @@ -0,0 +1,8 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; + +namespace JUS.SceneGatePlugin.Graphics; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryDstx4ConverterMatcher() + : HeaderBasedBinaryMatcher("DSTX", 1, 4); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs new file mode 100644 index 0000000..14f9f9b --- /dev/null +++ b/src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Graphics; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryKShapeConverterMatcher() + : PathBasedMatcher("data/bin/kshape.bin"); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs new file mode 100644 index 0000000..699b18f --- /dev/null +++ b/src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Graphics; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryKomaConverterMatcher() + : PathBasedMatcher("data/bin/koma.bin"); diff --git a/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs b/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs index 3008834..af70084 100644 --- a/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs +++ b/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs @@ -9,6 +9,7 @@ public abstract class HeaderBasedBinaryMatcher : IConverterMatcher { private readonly string expectedFormatId; private readonly byte? expectedVersion; + private readonly byte? expectedFlags; protected HeaderBasedBinaryMatcher(string formatId) { @@ -23,6 +24,14 @@ protected HeaderBasedBinaryMatcher(string formatId, byte version) expectedVersion = version; } + protected HeaderBasedBinaryMatcher(string formatId, byte version, byte flags) + { + ArgumentNullException.ThrowIfNull(formatId); + expectedFormatId = formatId; + expectedVersion = version; + expectedFlags = flags; + } + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) { if (input.Format is not IBinary) { @@ -43,6 +52,13 @@ public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) } } + if (expectedFlags.HasValue && context.Header.Length >= 6) { + byte flags = context.Header.Span[5]; + if (flags != expectedFlags.Value) { + return ConverterMatcherResult.Incompatible(); + } + } + level = MatchingConfidence.CouldBe; } diff --git a/src/JUS.SceneGatePlugin/PathBasedMatcher.cs b/src/JUS.SceneGatePlugin/PathBasedMatcher.cs index 1d70175..b550ec0 100644 --- a/src/JUS.SceneGatePlugin/PathBasedMatcher.cs +++ b/src/JUS.SceneGatePlugin/PathBasedMatcher.cs @@ -8,12 +8,12 @@ public abstract class PathBasedMatcher : IConverterMatcher where TFormat : IFormat where TConverter : IConverter, new() { - private readonly string assetsPath; + private readonly string[] assetsPaths; - protected PathBasedMatcher(string assetsPath) + protected PathBasedMatcher(params string[] assetsPaths) { - ArgumentException.ThrowIfNullOrEmpty(assetsPath); - this.assetsPath = assetsPath; + ArgumentNullException.ThrowIfNull(assetsPaths); + this.assetsPaths = assetsPaths; } public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) @@ -23,7 +23,7 @@ public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) } bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out Node? root); - bool isInExpectedPath = $"{root?.Path}/{assetsPath}" == input.Path; + bool isInExpectedPath = assetsPaths.Any(x => $"{root?.Path}/{x}" == input.Path); MatchingConfidence level = MatchingConfidence.Incompatible; if (compatibleSoftware == true && isInExpectedPath) { diff --git a/src/JUS.SceneGatePlugin/SupportedSoftware.cs b/src/JUS.SceneGatePlugin/SupportedSoftware.cs index 07aa0fd..dab9651 100644 --- a/src/JUS.SceneGatePlugin/SupportedSoftware.cs +++ b/src/JUS.SceneGatePlugin/SupportedSoftware.cs @@ -12,7 +12,7 @@ public static class SupportedSoftware { ProgramInfo? info = GetProgramInfo(assetNode); root = assetNode; - while (root is not null && info is not null) { + while (root is not null && info is null) { root = root.Parent; info = GetProgramInfo(root); } diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs index b073ea2..0aadf0b 100644 --- a/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs +++ b/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs @@ -1,7 +1,9 @@ -using JUS.Tool.Texts.Converters; +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; using Yarhl.IO; namespace JUS.SceneGatePlugin.Texts; +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] public class BinaryAbilityConverterMatcher(): PathBasedMatcher("data/bin/ability_t.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs new file mode 100644 index 0000000..b00c975 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryBgmConverterMatcher(): + PathBasedMatcher("data/bin/bgm.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs new file mode 100644 index 0000000..a12bb05 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryBtlCharConverterMatcher(): + PathBasedMatcher("data/bin/chr_b_t.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs new file mode 100644 index 0000000..9a9fb03 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryCommwinConverterMatcher(): + PathBasedMatcher("data/bin/commwin.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs new file mode 100644 index 0000000..b3553cc --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryDemoConverterMatcher(): + PathBasedMatcher("data/bin/demo.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs new file mode 100644 index 0000000..0579e7b --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs @@ -0,0 +1,10 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryJGalaxyComplexConverterMatcher(): + PathBasedMatcher( + "data/jgalaxy/jgalaxy.aar/jgalaxy/jgalaxy.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs new file mode 100644 index 0000000..1863066 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs @@ -0,0 +1,11 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryJGalaxySimpleConverterMatcher(): + PathBasedMatcher( + "data/jgalaxy/jgalaxy.aar/jgalaxy/battle.bin", + "data/jgalaxy/jgalaxy.aar/jgalaxy/mission.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs new file mode 100644 index 0000000..6323f3c --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs @@ -0,0 +1,10 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryJQuizConverterMatcher(): + PathBasedMatcher( + "data/jquiz/jquiz_pack.aar/jquiz/jquiz.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs new file mode 100644 index 0000000..85921b1 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryKomatxtConverterMatcher(): + PathBasedMatcher("data/bin/komatxt.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs new file mode 100644 index 0000000..e75f0b3 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryLocationConverterMatcher(): + PathBasedMatcher("data/bin/location.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs new file mode 100644 index 0000000..076911f --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryPieceConverterMatcher(): + PathBasedMatcher("data/bin/piece.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs new file mode 100644 index 0000000..93f0c86 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryPnameConverterMatcher(): + PathBasedMatcher("data/bin/pname.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs new file mode 100644 index 0000000..5e3dc81 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryRulemessConverterMatcher(): + PathBasedMatcher("data/bin/rulemess.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs new file mode 100644 index 0000000..57b9fef --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs @@ -0,0 +1,12 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinarySimpleBinConverterMatcher(): + PathBasedMatcher( + "data/bin/clearlst.bin", + "data/bin/infoname.bin", + "data/bin/title.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs new file mode 100644 index 0000000..da05b53 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryStageConverterMatcher(): + PathBasedMatcher("data/bin/stage.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs new file mode 100644 index 0000000..ae0f588 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinarySuppChrConverterMatcher(): + PathBasedMatcher("data/bin/chr_s_t.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs new file mode 100644 index 0000000..b3653b9 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public class BinaryTutorialConverterMatcher(): + PathBasedMatcher( + "data/deckmake/tutorial.bin", + "data/battle/tutorial0.bin", + "data/battle/tutorial1.bin", + "data/battle/tutorial2.bin", + "data/battle/tutorial3.bin", + "data/battle/tutorial4.bin", + "data/battle/tutorial5.bin"); diff --git a/src/JUS.Tool/Texts/Converters/Binary2JGalaxyComplex.cs b/src/JUS.Tool/Texts/Converters/Binary2JGalaxyComplex.cs index ffefa53..0c295e4 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2JGalaxyComplex.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2JGalaxyComplex.cs @@ -28,7 +28,7 @@ namespace JUS.Tool.Texts.Converters /// Converts between JGalaxyComplex format and BinaryFormat. /// public class Binary2JGalaxyComplex : - IConverter, + IConverter, IConverter { private DataReader reader = null!; @@ -39,7 +39,7 @@ public class Binary2JGalaxyComplex : /// BinaryFormat to convert. /// Text format. /// Source file does not exist. - public JGalaxyComplex Convert(BinaryFormat source) + public JGalaxyComplex Convert(IBinary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); diff --git a/src/JUS.Tool/Texts/Converters/Binary2JGalaxySimple.cs b/src/JUS.Tool/Texts/Converters/Binary2JGalaxySimple.cs index c11e154..a14fd13 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2JGalaxySimple.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2JGalaxySimple.cs @@ -27,7 +27,7 @@ namespace JUS.Tool.Texts.Converters /// Converts between JGalaxySimple format and BinaryFormat. /// public class Binary2JGalaxySimple : - IConverter, + IConverter, IConverter { private DataReader reader = null!; @@ -38,7 +38,7 @@ public class Binary2JGalaxySimple : /// BinaryFormat to convert. /// Text format. /// Source file does not exist. - public JGalaxySimple Convert(BinaryFormat source) + public JGalaxySimple Convert(IBinary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); diff --git a/src/JUS.Tool/Texts/Converters/Binary2JQuiz.cs b/src/JUS.Tool/Texts/Converters/Binary2JQuiz.cs index 5b7ba96..a7927c9 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2JQuiz.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2JQuiz.cs @@ -26,7 +26,7 @@ namespace JUS.Tool.Texts.Converters /// /// Converts between JQuiz format and BinaryFormat. /// - public class Binary2JQuiz : IConverter, IConverter + public class Binary2JQuiz : IConverter, IConverter { private DataReader reader = null!; @@ -36,7 +36,7 @@ public class Binary2JQuiz : IConverter, IConverterBinaryFormat to convert. /// Text format. /// Source file does not exist. - public JQuiz Convert(BinaryFormat source) + public JQuiz Convert(IBinary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); From 0b81171f36022c1ff9c49e3275ec6aade9ca4e34 Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Wed, 22 Apr 2026 13:42:39 +0200 Subject: [PATCH 5/7] feat: implement regex-based SG converter matchers --- .../RegexPathBasedConverterMatcher.cs | 42 +++++++++++++++++++ .../Texts/BinaryDeckConverterMatcher.cs | 8 ++++ .../BinaryInfoDeckDeckConverterMatcher.cs | 7 ++++ .../BinaryInfoDeckInfoConverterMatcher.cs | 7 ++++ .../Texts/BinaryPDeckConverterMatcher.cs | 8 ++++ src/JUS.Tool/Texts/Converters/Binary2Deck.cs | 4 +- .../Texts/Converters/Binary2InfoDeckDeck.cs | 4 +- .../Texts/Converters/Binary2InfoDeckInfo.cs | 4 +- src/JUS.Tool/Texts/Converters/Binary2PDeck.cs | 4 +- 9 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs diff --git a/src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs b/src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs new file mode 100644 index 0000000..de55399 --- /dev/null +++ b/src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs @@ -0,0 +1,42 @@ +using System.Text.RegularExpressions; +using SceneGate.UI.Formats.Discovery; +using Yarhl.FileFormat; +using Yarhl.FileSystem; + +namespace JUS.SceneGatePlugin; + +public abstract class RegexPathBasedConverterMatcher : IConverterMatcher + where TFormat : IFormat + where TConverter : IConverter, new() +{ + private readonly Regex regex; + + protected RegexPathBasedConverterMatcher(string pattern) + { + ArgumentException.ThrowIfNullOrEmpty(pattern); + regex = new Regex(pattern, RegexOptions.Compiled); + } + + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) + { + if (input.Format is not TFormat) { + return ConverterMatcherResult.Incompatible(); + } + + bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out _); + bool isInExpectedPath = regex.IsMatch(input.Path); + + MatchingConfidence level = MatchingConfidence.Incompatible; + if (compatibleSoftware == true && isInExpectedPath) { + level = MatchingConfidence.Confident; + } else if (compatibleSoftware is null && isInExpectedPath) { + level = MatchingConfidence.CouldBe; + } + + if (level is MatchingConfidence.Incompatible) { + return ConverterMatcherResult.Incompatible(); + } + + return ConverterMatcherResult.Create(level, new TConverter()); + } +} diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs new file mode 100644 index 0000000..818580d --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs @@ -0,0 +1,8 @@ +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +public class BinaryDeckConverterMatcher() + : RegexPathBasedConverterMatcher( + @"data/deck/Deck\.aar/deck/\w+/\d{3}.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs new file mode 100644 index 0000000..5557058 --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs @@ -0,0 +1,7 @@ +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +public class BinaryInfoDeckDeckConverterMatcher() + : RegexPathBasedConverterMatcher(@"data/bin/InfoDeck.aar/bin/deck/\w{2}.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs new file mode 100644 index 0000000..749d72b --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs @@ -0,0 +1,7 @@ +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +public class BinaryInfoDeckInfoConverterMatcher() + : RegexPathBasedConverterMatcher(@"data/bin/InfoDeck.aar/bin/info/(\w{2}|jump).bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs new file mode 100644 index 0000000..eb2308d --- /dev/null +++ b/src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs @@ -0,0 +1,8 @@ +using JUS.Tool.Texts.Converters; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin.Texts; + +public class BinaryPDeckConverterMatcher() + : RegexPathBasedConverterMatcher( + @"data/deck/Deck\.aar/deck/\w+/p\d{3}.bin"); diff --git a/src/JUS.Tool/Texts/Converters/Binary2Deck.cs b/src/JUS.Tool/Texts/Converters/Binary2Deck.cs index d2ca8ac..f4cfd27 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2Deck.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2Deck.cs @@ -27,7 +27,7 @@ namespace JUS.Tool.Texts.Converters /// Converts between Deck format and BinaryFormat. /// public class Binary2Deck : - IConverter, + IConverter, IConverter { /// @@ -36,7 +36,7 @@ public class Binary2Deck : /// BinaryFormat to convert. /// Text format. /// Source file does not exist. - public Deck Convert(BinaryFormat source) + public Deck Convert(IBinary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); diff --git a/src/JUS.Tool/Texts/Converters/Binary2InfoDeckDeck.cs b/src/JUS.Tool/Texts/Converters/Binary2InfoDeckDeck.cs index a115848..88b0ca4 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2InfoDeckDeck.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2InfoDeckDeck.cs @@ -27,7 +27,7 @@ namespace JUS.Tool.Texts.Converters /// Converts between InfoDeckDeck format and BinaryFormat. /// public class Binary2InfoDeckDeck : - IConverter, + IConverter, IConverter { private DataReader reader = null!; @@ -38,7 +38,7 @@ public class Binary2InfoDeckDeck : /// BinaryFormat to convert. /// Text format. /// Source file does not exist. - public InfoDeckDeck Convert(BinaryFormat source) + public InfoDeckDeck Convert(IBinary source) { ArgumentNullException.ThrowIfNull(source); diff --git a/src/JUS.Tool/Texts/Converters/Binary2InfoDeckInfo.cs b/src/JUS.Tool/Texts/Converters/Binary2InfoDeckInfo.cs index 1c2317a..24abcf1 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2InfoDeckInfo.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2InfoDeckInfo.cs @@ -27,7 +27,7 @@ namespace JUS.Tool.Texts.Converters /// Converts between InfoDeckInfo format and BinaryFormat. /// public class Binary2InfoDeckInfo : - IConverter, + IConverter, IConverter { private DataReader reader = null!; @@ -38,7 +38,7 @@ public class Binary2InfoDeckInfo : /// BinaryFormat to convert. /// Text format. /// Source file does not exist. - public InfoDeckInfo Convert(BinaryFormat source) + public InfoDeckInfo Convert(IBinary source) { ArgumentNullException.ThrowIfNull(source); diff --git a/src/JUS.Tool/Texts/Converters/Binary2PDeck.cs b/src/JUS.Tool/Texts/Converters/Binary2PDeck.cs index db0d13c..873b642 100644 --- a/src/JUS.Tool/Texts/Converters/Binary2PDeck.cs +++ b/src/JUS.Tool/Texts/Converters/Binary2PDeck.cs @@ -27,7 +27,7 @@ namespace JUS.Tool.Texts.Converters /// Converts between PDeck format and BinaryFormat. /// public class Binary2PDeck : - IConverter, + IConverter, IConverter { /// @@ -36,7 +36,7 @@ public class Binary2PDeck : /// BinaryFormat to convert. /// Text format. /// Source file does not exist. - public PDeck Convert(BinaryFormat source) + public PDeck Convert(IBinary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); From 4e1b9fc6338a8a19ee67c62e8d48953cdc074e7d Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Wed, 22 Apr 2026 18:45:28 +0200 Subject: [PATCH 6/7] ci: integrate test resources --- .github/workflows/build-and-release.yml | 12 +++++++++++- build.cs | 10 +++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 7ff1bee..0c10173 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -11,7 +11,8 @@ on: tags: [ "v*" ] env: - DOTNET_VERSIONS: 10.0.202 + TEST_RESOURCES_NAME: 'resources-0.zip' + DOTNET_VERSIONS: 10.0.203 DOTNET_INSTALL_DIR: '/tmp/dotnet/' jobs: @@ -36,6 +37,15 @@ jobs: --target=Default --target=Bundle --dotnet-configuration=Release + --resource-uri=${{ env.TEST_RESOURCES_URI }} + --resource-name=${{ env.TEST_RESOURCES_NAME }} + --resource-usr=${{ env.TEST_RESOURCES_USR }} + --resource-pwd=${{ env.TEST_RESOURCES_PWD }} + --dotnet-configuration=Release + env: + TEST_RESOURCES_URI: ${{ secrets.TEST_RESOURCES_URI }} + TEST_RESOURCES_USR: ${{ secrets.TEST_RESOURCES_USR }} + TEST_RESOURCES_PWD: ${{ secrets.TEST_RESOURCES_PWD }} - name: "Publish artifacts to CI" uses: actions/upload-artifact@v7 diff --git a/build.cs b/build.cs index f31dd25..e8d715b 100644 --- a/build.cs +++ b/build.cs @@ -1,4 +1,4 @@ -#!/usr/bin/env dotnet run +#!/usr/bin/env dotnet run #:property PublishAot=false #:package Cake.Frosting.PleOps.Recipe@1.0.4-preview.37 @@ -108,11 +108,7 @@ public override bool ShouldRun(BuildContext context) => public override void Run(BuildContext context) { - string resourcesPath = Path.GetFullPath(Path.Combine("resources", "tests")); - if (Directory.Exists(resourcesPath)) { - context.Log.Information("Test files already exists, skipping download."); - return; - } + string resourcesPath = Path.GetFullPath(Path.Combine("src", "JUS.Tests")); string resourceUri = string.Format(context.TestResourceUri!, context.TestResourceName); var downloadSettings = new DownloadFileSettings { @@ -128,6 +124,6 @@ public override void Run(BuildContext context) var compressedResources = context.DownloadFile(resourceUri, downloadSettings); context.Log.Debug("Unzipping resource"); - context.Unzip(compressedResources, resourcesPath); + context.Unzip(compressedResources, resourcesPath, true); } } From 33ecae1181e4784bedc8b76f324c8263cf728ccd Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Wed, 22 Apr 2026 22:54:12 +0200 Subject: [PATCH 7/7] refactor: simplify format definition for SG plugin --- .github/workflows/build-and-release.yml | 9 +- .../Containers/BinaryAlarConverterMatcher.cs | 12 --- .../Graphics/BinaryAlmtConverterMatcher.cs | 8 -- .../Graphics/BinaryDsigConverterMatcher.cs | 8 -- .../Graphics/BinaryDstx3ConverterMatcher.cs | 8 -- .../Graphics/BinaryDstx4ConverterMatcher.cs | 8 -- .../Graphics/BinaryKShapeConverterMatcher.cs | 9 -- .../Graphics/BinaryKomaConverterMatcher.cs | 9 -- .../HeaderBasedBinaryMatcher.cs | 76 ---------------- .../JusBinaryHeaderConverterMatcher.cs | 88 +++++++++++++++++++ .../JusPathBinaryConverterMatcher.cs | 75 ++++++++++++++++ .../JusRegexPathBinaryConverterMatcher.cs | 58 ++++++++++++ src/JUS.SceneGatePlugin/PathBasedMatcher.cs | 41 --------- .../RegexPathBasedConverterMatcher.cs | 42 --------- src/JUS.SceneGatePlugin/SupportedSoftware.cs | 11 ++- .../Texts/BinaryAbilityConverterMatcher.cs | 9 -- .../Texts/BinaryBgmConverterMatcher.cs | 9 -- .../Texts/BinaryBtlCharConverterMatcher.cs | 9 -- .../Texts/BinaryCommwinConverterMatcher.cs | 9 -- .../Texts/BinaryDeckConverterMatcher.cs | 8 -- .../Texts/BinaryDemoConverterMatcher.cs | 9 -- .../BinaryInfoDeckDeckConverterMatcher.cs | 7 -- .../BinaryInfoDeckInfoConverterMatcher.cs | 7 -- .../BinaryJGalaxyComplexConverterMatcher.cs | 10 --- .../BinaryJGalaxySimpleConverterMatcher.cs | 11 --- .../Texts/BinaryJQuizConverterMatcher.cs | 10 --- .../Texts/BinaryKomatxtConverterMatcher.cs | 9 -- .../Texts/BinaryLocationConverterMatcher.cs | 9 -- .../Texts/BinaryPDeckConverterMatcher.cs | 8 -- .../Texts/BinaryPieceConverterMatcher.cs | 9 -- .../Texts/BinaryPnameConverterMatcher.cs | 9 -- .../Texts/BinaryRulemessConverterMatcher.cs | 9 -- .../Texts/BinarySimpleBinConverterMatcher.cs | 12 --- .../Texts/BinaryStageConverterMatcher.cs | 9 -- .../Texts/BinarySuppChrConverterMatcher.cs | 9 -- .../Texts/BinaryTutorialConverterMatcher.cs | 16 ---- 36 files changed, 234 insertions(+), 425 deletions(-) delete mode 100644 src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/JusBinaryHeaderConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/JusPathBinaryConverterMatcher.cs create mode 100644 src/JUS.SceneGatePlugin/JusRegexPathBinaryConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/PathBasedMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs delete mode 100644 src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 0c10173..3dbabbf 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -31,7 +31,9 @@ jobs: with: dotnet-version: ${{ env.DOTNET_VERSIONS }} + # Full test for master builds and PR of repo owners - name: "Build, test, and bundle" + if: ${{ env.TEST_RESOURCES_URI != '' }} run: > dotnet run build.cs -- --target=Default @@ -41,12 +43,17 @@ jobs: --resource-name=${{ env.TEST_RESOURCES_NAME }} --resource-usr=${{ env.TEST_RESOURCES_USR }} --resource-pwd=${{ env.TEST_RESOURCES_PWD }} - --dotnet-configuration=Release env: TEST_RESOURCES_URI: ${{ secrets.TEST_RESOURCES_URI }} TEST_RESOURCES_USR: ${{ secrets.TEST_RESOURCES_USR }} TEST_RESOURCES_PWD: ${{ secrets.TEST_RESOURCES_PWD }} + # Tests without resources for PR of external contributors + - name: "Build, test, and bundle" + if: ${{ env.TEST_RESOURCES_URI == '' }} + run: > + dotnet run build.cs -- --target=Default --target=Bundle --dotnet-configuration=Release + - name: "Publish artifacts to CI" uses: actions/upload-artifact@v7 with: diff --git a/src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs b/src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs deleted file mode 100644 index 9a91597..0000000 --- a/src/JUS.SceneGatePlugin/Containers/BinaryAlarConverterMatcher.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Containers.Converters; - -namespace JUS.SceneGatePlugin.Containers; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryAlar2ConverterMatcher() - : HeaderBasedBinaryMatcher("ALAR", 2); - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryAlar3ConverterMatcher() - : HeaderBasedBinaryMatcher("ALAR", 3); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs deleted file mode 100644 index cd7c73f..0000000 --- a/src/JUS.SceneGatePlugin/Graphics/BinaryAlmtConverterMatcher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Graphics.Converters; - -namespace JUS.SceneGatePlugin.Graphics; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryAlmtConverterMatcher() - : HeaderBasedBinaryMatcher("ALMT"); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs deleted file mode 100644 index 43414c4..0000000 --- a/src/JUS.SceneGatePlugin/Graphics/BinaryDsigConverterMatcher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Graphics.Converters; - -namespace JUS.SceneGatePlugin.Graphics; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryDsigConverterMatcher() - : HeaderBasedBinaryMatcher("DSIG"); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs deleted file mode 100644 index e65b632..0000000 --- a/src/JUS.SceneGatePlugin/Graphics/BinaryDstx3ConverterMatcher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Graphics.Converters; - -namespace JUS.SceneGatePlugin.Graphics; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryDstx3ConverterMatcher() - : HeaderBasedBinaryMatcher("DSTX", 1, 3); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs deleted file mode 100644 index f2301c3..0000000 --- a/src/JUS.SceneGatePlugin/Graphics/BinaryDstx4ConverterMatcher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Graphics.Converters; - -namespace JUS.SceneGatePlugin.Graphics; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryDstx4ConverterMatcher() - : HeaderBasedBinaryMatcher("DSTX", 1, 4); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs deleted file mode 100644 index 14f9f9b..0000000 --- a/src/JUS.SceneGatePlugin/Graphics/BinaryKShapeConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Graphics.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Graphics; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryKShapeConverterMatcher() - : PathBasedMatcher("data/bin/kshape.bin"); diff --git a/src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs b/src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs deleted file mode 100644 index 699b18f..0000000 --- a/src/JUS.SceneGatePlugin/Graphics/BinaryKomaConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Graphics.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Graphics; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryKomaConverterMatcher() - : PathBasedMatcher("data/bin/koma.bin"); diff --git a/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs b/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs deleted file mode 100644 index af70084..0000000 --- a/src/JUS.SceneGatePlugin/HeaderBasedBinaryMatcher.cs +++ /dev/null @@ -1,76 +0,0 @@ -using SceneGate.UI.Formats.Discovery; -using Yarhl.FileSystem; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin; - -public abstract class HeaderBasedBinaryMatcher : IConverterMatcher - where T : new() -{ - private readonly string expectedFormatId; - private readonly byte? expectedVersion; - private readonly byte? expectedFlags; - - protected HeaderBasedBinaryMatcher(string formatId) - { - ArgumentNullException.ThrowIfNull(formatId); - expectedFormatId = formatId; - } - - protected HeaderBasedBinaryMatcher(string formatId, byte version) - { - ArgumentNullException.ThrowIfNull(formatId); - expectedFormatId = formatId; - expectedVersion = version; - } - - protected HeaderBasedBinaryMatcher(string formatId, byte version, byte flags) - { - ArgumentNullException.ThrowIfNull(formatId); - expectedFormatId = formatId; - expectedVersion = version; - expectedFlags = flags; - } - - public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) - { - if (input.Format is not IBinary) { - return ConverterMatcherResult.Incompatible(); - } - - MatchingConfidence level = MatchingConfidence.CannotDetermine; - if (context.Header.Length >= 4) { - string formatId = context.Header.ReadAsciiString(0, 4); - if (formatId != expectedFormatId) { - return ConverterMatcherResult.Incompatible(); - } - - if (expectedVersion.HasValue && context.Header.Length >= 5) { - byte version = context.Header.Span[4]; - if (version != expectedVersion.Value) { - return ConverterMatcherResult.Incompatible(); - } - } - - if (expectedFlags.HasValue && context.Header.Length >= 6) { - byte flags = context.Header.Span[5]; - if (flags != expectedFlags.Value) { - return ConverterMatcherResult.Incompatible(); - } - } - - level = MatchingConfidence.CouldBe; - } - - bool? fromCompatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out _); - if (fromCompatibleSoftware == false) { - return ConverterMatcherResult.Incompatible(); - } - - if (fromCompatibleSoftware == true && level >= MatchingConfidence.CouldBe) { - level = MatchingConfidence.Confident; - } - - return ConverterMatcherResult.Create(level, new T()); - } -} diff --git a/src/JUS.SceneGatePlugin/JusBinaryHeaderConverterMatcher.cs b/src/JUS.SceneGatePlugin/JusBinaryHeaderConverterMatcher.cs new file mode 100644 index 0000000..4b341b8 --- /dev/null +++ b/src/JUS.SceneGatePlugin/JusBinaryHeaderConverterMatcher.cs @@ -0,0 +1,88 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Containers.Converters; +using JUS.Tool.Graphics.Converters; +using SceneGate.UI.Formats.Discovery; +using Yarhl.FileSystem; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public sealed class JusBinaryHeaderConverterMatcher : IConverterMatcher +{ + private static readonly HeaderFormat[] SupportedFormats = [ + // Containers + HeaderFormat.Create("ALAR", 2, null), + HeaderFormat.Create("ALAR", 3, null), + // Graphics + HeaderFormat.Create("ALMT", null, null), + HeaderFormat.Create("DSIG", null, null), + HeaderFormat.Create("DSTX", 1, 3), + HeaderFormat.Create("DSTX", 1, 4), + ]; + + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) + { + if (input.Format is not IBinary) { + return ConverterMatcherResult.Incompatible(); + } + + // Validate the header data + HeaderFormat? compatibleFormat = SupportedFormats + .FirstOrDefault(f => MatchFormat(context, f)); + if (compatibleFormat is null) { + return ConverterMatcherResult.Incompatible(); + } + + // header data match... validate this is a supported game + bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out _); + if (compatibleSoftware == false) { + return ConverterMatcherResult.Incompatible(); + } + + // "should be" if header match, but we can't verify the game code + MatchingConfidence level = compatibleSoftware == true ? MatchingConfidence.Confident : MatchingConfidence.ShouldBe; + object converter = compatibleFormat.ConverterFactory(); + return new ConverterMatcherResult(level, compatibleFormat.ConverterType, converter); + } + + private static bool MatchFormat(ConverterMatcherContext context, HeaderFormat format) + { + int requiredHeaderData = format switch { + { Flags: not null } => 6, + { Version: not null } => 5, + _ => 4 + }; + if (context.Header.Length < requiredHeaderData) { + return false; + } + + if (context.Header.ReadAsciiString(0, 4) != format.Id) { + return false; + } + + if (format.Version.HasValue && context.Header.Span[4] != format.Version.Value) { + return false; + } + + if (format.Flags.HasValue && context.Header.Span[5] != format.Flags.Value) { + return false; + } + + return true; + } + + private sealed record HeaderFormat( + string Id, + byte? Version, + byte? Flags, + Type ConverterType, + Func ConverterFactory) + { + public static HeaderFormat Create(string id, byte? version, byte? flags) + where T : class, new() + { + return new HeaderFormat(id, version, flags, typeof(T), () => new T()); + } + } +} diff --git a/src/JUS.SceneGatePlugin/JusPathBinaryConverterMatcher.cs b/src/JUS.SceneGatePlugin/JusPathBinaryConverterMatcher.cs new file mode 100644 index 0000000..ab92445 --- /dev/null +++ b/src/JUS.SceneGatePlugin/JusPathBinaryConverterMatcher.cs @@ -0,0 +1,75 @@ +using System.Diagnostics.CodeAnalysis; +using JUS.Tool.Graphics.Converters; +using JUS.Tool.Texts.Converters; +using SceneGate.UI.Formats.Discovery; +using Yarhl.FileSystem; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public sealed class JusPathBinaryConverterMatcher : IConverterMatcher +{ + private static readonly FormatLocation[] SupportedFiles = [ + // Graphics + FormatLocation.Create("data/bin/koma.bin"), + FormatLocation.Create("data/bin/kshape.bin"), + // Texts + FormatLocation.Create("data/bin/ability_t.bin"), + FormatLocation.Create("data/bin/bgm.bin"), + FormatLocation.Create("data/bin/chr_b_t.bin"), + FormatLocation.Create("data/bin/chr_s_t.bin"), + FormatLocation.Create("data/bin/clearlst.bin"), + FormatLocation.Create("data/bin/commwin.bin"), + FormatLocation.Create("data/bin/demo.bin"), + FormatLocation.Create("data/bin/infoname.bin"), + FormatLocation.Create("data/bin/komatxt.bin"), + FormatLocation.Create("data/bin/location.bin"), + FormatLocation.Create("data/bin/piece.bin"), + FormatLocation.Create("data/bin/pname.bin"), + FormatLocation.Create("data/bin/rulemess.bin"), + FormatLocation.Create("data/bin/stage.bin"), + FormatLocation.Create("data/bin/title.bin"), + FormatLocation.Create("data/deckmake/tutorial.bin"), + FormatLocation.Create("data/jgalaxy/jgalaxy.aar/jgalaxy/jgalaxy.bin"), + FormatLocation.Create("data/jgalaxy/jgalaxy.aar/jgalaxy/battle.bin"), + FormatLocation.Create("data/jgalaxy/jgalaxy.aar/jgalaxy/mission.bin"), + FormatLocation.Create("data/jquiz/jquiz_pack.aar/jquiz/jquiz.bin"), + ]; + + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) + { + if (input.Format is not IBinary) { + return ConverterMatcherResult.Incompatible(); + } + + // Check the game code and get the root node. + bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out Node root); + if (compatibleSoftware == false) { + return ConverterMatcherResult.Incompatible(); + } + + // Build the relative path (once) and compare against support formats + // If we can't determine the nitrorom root, root will be the first node. + string relativePath = input.Path.Substring(root.Path.Length + 1); + FormatLocation? compatibleFormat = SupportedFiles + .FirstOrDefault(x => x.Path == relativePath); + if (compatibleFormat is null) { + return ConverterMatcherResult.Incompatible(); + } + + // "should be" if header match, but we can't verify the game code + MatchingConfidence level = compatibleSoftware == true ? MatchingConfidence.Confident : MatchingConfidence.ShouldBe; + object converter = compatibleFormat.ConverterFactory(); + return new ConverterMatcherResult(level, compatibleFormat.ConverterType, converter); + } + + private sealed record FormatLocation(string Path, Type ConverterType, Func ConverterFactory) + { + public static FormatLocation Create(string path) + where T : class, new() + { + return new FormatLocation(path, typeof(T), () => new T()); + } + } +} diff --git a/src/JUS.SceneGatePlugin/JusRegexPathBinaryConverterMatcher.cs b/src/JUS.SceneGatePlugin/JusRegexPathBinaryConverterMatcher.cs new file mode 100644 index 0000000..df191ec --- /dev/null +++ b/src/JUS.SceneGatePlugin/JusRegexPathBinaryConverterMatcher.cs @@ -0,0 +1,58 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; +using JUS.Tool.Texts.Converters; +using SceneGate.UI.Formats.Discovery; +using Yarhl.FileSystem; +using Yarhl.IO; + +namespace JUS.SceneGatePlugin; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] +public sealed class JusRegexPathBinaryConverterMatcher : IConverterMatcher +{ + private static readonly FormatLocation[] SupportedFiles = [ + // Texts + FormatLocation.Create(@"data/battle/tutorial\d.bin"), + FormatLocation.Create(@"data/bin/InfoDeck.aar/bin/deck/\w{2}.bin"), + FormatLocation.Create(@"data/bin/InfoDeck.aar/bin/info/(\w{2}|jump).bin"), + FormatLocation.Create(@"data/deck/Deck\.aar/deck/\w+/\d{3}.bin"), + FormatLocation.Create(@"data/deck/Deck\.aar/deck/\w+/p\d{3}.bin"), + ]; + + public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) + { + if (input.Format is not IBinary) { + return ConverterMatcherResult.Incompatible(); + } + + // Check the game code and get the root node. + bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out Node root); + if (compatibleSoftware == false) { + return ConverterMatcherResult.Incompatible(); + } + + // Build the relative path (once) and match against support formats + // If we can't determine the nitrorom root, root will be the first node. + string relativePath = input.Path.Substring(root.Path.Length + 1); + FormatLocation? compatibleFormat = SupportedFiles + .FirstOrDefault(x => x.Regex.IsMatch(relativePath)); + if (compatibleFormat is null) { + return ConverterMatcherResult.Incompatible(); + } + + // "should be" if header match, but we can't verify the game code + MatchingConfidence level = compatibleSoftware == true ? MatchingConfidence.Confident : MatchingConfidence.ShouldBe; + object converter = compatibleFormat.ConverterFactory(); + return new ConverterMatcherResult(level, compatibleFormat.ConverterType, converter); + } + + private sealed record FormatLocation(Regex Regex, Type ConverterType, Func ConverterFactory) + { + public static FormatLocation Create(string pattern) + where T : class, new() + { + Regex regex = new(pattern, RegexOptions.Compiled); + return new FormatLocation(regex, typeof(T), () => new T()); + } + } +} diff --git a/src/JUS.SceneGatePlugin/PathBasedMatcher.cs b/src/JUS.SceneGatePlugin/PathBasedMatcher.cs deleted file mode 100644 index b550ec0..0000000 --- a/src/JUS.SceneGatePlugin/PathBasedMatcher.cs +++ /dev/null @@ -1,41 +0,0 @@ -using SceneGate.UI.Formats.Discovery; -using Yarhl.FileFormat; -using Yarhl.FileSystem; - -namespace JUS.SceneGatePlugin; - -public abstract class PathBasedMatcher : IConverterMatcher - where TFormat : IFormat - where TConverter : IConverter, new() -{ - private readonly string[] assetsPaths; - - protected PathBasedMatcher(params string[] assetsPaths) - { - ArgumentNullException.ThrowIfNull(assetsPaths); - this.assetsPaths = assetsPaths; - } - - public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) - { - if (input.Format is not TFormat) { - return ConverterMatcherResult.Incompatible(); - } - - bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out Node? root); - bool isInExpectedPath = assetsPaths.Any(x => $"{root?.Path}/{x}" == input.Path); - - MatchingConfidence level = MatchingConfidence.Incompatible; - if (compatibleSoftware == true && isInExpectedPath) { - level = MatchingConfidence.Confident; - } else if (compatibleSoftware is null && isInExpectedPath) { - level = MatchingConfidence.CouldBe; - } - - if (level is MatchingConfidence.Incompatible) { - return ConverterMatcherResult.Incompatible(); - } - - return ConverterMatcherResult.Create(level, new TConverter()); - } -} diff --git a/src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs b/src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs deleted file mode 100644 index de55399..0000000 --- a/src/JUS.SceneGatePlugin/RegexPathBasedConverterMatcher.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Text.RegularExpressions; -using SceneGate.UI.Formats.Discovery; -using Yarhl.FileFormat; -using Yarhl.FileSystem; - -namespace JUS.SceneGatePlugin; - -public abstract class RegexPathBasedConverterMatcher : IConverterMatcher - where TFormat : IFormat - where TConverter : IConverter, new() -{ - private readonly Regex regex; - - protected RegexPathBasedConverterMatcher(string pattern) - { - ArgumentException.ThrowIfNullOrEmpty(pattern); - regex = new Regex(pattern, RegexOptions.Compiled); - } - - public ConverterMatcherResult Match(Node input, ConverterMatcherContext context) - { - if (input.Format is not TFormat) { - return ConverterMatcherResult.Incompatible(); - } - - bool? compatibleSoftware = SupportedSoftware.IsFromCompatibleSoftware(input, out _); - bool isInExpectedPath = regex.IsMatch(input.Path); - - MatchingConfidence level = MatchingConfidence.Incompatible; - if (compatibleSoftware == true && isInExpectedPath) { - level = MatchingConfidence.Confident; - } else if (compatibleSoftware is null && isInExpectedPath) { - level = MatchingConfidence.CouldBe; - } - - if (level is MatchingConfidence.Incompatible) { - return ConverterMatcherResult.Incompatible(); - } - - return ConverterMatcherResult.Create(level, new TConverter()); - } -} diff --git a/src/JUS.SceneGatePlugin/SupportedSoftware.cs b/src/JUS.SceneGatePlugin/SupportedSoftware.cs index dab9651..c2ae2d9 100644 --- a/src/JUS.SceneGatePlugin/SupportedSoftware.cs +++ b/src/JUS.SceneGatePlugin/SupportedSoftware.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using SceneGate.Ekona.Containers.Rom; +using SceneGate.Ekona.Containers.Rom; using Yarhl.FileSystem; namespace JUS.SceneGatePlugin; @@ -8,18 +7,18 @@ public static class SupportedSoftware { public static string GameCode => "AJUJ"; - public static bool? IsFromCompatibleSoftware(Node assetNode, [NotNullWhen(true)] out Node? root) + public static bool? IsFromCompatibleSoftware(Node assetNode, out Node root) { ProgramInfo? info = GetProgramInfo(assetNode); root = assetNode; - while (root is not null && info is null) { + while (root.Parent is not null && info is null) { root = root.Parent; info = GetProgramInfo(root); } return info is null ? null : GameCode == info.GameCode; - static ProgramInfo? GetProgramInfo(Node? node) => - node?.Children["system"]?.Children["info"]?.Format as ProgramInfo; + static ProgramInfo? GetProgramInfo(Node node) => + node.Children["system"]?.Children["info"]?.Format as ProgramInfo; } } diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs deleted file mode 100644 index 0aadf0b..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryAbilityConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryAbilityConverterMatcher(): - PathBasedMatcher("data/bin/ability_t.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs deleted file mode 100644 index b00c975..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryBgmConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryBgmConverterMatcher(): - PathBasedMatcher("data/bin/bgm.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs deleted file mode 100644 index a12bb05..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryBtlCharConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryBtlCharConverterMatcher(): - PathBasedMatcher("data/bin/chr_b_t.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs deleted file mode 100644 index 9a9fb03..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryCommwinConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryCommwinConverterMatcher(): - PathBasedMatcher("data/bin/commwin.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs deleted file mode 100644 index 818580d..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryDeckConverterMatcher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -public class BinaryDeckConverterMatcher() - : RegexPathBasedConverterMatcher( - @"data/deck/Deck\.aar/deck/\w+/\d{3}.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs deleted file mode 100644 index b3553cc..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryDemoConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryDemoConverterMatcher(): - PathBasedMatcher("data/bin/demo.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs deleted file mode 100644 index 5557058..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckDeckConverterMatcher.cs +++ /dev/null @@ -1,7 +0,0 @@ -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -public class BinaryInfoDeckDeckConverterMatcher() - : RegexPathBasedConverterMatcher(@"data/bin/InfoDeck.aar/bin/deck/\w{2}.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs deleted file mode 100644 index 749d72b..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryInfoDeckInfoConverterMatcher.cs +++ /dev/null @@ -1,7 +0,0 @@ -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -public class BinaryInfoDeckInfoConverterMatcher() - : RegexPathBasedConverterMatcher(@"data/bin/InfoDeck.aar/bin/info/(\w{2}|jump).bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs deleted file mode 100644 index 0579e7b..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxyComplexConverterMatcher.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryJGalaxyComplexConverterMatcher(): - PathBasedMatcher( - "data/jgalaxy/jgalaxy.aar/jgalaxy/jgalaxy.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs deleted file mode 100644 index 1863066..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryJGalaxySimpleConverterMatcher.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryJGalaxySimpleConverterMatcher(): - PathBasedMatcher( - "data/jgalaxy/jgalaxy.aar/jgalaxy/battle.bin", - "data/jgalaxy/jgalaxy.aar/jgalaxy/mission.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs deleted file mode 100644 index 6323f3c..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryJQuizConverterMatcher.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryJQuizConverterMatcher(): - PathBasedMatcher( - "data/jquiz/jquiz_pack.aar/jquiz/jquiz.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs deleted file mode 100644 index 85921b1..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryKomatxtConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryKomatxtConverterMatcher(): - PathBasedMatcher("data/bin/komatxt.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs deleted file mode 100644 index e75f0b3..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryLocationConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryLocationConverterMatcher(): - PathBasedMatcher("data/bin/location.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs deleted file mode 100644 index eb2308d..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryPDeckConverterMatcher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -public class BinaryPDeckConverterMatcher() - : RegexPathBasedConverterMatcher( - @"data/deck/Deck\.aar/deck/\w+/p\d{3}.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs deleted file mode 100644 index 076911f..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryPieceConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryPieceConverterMatcher(): - PathBasedMatcher("data/bin/piece.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs deleted file mode 100644 index 93f0c86..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryPnameConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryPnameConverterMatcher(): - PathBasedMatcher("data/bin/pname.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs deleted file mode 100644 index 5e3dc81..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryRulemessConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryRulemessConverterMatcher(): - PathBasedMatcher("data/bin/rulemess.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs deleted file mode 100644 index 57b9fef..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinarySimpleBinConverterMatcher.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinarySimpleBinConverterMatcher(): - PathBasedMatcher( - "data/bin/clearlst.bin", - "data/bin/infoname.bin", - "data/bin/title.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs deleted file mode 100644 index da05b53..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryStageConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryStageConverterMatcher(): - PathBasedMatcher("data/bin/stage.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs deleted file mode 100644 index ae0f588..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinarySuppChrConverterMatcher.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinarySuppChrConverterMatcher(): - PathBasedMatcher("data/bin/chr_s_t.bin"); diff --git a/src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs b/src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs deleted file mode 100644 index b3653b9..0000000 --- a/src/JUS.SceneGatePlugin/Texts/BinaryTutorialConverterMatcher.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using JUS.Tool.Texts.Converters; -using Yarhl.IO; - -namespace JUS.SceneGatePlugin.Texts; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] -public class BinaryTutorialConverterMatcher(): - PathBasedMatcher( - "data/deckmake/tutorial.bin", - "data/battle/tutorial0.bin", - "data/battle/tutorial1.bin", - "data/battle/tutorial2.bin", - "data/battle/tutorial3.bin", - "data/battle/tutorial4.bin", - "data/battle/tutorial5.bin");