Code Monkey home page Code Monkey logo

gamefinder's Introduction

GameFinder

CI codecov

.NET library for finding games. The following launchers are supported:

The following launchers are not yet supported or support has been dropped:

If you are interested in understanding how GameFinder finds these games, check the wiki for more information.

Additionally, the following Linux tools are supported:

Example

The example project uses every available store handler and can be used as a reference. You can go to the GitHub Actions Page and click on one of the latest CI workflow runs to download a build of this project.

Usage

All store handlers inherit from AHandler<TGame, TId> and implement FindAllGames() which returns IEnumerable<OneOf<TGame, ErrorMessage>>. The OneOf struct is a F# style union and is guaranteed to only contain one of the following: a TGame or an ErrorMessage. I recommended checking out the OneOf library, if you want to learn more.

Some important things to remember:

  • All store handler methods are pure, meaning they do not change the internal state of the store handler because they don't have any. This also means that the results are not cached and you shouldn't call the same method multiple times. It's up to the library consumer to cache the results somewhere.
  • Ids are store dependent. Each store handler has their own type of id and figuring out the right id for your game might require some testing. You can find useful resources in this README for some store handlers.

Basic Usage

var results = handler.FindAllGames();

foreach (var result in results)
{
    // using the switch method
    result.Switch(game =>
    {
        Console.WriteLine($"Found {game}");
    }, error =>
    {
        Console.WriteLine(error);
    });

    // using the provided extension functions
    if (result.TryGetGame(out var game))
    {
        Console.WriteLine($"Found {game}");
    } else
    {
        Console.WriteLine(result.AsError());
    }
}

Finding a single game

If you're working on an application that only needs to find 1 game, then you can use the FindOneGameById method instead. IMPORTANT NOTE: the results are not cached. If you call this method multiple, the store handler will do the same thing multiple times, which is search for every game installed. Do not call this method if you need to find multiple games.

var game = handler.FindOneGameById(someId, out var errors);

// I highly recommend logging errors regardless of whether or not the game was found.
foreach (var error in errors)
{
    Console.WriteLine(error);
}

if (game is null)
{
    Console.WriteLine("Unable to find game");
} else
{
    Console.WriteLine($"Found {game}");
}

Finding multiple games

If you need to find multiple games at once, you can use the FindAllGamesById method instead. This returns an IReadOnlyDictionary<TId, TGame> which you can use to lookup games by id. IMPORTANT NOTE: the results are not cached. You have to do that yourself.

var games = handler.FindAllGamesById(out var errors);

// I highly recommend always logging errors.
foreach (var error in errors)
{
    Console.WriteLine(error);
}

if (games.TryGetValue(someId, out var game))
{
    Console.WriteLine($"Found {game}");
} else
{
    Console.WriteLine($"Unable to find game with the id {someId}");
}

Supported Launchers

Steam

Steam is supported natively on Windows and Linux. Use SteamDB to find the ID of a game.

Usage (cross-platform):

var handler = new SteamHandler(FileSystem.Shared, OperatingSystem.IsWindows() ? WindowsRegistry.Shared : null);

GOG Galaxy

GOG Galaxy is supported natively on Windows, and with Wine on Linux. Use the GOG Database to find the ID of a game.

Usage (native on Windows):

var handler = new GOGHandler(WindowsRegistry.Shared, FileSystem.Shared);

Usage (Wine on Linux):

See Wine for more information.

// requires a valid prefix
var wineFileSystem = winePrefix.CreateOverlayFileSystem(FileSystem.Shared);
var wineRegistry = winePrefix.CreateRegistry(FileSystem.Shared);

var handler = new GOGHandler(wineRegistry, wineFileSystem);

Epic Games Store

The Epic Games Store is supported natively on Windows, and with Wine on Linux. Use the Epic Games Store Database to find the ID of a game (WIP).

Usage (native on Windows):

var handler = new EGSHandler(WindowsRegistry.Shared, FileSystem.Shared);

Usage (Wine on Linux):

See Wine for more information.

// requires a valid prefix
var wineFileSystem = winePrefix.CreateOverlayFileSystem(FileSystem.Shared);
var wineRegistry = winePrefix.CreateRegistry(FileSystem.Shared);

var handler = new EGSHandler(wineRegistry, wineFileSystem);

Origin

Origin is supported natively on Windows, and with Wine on Linux. Note: EA is deprecating Origin and will replace it with EA Desktop.

Usage (native on Windows):

var handler = new OriginHandler(FileSystem.Shared);

Usage (Wine on Linux):

See Wine for more information.

// requires a valid prefix
var wineFileSystem = winePrefix.CreateOverlayFileSystem(FileSystem.Shared);

var handler = new OriginHandler(wineFileSystem);

EA Desktop

EA Desktop is the replacement for Origin: See EA is deprecating Origin. This is by far, the most complicated Store Handler. You should read the wiki entry. My implementation decrypts the encrypted file, created by EA Desktop. You should be aware that the key used to encrypt the file is derived from hardware information. If the user changes their hardware, the decryption process might fail because they key has changed.

EA Desktop is only supported on Windows.

Usage:

var handler = new EADesktopHandler(FileSystem.Shared, new HardwareInfoProvider());

Xbox Game Pass

This package used to be deprecated, but I've re-added support in GameFinder 3.0.0. Xbox Game Pass used to install games inside a SYSTEM protected folder, making modding not feasible for the average user. You can read more about this here.

Xbox Game Pass is only supported on Windows.

Usage:

var handler = new XboxHandler(FileSystem.Shared);

Bethesda.net

As of May 11, 2022, the Bethesda.net launcher is no longer in use. The package GameFinder.StoreHandlers.BethNet has been deprecated and marked as legacy.

Wine

Wine is a compatibility layer capable of running Windows applications on Linux. Wine uses prefixes to create and store virtual C: drives. A user can install and run Windows program inside these prefixes, and applications running inside the prefixes likely won't even notice they are not actually running on Windows.

Since GameFinder is all about finding games, it also has to be able to find games inside Wine prefixes to provide good Linux support. The package NexusMods.Paths from NexusMods.App provides a file system abstraction IFileSystem which enables path re-mappings:

AWinePrefix prefix = //...

// creates a new IFileSystem, with path mappings into the wine prefix
IFileSystem wineFileSystem = prefix.CreateOverlayFileSystem(FileSystem.Shared);

