Skip to content

Commit 9019cfc

Browse files
authored
Merge pull request #3 from AlamoEngine-Tools/develop
Support SFX Events, Logging and reporting
2 parents dcc45e7 + 52f68c0 commit 9019cfc

161 files changed

Lines changed: 5857 additions & 1507 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ jobs:
5555
# Change into the artifacts directory to avoid including the directory itself in the zip archive
5656
working-directory: ./releases/net8.0
5757
run: zip -r ../ModVerify-Net8.zip .
58+
- name: Rename .NET Framework executable
59+
run: mv ./releases/net48/ModVerify.CliApp.exe ./releases/net48/ModVerify.exe
5860
- uses: dotnet/nbgv@v0.4.2
5961
id: nbgv
6062
- name: Create GitHub release
@@ -65,5 +67,5 @@ jobs:
6567
token: ${{ secrets.GITHUB_TOKEN }}
6668
generate_release_notes: true
6769
files: |
68-
./releases/net48/ModVerify.CliApp.exe
70+
./releases/net48/ModVerify.exe
6971
./releases/ModVerify-Net8.zip

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ItemGroup>
44
<PackageReference Include="Nerdbank.GitVersioning" Condition="!Exists('packages.config')">
55
<PrivateAssets>all</PrivateAssets>
6-
<Version>3.6.133</Version>
6+
<Version>3.6.139</Version>
77
</PackageReference>
88
</ItemGroup>
99
</Project>

PetroglyphTools

Submodule PetroglyphTools updated 124 files

