Skip to content

Commit

Permalink
Merge pull request #2052 from Nexus-Mods/feat/bg3-support
Browse files Browse the repository at this point in the history
Basic BG3 support
  • Loading branch information
Al12rs authored Sep 19, 2024
2 parents 05fa47a + c63937d commit 912f65e
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 0 deletions.
8 changes: 8 additions & 0 deletions NexusMods.App.sln
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,11 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Collections", "src\NexusMods.Collections\NexusMods.Collections.csproj", "{A9FD538A-E101-4AEA-A98E-35DCED950AEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Collections.Tests", "tests\NexusMods.Collections.Tests\NexusMods.Collections.Tests.csproj", "{8C817874-7A88-450E-B216-851A1B03684C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.Media", "src\Abstractions\NexusMods.Abstractions.Media\NexusMods.Abstractions.Media.csproj", "{5CB6D02C-07D0-4C0D-BF5C-4E2E958A0612}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Games.Larian", "src\Games\NexusMods.Games.Larian\NexusMods.Games.Larian.csproj", "{2A35EBB5-1CA6-4F5D-8CE8-352146C82C28}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -661,6 +664,10 @@ Global
{5CB6D02C-07D0-4C0D-BF5C-4E2E958A0612}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CB6D02C-07D0-4C0D-BF5C-4E2E958A0612}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CB6D02C-07D0-4C0D-BF5C-4E2E958A0612}.Release|Any CPU.Build.0 = Release|Any CPU
{2A35EBB5-1CA6-4F5D-8CE8-352146C82C28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A35EBB5-1CA6-4F5D-8CE8-352146C82C28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A35EBB5-1CA6-4F5D-8CE8-352146C82C28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A35EBB5-1CA6-4F5D-8CE8-352146C82C28}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -779,6 +786,7 @@ Global
{A9FD538A-E101-4AEA-A98E-35DCED950AEE} = {E7BAE287-D505-4D6D-A090-665A64309B2D}
{8C817874-7A88-450E-B216-851A1B03684C} = {52AF9D62-7D5B-4AD0-BA12-86F2AA67428B}
{5CB6D02C-07D0-4C0D-BF5C-4E2E958A0612} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{2A35EBB5-1CA6-4F5D-8CE8-352146C82C28} = {70D38D24-79AE-4600-8E83-17F3C11BA81F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9F9F8352-34DD-42C0-8564-EE9AF34A3501}
Expand Down
70 changes: 70 additions & 0 deletions src/Games/NexusMods.Games.Larian/BaldursGate3/BaldursGate3.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using Microsoft.Extensions.DependencyInjection;
using NexusMods.Abstractions.GameLocators;
using NexusMods.Abstractions.GameLocators.GameCapabilities;
using NexusMods.Abstractions.GameLocators.Stores.GOG;
using NexusMods.Abstractions.GameLocators.Stores.Steam;
using NexusMods.Abstractions.Games;
using NexusMods.Abstractions.Games.DTO;
using NexusMods.Abstractions.IO;
using NexusMods.Abstractions.IO.StreamFactories;
using NexusMods.Abstractions.Loadouts.Synchronizers;
using NexusMods.Paths;

namespace NexusMods.Games.Larian.BaldursGate3;