// this wineFileSystem can be used instead of FileSystem.Shared:
var handler = new OriginHandler(wineFileSystem);

// you can also create a new IRegistry:
IRegistry wineRegistry = prefix.CreateRegistry(FileSystem.Shared);

// and use both:
var handler = new EGSHandler(wineRegistry, wineFileSystem);

Default Prefix Manager

GameFinder.Wine implements a IWinePrefixManager for finding Wine prefixes.

Usage:

var prefixManager = new DefaultWinePrefixManager(FileSystem.Shared);

foreach (var result in prefixManager.FindPrefixes())
{
    result.Switch(prefix =>
    {
        Console.WriteLine($"Found wine prefix at {prefix.ConfigurationDirectory}");
    }, error =>
    {
        Console.WriteLine(error.Value);
    });
}

Bottles

GameFinder.Wine implements a IWinePrefixManager for finding Wine prefixes managed by Bottles.

Usage:

var prefixManager = new BottlesWinePrefixManager(FileSystem.Shared);

foreach (var result in prefixManager.FindPrefixes())
{
    result.Switch(prefix =>
    {
        Console.WriteLine($"Found wine prefix at {prefix.ConfigurationDirectory}");
    }, error =>
    {
        Console.WriteLine(error.Value);
    });
}

Proton

Valve's Proton is a compatibility tool for Steam and is mostly based on Wine. The Wine prefixes managed by Proton are in the compatdata directory of the steam library where the game itself is installed. Since the path is relative to the game itself and requires the app id, I've decided to put this functionality in GameFinder.StoreHandlers.Steam:

SteamGame? steamGame = steamHandler.FindOneGameById(1237970, out var errors);
if (steamGame is null) return;

ProtonWinePrefix protonPrefix = steamGame.GetProtonPrefix();
var protonPrefixDirectory = protonPrefix.ProtonDirectory;

if (protonDirectory != default && fileSystem.DirectoryExists(protonDirectory))
{
    Console.WriteLine($"Proton prefix is at {protonDirectory}");
}

Trimming

Self-contained deployments and executables can be trimmed starting with .NET 6. This feature is only available to applications that are published self-contained.

Trimmable:

  • GameFinder.Common
  • GameFinder.RegistryUtils
  • GameFinder.Wine
  • GameFinder.StoreHandlers.Steam
  • GameFinder.StoreHandlers.GOG
  • GameFinder.StoreHandlers.EGS
  • GameFinder.StoreHandlers.Origin

NOT Trimmable:

I recommend looking at the project file of the example project, if you run into warnings or errors with trimming.

Contributing

See CONTRIBUTING for more information.

License

See LICENSE for more information.

gamefinder's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gamefinder's Issues

Support Heroic Games Launcher

Many users prefer to use the Heroic Games Launcher, instead of the various official games launchers it replaces.
This is especially true on Linux, where it is a native & well integrated application, unlike most official launchers.

Heroic makes use of store-specific tools (currently Legendary, gogdl & Nile). These tools can be used separately from Heroic to install & launch games owned on the respective store.
However I don't think those tools keep track of and "manage" installed games, per-se. (Might be wrong about that, I've not used those tools directly).

Heroic can be installed via Flatpak, AppImage, via distro packages or manually from a tarball. This probably won't be too relevant since regardless of Heroic's installation method, users can install games to any location they wish on their system.
Although, Heroic's cache & config will be at a different path when it's installed as a flatpak.

Since users can install games anywhere, would probably need to scan the relevant config/list/database that catalogs installed games.

Add Origin Support

GameFinder.Example: ColoredConsoleTarget works with Windows Terminal, but not with default conhost PowerShell or cmd

