Skip to content

Commit

Permalink
Fix #118
Browse files Browse the repository at this point in the history
  • Loading branch information
erri120 committed Jan 8, 2024
1 parent ed3826c commit b781c60
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 32 deletions.
35 changes: 9 additions & 26 deletions src/GameFinder.StoreHandlers.Steam/Models/AppManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ public sealed record AppManifest
/// that was parsed to produce this <see cref="AppManifest"/>.
/// </summary>
/// <example><c>E:/SteamLibrary/steamapps/appmanifest_262060.acf</c></example>
/// <seealso cref="InstallationDirectoryName"/>
/// <seealso cref="GetInstallationDirectoryPath"/>
/// <seealso cref="InstallationDirectory"/>
public required AbsolutePath ManifestPath { get; init; }

#region Parsed Values
Expand All @@ -55,15 +54,9 @@ public sealed record AppManifest
public required StateFlags StateFlags { get; init; }

/// <summary>
/// Gets the name of the installation directory of the app.
/// Gets the <see cref="AbsolutePath"/> to the installation directory of the app.
/// </summary>
/// <remarks>
/// This is the relative path to the installation directory.
/// Use <see cref="GetInstallationDirectoryPath"/> get the absolute path.
/// </remarks>
/// <example><c>DarkestDungeon</c></example>
/// <seealso cref="GetInstallationDirectoryPath"/>
public required RelativePath InstallationDirectoryName { get; init; }
public required AbsolutePath InstallationDirectory { get; init; }

/// <summary>
/// Gets the time when the app was last updated.
Expand All @@ -78,7 +71,7 @@ public sealed record AppManifest
/// </summary>
/// <remarks>
/// This value is only set when installing or updating the app. If the
/// user adds or removes files from the <see cref="InstallationDirectoryName"/>, Steam
/// user adds or removes files from the <see cref="InstallationDirectory"/>, Steam
/// won't update this value automatically. This value will be <see cref="Size.Zero"/>
/// while the app is being staged.
/// </remarks>
Expand Down Expand Up @@ -244,16 +237,6 @@ public Result<AppManifest> Reload()
return AppManifestParser.ParseManifestFile(ManifestPath);
}

/// <summary>
/// Gets the <see cref="AbsolutePath"/> to the installation directory of the app.
/// </summary>
/// <remarks>This uses <see cref="ManifestPath"/> to get to the installation directory.</remarks>
/// <example><c>E:/SteamLibrary/steamapps/common/DarkestDungeon</c></example>
/// <seealso cref="InstallationDirectoryName"/>
public AbsolutePath GetInstallationDirectoryPath() => ManifestPath.Parent
.Combine(CommonDirectoryName)
.Combine(InstallationDirectoryName);

/// <summary>
/// Gets the path to the <c>appworkshop_*.acf</c> file.
/// </summary>
Expand Down Expand Up @@ -326,7 +309,7 @@ public bool Equals(AppManifest? other)
if (Universe != other.Universe) return false;
if (!string.Equals(Name, other.Name, StringComparison.Ordinal)) return false;
if (StateFlags != other.StateFlags) return false;
if (InstallationDirectoryName != other.InstallationDirectoryName) return false;
if (InstallationDirectory != other.InstallationDirectory) return false;
if (LastUpdated != other.LastUpdated) return false;
if (SizeOnDisk != other.SizeOnDisk) return false;
if (StagingSize != other.StagingSize) return false;
Expand Down Expand Up @@ -359,7 +342,7 @@ public override int GetHashCode()
hashCode.Add((int)Universe);
hashCode.Add(Name);
hashCode.Add((int)StateFlags);
hashCode.Add(InstallationDirectoryName);
hashCode.Add(InstallationDirectory);
hashCode.Add(LastUpdated);
hashCode.Add(SizeOnDisk);
hashCode.Add(StagingSize);
Expand Down Expand Up @@ -389,9 +372,9 @@ public override string ToString()
var sb = new StringBuilder();

sb.Append("{ ");
sb.Append($"AppId = {AppId}, ");
sb.Append($"Name = {Name}, ");
sb.Append($"InstallationDirectoryName = {InstallationDirectoryName}");
sb.Append($"{nameof(AppId)} = {AppId}, ");
sb.Append($"{nameof(Name)} = {Name}, ");
sb.Append($"{nameof(InstallationDirectory)} = {InstallationDirectory}");
sb.Append(" }");

return sb.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using GameFinder.StoreHandlers.Steam.Models.ValueTypes;
using JetBrains.Annotations;
using NexusMods.Paths;
using NexusMods.Paths.Utilities;
using ValveKeyValue;
using static GameFinder.StoreHandlers.Steam.Services.ParserHelpers;