public class BaldursGate3 : AGame, ISteamGame, IGogGame
{
private readonly IServiceProvider _serviceProvider;
private readonly IOSInformation _osInformation;
public override string Name => "Baldur's Gate 3";

public IEnumerable<uint> SteamIds => [1086940u];
public IEnumerable<long> GogIds => [1456460669];

public static GameDomain GameDomain => GameDomain.From("baldursgate3");
public override GameDomain Domain => GameDomain;

public BaldursGate3(IServiceProvider provider) : base(provider)
{
_serviceProvider = provider;
_osInformation = provider.GetRequiredService<IOSInformation>();
}

public override GamePath GetPrimaryFile(GameStore store)
{
if (_osInformation.IsOSX)
return new GamePath(LocationId.Game, "Contents/MacOS/Baldur's Gate 3");
return new GamePath(LocationId.Game, "bin/bg3.exe");
}

protected override IReadOnlyDictionary<LocationId, AbsolutePath> GetLocations(IFileSystem fileSystem, GameLocatorResult installation)
{
var result = new Dictionary<LocationId, AbsolutePath>()
{
{ LocationId.Game, installation.Path },
{ LocationId.From("Mods"), fileSystem.GetKnownPath(KnownPath.HomeDirectory).Combine("Larian Studios/Baldur's Gate 3/Mods") },
{ LocationId.From("PlayerProfiles"), fileSystem.GetKnownPath(KnownPath.HomeDirectory).Combine("Larian Studios/Baldur's Gate 3/PlayerProfiles/Public") },
{ LocationId.From("ScriptExtenderConfig"), fileSystem.GetKnownPath(KnownPath.HomeDirectory).Combine("Larian Studios/Baldur's Gate 3/ScriptExtender") },
};
return result;
}

/// <inheritdoc />
public override List<IModInstallDestination> GetInstallDestinations(IReadOnlyDictionary<LocationId, AbsolutePath> locations)
{
// TODO: fill this in for Generic installer
return [];
}

protected override ILoadoutSynchronizer MakeSynchronizer(IServiceProvider provider)
{
return new BaldursGate3Synchronizer(provider);
}

// TODO: We are using Icon for both Spine and GameWidget and GameImage is unused. We should use GameImage for the GameWidget, but need to update all the games to have better images.
public override IStreamFactory Icon =>
new EmbededResourceStreamFactory<BaldursGate3>("NexusMods.Games.Larian.Resources.BaldursGate3.icon.png");

public override IStreamFactory GameImage =>
new EmbededResourceStreamFactory<BaldursGate3>("NexusMods.Games.Larian.Resources.BaldursGate3.icon.png");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using NexusMods.Abstractions.Settings;

namespace NexusMods.Games.Larian.BaldursGate3;

public class BaldursGate3Settings : ISettings
{

/// <summary>
/// If true, the contents of the game folder will be backed up. If the game updates
/// the loadout may become invalid. If mods are installed into this folder via the app they
/// will still be backed up as needed
/// </summary>
public bool DoFullGameBackup { get; set; } = false;

public static ISettingsBuilder Configure(ISettingsBuilder settingsBuilder)
{
return settingsBuilder.AddToUI<BaldursGate3Settings>(builder => builder
.AddPropertyToUI(x => x.DoFullGameBackup, propertyBuilder => propertyBuilder
.AddToSection(Sections.Experimental)
.WithDisplayName("Full game backup: Baldur's Gate 3")
.WithDescription("Backup all game folders, this will greatly increase disk space usage. Should only be changed before managing the game.")
.UseBooleanContainer()
)
);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.Extensions.DependencyInjection;
using NexusMods.Abstractions.GameLocators;
using NexusMods.Abstractions.Loadouts.Synchronizers;
using NexusMods.Abstractions.Settings;

namespace NexusMods.Games.Larian.BaldursGate3;

public class BaldursGate3Synchronizer : ALoadoutSynchronizer
{
private readonly BaldursGate3Settings _settings;

private static GamePath GameFolder => new(LocationId.Game, "");
private static GamePath PublicPlayerProfiles => new(LocationId.From("PlayerProfiles"), "");

private static GamePath ModSettingsFile => new(LocationId.From("PlayerProfiles"), "modsettings.lsx");


public BaldursGate3Synchronizer(IServiceProvider provider) : base(provider)
{
var settingsManager = provider.GetRequiredService<ISettingsManager>();
_settings = settingsManager.Get<BaldursGate3Settings>();
}

public override bool IsIgnoredPath(GamePath path)
{
// Always ignore all PlayerProfile files except the modsettings file.
return path.InFolder(PublicPlayerProfiles) && path.Path != ModSettingsFile.Path;
}

public override bool IsIgnoredBackupPath(GamePath path)
{
if (_settings.DoFullGameBackup) return false;

// Optionally ignore all game folder files for size reasons
return path.InFolder(GameFolder) ||
(path.InFolder(PublicPlayerProfiles) && path.Path != ModSettingsFile.Path);
}
}
17 changes: 17 additions & 0 deletions src/Games/NexusMods.Games.Larian/BaldursGate3/Services.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Microsoft.Extensions.DependencyInjection;
using NexusMods.Abstractions.Games;
using NexusMods.Abstractions.Settings;

namespace NexusMods.Games.Larian.BaldursGate3;

public static class Services
{
public static IServiceCollection AddBaldursGate3(this IServiceCollection services)
{
services
.AddGame<BaldursGate3>()
.AddSettings<BaldursGate3Settings>();

return services;
}
}
19 changes: 19 additions & 0 deletions src/Games/NexusMods.Games.Larian/NexusMods.Games.Larian.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\..\Abstractions\NexusMods.Abstractions.Games\NexusMods.Abstractions.Games.csproj" />
<ProjectReference Include="..\..\Abstractions\NexusMods.Abstractions.Settings\NexusMods.Abstractions.Settings.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Resources\BaldursGate3\" />
</ItemGroup>

<ItemGroup>
<None Remove="Resources\BaldursGate3\game_image.jpg" />
<EmbeddedResource Include="Resources\BaldursGate3\game_image.jpg" />
<None Remove="Resources\BaldursGate3\icon.png" />
<EmbeddedResource Include="Resources\BaldursGate3\icon.png" />
</ItemGroup>

</Project>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/NexusMods.App/NexusMods.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<ProjectReference Include="..\Games\NexusMods.Games.FOMOD.UI\NexusMods.Games.FOMOD.UI.csproj" />
<ProjectReference Include="..\Games\NexusMods.Games.FOMOD\NexusMods.Games.FOMOD.csproj" />
<ProjectReference Include="..\Games\NexusMods.Games.Generic\NexusMods.Games.Generic.csproj" />
<ProjectReference Include="..\Games\NexusMods.Games.Larian\NexusMods.Games.Larian.csproj" />
<ProjectReference Include="..\Games\NexusMods.Games.TestHarness\NexusMods.Games.TestHarness.csproj" />
<ProjectReference Include="..\Networking\NexusMods.Networking.Downloaders\NexusMods.Networking.Downloaders.csproj" />
<ProjectReference Include="..\Networking\NexusMods.Networking.HttpDownloader\NexusMods.Networking.HttpDownloader.csproj" />
Expand Down
2 changes: 2 additions & 0 deletions src/NexusMods.App/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using NexusMods.Games.FOMOD;
using NexusMods.Games.FOMOD.UI;
using NexusMods.Games.Generic;
using NexusMods.Games.Larian.BaldursGate3;
using NexusMods.Games.TestHarness;
using NexusMods.Jobs;
using NexusMods.Library;
Expand Down Expand Up @@ -125,6 +126,7 @@ private static IServiceCollection AddSupportedGames(this IServiceCollection serv
{
if (experimentalSettings is { EnableAllGames: true })
{
services.AddBaldursGate3();
}

Games.RedEngine.Services.AddRedEngineGames(services);
Expand Down

0 comments on commit 912f65e

Please sign in to comment.