[With conhost PowerShell or cmd] I get results like, e.g.:
←[37m2023-03-07 09:56:57.6406←[0m|←[91mERROR←[0m|InstallInfo #17 for de84247f-f7fb-41c6-8daa-02b7f12bf457 (syndicate-1993) does not have the value "baseInstallPath"←[0m

I'm not sure if this is an implementation detail or an issue with NLog's library.

EDIT: Hm, looks like this may be the culprit.
EDIT # 2: Note that using the EnableVirtualTerminal() example provided in the above issue does the trick.

GameFinder fails to parse Steam Manifest if there is a quotation mark used in a drive label

As title says, when a drive for a Steam library is labelled with a " in the name, such as Game Drive 3.5" it will fail to parse the file.

Renaming the drive in the Steam drive menu to not include the " solves the issue as a bandaid solution

Example from the libraryfolders.vdf file

	"path"		"F:\\Games\\Steam"
	"label"		"Game Drive 3.5\""
	"contentid"		"2288888475556474100"
	"totalsize"		"1000191553536"

Renaming the drive in steam to no longer include the " turns it to this

	"path"		"F:\\Games\\Steam"
	"label"		"Game Drive 3.5"
	"contentid"		"2288888475556474100"
	"totalsize"		"1000191553536"

Which can be read no issue

Scope question with feature requests

@erri120 : Thanks for your work on the decryption and documentation of the EA Desktop json file! It proved very helpful for my purposes.

The overarching question I have with this Issue is: To what extent are you interested in expanding the scope of this library?

For some time I've been making major contributions to GLC, a lightweight C# Windows-only console multi-launcher app (supporting 17 launchers; and I just added two more). I even hacked in image support for conhost-based shells, e.g., cmd or PowerShell. @Solaire has big plans for 2.0, including moving to separate libraries for each platform. It'd be nice to use GameFinder as a dependency, but as a launcher (rather than to assist modding tools as originally designed here) we need additional data: an .exe or a protocol call to launch the game, an icon (where it's not an .exe launch), and preferably an uninstall entry. Some space for additional metadata would be nice. And of course it'd be great to have support for all the launchers. ;-)

So, to the requests... I'll divide them into separate issues if you're interested in taking up and/or accepting pull requests for any of these, but I don't know to what extent you want this project's scope to grow before I do that.

  1. Wiki:
  • Remove or revise the "Use the registry" alternative from the EA Desktop wiki. It seems backwards: are you suggesting to search all the user's disks for "installerdata.xml" files just to find the registry entries?
  • Add GLC to the Other Implementation sections.
  1. GOG:
  • Instead of the registry, use the SQLite database (%ProgramData%\GOG.com\Galaxy\storage\galaxy-2.0.db).

[This is more robust, e.g., would allow installed games to be found even after a Windows reinstall, and it allows you to discover owned but not-installed games. Also, I don't know why, but the registry is missing at least one of my recently installed GOG games. (In addition, there's additional metadata that can be collected; see Additional fields suggestion below). I'm happy to help implement this based on my work on GLC.]

  1. Additional launchers:
    If you're interested, I'd also be happy to help add handlers to support 16 17 more launchers. Though a few are simple registry scrapes, as above that's not the preferred solution. I've been playing around with the code and so far I've got Amazon and Arc [EDIT: all of the below] working in my fork:
  • Amazon
  • Arc
  • Battle.net
  • Big Fish
  • Game Jolt
  • Humble
  • Indiegala
  • itch
  • Legacy
  • Oculus
  • Paradox
  • Plarium
  • Riot
  • Robot Cache
  • Rockstar
  • Ubisoft
  • Wargaming
  1. Additional fields:
  • Offer a consistent method between handlers to get all available data (i.e., beyond id, name, and install path collected now).

[Admittedly, the available fields will vary a bit between launchers, where the GOG and Amazon local databases in particular offer lots of good metadata. You do currently provide a few methods to help assist in the collection of more data like EADesktopGame.GetInstallerDataFile() and SteamGame.GetManifestPath() (not that the latter file is a particularly rich source of data; in Steam's case a GetRegistryKey() method to easily get the corresponding registry entry in HKLM32\SOFTWARE\Valve\Steam\Steam app ) would have been nice). However, it seems rather odd to force the library's client to reinvent the wheel of often re-parsing a file/regkey to get data that could easily have been collected the first time through in this library.]

  • Access APIs or perform web scrapes to collect additional data.

[I've done some of this in GLC with the low-hanging fruit (e.g., where no authentication is required, or in EA's case, where a C# wrapper, PureOrigin.API, exists).]

  • Ensure compatibility for existing clients of this library.

[As an experiment, I've implemented one possible solution in my fork: I added a generic GameEx record type, and FindAllGamesEx() methods are in each handler to fill it. The existing FindAllGames() methods now call FindAllGamesEx() and convert IDs to longs or ints as necessary. Of course, you may have a better idea.]

Linux support

  • check if net5.0 can be used (Microsoft.Win32.Registry)
  • add README info on how to setup WINE
  • check ~/steam/steam on Linux instead of windows registry

Unknown hard error when parsing some Steam manifests

It looks as if the appmanifests created by Steam sometimes contain the full path of the installed application in the installdir field. I've noticed this in 3 separate cases and any one of them will crash with the message "Unknown hard error" and the following stacktrace when not running in debug mode:

Process terminated. Assertion failed.                                                                                                                                                                                                                                                       
Path is not sanitized: 'g:/programme/steam/steamapps/common/the binding of isaac'                                                                                                                                                                                                           
   at NexusMods.Paths.Utilities.PathHelpers.DebugAssertIsSanitized(ReadOnlySpan`1 path, IOSInformation os, Boolean isRelative)                                                                                                                                                              
   at NexusMods.Paths.RelativePath..ctor(String path)                                                                                                                                                                                                                                       
   at GameFinder.StoreHandlers.Steam.Services.AppManifestParser.<>c__DisplayClass0_0.<ParseManifestFile>b__2(KVValue x) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\Services\Parsers\AppManifestParser.cs:line 74                           
   at GameFinder.StoreHandlers.Steam.Services.ParserHelpers.<>c__DisplayClass2_0`1.<ParseChildObjectValue>b__0() in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\Services\Parsers\ParserHelpers.cs:line 73                                      
   at FluentResults.Result.Try[T](Func`1 action, Func`2 catchHandler)                                                                                                                                                                                                                       
   at GameFinder.StoreHandlers.Steam.Services.ParserHelpers.ParseChildObjectValue[T](KVObject childObject, KVObject parentObject, Func`2 parser) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\Services\Parsers\ParserHelpers.cs:line 72      
   at GameFinder.StoreHandlers.Steam.Services.ParserHelpers.<>c__DisplayClass6_0`1.<ParseRequiredChildObject>b__0(KVObject childObject) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\Services\Parsers\ParserHelpers.cs:line 130              
   at FluentResults.Result`1.Bind[TNewValue](Func`2 bind)                                                                                                                                                                                                                                   
   at GameFinder.StoreHandlers.Steam.Services.ParserHelpers.ParseRequiredChildObject[T](KVObject parentObject, String childObjectName, Func`2 parser) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\Services\Parsers\ParserHelpers.cs:line 130
   at GameFinder.StoreHandlers.Steam.Services.AppManifestParser.ParseManifestFile(AbsolutePath manifestPath) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\Services\Parsers\AppManifestParser.cs:line 74                                      
   at GameFinder.StoreHandlers.Steam.SteamHandler.FindAllGames()+MoveNext() in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.Steam\SteamHandler.cs:line 92                                                                                             
   at GameFinder.Example.Program.LogGamesAndErrors[TGame](IEnumerable`1 results, ILogger logger, Action`1 action) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\other\GameFinder.Example\Program.cs:line 215
   at GameFinder.Example.Program.RunSteamHandler(IFileSystem fileSystem, IRegistry registry) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\other\GameFinder.Example\Program.cs:line 183
   at GameFinder.Example.Program.Run(Options options, ILogger logger) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\other\GameFinder.Example\Program.cs:line 92
   at GameFinder.Example.Program.<>c__DisplayClass1_0.<Main>b__0(Options x) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\other\GameFinder.Example\Program.cs:line 77
   at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
   at GameFinder.Example.Program.Main(String[] args) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\other\GameFinder.Example\Program.cs:line 75

Examples of the full installation path in appmanifest files:

"AppState"
{
	"appid"		"113200"
	"Universe"		"1"
	"LauncherPath"		"G:\\Programme\\Steam\\steam.exe"
	"name"		"The Binding of Isaac"
	"StateFlags"		"4"
	"installdir"		"g:\\programme\\steam\\steamapps\\common\\the binding of isaac"
	"LastUpdated"		"1431776164"
	"UpdateResult"		"0"
	"SizeOnDisk"		"54971560"
	"buildid"		"624794"
    [...]
}
"AppState"
{
	"appid"		"32460"
	"Universe"		"1"
	"LauncherPath"		"G:\\Programme\\Steam\\steam.exe"
	"name"		"Monkey Island 2: Special Edition"
	"StateFlags"		"4"
	"installdir"		"g:\\programme\\steam\\steamapps\\common\\monkey2"
	"LastUpdated"		"1363801581"
	"UpdateResult"		"0"
	"SizeOnDisk"		"1936029427"
	"buildid"		"52245"
    [...]
}

This could probably be resolved by reinstalling the offending titles, but it might be a scenario worth supporting just to avoid crashes hard to debug if they don't happen to a developer.

Decrypt IS file failed

Hello,

I tried to decrypt the IS file by following th the wiki, but I can't do it.
My key is definitely bad, but I don't understand why :(

Here is what I got with wmic
BaseBoardManufacturer.txt
BaseBoardSerialNumber.txt
BIOSManufacturer.txt
BIOSSerialNumber.txt
ProcessorManufacturer.txt
ProcessorName.txt
ProcessorProcessorId.txt
PVideoControllerNPDeviceId.txt

And my volume serial is 748AF423.

The rendering should be :
Micro-Star International Co., Ltd. ;To be filled by O.E.M. ;American Megatrends International, LLC. ;To be filled by O.E.M. ;748AF423;PCI\VEN_1002&DEV_73A5&SUBSYS_441D1DA2&REV_C0\6&20C1D3AD&0&00000019 ROOT\DISPLAY\0000 ;AuthenticAMD;178BFBFF00A20F10;AMD Ryzen 5 5600X 6-Core Processor ;

I have a doubt with videoControllerDeviceId because there are line breaks, should I include them?
I also have a doubt with the volumeSerialNumber, is it possible that it is the same as doing a "dir" in cmd.exe?

To finish
My SHA1 with what's above is b2895e59b9d0713820e5d63b4de042d0ae1a8cb6
An my SHA3_256 is f3abd302f1963cddb38a116be0462a866436bf9cfe598d197c5972d12255e55a

But can't read my file :(
IS.zip

Thanks for any help !

EGS: consider using different ID type

Keeping track of some stuff:

INFO|Found game: EGSGame { CatalogItemId = 4fe75bbc5a674f4f9b356b5c90567da5, AppName = Fortnite, CatalogNamespace = fn, DisplayName = Fortnite }
INFO|Found game: EGSGame { CatalogItemId = 8d1ca909b2964a79af2ccd939f714b78, AppName = 965ccf8b2eba4f9381ef43183c08e205, CatalogNamespace = 400347196e674de89c23cc2a7f2121db, DisplayName = Assassin's Creed: Valhalla }
INFO|Found game: EGSGame { CatalogItemId = a5d920b94c1d41a182db6258dc5eea5b, AppName = Angelonia, CatalogNamespace = angelonia, DisplayName = Watch Dogs 2, InstallLocation = F:\Epic Games\Watchdogs2 }
INFO|Found game: EGSGame { CatalogItemId = 717ea51853604f1786dfb936b70a0c71, AppName = 1e6e892f7f9b4cbcace3a273854116bc, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = AMAZONS, InstallLocation = F:\Epic Games\TotalWarSagaTROY }
INFO|Found game: EGSGame { CatalogItemId = 6dc445f656de4e029834b2d32b6a2f77, AppName = Jasper, CatalogNamespace = ecebf45065bc4993abfe0e84c40ff18e, DisplayName = Watch Dogs, InstallLocation = F:\Epic Games\WatchDogs }
INFO|Found game: EGSGame { CatalogItemId = a3361123cbb5436ab8630caea6e1d39a, AppName = Godwit, CatalogNamespace = 5f7c811695f14b8fa3a8e1ea35713d23, DisplayName = Batman™ Arkham Asylum Game of the Year Edition, InstallLocation = F:\Epic Games\BatmanArkhamAsylum }
INFO|Found game: EGSGame { CatalogItemId = 4106b71233fa4b4ba3b04c818fce91d4, AppName = 8935bb3e1420443a9789fe01758039a5, CatalogNamespace = df37f065c3f14eadbf011177396e2966, DisplayName = Alien: Isolation, InstallLocation = F:\Epic Games\AlienIsolation }
INFO|Found game: EGSGame { CatalogItemId = da3d0706de4b4d39b943abcf96389ce3, AppName = ad3d0f08dd0841d8a1ba77d94ded4773, CatalogNamespace = 2736ab9fec9c4a93a7a2872ed5154d4b, DisplayName = Rage 2, InstallLocation = F:\Epic Games\Rage2 }
INFO|Found game: EGSGame { CatalogItemId = a61625d8a2e04a4aaf033312c649616c, AppName = 890d9cf396d04922a1559333df419fed, CatalogNamespace = 4b5461ca8d1c488787b5200b420de066, DisplayName = Shadow of the Tomb Raider: Definitive Edition, InstallLocation = F:\Epic Games\ShadowoftheTombRaider }
INFO|Found game: EGSGame { CatalogItemId = 460088fc5e5045c0a67876fd10f7310b, AppName = f7cc1c999ac146f39b356f53e3489514, CatalogNamespace = 48ffecf4a89f4fd496817b0451384f39, DisplayName = Rise of the Tomb Raider: 20 Year Celebration, InstallLocation = F:\Epic Games\RiseoftheTombRaider }
INFO|Found game: EGSGame { CatalogItemId = 281504e8e6e44b5dab3a072f9ee21c21, AppName = Cowbird, CatalogNamespace = e5e30c728f1947759251eb5283ffa6e3, DisplayName = Batman™ Arkham Knight, InstallLocation = F:\Epic Games\BatmanArkhamKnight }
INFO|Found game: EGSGame { CatalogItemId = f08663635fd84c33bfc62ea3bac000e6, AppName = 818447bb519b46d48d365d5753362796, CatalogNamespace = 45e7cf3c49054f2fb20b673d9b0ae69e, DisplayName = Sonic Mania, InstallLocation = F:\Epic Games\SonicMania }
INFO|Found game: EGSGame { CatalogItemId = dc82015622b34172a049514af0c07758, AppName = 11e598b192324994abce05bad4f81b50, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = A Total War Saga: TROY, InstallLocation = F:\Epic Games\TotalWarSagaTROY }
INFO|Found game: EGSGame { CatalogItemId = fda38b88f1ea454c9e65cba125947d60, AppName = Egret, CatalogNamespace = 40c34bea9cd0460589c867f6a7246342, DisplayName = Batman™ Arkham City - Game of the Year Edition, InstallLocation = F:\Epic Games\BatmanArkhamCity }
INFO|Found game: EGSGame { CatalogItemId = ebaf29e138a446d3a2d523668ab05ddc, AppName = 52d88e9a6df248da913c8e99f1e4c526, CatalogNamespace = 6ea398b9c2244250a9177c0b8a69b5cd, DisplayName = PREY, InstallLocation = F:\Epic Games\PREY }
INFO|Found game: EGSGame { CatalogItemId = 57cd8d4cb4524152a57192555063334a, AppName = 6b61b3692dae45be889bf38cb1f9ed84, CatalogNamespace = df37f065c3f14eadbf011177396e2966, DisplayName = Alien: Isolation - Last Survivor, InstallLocation = F:\Epic Games\AlienIsolation }
INFO|Found game: EGSGame { CatalogItemId = 6dfe148a5d5f4fa9b265dcc3803dc395, AppName = Muscovy, CatalogNamespace = 95b4d5a753d042678f775d5e1eb5ab25, DisplayName = Surviving the Aftermath, InstallLocation = F:\Epic Games\SurvivingTheAftermath }
INFO|Found game: EGSGame { CatalogItemId = 5266dc333bb44e1f86a53fc11bc0f9e4, AppName = 30d3a88d29e24716ac5a4720042289f7, CatalogNamespace = 0c321ac6d5fe49139c153253b60702f4, DisplayName = Total War: WARHAMMER, InstallLocation = F:\Epic Games\TWWarhammer }
INFO|Found game: EGSGame { CatalogItemId = 59fd9ca3c8ac41f39713a3f28407d3d1, AppName = dc07b9ead8214591b8df6d2546d2a0e3, CatalogNamespace = 31bd7140ab344cd59a770e14b2afbcea, DisplayName = Aven Colony, InstallLocation = F:\Epic Games\AvenColony }
INFO|Found game: EGSGame { CatalogItemId = dc82015622b34172a049514af0c07758, AppName = 11e598b192324994abce05bad4f81b50, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = A Total War Saga: TROY, InstallLocation = D:\Epic Games\TotalWarSagaTROY }
INFO|Found game: EGSGame { CatalogItemId = 6e563a2c0f5f46e3b4e88b5f4ed50cca, AppName = 9d2d0eb64d5c44529cece33fe2a46482, CatalogNamespace = 0584d2013f0149a791e7b9bad0eec102, DisplayName = Grand Theft Auto V, InstallLocation = E:\EGS\GTAV }
INFO|Found game: EGSGame { CatalogItemId = 6ab3fccba1b045a6b77eebefb5b65fc4, AppName = Dill, CatalogNamespace = bc81d1e7d1794d3a94e4dbf26e92166d, DisplayName = Transistor, InstallLocation = D:\Epic Games\Transistor }
INFO|Found game: EGSGame { CatalogItemId = 717ea51853604f1786dfb936b70a0c71, AppName = 1e6e892f7f9b4cbcace3a273854116bc, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = AMAZONS, InstallLocation = D:\Epic Games\TotalWarSagaTROY }
INFO|Found game: EGSGame { CatalogItemId = 9f5250193e914b849201a40d21b30939, AppName = 19927295d6e3467887d4e830d8c85963, CatalogNamespace = 9d2f484bbec64aa8ad234b3199dcaf1c, DisplayName = Absolute Drift, InstallLocation = D:\Epic Games\AbsoluteDrift }
INFO|Using "CatalogNamespace" as a key results in collisions
INFO|Conflicts with key "53310576ce1d4446b20dbbdac4f09f2d":
INFO|EGSGame { CatalogItemId = 717ea51853604f1786dfb936b70a0c71, AppName = 1e6e892f7f9b4cbcace3a273854116bc, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = AMAZONS, InstallLocation = F:\Epic Games\TotalWarSagaTROY }
INFO|EGSGame { CatalogItemId = dc82015622b34172a049514af0c07758, AppName = 11e598b192324994abce05bad4f81b50, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = A Total War Saga: TROY, InstallLocation = F:\Epic Games\TotalWarSagaTROY }
INFO|Conflicts with key "df37f065c3f14eadbf011177396e2966":
INFO|EGSGame { CatalogItemId = 4106b71233fa4b4ba3b04c818fce91d4, AppName = 8935bb3e1420443a9789fe01758039a5, CatalogNamespace = df37f065c3f14eadbf011177396e2966, DisplayName = Alien: Isolation, InstallLocation = F:\Epic Games\AlienIsolation }
INFO|EGSGame { CatalogItemId = 57cd8d4cb4524152a57192555063334a, AppName = 6b61b3692dae45be889bf38cb1f9ed84, CatalogNamespace = df37f065c3f14eadbf011177396e2966, DisplayName = Alien: Isolation - Last Survivor, InstallLocation = F:\Epic Games\AlienIsolation }
INFO|Conflicts with key "53310576ce1d4446b20dbbdac4f09f2d":
INFO|EGSGame { CatalogItemId = dc82015622b34172a049514af0c07758, AppName = 11e598b192324994abce05bad4f81b50, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = A Total War Saga: TROY, InstallLocation = D:\Epic Games\TotalWarSagaTROY }
INFO|EGSGame { CatalogItemId = 717ea51853604f1786dfb936b70a0c71, AppName = 1e6e892f7f9b4cbcace3a273854116bc, CatalogNamespace = 53310576ce1d4446b20dbbdac4f09f2d, DisplayName = AMAZONS, InstallLocation = D:\Epic Games\TotalWarSagaTROY }

Games and their DLCs share the same CatalogNamespace, however, their manifest files contain some more interesting stuff:

{
    "AppCategories": [
        "public",
        "games",
        "applications"
    ],
    "DisplayName": "Alien: Isolation",
    "TechnicalType": "public,games,applications",
    "ExpectingDLCInstalled":
    {
        "df37f065c3f14eadbf011177396e2966:57cd8d4cb4524152a57192555063334a:6b61b3692dae45be889bf38cb1f9ed84": true
    },
    "CatalogNamespace": "df37f065c3f14eadbf011177396e2966",
    "CatalogItemId": "4106b71233fa4b4ba3b04c818fce91d4",
    "AppName": "8935bb3e1420443a9789fe01758039a5",
    "MainGameCatalogNamespace": "df37f065c3f14eadbf011177396e2966",
    "MainGameCatalogItemId": "4106b71233fa4b4ba3b04c818fce91d4",
    "MainGameAppName": "8935bb3e1420443a9789fe01758039a5",
}
{
    "AppCategories": [
        "public",
        "addons",
        "applications"
    ],
    "DisplayName": "Alien: Isolation - Last Survivor",
    "TechnicalType": "public,addons,applications",
    "CatalogNamespace": "df37f065c3f14eadbf011177396e2966",
    "CatalogItemId": "57cd8d4cb4524152a57192555063334a",
    "AppName": "6b61b3692dae45be889bf38cb1f9ed84",
    "MainGameCatalogNamespace": "df37f065c3f14eadbf011177396e2966",
    "MainGameCatalogItemId": "4106b71233fa4b4ba3b04c818fce91d4",
    "MainGameAppName": "8935bb3e1420443a9789fe01758039a5",
}

EA Desktop: add Wine support

This requires adding a new implementation of IHardwareInfoProvider. https://github.com/Jinjinov/Hardware.Info might be interesting. It's probably just easier to use wineconsole.

Name Value (Windows) Method (Windows) Method (Linux) Value (Linux) Notes
Win32_BaseBoard Manufacturer ASRock WMI cat /sys/class/dmi/id/board_vendor ASRock
Win32_BaseBoard SerialNumber (22 white spaces) WMI cat /sys/class/dmi/id/board_serial (empty string) Only readable by root
Win32_BIOS Manufacturer American Megatrends Inc. WMI cat /sys/class/dmi/id/bios_vendor American Megatrends Inc.
Win32_BIOS SerialNumber To Be Filled By O.E.M. WMI cat /sys/class/dmi/id/product_serial To Be Filled By O.E.M. Only readable by root
hex string of the Serial Number of the C:\ drive 7CB7433E GetVolumeInformationW ? ?
Win32_VideoController PNPDeviceId PCI\VEN_10DE&DEV_2486&SUBSYS_147A10DE&REV_A1\4&2283F625&0&0019 WMI ? ?
Win32_Processor Manufacturer AuthenticAMD WMI grep -m1 ^"vendor_id" /proc/cpuinfo | awk '{ print $3 }' AuthenticAMD
Win32_Processor ProcessorId 178BFBFF00A20F10 WMI ? ?
Win32_Processor Name AMD Ryzen 7 5800X 8-Core Processor (total length: 47, has 13 white spaces at the end) WMI grep -m1 ^"model name" /proc/cpuinfo | awk '{ split($0,a,": ") ; print a[2] }' AMD Ryzen 7 5800X 8-Core Processor Linux value is trimmed

Beth Net Launcher detection not working

In the WJ client at least, the detection of Beth Net is not working.

The log doesn't even mention the launcher.

All tested "known" registry locations had no traces of Morrowind.

Steam Location Fails if a Universe Missing

Synthesis just swapped to using GameFinder as it's backing logic (Mutagen itself swapped a while back, but Synthesis hadn't had a new version that included it until a few days ago). There have been a few users that have complained that it can't find the Skyrim data folder for them anymore.

I spent some time with Accelerando, who ran GameFinder's demo app, which helped a ton in narrowing down the problem.

Essentially, he had a vestigial steam universe listed
image

C:\Steam was listed, but apparently didn't actually have steamapps subfolder because they moved all the games to another universe. This caused a SteamUniverseNotFoundException, to throw. Skyrim was in the other universes, but those never got around to processing, as the current loop just stops in this situation.

I'd love if the patterns were adjusted so it's not an all or nothing affair? If 1/3 universes have an issue, I'd love to be able to try to query anyway and cross my fingers that the game I was looking for was in one of the others.

Invalid search path for Linux steam games

Ubuntu 22.04 seems to put steam game metadata in ~/.steam/ instead of ~/.local/steam/, is there a way to configure this alternate path. If not can we get a way to configure this?

Games not installed on c:\ result in paths with `\\`

In WJ, this test fails for a game installed on D:

        [Fact]
        public void GamePathsDontIncludeDuplicateBackslash()
        {
            var path = Game.Morrowind.MetaData().GameLocation();
            Assert.DoesNotContain("\\\\", path.ToString());
        }
Xunit.Sdk.DoesNotContainException
Assert.DoesNotContain() Failure
Found:    \\
In value: D:\\SteamLibrary\steamapps\common\Morrowind
   at Wabbajack.Common.Test.GameTests.GamePathsDontIncludeDuplicateBackslash() in C:\oss\wabbajack\Wabbajack.Common.Test\GameTests.cs:line 25

Publish single file supports?

C:\Program Files\dotnet\sdk\7.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.CrossTargeting.targets(27,5): erro
r NETSDK1129: não há suporte para o destino 'Publish' sem especificar uma estrutura de destino. O projeto atual se dest
ina a várias estruturas. Você precisa especificar a estrutura do aplicativo publicado.

Game finder finds no games

When trying to grab a list of steam games using the example provided in the readme, it outputs nothing, the collection is blank, and there is no error whatsoever. Why?

WMIHelper can't handle multiple result objects

In my case this happens when trying to get the display adpater for building the EA Desktop decryption key.
This is probably not too common, but I have WMI showing more than one display adapter (the second one being created by the VR software Virtual Desktop).

This might actually be a good thing in this case, because the "wrong" display adapter is listed first, which as far as I can tell would have created an invalid decryption key.

For this specific scenario it should be possible to determine the correct display adapter by checking the Status of the devices returned by WMI, because Virtual Desktop keeps the adapter disabled unless it is actively used (VD's adapter shows a status of Error, while the real one shows OK).

Stacktrace:

System.Management.ManagementException: Call cancelled 
   at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
   at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
   at System.Management.ManagementObjectCollection.CopyTo(Array array, Int32 index)
   at System.Management.ManagementObjectCollection.CopyTo(ManagementBaseObject[] objectCollection, Int32 index)
   at GameFinder.StoreHandlers.EADesktop.Crypto.Windows.WMIHelper.GetWMIProperty(String className, String propertyName) in D:\Programming\CSharp\Projects\_git\GitHub\GameFinder\src\GameFinder.StoreHandlers.EADesktop\Crypto\Windows\WMIHelper.cs:line 39

Full Win32_VideoController output, in case you want to look for a better way of getting the right one:

Caption                      : Virtual Desktop Monitor
Description                  : Virtual Desktop Monitor
InstallDate                  :
Name                         : Virtual Desktop Monitor
Status                       : Error
Availability                 : 8
ConfigManagerErrorCode       : 22
ConfigManagerUserConfig      : False
CreationClassName            : Win32_VideoController
DeviceID                     : VideoController1
ErrorCleared                 :
ErrorDescription             :
LastErrorCode                :
PNPDeviceID                  : ROOT\DISPLAY\0000
PowerManagementCapabilities  :
PowerManagementSupported     :
StatusInfo                   :
SystemCreationClassName      : Win32_ComputerSystem
SystemName                   : CMC-DATA
MaxNumberControlled          :
ProtocolSupported            :
TimeOfLastReset              :
AcceleratorCapabilities      :
CapabilityDescriptions       :
CurrentBitsPerPixel          :
CurrentHorizontalResolution  :
CurrentNumberOfColors        :
CurrentNumberOfColumns       :
CurrentNumberOfRows          :
CurrentRefreshRate           :
CurrentScanMode              :
CurrentVerticalResolution    :
MaxMemorySupported           :
MaxRefreshRate               :
MinRefreshRate               :
NumberOfVideoPages           :
VideoMemoryType              : 2
VideoProcessor               :
NumberOfColorPlanes          :
VideoArchitecture            : 5
VideoMode                    :
AdapterCompatibility         : Virtual Desktop, Inc.
AdapterDACType               :
AdapterRAM                   :
ColorTableEntries            :
DeviceSpecificPens           :
DitherType                   :
DriverDate                   : 2022-06-30 02:00:00
DriverVersion                : 15.39.56.845
ICMIntent                    :
ICMMethod                    :
InfFilename                  : oem86.inf
InfSection                   : MyDevice_Install.NT
InstalledDisplayDrivers      :
Monochrome                   : False
ReservedSystemPaletteEntries :
SpecificationVersion         :
SystemPaletteEntries         :
VideoModeDescription         :
PSComputerName               :

Caption                      : NVIDIA GeForce RTX 3080
Description                  : NVIDIA GeForce RTX 3080
InstallDate                  :
Name                         : NVIDIA GeForce RTX 3080
Status                       : OK
Availability                 : 3
ConfigManagerErrorCode       : 0
ConfigManagerUserConfig      : False
CreationClassName            : Win32_VideoController
DeviceID                     : VideoController2
ErrorCleared                 :
ErrorDescription             :
LastErrorCode                :
PNPDeviceID                  : PCI\VEN_10DE&DEV_2216&SUBSYS_88221043&REV_A1\4&37732CF4&0&0008
PowerManagementCapabilities  :
PowerManagementSupported     :
StatusInfo                   :
SystemCreationClassName      : Win32_ComputerSystem
SystemName                   : CMC-DATA
MaxNumberControlled          :
ProtocolSupported            :
TimeOfLastReset              :
AcceleratorCapabilities      :
CapabilityDescriptions       :
CurrentBitsPerPixel          : 32
CurrentHorizontalResolution  : 2560
CurrentNumberOfColors        : 4294967296
CurrentNumberOfColumns       : 0
CurrentNumberOfRows          : 0
CurrentRefreshRate           : 164
CurrentScanMode              : 4
CurrentVerticalResolution    : 1440
MaxMemorySupported           :
MaxRefreshRate               : 164
MinRefreshRate               : 50
NumberOfVideoPages           :
VideoMemoryType              : 2
VideoProcessor               : NVIDIA GeForce RTX 3080
NumberOfColorPlanes          :
VideoArchitecture            : 5
VideoMode                    :
AdapterCompatibility         : NVIDIA
AdapterDACType               : Integrated RAMDAC
AdapterRAM                   : 4293918720
ColorTableEntries            :
DeviceSpecificPens           :
DitherType                   : 0
DriverDate                   : 2023-06-08 02:00:00
DriverVersion                : 31.0.15.3623
ICMIntent                    :
ICMMethod                    :
InfFilename                  : oem139.inf
InfSection                   : Section070
InstalledDisplayDrivers      : C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispig.inf_amd64_7e5fd280efaa5445\nvld
                               umdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispig.inf_amd64_7e5fd280efaa
                               5445\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispig.inf_amd64_7e5
                               fd280efaa5445\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispig.inf_
                               amd64_7e5fd280efaa5445\nvldumdx.dll
Monochrome                   : False
ReservedSystemPaletteEntries :
SpecificationVersion         :
SystemPaletteEntries         :
VideoModeDescription         : 2560 x 1440 x 4294967296 colors
PSComputerName               :

Game Discovery Issue on Steam

GameFinder failed to discover Bannerlord. Some quick debugging yielded this

Unable to parse value of child object!
______________________________________
System.OverflowException: Value was either too large or too small for an unsigned byte.
   at System.Number.ThrowOverflowException(TypeCode type)
   at System.Byte.Parse(ReadOnlySpan`1 s, NumberStyles style, NumberFormatInfo info)
   at System.Byte.Parse(String s, IFormatProvider provider)
   at GameFinder.StoreHandlers.Steam.Services.ParserHelpers.<>c__DisplayClass2_0`1.ParseChildObjectValue>b__0()
   at FluentResults.Result.Try[T](Func`1 action, Func`2 catchHandler)

The value is StateFlag with value 550. The ValueType was Int32, but the Stacktrace shows Result<byte>
I see that StateFlag is hardcoded as ParseByte, so the parser might be wrong
Btw, it seems that 550 is Update Paused

appmanifest_261550.acf
  "AppState"
  {
	  "appid"		"261550"
	  "universe"		"1"
	  "LauncherPath"		"C:\\Program Files (x86)\\Steam\\steam.exe"
	  "name"		"Mount & Blade II: Bannerlord"
	  "StateFlags"		"550"
	  "installdir"		"Mount & Blade II Bannerlord"
	  "LastUpdated"		"1690015272"
	  "SizeOnDisk"		"53423353739"
	  "StagingSize"		"0"
	  "buildid"		"11757198"
	  "LastOwner"		"76561198003106254"
	  "UpdateResult"		"12"
	  "BytesToDownload"		"3245578720"
	  "BytesDownloaded"		"0"
	  "BytesToStage"		"8912672474"
	  "BytesStaged"		"0"
	  "TargetBuildID"		"11865107"
	  "AutoUpdateBehavior"		"0"
	  "AllowOtherDownloadsWhileRunning"		"0"
	  "ScheduledAutoUpdate"		"1691979122"
	  "SingleFileUpdateMode"		"1"
	  "InstalledDepots"
	  {
		  "261552"
		  {
			  "manifest"		"8815693920949905826"
			  "size"		"4742750445"
		  }
		  "261551"
		  {
			  "manifest"		"2738993997005348582"
			  "size"		"47470544558"
		  }
		  "2240111"
		  {
			  "manifest"		"6194812840481947105"
			  "size"		"1210058736"
			  "dlcappid"		"2240110"
		  }
	  }
	  "SharedDepots"
	  {
		  "228988"		"228980"
		  "229006"		"228980"
	  }
	  "UserConfig"
	  {
		  "language"		"english"
		  "BetaKey"		"v1.2.0"
	  }
	  "MountedConfig"
	  {
		  "language"		"english"
		  "BetaKey"		"v1.2.0"
	  }
  }
  

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update dependency OneOf to v3.0.271

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v3
  • actions/checkout v3
  • codecov/codecov-action v3
  • actions/upload-artifact v3
.github/workflows/release.yml
  • actions/checkout v3
  • mindsers/changelog-reader-action v2
  • softprops/action-gh-release v1
.github/workflows/validate-codecov.yml
  • actions/checkout v3
nuget
Directory.Packages.props
  • GitHubActionsTestLogger 2.3.3
  • coverlet.collector 6.0.2
  • xunit.runner.visualstudio 2.5.7
  • Xunit.SkippableFact 1.4.13
  • xunit 2.7.0
  • NSubstitute.Analyzers.CSharp 1.0.17
  • NSubstitute 5.1.0
  • Microsoft.NET.Test.Sdk 17.9.0
  • FluentResults.Extensions.FluentAssertions 2.1.1
  • FluentAssertions.Analyzers 0.31.0
  • FluentAssertions 6.12.0
  • AutoFixture.Xunit2 4.18.1
  • AutoFixture 4.18.1
  • Microsoft.SourceLink.GitHub 8.0.0
  • JetBrains.Annotations 2023.3.0
  • Meziantou.Analyzer 2.0.146
  • TransparentValueObjects 1.0.1
  • ValveKeyValue 0.10.0.360
  • System.Management 8.0.0
  • SHA3.Net 2.0.0
  • OneOf 3.0.263
  • NLog.Extensions.Logging 5.3.8
  • NLog 5.2.8
  • NexusMods.Paths.TestingHelpers 0.9.0
  • NexusMods.Paths 0.9.0
  • Microsoft.Win32.Registry 5.0.0
  • FluentResults 3.15.2
  • CommandLineParser 2.9.1
  • BenchmarkDotNet 0.13.12

  • Check this box to trigger a request for Renovate to run again on this repository

Mo2 Ini Sourcing

On the topic of #15 where the game might be in atypical locations due to WJ "stock game" installations

If LostDragonist's fix registries Mo2 plugin (https://github.com/LostDragonist/MO2-Plugins) isnt installed, then registry lookups will fail.

Might also be nice to add some logic to sense if the program is being started via mo2, and look to mo2 ini sources for game location? I'm not too sure the details of what would go into this, but would add another nice layer of robustness

Change 'Can't find Manifest Folder / Directory' Errors to warnings

In Origin Game Finder, Epic Games Finder... Other Games Finders?

Using github actions with wabbajack and it's picking these up as errors and killing the process pre-emptively. Wondering if they could be changed to warnings? Unless there is a specific reason they are exceptions?

Add Registry Bounce

Just pitching the idea of adding registry support. Currently mutagen uses GameFinder, but only if it cannot locate an installation in the registry:
https://github.com/Mutagen-Modding/Mutagen/blob/cf708daf0b89c643b94bf08c28e7ab2a719d9451/Mutagen.Bethesda.Core.Windows/Installs/DI/GameLocator.cs#L50

Might be nice to just bubble that up to this lib? Is there a specific reason registries are not considered?

This would also help with WJ "stock game" installs, which you can see some discussions here:
https://discord.com/channels/759302581448474626/883872997214158909/883872999562960906
https://discord.com/channels/605449136870916175/623261438022254612/883870322581962792

Something is up with the nuget.

With the nuget package for 1.6.2, the Steam handler can't find Skyrim SE because it's looking for .steam in the user home folder (so the Linux method). And on Linux I'm seeing this:

[xUnit.net 00:00:01.03]     Wabbajack.Installer.Test.StandardInstallerTest.CanInstallAList [FAIL]
  Failed Wabbajack.Installer.Test.StandardInstallerTest.CanInstallAList [85 ms]
  Error Message:
   System.TypeInitializationException : The type initializer for 'Microsoft.Win32.Registry' threw an exception.
---- System.PlatformNotSupportedException : Registry is not supported on this platform.
  Stack Trace:
     at GameFinder.StoreHandlers.Steam.SteamHandler..ctor(ILogger logger) in GameFinder.StoreHandlers.Steam.dll:token 0x6000022+0x1d
   at Wabbajack.Installer.GameLocator..ctor(ILogger`1 logger) in /home/runner/work/wabbajack-redux/wabbajack-redux/Wabbajack.Installer/GameLocator.cs:line 20
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in System.Private.CoreLib.dll:token 0x6004d21+0x63
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000076+0x39
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000091+0x4f
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000079+0x59

It looks like the OS detection isn't working correctly.

This might be better done via a runtime check?

string initialPath = "";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    initialPath = @"Extractors\windows-x64\7z.exe";
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    initialPath = @"Extractors\linux-x64\7zz";
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
    initialPath = @"Extractors\mac\7zz";

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.