README.md

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,77 @@
1-
# ModVerify
1+
# ModVerify: A Mod Verification Tool
2+
3+
ModVerify is a command-line tool designed to verify mods for the game Star Wars: Empire at War and its expansion Forces of Corruption.
4+
5+
## Table of Contents
6+
7+
- [Installation](#installation)
8+
- [Usage](#usage)
9+
- [Options](#options)
10+
- [Available Checks](#available-checks)
11+
12+
## Installation
13+
14+
Download the latest release from the [releases page](https://github.com/AlamoEngine-Tools/ModVerify/releases). There are two versions of the application available.
15+
16+
1. `ModVerify.exe` is the default version. Use this if you simply want to verify your mods. This version only works on Windows.
17+
2. `ModVerify-NetX.zip` is the cross-platform app. It works on Windows and Linux and is most likely the version you want to use to include it in some CI/CD scenarios.
18+
19+
You can place the files anywhere on your system, eg. your Desktop. There is no need to place it inside a mod's directory.
20+
21+
*Note: Both versions have the exact same feature set. They just target a different .NET runtime. Linux and CI/CD support is not fully tested yet. Current priority is on the Windows-only version.*
22+
23+
## Usage
24+
25+
Simply run the executable file `ModVerify.exe`.
26+
27+
When given no specific argument through the command line, the app will ask you which game or mod you want to verify. When the tool is done, it will write the verification results into new files next to the executable.
28+
29+
A `.JSON` file lists all found issues. Into seperate `.txt` files the same errors get grouped by a category of the finding. The text files may be easier to read, while the json file is more useful for 3rd party tool processing.
30+
31+
## Options
32+
33+
You can also run the tool with command line arguments to adjust the tool to your needs.
34+
35+
To see all available options, open the command line and type:
36+
37+
```bash
38+
ModVerify.exe --help
39+
```
40+
41+
Here is a list of the most relevant options:
42+
43+
### `--path`
44+
Specifies a path that shall be analyzed. **There will be no user input required when using this option**
45+
46+
### `--output`
47+
Specified the output path where analysis result shall be written to.
48+
49+
### `--baseline`
50+
Specifies a baseline file that shall be used to filter out known errors. You can download the [FoC baseline](focBaseline.json) which includes all errors produced by the vanilla game.
51+
52+
### `--createBaseline`
53+
If you want to create your own baseline, add this option with a file path such as `myModBaseline.json`.
54+
55+
### Example
56+
This is an example run configuration that analyzes a specific mod, uses a the FoC basline and writes the output into a dedicated directory:
57+
58+
```bash
59+
ModVerify.exe --path "C:\My Games\FoC\Mods\MyMod" --output "C:\My Games\FoC\Mods\MyMod\verifyResults" --baseline focBaseline.json
60+
```
61+
62+
63+
## Available Checks
64+
65+
The following verifiers are currently implemented:
66+
67+
### For SFX Events:
68+
- Checks whether coded preset exists
69+
- Checks the referenced samples for validity (bit rate, sample size, channels, etc.)
70+
- Duplicates
71+
72+
73+
### For GameObjects
74+
- Checks the referenced models for validity (textures, particles and shaders)
75+
- Duplicates
76+
77+

aet.ico

37.2 KB
Binary file not shown.
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
2-
<Costura />
3-
</Weavers>
1+
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"/>

src/ModVerify.CliApp/GameFinderResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
namespace ModVerify.CliApp;
44

5-
public readonly record struct GameFinderResult(IGame Game, IGame FallbackGame);
5+
internal record GameFinderResult(IGame Game, IGame? FallbackGame);
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO.Abstractions;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Logging;
6+
using PG.StarWarsGame.Infrastructure.Clients.Steam;
7+
using PG.StarWarsGame.Infrastructure.Games;
8+
using PG.StarWarsGame.Infrastructure.Mods;
9+
using PG.StarWarsGame.Infrastructure.Services;
10+
using PG.StarWarsGame.Infrastructure.Services.Dependencies;
11+
using PG.StarWarsGame.Infrastructure.Services.Detection;
12+
13+
namespace ModVerify.CliApp;
14+
15+
internal class GameFinderService
16+
{
17+
private readonly IServiceProvider _serviceProvider;
18+
private readonly IFileSystem _fileSystem;
19+
private readonly ILogger? _logger;
20+
private readonly IGameFactory _gameFactory;
21+
private readonly IModFactory _modFactory;
22+
23+
public GameFinderService(IServiceProvider serviceProvider)
24+
{
25+
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
26+
_fileSystem = _serviceProvider.GetRequiredService<IFileSystem>();
27+
_gameFactory = _serviceProvider.GetRequiredService<IGameFactory>();
28+
_modFactory = _serviceProvider.GetRequiredService<IModFactory>();
29+
_logger = _serviceProvider.GetService<ILoggerFactory>()?.CreateLogger(GetType());
30+
}
31+
32+
public GameFinderResult FindGames()
33+
{
34+
var detectors = new List<IGameDetector>
35+
{
36+
new DirectoryGameDetector(_fileSystem.DirectoryInfo.New(Environment.CurrentDirectory), _serviceProvider),
37+
new SteamPetroglyphStarWarsGameDetector(_serviceProvider),
38+
};
39+
40+
return FindGames(detectors);
41+
}
42+
43+
public GameFinderResult FindGamesFromPath(string path)
44+
{
45+
// There are three common situations:
46+
// 1. path points to the actual game directory
47+
// 2. path points to a local mod in game/Mods/ModDir
48+
// 3. path points to a workshop mod
49+
var givenDirectory = _fileSystem.DirectoryInfo.New(path);
50+
var possibleGameDir = givenDirectory.Parent?.Parent;
51+
var possibleSteamAppsFolder = givenDirectory.Parent?.Parent?.Parent?.Parent?.Parent;
52+
53+
var detectors = new List<IGameDetector>
54+
{
55+
new DirectoryGameDetector(givenDirectory, _serviceProvider)
56+
};
57+
58+
if (possibleGameDir is not null)
59+
detectors.Add(new DirectoryGameDetector(possibleGameDir, _serviceProvider));
60+
61+
if (possibleSteamAppsFolder is not null && possibleSteamAppsFolder.Name == "steamapps" && uint.TryParse(givenDirectory.Name, out _))
62+
detectors.Add(new SteamPetroglyphStarWarsGameDetector(_serviceProvider));
63+
64+
return FindGames(detectors);
65+
}
66+
67+
private bool TryDetectGame(GameType gameType, IList<IGameDetector> detectors, out GameDetectionResult result)
68+
{
69+
var gd = new CompositeGameDetector(detectors, _serviceProvider, true);
70+
result = gd.Detect(new GameDetectorOptions(gameType));
71+
72+
if (result.Error is not null)
73+
{
74+
_logger?.LogTrace($"Unable to find game installation: {result.Error.Message}", result.Error);
75+
return false;
76+
}
77+
if (result.GameLocation is null)
78+
return false;
79+
80+
return true;
81+
}
82+
83+
84+
private void SetupMods(IGame game)
85+
{
86+
var modFinder = _serviceProvider.GetRequiredService<IModReferenceFinder>();
87+
var modRefs = modFinder.FindMods(game);
88+
89+
var mods = new List<IMod>();
90+
91+
foreach (var modReference in modRefs)
92+
{
93+
var mod = _modFactory.FromReference(game, modReference);
94+
mods.AddRange(mod);
95+
}
96+
97+
foreach (var mod in mods)
98+
game.AddMod(mod);
99+
100+
// Mods need to be added to the game first, before resolving their dependencies.
101+
foreach (var mod in mods)
102+
{
103+
var resolver = _serviceProvider.GetRequiredService<IDependencyResolver>();
104+
mod.ResolveDependencies(resolver,
105+
new DependencyResolverOptions { CheckForCycle = true, ResolveCompleteChain = true });
106+
}
107+
}
108+
109+
private GameFinderResult FindGames(IList<IGameDetector> detectors)
110+
{
111+
// FoC needs to be tried first
112+
if (!TryDetectGame(GameType.Foc, detectors, out var result))
113+
{
114+
_logger?.LogTrace("Unable to find FoC installation. Trying again with EaW...");
115+
if (!TryDetectGame(GameType.EaW, detectors, out result))
116+
throw new GameException("Unable to find game installation: Wrong install path?");
117+
}
118+
119+
if (result.GameLocation is null)
120+
throw new GameException("Unable to find game installation: Wrong install path?");
121+
122+
_logger?.LogTrace($"Found game installation: {result.GameIdentity} at {result.GameLocation.FullName}");
123+
124+
var game = _gameFactory.CreateGame(result);
125+
126+
SetupMods(game);
127+
128+
129+
IGame? fallbackGame = null;
130+
// If the game is Foc we want to set up Eaw as well as the fallbackGame
131+
if (game.Type == GameType.Foc)
132+
{
133+
var fallbackDetectors = new List<IGameDetector>();
134+
135+
if (game.Platform == GamePlatform.SteamGold)
136+
fallbackDetectors.Add(new SteamPetroglyphStarWarsGameDetector(_serviceProvider));
137+
else
138+
throw new NotImplementedException("Searching fallback game for non-Steam games is currently is not yet implemented.");
139+
140+
if (!TryDetectGame(GameType.EaW, fallbackDetectors, out var fallbackResult) || fallbackResult.GameLocation is null)
141+
throw new GameException("Unable to find fallback game installation: Wrong install path?");
142+
143+
_logger?.LogTrace($"Found fallback game installation: {fallbackResult.GameIdentity} at {fallbackResult.GameLocation.FullName}");
144+
145+
fallbackGame = _gameFactory.CreateGame(fallbackResult);
146+
147+
SetupMods(fallbackGame);
148+
}
149+
150+
return new GameFinderResult(game, fallbackGame);
151+
}
152+
}

src/ModVerify.CliApp/ModFinderService.cs

Lines changed: 0 additions & 93 deletions
This file was deleted.

0 commit comments

Comments
 (0)