-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSteamLibrary.cs
More file actions
127 lines (107 loc) · 4.38 KB
/
Copy pathSteamLibrary.cs
File metadata and controls
127 lines (107 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Abstractions;
using AET.SteamAbstraction.Games;
using AnakinRaW.CommonUtilities.FileSystem.Normalization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace AET.SteamAbstraction.Library;
internal class SteamLibrary : ISteamLibrary
{
private static readonly PathNormalizeOptions SteamLibraryPathNormalizeOptions = new()
{
UnifyCase = UnifyCasingKind.UpperCase,
TrailingDirectorySeparatorBehavior = TrailingDirectorySeparatorBehavior.Trim
};
private readonly string _normalizedLocation;
private readonly ILogger? _logger;
private readonly ConcurrentDictionary<KnownLibraryLocations, IDirectoryInfo> _locations = new();
private protected readonly IFileSystem FileSystem;
private readonly Dictionary<KnownLibraryLocations, string[]> _locationsNames = new()
{
{ KnownLibraryLocations.SteamApps, ["steamapps"] },
{ KnownLibraryLocations.Common, ["steamapps", "common"] },
{ KnownLibraryLocations.Workshops, ["steamapps", "workshop"] }
};
public IDirectoryInfo LibraryLocation { get; }
public IDirectoryInfo SteamAppsLocation => GetKnownLibraryLocation(KnownLibraryLocations.SteamApps);
public IDirectoryInfo CommonLocation => GetKnownLibraryLocation(KnownLibraryLocations.Common);
public IDirectoryInfo WorkshopsLocation => GetKnownLibraryLocation(KnownLibraryLocations.Workshops);
public SteamLibrary(IDirectoryInfo libraryLocation, IServiceProvider serviceProvider)
{
if (libraryLocation == null)
throw new ArgumentNullException(nameof(libraryLocation));
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
FileSystem = serviceProvider.GetRequiredService<IFileSystem>();
_logger = serviceProvider.GetService<ILoggerFactory>()?.CreateLogger(GetType());
_normalizedLocation = PathNormalizer.Normalize(FileSystem.Path.GetFullPath(libraryLocation.FullName), SteamLibraryPathNormalizeOptions);
LibraryLocation = libraryLocation;
}
public IEnumerable<SteamAppManifest> GetApps()
{
if (!SteamAppsLocation.Exists)
return [];
var apps = new HashSet<SteamAppManifest>();
foreach (var manifestFile in SteamAppsLocation.EnumerateFiles("*.acf", SearchOption.TopDirectoryOnly))
{
try
{
var manifest = SteamVdfReader.ReadManifest(manifestFile, this);
apps.Add(manifest);
}
catch (SteamException e)
{
_logger?.LogWarning(e, "Could not read game manifest file '{ManifestFile}': {Message}", manifestFile, e.Message);
}
}
return apps;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(this, obj))
return true;
return obj is ISteamLibrary other && Equals(other);
}
public override int GetHashCode()
{
return _normalizedLocation.GetHashCode();
}
public bool Equals(ISteamLibrary? other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
var normalizedOtherPath = PathNormalizer.Normalize(FileSystem.Path.GetFullPath(other.LibraryLocation.FullName), SteamLibraryPathNormalizeOptions);
return _normalizedLocation.Equals(normalizedOtherPath);
}
[ExcludeFromCodeCoverage]
public override string ToString()
{
return $"SteamLibrary: '{LibraryLocation.FullName}'";
}
private IDirectoryInfo GetKnownLibraryLocation(KnownLibraryLocations location)
{
return _locations.GetOrAdd(location, l =>
{
var fs = LibraryLocation.FileSystem;
var subPathParts = _locationsNames[l];
var basePath = LibraryLocation.FullName;
var pathParts = new string[subPathParts.Length + 1];
pathParts[0] = basePath;
Array.Copy(subPathParts, 0, pathParts, 1, subPathParts.Length);
var locationPath = fs.Path.Combine(pathParts);
return fs.DirectoryInfo.New(locationPath);
});
}
private enum KnownLibraryLocations
{
SteamApps,
Common,
Workshops
}
}