diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index be274ae..2d7d7f3 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -48,7 +48,7 @@ jobs:
# use publish for .NET Core
run: dotnet publish ${{ env.TOOL_PROJ_PATH }} --configuration Release -f net10.0 --output ./releases/net10.0 /p:DebugType=None /p:DebugSymbols=false
- name: Upload a Build Artifact
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
name: Binary Releases
path: ./releases
@@ -68,7 +68,7 @@ jobs:
with:
fetch-depth: 0
submodules: recursive
- - uses: actions/download-artifact@v7
+ - uses: actions/download-artifact@v8
with:
name: Binary Releases
path: ./releases
@@ -103,7 +103,7 @@ jobs:
# Change into the artifacts directory to avoid including the directory itself in the zip archive
working-directory: ./releases/net10.0
run: zip -r ../ModVerify-Net10.zip .
- - uses: dotnet/nbgv@v0.4.2
+ - uses: dotnet/nbgv@v0.5.1
id: nbgv
- name: Create GitHub release
# Create a GitHub release on push to main only
diff --git a/Directory.Build.props b/Directory.Build.props
index 5110cdb..3e2f119 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -33,20 +33,17 @@
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
+
all
3.9.50
-
+
\ No newline at end of file
diff --git a/aet.png b/aet.png
new file mode 100644
index 0000000..ac47943
Binary files /dev/null and b/aet.png differ
diff --git a/modules/ModdingToolBase b/modules/ModdingToolBase
index 5103bad..da072f4 160000
--- a/modules/ModdingToolBase
+++ b/modules/ModdingToolBase
@@ -1 +1 @@
-Subproject commit 5103bad6f09ba88061ccbc36ee285ee9300744cc
+Subproject commit da072f43e6b85aab35b43d11f6b36eab61bdcfa6
diff --git a/src/ModVerify.CliApp/App/CreateBaselineAction.cs b/src/ModVerify.CliApp/App/CreateBaselineAction.cs
index b0eb880..b776e09 100644
--- a/src/ModVerify.CliApp/App/CreateBaselineAction.cs
+++ b/src/ModVerify.CliApp/App/CreateBaselineAction.cs
@@ -2,10 +2,10 @@
using AET.ModVerify.App.Settings;
using AET.ModVerify.App.Utilities;
using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
-using System.Collections.Generic;
using System.IO.Abstractions;
using System.Threading.Tasks;
@@ -26,16 +26,14 @@ protected override void PrintAction(VerificationTarget target)
Console.WriteLine();
}
- protected override async Task ProcessVerifyFindings(
- VerificationTarget verificationTarget,
- IReadOnlyCollection allErrors)
+ protected override async Task ProcessResult(VerificationResult result)
{
var baselineFactory = ServiceProvider.GetRequiredService();
- var baseline = baselineFactory.CreateBaseline(verificationTarget, Settings, allErrors);
+ var baseline = baselineFactory.CreateBaseline(result.Target, Settings, result.Errors);
var fullPath = _fileSystem.Path.GetFullPath(Settings.NewBaselinePath);
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId,
- "Writing Baseline to '{FullPath}' with {Number} findings", fullPath, allErrors.Count);
+ "Writing Baseline to '{FullPath}' with {Number} findings", fullPath, result.Errors.Count);
await baselineFactory.WriteBaselineAsync(baseline, Settings.NewBaselinePath);
@@ -43,7 +41,7 @@ protected override async Task ProcessVerifyFindings(
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.DarkGreen;
- Console.WriteLine($"Baseline for {verificationTarget.Name} created.");
+ Console.WriteLine($"Baseline for {result.Target.Name} created.");
Console.ResetColor();
return ModVerifyConstants.Success;
diff --git a/src/ModVerify.CliApp/App/ModVerifyApplicationAction.cs b/src/ModVerify.CliApp/App/ModVerifyApplicationAction.cs
index b3f12f7..113e633 100644
--- a/src/ModVerify.CliApp/App/ModVerifyApplicationAction.cs
+++ b/src/ModVerify.CliApp/App/ModVerifyApplicationAction.cs
@@ -1,13 +1,13 @@
using System;
-using System.Collections.Generic;
using System.IO.Abstractions;
using System.Threading.Tasks;
using AET.ModVerify.App.GameFinder;
using AET.ModVerify.App.Reporting;
using AET.ModVerify.App.Settings;
using AET.ModVerify.App.TargetSelectors;
-using AET.ModVerify.Pipeline;
using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
+using AET.ModVerify.Reporting.Suppressions;
using AnakinRaW.ApplicationBase;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -71,43 +71,55 @@ public async Task ExecuteAsync()
PrintAction(verificationTarget);
- var allErrors = await VerifyTargetAsync(verificationTarget)
+ var verificationResult = await VerifyTargetAsync(verificationTarget)
.ConfigureAwait(false);
- return await ProcessVerifyFindings(verificationTarget, allErrors);
+ return await ProcessResult(verificationResult);
}
- protected abstract Task ProcessVerifyFindings(
- VerificationTarget verificationTarget,
- IReadOnlyCollection allErrors);
+ protected abstract Task ProcessResult(VerificationResult result);
protected abstract VerificationBaseline GetBaseline(VerificationTarget verificationTarget);
- private async Task> VerifyTargetAsync(VerificationTarget verificationTarget)
+ private async Task VerifyTargetAsync(VerificationTarget verificationTarget)
{
var progressReporter = new VerifyConsoleProgressReporter(verificationTarget.Name, Settings.ReportSettings);
var baseline = GetBaseline(verificationTarget);
var suppressions = GetSuppressions();
- using var verifyPipeline = new GameVerifyPipeline(
- verificationTarget,
- Settings.VerifyPipelineSettings,
- progressReporter,
- new EngineInitializeProgressReporter(verificationTarget.Engine),
- baseline,
- suppressions,
- ServiceProvider);
-
try
{
+ var verifierService = ServiceProvider.GetRequiredService();
+
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId, "Verifying '{Target}'...", verificationTarget.Name);
- await verifyPipeline.RunAsync().ConfigureAwait(false);
+
+ var verificationResult = await verifierService.VerifyAsync(
+ verificationTarget,
+ Settings.VerifierServiceSettings,
+ baseline,
+ suppressions,
+ progressReporter,
+ new EngineInitializeProgressReporter(verificationTarget.Engine));
+
progressReporter.Report(string.Empty, 1.0);
- }
- catch (OperationCanceledException)
- {
- Logger?.LogWarning(ModVerifyConstants.ConsoleEventId, "Verification stopped due to enabled failFast setting.");
+
+ switch (verificationResult.Status)
+ {
+ case VerificationCompletionStatus.CompletedFailFast:
+ Logger?.LogWarning(ModVerifyConstants.ConsoleEventId, "Verification stopped due to enabled failFast setting.");
+ break;
+ case VerificationCompletionStatus.Cancelled:
+ Logger?.LogWarning(ModVerifyConstants.ConsoleEventId, "Verification was cancelled.");
+ break;
+ case VerificationCompletionStatus.Completed:
+ default:
+ Logger?.LogInformation(ModVerifyConstants.ConsoleEventId, "Verification completed successfully.");
+ break;
+ }
+
+ return verificationResult;
+
}
catch (Exception e)
{
@@ -119,9 +131,6 @@ private async Task> VerifyTargetAsync(Ver
{
progressReporter.Dispose();
}
-
- Logger?.LogInformation(ModVerifyConstants.ConsoleEventId, "Finished verification");
- return verifyPipeline.FilteredErrors;
}
private SuppressionList GetSuppressions()
diff --git a/src/ModVerify.CliApp/App/VerifyAction.cs b/src/ModVerify.CliApp/App/VerifyAction.cs
index 0cfea0e..e17d7bc 100644
--- a/src/ModVerify.CliApp/App/VerifyAction.cs
+++ b/src/ModVerify.CliApp/App/VerifyAction.cs
@@ -1,12 +1,14 @@
using AET.ModVerify.App.Reporting;
using AET.ModVerify.App.Settings;
+using AET.ModVerify.App.Utilities;
using AET.ModVerify.Reporting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using AET.ModVerify.App.Utilities;
+using AET.ModVerify.Reporting.Reporters;
+using AET.ModVerify.Reporting.Baseline;
namespace AET.ModVerify.App;
@@ -23,20 +25,27 @@ protected override void PrintAction(VerificationTarget target)
Console.WriteLine();
}
- protected override async Task ProcessVerifyFindings(
- VerificationTarget verificationTarget,
- IReadOnlyCollection allErrors)
+ protected override async Task ProcessResult(VerificationResult result)
{
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId, "Reporting Errors...");
- var reportBroker = new VerificationReportBroker(ServiceProvider);
- await reportBroker.ReportAsync(allErrors);
+ var reportBroker = new VerificationReportBroker(CreateReporters(), ServiceProvider);
+
+ result = result with
+ {
+ Target = result.Target with
+ {
+ Location = result.Target.Location.MaskUsername()
+ }
+ };
+
+ await reportBroker.ReportAsync(result);
if (Settings.AppFailsOnMinimumSeverity.HasValue &&
- allErrors.Any(x => x.Severity >= Settings.AppFailsOnMinimumSeverity))
+ result.Errors.Any(x => x.Severity >= Settings.AppFailsOnMinimumSeverity))
{
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId,
"The verification of {Target} completed with findings of the specified failure severity {Severity}",
- verificationTarget.Name, Settings.AppFailsOnMinimumSeverity);
+ result.Target.Name, Settings.AppFailsOnMinimumSeverity);
return ModVerifyConstants.CompletedWithFindings;
}
@@ -57,4 +66,35 @@ protected override VerificationBaseline GetBaseline(VerificationTarget verificat
}
return baseline;
}
+
+ private IReadOnlyCollection CreateReporters()
+ {
+ var reporters = new List();
+
+ reporters.Add(IVerificationReporter.CreateConsole(new ConsoleReporterSettings
+ {
+ Verbose = Settings.ReportSettings.Verbose,
+ MinimumReportSeverity = Settings.VerifierServiceSettings.FailFastSettings.IsFailFast
+ ? VerificationSeverity.Information
+ : VerificationSeverity.Error
+ }, ServiceProvider));
+
+ var outputDirectory = Settings.ReportDirectory;
+ reporters.Add(IVerificationReporter.CreateJson(new JsonReporterSettings
+ {
+ OutputDirectory = outputDirectory,
+ MinimumReportSeverity = Settings.ReportSettings.MinimumReportSeverity,
+ AggregateResults = true,
+ Verbose = Settings.ReportSettings.Verbose
+ }, ServiceProvider));
+
+ reporters.Add(IVerificationReporter.CreateText(new TextFileReporterSettings
+ {
+ Verbose = Settings.ReportSettings.Verbose,
+ OutputDirectory = outputDirectory!,
+ MinimumReportSeverity = Settings.ReportSettings.MinimumReportSeverity
+ }, ServiceProvider));
+
+ return reporters;
+ }
}
\ No newline at end of file
diff --git a/src/ModVerify.CliApp/ModVerify.CliApp.csproj b/src/ModVerify.CliApp/ModVerify.CliApp.csproj
index ec2fd46..f7b7ff8 100644
--- a/src/ModVerify.CliApp/ModVerify.CliApp.csproj
+++ b/src/ModVerify.CliApp/ModVerify.CliApp.csproj
@@ -5,14 +5,14 @@
Exe
AET.ModVerify.App
ModVerify
- $(RepoRootPath)aet.ico
+ Resources/aet.ico
AlamoEngineTools.ModVerify.CliApp
ModVerify Console Application
AET.ModVerify
- Console application that analyzes game modifications for Empire at War / Forces of Corruption for common errors.
+ An application that analyzes game modifications for Empire at War / Forces of Corruption for common errors.
alamo,petroglyph,glyphx
@@ -25,27 +25,23 @@
true
-
-
-
-
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
@@ -66,15 +62,15 @@
-
+
compile
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
compile
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
@@ -86,10 +82,6 @@
-
-
-
-
diff --git a/src/ModVerify.CliApp/Program.cs b/src/ModVerify.CliApp/Program.cs
index 2d23b3b..e5316f4 100644
--- a/src/ModVerify.CliApp/Program.cs
+++ b/src/ModVerify.CliApp/Program.cs
@@ -2,11 +2,6 @@
using AET.ModVerify.App.Settings.CommandLine;
using AET.ModVerify.App.Updates;
using AET.ModVerify.App.Utilities;
-using AET.ModVerify.Reporting;
-using AET.ModVerify.Reporting.Reporters;
-using AET.ModVerify.Reporting.Reporters.JSON;
-using AET.ModVerify.Reporting.Reporters.Text;
-using AET.ModVerify.Reporting.Settings;
using AET.SteamAbstraction;
using AnakinRaW.ApplicationBase;
using AnakinRaW.ApplicationBase.Environment;
@@ -20,7 +15,6 @@
using Microsoft.Extensions.Logging;
using PG.Commons;
using PG.StarWarsGame.Engine;
-using PG.StarWarsGame.Engine.Xml.Parsers;
using PG.StarWarsGame.Files.ALO;
using PG.StarWarsGame.Files.MEG;
using PG.StarWarsGame.Files.MTD;
@@ -36,11 +30,11 @@
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO.Abstractions;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using AET.ModVerify.App.Reporting;
+using PG.StarWarsGame.Engine.Xml;
using Testably.Abstractions;
using ILogger = Serilog.ILogger;
@@ -57,8 +51,8 @@ private static Task Main(string[] args)
internal class Program : SelfUpdateableAppLifecycle
{
- private static readonly string EngineParserNamespace = typeof(XmlObjectParser<>).Namespace!;
- private static readonly string ParserNamespace = typeof(PetroglyphXmlFileParser<>).Namespace!;
+ private static readonly string EngineParserNamespace = typeof(PetroglyphStarWarsGameXmlParser).Namespace!;
+ private static readonly string ParserNamespace = typeof(XmlFileParser<>).Namespace!;
private static readonly string ModVerifyRootNameSpace = typeof(Program).Namespace!;
private static readonly CompiledExpression PrintToConsoleExpression = SerilogExpression.Compile($"EventId.Id = {ModVerifyConstants.ConsoleEventIdValue}");
@@ -157,11 +151,10 @@ protected override void CreateAppServices(IServiceCollection services, IReadOnly
PetroglyphCommons.ContributeServices(services);
PetroglyphEngineServiceContribution.ContributeServices(services);
+ services.AddModVerify();
services.RegisterVerifierCache();
services.AddSingleton(sp => new BaselineFactory(sp));
-
- SetupVerifyReporting(services);
if (_offlineMode)
{
@@ -200,37 +193,6 @@ protected override async Task RunAppAsync(string[] args, IServiceProvider a
return await new ModVerifyApplication(_modVerifyAppSettings, appServiceProvider).RunAsync().ConfigureAwait(false);
}
- private void SetupVerifyReporting(IServiceCollection serviceCollection)
- {
- Debug.Assert(_modVerifyAppSettings is not null);
-
- var verifySettings = _modVerifyAppSettings as AppVerifySettings;
-
- // Console should be in minimal summary mode if we are in a different mode than verify.
- serviceCollection.RegisterConsoleReporter(new ReporterSettings
- {
- MinimumReportSeverity = verifySettings?.VerifyPipelineSettings.FailFastSettings.IsFailFast is true
- ? VerificationSeverity.Information
- : VerificationSeverity.Error
- }, summaryOnly: verifySettings is null);
-
- if (verifySettings == null)
- return;
-
- var outputDirectory = verifySettings.ReportDirectory;
- serviceCollection.RegisterJsonReporter(new JsonReporterSettings
- {
- OutputDirectory = outputDirectory!,
- MinimumReportSeverity = _modVerifyAppSettings.ReportSettings.MinimumReportSeverity
- });
-
- serviceCollection.RegisterTextFileReporter(new TextFileReporterSettings
- {
- OutputDirectory = outputDirectory!,
- MinimumReportSeverity = _modVerifyAppSettings.ReportSettings.MinimumReportSeverity
- });
- }
-
private void ConfigureLogging(ILoggingBuilder loggingBuilder)
{
loggingBuilder.ClearProviders();
diff --git a/src/ModVerify.CliApp/Properties/launchSettings.json b/src/ModVerify.CliApp/Properties/launchSettings.json
index 299ce46..46fa0fc 100644
--- a/src/ModVerify.CliApp/Properties/launchSettings.json
+++ b/src/ModVerify.CliApp/Properties/launchSettings.json
@@ -2,15 +2,15 @@
"profiles": {
"Verify": {
"commandName": "Project",
- "commandLineArgs": ""
+ "commandLineArgs": "verify --offline"
},
"Verify (Interactive)": {
"commandName": "Project",
- "commandLineArgs": "verify -o verifyResults --offline --minFailSeverity Information"
+ "commandLineArgs": "verify -o verifyResults --offline --minFailSeverity Information --searchBaseline"
},
"Verify (Automatic Target Selection)": {
"commandName": "Project",
- "commandLineArgs": "verify -o verifyResults --path \"C:\\Program Files (x86)\\Steam\\steamapps\\common\\Star Wars Empire at War\\corruption\""
+ "commandLineArgs": "verify --offline -o verifyResults --path \"C:/Program Files (x86)/Steam/steamapps/common/Star Wars Empire at War/corruption/Mods/Test\""
},
"Create Baseline Interactive": {
"commandName": "Project",
diff --git a/src/ModVerify.CliApp/Reporting/BaselineFactory.cs b/src/ModVerify.CliApp/Reporting/BaselineFactory.cs
index a83cea9..b621343 100644
--- a/src/ModVerify.CliApp/Reporting/BaselineFactory.cs
+++ b/src/ModVerify.CliApp/Reporting/BaselineFactory.cs
@@ -7,10 +7,9 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Abstractions;
-using System.Linq;
using System.Threading.Tasks;
-using PG.StarWarsGame.Engine;
using AET.ModVerify.App.Utilities;
+using AET.ModVerify.Reporting.Baseline;
namespace AET.ModVerify.App.Reporting;
@@ -89,21 +88,13 @@ public VerificationBaseline CreateBaseline(
Engine = target.Engine,
Name = target.Name,
Version = target.Version,
- Location = settings.WriteLocations ? MaskUsername(target.Location) : null,
+ Location = settings.WriteLocations ? target.Location.MaskUsername() : null,
IsGame = target.IsGame,
};
return new VerificationBaseline(settings.ReportSettings.MinimumReportSeverity, errors, baselineTarget);
}
- private static GameLocations MaskUsername(GameLocations targetLocation)
- {
- return new GameLocations(
- targetLocation.ModPaths.Select(PathUtilities.MaskUsername).ToList(),
- PathUtilities.MaskUsername(targetLocation.GamePath),
- targetLocation.FallbackPaths.Select(PathUtilities.MaskUsername).ToList());
- }
-
public async Task WriteBaselineAsync(VerificationBaseline baseline, string filePath)
{
#if NET
diff --git a/src/ModVerify.CliApp/Reporting/BaselineSelector.cs b/src/ModVerify.CliApp/Reporting/BaselineSelector.cs
index 791eaae..efcaae5 100644
--- a/src/ModVerify.CliApp/Reporting/BaselineSelector.cs
+++ b/src/ModVerify.CliApp/Reporting/BaselineSelector.cs
@@ -1,6 +1,6 @@
using AET.ModVerify.App.Resources.Baselines;
using AET.ModVerify.App.Settings;
-using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
using AnakinRaW.ApplicationBase;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
diff --git a/src/ModVerify.CliApp/Reporting/IBaselineFactory.cs b/src/ModVerify.CliApp/Reporting/IBaselineFactory.cs
index 721a7ce..a534cdb 100644
--- a/src/ModVerify.CliApp/Reporting/IBaselineFactory.cs
+++ b/src/ModVerify.CliApp/Reporting/IBaselineFactory.cs
@@ -1,5 +1,6 @@
using AET.ModVerify.App.Settings;
using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
diff --git a/src/ModVerify.CliApp/Reporting/VerifyConsoleProgressReporter.cs b/src/ModVerify.CliApp/Reporting/VerifyConsoleProgressReporter.cs
index b2ce170..66587ae 100644
--- a/src/ModVerify.CliApp/Reporting/VerifyConsoleProgressReporter.cs
+++ b/src/ModVerify.CliApp/Reporting/VerifyConsoleProgressReporter.cs
@@ -1,7 +1,7 @@
using System;
using System.Threading;
using AET.ModVerify.App.Settings;
-using AET.ModVerify.Pipeline.Progress;
+using AET.ModVerify.Progress;
using AnakinRaW.CommonUtilities;
using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
using ShellProgressBar;
diff --git a/src/ModVerify.CliApp/Resources/Baselines/baseline-foc.json b/src/ModVerify.CliApp/Resources/Baselines/baseline-foc.json
index ce70f8a..39b65f9 100644
--- a/src/ModVerify.CliApp/Resources/Baselines/baseline-foc.json
+++ b/src/ModVerify.CliApp/Resources/Baselines/baseline-foc.json
@@ -1,5 +1,5 @@
{
- "version": "2.1",
+ "version": "2.2",
"target": {
"name": "Forces of Corruption (SteamGold)",
"engine": "Foc",
@@ -10,3038 +10,2864 @@
"errors": [
{
"id": "XML04",
- "verifiers": [
- "XMLError"
- ],
- "message": "Expected double but got value \u002737\u0060\u0027. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #11571\u0027",
"severity": "Warning",
+ "asset": "Size",
+ "message": "Expected double but got value \u002737\u0060\u0027. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #11571\u0027",
"context": [
- "DATA\\XML\\COMMANDBARCOMPONENTS.XML",
+ "Parser: PG.StarWarsGame.Files.XML.Parsers.PetroglyphXmlFloatParser",
+ "File: DATA\\XML\\COMMANDBARCOMPONENTS.XML",
"Size",
"parentName=\u0027bm_text_steal\u0027"
- ],
- "asset": "Size"
+ ]
},
{
"id": "XML04",
- "verifiers": [
- "XMLError"
- ],
- "message": "Expected integer but got \u002780, 20\u0027. File=\u0027DATA\\XML\\SFXEVENTSWEAPONS.XML #90\u0027",
"severity": "Warning",
+ "asset": "Probability",
+ "message": "Expected integer but got \u002780, 20\u0027. File=\u0027DATA\\XML\\SFXEVENTSWEAPONS.XML #90\u0027",
"context": [
- "DATA\\XML\\SFXEVENTSWEAPONS.XML",
+ "Parser: PG.StarWarsGame.Files.XML.Parsers.PetroglyphXmlIntegerParser",
+ "File: DATA\\XML\\SFXEVENTSWEAPONS.XML",
"Probability",
"parentName=\u0027Unit_TIE_Fighter_Fire\u0027"
- ],
- "asset": "Probability"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Reb_CelebHall.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "CIN_Reb_CelebHall.alo"
+ "id": "XML08",
+ "severity": "Information",
+ "asset": "DATA\\XML\\UNITS_HERO_REBEL_ROGUE_SQUADRON.XML",
+ "message": "XML header is not the first entry of the XML file. File=\u0027DATA\\XML\\UNITS_HERO_REBEL_ROGUE_SQUADRON.XML #0\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.GameObjectFileParser",
+ "File: DATA\\XML\\UNITS_HERO_REBEL_ROGUE_SQUADRON.XML"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_ssd_debris\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_ECLIPSE_UC_DC.ALO\u0027",
- "severity": "Error",
+ "id": "XML10",
+ "severity": "Information",
+ "asset": "Disabled_Darken",
+ "message": "The node \u0027Disabled_Darken\u0027 is not supported. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #8608\u0027",
"context": [
- "DATA\\ART\\MODELS\\UV_ECLIPSE_UC_DC.ALO"
- ],
- "asset": "p_ssd_debris"
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.CommandBarComponentParser",
+ "File: DATA\\XML\\COMMANDBARCOMPONENTS.XML",
+ "Disabled_Darken",
+ "parentName=\u0027b_fast_forward_t\u0027"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall.tga\u0027 for context: [W_SITH_LEFTHALL.ALO].",
- "severity": "Error",
+ "id": "XML10",
+ "severity": "Information",
+ "asset": "Mega_Texture_Name",
+ "message": "The node \u0027Mega_Texture_Name\u0027 is not supported. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #8\u0027",
"context": [
- "W_SITH_LEFTHALL.ALO"
- ],
- "asset": "Cin_Reb_CelebHall_Wall.tga"
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.CommandBarComponentParser",
+ "File: DATA\\XML\\COMMANDBARCOMPONENTS.XML",
+ "Mega_Texture_Name",
+ "parentName=\u0027i_main_commandbar\u0027"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_ImperialCraft.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "Cin_ImperialCraft.alo"
+ "id": "XML08",
+ "severity": "Information",
+ "asset": "DATA\\XML\\UNITS_SPACE_UNDERWORLD_INTERCEPTOR4.XML",
+ "message": "XML header is not the first entry of the XML file. File=\u0027DATA\\XML\\UNITS_SPACE_UNDERWORLD_INTERCEPTOR4.XML #0\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.GameObjectFileParser",
+ "File: DATA\\XML\\UNITS_SPACE_UNDERWORLD_INTERCEPTOR4.XML"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_Officer.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "Cin_Officer.alo"
+ "id": "XML08",
+ "severity": "Information",
+ "asset": "DATA\\XML\\UNITS_SPACE_EMPIRE_TIE_DEFENDER.XML",
+ "message": "XML header is not the first entry of the XML file. File=\u0027DATA\\XML\\UNITS_SPACE_EMPIRE_TIE_DEFENDER.XML #0\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.GameObjectFileParser",
+ "File: DATA\\XML\\UNITS_SPACE_EMPIRE_TIE_DEFENDER.XML"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_DStar_protons.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "Cin_DStar_protons.alo"
+ "id": "XML10",
+ "severity": "Information",
+ "asset": "Disabled_Darken",
+ "message": "The node \u0027Disabled_Darken\u0027 is not supported. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #8569\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.CommandBarComponentParser",
+ "File: DATA\\XML\\COMMANDBARCOMPONENTS.XML",
+ "Disabled_Darken",
+ "parentName=\u0027b_fast_forward\u0027"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027w_grenade.tga\u0027 for context: [W_GRENADE.ALO].",
- "severity": "Error",
+ "id": "XML08",
+ "severity": "Information",
+ "asset": "DATA\\XML\\GROUNDSTRUCTURES_UNDERWORLD.XML",
+ "message": "XML header is not the first entry of the XML file. File=\u0027DATA\\XML\\GROUNDSTRUCTURES_UNDERWORLD.XML #0\u0027",
"context": [
- "W_GRENADE.ALO"
- ],
- "asset": "w_grenade.tga"
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.GameObjectFileParser",
+ "File: DATA\\XML\\GROUNDSTRUCTURES_UNDERWORLD.XML"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_03_STATION_D.ALO\u0027",
- "severity": "Error",
+ "id": "XML08",
+ "severity": "Information",
+ "asset": "DATA\\XML\\UNITS_LAND_REBEL_GALLOFREE_HTT.XML",
+ "message": "XML header is not the first entry of the XML file. File=\u0027DATA\\XML\\UNITS_LAND_REBEL_GALLOFREE_HTT.XML #0\u0027",
"context": [
- "DATA\\ART\\MODELS\\UB_03_STATION_D.ALO"
- ],
- "asset": "p_uwstation_death"
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.GameObjectFileParser",
+ "File: DATA\\XML\\UNITS_LAND_REBEL_GALLOFREE_HTT.XML"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_EI_Vader.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "Cin_EI_Vader.alo"
+ "id": "XML10",
+ "severity": "Information",
+ "asset": "Disabled_Darken",
+ "message": "The node \u0027Disabled_Darken\u0027 is not supported. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #8589\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.CommandBarComponentParser",
+ "File: DATA\\XML\\COMMANDBARCOMPONENTS.XML",
+ "Disabled_Darken",
+ "parentName=\u0027b_play_pause_t\u0027"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027MODELS\u0027",
- "severity": "Error",
- "context": [],
- "asset": "MODELS"
+ "id": "XML10",
+ "severity": "Information",
+ "asset": "Disabled_Darken",
+ "message": "The node \u0027Disabled_Darken\u0027 is not supported. File=\u0027DATA\\XML\\COMMANDBARCOMPONENTS.XML #8550\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.CommandBarComponentParser",
+ "File: DATA\\XML\\COMMANDBARCOMPONENTS.XML",
+ "Disabled_Darken",
+ "parentName=\u0027b_play_pause\u0027"
+ ]
},
{
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_DeathStar_Wall.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "Cin_DeathStar_Wall.alo"
+ "id": "XML08",
+ "severity": "Information",
+ "asset": "DATA\\XML\\SPACEPROPS_UNDERWORLD.XML",
+ "message": "XML header is not the first entry of the XML file. File=\u0027DATA\\XML\\SPACEPROPS_UNDERWORLD.XML #0\u0027",
+ "context": [
+ "Parser: PG.StarWarsGame.Engine.Xml.Parsers.GameObjectFileParser",
+ "File: DATA\\XML\\SPACEPROPS_UNDERWORLD.XML"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_smoke_small_thin2\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_PRISON.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0210_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0210_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_PRISON.ALO"
- ],
- "asset": "p_smoke_small_thin2"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_01_STATION_D.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0207_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0207_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UB_01_STATION_D.ALO"
- ],
- "asset": "p_uwstation_death"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Officer_Row.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Officer_Row.alo"
+ "asset": "U000_LEI0205_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0205_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_MEDIUM.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0207_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0207_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\W_STARS_MEDIUM.ALO"
- ],
- "asset": "Lensflare0"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_DeathStar_Hangar.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_DeathStar_Hangar.alo"
+ "asset": "U000_DEF3006_ENG.WAV",
+ "message": "Audio file \u0027U000_DEF3006_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Corrupt_Sabateur"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_EV_lambdaShuttle_150.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_EV_lambdaShuttle_150.alo"
+ "asset": "U000_ARC3104_ENG.WAV",
+ "message": "Audio file \u0027U000_ARC3104_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Produce_Troops_Arc_Hammer"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_smoke_small_thin4\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_PRISON.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0315_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0315_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_PRISON.ALO"
- ],
- "asset": "p_smoke_small_thin4"
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_CINE.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0201_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0201_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\W_STARS_CINE.ALO"
- ],
- "asset": "Lensflare0"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_SKIPRAY.ALO\u0027.",
"severity": "Error",
+ "asset": "U000_LEI0211_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0211_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UV_SKIPRAY.ALO"
- ],
- "asset": "Default.fx"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\UI_IG88.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0303_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0303_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UI_IG88.ALO"
- ],
- "asset": "p_desert_ground_dust"
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_p_proton_torpedo.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_p_proton_torpedo.alo"
+ "asset": "U000_LEI0111_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0111_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Fire_Huge.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Fire_Huge.alo"
+ "asset": "AMB_URB_CLEAR_LOOP_1.WAV",
+ "message": "Audio file \u0027AMB_URB_CLEAR_LOOP_1.WAV\u0027 could not be found.",
+ "context": [
+ "Weather_Ambient_Clear_Urban_Loop"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_04_STATION_D.ALO\u0027",
"severity": "Error",
+ "asset": "FS_BEETLE_3.WAV",
+ "message": "Audio file \u0027FS_BEETLE_3.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UB_04_STATION_D.ALO"
- ],
- "asset": "p_uwstation_death"
+ "SFX_Anim_Beetle_Footsteps"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027RV_nebulonb_D_death_00.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "RV_nebulonb_D_death_00.ALO"
+ "asset": "U000_LEI0205_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0205_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_02_STATION_D.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0215_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0215_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UB_02_STATION_D.ALO"
- ],
- "asset": "p_uwstation_death"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_Kamino_Reflect.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_Kamino_Reflect.ALO"
+ "asset": "U000_LEI0504_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0504_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Remove_Corruption_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_smoke_small_thin2\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_MONCAL_BUILDING.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0104_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0104_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_MONCAL_BUILDING.ALO"
- ],
- "asset": "p_smoke_small_thin2"
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_steam_small\u0027 not found for model \u0027DATA\\ART\\MODELS\\RB_HEAVYVEHICLEFACTORY.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0303_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0303_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\RB_HEAVYVEHICLEFACTORY.ALO"
- ],
- "asset": "p_steam_small"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_EV_Stardestroyer_Warp.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_EV_Stardestroyer_Warp.alo"
+ "asset": "U000_LEI0202_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0202_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_DStar_TurretLasers.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_DStar_TurretLasers.alo"
+ "asset": "U000_LEI0212_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0212_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Rbel_GreyGroup.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Rbel_GreyGroup.alo"
+ "asset": "U000_LEI0105_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0105_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_Planet_Hoth_High.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_Planet_Hoth_High.alo"
+ "asset": "U000_LEI0311_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0311_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Trooper_Row.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Trooper_Row.alo"
+ "asset": "U000_LEI0110_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0110_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\UI_SABOTEUR.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0313_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0313_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UI_SABOTEUR.ALO"
- ],
- "asset": "p_desert_ground_dust"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_CINE_LUA.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0103_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0103_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\W_STARS_CINE_LUA.ALO"
- ],
- "asset": "Lensflare0"
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_AllShaders.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_AllShaders.ALO"
+ "asset": "U000_LEI0308_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0308_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\EV_TIE_LANCET.ALO\u0027.",
"severity": "Error",
+ "asset": "U000_TMC0212_ENG.WAV",
+ "message": "Audio file \u0027U000_TMC0212_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\EV_TIE_LANCET.ALO"
- ],
- "asset": "Default.fx"
+ "Unit_Assist_Move_Tie_Mauler"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CINE_EV_StarDestroyer.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "CINE_EV_StarDestroyer.ALO"
+ "asset": "U000_LEI0304_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0304_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_EI_Palpatine.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_EI_Palpatine.alo"
+ "asset": "U000_LEI0101_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0101_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027Cin_DeathStar.tga\u0027 for context: [ALTTEST.ALO].",
"severity": "Error",
+ "asset": "U000_LEI0211_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0211_ENG.WAV\u0027 could not be found.",
"context": [
- "ALTTEST.ALO"
- ],
- "asset": "Cin_DeathStar.tga"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027UB_girder_B.tga\u0027 for context: [UV_MDU_CAGE.ALO].",
"severity": "Error",
+ "asset": "U000_LEI0305_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0305_ENG.WAV\u0027 could not be found.",
"context": [
- "UV_MDU_CAGE.ALO"
- ],
- "asset": "UB_girder_B.tga"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027P_mptl-2a_Die\u0027 not found for model \u0027DATA\\ART\\MODELS\\RV_MPTL-2A.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0208_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0208_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\RV_MPTL-2A.ALO"
- ],
- "asset": "P_mptl-2a_Die"
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\EV_MDU_SENSORNODE.ALO\u0027.",
"severity": "Error",
+ "asset": "U000_LEI0311_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0311_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\EV_MDU_SENSORNODE.ALO"
- ],
- "asset": "Default.fx"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_Planet_Alderaan_High.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_Planet_Alderaan_High.alo"
+ "asset": "U000_LEI0314_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0314_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_hp_archammer-damage\u0027 not found for model \u0027DATA\\ART\\MODELS\\EV_ARCHAMMER.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0108_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0108_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\EV_ARCHAMMER.ALO"
- ],
- "asset": "p_hp_archammer-damage"
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_05_STATION_D.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0213_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0213_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UB_05_STATION_D.ALO"
- ],
- "asset": "p_uwstation_death"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_explosion_smoke_small_thin5\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_NOGHRI_HUT.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0202_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0202_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_NOGHRI_HUT.ALO"
- ],
- "asset": "p_explosion_smoke_small_thin5"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Probe_Droid.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Probe_Droid.alo"
+ "asset": "U000_LEI0113_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0113_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_HIGH.ALO\u0027",
"severity": "Error",
+ "asset": "AMB_DES_CLEAR_LOOP_1.WAV",
+ "message": "Audio file \u0027AMB_DES_CLEAR_LOOP_1.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\W_STARS_HIGH.ALO"
- ],
- "asset": "Lensflare0"
+ "Weather_Ambient_Clear_Sandstorm_Loop"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_Volcano_Rock02.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_Volcano_Rock02.ALO"
+ "asset": "U000_LEI0107_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0107_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027lookat\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_ECLIPSE.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0305_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0305_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UV_ECLIPSE.ALO"
- ],
- "asset": "lookat"
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_Shuttle_Tyderium.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_Shuttle_Tyderium.alo"
+ "asset": "U000_LEI0209_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0209_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_SwampGasEmit.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_SwampGasEmit.ALO"
+ "asset": "U000_LEI0308_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0308_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027P_heat_small01\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_VCH.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0207_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0207_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_VCH.ALO"
- ],
- "asset": "P_heat_small01"
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Rbel_NavyRow.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Rbel_NavyRow.alo"
+ "asset": "U000_MAL0503_ENG.WAV",
+ "message": "Audio file \u0027U000_MAL0503_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Assist_Move_Missile_Launcher"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Fire_Medium.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Fire_Medium.alo"
+ "asset": "U000_LEI0102_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0102_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_ewok_drag_dirt\u0027 not found for model \u0027DATA\\ART\\MODELS\\UI_EWOK_HANDLER.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0306_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0306_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UI_EWOK_HANDLER.ALO"
- ],
- "asset": "p_ewok_drag_dirt"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_Bush_Swmp00.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_Bush_Swmp00.ALO"
+ "asset": "FS_BEETLE_2.WAV",
+ "message": "Audio file \u0027FS_BEETLE_2.WAV\u0027 could not be found.",
+ "context": [
+ "SFX_Anim_Beetle_Footsteps"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_droid_steam.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_droid_steam.alo"
+ "asset": "U000_LEI0312_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0312_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Biker_Row.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Biker_Row.alo"
+ "asset": "U000_LEI0402_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0402_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Guard_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027w_planet_volcanic.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "w_planet_volcanic.alo"
+ "asset": "U000_LEI0309_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0309_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_smoke_small_thin2\u0027 not found for model \u0027DATA\\ART\\MODELS\\RB_HYPERVELOCITYGUN.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0501_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0501_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\RB_HYPERVELOCITYGUN.ALO"
- ],
- "asset": "p_smoke_small_thin2"
+ "Unit_Remove_Corruption_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027lookat\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_ECLIPSE_UC.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0201_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0201_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UV_ECLIPSE_UC.ALO"
- ],
- "asset": "lookat"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_REb_CelebCharacters.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_REb_CelebCharacters.alo"
+ "asset": "U000_MCF1601_ENG.WAV",
+ "message": "Audio file \u0027U000_MCF1601_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_StarDest_MC30_Frigate"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_DeathStar_High.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_DeathStar_High.alo"
+ "asset": "TESTUNITMOVE_ENG.WAV",
+ "message": "Audio file \u0027TESTUNITMOVE_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Move_Gneneric_Test"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall_B.tga\u0027 for context: [W_SITH_LEFTHALL.ALO].",
"severity": "Error",
+ "asset": "U000_LEI0114_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0114_ENG.WAV\u0027 could not be found.",
"context": [
- "W_SITH_LEFTHALL.ALO"
- ],
- "asset": "Cin_Reb_CelebHall_Wall_B.tga"
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027NB_YsalamiriTree_B.tga\u0027 for context: [UV_MDU_CAGE.ALO].",
"severity": "Error",
+ "asset": "U000_ARC3105_ENG.WAV",
+ "message": "Audio file \u0027U000_ARC3105_ENG.WAV\u0027 could not be found.",
"context": [
- "UV_MDU_CAGE.ALO"
- ],
- "asset": "NB_YsalamiriTree_B.tga"
- },
- {
- "id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_Coruscant.alo\u0027",
- "severity": "Error",
- "context": [],
- "asset": "Cin_Coruscant.alo"
+ "Unit_Complete_Troops_Arc_Hammer"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_prison_light\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_PRISON.ALO\u0027",
"severity": "Error",
+ "asset": "EGL_STAR_VIPER_SPINNING_1.WAV",
+ "message": "Audio file \u0027EGL_STAR_VIPER_SPINNING_1.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_PRISON.ALO"
- ],
- "asset": "p_prison_light"
+ "Unit_Star_Viper_Spinning_By"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_cold_tiny01\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_SCH.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0401_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0401_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\NB_SCH.ALO"
- ],
- "asset": "p_cold_tiny01"
+ "Unit_Guard_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_NavyTrooper_Row.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_NavyTrooper_Row.alo"
+ "asset": "U000_LEI0213_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0213_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_CRUSADERCLASSCORVETTE.ALO\u0027.",
"severity": "Error",
+ "asset": "U000_LEI0212_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0212_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\UV_CRUSADERCLASSCORVETTE.ALO"
- ],
- "asset": "Default.fx"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Rbel_Soldier.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Rbel_Soldier.alo"
+ "asset": "U000_LEI0115_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0115_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\RI_KYLEKATARN.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0306_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0306_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\RI_KYLEKATARN.ALO"
- ],
- "asset": "p_desert_ground_dust"
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Lambda_Mouth.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Lambda_Mouth.alo"
+ "asset": "U000_LEI0601_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0601_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Increase_Production_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027p_particle_master\u0027 for context: [P_DIRT_EMITTER_TEST1.ALO].",
"severity": "Error",
+ "asset": "U000_ARC3106_ENG.WAV",
+ "message": "Audio file \u0027U000_ARC3106_ENG.WAV\u0027 could not be found.",
"context": [
- "P_DIRT_EMITTER_TEST1.ALO"
- ],
- "asset": "p_particle_master"
+ "Unit_Complete_Troops_Arc_Hammer"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_bridge.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_bridge.alo"
+ "asset": "U000_LEI0602_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0602_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Increase_Production_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027W_Vol_Steam01.ALO\u0027",
"severity": "Error",
- "context": [],
- "asset": "W_Vol_Steam01.ALO"
+ "asset": "U000_DEF3106_ENG.WAV",
+ "message": "Audio file \u0027U000_DEF3106_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Weaken_Sabateur"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Rbel_grey.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Rbel_grey.alo"
+ "asset": "U000_LEI0403_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0403_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Guard_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027w_sith_arch.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "w_sith_arch.alo"
+ "asset": "U000_LEI0314_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0314_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_rv_XWingProp.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_rv_XWingProp.alo"
+ "asset": "U000_LEI0203_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0203_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_DStar_Dish_close.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_DStar_Dish_close.alo"
+ "asset": "U000_LEI0205_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0205_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier",
- "AET.ModVerify.Verifiers.Commons.TextureVeifier"
- ],
- "message": "Could not find texture \u0027W_TE_Rock_f_02_b.tga\u0027 for context: [EV_TIE_PHANTOM.ALO].",
"severity": "Error",
+ "asset": "U000_TMC0212_ENG.WAV",
+ "message": "Audio file \u0027U000_TMC0212_ENG.WAV\u0027 could not be found.",
"context": [
- "EV_TIE_PHANTOM.ALO"
- ],
- "asset": "W_TE_Rock_f_02_b.tga"
+ "Unit_Move_Tie_Mauler"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027pe_bwing_yellow\u0027 not found for model \u0027DATA\\ART\\MODELS\\RV_BWING.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0203_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0203_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\RV_BWING.ALO"
- ],
- "asset": "pe_bwing_yellow"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Lambda_Head.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Lambda_Head.alo"
+ "asset": "U000_LEI0307_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0307_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_explosion_small_delay00\u0027 not found for model \u0027DATA\\ART\\MODELS\\EB_COMMANDCENTER.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0203_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0203_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\EB_COMMANDCENTER.ALO"
- ],
- "asset": "p_explosion_small_delay00"
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_DStar_LeverPanel.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_DStar_LeverPanel.alo"
+ "asset": "U000_LEI0201_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0201_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027p_splash_wake_lava.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "p_splash_wake_lava.alo"
+ "asset": "FS_BEETLE_1.WAV",
+ "message": "Audio file \u0027FS_BEETLE_1.WAV\u0027 could not be found.",
+ "context": [
+ "SFX_Anim_Beetle_Footsteps"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_LOW.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0204_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0204_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\W_STARS_LOW.ALO"
- ],
- "asset": "Lensflare0"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\EI_MARAJADE.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0206_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0206_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\EI_MARAJADE.ALO"
- ],
- "asset": "p_desert_ground_dust"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Proxy particle \u0027p_bomb_spin\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_THERMAL_DETONATOR_EMPIRE.ALO\u0027",
"severity": "Error",
+ "asset": "U000_LEI0603_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0603_ENG.WAV\u0027 could not be found.",
"context": [
- "DATA\\ART\\MODELS\\W_THERMAL_DETONATOR_EMPIRE.ALO"
- ],
- "asset": "p_bomb_spin"
+ "Unit_Increase_Production_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027Cin_EV_TieAdvanced.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "Cin_EV_TieAdvanced.alo"
+ "asset": "U000_LEI0313_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0313_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.ReferencedModelsVerifier",
- "AET.ModVerify.Verifiers.Commons.SingleModelVerifier"
- ],
- "message": "Unable to find .ALO file \u0027CIN_Rbel_Soldier_Group.alo\u0027",
"severity": "Error",
- "context": [],
- "asset": "CIN_Rbel_Soldier_Group.alo"
+ "asset": "U000_LEI0301_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0301_ENG.WAV\u0027 could not be found.",
+ "context": [
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0213_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0312_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0312_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0213_ENG.WAV"
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0113_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0404_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0404_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0113_ENG.WAV"
+ "Unit_Guard_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0603_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0604_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0604_ENG.WAV\u0027 could not be found.",
"context": [
"Unit_Increase_Production_Leia"
- ],
- "asset": "U000_LEI0603_ENG.WAV"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0309_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0210_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0210_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0309_ENG.WAV"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0212_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0307_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0307_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0212_ENG.WAV"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_MAL0503_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "C000_DST0102_ENG.WAV",
+ "message": "Audio file \u0027C000_DST0102_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Assist_Move_Missile_Launcher"
- ],
- "asset": "U000_MAL0503_ENG.WAV"
+ "EHD_Death_Star_Activate"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_MCF1601_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0215_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0215_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_StarDest_MC30_Frigate"
- ],
- "asset": "U000_MCF1601_ENG.WAV"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0111_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0206_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0206_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0111_ENG.WAV"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_ARC3106_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0202_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0202_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Complete_Troops_Arc_Hammer"
- ],
- "asset": "U000_ARC3106_ENG.WAV"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0303_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0304_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0304_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0303_ENG.WAV"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0404_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0315_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0315_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Guard_Leia"
- ],
- "asset": "U000_LEI0404_ENG.WAV"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027TESTUNITMOVE_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0112_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0112_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Gneneric_Test"
- ],
- "asset": "TESTUNITMOVE_ENG.WAV"
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0401_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "FS_BEETLE_4.WAV",
+ "message": "Audio file \u0027FS_BEETLE_4.WAV\u0027 could not be found.",
"context": [
- "Unit_Guard_Leia"
- ],
- "asset": "U000_LEI0401_ENG.WAV"
+ "SFX_Anim_Beetle_Footsteps"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027EGL_STAR_VIPER_SPINNING_1.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0109_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0109_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Star_Viper_Spinning_By"
- ],
- "asset": "EGL_STAR_VIPER_SPINNING_1.WAV"
+ "Unit_Select_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_TMC0212_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0309_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0309_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Tie_Mauler"
- ],
- "asset": "U000_TMC0212_ENG.WAV"
+ "Unit_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0110_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0106_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0106_ENG.WAV\u0027 could not be found.",
"context": [
"Unit_Select_Leia"
- ],
- "asset": "U000_LEI0110_ENG.WAV"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0314_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0301_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0301_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0314_ENG.WAV"
+ "Unit_Group_Attack_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0305_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0209_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0209_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0305_ENG.WAV"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0112_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0208_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0208_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0112_ENG.WAV"
+ "Unit_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0209_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0503_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0503_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0209_ENG.WAV"
+ "Unit_Remove_Corruption_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0211_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0208_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0208_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0211_ENG.WAV"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0205_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0206_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0206_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0205_ENG.WAV"
+ "Unit_Fleet_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0115_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0502_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0502_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0115_ENG.WAV"
+ "Unit_Remove_Corruption_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0604_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "U000_LEI0204_ENG.WAV",
+ "message": "Audio file \u0027U000_LEI0204_ENG.WAV\u0027 could not be found.",
"context": [
- "Unit_Increase_Production_Leia"
- ],
- "asset": "U000_LEI0604_ENG.WAV"
+ "Unit_Group_Move_Leia"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0602_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "underworld_logo_off.tga",
+ "message": "Could not find GUI texture \u0027underworld_logo_off.tga\u0027 at location \u0027MegaTexture\u0027.",
"context": [
- "Unit_Increase_Production_Leia"
- ],
- "asset": "U000_LEI0602_ENG.WAV"
+ "IDC_PLAY_FACTION_A_BUTTON_BIG",
+ "MegaTexture"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0315_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "i_dialogue_button_large_middle_off.tga",
+ "message": "Could not find GUI texture \u0027i_dialogue_button_large_middle_off.tga\u0027 at location \u0027Repository\u0027.",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0315_ENG.WAV"
+ "IDC_PLAY_FACTION_B_BUTTON_BIG",
+ "Repository"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_DEF3006_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "underworld_logo_rollover.tga",
+ "message": "Could not find GUI texture \u0027underworld_logo_rollover.tga\u0027 at location \u0027MegaTexture\u0027.",
"context": [
- "Unit_Corrupt_Sabateur"
- ],
- "asset": "U000_DEF3006_ENG.WAV"
+ "IDC_PLAY_FACTION_A_BUTTON_BIG",
+ "MegaTexture"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0210_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "underworld_logo_selected.tga",
+ "message": "Could not find GUI texture \u0027underworld_logo_selected.tga\u0027 at location \u0027MegaTexture\u0027.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0210_ENG.WAV"
+ "IDC_PLAY_FACTION_A_BUTTON_BIG",
+ "MegaTexture"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0105_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "lookat",
+ "message": "Proxy particle \u0027lookat\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_ECLIPSE_UC.ALO\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0105_ENG.WAV"
+ "Eclipse_Super_Star_Destroyer",
+ "DATA\\ART\\MODELS\\UV_ECLIPSE_UC.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0208_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "w_planet_volcanic.alo",
+ "message": "Unable to find .ALO file \u0027w_planet_volcanic.alo\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0208_ENG.WAV"
+ "Volcanic_Backdrop_Large"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0106_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Default.fx",
+ "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_SKIPRAY.ALO\u0027.",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0106_ENG.WAV"
+ "Skipray_Bombing_Run",
+ "DATA\\ART\\MODELS\\UV_SKIPRAY.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0202_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "pe_bwing_yellow",
+ "message": "Proxy particle \u0027pe_bwing_yellow\u0027 not found for model \u0027DATA\\ART\\MODELS\\RV_BWING.ALO\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0202_ENG.WAV"
+ "B-Wing",
+ "DATA\\ART\\MODELS\\RV_BWING.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0306_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_DeathStar_High.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DeathStar_High.alo\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0306_ENG.WAV"
+ "Death_Star_Whole_small"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0101_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "CIN_Rbel_NavyRow.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Rbel_NavyRow.alo\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0101_ENG.WAV"
+ "Cin_Rebel_NavyRow"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027C000_DST0102_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "W_AllShaders.ALO",
+ "message": "Unable to find .ALO file \u0027W_AllShaders.ALO\u0027",
"context": [
- "EHD_Death_Star_Activate"
- ],
- "asset": "C000_DST0102_ENG.WAV"
+ "Prop_AllShaders"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0103_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_prison_light",
+ "message": "Proxy particle \u0027p_prison_light\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_PRISON.ALO\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0103_ENG.WAV"
+ "Imperial_Prison_Facility",
+ "DATA\\ART\\MODELS\\NB_PRISON.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0403_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_DeathStar_High.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DeathStar_High.alo\u0027",
"context": [
- "Unit_Guard_Leia"
- ],
- "asset": "U000_LEI0403_ENG.WAV"
+ "Death_Star_Whole_Vsmall"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027FS_BEETLE_2.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "W_Vol_Steam01.ALO",
+ "message": "Unable to find .ALO file \u0027W_Vol_Steam01.ALO\u0027",
"context": [
- "SFX_Anim_Beetle_Footsteps"
- ],
- "asset": "FS_BEETLE_2.WAV"
+ "Prop_Vol_Steam01"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0201_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_Coruscant.alo",
+ "message": "Unable to find .ALO file \u0027Cin_Coruscant.alo\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0201_ENG.WAV"
+ "Corusant_Backdrop_Large 6x"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0203_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Default.fx",
+ "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_CRUSADERCLASSCORVETTE.ALO\u0027.",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0203_ENG.WAV"
+ "Crusader_Gunship",
+ "DATA\\ART\\MODELS\\UV_CRUSADERCLASSCORVETTE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0114_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Lensflare0",
+ "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_HIGH.ALO\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0114_ENG.WAV"
+ "Stars_High",
+ "DATA\\ART\\MODELS\\W_STARS_HIGH.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027FS_BEETLE_1.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "lookat",
+ "message": "Proxy particle \u0027lookat\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_ECLIPSE.ALO\u0027",
"context": [
- "SFX_Anim_Beetle_Footsteps"
- ],
- "asset": "FS_BEETLE_1.WAV"
+ "Eclipse_Prop",
+ "DATA\\ART\\MODELS\\UV_ECLIPSE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0304_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_uwstation_death",
+ "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_05_STATION_D.ALO\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0304_ENG.WAV"
+ "Underworld_Star_Base_5_Death_Clone",
+ "DATA\\ART\\MODELS\\UB_05_STATION_D.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_DeathStar.tga",
+ "message": "Could not find texture \u0027Cin_DeathStar.tga\u0027 for context: [Test_Base_Hector--\u003EALTTEST.ALO].",
+ "context": [
+ "Test_Base_Hector",
+ "ALTTEST.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Lensflare0",
+ "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_CINE_LUA.ALO\u0027",
+ "context": [
+ "Stars_Lua_Cinematic",
+ "DATA\\ART\\MODELS\\W_STARS_CINE_LUA.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_DStar_LeverPanel.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DStar_LeverPanel.alo\u0027",
+ "context": [
+ "Death_Star_LeverPanel"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Lensflare0",
+ "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_LOW.ALO\u0027",
+ "context": [
+ "Stars_Low",
+ "DATA\\ART\\MODELS\\W_STARS_LOW.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "W_TE_Rock_f_02_b.tga",
+ "message": "Could not find texture \u0027W_TE_Rock_f_02_b.tga\u0027 for context: [Vengeance_Frigate--\u003EUV_VENGEANCE.ALO].",
+ "context": [
+ "Vengeance_Frigate",
+ "UV_VENGEANCE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_rv_XWingProp.alo",
+ "message": "Unable to find .ALO file \u0027Cin_rv_XWingProp.alo\u0027",
+ "context": [
+ "Cin_X-WingProp"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Lambda_Mouth.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Lambda_Mouth.alo\u0027",
+ "context": [
+ "Cin_Lambda_Mouth"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_uwstation_death",
+ "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_04_STATION_D.ALO\u0027",
+ "context": [
+ "Underworld_Star_Base_4_Death_Clone",
+ "DATA\\ART\\MODELS\\UB_04_STATION_D.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_EV_lambdaShuttle_150.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EV_lambdaShuttle_150.alo\u0027",
+ "context": [
+ "Lambda_Shuttle_150X6-9"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Rbel_Soldier_Group.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Rbel_Soldier_Group.alo\u0027",
+ "context": [
+ "Cin_Rebel_SoldierRow"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_EI_Palpatine.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EI_Palpatine.alo\u0027",
+ "context": [
+ "Cin_Emperor_Shot_5"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_Reb_CelebHall_Wall_B.tga",
+ "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall_B.tga\u0027 for context: [Cin_sith_console--\u003EW_SITH_CONSOLE.ALO].",
+ "context": [
+ "Cin_sith_console",
+ "W_SITH_CONSOLE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_rv_XWingProp.alo",
+ "message": "Unable to find .ALO file \u0027Cin_rv_XWingProp.alo\u0027",
+ "context": [
+ "Grounded_Xwing"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_EV_Stardestroyer_Warp.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EV_Stardestroyer_Warp.alo\u0027",
+ "context": [
+ "Star_Destroyer_Warp"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_particle_master",
+ "message": "Could not find texture \u0027p_particle_master\u0027 for context: [Test_Particle--\u003EP_DIRT_EMITTER_TEST1.ALO].",
+ "context": [
+ "Test_Particle",
+ "P_DIRT_EMITTER_TEST1.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "W_Bush_Swmp00.ALO",
+ "message": "Unable to find .ALO file \u0027W_Bush_Swmp00.ALO\u0027",
+ "context": [
+ "Prop_Swamp_Bush00"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "W_TE_Rock_f_02_b.tga",
+ "message": "Could not find texture \u0027W_TE_Rock_f_02_b.tga\u0027 for context: [The_Peacebringer--\u003EUV_KRAYTCLASSDESTROYER_TYBER.ALO].",
+ "context": [
+ "The_Peacebringer",
+ "UV_KRAYTCLASSDESTROYER_TYBER.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_Reb_CelebHall_Wall_B.tga",
+ "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall_B.tga\u0027 for context: [Cin_sith_lefthall--\u003EW_SITH_LEFTHALL.ALO].",
+ "context": [
+ "Cin_sith_lefthall",
+ "W_SITH_LEFTHALL.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_Shuttle_Tyderium.alo",
+ "message": "Unable to find .ALO file \u0027Cin_Shuttle_Tyderium.alo\u0027",
+ "context": [
+ "Intro2_Shuttle_Tyderium"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_smoke_small_thin2",
+ "message": "Proxy particle \u0027p_smoke_small_thin2\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_PRISON.ALO\u0027",
+ "context": [
+ "Imperial_Prison_Facility",
+ "DATA\\ART\\MODELS\\NB_PRISON.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "P_mptl-2a_Die",
+ "message": "Proxy particle \u0027P_mptl-2a_Die\u0027 not found for model \u0027DATA\\ART\\MODELS\\RV_MPTL-2A.ALO\u0027",
+ "context": [
+ "MPTL",
+ "DATA\\ART\\MODELS\\RV_MPTL-2A.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_DeathStar_High.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DeathStar_High.alo\u0027",
+ "context": [
+ "UM05_PROP_DSTAR"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Rbel_GreyGroup.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Rbel_GreyGroup.alo\u0027",
+ "context": [
+ "Cin_Rebel_GreyGroup"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_Officer.alo",
+ "message": "Unable to find .ALO file \u0027Cin_Officer.alo\u0027",
+ "context": [
+ "FIN_Officer"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Reb_CelebHall.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Reb_CelebHall.alo\u0027",
+ "context": [
+ "REb_CelebHall"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_ewok_drag_dirt",
+ "message": "Proxy particle \u0027p_ewok_drag_dirt\u0027 not found for model \u0027DATA\\ART\\MODELS\\UI_EWOK_HANDLER.ALO\u0027",
+ "context": [
+ "Ewok_Handler",
+ "DATA\\ART\\MODELS\\UI_EWOK_HANDLER.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_steam_small",
+ "message": "Proxy particle \u0027p_steam_small\u0027 not found for model \u0027DATA\\ART\\MODELS\\RB_HEAVYVEHICLEFACTORY.ALO\u0027",
+ "context": [
+ "R_Ground_Heavy_Vehicle_Factory",
+ "DATA\\ART\\MODELS\\RB_HEAVYVEHICLEFACTORY.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_DeathStar_Wall.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DeathStar_Wall.alo\u0027",
+ "context": [
+ "Death_Star_Hangar_Outside"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "W_Kamino_Reflect.ALO",
+ "message": "Unable to find .ALO file \u0027W_Kamino_Reflect.ALO\u0027",
+ "context": [
+ "Prop_Kamino_Reflection_00"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Warning",
+ "asset": "i_button_general_dodonna.tga",
+ "message": "Could not find icon \u0027i_button_general_dodonna.tga\u0027 for game object type \u0027General_Dodonna\u0027.",
+ "context": [
+ "General_Dodonna"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_cold_tiny01",
+ "message": "Proxy particle \u0027p_cold_tiny01\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_SCH.ALO\u0027",
+ "context": [
+ "Arctic_Civilian_Spawn_House",
+ "DATA\\ART\\MODELS\\NB_SCH.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_desert_ground_dust",
+ "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\EI_MARAJADE.ALO\u0027",
+ "context": [
+ "Mara_Jade",
+ "DATA\\ART\\MODELS\\EI_MARAJADE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_smoke_small_thin2",
+ "message": "Proxy particle \u0027p_smoke_small_thin2\u0027 not found for model \u0027DATA\\ART\\MODELS\\RB_HYPERVELOCITYGUN.ALO\u0027",
+ "context": [
+ "Ground_Empire_Hypervelocity_Gun",
+ "DATA\\ART\\MODELS\\RB_HYPERVELOCITYGUN.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_uwstation_death",
+ "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_02_STATION_D.ALO\u0027",
+ "context": [
+ "Underworld_Star_Base_2_Death_Clone",
+ "DATA\\ART\\MODELS\\UB_02_STATION_D.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_splash_wake_lava.alo",
+ "message": "Unable to find .ALO file \u0027p_splash_wake_lava.alo\u0027",
+ "context": [
+ "Splash_Wake_Lava"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_Reb_CelebHall_Wall.tga",
+ "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall.tga\u0027 for context: [Cin_sith_console--\u003EW_SITH_CONSOLE.ALO].",
+ "context": [
+ "Cin_sith_console",
+ "W_SITH_CONSOLE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_EV_TieAdvanced.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EV_TieAdvanced.alo\u0027",
+ "context": [
+ "Fin_Vader_TIE"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_uwstation_death",
+ "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_03_STATION_D.ALO\u0027",
+ "context": [
+ "Underworld_Star_Base_3_Death_Clone",
+ "DATA\\ART\\MODELS\\UB_03_STATION_D.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Trooper_Row.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Trooper_Row.alo\u0027",
+ "context": [
+ "Cin_Trooper_Row"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Officer_Row.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Officer_Row.alo\u0027",
+ "context": [
+ "Cin_Officer_Row"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CINE_EV_StarDestroyer.ALO",
+ "message": "Unable to find .ALO file \u0027CINE_EV_StarDestroyer.ALO\u0027",
+ "context": [
+ "CIN_Star_Destroyer3X"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_EV_lambdaShuttle_150.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EV_lambdaShuttle_150.alo\u0027",
+ "context": [
+ "Lambda_Shuttle_150"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Lensflare0",
+ "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_MEDIUM.ALO\u0027",
+ "context": [
+ "Stars_Medium",
+ "DATA\\ART\\MODELS\\W_STARS_MEDIUM.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_DStar_TurretLasers.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DStar_TurretLasers.alo\u0027",
+ "context": [
+ "TurretLasers_DStar_Xplode"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Rbel_Soldier.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Rbel_Soldier.alo\u0027",
+ "context": [
+ "Cin_Rebel_soldier"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0301_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_smoke_small_thin4",
+ "message": "Proxy particle \u0027p_smoke_small_thin4\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_PRISON.ALO\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0301_ENG.WAV"
+ "Imperial_Prison_Facility",
+ "DATA\\ART\\MODELS\\NB_PRISON.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0503_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_ImperialCraft.alo",
+ "message": "Unable to find .ALO file \u0027Cin_ImperialCraft.alo\u0027",
"context": [
- "Unit_Remove_Corruption_Leia"
- ],
- "asset": "U000_LEI0503_ENG.WAV"
+ "Intro2_ImperialCraft"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0109_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "W_SwampGasEmit.ALO",
+ "message": "Unable to find .ALO file \u0027W_SwampGasEmit.ALO\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0109_ENG.WAV"
+ "Prop_SwampGasEmitter"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0308_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_desert_ground_dust",
+ "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\UI_IG88.ALO\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0308_ENG.WAV"
+ "IG-88",
+ "DATA\\ART\\MODELS\\UI_IG88.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0402_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_Planet_Hoth_High.alo",
+ "message": "Unable to find .ALO file \u0027Cin_Planet_Hoth_High.alo\u0027",
"context": [
- "Unit_Guard_Leia"
- ],
- "asset": "U000_LEI0402_ENG.WAV"
+ "Hoth_Backdrop_Large 6x"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0108_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "NB_YsalamiriTree_B.tga",
+ "message": "Could not find texture \u0027NB_YsalamiriTree_B.tga\u0027 for context: [Ysalamiri_Tree--\u003ENB_YSALAMIRI_TREE.ALO].",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0108_ENG.WAV"
+ "Ysalamiri_Tree",
+ "NB_YSALAMIRI_TREE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0307_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "CIN_DeathStar_Hangar.alo",
+ "message": "Unable to find .ALO file \u0027CIN_DeathStar_Hangar.alo\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0307_ENG.WAV"
+ "Cin_DeathStar_Hangar"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0311_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Lensflare0",
+ "message": "Proxy particle \u0027Lensflare0\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_STARS_CINE.ALO\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0311_ENG.WAV"
+ "Stars_Cinematic",
+ "DATA\\ART\\MODELS\\W_STARS_CINE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0102_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "w_sith_arch.alo",
+ "message": "Unable to find .ALO file \u0027w_sith_arch.alo\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0102_ENG.WAV"
+ "Cin_sith_arch"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0104_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "W_TE_Rock_f_02_b.tga",
+ "message": "Could not find texture \u0027W_TE_Rock_f_02_b.tga\u0027 for context: [F9TZ_Cloaking_Transport--\u003EUV_F9TZTRANSPORT.ALO].",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0104_ENG.WAV"
+ "F9TZ_Cloaking_Transport",
+ "UV_F9TZTRANSPORT.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027FS_BEETLE_3.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_Reb_CelebHall_Wall_B.tga",
+ "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall_B.tga\u0027 for context: [Cin_w_tile--\u003EW_TILE.ALO].",
"context": [
- "SFX_Anim_Beetle_Footsteps"
- ],
- "asset": "FS_BEETLE_3.WAV"
+ "Cin_w_tile",
+ "W_TILE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0313_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "CIN_Probe_Droid.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Probe_Droid.alo\u0027",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0313_ENG.WAV"
+ "Empire_Droid"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0206_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "CIN_Fire_Medium.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Fire_Medium.alo\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0206_ENG.WAV"
+ "Fin_Fire_Medium"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_ARC3104_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_Planet_Alderaan_High.alo",
+ "message": "Unable to find .ALO file \u0027Cin_Planet_Alderaan_High.alo\u0027",
"context": [
- "Unit_Produce_Troops_Arc_Hammer"
- ],
- "asset": "U000_ARC3104_ENG.WAV"
+ "Alderaan_Backdrop_Large 6x"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Warning",
+ "asset": "i_button_ni_nightsister_ranger.tga",
+ "message": "Could not find icon \u0027i_button_ni_nightsister_ranger.tga\u0027 for game object type \u0027Dathomir_Night_Sister\u0027.",
+ "context": [
+ "Dathomir_Night_Sister"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0312_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_Reb_CelebHall_Wall.tga",
+ "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall.tga\u0027 for context: [Cin_w_tile--\u003EW_TILE.ALO].",
"context": [
- "Unit_Attack_Leia"
- ],
- "asset": "U000_LEI0312_ENG.WAV"
+ "Cin_w_tile",
+ "W_TILE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0215_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "W_Kamino_Reflect.ALO",
+ "message": "Unable to find .ALO file \u0027W_Kamino_Reflect.ALO\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0215_ENG.WAV"
+ "Prop_Kamino_Reflection_01"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0107_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "CIN_Lambda_Head.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Lambda_Head.alo\u0027",
"context": [
- "Unit_Select_Leia"
- ],
- "asset": "U000_LEI0107_ENG.WAV"
+ "Cin_Lambda_Head"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0501_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_explosion_small_delay00",
+ "message": "Proxy particle \u0027p_explosion_small_delay00\u0027 not found for model \u0027DATA\\ART\\MODELS\\EB_COMMANDCENTER.ALO\u0027",
"context": [
- "Unit_Remove_Corruption_Leia"
- ],
- "asset": "U000_LEI0501_ENG.WAV"
+ "Imperial_Command_Center",
+ "DATA\\ART\\MODELS\\EB_COMMANDCENTER.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027AMB_DES_CLEAR_LOOP_1.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_smoke_small_thin2",
+ "message": "Proxy particle \u0027p_smoke_small_thin2\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_MONCAL_BUILDING.ALO\u0027",
"context": [
- "Weather_Ambient_Clear_Sandstorm_Loop"
- ],
- "asset": "AMB_DES_CLEAR_LOOP_1.WAV"
+ "MonCalamari_Spawn_House",
+ "DATA\\ART\\MODELS\\NB_MONCAL_BUILDING.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0504_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "W_Volcano_Rock02.ALO",
+ "message": "Unable to find .ALO file \u0027W_Volcano_Rock02.ALO\u0027",
"context": [
- "Unit_Remove_Corruption_Leia"
- ],
- "asset": "U000_LEI0504_ENG.WAV"
+ "Prop_Volcano_RockForm03"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0502_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_EI_Vader.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EI_Vader.alo\u0027",
"context": [
- "Unit_Remove_Corruption_Leia"
- ],
- "asset": "U000_LEI0502_ENG.WAV"
+ "Cin_Vader_Shot_6-9"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_DEF3106_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_uwstation_death",
+ "message": "Proxy particle \u0027p_uwstation_death\u0027 not found for model \u0027DATA\\ART\\MODELS\\UB_01_STATION_D.ALO\u0027",
"context": [
- "Unit_Weaken_Sabateur"
- ],
- "asset": "U000_DEF3106_ENG.WAV"
+ "Underworld_Star_Base_1_Death_Clone",
+ "DATA\\ART\\MODELS\\UB_01_STATION_D.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_ARC3105_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_Reb_CelebHall_Wall.tga",
+ "message": "Could not find texture \u0027Cin_Reb_CelebHall_Wall.tga\u0027 for context: [Cin_sith_lefthall--\u003EW_SITH_LEFTHALL.ALO].",
"context": [
- "Unit_Complete_Troops_Arc_Hammer"
- ],
- "asset": "U000_ARC3105_ENG.WAV"
+ "Cin_sith_lefthall",
+ "W_SITH_LEFTHALL.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0601_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "CIN_NavyTrooper_Row.alo",
+ "message": "Unable to find .ALO file \u0027CIN_NavyTrooper_Row.alo\u0027",
"context": [
- "Unit_Increase_Production_Leia"
- ],
- "asset": "U000_LEI0601_ENG.WAV"
+ "Cin_NavyTrooper_Row"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0204_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_ssd_debris",
+ "message": "Proxy particle \u0027p_ssd_debris\u0027 not found for model \u0027DATA\\ART\\MODELS\\UV_ECLIPSE_UC_DC.ALO\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0204_ENG.WAV"
+ "Eclipse_Super_Star_Destroyer_Death_Clone",
+ "DATA\\ART\\MODELS\\UV_ECLIPSE_UC_DC.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027U000_LEI0207_ENG.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "Cin_EI_Vader.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EI_Vader.alo\u0027",
"context": [
- "Unit_Move_Leia"
- ],
- "asset": "U000_LEI0207_ENG.WAV"
+ "Cin_Vader"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027FS_BEETLE_4.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_explosion_smoke_small_thin5",
+ "message": "Proxy particle \u0027p_explosion_smoke_small_thin5\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_NOGHRI_HUT.ALO\u0027",
"context": [
- "SFX_Anim_Beetle_Footsteps"
- ],
- "asset": "FS_BEETLE_4.WAV"
+ "Noghri_Spawn_House",
+ "DATA\\ART\\MODELS\\NB_NOGHRI_HUT.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.AudioFilesVerifier"
- ],
- "message": "Audio file \u0027AMB_URB_CLEAR_LOOP_1.WAV\u0027 could not be found.",
"severity": "Error",
+ "asset": "p_hp_archammer-damage",
+ "message": "Proxy particle \u0027p_hp_archammer-damage\u0027 not found for model \u0027DATA\\ART\\MODELS\\EV_ARCHAMMER.ALO\u0027",
"context": [
- "Weather_Ambient_Clear_Urban_Loop"
- ],
- "asset": "AMB_URB_CLEAR_LOOP_1.WAV"
+ "Arc_Hammer",
+ "DATA\\ART\\MODELS\\EV_ARCHAMMER.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.GuiDialogs.GuiDialogsVerifier"
- ],
- "message": "Could not find GUI texture \u0027i_dialogue_button_large_middle_off.tga\u0027 at location \u0027Repository\u0027.",
"severity": "Error",
+ "asset": "NB_YsalamiriTree_B.tga",
+ "message": "Could not find texture \u0027NB_YsalamiriTree_B.tga\u0027 for context: [Underworld_Ysalamiri_Cage--\u003EUV_MDU_CAGE.ALO].",
"context": [
- "IDC_PLAY_FACTION_B_BUTTON_BIG",
- "Repository"
- ],
- "asset": "i_dialogue_button_large_middle_off.tga"
+ "Underworld_Ysalamiri_Cage",
+ "UV_MDU_CAGE.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.GuiDialogs.GuiDialogsVerifier"
- ],
- "message": "Could not find GUI texture \u0027underworld_logo_selected.tga\u0027 at location \u0027MegaTexture\u0027.",
"severity": "Error",
+ "asset": "Cin_bridge.alo",
+ "message": "Unable to find .ALO file \u0027Cin_bridge.alo\u0027",
"context": [
- "IDC_PLAY_FACTION_A_BUTTON_BIG",
- "MegaTexture"
- ],
- "asset": "underworld_logo_selected.tga"
+ "UM05_PROP_BRIDGE"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.GuiDialogs.GuiDialogsVerifier"
- ],
- "message": "Could not find GUI texture \u0027underworld_logo_off.tga\u0027 at location \u0027MegaTexture\u0027.",
"severity": "Error",
+ "asset": "Cin_DStar_protons.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DStar_protons.alo\u0027",
"context": [
- "IDC_PLAY_FACTION_A_BUTTON_BIG",
- "MegaTexture"
- ],
- "asset": "underworld_logo_off.tga"
+ "Protons_DStar_Xplode"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.GuiDialogs.GuiDialogsVerifier"
- ],
- "message": "Could not find GUI texture \u0027i_button_petro_sliver.tga\u0027 at location \u0027MegaTexture\u0027.",
"severity": "Error",
+ "asset": "Cin_DeathStar_High.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DeathStar_High.alo\u0027",
"context": [
- "IDC_MENU_PETRO_LOGO",
- "MegaTexture"
- ],
- "asset": "i_button_petro_sliver.tga"
+ "Death_Star_Whole"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Default.fx",
+ "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\EV_TIE_LANCET.ALO\u0027.",
+ "context": [
+ "Lancet_Air_Artillery",
+ "DATA\\ART\\MODELS\\EV_TIE_LANCET.ALO"
+ ]
},
{
"id": "FILE00",
- "verifiers": [
- "AET.ModVerify.Verifiers.GuiDialogs.GuiDialogsVerifier"
- ],
- "message": "Could not find GUI texture \u0027underworld_logo_rollover.tga\u0027 at location \u0027MegaTexture\u0027.",
"severity": "Error",
+ "asset": "UB_girder_B.tga",
+ "message": "Could not find texture \u0027UB_girder_B.tga\u0027 for context: [Underworld_Ysalamiri_Cage--\u003EUV_MDU_CAGE.ALO].",
"context": [
- "IDC_PLAY_FACTION_A_BUTTON_BIG",
- "MegaTexture"
- ],
- "asset": "underworld_logo_rollover.tga"
+ "Underworld_Ysalamiri_Cage",
+ "UV_MDU_CAGE.ALO"
+ ]
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_planet_land_forces\u0027 is not connected to a shell component.",
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_bridge.alo",
+ "message": "Unable to find .ALO file \u0027Cin_bridge.alo\u0027",
+ "context": [
+ "Imperial_Bridge"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_desert_ground_dust",
+ "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\UI_SABOTEUR.ALO\u0027",
+ "context": [
+ "Underworld_Saboteur",
+ "DATA\\ART\\MODELS\\UI_SABOTEUR.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_p_proton_torpedo.alo",
+ "message": "Unable to find .ALO file \u0027CIN_p_proton_torpedo.alo\u0027",
+ "context": [
+ "Cin_Proj_Ground_Proton_Torpedo"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Rbel_grey.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Rbel_grey.alo\u0027",
+ "context": [
+ "Cin_Rebel_Grey"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Default.fx",
+ "message": "Shader effect \u0027Default.fx\u0027 not found for model \u0027DATA\\ART\\MODELS\\EV_MDU_SENSORNODE.ALO\u0027.",
+ "context": [
+ "Empire_Offensive_Sensor_Node",
+ "DATA\\ART\\MODELS\\EV_MDU_SENSORNODE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "w_grenade.tga",
+ "message": "Could not find texture \u0027w_grenade.tga\u0027 for context: [Proj_Merc_Concussion_Grenade--\u003EW_GRENADE.ALO].",
+ "context": [
+ "Proj_Merc_Concussion_Grenade",
+ "W_GRENADE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Fire_Huge.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Fire_Huge.alo\u0027",
+ "context": [
+ "Fin_Fire_Huge"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_EI_Palpatine.alo",
+ "message": "Unable to find .ALO file \u0027Cin_EI_Palpatine.alo\u0027",
+ "context": [
+ "Cin_Emperor_Shot_6-9"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_desert_ground_dust",
+ "message": "Proxy particle \u0027p_desert_ground_dust\u0027 not found for model \u0027DATA\\ART\\MODELS\\RI_KYLEKATARN.ALO\u0027",
+ "context": [
+ "Kyle_Katarn",
+ "DATA\\ART\\MODELS\\RI_KYLEKATARN.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "P_heat_small01",
+ "message": "Proxy particle \u0027P_heat_small01\u0027 not found for model \u0027DATA\\ART\\MODELS\\NB_VCH.ALO\u0027",
+ "context": [
+ "Volcanic_Civilian_Spawn_House_Independent_AI",
+ "DATA\\ART\\MODELS\\NB_VCH.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_REb_CelebCharacters.alo",
+ "message": "Unable to find .ALO file \u0027CIN_REb_CelebCharacters.alo\u0027",
+ "context": [
+ "REb_CelebCharacters"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "W_TE_Rock_f_02_b.tga",
+ "message": "Could not find texture \u0027W_TE_Rock_f_02_b.tga\u0027 for context: [TIE_Phantom--\u003EEV_TIE_PHANTOM.ALO].",
+ "context": [
+ "TIE_Phantom",
+ "EV_TIE_PHANTOM.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "CIN_Biker_Row.alo",
+ "message": "Unable to find .ALO file \u0027CIN_Biker_Row.alo\u0027",
+ "context": [
+ "Cin_Biker_Row"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "p_bomb_spin",
+ "message": "Proxy particle \u0027p_bomb_spin\u0027 not found for model \u0027DATA\\ART\\MODELS\\W_THERMAL_DETONATOR_EMPIRE.ALO\u0027",
+ "context": [
+ "TIE_Bomber_Bombing_Run_Bomb",
+ "DATA\\ART\\MODELS\\W_THERMAL_DETONATOR_EMPIRE.ALO"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "Cin_DStar_Dish_close.alo",
+ "message": "Unable to find .ALO file \u0027Cin_DStar_Dish_close.alo\u0027",
+ "context": [
+ "Death_Star_Dish_Close"
+ ]
+ },
+ {
+ "id": "FILE00",
+ "severity": "Error",
+ "asset": "W_droid_steam.alo",
+ "message": "Unable to find .ALO file \u0027W_droid_steam.alo\u0027",
+ "context": [
+ "Prop_Droid_Steam"
+ ]
+ },
+ {
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_planet_land_forces"
+ "asset": "b_planet_left",
+ "message": "The CommandBar component \u0027b_planet_left\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_ground_sell\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_ground_sell"
+ "asset": "encyclopedia_header_text",
+ "message": "The CommandBar component \u0027encyclopedia_header_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_bracket_medium\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_bracket_medium"
+ "asset": "st_control_group",
+ "message": "The CommandBar component \u0027st_control_group\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027b_planet_right\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "b_planet_right"
+ "asset": "tutorial_text_back",
+ "message": "The CommandBar component \u0027tutorial_text_back\u0027 is not connected to a shell component.",
+ "context": []
},
{
"id": "CMDBAR04",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_credit_bar\u0027 is not supported by the game.",
- "severity": "Information",
- "context": [],
- "asset": "g_credit_bar"
+ "severity": "Warning",
+ "asset": "encyclopedia_back",
+ "message": "The CommandBar component \u0027encyclopedia_back\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027zoomed_header_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "zoomed_header_text"
+ "asset": "g_build",
+ "message": "The CommandBar component \u0027g_build\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_space_level_pips\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_space_level_pips"
+ "asset": "generic_collision",
+ "message": "The CommandBar component \u0027generic_collision\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027bribed_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "bribed_icon"
+ "asset": "objective_back",
+ "message": "The CommandBar component \u0027objective_back\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_header_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_header_text"
+ "asset": "st_shields_large",
+ "message": "The CommandBar component \u0027st_shields_large\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tutorial_text_back\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tutorial_text_back"
+ "asset": "zoomed_cost_text",
+ "message": "The CommandBar component \u0027zoomed_cost_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_back\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_back"
+ "asset": "st_bracket_medium",
+ "message": "The CommandBar component \u0027st_bracket_medium\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_text"
+ "asset": "g_smuggled",
+ "message": "The CommandBar component \u0027g_smuggled\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027balance_pip\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "balance_pip"
+ "asset": "skirmish_upgrade",
+ "message": "The CommandBar component \u0027skirmish_upgrade\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027objective_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "objective_text"
+ "asset": "st_ability_icon",
+ "message": "The CommandBar component \u0027st_ability_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027skirmish_upgrade\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "skirmish_upgrade"
+ "asset": "g_bounty_hunter",
+ "message": "The CommandBar component \u0027g_bounty_hunter\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027surface_mod_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "surface_mod_icon"
+ "asset": "radar_blip",
+ "message": "The CommandBar component \u0027radar_blip\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_hero_health\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_hero_health"
+ "asset": "g_weather",
+ "message": "The CommandBar component \u0027g_weather\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027bribe_display\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "bribe_display"
+ "asset": "st_health_medium",
+ "message": "The CommandBar component \u0027st_health_medium\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_build\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_build"
+ "asset": "tutorial_text",
+ "message": "The CommandBar component \u0027tutorial_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027garrison_slot_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "garrison_slot_icon"
+ "asset": "garrison_slot_icon",
+ "message": "The CommandBar component \u0027garrison_slot_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_conflict\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_conflict"
+ "asset": "encyclopedia_right_text",
+ "message": "The CommandBar component \u0027encyclopedia_right_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tooltip_name\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tooltip_name"
+ "asset": "g_planet_ring",
+ "message": "The CommandBar component \u0027g_planet_ring\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027garrison_respawn_counter\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "garrison_respawn_counter"
+ "asset": "tooltip_price",
+ "message": "The CommandBar component \u0027tooltip_price\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_ability_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_ability_icon"
+ "asset": "bribe_display",
+ "message": "The CommandBar component \u0027bribe_display\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_shields_medium\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_shields_medium"
+ "asset": "tooltip_icon_land",
+ "message": "The CommandBar component \u0027tooltip_icon_land\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_health\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_health"
+ "asset": "encyclopedia_center_text",
+ "message": "The CommandBar component \u0027encyclopedia_center_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_weather\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_weather"
+ "asset": "st_bracket_small",
+ "message": "The CommandBar component \u0027st_bracket_small\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_health_medium\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_health_medium"
+ "asset": "g_ground_sell",
+ "message": "The CommandBar component \u0027g_ground_sell\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_power\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_power"
+ "asset": "st_shields_medium",
+ "message": "The CommandBar component \u0027st_shields_medium\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_ground_level_pips\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_ground_level_pips"
+ "asset": "g_corruption_text",
+ "message": "The CommandBar component \u0027g_corruption_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027zoomed_cost_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "zoomed_cost_text"
+ "asset": "st_health_bar",
+ "message": "The CommandBar component \u0027st_health_bar\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027bm_title_4011\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "bm_title_4011"
+ "asset": "b_quick_ref",
+ "message": "The CommandBar component \u0027b_quick_ref\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_planet_name\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_planet_name"
+ "asset": "g_special_ability",
+ "message": "The CommandBar component \u0027g_special_ability\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_shields_large\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_shields_large"
+ "asset": "g_hero_icon",
+ "message": "The CommandBar component \u0027g_hero_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_hero_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_hero_icon"
+ "asset": "st_hero_health",
+ "message": "The CommandBar component \u0027st_hero_health\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027generic_flytext\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "generic_flytext"
+ "asset": "bribed_icon",
+ "message": "The CommandBar component \u0027bribed_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027reinforcement_counter\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "reinforcement_counter"
+ "asset": "g_credit_bar",
+ "message": "The CommandBar component \u0027g_credit_bar\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_planet_value\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_planet_value"
+ "asset": "g_space_icon",
+ "message": "The CommandBar component \u0027g_space_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027radar_blip\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "radar_blip"
+ "asset": "bm_title_4010",
+ "message": "The CommandBar component \u0027bm_title_4010\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_political_control\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_political_control"
+ "asset": "help_back",
+ "message": "The CommandBar component \u0027help_back\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_planet_ring\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_planet_ring"
+ "asset": "g_space_level",
+ "message": "The CommandBar component \u0027g_space_level\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_garrison_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_garrison_icon"
+ "asset": "g_planet_ability",
+ "message": "The CommandBar component \u0027g_planet_ability\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_right_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_right_text"
+ "asset": "st_shields",
+ "message": "The CommandBar component \u0027st_shields\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027b_quick_ref\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "b_quick_ref"
+ "asset": "b_planet_right",
+ "message": "The CommandBar component \u0027b_planet_right\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027objective_back\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "objective_back"
+ "asset": "st_health_large",
+ "message": "The CommandBar component \u0027st_health_large\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_center_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_center_text"
+ "asset": "bm_title_4011",
+ "message": "The CommandBar component \u0027bm_title_4011\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_shields\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_shields"
+ "asset": "g_ground_level_pips",
+ "message": "The CommandBar component \u0027g_ground_level_pips\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_grab_bar\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_grab_bar"
+ "asset": "g_political_control",
+ "message": "The CommandBar component \u0027g_political_control\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_smuggler\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_smuggler"
+ "asset": "st_hero_icon",
+ "message": "The CommandBar component \u0027st_hero_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_enemy_hero\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_enemy_hero"
+ "asset": "objective_text",
+ "message": "The CommandBar component \u0027objective_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027cs_ability_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "cs_ability_text"
+ "asset": "zoomed_text",
+ "message": "The CommandBar component \u0027zoomed_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_cost_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_cost_text"
+ "asset": "garrison_respawn_counter",
+ "message": "The CommandBar component \u0027garrison_respawn_counter\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_planet_ability\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_planet_ability"
+ "asset": "st_grab_bar",
+ "message": "The CommandBar component \u0027st_grab_bar\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_control_group\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_control_group"
+ "asset": "zoomed_center_text",
+ "message": "The CommandBar component \u0027zoomed_center_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027gui_dialog_tooltip\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "gui_dialog_tooltip"
+ "asset": "g_space_level_pips",
+ "message": "The CommandBar component \u0027g_space_level_pips\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027remote_bomb_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "remote_bomb_icon"
+ "asset": "generic_flytext",
+ "message": "The CommandBar component \u0027generic_flytext\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tutorial_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tutorial_text"
+ "asset": "gui_dialog_tooltip",
+ "message": "The CommandBar component \u0027gui_dialog_tooltip\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_space_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_space_icon"
+ "asset": "st_health",
+ "message": "The CommandBar component \u0027st_health\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_bracket_large\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_bracket_large"
+ "asset": "g_planet_name",
+ "message": "The CommandBar component \u0027g_planet_name\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027zoomed_back\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "zoomed_back"
+ "asset": "zoomed_header_text",
+ "message": "The CommandBar component \u0027zoomed_header_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027encyclopedia_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "encyclopedia_icon"
+ "asset": "g_conflict",
+ "message": "The CommandBar component \u0027g_conflict\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027zoomed_right_text\u0027 is not connected to a shell component.",
- "severity": "Warning",
- "context": [],
- "asset": "zoomed_right_text"
+ "id": "CMDBAR03",
+ "severity": "Information",
+ "asset": "g_credit_bar",
+ "message": "The CommandBar component \u0027g_credit_bar\u0027 is not supported by the game.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027b_beacon_t\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "b_beacon_t"
+ "asset": "zoomed_back",
+ "message": "The CommandBar component \u0027zoomed_back\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_bounty_hunter\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_bounty_hunter"
+ "asset": "zoomed_right_text",
+ "message": "The CommandBar component \u0027zoomed_right_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_credit_bar\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_credit_bar"
+ "asset": "st_power",
+ "message": "The CommandBar component \u0027st_power\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_hero\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_hero"
+ "asset": "st_bracket_large",
+ "message": "The CommandBar component \u0027st_bracket_large\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027bm_title_4010\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "bm_title_4010"
+ "asset": "g_ground_icon",
+ "message": "The CommandBar component \u0027g_ground_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_planet_fleet\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_planet_fleet"
+ "asset": "g_planet_land_forces",
+ "message": "The CommandBar component \u0027g_planet_land_forces\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_corruption_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_corruption_icon"
+ "asset": "tooltip_back",
+ "message": "The CommandBar component \u0027tooltip_back\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_smuggled\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_smuggled"
+ "asset": "b_beacon_t",
+ "message": "The CommandBar component \u0027b_beacon_t\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027help_back\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "help_back"
+ "asset": "balance_pip",
+ "message": "The CommandBar component \u0027balance_pip\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_bracket_small\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_bracket_small"
+ "asset": "g_corruption_icon",
+ "message": "The CommandBar component \u0027g_corruption_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027objective_header_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "objective_header_text"
+ "asset": "g_radar_blip",
+ "message": "The CommandBar component \u0027g_radar_blip\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_corruption_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_corruption_text"
+ "asset": "g_hero",
+ "message": "The CommandBar component \u0027g_hero\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_ground_level\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_ground_level"
+ "asset": "encyclopedia_cost_text",
+ "message": "The CommandBar component \u0027encyclopedia_cost_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027lt_weather_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "lt_weather_icon"
+ "asset": "remote_bomb_icon",
+ "message": "The CommandBar component \u0027remote_bomb_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027cs_ability_button\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "cs_ability_button"
+ "asset": "surface_mod_icon",
+ "message": "The CommandBar component \u0027surface_mod_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_radar_view\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_radar_view"
+ "asset": "cs_ability_button",
+ "message": "The CommandBar component \u0027cs_ability_button\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027objective_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "objective_icon"
+ "asset": "encyclopedia_text",
+ "message": "The CommandBar component \u0027encyclopedia_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tooltip_back\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tooltip_back"
+ "asset": "objective_icon",
+ "message": "The CommandBar component \u0027objective_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027zoomed_center_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "zoomed_center_text"
+ "asset": "st_garrison_icon",
+ "message": "The CommandBar component \u0027st_garrison_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_health_bar\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_health_bar"
+ "asset": "g_enemy_hero",
+ "message": "The CommandBar component \u0027g_enemy_hero\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027zoomed_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "zoomed_text"
+ "asset": "g_radar_view",
+ "message": "The CommandBar component \u0027g_radar_view\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027generic_collision\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "generic_collision"
+ "asset": "tactical_sell",
+ "message": "The CommandBar component \u0027tactical_sell\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tooltip_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tooltip_icon"
+ "asset": "cs_ability_text",
+ "message": "The CommandBar component \u0027cs_ability_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_radar_blip\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_radar_blip"
+ "asset": "g_smuggler",
+ "message": "The CommandBar component \u0027g_smuggler\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_hero_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_hero_icon"
+ "asset": "reinforcement_counter",
+ "message": "The CommandBar component \u0027reinforcement_counter\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_space_level\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_space_level"
+ "asset": "g_planet_fleet",
+ "message": "The CommandBar component \u0027g_planet_fleet\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027b_planet_left\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "b_planet_left"
+ "asset": "tooltip_left_text",
+ "message": "The CommandBar component \u0027tooltip_left_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tooltip_icon_land\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tooltip_icon_land"
+ "asset": "objective_header_text",
+ "message": "The CommandBar component \u0027objective_header_text\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_ground_icon\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_ground_icon"
+ "asset": "lt_weather_icon",
+ "message": "The CommandBar component \u0027lt_weather_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tooltip_price\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tooltip_price"
+ "asset": "g_planet_value",
+ "message": "The CommandBar component \u0027g_planet_value\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tooltip_left_text\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tooltip_left_text"
+ "asset": "tooltip_icon",
+ "message": "The CommandBar component \u0027tooltip_icon\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027st_health_large\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "st_health_large"
+ "asset": "g_ground_level",
+ "message": "The CommandBar component \u0027g_ground_level\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027tactical_sell\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "tactical_sell"
+ "asset": "tooltip_name",
+ "message": "The CommandBar component \u0027tooltip_name\u0027 is not connected to a shell component.",
+ "context": []
},
{
- "id": "CMDBAR05",
- "verifiers": [
- "AET.ModVerify.Verifiers.CommandBarVerifier"
- ],
- "message": "The CommandBar component \u0027g_special_ability\u0027 is not connected to a shell component.",
+ "id": "CMDBAR04",
"severity": "Warning",
- "context": [],
- "asset": "g_special_ability"
+ "asset": "encyclopedia_icon",
+ "message": "The CommandBar component \u0027encyclopedia_icon\u0027 is not connected to a shell component.",
+ "context": []
}
]
}
\ No newline at end of file
diff --git a/aet.ico b/src/ModVerify.CliApp/Resources/aet.ico
similarity index 100%
rename from aet.ico
rename to src/ModVerify.CliApp/Resources/aet.ico
diff --git a/src/ModVerify.CliApp/Settings/ModVerifyAppSettings.cs b/src/ModVerify.CliApp/Settings/ModVerifyAppSettings.cs
index e4488a0..add39a5 100644
--- a/src/ModVerify.CliApp/Settings/ModVerifyAppSettings.cs
+++ b/src/ModVerify.CliApp/Settings/ModVerifyAppSettings.cs
@@ -29,7 +29,7 @@ public required VerificationTargetSettings VerificationTargetSettings
init => field = value ?? throw new ArgumentNullException(nameof(value));
}
- public required VerifyPipelineSettings VerifyPipelineSettings
+ public required VerifierServiceSettings VerifierServiceSettings
{
get;
init => field = value ?? throw new ArgumentNullException(nameof(value));
diff --git a/src/ModVerify.CliApp/Settings/SettingsBuilder.cs b/src/ModVerify.CliApp/Settings/SettingsBuilder.cs
index 23a89ff..62bca7a 100644
--- a/src/ModVerify.CliApp/Settings/SettingsBuilder.cs
+++ b/src/ModVerify.CliApp/Settings/SettingsBuilder.cs
@@ -1,5 +1,4 @@
using AET.ModVerify.App.Settings.CommandLine;
-using AET.ModVerify.Pipeline;
using AET.ModVerify.Settings;
using Microsoft.Extensions.DependencyInjection;
using System;
@@ -31,7 +30,7 @@ private AppVerifySettings BuildFromVerifyVerb(VerifyVerbOption verifyOptions)
return new AppVerifySettings(BuildReportSettings())
{
ReportDirectory = GetReportDirectory(),
- VerifyPipelineSettings = new VerifyPipelineSettings
+ VerifierServiceSettings = new VerifierServiceSettings
{
ParallelVerifiers = verifyOptions.Parallel ? 4 : 1,
VerifiersProvider = new DefaultGameVerifiersProvider(),
@@ -97,7 +96,7 @@ private AppBaselineSettings BuildFromCreateBaselineVerb(CreateBaselineVerbOption
{
return new AppBaselineSettings(BuildReportSettings())
{
- VerifyPipelineSettings = new VerifyPipelineSettings
+ VerifierServiceSettings = new VerifierServiceSettings
{
ParallelVerifiers = baselineVerb.Parallel ? 4 : 1,
VerifiersProvider = new DefaultGameVerifiersProvider(),
diff --git a/src/ModVerify.CliApp/TargetSelectors/VerificationTargetSelectorBase.cs b/src/ModVerify.CliApp/TargetSelectors/VerificationTargetSelectorBase.cs
index 68f0f39..0c45986 100644
--- a/src/ModVerify.CliApp/TargetSelectors/VerificationTargetSelectorBase.cs
+++ b/src/ModVerify.CliApp/TargetSelectors/VerificationTargetSelectorBase.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
-using System.Runtime.InteropServices;
using AET.ModVerify.App.GameFinder;
using AET.ModVerify.App.Settings;
using Microsoft.Extensions.DependencyInjection;
diff --git a/src/ModVerify.CliApp/Utilities/ExtensionMethods.cs b/src/ModVerify.CliApp/Utilities/ExtensionMethods.cs
index fc07469..5871311 100644
--- a/src/ModVerify.CliApp/Utilities/ExtensionMethods.cs
+++ b/src/ModVerify.CliApp/Utilities/ExtensionMethods.cs
@@ -1,8 +1,9 @@
-using System.Diagnostics.CodeAnalysis;
-using AET.ModVerify.App.Settings.CommandLine;
+using AET.ModVerify.App.Settings.CommandLine;
using AnakinRaW.ApplicationBase.Environment;
using PG.StarWarsGame.Engine;
using PG.StarWarsGame.Infrastructure.Games;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
namespace AET.ModVerify.App.Utilities;
@@ -21,10 +22,6 @@ public GameEngineType Opposite()
}
}
- public static GameEngineType ToEngineType(this GameType type)
- {
- return (GameEngineType)(int)type;
- }
extension(ApplicationEnvironment modVerifyEnvironment)
{
public bool IsUpdatable()
@@ -39,6 +36,19 @@ public bool IsUpdatable([NotNullWhen(true)] out UpdatableApplicationEnvironment?
}
}
+ public static GameEngineType ToEngineType(this GameType type)
+ {
+ return (GameEngineType)(int)type;
+ }
+
+ public static GameLocations MaskUsername(this GameLocations targetLocation)
+ {
+ return new GameLocations(
+ targetLocation.ModPaths.Select(PathUtilities.MaskUsername).ToList(),
+ PathUtilities.MaskUsername(targetLocation.GamePath),
+ targetLocation.FallbackPaths.Select(PathUtilities.MaskUsername).ToList());
+ }
+
public static bool LaunchedWithoutArguments(this BaseModVerifyOptions options)
{
if (options is VerifyVerbOption verifyOptions)
diff --git a/src/ModVerify.CliApp/Utilities/ModVerifyConsoleUtilities.cs b/src/ModVerify.CliApp/Utilities/ModVerifyConsoleUtilities.cs
index b9ebff0..9f9962b 100644
--- a/src/ModVerify.CliApp/Utilities/ModVerifyConsoleUtilities.cs
+++ b/src/ModVerify.CliApp/Utilities/ModVerifyConsoleUtilities.cs
@@ -2,7 +2,7 @@
using Figgle;
using System;
using System.Collections.Generic;
-using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
namespace AET.ModVerify.App.Utilities;
diff --git a/src/ModVerify/DefaultGameVerifiersProvider.cs b/src/ModVerify/DefaultGameVerifiersProvider.cs
new file mode 100644
index 0000000..d7ce226
--- /dev/null
+++ b/src/ModVerify/DefaultGameVerifiersProvider.cs
@@ -0,0 +1,28 @@
+using AET.ModVerify.Settings;
+using AET.ModVerify.Verifiers;
+using AET.ModVerify.Verifiers.CommandBar;
+using AET.ModVerify.Verifiers.Engine;
+using AET.ModVerify.Verifiers.GameObjects;
+using AET.ModVerify.Verifiers.GuiDialogs;
+using AET.ModVerify.Verifiers.SfxEvents;
+using PG.StarWarsGame.Engine;
+using System;
+using System.Collections.Generic;
+
+namespace AET.ModVerify;
+
+public sealed class DefaultGameVerifiersProvider : IGameVerifiersProvider
+{
+ public IEnumerable GetVerifiers(
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider)
+ {
+ //yield break;
+ yield return new SfxEventVerifier(gameEngine, settings, serviceProvider);
+ yield return new HardcodedAssetsVerifier(gameEngine, settings, serviceProvider);
+ yield return new GuiDialogsVerifier(gameEngine, settings, serviceProvider);
+ yield return new GameObjectTypeVerifier(gameEngine, settings, serviceProvider);
+ yield return new CommandBarVerifier(gameEngine, settings, serviceProvider);
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/GameVerificationException.cs b/src/ModVerify/GameVerificationException.cs
index dba312b..a6ada92 100644
--- a/src/ModVerify/GameVerificationException.cs
+++ b/src/ModVerify/GameVerificationException.cs
@@ -7,8 +7,11 @@ namespace AET.ModVerify;
public sealed class GameVerificationException : Exception
{
+ ///
+ public override string Message => ErrorMessage;
+
public IReadOnlyCollection Errors { get; }
-
+
private string ErrorMessage
{
get
@@ -23,14 +26,11 @@ private string ErrorMessage
}
} = null;
- ///
- public override string Message => ErrorMessage;
-
- public GameVerificationException(VerificationError error) : this([error])
+ internal GameVerificationException(VerificationError error) : this([error])
{
}
- public GameVerificationException(IEnumerable errors)
+ internal GameVerificationException(IEnumerable errors)
{
if (errors is null)
throw new ArgumentNullException(nameof(errors));
diff --git a/src/ModVerify/Pipeline/GameVerifierPipelineStep.cs b/src/ModVerify/GameVerifierPipelineStep.cs
similarity index 91%
rename from src/ModVerify/Pipeline/GameVerifierPipelineStep.cs
rename to src/ModVerify/GameVerifierPipelineStep.cs
index e83cb25..b1f45b8 100644
--- a/src/ModVerify/Pipeline/GameVerifierPipelineStep.cs
+++ b/src/ModVerify/GameVerifierPipelineStep.cs
@@ -1,16 +1,16 @@
-using AET.ModVerify.Verifiers;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using AET.ModVerify.Progress;
+using AET.ModVerify.Verifiers;
using AnakinRaW.CommonUtilities.SimplePipeline;
using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
using AnakinRaW.CommonUtilities.SimplePipeline.Steps;
using Microsoft.Extensions.Logging;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using AET.ModVerify.Pipeline.Progress;
-namespace AET.ModVerify.Pipeline;
+namespace AET.ModVerify;
-public sealed class GameVerifierPipelineStep(
+internal sealed class GameVerifierPipelineStep(
GameVerifier verifier,
IServiceProvider serviceProvider)
: PipelineStep(serviceProvider), IProgressStep
diff --git a/src/ModVerify/GameVerifierService.cs b/src/ModVerify/GameVerifierService.cs
new file mode 100644
index 0000000..f6d8f07
--- /dev/null
+++ b/src/ModVerify/GameVerifierService.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using AET.ModVerify.Progress;
+using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
+using AET.ModVerify.Reporting.Suppressions;
+using AET.ModVerify.Settings;
+using PG.StarWarsGame.Engine;
+
+namespace AET.ModVerify;
+
+internal sealed class GameVerifierService(IServiceProvider serviceProvider) : IGameVerifierService
+{
+ public async Task VerifyAsync(
+ VerificationTarget verificationTarget,
+ VerifierServiceSettings settings,
+ VerificationBaseline baseline,
+ SuppressionList suppressions,
+ IVerifyProgressReporter? progressReporter,
+ IGameEngineInitializationReporter? engineInitializationReporter,
+ CancellationToken token = default)
+ {
+ if (verificationTarget == null)
+ throw new ArgumentNullException(nameof(verificationTarget));
+ if (settings == null)
+ throw new ArgumentNullException(nameof(settings));
+
+ using var pipeline = new GameVerifyPipeline(
+ verificationTarget,
+ settings,
+ serviceProvider,
+ baseline,
+ suppressions,
+ progressReporter,
+ engineInitializationReporter);
+
+ VerificationCompletionStatus completionStatus;
+ var start = DateTime.UtcNow;
+
+ try
+ {
+ await pipeline.RunAsync(token).ConfigureAwait(false);
+ completionStatus = VerificationCompletionStatus.Completed;
+ }
+ catch (OperationCanceledException)
+ {
+ completionStatus = settings.FailFastSettings.IsFailFast
+ ? VerificationCompletionStatus.CompletedFailFast
+ : VerificationCompletionStatus.Cancelled;
+ }
+
+ var duration = DateTime.UtcNow - start;
+
+ return new VerificationResult
+ {
+ Duration = duration,
+ Errors = pipeline.Errors,
+ Status = completionStatus,
+ Target = verificationTarget,
+ UsedBaseline = baseline,
+ UsedSuppressions = suppressions,
+ Verifiers = pipeline.Verifiers
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Pipeline/GameVerifyPipeline.cs b/src/ModVerify/GameVerifyPipeline.cs
similarity index 55%
rename from src/ModVerify/Pipeline/GameVerifyPipeline.cs
rename to src/ModVerify/GameVerifyPipeline.cs
index 493aa8c..4a7e0fb 100644
--- a/src/ModVerify/Pipeline/GameVerifyPipeline.cs
+++ b/src/ModVerify/GameVerifyPipeline.cs
@@ -1,63 +1,69 @@
-using AET.ModVerify.Pipeline.Progress;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using AET.ModVerify.Progress;
using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
+using AET.ModVerify.Reporting.Engine;
+using AET.ModVerify.Reporting.Suppressions;
using AET.ModVerify.Settings;
+using AET.ModVerify.Utilities;
using AET.ModVerify.Verifiers;
+using AET.ModVerify.Verifiers.Engine;
+using AET.ModVerify.Verifiers.Utilities;
using AnakinRaW.CommonUtilities.SimplePipeline;
using AnakinRaW.CommonUtilities.SimplePipeline.Runners;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PG.StarWarsGame.Engine;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using AET.ModVerify.Utilities;
-using Microsoft.Extensions.DependencyInjection;
-namespace AET.ModVerify.Pipeline;
+namespace AET.ModVerify;
-public sealed class GameVerifyPipeline : StepRunnerPipelineBase
+internal sealed class GameVerifyPipeline : StepRunnerPipelineBase
{
private readonly List _verifiers = [];
+ private readonly List _errors = [];
private readonly List _verificationSteps = [];
- private readonly ConcurrentGameEngineErrorReporter _engineErrorReporter = new();
-
+
+ private readonly GameEngineErrorCollection _engineErrorReporter = new();
private readonly VerificationTarget _verificationTarget;
- private readonly VerifyPipelineSettings _pipelineSettings;
- private readonly IVerifyProgressReporter _progressReporter;
+ private readonly VerifierServiceSettings _serviceSettings;
+ private readonly IVerifyProgressReporter? _progressReporter;
private readonly IGameEngineInitializationReporter? _engineInitializationReporter;
- private readonly IPetroglyphStarWarsGameEngineService _gameEngineService;
- private readonly ILogger? _logger;
- private AggregatedVerifyProgressReporter? _aggregatedVerifyProgressReporter;
+ private readonly VerificationBaseline _baseline;
+ private readonly SuppressionList _suppressions;
+
+ internal IReadOnlyCollection Errors => [.._errors];
+
+ internal IReadOnlyCollection Verifiers => [.. _verifiers];
- public IReadOnlyCollection FilteredErrors { get; private set; } = [];
- public VerificationBaseline Baseline { get; }
- public SuppressionList Suppressions { get; }
+ private AggregatedVerifyProgressReporter? _aggregatedVerifyProgressReporter;
public GameVerifyPipeline(
VerificationTarget verificationTarget,
- VerifyPipelineSettings pipelineSettings,
- IVerifyProgressReporter progressReporter,
- IGameEngineInitializationReporter? engineInitializationReporter,
+ VerifierServiceSettings serviceSettings,
+ IServiceProvider serviceProvider,
VerificationBaseline baseline,
SuppressionList suppressions,
- IServiceProvider serviceProvider) : base(serviceProvider)
+ IVerifyProgressReporter? progressReporter = null,
+ IGameEngineInitializationReporter? engineInitializationReporter = null)
+ : base(serviceProvider)
{
- Baseline = baseline ?? throw new ArgumentNullException(nameof(baseline));
- Suppressions = suppressions ?? throw new ArgumentNullException(nameof(suppressions));
_verificationTarget = verificationTarget ?? throw new ArgumentNullException(nameof(verificationTarget));
- _pipelineSettings = pipelineSettings ?? throw new ArgumentNullException(nameof(pipelineSettings));
- _progressReporter = progressReporter ?? throw new ArgumentNullException(nameof(progressReporter));
+ _serviceSettings = serviceSettings ?? throw new ArgumentNullException(nameof(serviceSettings));
+ _baseline = baseline ?? throw new ArgumentNullException(nameof(baseline));
+ _suppressions = suppressions ?? throw new ArgumentNullException(nameof(suppressions));
+ _progressReporter = progressReporter;
_engineInitializationReporter = engineInitializationReporter;
- _gameEngineService = serviceProvider.GetRequiredService();
- _logger = serviceProvider.GetService()?.CreateLogger(GetType());
- FailFast = pipelineSettings.FailFastSettings.IsFailFast;
+ FailFast = serviceSettings.FailFastSettings.IsFailFast;
}
-
+
protected override AsyncStepRunner CreateRunner()
{
- var requestedRunnerCount = _pipelineSettings.ParallelVerifiers;
+ var requestedRunnerCount = _serviceSettings.ParallelVerifiers;
return requestedRunnerCount switch
{
< 0 or > 64 => throw new InvalidOperationException(
@@ -70,12 +76,14 @@ protected override AsyncStepRunner CreateRunner()
protected override async Task PrepareCoreAsync(CancellationToken token)
{
_verifiers.Clear();
+ _errors.Clear();
IStarWarsGameEngine gameEngine;
try
{
- gameEngine = await _gameEngineService.InitializeAsync(
+ var engineService = ServiceProvider.GetRequiredService();
+ gameEngine = await engineService.InitializeAsync(
_verificationTarget.Engine,
_verificationTarget.Location,
_engineErrorReporter,
@@ -85,38 +93,43 @@ protected override async Task PrepareCoreAsync(CancellationToken token)
}
catch (Exception e)
{
- _logger?.LogError(e, "Creating game engine failed: {Message}", e.Message);
+ Logger?.LogError(e, "Creating game engine failed: {Message}", e.Message);
throw;
}
- AddStep(new GameEngineErrorCollector(_engineErrorReporter, gameEngine, _pipelineSettings.GameVerifySettings, ServiceProvider));
+ AddStep(new GameEngineErrorCollector(_engineErrorReporter, gameEngine, _serviceSettings.GameVerifySettings, ServiceProvider));
- foreach (var gameVerificationStep in CreateVerificationSteps(gameEngine))
+ foreach (var gameVerificationStep in CreateVerifiers(gameEngine))
AddStep(gameVerificationStep);
}
protected override void OnExecuteStarted()
{
Logger?.LogInformation("Running game verifiers...");
- _aggregatedVerifyProgressReporter = new AggregatedVerifyProgressReporter(_progressReporter, _verificationSteps);
- _progressReporter.Report(0.0, $"Verifying {_verificationTarget.Name}...", VerifyProgress.ProgressType, default);
+ if (_progressReporter is not null)
+ {
+ _aggregatedVerifyProgressReporter = new AggregatedVerifyProgressReporter(_progressReporter, _verificationSteps);
+ _progressReporter.Report(0.0, $"Verifying {_verificationTarget.Name}...",
+ VerifyProgress.ProgressType, default);
+ }
}
protected override void OnExecuteCompleted()
{
Logger?.LogInformation("Game verifiers finished.");
- FilteredErrors = GetReportableErrors(_verifiers.SelectMany(s => s.VerifyErrors)).ToList();
- _progressReporter.Report(1.0, $"Finished Verifying {_verificationTarget.Name}", VerifyProgress.ProgressType, default);
+ _errors.AddRange(GetReportableErrors(_verifiers.SelectMany(s => s.VerifyErrors)));
+ _progressReporter?.Report(1.0, $"Finished Verifying {_verificationTarget.Name}",
+ VerifyProgress.ProgressType, default);
}
protected override void OnRunnerExecutionError(object sender, StepRunnerErrorEventArgs e)
{
if (FailFast && e.Exception is GameVerificationException verificationException)
{
- var minSeverity = _pipelineSettings.FailFastSettings.MinumumSeverity;
+ var minSeverity = _serviceSettings.FailFastSettings.MinumumSeverity;
var ignoreError = verificationException.Errors
.Where(error => error.Severity >= minSeverity)
- .All(error => Baseline.Contains(error) || Suppressions.Suppresses(error));
+ .All(error => _baseline.Contains(error) || _suppressions.Suppresses(error));
if (ignoreError)
return;
}
@@ -128,6 +141,14 @@ protected override IEnumerable GetFailedSteps(IEnumerable steps)
return base.GetFailedSteps(steps).Where(s => s.Error is not GameVerificationException);
}
+ protected override void DisposeResources()
+ {
+ base.DisposeResources();
+ _engineErrorReporter.Clear();
+ _aggregatedVerifyProgressReporter?.Dispose();
+ _aggregatedVerifyProgressReporter = null;
+ }
+
private void AddStep(GameVerifier verifier)
{
var verificationStep = new GameVerifierPipelineStep(verifier, ServiceProvider);
@@ -141,18 +162,13 @@ private IEnumerable GetReportableErrors(IEnumerable CreateVerificationSteps(IStarWarsGameEngine engine)
- {
- return _pipelineSettings.VerifiersProvider
- .GetVerifiers(engine, _pipelineSettings.GameVerifySettings, ServiceProvider);
+ return errors.ApplyBaseline(_baseline).ApplySuppressions(_suppressions);
}
- protected override void DisposeResources()
+ private IEnumerable CreateVerifiers(IStarWarsGameEngine engine)
{
- base.DisposeResources();
- _aggregatedVerifyProgressReporter?.Dispose();
+ return _serviceSettings.VerifiersProvider
+ .GetVerifiers(engine, _serviceSettings.GameVerifySettings, ServiceProvider)
+ .Distinct(NameBasedEqualityComparer.Instance);
}
}
\ No newline at end of file
diff --git a/src/ModVerify/IGameVerifierService.cs b/src/ModVerify/IGameVerifierService.cs
new file mode 100644
index 0000000..c814779
--- /dev/null
+++ b/src/ModVerify/IGameVerifierService.cs
@@ -0,0 +1,22 @@
+using System.Threading;
+using System.Threading.Tasks;
+using AET.ModVerify.Progress;
+using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
+using AET.ModVerify.Reporting.Suppressions;
+using AET.ModVerify.Settings;
+using PG.StarWarsGame.Engine;
+
+namespace AET.ModVerify;
+
+public interface IGameVerifierService
+{
+ Task VerifyAsync(
+ VerificationTarget verificationTarget,
+ VerifierServiceSettings settings,
+ VerificationBaseline baseline,
+ SuppressionList suppressions,
+ IVerifyProgressReporter? progressReporter,
+ IGameEngineInitializationReporter? engineInitializationReporter,
+ CancellationToken token = default);
+}
\ No newline at end of file
diff --git a/src/ModVerify/Pipeline/IGameVerifiersProvider.cs b/src/ModVerify/IGameVerifiersProvider.cs
similarity index 81%
rename from src/ModVerify/Pipeline/IGameVerifiersProvider.cs
rename to src/ModVerify/IGameVerifiersProvider.cs
index 930afa6..c34c98d 100644
--- a/src/ModVerify/Pipeline/IGameVerifiersProvider.cs
+++ b/src/ModVerify/IGameVerifiersProvider.cs
@@ -4,12 +4,12 @@
using AET.ModVerify.Verifiers;
using PG.StarWarsGame.Engine;
-namespace AET.ModVerify.Pipeline;
+namespace AET.ModVerify;
public interface IGameVerifiersProvider
{
IEnumerable GetVerifiers(
- IStarWarsGameEngine database,
+ IStarWarsGameEngine gameEngine,
GameVerifySettings settings,
IServiceProvider serviceProvider);
}
\ No newline at end of file
diff --git a/src/ModVerify/ModVerify.csproj b/src/ModVerify/ModVerify.csproj
index f1415bc..96656cc 100644
--- a/src/ModVerify/ModVerify.csproj
+++ b/src/ModVerify/ModVerify.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netstandard2.1
+ netstandard2.0;netstandard2.1;net10.0
AlamoEngineTools.ModVerify
AET.ModVerify
AET.ModVerify
@@ -10,33 +10,25 @@
ModVerify Core
AET.ModVerify
- Provides interfaces and classes to verify Empire at War / Forces of Corruption game modifications.
+ A library that contains classes and methods to verify Empire at War / Forces of Corruption game modifications.
alamo,petroglyph,glyphx
true
true
-
-
-
true
snupkg
-
-
-
-
-
+
-
-
-
-
+
+
+
@@ -50,9 +42,4 @@
-
-
-
-
-
diff --git a/src/ModVerify/ModVerify.csproj.DotSettings b/src/ModVerify/ModVerify.csproj.DotSettings
index fcd6f14..d3b37e3 100644
--- a/src/ModVerify/ModVerify.csproj.DotSettings
+++ b/src/ModVerify/ModVerify.csproj.DotSettings
@@ -1,4 +1,12 @@
- True
+ True
+ True
+ True
+ True
+ False
+ False
+ True
+ True
True
- True
\ No newline at end of file
+ False
+ False
\ No newline at end of file
diff --git a/src/ModVerify/ModVerifyServiceExtensions.cs b/src/ModVerify/ModVerifyServiceExtensions.cs
index 8b46960..04567e7 100644
--- a/src/ModVerify/ModVerifyServiceExtensions.cs
+++ b/src/ModVerify/ModVerifyServiceExtensions.cs
@@ -1,12 +1,20 @@
-using AET.ModVerify.Verifiers;
+using AET.ModVerify.Verifiers.Caching;
using Microsoft.Extensions.DependencyInjection;
namespace AET.ModVerify;
public static class ModVerifyServiceExtensions
{
- public static IServiceCollection RegisterVerifierCache(this IServiceCollection serviceCollection)
+ extension(IServiceCollection serviceCollection)
{
- return serviceCollection.AddSingleton(sp => new AlreadyVerifiedCache(sp));
+ public IServiceCollection AddModVerify()
+ {
+ return serviceCollection.AddSingleton(sp => new GameVerifierService(sp));
+ }
+
+ public IServiceCollection RegisterVerifierCache()
+ {
+ return serviceCollection.AddSingleton(new AlreadyVerifiedCache());
+ }
}
}
\ No newline at end of file
diff --git a/src/ModVerify/Pipeline/DefaultGameVerifiersProvider.cs b/src/ModVerify/Pipeline/DefaultGameVerifiersProvider.cs
deleted file mode 100644
index 26b3893..0000000
--- a/src/ModVerify/Pipeline/DefaultGameVerifiersProvider.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using AET.ModVerify.Settings;
-using AET.ModVerify.Verifiers;
-using AET.ModVerify.Verifiers.GuiDialogs;
-using PG.StarWarsGame.Engine;
-
-namespace AET.ModVerify.Pipeline;
-
-public sealed class DefaultGameVerifiersProvider : IGameVerifiersProvider
-{
- public IEnumerable GetVerifiers(
- IStarWarsGameEngine database,
- GameVerifySettings settings,
- IServiceProvider serviceProvider)
- {
- yield return new ReferencedModelsVerifier(database, settings, serviceProvider);
- yield return new DuplicateNameFinder(database, settings, serviceProvider);
- yield return new AudioFilesVerifier(database, settings, serviceProvider);
- yield return new GuiDialogsVerifier(database, settings, serviceProvider);
- //yield return new CommandBarVerifier(database, settings, serviceProvider);
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Pipeline/Progress/AggregatedVerifyProgressReporter.cs b/src/ModVerify/Progress/AggregatedVerifyProgressReporter.cs
similarity index 95%
rename from src/ModVerify/Pipeline/Progress/AggregatedVerifyProgressReporter.cs
rename to src/ModVerify/Progress/AggregatedVerifyProgressReporter.cs
index cfdae25..1dbf538 100644
--- a/src/ModVerify/Pipeline/Progress/AggregatedVerifyProgressReporter.cs
+++ b/src/ModVerify/Progress/AggregatedVerifyProgressReporter.cs
@@ -1,8 +1,8 @@
-using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
-using System;
+using System;
using System.Collections.Generic;
+using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
-namespace AET.ModVerify.Pipeline.Progress;
+namespace AET.ModVerify.Progress;
internal class AggregatedVerifyProgressReporter(
IVerifyProgressReporter progressReporter,
diff --git a/src/ModVerify/Pipeline/Progress/IVerifyProgressReporter.cs b/src/ModVerify/Progress/IVerifyProgressReporter.cs
similarity index 76%
rename from src/ModVerify/Pipeline/Progress/IVerifyProgressReporter.cs
rename to src/ModVerify/Progress/IVerifyProgressReporter.cs
index e63e0f9..99c2141 100644
--- a/src/ModVerify/Pipeline/Progress/IVerifyProgressReporter.cs
+++ b/src/ModVerify/Progress/IVerifyProgressReporter.cs
@@ -1,5 +1,5 @@
using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
-namespace AET.ModVerify.Pipeline.Progress;
+namespace AET.ModVerify.Progress;
public interface IVerifyProgressReporter : IProgressReporter;
\ No newline at end of file
diff --git a/src/ModVerify/Pipeline/Progress/VerifyProgress.cs b/src/ModVerify/Progress/VerifyProgress.cs
similarity index 84%
rename from src/ModVerify/Pipeline/Progress/VerifyProgress.cs
rename to src/ModVerify/Progress/VerifyProgress.cs
index a18f3d3..aa5f2f2 100644
--- a/src/ModVerify/Pipeline/Progress/VerifyProgress.cs
+++ b/src/ModVerify/Progress/VerifyProgress.cs
@@ -1,6 +1,6 @@
using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
-namespace AET.ModVerify.Pipeline.Progress;
+namespace AET.ModVerify.Progress;
public static class VerifyProgress
{
diff --git a/src/ModVerify/Pipeline/Progress/VerifyProgressInfo.cs b/src/ModVerify/Progress/VerifyProgressInfo.cs
similarity index 74%
rename from src/ModVerify/Pipeline/Progress/VerifyProgressInfo.cs
rename to src/ModVerify/Progress/VerifyProgressInfo.cs
index cadeb0d..b7c8b3d 100644
--- a/src/ModVerify/Pipeline/Progress/VerifyProgressInfo.cs
+++ b/src/ModVerify/Progress/VerifyProgressInfo.cs
@@ -1,4 +1,4 @@
-namespace AET.ModVerify.Pipeline.Progress;
+namespace AET.ModVerify.Progress;
public struct VerifyProgressInfo
{
diff --git a/src/ModVerify/Reporting/Baseline/BaselineVerificationTarget.cs b/src/ModVerify/Reporting/Baseline/BaselineVerificationTarget.cs
new file mode 100644
index 0000000..ca77fa8
--- /dev/null
+++ b/src/ModVerify/Reporting/Baseline/BaselineVerificationTarget.cs
@@ -0,0 +1,12 @@
+using PG.StarWarsGame.Engine;
+
+namespace AET.ModVerify.Reporting.Baseline;
+
+public sealed record BaselineVerificationTarget
+{
+ public required GameEngineType Engine { get; init; }
+ public required string Name { get; init; }
+ public GameLocations? Location { get; init; } // Optional compared to Verification Target
+ public string? Version { get; init; }
+ public bool IsGame { get; init; }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Baseline/InvalidBaselineException.cs b/src/ModVerify/Reporting/Baseline/InvalidBaselineException.cs
new file mode 100644
index 0000000..58e180e
--- /dev/null
+++ b/src/ModVerify/Reporting/Baseline/InvalidBaselineException.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace AET.ModVerify.Reporting.Baseline;
+
+public sealed class InvalidBaselineException : Exception
+{
+ internal InvalidBaselineException(string message) : base(message)
+ {
+ }
+
+ internal InvalidBaselineException(string? message, Exception? inner) : base(message, inner)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonBaselineParser.cs b/src/ModVerify/Reporting/Baseline/Json/JsonBaselineParser.cs
similarity index 95%
rename from src/ModVerify/Reporting/Json/JsonBaselineParser.cs
rename to src/ModVerify/Reporting/Baseline/Json/JsonBaselineParser.cs
index 669ef53..a8ba53c 100644
--- a/src/ModVerify/Reporting/Json/JsonBaselineParser.cs
+++ b/src/ModVerify/Reporting/Baseline/Json/JsonBaselineParser.cs
@@ -2,7 +2,7 @@
using System.IO;
using System.Text.Json;
-namespace AET.ModVerify.Reporting.Json;
+namespace AET.ModVerify.Reporting.Baseline.Json;
internal static class JsonBaselineParser
{
diff --git a/src/ModVerify/Reporting/Json/JsonBaselineSchema.cs b/src/ModVerify/Reporting/Baseline/Json/JsonBaselineSchema.cs
similarity index 97%
rename from src/ModVerify/Reporting/Json/JsonBaselineSchema.cs
rename to src/ModVerify/Reporting/Baseline/Json/JsonBaselineSchema.cs
index 12e3705..cf4513a 100644
--- a/src/ModVerify/Reporting/Json/JsonBaselineSchema.cs
+++ b/src/ModVerify/Reporting/Baseline/Json/JsonBaselineSchema.cs
@@ -7,9 +7,9 @@
using Json.Schema;
using Json.Schema.Keywords;
-namespace AET.ModVerify.Reporting.Json;
+namespace AET.ModVerify.Reporting.Baseline.Json;
-public static class JsonBaselineSchema
+internal static class JsonBaselineSchema
{
private static readonly JsonSchema Schema;
private static readonly EvaluationOptions EvaluationOptions;
diff --git a/src/ModVerify/Reporting/Json/JsonVerificationBaseline.cs b/src/ModVerify/Reporting/Baseline/Json/JsonVerificationBaseline.cs
similarity index 87%
rename from src/ModVerify/Reporting/Json/JsonVerificationBaseline.cs
rename to src/ModVerify/Reporting/Baseline/Json/JsonVerificationBaseline.cs
index 0d9a1b7..13d9b56 100644
--- a/src/ModVerify/Reporting/Json/JsonVerificationBaseline.cs
+++ b/src/ModVerify/Reporting/Baseline/Json/JsonVerificationBaseline.cs
@@ -1,9 +1,10 @@
-using System;
+using AET.ModVerify.Reporting.Json;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
-namespace AET.ModVerify.Reporting.Json;
+namespace AET.ModVerify.Reporting.Baseline.Json;
internal class JsonVerificationBaseline
{
@@ -32,8 +33,8 @@ public JsonVerificationBaseline(VerificationBaseline baseline)
[JsonConstructor]
private JsonVerificationBaseline(
JsonVerificationTarget target,
- Version version,
- VerificationSeverity minimumSeverity,
+ Version version,
+ VerificationSeverity minimumSeverity,
IEnumerable errors)
{
Target = target;
diff --git a/src/ModVerify/Reporting/VerificationBaseline.cs b/src/ModVerify/Reporting/Baseline/VerificationBaseline.cs
similarity index 94%
rename from src/ModVerify/Reporting/VerificationBaseline.cs
rename to src/ModVerify/Reporting/Baseline/VerificationBaseline.cs
index 3f9c274..80f95b8 100644
--- a/src/ModVerify/Reporting/VerificationBaseline.cs
+++ b/src/ModVerify/Reporting/Baseline/VerificationBaseline.cs
@@ -6,13 +6,14 @@
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
+using AET.ModVerify.Reporting.Baseline.Json;
using AET.ModVerify.Reporting.Json;
-namespace AET.ModVerify.Reporting;
+namespace AET.ModVerify.Reporting.Baseline;
public sealed class VerificationBaseline : IReadOnlyCollection
{
- public static readonly Version LatestVersion = new(2, 1);
+ public static readonly Version LatestVersion = new(2, 2);
public static readonly string LatestVersionString = LatestVersion.ToString(2);
public static readonly VerificationBaseline Empty = new(VerificationSeverity.Information, [], null);
@@ -60,7 +61,6 @@ public void ToJson(Stream stream)
{
JsonSerializer.Serialize(stream, new JsonVerificationBaseline(this), ModVerifyJsonSettings.JsonSettings);
}
-
public Task ToJsonAsync(Stream stream)
{
return JsonSerializer.SerializeAsync(stream, new JsonVerificationBaseline(this), ModVerifyJsonSettings.JsonSettings);
diff --git a/src/ModVerify/Reporting/BaselineVerificationTarget.cs b/src/ModVerify/Reporting/BaselineVerificationTarget.cs
deleted file mode 100644
index 6e21ddd..0000000
--- a/src/ModVerify/Reporting/BaselineVerificationTarget.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Text;
-using PG.StarWarsGame.Engine;
-
-namespace AET.ModVerify.Reporting;
-
-public sealed class BaselineVerificationTarget
-{
- public required GameEngineType Engine { get; init; }
- public required string Name { get; init; }
- public GameLocations? Location { get; init; } // Optional compared to Verification Target
- public string? Version { get; init; }
- public bool IsGame { get; init; }
-
- public override string ToString()
- {
- var sb = new StringBuilder($"[Name={Name};EngineType={Engine};IsGame={IsGame};");
- if (!string.IsNullOrEmpty(Version)) sb.Append($"Version={Version};");
- if (Location is not null)
- sb.Append($"Location={Location};");
- sb.Append(']');
- return sb.ToString();
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/ConcurrentGameEngineErrorReporter.cs b/src/ModVerify/Reporting/ConcurrentGameEngineErrorReporter.cs
deleted file mode 100644
index 3130547..0000000
--- a/src/ModVerify/Reporting/ConcurrentGameEngineErrorReporter.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using PG.StarWarsGame.Engine.ErrorReporting;
-
-namespace AET.ModVerify.Reporting;
-
-public sealed class ConcurrentGameEngineErrorReporter : GameEngineErrorReporter, IGameEngineErrorCollection
-{
- private readonly ConcurrentBag _xmlErrors = new();
- private readonly ConcurrentBag _initializationErrors = new();
- private readonly ConcurrentBag _asserts = new();
-
- public IEnumerable XmlErrors => _xmlErrors.ToList();
-
- public IEnumerable InitializationErrors => _initializationErrors.ToList();
-
- public IEnumerable Asserts => _asserts.ToList();
-
- public override void Report(XmlError error)
- {
- _xmlErrors.Add(error);
- }
-
- public override void Report(InitializationError error)
- {
- _initializationErrors.Add(error);
- }
-
- public override void Assert(EngineAssert assert)
- {
- _asserts.Add(assert);
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/Engine/EngineErrorReporterBase.cs b/src/ModVerify/Reporting/Engine/EngineErrorReporterBase.cs
similarity index 59%
rename from src/ModVerify/Reporting/Reporters/Engine/EngineErrorReporterBase.cs
rename to src/ModVerify/Reporting/Engine/EngineErrorReporterBase.cs
index 455212d..f8c7cd2 100644
--- a/src/ModVerify/Reporting/Reporters/Engine/EngineErrorReporterBase.cs
+++ b/src/ModVerify/Reporting/Engine/EngineErrorReporterBase.cs
@@ -1,16 +1,30 @@
using System;
using System.Collections.Generic;
+using AET.ModVerify.Verifiers;
using AnakinRaW.CommonUtilities;
using PG.StarWarsGame.Engine.IO;
-namespace AET.ModVerify.Reporting.Reporters.Engine;
+namespace AET.ModVerify.Reporting.Engine;
-internal abstract class EngineErrorReporterBase(IGameRepository gameRepository, IServiceProvider serviceProvider)
+internal abstract class EngineErrorReporterBase : IGameVerifierInfo
{
- protected readonly IGameRepository GameRepository = gameRepository ?? throw new ArgumentNullException(nameof(gameRepository));
- protected readonly IServiceProvider ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
+ protected readonly IGameRepository GameRepository;
+ protected readonly IServiceProvider ServiceProvider;
- public abstract string Name { get; }
+ public IGameVerifierInfo? Parent => null;
+
+ public IReadOnlyList VerifierChain { get; }
+
+ public string Name => GetType().FullName;
+
+ public abstract string FriendlyName { get; }
+
+ protected EngineErrorReporterBase(IGameRepository gameRepository, IServiceProvider serviceProvider)
+ {
+ GameRepository = gameRepository ?? throw new ArgumentNullException(nameof(gameRepository));
+ ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
+ VerifierChain = [this];
+ }
public IEnumerable GetErrors(IEnumerable errors)
{
@@ -18,7 +32,7 @@ public IEnumerable GetErrors(IEnumerable errors)
{
var errorData = CreateError(error);
yield return new VerificationError(
- errorData.Identifier, errorData.Message, [Name], errorData.Context, errorData.Asset, errorData.Severity);
+ errorData.Identifier, errorData.Message, this, errorData.Context, errorData.Asset, errorData.Severity);
}
}
diff --git a/src/ModVerify/Reporting/Reporters/Engine/GameAssertErrorReporter.cs b/src/ModVerify/Reporting/Engine/GameAssertErrorReporter.cs
similarity index 79%
rename from src/ModVerify/Reporting/Reporters/Engine/GameAssertErrorReporter.cs
rename to src/ModVerify/Reporting/Engine/GameAssertErrorReporter.cs
index 6c5fb17..0c8c633 100644
--- a/src/ModVerify/Reporting/Reporters/Engine/GameAssertErrorReporter.cs
+++ b/src/ModVerify/Reporting/Engine/GameAssertErrorReporter.cs
@@ -5,19 +5,24 @@
using PG.StarWarsGame.Engine.ErrorReporting;
using PG.StarWarsGame.Engine.IO;
-namespace AET.ModVerify.Reporting.Reporters.Engine;
+namespace AET.ModVerify.Reporting.Engine;
internal sealed class GameAssertErrorReporter(IGameRepository gameRepository, IServiceProvider serviceProvider)
: EngineErrorReporterBase(gameRepository, serviceProvider)
{
- public override string Name => "GameAsserts";
+ public override string FriendlyName => "Game Engine Asserts";
protected override ErrorData CreateError(EngineAssert assert)
{
var context = new List();
context.AddRange(assert.Context);
context.Add($"location='{GetLocation(assert)}'");
- return new ErrorData(GetIdFromError(assert.Kind), assert.Message, context, assert.Value, VerificationSeverity.Warning);
+ return new ErrorData(
+ GetIdFromError(assert.Kind),
+ assert.Message,
+ context,
+ assert.Value,
+ VerificationSeverity.Warning);
}
private static string GetLocation(EngineAssert assert)
@@ -41,6 +46,7 @@ private static string GetIdFromError(EngineAssertKind assertKind)
EngineAssertKind.ValueOutOfRange => VerifierErrorCodes.AssertValueOutOfRange,
EngineAssertKind.InvalidValue => VerifierErrorCodes.AssertValueInvalid,
EngineAssertKind.FileNotFound => VerifierErrorCodes.FileNotFound,
+ EngineAssertKind.DuplicateEntry => VerifierErrorCodes.Duplicate,
_ => throw new ArgumentOutOfRangeException(nameof(assertKind), assertKind, null)
};
}
diff --git a/src/ModVerify/Reporting/Engine/GameEngineErrorCollection.cs b/src/ModVerify/Reporting/Engine/GameEngineErrorCollection.cs
new file mode 100644
index 0000000..8cb67c0
--- /dev/null
+++ b/src/ModVerify/Reporting/Engine/GameEngineErrorCollection.cs
@@ -0,0 +1,53 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using PG.StarWarsGame.Engine.ErrorReporting;
+using PG.StarWarsGame.Files.XML.ErrorHandling;
+
+namespace AET.ModVerify.Reporting.Engine;
+
+public sealed class GameEngineErrorCollection : IGameEngineErrorCollection, IGameEngineErrorReporter
+{
+ private readonly ConcurrentBag _xmlErrors = new();
+ private readonly ConcurrentBag _initializationErrors = new();
+ private readonly ConcurrentBag _asserts = new();
+
+ public IEnumerable XmlErrors => _xmlErrors.ToList();
+
+ public IEnumerable InitializationErrors => _initializationErrors.ToList();
+
+ public IEnumerable Asserts => _asserts.ToList();
+
+ void IXmlParserErrorReporter.Report(XmlError error)
+ {
+ _xmlErrors.Add(error);
+ }
+
+ void IGameEngineErrorReporter.Report(InitializationError error)
+ {
+ _initializationErrors.Add(error);
+ }
+
+ void IGameEngineErrorReporter.Assert(EngineAssert assert)
+ {
+ _asserts.Add(assert);
+ }
+
+ internal void Clear()
+ {
+#if !NETFRAMEWORK && !NETSTANDARD2_0
+ _xmlErrors.Clear();
+ _initializationErrors.Clear();
+ _asserts.Clear();
+#else
+ ClearUnsafe(_xmlErrors);
+ ClearUnsafe(_initializationErrors);
+ ClearUnsafe(_asserts);
+
+ static void ClearUnsafe(ConcurrentBag bag)
+ {
+ while (bag.TryTake(out _)) ;
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/IGameEngineErrorCollection.cs b/src/ModVerify/Reporting/Engine/IGameEngineErrorCollection.cs
similarity index 76%
rename from src/ModVerify/Reporting/IGameEngineErrorCollection.cs
rename to src/ModVerify/Reporting/Engine/IGameEngineErrorCollection.cs
index 14d59d9..286d047 100644
--- a/src/ModVerify/Reporting/IGameEngineErrorCollection.cs
+++ b/src/ModVerify/Reporting/Engine/IGameEngineErrorCollection.cs
@@ -1,7 +1,8 @@
using System.Collections.Generic;
using PG.StarWarsGame.Engine.ErrorReporting;
+using PG.StarWarsGame.Files.XML.ErrorHandling;
-namespace AET.ModVerify.Reporting;
+namespace AET.ModVerify.Reporting.Engine;
public interface IGameEngineErrorCollection
{
diff --git a/src/ModVerify/Reporting/Reporters/Engine/InitializationErrorReporter.cs b/src/ModVerify/Reporting/Engine/InitializationErrorReporter.cs
similarity index 84%
rename from src/ModVerify/Reporting/Reporters/Engine/InitializationErrorReporter.cs
rename to src/ModVerify/Reporting/Engine/InitializationErrorReporter.cs
index fc44c66..e46db1a 100644
--- a/src/ModVerify/Reporting/Reporters/Engine/InitializationErrorReporter.cs
+++ b/src/ModVerify/Reporting/Engine/InitializationErrorReporter.cs
@@ -3,12 +3,12 @@
using PG.StarWarsGame.Engine.ErrorReporting;
using PG.StarWarsGame.Engine.IO;
-namespace AET.ModVerify.Reporting.Reporters.Engine;
+namespace AET.ModVerify.Reporting.Engine;
internal sealed class InitializationErrorReporter(IGameRepository gameRepository, IServiceProvider serviceProvider)
: EngineErrorReporterBase(gameRepository, serviceProvider)
{
- public override string Name => "InitializationErrors";
+ public override string FriendlyName => "Initialization Errors";
protected override ErrorData CreateError(InitializationError error)
{
diff --git a/src/ModVerify/Reporting/Reporters/Engine/XmlParseErrorReporter.cs b/src/ModVerify/Reporting/Engine/XmlParseErrorReporter.cs
similarity index 88%
rename from src/ModVerify/Reporting/Reporters/Engine/XmlParseErrorReporter.cs
rename to src/ModVerify/Reporting/Engine/XmlParseErrorReporter.cs
index 094a701..9548ad4 100644
--- a/src/ModVerify/Reporting/Reporters/Engine/XmlParseErrorReporter.cs
+++ b/src/ModVerify/Reporting/Engine/XmlParseErrorReporter.cs
@@ -4,18 +4,17 @@
using AET.ModVerify.Utilities;
using AET.ModVerify.Verifiers;
using Microsoft.Extensions.DependencyInjection;
-using PG.StarWarsGame.Engine.ErrorReporting;
using PG.StarWarsGame.Engine.IO;
using PG.StarWarsGame.Files.XML.ErrorHandling;
-namespace AET.ModVerify.Reporting.Reporters.Engine;
+namespace AET.ModVerify.Reporting.Engine;
internal sealed class XmlParseErrorReporter(IGameRepository gameRepository, IServiceProvider serviceProvider) :
EngineErrorReporterBase(gameRepository, serviceProvider)
{
private readonly IFileSystem _fileSystem = serviceProvider.GetRequiredService();
- public override string Name => "XMLError";
+ public override string FriendlyName => "XML Errors";
protected override ErrorData CreateError(XmlError error)
{
@@ -29,7 +28,8 @@ protected override ErrorData CreateError(XmlError error)
var context = new List
{
- strippedFileName
+ $"Parser: {error.Parser.Name}",
+ $"File: {strippedFileName}"
};
var xmlElement = error.Element;
@@ -75,6 +75,8 @@ private static VerificationSeverity GetSeverityFromError(XmlParseErrorKind xmlEr
XmlParseErrorKind.DataBeforeHeader => VerificationSeverity.Information,
XmlParseErrorKind.MissingNode => VerificationSeverity.Critical,
XmlParseErrorKind.UnknownNode => VerificationSeverity.Information,
+ XmlParseErrorKind.TagHasElements => VerificationSeverity.Warning,
+ XmlParseErrorKind.UnexceptedElementName => VerificationSeverity.Information,
_ => VerificationSeverity.Warning
};
}
@@ -94,6 +96,8 @@ private static string GetIdFromError(XmlParseErrorKind xmlErrorErrorKind)
XmlParseErrorKind.DataBeforeHeader => VerifierErrorCodes.XmlDataBeforeHeader,
XmlParseErrorKind.MissingNode => VerifierErrorCodes.XmlMissingNode,
XmlParseErrorKind.UnknownNode => VerifierErrorCodes.XmlUnsupportedTag,
+ XmlParseErrorKind.TagHasElements => VerifierErrorCodes.XmlElementsInTag,
+ XmlParseErrorKind.UnexceptedElementName => VerifierErrorCodes.XmlUnexceptedElementName,
_ => throw new ArgumentOutOfRangeException(nameof(xmlErrorErrorKind), xmlErrorErrorKind, null)
};
}
diff --git a/src/ModVerify/Reporting/IVerificationReporter.cs b/src/ModVerify/Reporting/IVerificationReporter.cs
deleted file mode 100644
index 8b8664e..0000000
--- a/src/ModVerify/Reporting/IVerificationReporter.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace AET.ModVerify.Reporting;
-
-public interface IVerificationReporter
-{
- public Task ReportAsync(IReadOnlyCollection errors);
-}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/InvalidBaselineException.cs b/src/ModVerify/Reporting/InvalidBaselineException.cs
deleted file mode 100644
index 37ab9c8..0000000
--- a/src/ModVerify/Reporting/InvalidBaselineException.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace AET.ModVerify.Reporting;
-
-public sealed class InvalidBaselineException : Exception
-{
- public InvalidBaselineException(string message) : base(message)
- {
- }
-
- public InvalidBaselineException(string? message, Exception? inner) : base(message, inner)
- {
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonAggregatedVerificationError.cs b/src/ModVerify/Reporting/Json/JsonAggregatedVerificationError.cs
new file mode 100644
index 0000000..a60b3de
--- /dev/null
+++ b/src/ModVerify/Reporting/Json/JsonAggregatedVerificationError.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace AET.ModVerify.Reporting.Json;
+
+internal class JsonAggregatedVerificationError : JsonVerificationErrorBase
+{
+ [JsonPropertyName("contexts")]
+ [JsonPropertyOrder(99)]
+ public IEnumerable> Contexts { get; }
+
+ [JsonConstructor]
+ public JsonAggregatedVerificationError(
+ string id,
+ IReadOnlyList? verifierChain,
+ string message,
+ VerificationSeverity severity,
+ IEnumerable>? contexts,
+ string? asset) : base(id, severity, asset, message, verifierChain)
+ {
+ Contexts = contexts ?? [];
+ }
+
+ public JsonAggregatedVerificationError(
+ VerificationError error,
+ IEnumerable> contexts,
+ bool verbose = false)
+ : base(error, verbose)
+ {
+ Contexts = contexts;
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonVerificationError.cs b/src/ModVerify/Reporting/Json/JsonVerificationError.cs
index 55f7b92..8094058 100644
--- a/src/ModVerify/Reporting/Json/JsonVerificationError.cs
+++ b/src/ModVerify/Reporting/Json/JsonVerificationError.cs
@@ -1,53 +1,30 @@
using System.Collections.Generic;
+using System.Linq;
using System.Text.Json.Serialization;
namespace AET.ModVerify.Reporting.Json;
-internal class JsonVerificationError
+internal class JsonVerificationError : JsonVerificationErrorBase
{
- [JsonPropertyName("id")]
- public string Id { get; }
-
- [JsonPropertyName("verifiers")]
- public IReadOnlyList VerifierChain { get; }
-
- [JsonPropertyName("message")]
- public string Message { get; }
-
- [JsonPropertyName("severity")]
- [JsonConverter(typeof(JsonStringEnumConverter))]
- public VerificationSeverity Severity { get; }
-
[JsonPropertyName("context")]
+ [JsonPropertyOrder(99)]
public IEnumerable ContextEntries { get; }
- [JsonPropertyName("asset")]
- public string Asset { get; }
-
[JsonConstructor]
- private JsonVerificationError(
- string id,
- IReadOnlyList? verifierChain,
+ public JsonVerificationError(
+ string id,
+ VerificationSeverity severity,
+ string? asset,
string message,
- VerificationSeverity severity,
- IEnumerable? contextEntries,
- string? asset)
+ IReadOnlyList? verifierChain,
+ IEnumerable contextEntries) : base(id, severity, asset, message, verifierChain)
{
- Id = id;
- VerifierChain = verifierChain ?? [];
- Message = message;
- Severity = severity;
- ContextEntries = contextEntries ?? [];
- Asset = asset ?? string.Empty;
+ ContextEntries = contextEntries;
}
- public JsonVerificationError(VerificationError error)
+ public JsonVerificationError(VerificationError error, bool verbose = false)
+ : base(error, verbose)
{
- Id = error.Id;
- VerifierChain = error.VerifierChain;
- Message = error.Message;
- Severity = error.Severity;
- ContextEntries = error.ContextEntries;
- Asset = error.Asset;
+ ContextEntries = error.ContextEntries.Any() ? error.ContextEntries : [];
}
}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonVerificationErrorBase.cs b/src/ModVerify/Reporting/Json/JsonVerificationErrorBase.cs
new file mode 100644
index 0000000..b7aa298
--- /dev/null
+++ b/src/ModVerify/Reporting/Json/JsonVerificationErrorBase.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json.Serialization;
+
+namespace AET.ModVerify.Reporting.Json;
+
+[JsonDerivedType(typeof(JsonVerificationError))]
+[JsonDerivedType(typeof(JsonAggregatedVerificationError))]
+internal abstract class JsonVerificationErrorBase
+{
+ [JsonPropertyName("id")]
+ public string Id { get; }
+
+ [JsonPropertyName("severity")]
+ [JsonConverter(typeof(JsonStringEnumConverter))]
+ public VerificationSeverity Severity { get; }
+
+ [JsonPropertyName("asset")]
+ public string Asset { get; }
+
+ [JsonPropertyName("message")]
+ public string Message { get; }
+
+ [JsonPropertyName("verifiers")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public IReadOnlyList? VerifierChain { get; }
+
+ protected JsonVerificationErrorBase(string id,
+ VerificationSeverity severity,
+ string? asset,
+ string message,
+ IReadOnlyList? verifierChain)
+ {
+ Id = id;
+ VerifierChain = verifierChain;
+ Message = message;
+ Severity = severity;
+ Asset = asset ?? string.Empty;
+ }
+ protected JsonVerificationErrorBase(VerificationError error, bool verbose = false)
+ {
+ Id = error.Id;
+ VerifierChain = verbose ? error.VerifierChain.Select(x => x.Name).ToList() : null;
+ Message = error.Message;
+ Severity = error.Severity;
+ Asset = error.Asset;
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonVerificationReport.cs b/src/ModVerify/Reporting/Json/JsonVerificationReport.cs
index 6ebb926..d10d18f 100644
--- a/src/ModVerify/Reporting/Json/JsonVerificationReport.cs
+++ b/src/ModVerify/Reporting/Json/JsonVerificationReport.cs
@@ -3,8 +3,11 @@
namespace AET.ModVerify.Reporting.Json;
-internal class JsonVerificationReport(IEnumerable errors)
+internal class JsonVerificationReport
{
+ [JsonPropertyName("metadata")]
+ public required JsonVerificationReportMetadata Metadata { get; init; }
+
[JsonPropertyName("errors")]
- public IEnumerable Errors { get; } = errors;
+ public required IEnumerable Errors { get; init; }
}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonVerificationReportMetadata.cs b/src/ModVerify/Reporting/Json/JsonVerificationReportMetadata.cs
new file mode 100644
index 0000000..7e3b90e
--- /dev/null
+++ b/src/ModVerify/Reporting/Json/JsonVerificationReportMetadata.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace AET.ModVerify.Reporting.Json;
+
+internal class JsonVerificationReportMetadata
+{
+ [JsonPropertyName("status")]
+ [JsonConverter(typeof(JsonStringEnumConverter))]
+ public VerificationCompletionStatus Status { get; init; }
+
+ [JsonPropertyName("target")]
+ public JsonVerificationTarget Target { get; init; }
+
+ [JsonPropertyName("time")]
+ public string Date { get; } = DateTime.Now.ToString("s");
+
+ [JsonPropertyName("duration")]
+ public string Duration { get; init; }
+
+ [JsonPropertyName("verifiers")]
+ public IReadOnlyCollection Verifiers { get; init; }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonVerificationTarget.cs b/src/ModVerify/Reporting/Json/JsonVerificationTarget.cs
index 9495456..ccde4b7 100644
--- a/src/ModVerify/Reporting/Json/JsonVerificationTarget.cs
+++ b/src/ModVerify/Reporting/Json/JsonVerificationTarget.cs
@@ -1,11 +1,12 @@
using System.Text.Json.Serialization;
+using AET.ModVerify.Reporting.Baseline;
using PG.StarWarsGame.Engine;
namespace AET.ModVerify.Reporting.Json;
internal class JsonVerificationTarget
{
- [JsonPropertyName("name")]
+ [JsonPropertyName("name")]
public string Name { get; }
[JsonPropertyName("engine")]
@@ -17,7 +18,7 @@ internal class JsonVerificationTarget
[JsonPropertyName("version")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- public string? Version{ get; }
+ public string? Version { get; }
[JsonPropertyName("location")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -25,9 +26,9 @@ internal class JsonVerificationTarget
[JsonConstructor]
private JsonVerificationTarget(
- string name,
- string? version,
- JsonGameLocation? location,
+ string name,
+ string? version,
+ JsonGameLocation? location,
GameEngineType engine,
bool isGame)
{
@@ -38,6 +39,15 @@ private JsonVerificationTarget(
IsGame = isGame;
}
+ public JsonVerificationTarget(VerificationTarget target)
+ {
+ Name = target.Name;
+ Version = target.Version;
+ Engine = target.Engine;
+ Location = new JsonGameLocation(target.Location);
+ IsGame = target.IsGame;
+ }
+
public JsonVerificationTarget(BaselineVerificationTarget target)
{
Name = target.Name;
diff --git a/src/ModVerify/Reporting/Reporters/ConsoleReporter.cs b/src/ModVerify/Reporting/Reporters/Console/ConsoleReporter.cs
similarity index 62%
rename from src/ModVerify/Reporting/Reporters/ConsoleReporter.cs
rename to src/ModVerify/Reporting/Reporters/Console/ConsoleReporter.cs
index dbee50d..5266550 100644
--- a/src/ModVerify/Reporting/Reporters/ConsoleReporter.cs
+++ b/src/ModVerify/Reporting/Reporters/Console/ConsoleReporter.cs
@@ -2,25 +2,21 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using AET.ModVerify.Reporting.Settings;
namespace AET.ModVerify.Reporting.Reporters;
-internal class ConsoleReporter(
- ReporterSettings settings,
- bool summaryOnly,
- IServiceProvider serviceProvider) :
- ReporterBase(settings, serviceProvider)
+internal class ConsoleReporter(ConsoleReporterSettings settings, IServiceProvider serviceProvider) :
+ ReporterBase(settings, serviceProvider)
{
- public override Task ReportAsync(IReadOnlyCollection errors)
+ public override Task ReportAsync(VerificationResult verificationResult)
{
- var filteredErrors = FilteredErrors(errors).OrderByDescending(x => x.Severity).ToList();
- PrintErrorStats(errors, filteredErrors);
+ var filteredErrors = FilteredErrors(verificationResult.Errors).OrderByDescending(x => x.Severity).ToList();
+ PrintErrorStats(verificationResult, filteredErrors);
Console.WriteLine();
return Task.CompletedTask;
}
- private void PrintErrorStats(IReadOnlyCollection errors, List filteredErrors)
+ private void PrintErrorStats(VerificationResult verificationResult, List filteredErrors)
{
Console.WriteLine();
Console.WriteLine();
@@ -28,9 +24,9 @@ private void PrintErrorStats(IReadOnlyCollection errors, List
Console.WriteLine(" Error Report ");
Console.WriteLine("***********************");
Console.WriteLine();
- if (errors.Count == 0)
+ if (verificationResult.Errors.Count == 0)
{
- if (summaryOnly)
+ if (Settings.SummaryOnly)
{
Console.WriteLine("No errors found.");
}
@@ -44,21 +40,21 @@ private void PrintErrorStats(IReadOnlyCollection errors, List
return;
}
- Console.WriteLine($"TOTAL Verification Errors: {errors.Count}");
+ Console.WriteLine($"TOTAL Verification Errors: {verificationResult.Errors.Count}");
- var groupedBySeverity = errors.GroupBy(x => x.Severity);
+ var groupedBySeverity = verificationResult.Errors.GroupBy(x => x.Severity);
foreach (var group in groupedBySeverity)
Console.WriteLine($" Severity {group.Key}: {group.Count()}");
Console.WriteLine();
if (filteredErrors.Count == 0)
{
- if (errors.Count != 0)
+ if (verificationResult.Errors.Count != 0)
Console.WriteLine("Some errors are not displayed to the console. Please check the created output files.");
return;
}
- if (summaryOnly)
+ if (Settings.SummaryOnly)
return;
Console.WriteLine($"Below the list of errors with severity '{Settings.MinimumReportSeverity}' or higher:");
diff --git a/src/ModVerify/Reporting/Reporters/Console/ConsoleReporterSettings.cs b/src/ModVerify/Reporting/Reporters/Console/ConsoleReporterSettings.cs
new file mode 100644
index 0000000..4dc2a77
--- /dev/null
+++ b/src/ModVerify/Reporting/Reporters/Console/ConsoleReporterSettings.cs
@@ -0,0 +1,6 @@
+namespace AET.ModVerify.Reporting.Reporters;
+
+public sealed record ConsoleReporterSettings : ReporterSettings
+{
+ public bool SummaryOnly { get; init; }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/ExtensionMethods.cs b/src/ModVerify/Reporting/Reporters/ExtensionMethods.cs
new file mode 100644
index 0000000..480e956
--- /dev/null
+++ b/src/ModVerify/Reporting/Reporters/ExtensionMethods.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace AET.ModVerify.Reporting.Reporters;
+
+public static class ExtensionMethods
+{
+ extension(IVerificationReporter)
+ {
+ public static IVerificationReporter CreateJson(IServiceProvider serviceProvider)
+ {
+ return IVerificationReporter.CreateJson(new JsonReporterSettings(), serviceProvider);
+ }
+
+ public static IVerificationReporter CreateJson(JsonReporterSettings settings, IServiceProvider serviceProvider)
+ {
+ return new JsonReporter(settings, serviceProvider);
+ }
+
+ public static IVerificationReporter CreateText(IServiceProvider serviceProvider)
+ {
+ return IVerificationReporter.CreateText(new TextFileReporterSettings(), serviceProvider);
+ }
+
+ public static IVerificationReporter CreateText(TextFileReporterSettings settings, IServiceProvider serviceProvider)
+ {
+ return new TextFileReporter(settings, serviceProvider);
+ }
+
+ public static IVerificationReporter CreateConsole(IServiceProvider serviceProvider, bool summaryOnly = false)
+ {
+ var settings = new ConsoleReporterSettings
+ {
+ MinimumReportSeverity = VerificationSeverity.Error,
+ SummaryOnly = summaryOnly
+ };
+ return IVerificationReporter.CreateConsole(settings, serviceProvider);
+ }
+
+ public static IVerificationReporter CreateConsole(ConsoleReporterSettings settings, IServiceProvider serviceProvider)
+ {
+ return new ConsoleReporter(settings, serviceProvider);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/FileBasedReporter.cs b/src/ModVerify/Reporting/Reporters/FileBasedReporter.cs
index 1057bfa..4c60121 100644
--- a/src/ModVerify/Reporting/Reporters/FileBasedReporter.cs
+++ b/src/ModVerify/Reporting/Reporters/FileBasedReporter.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.IO.Abstractions;
-using AET.ModVerify.Reporting.Settings;
using Microsoft.Extensions.DependencyInjection;
namespace AET.ModVerify.Reporting.Reporters;
diff --git a/src/ModVerify/Reporting/Settings/FileBasedReporterSettings.cs b/src/ModVerify/Reporting/Reporters/FileBasedReporterSettings.cs
similarity index 85%
rename from src/ModVerify/Reporting/Settings/FileBasedReporterSettings.cs
rename to src/ModVerify/Reporting/Reporters/FileBasedReporterSettings.cs
index 759a6ab..aa468fc 100644
--- a/src/ModVerify/Reporting/Settings/FileBasedReporterSettings.cs
+++ b/src/ModVerify/Reporting/Reporters/FileBasedReporterSettings.cs
@@ -1,6 +1,6 @@
using System;
-namespace AET.ModVerify.Reporting.Settings;
+namespace AET.ModVerify.Reporting.Reporters;
public record FileBasedReporterSettings : ReporterSettings
{
diff --git a/src/ModVerify/Reporting/Reporters/IVerificationReporter.cs b/src/ModVerify/Reporting/Reporters/IVerificationReporter.cs
new file mode 100644
index 0000000..5ce7a65
--- /dev/null
+++ b/src/ModVerify/Reporting/Reporters/IVerificationReporter.cs
@@ -0,0 +1,8 @@
+using System.Threading.Tasks;
+
+namespace AET.ModVerify.Reporting.Reporters;
+
+public interface IVerificationReporter
+{
+ public Task ReportAsync(VerificationResult verificationResult);
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/JSON/JsonReporter.cs b/src/ModVerify/Reporting/Reporters/JSON/JsonReporter.cs
index 348fbb1..ac11bb6 100644
--- a/src/ModVerify/Reporting/Reporters/JSON/JsonReporter.cs
+++ b/src/ModVerify/Reporting/Reporters/JSON/JsonReporter.cs
@@ -4,21 +4,92 @@
using System.Text.Json;
using System.Threading.Tasks;
using AET.ModVerify.Reporting.Json;
+using AET.ModVerify.Verifiers;
+using AnakinRaW.CommonUtilities.FileSystem.Validation;
-namespace AET.ModVerify.Reporting.Reporters.JSON;
+namespace AET.ModVerify.Reporting.Reporters;
internal class JsonReporter(JsonReporterSettings settings, IServiceProvider serviceProvider)
: FileBasedReporter(settings, serviceProvider)
{
- public const string FileName = "VerificationResult.json";
-
- public override async Task ReportAsync(IReadOnlyCollection errors)
+ public override async Task ReportAsync(VerificationResult verificationResult)
{
- var report = new JsonVerificationReport(errors.Select(x => new JsonVerificationError(x)));
+ var report = CreateJsonReport(verificationResult);
+ var fileName = CreateFileName(verificationResult);
+
#if NET || NETSTANDARD2_1
await
#endif
- using var fs = CreateFile(FileName);
+ using var fs = CreateFile(fileName);
await JsonSerializer.SerializeAsync(fs, report, ModVerifyJsonSettings.JsonSettings);
}
+
+ private JsonVerificationReport CreateJsonReport(VerificationResult result)
+ {
+ IEnumerable errors;
+ if (Settings.AggregateResults)
+ {
+ errors = result.Errors
+ .OrderByDescending(x => x.Severity)
+ .ThenBy(x => x.Id)
+ .GroupBy(x => new GroupKey(x.Asset, x.Id, x.VerifierChain))
+ .Select, JsonVerificationErrorBase>(g =>
+ {
+ var first = g.First();
+ var contexts = g.Select(x => x.ContextEntries).ToList();
+ if (contexts.Count == 1)
+ return new JsonVerificationError(first, Settings.Verbose);
+ return new JsonAggregatedVerificationError(first, contexts, Settings.Verbose);
+ });
+ }
+ else
+ {
+ errors = result.Errors
+ .OrderByDescending(x => x.Severity)
+ .ThenBy(x => x.Id)
+ .Select(x => new JsonVerificationError(x, Settings.Verbose));
+ }
+
+ return new JsonVerificationReport
+ {
+ Metadata = new JsonVerificationReportMetadata
+ {
+ Target = new JsonVerificationTarget(result.Target),
+ Duration = result.Duration.ToString("g"),
+ Status = result.Status,
+ Verifiers = result.Verifiers.Select(x => x.Name).ToList()
+ },
+ Errors = errors
+ };
+ }
+
+ private static string CreateFileName(VerificationResult result)
+ {
+ var fileName = $"VerificationResult_{result.Target.Name}.json";
+ if (CurrentSystemFileNameValidator.Instance.IsValidFileName(fileName) is FileNameValidationResult.Valid)
+ return fileName;
+ // I don't think there is a safe/secure way to re-encode the file name, if it's not valid using the plain target name.
+ // Thus, we simply use the current date and accept the fact that files may get overwritten for different targets.
+ return $"VerificationResult_{DateTime.Now:yyyy_mm_dd}.json";
+
+ }
+
+ private readonly record struct GroupKey(string Asset, string Id, IReadOnlyList VerifierChain)
+ {
+ public bool Equals(GroupKey other)
+ {
+ return Asset == other.Asset
+ && Id == other.Id
+ && VerifierChainEqualityComparer.Instance.Equals(VerifierChain, other.VerifierChain);
+ }
+
+ public override int GetHashCode()
+ {
+ var hashCode = new HashCode();
+ hashCode.Add(Asset);
+ hashCode.Add(Id);
+ hashCode.Add(VerifierChain, VerifierChainEqualityComparer.Instance);
+ return hashCode.ToHashCode();
+ }
+ }
}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/JSON/JsonReporterSettings.cs b/src/ModVerify/Reporting/Reporters/JSON/JsonReporterSettings.cs
index 4207b36..a2503ed 100644
--- a/src/ModVerify/Reporting/Reporters/JSON/JsonReporterSettings.cs
+++ b/src/ModVerify/Reporting/Reporters/JSON/JsonReporterSettings.cs
@@ -1,5 +1,5 @@
-using AET.ModVerify.Reporting.Settings;
-
-namespace AET.ModVerify.Reporting.Reporters.JSON;
-
-public record JsonReporterSettings : FileBasedReporterSettings;
\ No newline at end of file
+namespace AET.ModVerify.Reporting.Reporters;
+public record JsonReporterSettings : FileBasedReporterSettings
+{
+ public bool AggregateResults { get; init; }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/ReporterBase.cs b/src/ModVerify/Reporting/Reporters/ReporterBase.cs
index df444e3..47cafc5 100644
--- a/src/ModVerify/Reporting/Reporters/ReporterBase.cs
+++ b/src/ModVerify/Reporting/Reporters/ReporterBase.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using AET.ModVerify.Reporting.Settings;
namespace AET.ModVerify.Reporting.Reporters;
@@ -12,7 +11,7 @@ public abstract class ReporterBase(T settings, IServiceProvider serviceProvid
protected T Settings { get; } = settings ?? throw new ArgumentNullException(nameof(settings));
- public abstract Task ReportAsync(IReadOnlyCollection errors);
+ public abstract Task ReportAsync(VerificationResult verificationResult);
protected IEnumerable FilteredErrors(IReadOnlyCollection errors)
{
diff --git a/src/ModVerify/Reporting/Settings/ReporterSettings.cs b/src/ModVerify/Reporting/Reporters/ReporterSettings.cs
similarity index 61%
rename from src/ModVerify/Reporting/Settings/ReporterSettings.cs
rename to src/ModVerify/Reporting/Reporters/ReporterSettings.cs
index ef33857..6cd56d3 100644
--- a/src/ModVerify/Reporting/Settings/ReporterSettings.cs
+++ b/src/ModVerify/Reporting/Reporters/ReporterSettings.cs
@@ -1,6 +1,7 @@
-namespace AET.ModVerify.Reporting.Settings;
+namespace AET.ModVerify.Reporting.Reporters;
public record ReporterSettings
{
public VerificationSeverity MinimumReportSeverity { get; init; } = VerificationSeverity.Information;
+ public bool Verbose { get; init; }
}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/Text/TextFileReporter.cs b/src/ModVerify/Reporting/Reporters/Text/TextFileReporter.cs
index cfc5c91..f3e8126 100644
--- a/src/ModVerify/Reporting/Reporters/Text/TextFileReporter.cs
+++ b/src/ModVerify/Reporting/Reporters/Text/TextFileReporter.cs
@@ -1,49 +1,56 @@
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text;
using System.Threading.Tasks;
-namespace AET.ModVerify.Reporting.Reporters.Text;
+namespace AET.ModVerify.Reporting.Reporters;
-internal class TextFileReporter(TextFileReporterSettings settings, IServiceProvider serviceProvider) : FileBasedReporter(settings, serviceProvider)
+internal sealed class TextFileReporter(TextFileReporterSettings settings, IServiceProvider serviceProvider)
+ : FileBasedReporter(settings, serviceProvider)
{
internal const string SingleReportFileName = "VerificationResult.txt";
- public override async Task ReportAsync(IReadOnlyCollection errors)
+ public override async Task ReportAsync(VerificationResult verificationResult)
{
if (Settings.SplitIntoFiles)
- await ReportByVerifier(errors);
+ await ReportByVerifier(verificationResult);
else
- await ReportWhole(errors);
+ await ReportWhole(verificationResult);
}
- private async Task ReportWhole(IReadOnlyCollection errors)
+ private async Task ReportWhole(VerificationResult result)
{
#if NET || NETSTANDARD2_1
await
#endif
using var streamWriter = new StreamWriter(CreateFile(SingleReportFileName));
- foreach (var error in errors.OrderBy(x => x.Id))
+ await WriteHeader(result.Target, DateTime.Now, null, streamWriter);
+
+ foreach (var error in result.Errors.OrderBy(x => x.Id))
await WriteError(error, streamWriter);
}
- private async Task ReportByVerifier(IReadOnlyCollection errors)
+ private async Task ReportByVerifier(VerificationResult result)
{
- var grouped = errors.GroupBy(x => x.VerifierChain.Last());
+ var time = DateTime.Now;
+ var grouped = result.Errors.GroupBy(x => x.VerifierChain.Last().Name);
foreach (var group in grouped)
- await ReportToSingleFile(group);
+ await ReportToSingleFile(group, result.Target, time);
}
- private async Task ReportToSingleFile(IGrouping group)
+ private async Task ReportToSingleFile(IGrouping group, VerificationTarget target, DateTime time)
{
- var fileName = $"{GetVerifierName(group.Key)}Results.txt";
+ var fileName = $"{GetVerifierName(group.Key)}_Results.txt";
#if NET || NETSTANDARD2_1
await
#endif
using var streamWriter = new StreamWriter(CreateFile(fileName));
+
+ await WriteHeader(target, time, group.Key, streamWriter);
+
foreach (var error in group.OrderBy(x => x.Id))
await WriteError(error, streamWriter);
}
@@ -52,23 +59,41 @@ private static string GetVerifierName(string verifierTypeName)
{
var typeNameSpan = verifierTypeName.AsSpan();
var nameIndex = typeNameSpan.LastIndexOf('.');
+ var isSupType = typeNameSpan.IndexOf('/') > -1;
- if (nameIndex == -1)
+ if (nameIndex == -1 && !isSupType)
return verifierTypeName;
- // They type name must not be empty
- if (typeNameSpan.Length == nameIndex)
- throw new InvalidOperationException();
-
var name = typeNameSpan.Slice(nameIndex + 1);
// Normalize subtypes (such as C/M) to avoid creating directories
- if (name.IndexOf('/') != -1)
+ if (isSupType)
return name.ToString().Replace('/', '.');
return name.ToString();
}
+ private static async Task WriteHeader(
+ VerificationTarget target,
+ DateTime time,
+ string? verifier,
+ StreamWriter writer)
+ {
+ var header = CreateHeader(target, time, verifier);
+ await writer.WriteLineAsync(header);
+ await writer.WriteLineAsync();
+ }
+
+ private static string CreateHeader(VerificationTarget target, DateTime time, string? verifier)
+ {
+ var sb = new StringBuilder();
+ sb.Append($"# Target '{target.Name}'");
+ if (!string.IsNullOrEmpty(verifier))
+ sb.Append($"; Verifier: {verifier}");
+ sb.Append($"; Time: {time:s}");
+ return sb.ToString();
+ }
+
private static async Task WriteError(VerificationError error, StreamWriter writer)
{
await writer.WriteLineAsync($"[{error.Id}] {error.Message}");
diff --git a/src/ModVerify/Reporting/Reporters/Text/TextFileReporterSettings.cs b/src/ModVerify/Reporting/Reporters/Text/TextFileReporterSettings.cs
index 8fb833b..2d0e348 100644
--- a/src/ModVerify/Reporting/Reporters/Text/TextFileReporterSettings.cs
+++ b/src/ModVerify/Reporting/Reporters/Text/TextFileReporterSettings.cs
@@ -1,8 +1,6 @@
-using AET.ModVerify.Reporting.Settings;
+namespace AET.ModVerify.Reporting.Reporters;
-namespace AET.ModVerify.Reporting.Reporters.Text;
-
-public record TextFileReporterSettings : FileBasedReporterSettings
+public sealed record TextFileReporterSettings : FileBasedReporterSettings
{
public bool SplitIntoFiles { get; init; } = true;
}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/VerificationReportBroker.cs b/src/ModVerify/Reporting/Reporters/VerificationReportBroker.cs
new file mode 100644
index 0000000..0ea6630
--- /dev/null
+++ b/src/ModVerify/Reporting/Reporters/VerificationReportBroker.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace AET.ModVerify.Reporting.Reporters;
+
+public sealed class VerificationReportBroker : IVerificationReporter
+{
+ private readonly ILogger? _logger;
+ private readonly IReadOnlyCollection _reporters;
+
+ public VerificationReportBroker(
+ IReadOnlyCollection reporters,
+ IServiceProvider serviceProvider)
+ {
+ _reporters = reporters ?? throw new ArgumentNullException(nameof(reporters));
+ _logger = serviceProvider.GetService()?.CreateLogger(typeof(VerificationReportBroker));
+ }
+
+ public async Task ReportAsync(VerificationResult result)
+ {
+ foreach (var reporter in _reporters)
+ {
+ try
+ {
+ await reporter.ReportAsync(result);
+ }
+ catch (Exception e)
+ {
+ _logger?.LogError(e, "Exception while reporting verification error");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Reporters/VerificationReportersExtensions.cs b/src/ModVerify/Reporting/Reporters/VerificationReportersExtensions.cs
deleted file mode 100644
index b8906ac..0000000
--- a/src/ModVerify/Reporting/Reporters/VerificationReportersExtensions.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using AET.ModVerify.Reporting.Reporters.JSON;
-using AET.ModVerify.Reporting.Reporters.Text;
-using AET.ModVerify.Reporting.Settings;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace AET.ModVerify.Reporting.Reporters;
-
-public static class VerificationReportersExtensions
-{
- extension(IServiceCollection serviceCollection)
- {
- public IServiceCollection RegisterJsonReporter()
- {
- return serviceCollection.RegisterJsonReporter(new JsonReporterSettings
- {
- OutputDirectory = "."
- });
- }
-
- public IServiceCollection RegisterTextFileReporter()
- {
- return serviceCollection.RegisterTextFileReporter(new TextFileReporterSettings
- {
- OutputDirectory = "."
- });
- }
-
- public IServiceCollection RegisterConsoleReporter(bool summaryOnly = false)
- {
- return serviceCollection.RegisterConsoleReporter(new ReporterSettings
- {
- MinimumReportSeverity = VerificationSeverity.Error
- }, summaryOnly);
- }
-
- public IServiceCollection RegisterJsonReporter(JsonReporterSettings settings)
- {
- return serviceCollection.AddSingleton(sp => new JsonReporter(settings, sp));
- }
-
- public IServiceCollection RegisterTextFileReporter(TextFileReporterSettings settings)
- {
- return serviceCollection.AddSingleton(sp => new TextFileReporter(settings, sp));
- }
-
- public IServiceCollection RegisterConsoleReporter(ReporterSettings settings,
- bool summaryOnly = false)
- {
- return serviceCollection.AddSingleton(sp => new ConsoleReporter(settings, summaryOnly, sp));
- }
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/RestoredVerifierInfo.cs b/src/ModVerify/Reporting/RestoredVerifierInfo.cs
new file mode 100644
index 0000000..0f0a87b
--- /dev/null
+++ b/src/ModVerify/Reporting/RestoredVerifierInfo.cs
@@ -0,0 +1,15 @@
+using AET.ModVerify.Verifiers;
+using AET.ModVerify.Verifiers.Utilities;
+using System.Collections.Generic;
+
+namespace AET.ModVerify.Reporting;
+
+internal sealed class RestoredVerifierInfo : IGameVerifierInfo
+{
+ public IGameVerifierInfo? Parent { get; init; }
+
+ public IReadOnlyList VerifierChain => field ??= this.GetVerifierChain();
+
+ public required string Name { get; init; }
+ public string FriendlyName => Name;
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Settings/GlobalVerifyReportSettings.cs b/src/ModVerify/Reporting/Settings/GlobalVerifyReportSettings.cs
deleted file mode 100644
index 5a51436..0000000
--- a/src/ModVerify/Reporting/Settings/GlobalVerifyReportSettings.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace AET.ModVerify.Reporting.Settings;
-
-//public record GlobalVerifyReportSettings
-//{
-// //public VerificationSeverity MinimumReportSeverity { get; init; } = VerificationSeverity.Information;
-
-// public VerificationBaseline Baseline { get; init; } = VerificationBaseline.Empty;
-
-// public SuppressionList Suppressions { get; init; } = SuppressionList.Empty;
-//}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/Json/JsonSuppressionFilter.cs b/src/ModVerify/Reporting/Suppressions/Json/JsonSuppressionFilter.cs
similarity index 91%
rename from src/ModVerify/Reporting/Json/JsonSuppressionFilter.cs
rename to src/ModVerify/Reporting/Suppressions/Json/JsonSuppressionFilter.cs
index 6d232c7..13f8335 100644
--- a/src/ModVerify/Reporting/Json/JsonSuppressionFilter.cs
+++ b/src/ModVerify/Reporting/Suppressions/Json/JsonSuppressionFilter.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace AET.ModVerify.Reporting.Json;
+namespace AET.ModVerify.Reporting.Suppressions.Json;
internal class JsonSuppressionFilter(SuppressionFilter filter)
{
diff --git a/src/ModVerify/Reporting/Json/JsonSuppressionList.cs b/src/ModVerify/Reporting/Suppressions/Json/JsonSuppressionList.cs
similarity index 88%
rename from src/ModVerify/Reporting/Json/JsonSuppressionList.cs
rename to src/ModVerify/Reporting/Suppressions/Json/JsonSuppressionList.cs
index 1a8cb4a..54569eb 100644
--- a/src/ModVerify/Reporting/Json/JsonSuppressionList.cs
+++ b/src/ModVerify/Reporting/Suppressions/Json/JsonSuppressionList.cs
@@ -2,7 +2,7 @@
using System.Linq;
using System.Text.Json.Serialization;
-namespace AET.ModVerify.Reporting.Json;
+namespace AET.ModVerify.Reporting.Suppressions.Json;
internal class JsonSuppressionList
{
diff --git a/src/ModVerify/Reporting/SuppressionFilter.cs b/src/ModVerify/Reporting/Suppressions/SuppressionFilter.cs
similarity index 93%
rename from src/ModVerify/Reporting/SuppressionFilter.cs
rename to src/ModVerify/Reporting/Suppressions/SuppressionFilter.cs
index efac588..35a21d7 100644
--- a/src/ModVerify/Reporting/SuppressionFilter.cs
+++ b/src/ModVerify/Reporting/Suppressions/SuppressionFilter.cs
@@ -1,8 +1,8 @@
using System;
using System.Linq;
-using AET.ModVerify.Reporting.Json;
+using AET.ModVerify.Reporting.Suppressions.Json;
-namespace AET.ModVerify.Reporting;
+namespace AET.ModVerify.Reporting.Suppressions;
public sealed class SuppressionFilter : IEquatable
{
@@ -42,7 +42,7 @@ public bool Suppresses(VerificationError error)
if (Verifier is not null)
{
- if (error.VerifierChain.Contains(Verifier))
+ if (error.VerifierChain.Any(x => x.Name.Equals(Verifier)))
suppresses = true;
else
return false;
diff --git a/src/ModVerify/Reporting/SuppressionList.cs b/src/ModVerify/Reporting/Suppressions/SuppressionList.cs
similarity index 96%
rename from src/ModVerify/Reporting/SuppressionList.cs
rename to src/ModVerify/Reporting/Suppressions/SuppressionList.cs
index 12ebab4..a5fc8f9 100644
--- a/src/ModVerify/Reporting/SuppressionList.cs
+++ b/src/ModVerify/Reporting/Suppressions/SuppressionList.cs
@@ -5,8 +5,9 @@
using System.IO;
using System.Linq;
using System.Text.Json;
+using AET.ModVerify.Reporting.Suppressions.Json;
-namespace AET.ModVerify.Reporting;
+namespace AET.ModVerify.Reporting.Suppressions;
public sealed class SuppressionList : IReadOnlyCollection
{
diff --git a/src/ModVerify/Reporting/VerificationCompletionStatus.cs b/src/ModVerify/Reporting/VerificationCompletionStatus.cs
new file mode 100644
index 0000000..94fde18
--- /dev/null
+++ b/src/ModVerify/Reporting/VerificationCompletionStatus.cs
@@ -0,0 +1,8 @@
+namespace AET.ModVerify.Reporting;
+
+public enum VerificationCompletionStatus
+{
+ Completed,
+ CompletedFailFast,
+ Cancelled,
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/VerificationError.cs b/src/ModVerify/Reporting/VerificationError.cs
index 538a8fd..2e95327 100644
--- a/src/ModVerify/Reporting/VerificationError.cs
+++ b/src/ModVerify/Reporting/VerificationError.cs
@@ -17,7 +17,7 @@ public sealed class VerificationError : IEquatable
public string Message { get; }
- public IReadOnlyList VerifierChain { get; }
+ public IReadOnlyList VerifierChain { get; }
public IReadOnlyCollection ContextEntries { get; }
@@ -28,11 +28,13 @@ public sealed class VerificationError : IEquatable
public VerificationError(
string id,
string message,
- IReadOnlyList verifiers,
+ IGameVerifierInfo verifier,
IEnumerable contextEntries,
string asset,
VerificationSeverity severity)
{
+ if (verifier == null)
+ throw new ArgumentNullException(nameof(verifier));
if (contextEntries == null)
throw new ArgumentNullException(nameof(contextEntries));
if (asset is null)
@@ -41,10 +43,9 @@ public VerificationError(
Id = id;
Message = message ?? throw new ArgumentNullException(nameof(message));
- VerifierChain = verifiers;
+ VerifierChain = verifier.VerifierChain;
Severity = severity;
- _contextEntries = [.. contextEntries];
- ContextEntries = _contextEntries.ToList();
+ ContextEntries = _contextEntries = [.. contextEntries];
Asset = asset;
}
@@ -52,25 +53,25 @@ internal VerificationError(JsonVerificationError error)
{
Id = error.Id;
Message = error.Message;
- VerifierChain = error.VerifierChain;
+ VerifierChain = RestoreVerifierChain(error.VerifierChain);
_contextEntries = [..error.ContextEntries];
ContextEntries = _contextEntries.ToList();
Asset = error.Asset;
}
public static VerificationError Create(
- IReadOnlyList verifiers,
+ IGameVerifierInfo verifier,
string id,
string message,
VerificationSeverity severity,
IEnumerable context,
string asset)
{
- return new VerificationError(id, message, verifiers.Select(x => x.Name).ToList(), context, asset, severity);
+ return new VerificationError(id, message, verifier, context, asset, severity);
}
public static VerificationError Create(
- IReadOnlyList verifiers,
+ IGameVerifierInfo verifier,
string id,
string message,
VerificationSeverity severity,
@@ -79,7 +80,7 @@ public static VerificationError Create(
return new VerificationError(
id,
message,
- verifiers.Select(x => x.Name).ToList(),
+ verifier,
[],
asset,
severity);
@@ -120,4 +121,26 @@ public override string ToString()
return $"[{Severity}] [{string.Join(" --> ", VerifierChain)}] " +
$"{Id}: Message={Message}; Asset='{Asset}'; Context=[{string.Join(",", ContextEntries)}];";
}
+
+ private static IReadOnlyList RestoreVerifierChain(IReadOnlyList? errorVerifierChain)
+ {
+ if (errorVerifierChain is null)
+ return [];
+
+ var verifierChain = new List();
+ IGameVerifierInfo? previousVerifier = null;
+
+ foreach (var name in errorVerifierChain)
+ {
+ var verifier = new RestoredVerifierInfo
+ {
+ Name = name,
+ Parent = previousVerifier
+ };
+ verifierChain.Add(verifier);
+ previousVerifier = verifier;
+ }
+
+ return verifierChain;
+ }
}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/VerificationReportBroker.cs b/src/ModVerify/Reporting/VerificationReportBroker.cs
deleted file mode 100644
index 5c1e8a3..0000000
--- a/src/ModVerify/Reporting/VerificationReportBroker.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-
-namespace AET.ModVerify.Reporting;
-
-public sealed class VerificationReportBroker(IServiceProvider serviceProvider)
-{
- private readonly ILogger? _logger = serviceProvider.GetService()?.CreateLogger(typeof(VerificationReportBroker));
-
- public async Task ReportAsync(IReadOnlyCollection errors)
- {
- var reporters = serviceProvider.GetServices();
-
- foreach (var reporter in reporters)
- {
- try
- {
- await reporter.ReportAsync(errors);
- }
- catch (Exception e)
- {
- _logger?.LogError(e, "Exception while reporting verification error");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/VerificationResult.cs b/src/ModVerify/Reporting/VerificationResult.cs
new file mode 100644
index 0000000..a4dbe1c
--- /dev/null
+++ b/src/ModVerify/Reporting/VerificationResult.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using AET.ModVerify.Reporting.Baseline;
+using AET.ModVerify.Reporting.Suppressions;
+using AET.ModVerify.Verifiers;
+
+namespace AET.ModVerify.Reporting;
+
+public sealed record VerificationResult
+{
+ public required VerificationCompletionStatus Status { get; init; }
+
+ public required IReadOnlyCollection Errors
+ {
+ get;
+ init => field = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ public required VerificationBaseline UsedBaseline
+ {
+ get;
+ init => field = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ public required SuppressionList UsedSuppressions
+ {
+ get;
+ init => field = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ public required IReadOnlyCollection Verifiers
+ {
+ get;
+ init => field = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ public required VerificationTarget Target
+ {
+ get;
+ init => field = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ public required TimeSpan Duration { get; init; }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Reporting/VerifierChainEqualityComparer.cs b/src/ModVerify/Reporting/VerifierChainEqualityComparer.cs
new file mode 100644
index 0000000..27897cb
--- /dev/null
+++ b/src/ModVerify/Reporting/VerifierChainEqualityComparer.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using AET.ModVerify.Verifiers;
+using AET.ModVerify.Verifiers.Utilities;
+
+namespace AET.ModVerify.Reporting;
+
+internal sealed class VerifierChainEqualityComparer : IEqualityComparer>
+{
+ public static readonly VerifierChainEqualityComparer Instance = new();
+
+ private VerifierChainEqualityComparer()
+ {
+ }
+
+ public bool Equals(IReadOnlyList? x, IReadOnlyList? y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+ if (x is null || y is null)
+ return false;
+ if (x.Count != y.Count)
+ return false;
+ for (var i = 0; i < x.Count; i++)
+ {
+ if (!NameBasedEqualityComparer.Instance.Equals(x[i], y[i]))
+ return false;
+ }
+ return true;
+ }
+
+ public int GetHashCode(IReadOnlyList? obj)
+ {
+ if (obj == null)
+ return 0;
+ var hashCode = new HashCode();
+ foreach (var verifier in obj)
+ hashCode.Add(verifier.Name);
+ return hashCode.ToHashCode();
+ }
+}
diff --git a/src/ModVerify/Resources/Schemas/2.1/baseline.json b/src/ModVerify/Resources/Schemas/2.2/baseline.json
similarity index 92%
rename from src/ModVerify/Resources/Schemas/2.1/baseline.json
rename to src/ModVerify/Resources/Schemas/2.2/baseline.json
index da37c4d..d893b4d 100644
--- a/src/ModVerify/Resources/Schemas/2.1/baseline.json
+++ b/src/ModVerify/Resources/Schemas/2.2/baseline.json
@@ -1,5 +1,5 @@
{
- "$id": "https://AlamoEngine-Tools.github.io/schemas/mod-verify/2.1/baseline",
+ "$id": "https://AlamoEngine-Tools.github.io/schemas/mod-verify/2.2/baseline",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Represents a baseline for AET ModVerify",
"type": "object",
@@ -73,12 +73,6 @@
"severity": {
"$ref": "#/$defs/severity"
},
- "verifiers": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
"context": {
"type": "array",
"items": {
@@ -91,7 +85,6 @@
"message",
"asset",
"severity",
- "verifiers",
"context"
],
"additionalProperties": false
@@ -99,7 +92,7 @@
},
"properties": {
"version": {
- "const": "2.1"
+ "const": "2.2"
},
"minSeverity": {
"$ref": "#/$defs/severity"
diff --git a/src/ModVerify/Settings/VerifyPipelineSettings.cs b/src/ModVerify/Settings/VerifierServiceSettings.cs
similarity index 72%
rename from src/ModVerify/Settings/VerifyPipelineSettings.cs
rename to src/ModVerify/Settings/VerifierServiceSettings.cs
index 46fc997..762806d 100644
--- a/src/ModVerify/Settings/VerifyPipelineSettings.cs
+++ b/src/ModVerify/Settings/VerifierServiceSettings.cs
@@ -1,8 +1,6 @@
-using AET.ModVerify.Pipeline;
+namespace AET.ModVerify.Settings;
-namespace AET.ModVerify.Settings;
-
-public sealed class VerifyPipelineSettings
+public sealed class VerifierServiceSettings
{
public required GameVerifySettings GameVerifySettings { get; init; }
diff --git a/src/ModVerify/Utilities/VerificationErrorExtensions.cs b/src/ModVerify/Utilities/VerificationErrorExtensions.cs
index e5aa9fe..f7eefbc 100644
--- a/src/ModVerify/Utilities/VerificationErrorExtensions.cs
+++ b/src/ModVerify/Utilities/VerificationErrorExtensions.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using AET.ModVerify.Reporting;
+using AET.ModVerify.Reporting.Baseline;
+using AET.ModVerify.Reporting.Suppressions;
namespace AET.ModVerify.Utilities;
diff --git a/src/ModVerify/VerificationTarget.cs b/src/ModVerify/VerificationTarget.cs
index c0d5b97..f12bc4d 100644
--- a/src/ModVerify/VerificationTarget.cs
+++ b/src/ModVerify/VerificationTarget.cs
@@ -1,10 +1,9 @@
using System;
-using System.Text;
using PG.StarWarsGame.Engine;
namespace AET.ModVerify;
-public sealed class VerificationTarget
+public sealed record VerificationTarget
{
public required GameEngineType Engine { get; init; }
@@ -28,14 +27,4 @@ public required GameLocations Location
public string? Version { get; init; }
public bool IsGame => Location.ModPaths.Count == 0;
-
- public override string ToString()
- {
- var sb = new StringBuilder($"[Name={Name};EngineType={Engine};");
- if (!string.IsNullOrEmpty(Version))
- sb.Append($"Version={Version};");
- sb.Append($"Location={Location};");
- sb.Append(']');
- return sb.ToString();
- }
}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/AlreadyVerifiedCache.cs b/src/ModVerify/Verifiers/AlreadyVerifiedCache.cs
deleted file mode 100644
index 530ca4e..0000000
--- a/src/ModVerify/Verifiers/AlreadyVerifiedCache.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using Microsoft.Extensions.DependencyInjection;
-using PG.Commons.Hashing;
-using PG.StarWarsGame.Engine;
-
-namespace AET.ModVerify.Verifiers;
-
-internal sealed class AlreadyVerifiedCache(IServiceProvider serviceProvider) : IAlreadyVerifiedCache
-{
- private readonly ICrc32HashingService _crc32Hashing = serviceProvider.GetRequiredService();
- private readonly ConcurrentDictionary _cachedChecksums = new();
-
- public bool TryAddEntry(string entry)
- {
- return TryAddEntry(entry.AsSpan());
- }
-
- public bool TryAddEntry(ReadOnlySpan entry)
- {
- return TryAddEntry(_crc32Hashing.GetCrc32Upper(entry, PGConstants.DefaultPGEncoding));
- }
-
- public bool TryAddEntry(Crc32 checksum)
- {
- return _cachedChecksums.TryAdd(checksum, 0);
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/AudioFilesVerifier.cs b/src/ModVerify/Verifiers/AudioFilesVerifier.cs
deleted file mode 100644
index ddd9252..0000000
--- a/src/ModVerify/Verifiers/AudioFilesVerifier.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Abstractions;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using AET.ModVerify.Reporting;
-using AET.ModVerify.Settings;
-using AnakinRaW.CommonUtilities.FileSystem.Normalization;
-using Microsoft.Extensions.DependencyInjection;
-using PG.Commons.Hashing;
-using PG.StarWarsGame.Engine;
-using PG.StarWarsGame.Engine.Audio.Sfx;
-using PG.StarWarsGame.Engine.Localization;
-#if NETSTANDARD2_0
-using AnakinRaW.CommonUtilities.FileSystem;
-#endif
-
-namespace AET.ModVerify.Verifiers;
-
-public class AudioFilesVerifier : GameVerifier
-{
- private static readonly PathNormalizeOptions SampleNormalizerOptions = new()
- {
- UnifyCase = UnifyCasingKind.UpperCaseForce,
- UnifySeparatorKind = DirectorySeparatorKind.Windows,
- UnifyDirectorySeparators = true
- };
-
- private readonly ICrc32HashingService _hashingService;
- private readonly IFileSystem _fileSystem;
- private readonly IGameLanguageManager _languageManager;
-
- public AudioFilesVerifier(IStarWarsGameEngine gameEngine, GameVerifySettings settings, IServiceProvider serviceProvider)
- : base(null, gameEngine, settings, serviceProvider)
- {
- _hashingService = serviceProvider.GetRequiredService();
- _fileSystem = serviceProvider.GetRequiredService();
- _languageManager = serviceProvider.GetRequiredService()
- .GetLanguageManager(Repository.EngineType);
- }
-
- public override string FriendlyName => "Audio Files";
-
- public override void Verify(CancellationToken token)
- {
- var visitedSamples = new HashSet();
- var languagesToVerify = GetLanguagesToVerify().ToList();
-
-
- var numSamples = GameEngine.SfxGameManager.Entries.Sum(x => x.AllSamples.Count());
- double counter = 0;
-
- foreach (var sfxEvent in GameEngine.SfxGameManager.Entries)
- {
- foreach (var codedSample in sfxEvent.AllSamples)
- {
- OnProgress(++counter / numSamples, $"Audio File - '{codedSample}'");
- VerifySample(codedSample.AsSpan(), sfxEvent, languagesToVerify, visitedSamples);
- }
- }
- }
-
- private void VerifySample(ReadOnlySpan sample, SfxEvent sfxEvent, IEnumerable languagesToVerify, HashSet visitedSamples)
- {
- char[]? pooledBuffer = null;
-
- var buffer = sample.Length < PGConstants.MaxMegEntryPathLength
- ? stackalloc char[PGConstants.MaxMegEntryPathLength]
- : pooledBuffer = ArrayPool.Shared.Rent(sample.Length);
-
- try
- {
- var length = PathNormalizer.Normalize(sample, buffer, SampleNormalizerOptions);
- var sampleNameBuffer = buffer.Slice(0, length);
-
- var crc = _hashingService.GetCrc32(sampleNameBuffer, Encoding.ASCII);
- if (!visitedSamples.Add(crc))
- return;
-
- if (sfxEvent.IsLocalized)
- {
- foreach (var language in languagesToVerify)
- {
- VerifySampleLocalized(sfxEvent, sampleNameBuffer, language, out var localized);
- if (!localized)
- return;
- }
- }
- else
- {
- VerifySample(sampleNameBuffer, sfxEvent);
- }
- }
- finally
- {
- if (pooledBuffer is not null)
- ArrayPool.Shared.Return(pooledBuffer);
- }
-
- }
-
- private void VerifySampleLocalized(SfxEvent sfxEvent, ReadOnlySpan sample, LanguageType language, out bool localized)
- {
- char[]? pooledBuffer = null;
-
- var buffer = sample.Length < PGConstants.MaxMegEntryPathLength
- ? stackalloc char[PGConstants.MaxMegEntryPathLength]
- : pooledBuffer = ArrayPool.Shared.Rent(sample.Length);
- try
- {
- var l = _languageManager.LocalizeFileName(sample, language, buffer, out localized);
- var localizedName = buffer.Slice(0, l);
- VerifySample(localizedName, sfxEvent);
- }
- finally
- {
- if (pooledBuffer is not null)
- ArrayPool.Shared.Return(pooledBuffer);
- }
- }
-
- private void VerifySample(ReadOnlySpan sample, SfxEvent sfxEvent)
- {
- using var sampleStream = Repository.TryOpenFile(sample);
- if (sampleStream is null)
- {
- var sampleString = sample.ToString();
- AddError(VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes.FileNotFound,
- $"Audio file '{sampleString}' could not be found.",
- VerificationSeverity.Error,
- [sfxEvent.Name],
- sampleString));
- return;
- }
- using var binaryReader = new BinaryReader(sampleStream);
-
- // Skip Header + "fmt "
- binaryReader.BaseStream.Seek(16, SeekOrigin.Begin);
-
- var fmtSize = binaryReader.ReadInt32();
- var format = (WaveFormats)binaryReader.ReadInt16();
- var channels = binaryReader.ReadInt16();
-
- var sampleRate = binaryReader.ReadInt32();
- var bytesPerSecond = binaryReader.ReadInt32();
-
- var frameSize = binaryReader.ReadInt16();
- var bitPerSecondPerChannel = binaryReader.ReadInt16();
-
- if (format != WaveFormats.PCM)
- {
- var sampleString = sample.ToString();
- AddError(VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes.SampleNotPCM,
- $"Audio file '{sampleString}' has an invalid format '{format}'. Supported is {WaveFormats.PCM}",
- VerificationSeverity.Error,
- [sfxEvent.Name],
- sampleString));
- }
-
- if (channels > 1 && !IsAmbient2D(sfxEvent))
- {
- var sampleString = sample.ToString();
- AddError(VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes.SampleNotMono,
- $"Audio file '{sampleString}' is not mono audio.",
- VerificationSeverity.Information,
- sampleString));
- }
-
- if (sampleRate > 48_000)
- {
- var sampleString = sample.ToString();
- AddError(VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes. InvalidSampleRate,
- $"Audio file '{sampleString}' has a too high sample rate of {sampleRate}. Maximum is 48.000Hz.",
- VerificationSeverity.Error,
- [sfxEvent.Name],
- sampleString));
- }
-
- if (bitPerSecondPerChannel > 16)
- {
- var sampleString = sample.ToString();
- AddError(VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes.InvalidBitsPerSeconds,
- $"Audio file '{sampleString}' has an invalid bit size of {bitPerSecondPerChannel}. Supported are 16bit.",
- VerificationSeverity.Error,
- [sfxEvent.Name],
- sampleString));
- }
- }
-
- // Some heuristics whether a SFXEvent is most likely to be an ambient sound.
- private bool IsAmbient2D(SfxEvent sfxEvent)
- {
- if (!sfxEvent.Is2D)
- return false;
-
- if (sfxEvent.IsPreset)
- return false;
-
- // If the event is located in SFXEventsAmbient.xml we simply assume it's an ambient sound.
- var fileName = _fileSystem.Path.GetFileName(sfxEvent.Location.XmlFile.AsSpan());
- if (fileName.Equals("SFXEventsAmbient.xml".AsSpan(), StringComparison.OrdinalIgnoreCase))
- return true;
-
- if (string.IsNullOrEmpty(sfxEvent.UsePresetName))
- return false;
-
- if (sfxEvent.UsePresetName!.StartsWith("Preset_AMB_2D"))
- return true;
-
- return true;
- }
-
- private IEnumerable GetLanguagesToVerify()
- {
- switch (Settings.LocalizationOption)
- {
- case VerifyLocalizationOption.English:
- return new List { LanguageType.English };
- case VerifyLocalizationOption.CurrentSystem:
- return new List { _languageManager.GetLanguagesFromUser() };
- case VerifyLocalizationOption.AllInstalled:
- return GameEngine.InstalledLanguages;
- case VerifyLocalizationOption.All:
- return _languageManager.SupportedLanguages;
- default:
- throw new NotSupportedException($"{Settings.LocalizationOption} is not supported");
- }
- }
-
- private enum WaveFormats
- {
- PCM = 1,
- MSADPCM = 2,
- IEEE_Float = 3,
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Caching/AlreadyVerifiedCache.cs b/src/ModVerify/Verifiers/Caching/AlreadyVerifiedCache.cs
new file mode 100644
index 0000000..c6dda7c
--- /dev/null
+++ b/src/ModVerify/Verifiers/Caching/AlreadyVerifiedCache.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+namespace AET.ModVerify.Verifiers.Caching;
+
+internal sealed class AlreadyVerifiedCache : IAlreadyVerifiedCache
+{
+ private readonly Dictionary _cachedEntries = new();
+
+ public bool TryAddEntry(string entry, bool assetExists)
+ {
+ var upper = entry.ToUpperInvariant();
+
+#if NETSTANDARD2_1 || NET
+ return _cachedEntries.TryAdd(upper, assetExists);
+#else
+ var alreadyVerified = _cachedEntries.ContainsKey(upper);
+ if (alreadyVerified)
+ return false;
+
+ _cachedEntries[upper] = assetExists;
+ return true;
+#endif
+ }
+
+ public VerifiedCacheEntry GetEntry(string entry)
+ {
+ var upper = entry.ToUpperInvariant();
+ var alreadyVerified = _cachedEntries.TryGetValue(upper, out var exists);
+ return alreadyVerified ? new VerifiedCacheEntry(true, exists) : default;
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Caching/IAlreadyVerifiedCache.cs b/src/ModVerify/Verifiers/Caching/IAlreadyVerifiedCache.cs
new file mode 100644
index 0000000..68f39b4
--- /dev/null
+++ b/src/ModVerify/Verifiers/Caching/IAlreadyVerifiedCache.cs
@@ -0,0 +1,8 @@
+namespace AET.ModVerify.Verifiers.Caching;
+
+public interface IAlreadyVerifiedCache
+{
+ bool TryAddEntry(string entry, bool assetExists);
+
+ VerifiedCacheEntry GetEntry(string entry);
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Caching/VerifiedCacheEntry.cs b/src/ModVerify/Verifiers/Caching/VerifiedCacheEntry.cs
new file mode 100644
index 0000000..252a7c0
--- /dev/null
+++ b/src/ModVerify/Verifiers/Caching/VerifiedCacheEntry.cs
@@ -0,0 +1,14 @@
+namespace AET.ModVerify.Verifiers.Caching;
+
+public readonly struct VerifiedCacheEntry
+{
+ public bool AlreadyVerified { get; }
+
+ public bool AssetExists { get; }
+
+ public VerifiedCacheEntry(bool alreadyVerified, bool assetExists)
+ {
+ AlreadyVerified = alreadyVerified;
+ AssetExists = assetExists;
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Base.cs b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Base.cs
deleted file mode 100644
index 3373f8e..0000000
--- a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Base.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading;
-using AET.ModVerify.Reporting;
-using AET.ModVerify.Settings;
-using AnakinRaW.CommonUtilities.Collections;
-using PG.StarWarsGame.Engine;
-using PG.StarWarsGame.Engine.CommandBar;
-using PG.StarWarsGame.Engine.CommandBar.Components;
-
-namespace AET.ModVerify.Verifiers;
-
-public partial class CommandBarVerifier(IStarWarsGameEngine gameEngine, GameVerifySettings settings, IServiceProvider serviceProvider)
- : GameVerifier(null, gameEngine, settings, serviceProvider)
-{
- public const string CommandBarNoShellsGroup = "CMDBAR00";
- public const string CommandBarManyShellsGroup = "CMDBAR01";
- public const string CommandBarNoShellsComponentInShellGroup = "CMDBAR02";
- public const string CommandBarDuplicateComponent = "CMDBAR03";
- public const string CommandBarUnsupportedComponent = "CMDBAR04";
- public const string CommandBarShellNoModel = "CMDBAR05";
-
- public override string FriendlyName => "CommandBar";
-
- public override void Verify(CancellationToken token)
- {
- VerifyCommandBarShellsGroups();
- VerifyCommandBarComponents();
- }
-
- private void VerifySingleComponent(CommandBarBaseComponent component)
- {
- VerifyCommandBarModel(component);
- VerifyComponentBone(component);
- }
-}
-
-partial class CommandBarVerifier
-{
- private void VerifyCommandBarModel(CommandBarBaseComponent component)
- {
- if (component is not CommandBarShellComponent shellComponent)
- return;
-
- if (shellComponent.ModelPath is null)
- {
- AddError(VerificationError.Create(VerifierChain,
- CommandBarShellNoModel, $"The CommandBarShellComponent '{component.Name}' has no model specified.",
- VerificationSeverity.Error, shellComponent.Name));
- return;
- }
-
- var model = GameEngine.PGRender.LoadModelAndAnimations(shellComponent.ModelPath.AsSpan(), null);
- if (model is null)
- {
- AddError(VerificationError.Create(VerifierChain,
- CommandBarShellNoModel, $"Could not find model '{shellComponent.ModelPath}' for CommandBarShellComponent '{component.Name}'.",
- VerificationSeverity.Error, [shellComponent.Name], shellComponent.ModelPath));
- return;
- }
- }
-
- private void VerifyComponentBone(CommandBarBaseComponent component)
- {
- if (component is CommandBarShellComponent)
- return;
-
- if (component.Bone == -1)
- {
- AddError(VerificationError.Create(VerifierChain,
- CommandBarShellNoModel, $"The CommandBar component '{component.Name}' is not connected to a shell component.",
- VerificationSeverity.Warning, component.Name));
- }
- }
-}
-
-partial class CommandBarVerifier
-{
- private void VerifyCommandBarComponents()
- {
- var occupiedComponentIds = SupportedCommandBarComponentData.GetComponentIdsForEngine(Repository.EngineType).Keys
- .ToDictionary(value => value, _ => false);
-
- foreach (var component in GameEngine.CommandBar.Components)
- {
- if (!occupiedComponentIds.TryGetValue(component.Id, out var alreadyOccupied))
- {
- AddError(VerificationError.Create(
- VerifierChain,
- CommandBarUnsupportedComponent,
- $"The CommandBar component '{component.Name}' is not supported by the game.",
- VerificationSeverity.Information,
- component.Name));
- }
- else
- {
- occupiedComponentIds[component.Id] = true;
- }
-
- if (alreadyOccupied)
- {
- AddError(VerificationError.Create(VerifierChain,
- CommandBarDuplicateComponent,
- $"The CommandBar component '{component.Name}' with ID '{component.Id}' already exists.",
- VerificationSeverity.Warning,
- component.Name));
- }
-
- VerifySingleComponent(component);
- }
- }
-}
-
-partial class CommandBarVerifier
-{
- private void VerifyCommandBarShellsGroups()
- {
- var shellGroups = new FrugalList();
- foreach (var groupPair in GameEngine.CommandBar.Groups)
- {
- if (groupPair.Key == CommandBarConstants.ShellGroupName)
- {
- shellGroups.Add(groupPair.Key);
- VerifyShellGroup(groupPair.Value);
- }
- else if (groupPair.Key.Equals(CommandBarConstants.ShellGroupName, StringComparison.OrdinalIgnoreCase))
- {
- shellGroups.Add(groupPair.Key);
- }
- }
-
- if (shellGroups.Count == 0)
- AddError(VerificationError.Create(VerifierChain,
- CommandBarNoShellsGroup,
- $"No CommandBarGroup '{CommandBarConstants.ShellGroupName}' found.",
- VerificationSeverity.Error,
- "GameCommandBar"));
-
- if (shellGroups.Count > 1)
- AddError(VerificationError.Create(VerifierChain,
- CommandBarManyShellsGroup,
- $"Found more than one Shells CommandBarGroup. Mind that group names are case-sensitive. Correct name is '{CommandBarConstants.ShellGroupName}'",
- VerificationSeverity.Warning,
- shellGroups, "GameCommandBar"));
- }
-
- private void VerifyShellGroup(CommandBarComponentGroup shellGroup)
- {
- foreach (var component in shellGroup.Components)
- {
- var shellComponent = component as CommandBarShellComponent;
- if (shellComponent?.Type is not CommandBarComponentType.Shell)
- {
- AddError(VerificationError.Create(VerifierChain,
- CommandBarNoShellsComponentInShellGroup,
- $"The CommandBar component '{component.Name}' is not a shell component, but part of the '{CommandBarConstants.ShellGroupName}' group.",
- VerificationSeverity.Warning, component.Name));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Components.cs b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Components.cs
new file mode 100644
index 0000000..3b43093
--- /dev/null
+++ b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Components.cs
@@ -0,0 +1,51 @@
+using AET.ModVerify.Reporting;
+using PG.StarWarsGame.Engine.CommandBar;
+using System.Linq;
+using System.Threading;
+
+namespace AET.ModVerify.Verifiers.CommandBar;
+
+partial class CommandBarVerifier
+{
+ private void VerifyCommandBarComponents(CancellationToken token, double startProgress)
+ {
+ var occupiedComponentIds = SupportedCommandBarComponentData
+ .GetComponentIdsForEngine(Repository.EngineType).Keys
+ .ToDictionary(value => value, _ => false);
+
+ var counter = 0;
+ var numEntities = GameEngine.CommandBar.Components.Count;
+ var num = 1 - startProgress;
+
+ foreach (var component in GameEngine.CommandBar.Components)
+ {
+ var progress = num + (++counter / (double)numEntities) * startProgress;
+ OnProgress(progress, $"CommandBarComponent - '{component.Name}'");
+
+ if (!occupiedComponentIds.TryGetValue(component.Id, out var alreadyOccupied))
+ {
+ AddError(VerificationError.Create(
+ this,
+ CommandBarUnsupportedComponent,
+ $"The CommandBar component '{component.Name}' is not supported by the game.",
+ VerificationSeverity.Information,
+ component.Name));
+ }
+ else
+ {
+ occupiedComponentIds[component.Id] = true;
+ }
+
+ if (alreadyOccupied)
+ {
+ AddError(VerificationError.Create(this,
+ VerifierErrorCodes.Duplicate,
+ $"The CommandBar component '{component.Name}' with ID '{component.Id}' already exists.",
+ VerificationSeverity.Warning,
+ component.Name));
+ }
+
+ VerifySingleComponent(component, token);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Groups.cs b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Groups.cs
new file mode 100644
index 0000000..e3ed107
--- /dev/null
+++ b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.Groups.cs
@@ -0,0 +1,56 @@
+using System;
+using AET.ModVerify.Reporting;
+using AnakinRaW.CommonUtilities.Collections;
+using PG.StarWarsGame.Engine.CommandBar;
+using PG.StarWarsGame.Engine.CommandBar.Components;
+
+namespace AET.ModVerify.Verifiers.CommandBar;
+
+partial class CommandBarVerifier
+{
+ private void VerifyCommandBarShellsGroups()
+ {
+ var shellGroups = new FrugalList();
+ foreach (var groupPair in GameEngine.CommandBar.Groups)
+ {
+ if (groupPair.Key == CommandBarConstants.ShellGroupName)
+ {
+ shellGroups.Add(groupPair.Key);
+ VerifyShellGroup(groupPair.Value);
+ }
+ else if (groupPair.Key.Equals(CommandBarConstants.ShellGroupName, StringComparison.OrdinalIgnoreCase))
+ {
+ shellGroups.Add(groupPair.Key);
+ }
+ }
+
+ if (shellGroups.Count == 0)
+ AddError(VerificationError.Create(this,
+ CommandBarNoShellsGroup,
+ $"No CommandBarGroup '{CommandBarConstants.ShellGroupName}' found.",
+ VerificationSeverity.Error,
+ "GameCommandBar"));
+
+ if (shellGroups.Count > 1)
+ AddError(VerificationError.Create(this,
+ CommandBarManyShellsGroup,
+ $"Found more than one Shells CommandBarGroup. Mind that group names are case-sensitive. Correct name is '{CommandBarConstants.ShellGroupName}'",
+ VerificationSeverity.Warning,
+ shellGroups, "GameCommandBar"));
+ }
+
+ private void VerifyShellGroup(CommandBarComponentGroup shellGroup)
+ {
+ foreach (var component in shellGroup.Components)
+ {
+ var shellComponent = component as CommandBarShellComponent;
+ if (shellComponent?.Type is not CommandBarComponentType.Shell)
+ {
+ AddError(VerificationError.Create(this,
+ CommandBarNoShellsComponentInShellGroup,
+ $"The CommandBar component '{component.Name}' is not a shell component, but part of the '{CommandBarConstants.ShellGroupName}' group.",
+ VerificationSeverity.Warning, component.Name));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.MegaTexture.cs b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.MegaTexture.cs
new file mode 100644
index 0000000..8d86bad
--- /dev/null
+++ b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.MegaTexture.cs
@@ -0,0 +1,41 @@
+using System.Threading;
+using AET.ModVerify.Reporting;
+using AET.ModVerify.Verifiers.Commons;
+using AET.ModVerify.Verifiers.Utilities;
+using PG.StarWarsGame.Engine.CommandBar;
+
+namespace AET.ModVerify.Verifiers.CommandBar;
+
+partial class CommandBarVerifier
+{
+ private void VerifyMegaTexture(CancellationToken token)
+ {
+ if (CommandBar.MtdFile is null)
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound,
+ $"Cannot find CommandBar MegaTextureDirectory '{CommandBarConstants.MegaTextureBaseName}.mtd'",
+ VerificationSeverity.Critical, $"{CommandBarConstants.MegaTextureBaseName}.mtd"));
+ }
+ else
+ {
+ var dupVerifier = new DuplicateVerifier(this);
+ dupVerifier.Verify(IDuplicateVerificationContext.CreateForMtd(CommandBar.MtdFile), [], token);
+
+ foreach (var duplicateError in dupVerifier.VerifyErrors)
+ AddError(duplicateError);
+ }
+
+ if (CommandBar.MegaTextureFileName is null)
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound,
+ $"Cannot find CommandBar MegaTexture '{CommandBarConstants.MegaTextureBaseName}.tga'",
+ VerificationSeverity.Critical, $"{CommandBarConstants.MegaTextureBaseName}.tga"));
+ }
+ else if (!GameEngine.GameRepository.TextureRepository.FileExists(CommandBar.MegaTextureFileName))
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound,
+ $"Cannot find CommandBar MegaTexture '{CommandBarConstants.MegaTextureBaseName}.tga'",
+ VerificationSeverity.Critical, $"{CommandBarConstants.MegaTextureBaseName}.tga"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.SingleComponent.cs b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.SingleComponent.cs
new file mode 100644
index 0000000..4a0d951
--- /dev/null
+++ b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.SingleComponent.cs
@@ -0,0 +1,74 @@
+using AET.ModVerify.Reporting;
+using PG.StarWarsGame.Engine;
+using PG.StarWarsGame.Engine.CommandBar.Components;
+using System;
+using System.Threading;
+
+namespace AET.ModVerify.Verifiers.CommandBar;
+
+partial class CommandBarVerifier
+{
+ private void VerifySingleComponent(CommandBarBaseComponent component, CancellationToken token)
+ {
+ VerifyName(component);
+ VerifyCommandBarModel(component, token);
+ VerifyComponentBone(component);
+
+ // TODO: Textures
+ }
+
+ private void VerifyName(CommandBarBaseComponent component)
+ {
+ if (component.Name.Length > PGConstants.MaxCommandBarComponentNameBuffer)
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.NameTooLong,
+ // Deliberately not reporting the buffer length as max, as it's considered to be internal data
+ $"The CommandBarShellComponent name '{component.Name}' is too long. Maximum length is {PGConstants.MaxCommandBarComponentName}.",
+ VerificationSeverity.Critical, [], component.Name));
+ }
+ }
+
+ private void VerifyCommandBarModel(CommandBarBaseComponent component, CancellationToken token)
+ {
+ if (component is not CommandBarShellComponent shellComponent)
+ return;
+
+ if (shellComponent.ModelPath is null)
+ {
+ AddError(VerificationError.Create(this,
+ CommandBarShellNoModel, $"The CommandBarShellComponent '{component.Name}' has no model specified.",
+ VerificationSeverity.Error, [shellComponent.Name], shellComponent.Name));
+ return;
+ }
+
+ using var model = GameEngine.PGRender.LoadModelAndAnimations(shellComponent.ModelPath.AsSpan(), null);
+ if (model is null)
+ {
+ AddError(VerificationError.Create(this,
+ CommandBarShellNoModel, $"Could not find model '{shellComponent.ModelPath}' for CommandBarShellComponent '{component.Name}'.",
+ VerificationSeverity.Error, [shellComponent.Name], shellComponent.ModelPath));
+ return;
+ }
+
+ _modelVerifier.VerifyModelOrParticle(model.File, [shellComponent.Name], token);
+
+ if (model.Animations.Cout == 0)
+ return;
+
+ // TODO: Verify Animations
+
+ }
+
+ private void VerifyComponentBone(CommandBarBaseComponent component)
+ {
+ if (component is CommandBarShellComponent)
+ return;
+
+ if (component.Bone == -1)
+ {
+ AddError(VerificationError.Create(this,
+ CommandBarShellNoModel, $"The CommandBar component '{component.Name}' is not connected to a shell component.",
+ VerificationSeverity.Warning, component.Name));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.cs b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.cs
new file mode 100644
index 0000000..4894673
--- /dev/null
+++ b/src/ModVerify/Verifiers/CommandBar/CommandBarVerifier.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Linq;
+using System.Threading;
+using AET.ModVerify.Settings;
+using AET.ModVerify.Verifiers.Commons;
+using PG.StarWarsGame.Engine;
+using PG.StarWarsGame.Engine.CommandBar;
+
+namespace AET.ModVerify.Verifiers.CommandBar;
+
+public partial class CommandBarVerifier : GameVerifier
+{
+ public const string CommandBarNoShellsGroup = "CMDBAR00";
+ public const string CommandBarManyShellsGroup = "CMDBAR01";
+ public const string CommandBarNoShellsComponentInShellGroup = "CMDBAR02";
+ public const string CommandBarUnsupportedComponent = "CMDBAR03";
+ public const string CommandBarShellNoModel = "CMDBAR04";
+
+ private readonly SingleModelVerifier _modelVerifier;
+ private readonly TextureVerifier _textureVerifier;
+
+ public override string FriendlyName => "CommandBar";
+
+ public ICommandBarGameManager CommandBar { get; }
+
+ public CommandBarVerifier(IStarWarsGameEngine gameEngine, GameVerifySettings settings, IServiceProvider serviceProvider)
+ : base(gameEngine, settings, serviceProvider)
+ {
+ CommandBar = gameEngine.CommandBar;
+ _modelVerifier = new SingleModelVerifier(this);
+ _textureVerifier = new TextureVerifier(this);
+ }
+
+ public override void Verify(CancellationToken token)
+ {
+ var progress = 0.0d;
+ OnProgress(progress, "Verifying MegaTexture");
+ VerifyMegaTexture(token);
+ progress = 1 / 3.0;
+ OnProgress(progress, "Verifying CommandBar Shell");
+ VerifyCommandBarShellsGroups();
+ progress = 2 / 3.0;
+ OnProgress(progress, "Verifying CommandBar components");
+ VerifyCommandBarComponents(token, progress);
+
+ foreach (var subError in _modelVerifier.VerifyErrors.Concat(_textureVerifier.VerifyErrors))
+ AddError(subError);
+
+ progress = 1.0;
+ OnProgress(progress, null);
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Commons/Audio/AudioFileInfo.cs b/src/ModVerify/Verifiers/Commons/Audio/AudioFileInfo.cs
new file mode 100644
index 0000000..ee428cb
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/Audio/AudioFileInfo.cs
@@ -0,0 +1,15 @@
+namespace AET.ModVerify.Verifiers.Commons;
+
+public class AudioFileInfo
+{
+ public string SampleName { get; }
+ public AudioFileType ExpectedType { get; }
+ public bool IsAmbient { get; }
+
+ public AudioFileInfo(string sampleName, AudioFileType expectedType, bool isAmbient)
+ {
+ SampleName = sampleName;
+ ExpectedType = expectedType;
+ IsAmbient = isAmbient;
+ }
+}
diff --git a/src/ModVerify/Verifiers/Commons/Audio/AudioFileType.cs b/src/ModVerify/Verifiers/Commons/Audio/AudioFileType.cs
new file mode 100644
index 0000000..05ea0bc
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/Audio/AudioFileType.cs
@@ -0,0 +1,7 @@
+namespace AET.ModVerify.Verifiers.Commons;
+
+public enum AudioFileType
+{
+ Wav,
+ Mp3
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Commons/AudioFileVerifier.cs b/src/ModVerify/Verifiers/Commons/AudioFileVerifier.cs
new file mode 100644
index 0000000..4537a64
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/AudioFileVerifier.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using AET.ModVerify.Reporting;
+using AET.ModVerify.Settings;
+using PG.StarWarsGame.Engine;
+using System.Threading;
+using Microsoft.Extensions.DependencyInjection;
+using AET.ModVerify.Verifiers.Caching;
+
+namespace AET.ModVerify.Verifiers.Commons;
+
+public class AudioFileVerifier : GameVerifier
+{
+ private readonly IAlreadyVerifiedCache? _alreadyVerifiedCache;
+
+ public AudioFileVerifier(GameVerifierBase parent) : base(parent)
+ {
+ _alreadyVerifiedCache = Services.GetService();
+ }
+
+ public AudioFileVerifier(IGameVerifierInfo? parent,
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider) : base(parent, gameEngine, settings, serviceProvider)
+ {
+ _alreadyVerifiedCache = serviceProvider.GetService();
+ }
+
+ public override string FriendlyName => "Audio File format";
+
+ public override void Verify(AudioFileInfo sampleInfo, IReadOnlyCollection contextInfo, CancellationToken token)
+ {
+ var cached = _alreadyVerifiedCache?.GetEntry(sampleInfo.SampleName);
+
+ if (cached?.AlreadyVerified is true)
+ {
+ if (!cached.Value.AssetExists)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.FileNotFound,
+ $"Audio file '{sampleInfo.SampleName}' could not be found.",
+ VerificationSeverity.Error,
+ [.. contextInfo],
+ sampleInfo.SampleName));
+ }
+ return;
+ }
+
+
+ var sampleString = sampleInfo.SampleName;
+
+ using var sampleStream = Repository.TryOpenFile(sampleString.AsSpan());
+
+ _alreadyVerifiedCache?.TryAddEntry(sampleInfo.SampleName, sampleStream is not null);
+
+ if (sampleStream is null)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.FileNotFound,
+ $"Audio file '{sampleString}' could not be found.",
+ VerificationSeverity.Error,
+ [..contextInfo],
+ sampleString));
+ return;
+ }
+
+ if (sampleInfo.ExpectedType == AudioFileType.Mp3)
+ {
+ // TODO: MP3 support to be implemented
+ return;
+ }
+
+ using var binaryReader = new BinaryReader(sampleStream);
+
+ // Skip Header + "fmt "
+ binaryReader.BaseStream.Seek(16, SeekOrigin.Begin);
+
+ var fmtSize = binaryReader.ReadInt32();
+ var format = (WaveFormats)binaryReader.ReadInt16();
+ var channels = binaryReader.ReadInt16();
+
+ var sampleRate = binaryReader.ReadInt32();
+ var bytesPerSecond = binaryReader.ReadInt32();
+
+ var frameSize = binaryReader.ReadInt16();
+ var bitPerSecondPerChannel = binaryReader.ReadInt16();
+
+ if (format != WaveFormats.PCM)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.SampleNotPCM,
+ $"Audio file '{sampleString}' has an invalid format '{format}'. Supported is {WaveFormats.PCM}",
+ VerificationSeverity.Error,
+ [..contextInfo],
+ sampleString));
+ }
+
+ if (channels > 1 && !sampleInfo.IsAmbient)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.SampleNotMono,
+ $"Audio file '{sampleString}' is not mono audio.",
+ VerificationSeverity.Information,
+ sampleString));
+ }
+
+ if (sampleRate > 48_000)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.InvalidSampleRate,
+ $"Audio file '{sampleString}' has a too high sample rate of {sampleRate}. Maximum is 48.000Hz.",
+ VerificationSeverity.Error,
+ [..contextInfo],
+ sampleString));
+ }
+
+ if (bitPerSecondPerChannel > 16)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.InvalidBitsPerSeconds,
+ $"Audio file '{sampleString}' has an invalid bit size of {bitPerSecondPerChannel}. Supported are 16bit.",
+ VerificationSeverity.Error,
+ [..contextInfo],
+ sampleString));
+ }
+ }
+
+ private enum WaveFormats
+ {
+ PCM = 1,
+ MSADPCM = 2,
+ IEEE_Float = 3,
+ }
+}
diff --git a/src/ModVerify/Verifiers/Commons/DuplicateVerifier.cs b/src/ModVerify/Verifiers/Commons/DuplicateVerifier.cs
new file mode 100644
index 0000000..7aa19e6
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/DuplicateVerifier.cs
@@ -0,0 +1,43 @@
+using AET.ModVerify.Reporting;
+using AET.ModVerify.Settings;
+using PG.StarWarsGame.Engine;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace AET.ModVerify.Verifiers.Commons;
+
+public sealed class DuplicateVerifier : GameVerifier
+{
+ public override string FriendlyName => "Duplicate Verifier";
+
+ public DuplicateVerifier(GameVerifierBase parent) : base(parent)
+ {
+ }
+
+ public DuplicateVerifier(
+ IGameVerifierInfo? parent,
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider)
+ : base(parent, gameEngine, settings, serviceProvider)
+ {
+ }
+
+ public override void Verify(IDuplicateVerificationContext toVerify, IReadOnlyCollection contextInfo, CancellationToken token)
+ {
+ foreach (var crc32 in toVerify.GetCrcs())
+ {
+ if (toVerify.HasDuplicates(crc32, out var entryNames, out var context, out var errorMessage))
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.Duplicate,
+ errorMessage,
+ VerificationSeverity.Error,
+ context,
+ entryNames));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Commons/Duplicates/IDuplicateVerificationContext.cs b/src/ModVerify/Verifiers/Commons/Duplicates/IDuplicateVerificationContext.cs
new file mode 100644
index 0000000..4301e54
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/Duplicates/IDuplicateVerificationContext.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using PG.Commons.Hashing;
+
+namespace AET.ModVerify.Verifiers.Commons;
+
+public interface IDuplicateVerificationContext
+{
+ string SourceName { get; }
+ IEnumerable GetCrcs();
+ bool HasDuplicates(Crc32 crc, out string entryNames, out IEnumerable duplicateContext, out string errorMessage);
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Commons/Duplicates/MtdDuplicateVerificationContext.cs b/src/ModVerify/Verifiers/Commons/Duplicates/MtdDuplicateVerificationContext.cs
new file mode 100644
index 0000000..624a0a6
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/Duplicates/MtdDuplicateVerificationContext.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using System.Linq;
+using PG.Commons.Hashing;
+using PG.StarWarsGame.Files.MTD.Files;
+
+namespace AET.ModVerify.Verifiers.Commons;
+
+internal sealed class MtdDuplicateVerificationContext(IMtdFile mtdFile) : IDuplicateVerificationContext
+{
+ public string SourceName => mtdFile.FileName;
+
+ public IEnumerable GetCrcs() => mtdFile.Content.Select(x => x.Crc32);
+
+ public bool HasDuplicates(Crc32 crc, out string entryNames, out IEnumerable duplicateContext, out string errorMessage)
+ {
+ var entries = mtdFile.Content.EntriesWithCrc(crc);
+ if (entries.Count > 1)
+ {
+ var firstEntry = entries.First();
+ entryNames = firstEntry.FileName;
+ duplicateContext = entries.Select(x => $"'{x.FileName}' (CRC: {x.Crc32})");
+ errorMessage = $"MTD File '{SourceName}' has duplicate definitions for CRC ({firstEntry}): " +
+ $"{string.Join(",", entries.Select(x => x.FileName))}";
+ return true;
+ }
+
+ entryNames = string.Empty;
+ duplicateContext = [];
+ errorMessage = string.Empty;
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Commons/Duplicates/NamedXmlObjectDuplicateVerificationContext.cs b/src/ModVerify/Verifiers/Commons/Duplicates/NamedXmlObjectDuplicateVerificationContext.cs
new file mode 100644
index 0000000..d50057d
--- /dev/null
+++ b/src/ModVerify/Verifiers/Commons/Duplicates/NamedXmlObjectDuplicateVerificationContext.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using PG.Commons.Hashing;
+using PG.StarWarsGame.Engine;
+using PG.StarWarsGame.Files.XML.Data;
+
+namespace AET.ModVerify.Verifiers.Commons;
+
+internal sealed class NamedXmlObjectDuplicateVerificationContext(string databaseName, IGameManager gameManager)
+ : IDuplicateVerificationContext
+ where T : NamedXmlObject
+{
+ public string SourceName => databaseName;
+
+ public IEnumerable GetCrcs() => gameManager.EntryKeys;
+
+ public bool HasDuplicates(Crc32 crc, out string entryNames, out IEnumerable duplicateContext, out string errorMessage)
+ {
+ var entries = gameManager.GetEntries(crc);
+ if (entries.Count > 1)
+ {
+ var firstEntry = entries.First();
+ entryNames = firstEntry.Name;
+ duplicateContext = entries.Select(x => $"'{x.Name}' - {x.Location}");
+ var message = $"{SourceName} '{firstEntry.Name}' ({firstEntry.Crc32}) has duplicate definitions: ";
+ message = entries.Aggregate(message, (current, entry) => current + $"['{entry.Name}' in {entry.Location.XmlFile}:{entry.Location.Line}] ");
+ errorMessage = message.TrimEnd();
+ return true;
+ }
+
+ entryNames = string.Empty;
+ duplicateContext = Array.Empty();
+ errorMessage = string.Empty;
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/Commons/ModelVerifier.cs b/src/ModVerify/Verifiers/Commons/SingleModelVerifier.cs
similarity index 80%
rename from src/ModVerify/Verifiers/Commons/ModelVerifier.cs
rename to src/ModVerify/Verifiers/Commons/SingleModelVerifier.cs
index 25704d1..fa621e1 100644
--- a/src/ModVerify/Verifiers/Commons/ModelVerifier.cs
+++ b/src/ModVerify/Verifiers/Commons/SingleModelVerifier.cs
@@ -4,6 +4,7 @@
using AET.ModVerify.Reporting;
using AET.ModVerify.Settings;
using AET.ModVerify.Utilities;
+using AET.ModVerify.Verifiers.Caching;
using Microsoft.Extensions.DependencyInjection;
using PG.StarWarsGame.Engine;
using PG.StarWarsGame.Files;
@@ -22,47 +23,93 @@ public sealed class SingleModelVerifier : GameVerifier
{
private const string ProxyAltIdentifier = "_ALT";
- private readonly TextureVeifier _textureVerifier;
+ private readonly TextureVerifier _textureVerifier;
private readonly IAlreadyVerifiedCache? _cache;
- public SingleModelVerifier(IGameVerifierInfo? parent,
+ public SingleModelVerifier(GameVerifierBase parent) : base(parent)
+ {
+ _textureVerifier = new TextureVerifier(this);
+ _cache = Services.GetService();
+ }
+
+ public SingleModelVerifier(
+ IGameVerifierInfo? parent,
IStarWarsGameEngine engine,
GameVerifySettings settings,
IServiceProvider serviceProvider) : base(parent, engine, settings, serviceProvider)
{
- _textureVerifier = new TextureVeifier(this, engine, settings, serviceProvider);
+ _textureVerifier = new TextureVerifier(this);
_cache = serviceProvider.GetService();
}
public override void Verify(string modelName, IReadOnlyCollection contextInfo, CancellationToken token)
{
- try
+ var cacheEntry = _cache?.GetEntry(modelName);
+ if (cacheEntry?.AlreadyVerified is true)
{
- _textureVerifier.Error += OnTextureError;
-
- var modelPath = BuildModelPath(modelName);
- VerifyAlamoFile(modelPath, contextInfo, token);
+ if (!cacheEntry.Value.AssetExists)
+ {
+ var error = VerificationError.Create(
+ this,
+ VerifierErrorCodes.FileNotFound,
+ $"Unable to find .ALO file '{modelName}'",
+ VerificationSeverity.Error,
+ contextInfo,
+ modelName);
+ AddError(error);
+ }
+ return;
}
- finally
+
+ var modelPath = BuildModelPath(modelName);
+ VerifyAlamoFile(modelPath, contextInfo, token, out var modelExists);
+
+ if (!modelExists)
{
- _textureVerifier.Error -= OnTextureError;
+ var error = VerificationError.Create(
+ this,
+ VerifierErrorCodes.FileNotFound,
+ $"Unable to find .ALO file '{modelName}'",
+ VerificationSeverity.Error,
+ contextInfo,
+ modelName);
+ AddError(error);
}
+
+ _cache?.TryAddEntry(modelName, modelExists);
+
+ foreach (var textureError in _textureVerifier.VerifyErrors)
+ AddError(textureError);
}
- private void OnTextureError(object sender, VerificationErrorEventArgs e)
+ public void VerifyModelOrParticle(
+ IAloFile aloFile,
+ IReadOnlyCollection contextInfo,
+ CancellationToken token)
{
- AddError(e.Error);
+ switch (aloFile)
+ {
+ case IAloModelFile model:
+ VerifyModel(model, contextInfo, token);
+ break;
+ case IAloParticleFile particle:
+ VerifyParticle(particle, contextInfo);
+ break;
+ default:
+ throw new InvalidOperationException("The data stream is neither a model nor particle.");
+ }
}
- private void VerifyAlamoFile(string modelPath, IReadOnlyCollection contextInfo, CancellationToken token)
+ private void VerifyAlamoFile(
+ string modelPath,
+ IReadOnlyCollection contextInfo,
+ CancellationToken token,
+ out bool modelExists)
{
token.ThrowIfCancellationRequested();
- var modelName = FileSystem.Path.GetFileName(modelPath.AsSpan());
+ modelExists = true;
- if (_cache?.TryAddEntry(modelName) == false)
- return;
-
IAloFile? aloFile = null;
try
{
@@ -74,22 +121,16 @@ private void VerifyAlamoFile(string modelPath, IReadOnlyCollection conte
{
var aloFilePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), modelPath.AsSpan()).ToString();
var message = $"'{aloFilePath}' is corrupted: {e.Message}";
- AddError(VerificationError.Create(VerifierChain, VerifierErrorCodes.FileCorrupt, message,
+ AddError(VerificationError.Create(this, VerifierErrorCodes.BinaryFileCorrupt, message,
VerificationSeverity.Critical, contextInfo, aloFilePath));
return;
}
+ // Because throwsException is true, we know that if aloFile is null,
+ // the file does not exist
if (aloFile is null)
{
- var modelNameString = modelName.ToString();
- var error = VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes.FileNotFound,
- $"Unable to find .ALO file '{modelNameString}'",
- VerificationSeverity.Error,
- contextInfo,
- modelNameString);
- AddError(error);
+ modelExists = false;
return;
}
@@ -101,24 +142,6 @@ private void VerifyAlamoFile(string modelPath, IReadOnlyCollection conte
}
}
- private void VerifyModelOrParticle(
- IAloFile aloFile,
- IReadOnlyCollection contextInfo,
- CancellationToken token)
- {
- switch (aloFile)
- {
- case IAloModelFile model:
- VerifyModel(model, contextInfo, token);
- break;
- case IAloParticleFile particle:
- VerifyParticle(particle, contextInfo);
- break;
- default:
- throw new InvalidOperationException("The data stream is neither a model nor particle.");
- }
- }
-
private void VerifyParticle(IAloParticleFile file, IReadOnlyCollection contextInfo)
{
foreach (var texture in file.Content.Textures)
@@ -129,7 +152,7 @@ private void VerifyParticle(IAloParticleFile file, IReadOnlyCollection c
{
var particlePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), file.FilePath.AsSpan()).ToString();
AddError(VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.InvalidFilePath,
$"Invalid texture file name '{texture}' in particle '{particlePath}'",
VerificationSeverity.Error,
@@ -144,7 +167,7 @@ private void VerifyParticle(IAloParticleFile file, IReadOnlyCollection c
{
var particlePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), file.FilePath.AsSpan()).ToString();
AddError(VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.InvalidParticleName,
$"The particle name '{file.Content.Name}' does not match file name '{particlePath}'",
VerificationSeverity.Error,
@@ -163,7 +186,7 @@ private void VerifyModel(IAloModelFile file, IReadOnlyCollection context
{
var modelFilePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), file.FilePath.AsSpan()).ToString();
AddError(VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.InvalidFilePath,
$"Invalid texture file name '{texture}' in model '{modelFilePath}'",
VerificationSeverity.Error,
@@ -181,7 +204,7 @@ private void VerifyModel(IAloModelFile file, IReadOnlyCollection context
var modelFilePath =
FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), file.FilePath.AsSpan()).ToString();
AddError(VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.InvalidFilePath,
$"Invalid shader file name '{shader}' in model '{modelFilePath}'",
VerificationSeverity.Error,
@@ -200,7 +223,7 @@ private void VerifyModel(IAloModelFile file, IReadOnlyCollection context
var modelFilePath = FileSystem.Path
.GetGameStrippedPath(Repository.Path.AsSpan(), file.FilePath.AsSpan()).ToString();
AddError(VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.InvalidFilePath,
$"Invalid proxy file name '{proxy}' for model '{modelFilePath}'",
VerificationSeverity.Error,
@@ -223,22 +246,21 @@ private void VerifyProxyExists(IPetroglyphFileHolder model, string proxy, IReadO
var proxyPath = BuildModelPath(proxyName);
var modelFilePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), model.FilePath.AsSpan()).ToString();
+
+ VerifyAlamoFile(proxyPath, [..contextInfo, modelFilePath], token, out var proxyExists);
- if (!Repository.ModelRepository.FileExists(proxyPath))
+ if (!proxyExists)
{
var message = $"Proxy particle '{proxyName}' not found for model '{modelFilePath}'";
var error = VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.FileNotFound,
- message,
- VerificationSeverity.Error,
- [..contextInfo, modelFilePath],
+ message,
+ VerificationSeverity.Error,
+ [.. contextInfo, modelFilePath],
proxyName);
AddError(error);
- return;
}
-
- VerifyAlamoFile(proxyPath, [..contextInfo, modelFilePath], token);
}
private void VerifyShaderExists(IPetroglyphFileHolder model, string shader, IReadOnlyCollection contextInfo)
@@ -251,7 +273,7 @@ private void VerifyShaderExists(IPetroglyphFileHolder model, string shader, IRea
var modelFilePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), model.FilePath.AsSpan()).ToString();
var message = $"Shader effect '{shader}' not found for model '{modelFilePath}'.";
var error = VerificationError.Create(
- VerifierChain,
+ this,
VerifierErrorCodes.FileNotFound,
message,
VerificationSeverity.Error,
diff --git a/src/ModVerify/Verifiers/Commons/TextureVeifier.cs b/src/ModVerify/Verifiers/Commons/TextureVerifier.cs
similarity index 68%
rename from src/ModVerify/Verifiers/Commons/TextureVeifier.cs
rename to src/ModVerify/Verifiers/Commons/TextureVerifier.cs
index 1bd3a08..e7709e3 100644
--- a/src/ModVerify/Verifiers/Commons/TextureVeifier.cs
+++ b/src/ModVerify/Verifiers/Commons/TextureVerifier.cs
@@ -4,19 +4,24 @@
using System.Threading;
using AET.ModVerify.Reporting;
using AET.ModVerify.Settings;
-using Microsoft.Extensions.DependencyInjection;
using PG.StarWarsGame.Engine;
namespace AET.ModVerify.Verifiers.Commons;
-public sealed class TextureVeifier(
- IGameVerifierInfo? parent,
- IStarWarsGameEngine gameEngine,
- GameVerifySettings settings,
- IServiceProvider serviceProvider)
- : GameVerifier(parent, gameEngine, settings, serviceProvider)
+public sealed class TextureVerifier : GameVerifier
{
- private readonly IAlreadyVerifiedCache? _cache = serviceProvider.GetService();
+ public TextureVerifier(GameVerifierBase parent) : base(parent)
+ {
+ }
+
+ public TextureVerifier(
+ IGameVerifierInfo? parent,
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider) :
+ base(parent, gameEngine, settings, serviceProvider)
+ {
+ }
public override void Verify(string texturePath, IReadOnlyCollection contextInfo, CancellationToken token)
{
@@ -27,10 +32,6 @@ public void Verify(ReadOnlySpan textureName, IReadOnlyCollection c
{
token.ThrowIfCancellationRequested();
-
- if (_cache?.TryAddEntry(textureName) == false)
- return;
-
if (Repository.TextureRepository.FileExists(textureName, false, out var tooLongPath))
return;
@@ -38,7 +39,7 @@ public void Verify(ReadOnlySpan textureName, IReadOnlyCollection c
if (tooLongPath)
{
- AddError(VerificationError.Create(VerifierChain, VerifierErrorCodes.FilePathTooLong,
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FilePathTooLong,
$"Could not find texture '{pathString}' because the engine resolved a path that is too long.",
VerificationSeverity.Error, contextInfo, pathString));
return;
@@ -55,7 +56,7 @@ public void Verify(ReadOnlySpan textureName, IReadOnlyCollection c
messageBuilder.Append('.');
- AddError(VerificationError.Create(VerifierChain, VerifierErrorCodes.FileNotFound,
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound,
messageBuilder.ToString(),
VerificationSeverity.Error, contextInfo, pathString));
}
diff --git a/src/ModVerify/Verifiers/DuplicateNameFinder.cs b/src/ModVerify/Verifiers/DuplicateNameFinder.cs
deleted file mode 100644
index 0b3b585..0000000
--- a/src/ModVerify/Verifiers/DuplicateNameFinder.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using AET.ModVerify.Reporting;
-using AET.ModVerify.Settings;
-using AnakinRaW.CommonUtilities.Collections;
-using PG.Commons.Hashing;
-using PG.StarWarsGame.Engine;
-using PG.StarWarsGame.Engine.Xml;
-using PG.StarWarsGame.Files.MTD.Data;
-using PG.StarWarsGame.Files.MTD.Files;
-
-namespace AET.ModVerify.Verifiers;
-
-public sealed class DuplicateNameFinder(
- IStarWarsGameEngine gameEngine,
- GameVerifySettings settings,
- IServiceProvider serviceProvider)
- : GameVerifier(null, gameEngine, settings, serviceProvider)
-{
- public override string FriendlyName => "Duplicates";
-
- public override void Verify(CancellationToken token)
- {
- CheckXmlObjectsForDuplicates("GameObject", GameEngine.GameObjectTypeManager);
- CheckXmlObjectsForDuplicates("SFXEvent", GameEngine.SfxGameManager);
-
- if (GameEngine.GuiDialogManager.MtdFile is not null)
- CheckMtdForDuplicates(GameEngine.GuiDialogManager.MtdFile);
-
- if (GameEngine.CommandBar.MegaTextureFile is not null)
- {
- if (!GameEngine.CommandBar.MegaTextureFile.FilePath.Equals(GameEngine.GuiDialogManager.MtdFile?.FileName))
- CheckMtdForDuplicates(GameEngine.CommandBar.MegaTextureFile);
- }
- }
-
- private void CheckForDuplicateCrcEntries(
- string sourceName,
- TSource source,
- Func> crcSelector,
- Func> entrySelector,
- Func entryToStringSelector,
- Func, IEnumerable> contextSelector,
- Func, string, string> errorMessageCreator)
- {
- foreach (var crc32 in crcSelector(source))
- {
- var entries = entrySelector(source, crc32);
- if (entries.Count > 1)
- {
- var entryNames = entryToStringSelector(entries.First());
- var context = contextSelector(entries);
- AddError(VerificationError.Create(
- VerifierChain,
- VerifierErrorCodes.DuplicateFound,
- errorMessageCreator(entries, sourceName),
- VerificationSeverity.Error,
- context,
- entryNames));
- }
- }
- }
-
- private void CheckMtdForDuplicates(IMtdFile mtdFile)
- {
- CheckForDuplicateCrcEntries(
- mtdFile.FileName,
- mtdFile,
- mtd => mtd.Content.Select(x => x.Crc32),
- (mtd, crc32) => mtd.Content.EntriesWithCrc(crc32),
- entry => entry.FileName,
- entries => entries.Select(x => $"'{x.FileName}' (CRC: {x.Crc32})"),
- CreateDuplicateMtdErrorMessage);
- }
-
- private void CheckXmlObjectsForDuplicates(string databaseName, IGameManager gameManager) where T : NamedXmlObject
- {
- CheckForDuplicateCrcEntries(
- databaseName,
- gameManager,
- manager => manager.EntryKeys,
- (manager, crc32) => manager.GetEntries(crc32),
- entry => entry.Name,
- entries => entries.Select(x => $"'{x.Name}' - {x.Location}"),
- CreateDuplicateXmlErrorMessage);
- }
-
- private static string CreateDuplicateMtdErrorMessage(ImmutableFrugalList entries, string fileName)
- {
- var firstEntry = entries.First();
- return $"MTD File '{fileName}' has duplicate definitions for CRC ({firstEntry}): {string.Join(",", entries.Select(x => x.FileName))}";
- }
-
- private static string CreateDuplicateXmlErrorMessage(ImmutableFrugalList entries, string databaseName) where T : NamedXmlObject
- {
- var firstEntry = entries.First();
- var message = $"{databaseName} '{firstEntry.Name}' ({firstEntry.Crc32}) has duplicate definitions: ";
- foreach (var entry in entries)
- message += $"['{entry.Name}' in {entry.Location.XmlFile}:{entry.Location.Line}] ";
- return message.TrimEnd();
- }
-}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameEngineErrorCollector.cs b/src/ModVerify/Verifiers/Engine/GameEngineErrorCollector.cs
similarity index 84%
rename from src/ModVerify/Verifiers/GameEngineErrorCollector.cs
rename to src/ModVerify/Verifiers/Engine/GameEngineErrorCollector.cs
index 6475ea7..70c1cb3 100644
--- a/src/ModVerify/Verifiers/GameEngineErrorCollector.cs
+++ b/src/ModVerify/Verifiers/Engine/GameEngineErrorCollector.cs
@@ -2,17 +2,18 @@
using System.Collections.Generic;
using System.Threading;
using AET.ModVerify.Reporting;
-using AET.ModVerify.Reporting.Reporters.Engine;
+using AET.ModVerify.Reporting.Engine;
using AET.ModVerify.Settings;
using PG.StarWarsGame.Engine;
-namespace AET.ModVerify.Verifiers;
+namespace AET.ModVerify.Verifiers.Engine;
public sealed class GameEngineErrorCollector(
IGameEngineErrorCollection errorCollection,
IStarWarsGameEngine gameEngine,
GameVerifySettings settings,
- IServiceProvider serviceProvider) : GameVerifier(null, gameEngine, settings, serviceProvider)
+ IServiceProvider serviceProvider)
+ : GameVerifier(gameEngine, settings, serviceProvider)
{
public override string FriendlyName => "Game Engine Initialization";
diff --git a/src/ModVerify/Verifiers/Engine/HardcodedAssetsVerifier.cs b/src/ModVerify/Verifiers/Engine/HardcodedAssetsVerifier.cs
new file mode 100644
index 0000000..69a6800
--- /dev/null
+++ b/src/ModVerify/Verifiers/Engine/HardcodedAssetsVerifier.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading;
+using AET.ModVerify.Settings;
+using AET.ModVerify.Verifiers.Commons;
+using PG.StarWarsGame.Engine;
+
+namespace AET.ModVerify.Verifiers.Engine;
+
+public sealed class HardcodedAssetsVerifier : GameVerifier
+{
+ private readonly SingleModelVerifier _modelVerifier;
+
+ public HardcodedAssetsVerifier(IStarWarsGameEngine gameEngine, GameVerifySettings settings, IServiceProvider serviceProvider)
+ : base(gameEngine, settings, serviceProvider)
+ {
+ _modelVerifier = new SingleModelVerifier(this);
+ }
+
+ public override void Verify(CancellationToken token)
+ {
+ OnProgress(0.0d, "Verifying Hardcoded Models");
+ VerifyModels(token);
+ OnProgress(1.0, null);
+ }
+
+ private void VerifyModels(CancellationToken token)
+ {
+ var models = HardcodedEngineAssets.GetHardcodedModels(GameEngine.EngineType);
+
+ foreach (var model in models)
+ _modelVerifier.Verify(model, [], token);
+
+ foreach (var error in _modelVerifier.VerifyErrors)
+ AddError(error);
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.Icons.cs b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.Icons.cs
new file mode 100644
index 0000000..36541bb
--- /dev/null
+++ b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.Icons.cs
@@ -0,0 +1,41 @@
+using AET.ModVerify.Reporting;
+using PG.StarWarsGame.Engine.GameObjects;
+
+namespace AET.ModVerify.Verifiers.GameObjects;
+
+public sealed partial class GameObjectTypeVerifier
+{
+ private void VerifyIcons(GameObject gameObject, string[] context)
+ {
+ VerifyObjectIcon(gameObject, context);
+ }
+
+ private void VerifyObjectIcon(GameObject gameObject, string[] context)
+ {
+ if (string.IsNullOrEmpty(gameObject.IconName))
+ return;
+
+ /*
+ * The engine loads game object icons with different strategies, depending on where the icon is displayed:
+ * 1. the game loads the texture from MTD and supports the faction prefixes e.g, r_ or e_
+ * Faction prefixes have higher priority than the non-prefix versions. The player's faction (not the object owner) is used.
+ * This applies to all command bar components (such as build buttons)
+ * 2. the game loads the texture form MTD and does NOT support faction prefix.
+ * If the texture is not found, the game searches the texture with forced .dds name in the Textures folder.
+ * This applies to the GUI dialogs (such as battle summary)
+ * 3. the game only loads the texture from MTD NOT supporting faction prefix nor textures folder fallback.
+ * This applies (only) to the neutralize hero dialog
+ *
+ * We only verify whether the icon exists in the MTD data, as this is the primary case to all strategies
+ * (and it's what really should only be used for mods)
+ * Faction-specific icons are not verified as they are statically not decidable.
+ */
+
+ if (!GameEngine.CommandBar.IconExists(gameObject))
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound,
+ $"Could not find icon '{gameObject.IconName}' for game object type '{gameObject.Name}'.",
+ VerificationSeverity.Warning, context, gameObject.IconName!));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.Models.cs b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.Models.cs
new file mode 100644
index 0000000..39699a7
--- /dev/null
+++ b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.Models.cs
@@ -0,0 +1,13 @@
+using PG.StarWarsGame.Engine.GameObjects;
+using System.Threading;
+
+namespace AET.ModVerify.Verifiers.GameObjects;
+
+public sealed partial class GameObjectTypeVerifier
+{
+ private void VerifyModels(GameObject gameObject, string[] context, CancellationToken token)
+ {
+ foreach (var model in GameEngine.GameObjectTypeManager.GetModels(gameObject))
+ _singleModelVerifier.Verify(model, context, token);
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.XRef.cs b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.XRef.cs
new file mode 100644
index 0000000..1bca0e9
--- /dev/null
+++ b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.XRef.cs
@@ -0,0 +1,44 @@
+using System.Linq;
+using AET.ModVerify.Reporting;
+using PG.StarWarsGame.Engine.GameObjects;
+
+namespace AET.ModVerify.Verifiers.GameObjects;
+
+public sealed partial class GameObjectTypeVerifier
+{
+ private void VerifyXRefs(GameObject gameObject, string[] context)
+ {
+ if (!string.IsNullOrEmpty(gameObject.VariantOfExistingTypeName) && gameObject.VariantOfExistingType is null)
+ {
+ AddError(VerificationError.Create(
+ this,
+ VerifierErrorCodes.MissingXRef,
+ $"Missing base type '{gameObject.VariantOfExistingTypeName}' for GameObject '{gameObject.Name}'",
+ VerificationSeverity.Critical,
+ [..context, "VariantOfExistingType"],
+ gameObject.VariantOfExistingTypeName));
+ }
+
+ VerifyCompanyUnits(gameObject, context);
+ }
+
+ private void VerifyCompanyUnits(GameObject gameObject, string[] context)
+ {
+ if (gameObject.GroundCompanyUnits.Count == 0)
+ return;
+
+ var uniqueCompanyUnits = gameObject.GroundCompanyUnits
+ .Select(x => x.ToUpperInvariant())
+ .Distinct();
+
+ foreach (var companyUnit in uniqueCompanyUnits)
+ {
+ if (GameEngine.GameObjectTypeManager.FindObjectType(companyUnit) is null)
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.MissingXRef,
+ $"Missing company unit '{companyUnit}' for GameObject '{gameObject.Name}'",
+ VerificationSeverity.Critical, [..context, "CompanyUnits"], companyUnit));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.cs b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.cs
new file mode 100644
index 0000000..66d4672
--- /dev/null
+++ b/src/ModVerify/Verifiers/GameObjects/GameObjectTypeVerifier.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Threading;
+using AET.ModVerify.Reporting;
+using AET.ModVerify.Settings;
+using AET.ModVerify.Verifiers.Commons;
+using PG.StarWarsGame.Engine;
+using PG.StarWarsGame.Engine.GameObjects;
+
+namespace AET.ModVerify.Verifiers.GameObjects;
+
+// TODO: Add GameObjectTypeVerifier and check that LandModelTerrainOverride is correct (all keys correct, no dups)
+public sealed partial class GameObjectTypeVerifier : NamedGameEntityVerifier
+{
+ private readonly SingleModelVerifier _singleModelVerifier;
+
+ public override string FriendlyName => "GameObjectType Verifier";
+
+ public override IGameManager GameManager => GameEngine.GameObjectTypeManager;
+
+ public override string EntityTypeName => "GameObjectType";
+
+ public GameObjectTypeVerifier(
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider)
+ : base(gameEngine, settings, serviceProvider)
+ {
+ _singleModelVerifier = new SingleModelVerifier(this);
+ }
+
+ protected override void VerifyEntity(GameObject entity, string[] context, double progress, CancellationToken token)
+ {
+ if (entity.Name.Length >= PGConstants.MaxGameObjectTypeName)
+ {
+ AddError(VerificationError.Create(this, VerifierErrorCodes.NameTooLong,
+ $"The GameObjectType name '{entity.Name}' is too long. Maximum length is {PGConstants.MaxGameObjectTypeName}.",
+ VerificationSeverity.Critical, entity.Name));
+ }
+ VerifyXRefs(entity, context);
+ VerifyModels(entity, context, token);
+ VerifyIcons(entity, context);
+ }
+
+ protected override void PostEntityVerify(CancellationToken token)
+ {
+ foreach (var modelError in _singleModelVerifier.VerifyErrors)
+ AddError(modelError);
+ }
+}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameVerifier.cs b/src/ModVerify/Verifiers/GameVerifier.cs
index aebfe94..83871d9 100644
--- a/src/ModVerify/Verifiers/GameVerifier.cs
+++ b/src/ModVerify/Verifiers/GameVerifier.cs
@@ -6,22 +6,50 @@
namespace AET.ModVerify.Verifiers;
-public abstract class GameVerifier(
- IGameVerifierInfo? parent,
- IStarWarsGameEngine gameEngine,
- GameVerifySettings settings,
- IServiceProvider serviceProvider)
- : GameVerifierBase(parent, gameEngine, settings, serviceProvider) where T : notnull
+public abstract class GameVerifier : GameVerifierBase where T : notnull
{
+ protected GameVerifier(
+ IGameVerifierInfo? parent,
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider) : base(parent, gameEngine, settings, serviceProvider)
+ {
+ }
+ protected GameVerifier(GameVerifierBase parent) : base(parent)
+ {
+ }
+
+ protected GameVerifier(
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider) : base(gameEngine, settings, serviceProvider)
+ {
+ }
+
public abstract void Verify(T toVerify, IReadOnlyCollection contextInfo, CancellationToken token);
}
-public abstract class GameVerifier(
- IGameVerifierInfo? parent,
- IStarWarsGameEngine gameEngine,
- GameVerifySettings settings,
- IServiceProvider serviceProvider)
- : GameVerifierBase(parent, gameEngine, settings, serviceProvider)
+public abstract class GameVerifier : GameVerifierBase
{
+ protected GameVerifier(
+ IGameVerifierInfo? parent,
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider)
+ : base(parent, gameEngine, settings, serviceProvider)
+ {
+ }
+ protected GameVerifier(GameVerifierBase parent) : base(parent)
+ {
+ }
+
+ protected GameVerifier(
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider)
+ : base(gameEngine, settings, serviceProvider)
+ {
+ }
+
public abstract void Verify(CancellationToken token);
}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GameVerifierBase.cs b/src/ModVerify/Verifiers/GameVerifierBase.cs
index 02bacc4..2da47bc 100644
--- a/src/ModVerify/Verifiers/GameVerifierBase.cs
+++ b/src/ModVerify/Verifiers/GameVerifierBase.cs
@@ -7,8 +7,11 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Abstractions;
-using AET.ModVerify.Pipeline.Progress;
+using AET.ModVerify.Progress;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
using PG.StarWarsGame.Engine;
+using AET.ModVerify.Verifiers.Utilities;
namespace AET.ModVerify.Verifiers;
@@ -22,6 +25,7 @@ public abstract class GameVerifierBase : IGameVerifierInfo
protected readonly IFileSystem FileSystem;
protected readonly IServiceProvider Services;
protected readonly GameVerifySettings Settings;
+ protected readonly ILogger Logger;
public IReadOnlyCollection VerifyErrors => [.. _verifyErrors.Keys];
@@ -35,7 +39,23 @@ public abstract class GameVerifierBase : IGameVerifierInfo
protected IGameRepository Repository => GameEngine.GameRepository;
- protected IReadOnlyList VerifierChain { get; }
+ public IReadOnlyList VerifierChain { get; }
+
+
+ protected GameVerifierBase(GameVerifierBase parent)
+ : this(parent, parent.GameEngine, parent.Settings, parent.Services)
+ {
+ if (parent == null)
+ throw new ArgumentNullException(nameof(parent));
+ }
+
+ protected GameVerifierBase(
+ IStarWarsGameEngine gameEngine,
+ GameVerifySettings settings,
+ IServiceProvider serviceProvider)
+ : this (null, gameEngine, settings, serviceProvider)
+ {
+ }
protected GameVerifierBase(
IGameVerifierInfo? parent,
@@ -45,12 +65,13 @@ protected GameVerifierBase(
{
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
+ Logger = serviceProvider.GetService()?.CreateLogger(GetType()) ?? NullLogger.Instance;
FileSystem = serviceProvider.GetRequiredService();
Services = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
Parent = parent;
Settings = settings ?? throw new ArgumentNullException(nameof(settings));
GameEngine = gameEngine ?? throw new ArgumentNullException(nameof(gameEngine));
- VerifierChain = CreateVerifierChain();
+ VerifierChain = this.GetVerifierChain();
}
protected void AddError(VerificationError error)
@@ -80,18 +101,4 @@ protected void OnProgress(double progress, string? message)
{
Progress?.Invoke(this, new(progress, message));
}
-
- private IReadOnlyList CreateVerifierChain()
- {
- var verifierChain = new List { this };
-
- var parent = Parent;
- while (parent != null)
- {
- verifierChain.Insert(0, parent);
- parent = parent.Parent;
- }
-
- return verifierChain;
- }
}
\ No newline at end of file
diff --git a/src/ModVerify/Verifiers/GuiDialogs/GuiDialogsVerifier.cs b/src/ModVerify/Verifiers/GuiDialogs/GuiDialogsVerifier.cs
index 435c5de..a33f900 100644
--- a/src/ModVerify/Verifiers/GuiDialogs/GuiDialogsVerifier.cs
+++ b/src/ModVerify/Verifiers/GuiDialogs/GuiDialogsVerifier.cs
@@ -1,5 +1,6 @@
using AET.ModVerify.Reporting;
using AET.ModVerify.Settings;
+using AET.ModVerify.Verifiers.Caching;
using AET.ModVerify.Verifiers.Commons;
using Microsoft.Extensions.DependencyInjection;
using PG.StarWarsGame.Engine;
@@ -8,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text;
using System.Threading;
namespace AET.ModVerify.Verifiers.GuiDialogs;
@@ -16,32 +18,29 @@ sealed class GuiDialogsVerifier : GameVerifier
{
internal const string DefaultComponentIdentifier = "<>";
- private static readonly GuiComponentType[] GuiComponentTypes =
+ private static readonly IReadOnlyList GuiComponentTypes =
Enum.GetValues(typeof(GuiComponentType)).OfType().ToArray();
private readonly IAlreadyVerifiedCache? _cache;
- private readonly TextureVeifier _textureVerifier;
+ private readonly TextureVerifier _textureVerifier;
- public GuiDialogsVerifier(IStarWarsGameEngine gameEngine,
+ public GuiDialogsVerifier(
+ IStarWarsGameEngine gameEngine,
GameVerifySettings settings,
- IServiceProvider serviceProvider) : base(null, gameEngine, settings, serviceProvider)
+ IServiceProvider serviceProvider)
+ : base(gameEngine, settings, serviceProvider)
{
_cache = serviceProvider.GetService();
- _textureVerifier = new TextureVeifier(this, gameEngine, settings, serviceProvider);
+ _textureVerifier = new TextureVerifier(this);
}
public override void Verify(CancellationToken token)
{
- try
- {
- _textureVerifier.Error += OnTextureError;
- VerifyMegaTexturesExist(token);
- VerifyGuiTextures();
- }
- finally
- {
- _textureVerifier.Error -= OnTextureError;
- }
+ VerifyMegaTexturesExist(token);
+ VerifyGuiTextures();
+
+ foreach (var textureError in _textureVerifier.VerifyErrors)
+ AddError(textureError);
}
private void VerifyGuiTextures()
@@ -52,6 +51,8 @@ private void VerifyGuiTextures()
};
components.AddRange(GameEngine.GuiDialogManager.Components);
+ // TODO: Verify no double definitions for textures and components exit
+
foreach (var component in components)
VerifyGuiComponentTexturesExist(component);
@@ -63,8 +64,8 @@ private void VerifyMegaTexturesExist(CancellationToken token)
if (GameEngine.GuiDialogManager.MtdFile is null)
{
var mtdFileName = megaTextureName ?? "<>";
- VerificationError.Create(VerifierChain, VerifierErrorCodes.FileNotFound, $"MtdFile '{mtdFileName}.mtd' could not be found",
- VerificationSeverity.Critical, mtdFileName);
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound, $"MtdFile '{mtdFileName}.mtd' could not be found",
+ VerificationSeverity.Critical, mtdFileName));
}
if (megaTextureName is not null)
@@ -84,13 +85,19 @@ private void VerifyMegaTexturesExist(CancellationToken token)
private void VerifyGuiComponentTexturesExist(string component)
{
- var middleButtonInRepoMode = false;
-
-
+ var buttonSpecialMode = false;
+
var entriesForComponent = GetTextureEntriesForComponents(component, out var defined);
if (!defined)
return;
+ if (entriesForComponent.TryGetValue(GuiComponentType.ButtonMiddle, out var middleTexture))
+ {
+ GameEngine.GuiDialogManager.TextureExists(middleTexture, out var origin, out _);
+ if (origin == GuiTextureOrigin.Repository)
+ buttonSpecialMode = true;
+ }
+
foreach (var componentType in GuiComponentTypes)
{
try
@@ -98,55 +105,68 @@ private void VerifyGuiComponentTexturesExist(string component)
if (!entriesForComponent.TryGetValue(componentType, out var texture))
continue;
- if (_cache?.TryAddEntry(texture.Texture) == false)
+ if (buttonSpecialMode && componentType.IsButton() && !componentType.SupportsSpecialTextureMode())
+ {
+ // If we are in special button mode, non-supported button textures won't be loaded anyway.
+ continue;
+ }
+
+ var cached = _cache?.GetEntry(texture.Texture);
+ if (cached?.AlreadyVerified is true)
{
// If we are in a special case we don't want to skip
- if (!middleButtonInRepoMode &&
+ if (!buttonSpecialMode &&
componentType is not GuiComponentType.ButtonMiddle &&
componentType is not GuiComponentType.Scanlines &&
componentType is not GuiComponentType.FrameBackground)
continue;
}
- if (!GameEngine.GuiDialogManager.TextureExists(
- texture,
- out var origin,
- out var isNone,
- middleButtonInRepoMode)
- && !isNone)
+ var exists = GameEngine.GuiDialogManager.TextureExists(
+ texture,
+ out var origin,
+ out var isNone,
+ buttonSpecialMode);
+
+ if (!exists && !isNone)
{
-
if (origin == GuiTextureOrigin.MegaTexture && texture.Texture.Length > MtdFileConstants.MaxFileNameSize)
{
- AddError(VerificationError.Create(VerifierChain, VerifierErrorCodes.FilePathTooLong,
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FilePathTooLong,
$"The filename is too long. Max length is {MtdFileConstants.MaxFileNameSize} characters.",
VerificationSeverity.Error, texture.Texture));
}
else
{
- var message = $"Could not find GUI texture '{texture.Texture}' at location '{origin}'.";
-
- if (texture.Texture.Length > PGConstants.MaxMegEntryPathLength)
- message += " The file name is too long.";
-
- AddError(VerificationError.Create(VerifierChain, VerifierErrorCodes.FileNotFound,
- message, VerificationSeverity.Error,
- [component, origin.ToString()], texture.Texture));
+ AddNotFoundError(texture, component, origin);
}
}
-
- if (componentType is GuiComponentType.ButtonMiddle && origin is GuiTextureOrigin.Repository)
- middleButtonInRepoMode = true;
+
+ _cache?.TryAddEntry(texture.Texture, exists);
}
finally
{
-
- if (componentType >= GuiComponentType.ButtonRightDisabled)
- middleButtonInRepoMode = false;
+ if (!componentType.IsButton())
+ buttonSpecialMode = false;
}
}
}
+ private void AddNotFoundError(ComponentTextureEntry texture, string component, GuiTextureOrigin? origin)
+ {
+ var sb = new StringBuilder($"Could not find GUI texture '{texture.Texture}'");
+ if (origin is not null)
+ sb.Append($" at location '{origin}'");
+ sb.Append('.');
+
+ if (texture.Texture.Length > PGConstants.MaxMegEntryPathLength)
+ sb.Append(" The file name is too long.");
+
+ AddError(VerificationError.Create(this, VerifierErrorCodes.FileNotFound,
+ sb.ToString(), VerificationSeverity.Error,
+ [component, origin.ToString()], texture.Texture));
+ }
+
private IReadOnlyDictionary GetTextureEntriesForComponents(string component, out bool defined)
{
if (component == DefaultComponentIdentifier)
diff --git a/src/ModVerify/Verifiers/IAlreadyVerifiedCache.cs b/src/ModVerify/Verifiers/IAlreadyVerifiedCache.cs
deleted file mode 100644
index 1fe8ad5..0000000
--- a/src/ModVerify/Verifiers/IAlreadyVerifiedCache.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using PG.Commons.Hashing;
-
-namespace AET.ModVerify.Verifiers;
-
-public interface IAlreadyVerifiedCache
-{
- public bool TryAddEntry(string entry);
- public bool TryAddEntry(ReadOnlySpan