- 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>
<UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
<Version>4.9.7</Version>
<Version>4.9.8</Version>
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
<Company>CreamInstaller</Company>
<Product>Automatic DLC Unlocker Installer &amp; Configuration Generator</Product>

View file

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

View file

@ -39,7 +39,8 @@ internal static class EpicLibrary
try
{
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);
}
catch

View file

@ -12,22 +12,15 @@ namespace CreamInstaller.Platforms.Epic;
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 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)
internal static async Task<List<(string id, string name, string product, string icon, string developer)>> QueryCatalog(string categoryNamespace)
{
List<(string id, string name, string product, string icon, string developer)> dlcIds = new();
string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json";
bool cachedExists = cacheFile.FileExists();
Response response = null;
if (!cachedExists || ProgramData.CheckCooldown(categoryNamespace, CooldownEntitlement))
if (!cachedExists || ProgramData.CheckCooldown(categoryNamespace, Cooldown))
{
response = await QueryGraphQL(categoryNamespace);
try

View file

@ -28,7 +28,7 @@ internal static class HeroicLibrary
try
{
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;
Manifest manifest = new()
{

View file

@ -79,19 +79,19 @@ internal static class SteamLibrary
private static async Task<HashSet<string>> GetLibraryDirectories()
=> await Task.Run(() =>
{
HashSet<string> gameDirectories = new();
HashSet<string> libraryDirectories = new();
if (Program.Canceled)
return gameDirectories;
return libraryDirectories;
string steamInstallPath = InstallPath;
if (steamInstallPath == null || !steamInstallPath.DirectoryExists())
return gameDirectories;
return libraryDirectories;
string libraryFolder = steamInstallPath + @"\steamapps";
if (!libraryFolder.DirectoryExists())
return gameDirectories;
_ = gameDirectories.Add(libraryFolder);
return libraryDirectories;
_ = libraryDirectories.Add(libraryFolder);
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
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 _)))
{
VProperty property = (VProperty)vToken;
@ -100,8 +100,8 @@ internal static class SteamLibrary
continue;
path += @"\steamapps";
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)
{
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> overrideEntitlements = selection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement && !dlc.Enabled).ToHashSet();
HashSet<SelectionDLC> overrideCatalogItems = selection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !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 (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);
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement && !dlc.Enabled))
_ = overrideEntitlements.Add(extraDlc);
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement))
{
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)
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
config.CreateFile(true, installForm).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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.Close();
}
@ -52,8 +65,8 @@ internal static class ScreamAPI
}
}
private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> overrideCatalogItems, SortedList<string, SelectionDLC> entitlements,
InstallForm installForm = null)
private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> overrideCatalogItems,
SortedList<string, SelectionDLC> injectedEntitlements, InstallForm installForm = null)
{
writer.WriteLine("{");
writer.WriteLine(" \"version\": 2,");
@ -79,23 +92,27 @@ internal static class ScreamAPI
writer.WriteLine(" \"override\": []");
writer.WriteLine(" },");
writer.WriteLine(" \"entitlements\": {");
writer.WriteLine(" \"unlock_all\": true,");
writer.WriteLine(" \"auto_inject\": true,");
if (entitlements.Count > 0)
if (injectedEntitlements.Count > 0)
{
writer.WriteLine(" \"unlock_all\": false,");
writer.WriteLine(" \"auto_inject\": false,");
writer.WriteLine(" \"inject\": [");
KeyValuePair<string, SelectionDLC> lastEntitlement = entitlements.Last();
foreach (KeyValuePair<string, SelectionDLC> pair in entitlements)
KeyValuePair<string, SelectionDLC> lastEntitlement = injectedEntitlements.Last();
foreach (KeyValuePair<string, SelectionDLC> pair in injectedEntitlements)
{
SelectionDLC selectionDlc = pair.Value;
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);
}
writer.WriteLine(" ]");
}
else
{
writer.WriteLine(" \"unlock_all\": true,");
writer.WriteLine(" \"auto_inject\": true,");
writer.WriteLine(" \"inject\": []");
}
writer.WriteLine(" }");
writer.WriteLine("}");
}

View file

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