- Implemented Paradox Launcher support for Epic games
- Minor refactoring
This commit is contained in:
pointfeev 2022-03-29 16:50:56 -04:00
parent 124dea6fc2
commit 90dc9853fa
4 changed files with 86 additions and 71 deletions

View file

@ -5,7 +5,7 @@
<UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<Version>3.4.1.1</Version>
<Version>3.4.2.0</Version>
<PackageIcon>Resources\ini.ico</PackageIcon>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>

View file

@ -4,6 +4,7 @@ using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -51,11 +52,13 @@ internal partial class InstallForm : CustomForm
if (logTextBox.Text.Length > 0) logTextBox.AppendText(Environment.NewLine, color);
logTextBox.AppendText(text, color);
});
Thread.Sleep(0);
}
}
internal static void WriteCreamConfiguration(StreamWriter writer, string appId, string name, SortedList<string, (DlcType type, string name, string icon)> dlc, InstallForm installForm = null)
{
Thread.Sleep(0);
writer.WriteLine($"; {name}");
writer.WriteLine("[steam]");
writer.WriteLine($"appid = {appId}");
@ -65,6 +68,7 @@ internal partial class InstallForm : CustomForm
installForm.UpdateUser($"Added game to cream_api.ini with appid {appId} ({name})", InstallationLog.Action, info: false);
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in dlc)
{
Thread.Sleep(0);
string dlcId = pair.Key;
(_, string dlcName, _) = pair.Value;
writer.WriteLine($"{dlcId} = {dlcName}");
@ -141,21 +145,24 @@ internal partial class InstallForm : CustomForm
StreamWriter writer = new(config, true, Encoding.UTF8);
if (selection.Id != "ParadoxLauncher")
WriteCreamConfiguration(writer, selection.Id, selection.Name, selection.SelectedDlc, installForm);
foreach (Tuple<string, string, SortedList<string, (DlcType type, string name, string icon)>> extraAppDlc in selection.ExtraDlc)
WriteCreamConfiguration(writer, extraAppDlc.Item1, extraAppDlc.Item2, extraAppDlc.Item3, installForm);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> dlc) in selection.ExtraDlc)
WriteCreamConfiguration(writer, id, name, dlc, installForm);
writer.Flush();
writer.Close();
});
internal static void WriteScreamConfiguration(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> dlc, InstallForm installForm = null)
internal static void WriteScreamConfiguration(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> dlc, List<(string id, string name, SortedList<string, (DlcType type, string name, string icon)> dlc)> extraDlc, InstallForm installForm = null)
{
Thread.Sleep(0);
writer.WriteLine("{");
writer.WriteLine(" \"version\": 2,");
writer.WriteLine(" \"logging\": false,");
writer.WriteLine(" \"eos_logging\": false,");
writer.WriteLine(" \"block_metrics\": false,");
writer.WriteLine(" \"catalog_items\": {");
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> catalogItems = dlc.Where(pair => pair.Value.type == DlcType.CatalogItem);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> catalogItems = dlc.Where(pair => pair.Value.type == DlcType.EpicCatalogItem);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> _dlc) in extraDlc)
catalogItems = catalogItems.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicCatalogItem));
if (catalogItems.Any())
{
writer.WriteLine(" \"unlock_all\": false,");
@ -163,6 +170,7 @@ internal partial class InstallForm : CustomForm
KeyValuePair<string, (DlcType type, string name, string icon)> lastCatalogItem = catalogItems.Last();
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in catalogItems)
{
Thread.Sleep(0);
string id = pair.Key;
(_, string name, _) = pair.Value;
writer.WriteLine($" \"{id}\"{(pair.Equals(lastCatalogItem) ? "" : ",")}");
@ -178,7 +186,9 @@ internal partial class InstallForm : CustomForm
}
writer.WriteLine(" },");
writer.WriteLine(" \"entitlements\": {");
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> entitlements = dlc.Where(pair => pair.Value.type == DlcType.Entitlement);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> entitlements = dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> _dlc) in extraDlc)
entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement));
if (entitlements.Any())
{
writer.WriteLine(" \"unlock_all\": false,");
@ -187,6 +197,7 @@ internal partial class InstallForm : CustomForm
KeyValuePair<string, (DlcType type, string name, string icon)> lastEntitlement = entitlements.Last();
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in entitlements)
{
Thread.Sleep(0);
string id = pair.Key;
(_, string name, _) = pair.Value;
writer.WriteLine($" \"{id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}");
@ -271,10 +282,7 @@ internal partial class InstallForm : CustomForm
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
if (selection.Id != "ParadoxLauncher")
WriteScreamConfiguration(writer, selection.SelectedDlc, installForm);
foreach (Tuple<string, string, SortedList<string, (DlcType type, string name, string icon)>> extraAppDlc in selection.ExtraDlc)
WriteScreamConfiguration(writer, extraAppDlc.Item3, installForm);
WriteScreamConfiguration(writer, selection.SelectedDlc, selection.ExtraDlc, installForm);
writer.Flush();
writer.Close();
});
@ -306,27 +314,36 @@ internal partial class InstallForm : CustomForm
}
}
if (code < 0) throw new CustomMessageException("Repair failed!");
string platform = selection.Platform == Platform.Steam ? "CreamAPI"
: selection.Platform == Platform.Epic ? "ScreamAPI"
: throw new InvalidPlatformException(selection.Platform);
foreach (string directory in selection.DllDirectories)
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} {platform}" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Program.Canceled || !Program.IsProgramRunningDialog(this, selection)) throw new CustomMessageException("The operation was canceled.");
if (platform == "CreamAPI")
Thread.Sleep(0);
if (selection.IsSteam && selection.SelectedDlc.Any(d => d.Value.type is DlcType.Steam)
|| selection.ExtraDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.Steam)))
{
if (Uninstalling)
await UninstallCreamAPI(directory, this);
else
await InstallCreamAPI(directory, selection, this);
directory.GetCreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config);
if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config))
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} CreamAPI" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Uninstalling)
await UninstallCreamAPI(directory, this);
else
await InstallCreamAPI(directory, selection, this);
}
}
else if (platform == "ScreamAPI")
if (selection.IsEpic && selection.SelectedDlc.Any(d => d.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement)
|| selection.ExtraDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement)))
{
if (Uninstalling)
await UninstallScreamAPI(directory, this);
else
await InstallScreamAPI(directory, selection, this);
directory.GetScreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config);
if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config))
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} ScreamAPI" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Uninstalling)
await UninstallScreamAPI(directory, this);
else
await InstallScreamAPI(directory, selection, this);
}
}
UpdateProgress(++cur / count * 100);
}
@ -342,6 +359,7 @@ internal partial class InstallForm : CustomForm
foreach (ProgramSelection selection in programSelections)
{
if (Program.Canceled || !Program.IsProgramRunningDialog(this, selection)) throw new CustomMessageException("The operation was canceled.");
Thread.Sleep(0);
try
{
await OperateFor(selection);

View file

@ -103,9 +103,7 @@ internal partial class SelectForm : CustomForm
if (Directory.Exists(ParadoxLauncher.InstallPath) && ProgramsToScan.Any(c => c.platform == "Paradox" && c.id == "ParadoxLauncher"))
{
List<string> steamDllDirectories = await SteamLibrary.GetDllDirectoriesFromGameDirectory(ParadoxLauncher.InstallPath);
List<string> epicDllDirectories = null;
if (steamDllDirectories is null)
epicDllDirectories = await EpicLibrary.GetDllDirectoriesFromGameDirectory(ParadoxLauncher.InstallPath);
List<string> epicDllDirectories = await EpicLibrary.GetDllDirectoriesFromGameDirectory(ParadoxLauncher.InstallPath);
if (steamDllDirectories is not null || epicDllDirectories is not null)
{
ProgramSelection selection = ProgramSelection.FromId("ParadoxLauncher");
@ -115,7 +113,8 @@ internal partial class SelectForm : CustomForm
selection.Name = "Paradox Launcher";
selection.RootDirectory = ParadoxLauncher.InstallPath;
selection.DllDirectories = steamDllDirectories ?? epicDllDirectories;
selection.Platform = steamDllDirectories is not null ? Platform.Steam : Platform.Epic;
selection.IsSteam = steamDllDirectories is not null;
selection.IsEpic = epicDllDirectories is not null;
TreeNode programNode = treeNodes.Find(s => s.Name == selection.Id) ?? new();
programNode.Name = selection.Id;
@ -196,7 +195,7 @@ internal partial class SelectForm : CustomForm
}
if (Program.Canceled) return;
if (!string.IsNullOrWhiteSpace(dlcName))
dlc[dlcAppId] = (DlcType.Default, dlcName, dlcIcon);
dlc[dlcAppId] = (DlcType.Steam, dlcName, dlcIcon);
RemoveFromRemainingDLCs(dlcAppId);
});
dlcTasks.Add(task);
@ -217,11 +216,11 @@ internal partial class SelectForm : CustomForm
ProgramSelection selection = ProgramSelection.FromId(appId) ?? new();
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraDlc.Any();
selection.Platform = Platform.Steam;
selection.Id = appId;
selection.Name = appData?.name ?? name;
selection.RootDirectory = directory;
selection.DllDirectories = dllDirectories;
selection.IsSteam = true;
selection.ProductUrl = "https://store.steampowered.com/app/" + appId;
selection.IconUrl = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("icon")?.ToString()}.jpg";
selection.SubIconUrl = appData?.header_image ?? IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("clienticon")?.ToString()}.ico";
@ -318,11 +317,11 @@ internal partial class SelectForm : CustomForm
ProgramSelection selection = ProgramSelection.FromId(@namespace) ?? new();
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraDlc.Any();
selection.Platform = Platform.Epic;
selection.Id = @namespace;
selection.Name = name;
selection.RootDirectory = directory;
selection.DllDirectories = dllDirectories;
selection.IsEpic = true;
foreach (KeyValuePair<string, (string name, string product, string icon, string developer)> pair in entitlements)
{
Thread.Sleep(0);
@ -364,7 +363,7 @@ internal partial class SelectForm : CustomForm
if (programNode is null/* || entitlementsNode is null*/) return;
Thread.Sleep(0);
string dlcId = pair.Key;
(DlcType type, string name, string icon) dlcApp = (DlcType.Entitlement, pair.Value.name, pair.Value.icon);
(DlcType type, string name, string icon) dlcApp = (DlcType.EpicEntitlement, pair.Value.name, pair.Value.icon);
selection.AllDlc[dlcId] = dlcApp;
if (allCheckBox.Checked) selection.SelectedDlc[dlcId] = dlcApp;
TreeNode dlcNode = treeNodes.Find(s => s.Name == dlcId) ?? new();
@ -614,10 +613,8 @@ internal partial class SelectForm : CustomForm
List<ContextMenuItem> queries = new();
if (File.Exists(appInfoJSON))
{
string platform = (selection is null || selection.Platform == Platform.Steam) ? "Steam Store"
: selection.Platform == Platform.Epic ? "Epic GraphQL"
: throw new InvalidPlatformException(selection.Platform);
queries.Add(new ContextMenuItem($"Open {platform} Query", "Notepad",
string platform = (selection is null || selection.IsSteam) ? "Steam Store " : selection.IsEpic ? "Epic GraphQL " : "";
queries.Add(new ContextMenuItem($"Open {platform}Query", "Notepad",
new EventHandler((sender, e) => Diagnostics.OpenFileInNotepad(appInfoJSON))));
}
if (File.Exists(appInfoVDF))
@ -662,20 +659,32 @@ internal partial class SelectForm : CustomForm
contextMenuStrip.Items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory))));
List<string> directories = selection.DllDirectories.ToList();
string platform = selection.Platform == Platform.Steam ? "Steamworks"
: selection.Platform == Platform.Epic ? "Epic Online Services"
: throw new InvalidPlatformException(selection.Platform);
for (int i = 0; i < directories.Count; i++)
{
string directory = directories[i];
contextMenuStrip.Items.Add(new ContextMenuItem($"Open {platform} SDK Directory #{i + 1}", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))));
}
if (selection.IsSteam)
for (int i = 0; i < directories.Count; i++)
{
string directory = directories[i];
directory.GetCreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config);
if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config))
{
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Steamworks SDK Directory #{i + 1}", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))));
}
}
if (selection.IsEpic)
for (int i = 0; i < directories.Count; i++)
{
string directory = directories[i];
directory.GetScreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config);
if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config))
{
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Epic Online Services SDK Directory #{i + 1}", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))));
}
}
}
if (id != "ParadoxLauncher")
{
if (selection is not null && selection.Platform == Platform.Steam
|| dlcParentSelection is not null && dlcParentSelection.Platform == Platform.Steam)
if (selection is not null && selection.IsSteam || dlcParentSelection is not null && dlcParentSelection.IsSteam)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open SteamDB", "SteamDB",
@ -683,14 +692,14 @@ internal partial class SelectForm : CustomForm
}
if (selection is not null)
{
if (selection.Platform == Platform.Steam)
if (selection.IsSteam)
{
contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))));
contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Community", (id, selection.SubIconUrl, true), "Steam Community",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id))));
}
else if (selection.Platform == Platform.Epic)
else if (selection.IsEpic)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -7,30 +6,16 @@ using CreamInstaller.Components;
namespace CreamInstaller;
public enum Platform
{
Steam = 0,
Epic = 1
}
public class InvalidPlatformException : Exception
{
public InvalidPlatformException() : base("Invalid platform!") { }
public InvalidPlatformException(Platform platform) : base($"Invalid platform ({platform})!") { }
public InvalidPlatformException(string message) : base(message) { }
public InvalidPlatformException(string message, Exception innerException) : base(message, innerException) { }
}
public enum DlcType
{
Default = 0,
CatalogItem = 1,
Entitlement = 2
Steam = 0,
EpicCatalogItem = 1,
EpicEntitlement = 2
}
internal class ProgramSelection
{
internal bool Enabled;
internal Platform Platform = (Platform)(-1);
internal string Id = "0";
internal string Name = "Program";
@ -44,9 +29,12 @@ internal class ProgramSelection
internal string RootDirectory;
internal List<string> DllDirectories;
internal bool IsSteam;
internal bool IsEpic;
internal readonly SortedList<string, (DlcType type, string name, string icon)> AllDlc = new(AppIdComparer.Comparer);
internal readonly SortedList<string, (DlcType type, string name, string icon)> SelectedDlc = new(AppIdComparer.Comparer);
internal readonly List<Tuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>> ExtraDlc = new(); // for Paradox Launcher
internal readonly List<(string id, string name, SortedList<string, (DlcType type, string name, string icon)> dlc)> ExtraDlc = new(); // for Paradox Launcher
internal bool AreDllsLocked
{