Expand Down Expand Up @@ -71,7 +72,7 @@ public static Result<AppManifest> ParseManifestFile(AbsolutePath manifestPath)
var universeResult = ParseOptionalChildObject(appState, "Universe", ParseUInt32, default).Map(x => (SteamUniverse)x);
var nameResult = ParseRequiredChildObject(appState, "name", ParseString);
var stateFlagsResult = ParseRequiredChildObject(appState, "StateFlags", ParseUInt32).Map(x => (StateFlags)x);
var installationDirectoryNameResult = ParseRequiredChildObject(appState, "installdir", x => ParseRelativePath(x, manifestPath.FileSystem));
var installationDirectoryNameResult = ParseInstallationDirectory(appState, manifestPath.FileSystem, manifestPath);
var lastUpdatedResult = ParseOptionalChildObject(appState, "LastUpdated", ParseDateTimeOffset, DateTimeOffset.UnixEpoch);
var sizeOnDiskResult = ParseOptionalChildObject(appState, "SizeOnDisk", ParseSize, Size.Zero);
var stagingSizeResult = ParseOptionalChildObject(appState, "StagingSize", ParseSize, Size.Zero);
Expand Down Expand Up @@ -153,7 +154,7 @@ public static Result<AppManifest> ParseManifestFile(AbsolutePath manifestPath)
Universe = universeResult.Value,
Name = nameResult.Value,
StateFlags = stateFlagsResult.Value,
InstallationDirectoryName = installationDirectoryNameResult.Value,
InstallationDirectory = installationDirectoryNameResult.Value,

LastUpdated = lastUpdatedResult.Value,
SizeOnDisk = sizeOnDiskResult.Value,
Expand Down Expand Up @@ -188,6 +189,28 @@ public static Result<AppManifest> ParseManifestFile(AbsolutePath manifestPath)
}
}

private static Result<AbsolutePath> ParseInstallationDirectory(KVObject appState, IFileSystem fileSystem, AbsolutePath manifestPath)
{
var installDirectoryResult = FindRequiredChildObject(appState, "installdir");
if (installDirectoryResult.IsFailed) return installDirectoryResult.ToResult();

var parseResult = ParseChildObjectValue(installDirectoryResult.Value, appState, ParseString);
if (parseResult.IsFailed) return parseResult.ToResult();

var rawPath = parseResult.Value;
var sanitizedPath = PathHelpers.Sanitize(rawPath, fileSystem.OS);
var isRelative = PathHelpers.GetRootLength(sanitizedPath, fileSystem.OS) == -1;

if (isRelative)
{
var relativePath = new RelativePath(sanitizedPath);
return Result.Ok(manifestPath.Parent.Combine("common").Combine(relativePath));
}

var absolutePath = fileSystem.FromUnsanitizedFullPath(rawPath);
return absolutePath;
}

private static Result<IReadOnlyDictionary<DepotId, InstalledDepot>> ParseInstalledDepots(KVObject appState)
{
var installedDepotsObject = FindOptionalChildObject(appState, "InstalledDepots");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static Result Write(AppManifest manifest, AbsolutePath outputPath)
values.AddValue("Universe", (byte)manifest.Universe, -1);
values.AddValue("name", manifest.Name, string.Empty);
values.AddValue("StateFlags", (byte)manifest.StateFlags, -1);
values.AddValue("installdir", manifest.InstallationDirectoryName.ToString(), string.Empty);
values.AddValue("installdir", manifest.InstallationDirectory.Name.ToString(), string.Empty);
values.AddValue("LastUpdated", manifest.LastUpdated.ToUnixTimeSeconds(), default);
values.AddValue("SizeOnDisk", manifest.SizeOnDisk.Value, default);
values.AddValue("StagingSize", manifest.StagingSize.Value, default);
Expand Down
2 changes: 1 addition & 1 deletion src/GameFinder.StoreHandlers.Steam/SteamGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public sealed record SteamGame : IGame
/// <summary>
/// Gets the absolute path to the game's installation directory.
/// </summary>
public AbsolutePath Path => AppManifest.GetInstallationDirectoryPath();
public AbsolutePath Path => AppManifest.InstallationDirectory;

/// <summary>
/// Gets the absolute path to the cloud saves directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static AppManifest CreateAppManifest(AbsolutePath manifestPath)
Universe = SteamUniverse.Public,
Name = fixture.Create<string>(),
StateFlags = StateFlags.FullyInstalled,
InstallationDirectoryName = fixture.Create<string>().ToRelativePath(),
InstallationDirectory = manifestPath.Parent.Combine("common").Combine(fixture.Create<string>()),
LastUpdated = fixture.Create<DateTimeOffset>(),
SizeOnDisk = fixture.Create<Size>(),
StagingSize = fixture.Create<Size>(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void Test_Success_OnlyRequired(AbsolutePath manifestFilePath)
AppId = AppId.From(262060),
Name = "Darkest Dungeon",
StateFlags = StateFlags.FullyInstalled,
InstallationDirectoryName = "DarkestDungeon",
InstallationDirectory = manifestFilePath.Parent.Combine("common").Combine("DarkestDungeon"),
};

var writeResult = AppManifestWriter.Write(expected, manifestFilePath);
Expand Down

0 comments on commit b781c60

Please sign in to comment.