- Minor refactoring
- Fixed minor harmless Epic game path inconsistencies
- Fixed Epic Games DLC overrides
This commit is contained in:
pointfeev 2023-07-01 10:40:30 -04:00
parent d307b22fd7
commit e7215829f0
8 changed files with 61 additions and 60 deletions

View file

@ -4,7 +4,7 @@
<TargetFramework>net7.0-windows10.0.22621.0</TargetFramework> <TargetFramework>net7.0-windows10.0.22621.0</TargetFramework>
<UseWindowsForms>True</UseWindowsForms> <UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>Resources\ini.ico</ApplicationIcon> <ApplicationIcon>Resources\ini.ico</ApplicationIcon>
<Version>4.9.7</Version> <Version>4.9.8</Version>
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright> <Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
<Company>CreamInstaller</Company> <Company>CreamInstaller</Company>
<Product>Automatic DLC Unlocker Installer &amp; Configuration Generator</Product> <Product>Automatic DLC Unlocker Installer &amp; Configuration Generator</Product>

View file

@ -369,14 +369,11 @@ internal sealed partial class SelectForm : CustomForm
} }
if (Program.Canceled) if (Program.Canceled)
return; return;
ConcurrentDictionary<SelectionDLC, byte> catalogItems = new();
// get catalog items
ConcurrentDictionary<SelectionDLC, byte> entitlements = new();
List<Task> dlcTasks = new(); List<Task> dlcTasks = new();
List<(string id, string name, string product, string icon, string developer)> ConcurrentDictionary<SelectionDLC, byte> catalogItems = new();
entitlementIds = await EpicStore.QueryEntitlements(@namespace); List<(string id, string name, string product, string icon, string developer)> catalogIds = await EpicStore.QueryCatalog(@namespace);
if (entitlementIds.Count > 0) if (catalogIds.Count > 0)
foreach ((string id, string name, string product, string icon, string developer) in entitlementIds) foreach ((string id, string name, string product, string icon, string developer) in catalogIds)
{ {
if (Program.Canceled) if (Program.Canceled)
return; return;
@ -385,11 +382,11 @@ internal sealed partial class SelectForm : CustomForm
{ {
if (Program.Canceled) if (Program.Canceled)
return; return;
SelectionDLC entitlement = SelectionDLC.GetOrCreate(DLCType.EpicEntitlement, @namespace, id, name); SelectionDLC catalogItem = SelectionDLC.GetOrCreate(DLCType.Epic, @namespace, id, name);
entitlement.Icon = icon; catalogItem.Icon = icon;
entitlement.Product = product; catalogItem.Product = product;
entitlement.Publisher = developer; catalogItem.Publisher = developer;
_ = entitlements.TryAdd(entitlement, default); _ = catalogItems.TryAdd(catalogItem, default);
RemoveFromRemainingDLCs(id); RemoveFromRemainingDLCs(id);
}); });
dlcTasks.Add(task); dlcTasks.Add(task);
@ -402,14 +399,14 @@ internal sealed partial class SelectForm : CustomForm
return; return;
await task; await task;
} }
if (catalogItems.IsEmpty && entitlements.IsEmpty) if (catalogItems.IsEmpty)
{ {
RemoveFromRemainingGames(name); RemoveFromRemainingGames(name);
return; return;
} }
Selection selection = Selection.GetOrCreate(Platform.Epic, @namespace, name, directory, dllDirectories, Selection selection = Selection.GetOrCreate(Platform.Epic, @namespace, name, directory, dllDirectories,
await directory.GetExecutableDirectories(true)); await directory.GetExecutableDirectories(true));
foreach ((SelectionDLC dlc, _) in entitlements.Where(dlc => dlc.Key.Name == selection.Name)) foreach ((SelectionDLC dlc, _) in catalogItems.Where(dlc => dlc.Key.Name == selection.Name))
{ {
if (Program.Canceled) if (Program.Canceled)
return; return;
@ -425,16 +422,9 @@ internal sealed partial class SelectForm : CustomForm
return; return;
if (selection.TreeNode.TreeView is null) if (selection.TreeNode.TreeView is null)
_ = selectionTreeView.Nodes.Add(selection.TreeNode); _ = selectionTreeView.Nodes.Add(selection.TreeNode);
if (!catalogItems.IsEmpty) if (catalogItems.IsEmpty)
foreach ((SelectionDLC dlc, _) in catalogItems)
{
if (Program.Canceled)
return;
dlc.Selection = selection;
}
if (entitlements.IsEmpty)
return; return;
foreach ((SelectionDLC dlc, _) in entitlements) foreach ((SelectionDLC dlc, _) in catalogItems)
{ {
if (Program.Canceled) if (Program.Canceled)
return; return;

View file

@ -39,7 +39,8 @@ internal static class EpicLibrary
try try
{ {
Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json); Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json);
if (manifest is not null && games.All(g => g.CatalogNamespace != manifest.CatalogNamespace)) if (manifest is not null && (manifest.InstallLocation = manifest.InstallLocation.ResolvePath()) is not null
&& games.All(g => g.CatalogNamespace != manifest.CatalogNamespace))
games.Add(manifest); games.Add(manifest);
} }
catch catch

View file

@ -12,22 +12,15 @@ namespace CreamInstaller.Platforms.Epic;
internal static class EpicStore internal static class EpicStore
{ {
//private const int CooldownCatalogItem = 600; private const int Cooldown = 600;
/* need a method to query catalog items internal static async Task<List<(string id, string name, string product, string icon, string developer)>> QueryCatalog(string categoryNamespace)
internal static async Task QueryCatalogItems(Manifest manifest)
{
}*/
private const int CooldownEntitlement = 600;
internal static async Task<List<(string id, string name, string product, string icon, string developer)>> QueryEntitlements(string categoryNamespace)
{ {
List<(string id, string name, string product, string icon, string developer)> dlcIds = new(); List<(string id, string name, string product, string icon, string developer)> dlcIds = new();
string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json"; string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json";
bool cachedExists = cacheFile.FileExists(); bool cachedExists = cacheFile.FileExists();
Response response = null; Response response = null;
if (!cachedExists || ProgramData.CheckCooldown(categoryNamespace, CooldownEntitlement)) if (!cachedExists || ProgramData.CheckCooldown(categoryNamespace, Cooldown))
{ {
response = await QueryGraphQL(categoryNamespace); response = await QueryGraphQL(categoryNamespace);
try try

View file

@ -28,7 +28,7 @@ internal static class HeroicLibrary
try try
{ {
HeroicAppData appData = token.ToObject<HeroicAppData>(); HeroicAppData appData = token.ToObject<HeroicAppData>();
if (appData is null || string.IsNullOrWhiteSpace(appData.Install.InstallPath)) if (appData is null || string.IsNullOrWhiteSpace(appData.Install.InstallPath = appData.Install.InstallPath.ResolvePath()))
continue; continue;
Manifest manifest = new() Manifest manifest = new()
{ {

View file

@ -79,19 +79,19 @@ internal static class SteamLibrary
private static async Task<HashSet<string>> GetLibraryDirectories() private static async Task<HashSet<string>> GetLibraryDirectories()
=> await Task.Run(() => => await Task.Run(() =>
{ {
HashSet<string> gameDirectories = new(); HashSet<string> libraryDirectories = new();
if (Program.Canceled) if (Program.Canceled)
return gameDirectories; return libraryDirectories;
string steamInstallPath = InstallPath; string steamInstallPath = InstallPath;
if (steamInstallPath == null || !steamInstallPath.DirectoryExists()) if (steamInstallPath == null || !steamInstallPath.DirectoryExists())
return gameDirectories; return libraryDirectories;
string libraryFolder = steamInstallPath + @"\steamapps"; string libraryFolder = steamInstallPath + @"\steamapps";
if (!libraryFolder.DirectoryExists()) if (!libraryFolder.DirectoryExists())
return gameDirectories; return libraryDirectories;
_ = gameDirectories.Add(libraryFolder); _ = libraryDirectories.Add(libraryFolder);
string libraryFolders = libraryFolder + @"\libraryfolders.vdf"; string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
if (!libraryFolders.FileExists() || !ValveDataFile.TryDeserialize(libraryFolders.ReadFile(), out VProperty result)) if (!libraryFolders.FileExists() || !ValveDataFile.TryDeserialize(libraryFolders.ReadFile(), out VProperty result))
return gameDirectories; return libraryDirectories;
foreach (VToken vToken in result.Value.Where(p => p is VProperty property && int.TryParse(property.Key, out int _))) foreach (VToken vToken in result.Value.Where(p => p is VProperty property && int.TryParse(property.Key, out int _)))
{ {
VProperty property = (VProperty)vToken; VProperty property = (VProperty)vToken;
@ -100,8 +100,8 @@ internal static class SteamLibrary
continue; continue;
path += @"\steamapps"; path += @"\steamapps";
if (path.DirectoryExists()) if (path.DirectoryExists())
_ = gameDirectories.Add(path); _ = libraryDirectories.Add(path);
} }
return gameDirectories; return libraryDirectories;
}); });
} }

View file

@ -25,23 +25,36 @@ internal static class ScreamAPI
internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null) internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null)
{ {
directory.GetScreamApiComponents(out _, out _, out _, out _, out string config, out _); directory.GetScreamApiComponents(out _, out _, out _, out _, out string config, out _);
HashSet<SelectionDLC> overrideCatalogItems = selection.DLC.Where(dlc => dlc.Type is DLCType.EpicCatalogItem && !dlc.Enabled).ToHashSet(); HashSet<SelectionDLC> overrideCatalogItems = selection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !dlc.Enabled).ToHashSet();
HashSet<SelectionDLC> overrideEntitlements = selection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement && !dlc.Enabled).ToHashSet(); int entitlementCount = 0;
HashSet<SelectionDLC> injectedEntitlements = new();
foreach (SelectionDLC dlc in selection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement))
{
if (dlc.Enabled)
_ = injectedEntitlements.Add(dlc);
entitlementCount++;
}
foreach (Selection extraSelection in selection.ExtraSelections) foreach (Selection extraSelection in selection.ExtraSelections)
{ {
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicCatalogItem && !dlc.Enabled)) foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !dlc.Enabled))
_ = overrideCatalogItems.Add(extraDlc); _ = overrideCatalogItems.Add(extraDlc);
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement && !dlc.Enabled)) foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement))
_ = overrideEntitlements.Add(extraDlc); {
if (extraDlc.Enabled)
_ = injectedEntitlements.Add(extraDlc);
entitlementCount++;
}
} }
if (overrideCatalogItems.Count > 0 || overrideEntitlements.Count > 0) if (injectedEntitlements.Count == entitlementCount)
injectedEntitlements.Clear();
if (overrideCatalogItems.Count > 0 || injectedEntitlements.Count > 0)
{ {
/*if (installForm is not null) /*if (installForm is not null)
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/ installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
config.CreateFile(true, installForm).Close(); config.CreateFile(true, installForm).Close();
StreamWriter writer = new(config, true, Encoding.UTF8); StreamWriter writer = new(config, true, Encoding.UTF8);
WriteConfig(writer, new(overrideCatalogItems.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), WriteConfig(writer, new(overrideCatalogItems.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
new(overrideEntitlements.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm); new(injectedEntitlements.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
writer.Flush(); writer.Flush();
writer.Close(); writer.Close();
} }
@ -52,8 +65,8 @@ internal static class ScreamAPI
} }
} }
private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> overrideCatalogItems, SortedList<string, SelectionDLC> entitlements, private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> overrideCatalogItems,
InstallForm installForm = null) SortedList<string, SelectionDLC> injectedEntitlements, InstallForm installForm = null)
{ {
writer.WriteLine("{"); writer.WriteLine("{");
writer.WriteLine(" \"version\": 2,"); writer.WriteLine(" \"version\": 2,");
@ -79,23 +92,27 @@ internal static class ScreamAPI
writer.WriteLine(" \"override\": []"); writer.WriteLine(" \"override\": []");
writer.WriteLine(" },"); writer.WriteLine(" },");
writer.WriteLine(" \"entitlements\": {"); writer.WriteLine(" \"entitlements\": {");
writer.WriteLine(" \"unlock_all\": true,"); if (injectedEntitlements.Count > 0)
writer.WriteLine(" \"auto_inject\": true,");
if (entitlements.Count > 0)
{ {
writer.WriteLine(" \"unlock_all\": false,");
writer.WriteLine(" \"auto_inject\": false,");
writer.WriteLine(" \"inject\": ["); writer.WriteLine(" \"inject\": [");
KeyValuePair<string, SelectionDLC> lastEntitlement = entitlements.Last(); KeyValuePair<string, SelectionDLC> lastEntitlement = injectedEntitlements.Last();
foreach (KeyValuePair<string, SelectionDLC> pair in entitlements) foreach (KeyValuePair<string, SelectionDLC> pair in injectedEntitlements)
{ {
SelectionDLC selectionDlc = pair.Value; SelectionDLC selectionDlc = pair.Value;
writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}"); writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}");
installForm?.UpdateUser($"Added locked entitlement to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action, installForm?.UpdateUser($"Added injected entitlement to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
false); false);
} }
writer.WriteLine(" ]"); writer.WriteLine(" ]");
} }
else else
{
writer.WriteLine(" \"unlock_all\": true,");
writer.WriteLine(" \"auto_inject\": true,");
writer.WriteLine(" \"inject\": []"); writer.WriteLine(" \"inject\": []");
}
writer.WriteLine(" }"); writer.WriteLine(" }");
writer.WriteLine("}"); writer.WriteLine("}");
} }

View file

@ -8,7 +8,7 @@ namespace CreamInstaller;
public enum DLCType public enum DLCType
{ {
None = 0, Steam, SteamHidden, None = 0, Steam, SteamHidden,
EpicCatalogItem, EpicEntitlement Epic, EpicEntitlement
} }
internal sealed class SelectionDLC : IEquatable<SelectionDLC> internal sealed class SelectionDLC : IEquatable<SelectionDLC>