start of v4.9.0
- Large refactoring & optimization - Fixed & optimized right-click context menu - Fixed silent HTTP cache concurrency exception - Added a better SafeIO exception output for anti-virus detections - Updated the help button dialog
This commit is contained in:
parent
324b0606e5
commit
9318fd7768
23 changed files with 484 additions and 489 deletions
|
@ -51,14 +51,10 @@ internal class CustomForm : Form
|
|||
_ = helpDialog.Show(SystemIcons.Information,
|
||||
"Automatically finds all installed Steam, Epic and Ubisoft games with their respective DLC-related DLL locations on the user's computer,\n"
|
||||
+ "parses SteamCMD, Steam Store and Epic Games Store for user-selected games' DLCs, then provides a very simple graphical interface\n"
|
||||
+ "utilizing the gathered information for the maintenance of DLC unlockers.\n" + "\n"
|
||||
+ "utilizing the gathered information for the maintenance of DLC unlockers.\n\n"
|
||||
+ $"The program utilizes the latest versions of [Koaloader]({acidicoala}/Koaloader), [SmokeAPI]({acidicoala}/SmokeAPI), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1 Unlocker]({acidicoala}/UplayR1Unlocker) and [Uplay R2 Unlocker]({acidicoala}/UplayR2Unlocker), all by\n"
|
||||
+ $"the wonderful [acidicoala]({acidicoala}), and all downloaded and embedded into the program itself; no further downloads necessary on your part!\n"
|
||||
+ "\n" + "NOTE: This program does not automatically download nor install actual DLC files for you. As the title of the program says, it's\n"
|
||||
+ "only a DLC Unlocker installer. Should the game you wish to unlock DLC for not already come with the DLCs installed (very many\n"
|
||||
+ "do not), you have to find, download, and install those yourself. Preferably, you should be referring to the proper cs.rin.ru post for\n"
|
||||
+ "the game(s) you're tinkering with; you'll usually find any answer to your problems there.\n" + "\n" + "USAGE:\n"
|
||||
+ " 1. Choose which programs and/or games the program should scan for DLC.\n"
|
||||
+ $"the wonderful [acidicoala]({acidicoala}), and all downloaded and embedded into the program itself; no further downloads necessary on your part!\n\n"
|
||||
+ "USAGE:\n" + " 1. Choose which programs and/or games the program should scan for DLC.\n"
|
||||
+ " The program automatically gathers all installed games from Steam, Epic and Ubisoft directories.\n"
|
||||
+ " 2. Wait for the program to download and install SteamCMD (if you chose a Steam game).\n"
|
||||
+ " 3. Wait for the program to gather and cache the chosen games' information && DLCs.\n"
|
||||
|
@ -69,10 +65,17 @@ internal class CustomForm : Form
|
|||
+ " If the default \'version.dll\' doesn't work, then see [here](https://cs.rin.ru/forum/viewtopic.php?p=2552172#p2552172) to find one that does.\n"
|
||||
+ " 6. Click the \"Generate and Install\" button.\n" + " 7. Click the \"OK\" button to close the program.\n"
|
||||
+ " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\n"
|
||||
+ " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n" + "\n"
|
||||
+ $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n"
|
||||
+ "\n" + "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n"
|
||||
+ $"The program automatically and very quickly updates from [GitHub]({repository}) using [Onova](https://github.com/Tyrrrz/Onova). (updates can be ignored)\n"
|
||||
+ " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n\n"
|
||||
+ "NOTE: This program does not automatically download nor install actual DLC files for you; as the title of the program states, this program\n"
|
||||
+ "is only a DLC Unlocker installer. Should the game you wish to unlock DLC for not already come with the DLCs installed, as is the case with\n"
|
||||
+ "a good majority of games, you must find, download and install those to the game yourself. This process includes manually installing new\n"
|
||||
+ "DLCs and manually updating the previously manually installed DLCs after game updates.\n\n"
|
||||
+ $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n\n"
|
||||
+ $"HOWEVER: Please read the template issue corresponding to your problem should one exist! Also, note that the [GitHub Issues]({repository}/issues) page is not\n"
|
||||
+ "your personal assistance hotline, rather it is for genuine bugs/crashes/issues with the program itself. If you post an issue which has already\n"
|
||||
+ "been explained within the template issues and/or within this text, I will just close it.\n\n"
|
||||
+ "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n"
|
||||
+ $"The program automatically and very quickly updates from [GitHub]({repository}) by choice of the user through a dialog on startup.\n"
|
||||
+ $"The program source and other information can be found on [GitHub]({repository}).");
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ internal sealed class CustomTreeView : TreeView
|
|||
private static readonly Color C7 = ColorTranslator.FromHtml("#006900");
|
||||
private static readonly Color C8 = ColorTranslator.FromHtml("#69AA69");
|
||||
|
||||
private readonly Dictionary<ProgramSelection, Rectangle> checkBoxBounds = new();
|
||||
private readonly Dictionary<ProgramSelection, Rectangle> comboBoxBounds = new();
|
||||
private readonly Dictionary<Selection, Rectangle> checkBoxBounds = new();
|
||||
private readonly Dictionary<Selection, Rectangle> comboBoxBounds = new();
|
||||
|
||||
private readonly Dictionary<TreeNode, Rectangle> selectionBounds = new();
|
||||
private SolidBrush backBrush;
|
||||
|
@ -110,7 +110,7 @@ internal sealed class CustomTreeView : TreeView
|
|||
}
|
||||
if (form is SelectForm)
|
||||
{
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(platform, platformId);
|
||||
Selection selection = Selection.FromPlatformId(platform, platformId);
|
||||
if (selection is not null)
|
||||
{
|
||||
if (bounds == node.Bounds)
|
||||
|
@ -145,7 +145,7 @@ internal sealed class CustomTreeView : TreeView
|
|||
{
|
||||
comboBoxFont ??= new(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
|
||||
ComboBoxState comboBoxState = Enabled ? ComboBoxState.Normal : ComboBoxState.Disabled;
|
||||
text = (selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy) + ".dll";
|
||||
text = (selection.KoaloaderProxy ?? Selection.DefaultKoaloaderProxy) + ".dll";
|
||||
size = TextRenderer.MeasureText(graphics, text, comboBoxFont) + new Size(6, 0);
|
||||
const int padding = 2;
|
||||
bounds = new(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width, bounds.Height - padding);
|
||||
|
@ -186,9 +186,9 @@ internal sealed class CustomTreeView : TreeView
|
|||
}
|
||||
if (e.Button is not MouseButtons.Left)
|
||||
return;
|
||||
if (comboBoxBounds.Any() && selectForm is not null)
|
||||
foreach (KeyValuePair<ProgramSelection, Rectangle> pair in comboBoxBounds)
|
||||
if (!ProgramSelection.All.Contains(pair.Key))
|
||||
if (comboBoxBounds.Count > 0 && selectForm is not null)
|
||||
foreach (KeyValuePair<Selection, Rectangle> pair in comboBoxBounds)
|
||||
if (!Selection.All.Contains(pair.Key))
|
||||
_ = comboBoxBounds.Remove(pair.Key);
|
||||
else if (pair.Value.Contains(clickPoint))
|
||||
{
|
||||
|
@ -214,15 +214,15 @@ internal sealed class CustomTreeView : TreeView
|
|||
if (canUse)
|
||||
_ = comboBoxDropDown.Items.Add(new ToolStripButton(proxy + ".dll", null, (_, _) =>
|
||||
{
|
||||
pair.Key.KoaloaderProxy = proxy == ProgramSelection.DefaultKoaloaderProxy ? null : proxy;
|
||||
pair.Key.KoaloaderProxy = proxy == Selection.DefaultKoaloaderProxy ? null : proxy;
|
||||
selectForm.OnKoaloaderChanged();
|
||||
}) { Font = comboBoxFont });
|
||||
}
|
||||
comboBoxDropDown.Show(this, PointToScreen(new(pair.Value.Left, pair.Value.Bottom - 1)));
|
||||
break;
|
||||
}
|
||||
foreach (KeyValuePair<ProgramSelection, Rectangle> pair in checkBoxBounds)
|
||||
if (!ProgramSelection.All.Contains(pair.Key))
|
||||
foreach (KeyValuePair<Selection, Rectangle> pair in checkBoxBounds)
|
||||
if (!Selection.All.Contains(pair.Key))
|
||||
_ = checkBoxBounds.Remove(pair.Key);
|
||||
else if (pair.Value.Contains(clickPoint))
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
|
||||
<Version>4.8.1</Version>
|
||||
<Version>4.9.0</Version>
|
||||
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
|
||||
<Company>CreamInstaller</Company>
|
||||
<Product>Automatic DLC Unlocker Installer & Configuration Generator</Product>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using CreamInstaller.Components;
|
||||
|
||||
|
@ -52,14 +51,14 @@ internal sealed partial class DialogForm : CustomForm
|
|||
}
|
||||
if (customFormIcon is not null)
|
||||
Icon = customFormIcon;
|
||||
if (!links.Any())
|
||||
if (links.Count < 1)
|
||||
return ShowDialog();
|
||||
foreach (LinkLabel.Link link in links)
|
||||
_ = descriptionLabel.Links.Add(link);
|
||||
descriptionLabel.LinkClicked += (_, e) =>
|
||||
descriptionLabel.LinkClicked += (s, e) =>
|
||||
{
|
||||
if (e.Link != null)
|
||||
Process.Start(new ProcessStartInfo((string)e.Link.LinkData) { UseShellExecute = true });
|
||||
_ = Process.Start(new ProcessStartInfo((string)e.Link.LinkData) { UseShellExecute = true });
|
||||
};
|
||||
return ShowDialog();
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace CreamInstaller.Forms;
|
|||
|
||||
internal sealed partial class InstallForm : CustomForm
|
||||
{
|
||||
private readonly List<ProgramSelection> disabledSelections = new();
|
||||
private readonly List<Selection> disabledSelections = new();
|
||||
|
||||
private readonly int programCount = ProgramSelection.AllEnabled.Count;
|
||||
private readonly int programCount = Selection.AllEnabled.Count;
|
||||
private readonly bool uninstalling;
|
||||
private int completeOperationsCount;
|
||||
|
||||
|
@ -58,7 +58,7 @@ internal sealed partial class InstallForm : CustomForm
|
|||
});
|
||||
}
|
||||
|
||||
private async Task OperateFor(ProgramSelection selection)
|
||||
private async Task OperateFor(Selection selection)
|
||||
{
|
||||
UpdateProgress(0);
|
||||
if (selection.Id == "PL")
|
||||
|
@ -189,10 +189,10 @@ internal sealed partial class InstallForm : CustomForm
|
|||
|
||||
private async Task Operate()
|
||||
{
|
||||
List<ProgramSelection> programSelections = ProgramSelection.AllEnabled;
|
||||
List<Selection> programSelections = Selection.AllEnabled;
|
||||
operationsCount = programSelections.Count;
|
||||
completeOperationsCount = 0;
|
||||
foreach (ProgramSelection selection in programSelections)
|
||||
foreach (Selection selection in programSelections)
|
||||
{
|
||||
if (Program.Canceled || !Program.AreDllsLockedDialog(this, selection))
|
||||
throw new CustomMessageException("The operation was canceled.");
|
||||
|
@ -210,13 +210,13 @@ internal sealed partial class InstallForm : CustomForm
|
|||
++completeOperationsCount;
|
||||
}
|
||||
Program.Cleanup();
|
||||
List<ProgramSelection> failedSelections = ProgramSelection.AllEnabled;
|
||||
if (failedSelections.Any())
|
||||
List<Selection> failedSelections = Selection.AllEnabled;
|
||||
if (failedSelections.Count > 0)
|
||||
if (failedSelections.Count == 1)
|
||||
throw new CustomMessageException($"Operation failed for {failedSelections.First().Name}.");
|
||||
else
|
||||
throw new CustomMessageException($"Operation failed for {failedSelections.Count} programs.");
|
||||
foreach (ProgramSelection selection in disabledSelections)
|
||||
foreach (Selection selection in disabledSelections)
|
||||
selection.Enabled = true;
|
||||
disabledSelections.Clear();
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ internal sealed partial class InstallForm : CustomForm
|
|||
{
|
||||
Program.Cleanup();
|
||||
Reselecting = true;
|
||||
foreach (ProgramSelection selection in disabledSelections)
|
||||
foreach (Selection selection in disabledSelections)
|
||||
selection.Enabled = true;
|
||||
disabledSelections.Clear();
|
||||
Close();
|
||||
|
|
|
@ -16,7 +16,7 @@ internal sealed partial class SelectDialogForm : CustomForm
|
|||
out List<(Platform platform, string id, string name)> choices)
|
||||
{
|
||||
choices = null;
|
||||
if (!potentialChoices.Any())
|
||||
if (potentialChoices.Count < 1)
|
||||
return DialogResult.Cancel;
|
||||
groupBox.Text = groupBoxText;
|
||||
allCheckBox.Enabled = false;
|
||||
|
@ -28,13 +28,13 @@ internal sealed partial class SelectDialogForm : CustomForm
|
|||
OnTreeNodeChecked(node);
|
||||
_ = selectionTreeView.Nodes.Add(node);
|
||||
}
|
||||
if (!selected.Any())
|
||||
if (selected.Count < 1)
|
||||
OnLoad(null, null);
|
||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||
allCheckBox.Checked = selectionTreeView.Nodes.Cast<TreeNode>().All(n => n.Checked);
|
||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||
allCheckBox.Enabled = true;
|
||||
acceptButton.Enabled = selected.Any();
|
||||
acceptButton.Enabled = selected.Count > 0;
|
||||
saveButton.Enabled = acceptButton.Enabled;
|
||||
loadButton.Enabled = ProgramData.ReadProgramChoices() is not null;
|
||||
OnResize(null, null);
|
||||
|
@ -46,7 +46,7 @@ internal sealed partial class SelectDialogForm : CustomForm
|
|||
private void OnTreeNodeChecked(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
OnTreeNodeChecked(e.Node);
|
||||
acceptButton.Enabled = selected.Any();
|
||||
acceptButton.Enabled = selected.Count > 0;
|
||||
saveButton.Enabled = acceptButton.Enabled;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ internal sealed partial class SelectDialogForm : CustomForm
|
|||
private void OnLoad(object sender, EventArgs e)
|
||||
{
|
||||
List<(Platform platform, string id)> choices = ProgramData.ReadProgramChoices().ToList();
|
||||
if (!choices.Any())
|
||||
if (choices.Count < 1)
|
||||
return;
|
||||
foreach (TreeNode node in selectionTreeView.Nodes)
|
||||
{
|
||||
|
|
|
@ -23,9 +23,9 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
private const string HelpButtonListPrefix = "\n • ";
|
||||
|
||||
private readonly SynchronizedCollection<string> remainingDLCs = new();
|
||||
private readonly ConcurrentDictionary<string, string> remainingDLCs = new();
|
||||
|
||||
private readonly SynchronizedCollection<string> remainingGames = new();
|
||||
private readonly ConcurrentDictionary<string, string> remainingGames = new();
|
||||
|
||||
private List<(Platform platform, string id, string name)> programsToScan;
|
||||
|
||||
|
@ -39,8 +39,8 @@ internal sealed partial class SelectForm : CustomForm
|
|||
|
||||
private List<TreeNode> TreeNodes => GatherTreeNodes(selectionTreeView.Nodes);
|
||||
|
||||
private static void UpdateRemaining(Label label, SynchronizedCollection<string> list, string descriptor)
|
||||
=> label.Text = list.Any() ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") : "";
|
||||
private static void UpdateRemaining(Label label, ConcurrentDictionary<string, string> list, string descriptor)
|
||||
=> label.Text = list.IsEmpty ? "" : $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list.Values).Replace("&", "&&");
|
||||
|
||||
private void UpdateRemainingGames() => UpdateRemaining(progressLabelGames, remainingGames, "games");
|
||||
|
||||
|
@ -52,8 +52,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
if (!remainingGames.Contains(gameName))
|
||||
remainingGames.Add(gameName);
|
||||
remainingGames[gameName] = gameName;
|
||||
UpdateRemainingGames();
|
||||
});
|
||||
}
|
||||
|
@ -66,7 +65,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
remainingGames.Remove(gameName);
|
||||
_ = remainingGames.Remove(gameName, out _);
|
||||
UpdateRemainingGames();
|
||||
});
|
||||
}
|
||||
|
@ -81,8 +80,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
if (!remainingDLCs.Contains(dlcId))
|
||||
remainingDLCs.Add(dlcId);
|
||||
remainingDLCs[dlcId] = dlcId;
|
||||
UpdateRemainingDLCs();
|
||||
});
|
||||
}
|
||||
|
@ -95,14 +93,14 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
remainingDLCs.Remove(dlcId);
|
||||
_ = remainingDLCs.Remove(dlcId, out _);
|
||||
UpdateRemainingDLCs();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task GetApplicablePrograms(IProgress<int> progress, bool uninstallAll = false)
|
||||
{
|
||||
if (!uninstallAll && (programsToScan is null || !programsToScan.Any()))
|
||||
if (!uninstallAll && (programsToScan is null || programsToScan.Count < 1))
|
||||
return;
|
||||
int totalGameCount = 0;
|
||||
int completeGameCount = 0;
|
||||
|
@ -126,12 +124,12 @@ internal sealed partial class SelectForm : CustomForm
|
|||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Paradox))
|
||||
{
|
||||
AddToRemainingGames("Paradox Launcher");
|
||||
List<string> dllDirectories = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox);
|
||||
HashSet<string> dllDirectories = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox);
|
||||
if (dllDirectories is not null)
|
||||
{
|
||||
if (uninstallAll)
|
||||
{
|
||||
ProgramSelection bareSelection = ProgramSelection.FromPlatformId(Platform.Paradox, "PL") ?? new();
|
||||
Selection bareSelection = Selection.FromPlatformId(Platform.Paradox, "PL") ?? new();
|
||||
bareSelection.Enabled = true;
|
||||
bareSelection.Id = "PL";
|
||||
bareSelection.Name = "Paradox Launcher";
|
||||
|
@ -142,7 +140,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
else
|
||||
{
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Paradox, "PL") ?? new();
|
||||
Selection selection = Selection.FromPlatformId(Platform.Paradox, "PL") ?? new();
|
||||
if (allCheckBox.Checked)
|
||||
selection.Enabled = true;
|
||||
if (koaloaderAllCheckBox.Checked)
|
||||
|
@ -167,7 +165,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
int steamGamesToCheck;
|
||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Steam))
|
||||
{
|
||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> steamGames = await SteamLibrary.GetGames();
|
||||
HashSet<(string appId, string name, string branch, int buildId, string gameDirectory)> steamGames = await SteamLibrary.GetGames();
|
||||
steamGamesToCheck = steamGames.Count;
|
||||
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in steamGames)
|
||||
{
|
||||
|
@ -175,7 +173,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
return;
|
||||
if (!uninstallAll && (Program.IsGameBlocked(name, gameDirectory) || !programsToScan.Any(c => c.platform is Platform.Steam && c.id == appId)))
|
||||
{
|
||||
Interlocked.Decrement(ref steamGamesToCheck);
|
||||
_ = Interlocked.Decrement(ref steamGamesToCheck);
|
||||
continue;
|
||||
}
|
||||
AddToRemainingGames(name);
|
||||
|
@ -183,16 +181,16 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
List<string> dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam);
|
||||
HashSet<string> dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam);
|
||||
if (dllDirectories is null)
|
||||
{
|
||||
Interlocked.Decrement(ref steamGamesToCheck);
|
||||
_ = Interlocked.Decrement(ref steamGamesToCheck);
|
||||
RemoveFromRemainingGames(name);
|
||||
return;
|
||||
}
|
||||
if (uninstallAll)
|
||||
{
|
||||
ProgramSelection bareSelection = ProgramSelection.FromPlatformId(Platform.Steam, appId) ?? new ProgramSelection();
|
||||
Selection bareSelection = Selection.FromPlatformId(Platform.Steam, appId) ?? new Selection();
|
||||
bareSelection.Enabled = true;
|
||||
bareSelection.Id = appId;
|
||||
bareSelection.Name = name;
|
||||
|
@ -206,7 +204,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
if (Program.Canceled)
|
||||
return;
|
||||
AppData appData = await SteamStore.QueryStoreAPI(appId);
|
||||
Interlocked.Decrement(ref steamGamesToCheck);
|
||||
_ = Interlocked.Decrement(ref steamGamesToCheck);
|
||||
VProperty appInfo = await SteamCMD.GetAppInfo(appId, branch, buildId);
|
||||
if (appData is null && appInfo is null)
|
||||
{
|
||||
|
@ -215,7 +213,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
ConcurrentDictionary<string, (DlcType type, string name, string icon)> dlc = new();
|
||||
ConcurrentDictionary<string, SelectionDLC> dlc = new();
|
||||
List<Task> dlcTasks = new();
|
||||
List<string> dlcIds = new();
|
||||
if (appData is not null)
|
||||
|
@ -292,13 +290,20 @@ internal sealed partial class SelectForm : CustomForm
|
|||
if (Program.Canceled)
|
||||
return;
|
||||
if (!string.IsNullOrWhiteSpace(fullGameName))
|
||||
dlc[fullGameAppId] = (fullGameOnSteamStore ? DlcType.Steam : DlcType.SteamHidden, fullGameName, fullGameIcon);
|
||||
dlc[fullGameAppId] = new()
|
||||
{
|
||||
Id = fullGameAppId, Type = fullGameOnSteamStore ? DLCType.Steam : DLCType.SteamHidden, Name = fullGameName,
|
||||
Icon = fullGameIcon
|
||||
};
|
||||
}
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
if (string.IsNullOrWhiteSpace(dlcName))
|
||||
dlcName = "Unknown";
|
||||
dlc[dlcAppId] = (onSteamStore ? DlcType.Steam : DlcType.SteamHidden, dlcName, dlcIcon);
|
||||
dlc[dlcAppId] = new()
|
||||
{
|
||||
Id = dlcAppId, Type = onSteamStore ? DLCType.Steam : DLCType.SteamHidden, Name = dlcName, Icon = dlcIcon
|
||||
};
|
||||
RemoveFromRemainingDLCs(dlcAppId);
|
||||
});
|
||||
dlcTasks.Add(task);
|
||||
|
@ -317,8 +322,14 @@ internal sealed partial class SelectForm : CustomForm
|
|||
await task;
|
||||
}
|
||||
steamGamesToCheck = 0;
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Steam, appId) ?? new ProgramSelection();
|
||||
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any();
|
||||
if (dlc.IsEmpty)
|
||||
{
|
||||
RemoveFromRemainingGames(name);
|
||||
return;
|
||||
}
|
||||
Selection selection = Selection.FromPlatformId(Platform.Steam, appId) ?? new Selection();
|
||||
selection.Enabled = allCheckBox.Checked || selection.DLC.Any(dlc => dlc.Enabled)
|
||||
|| selection.ExtraSelections.Any(extraSelection => extraSelection.DLC.Any(dlc => dlc.Enabled));
|
||||
if (koaloaderAllCheckBox.Checked)
|
||||
selection.Koaloader = true;
|
||||
selection.Id = appId;
|
||||
|
@ -327,12 +338,12 @@ internal sealed partial class SelectForm : CustomForm
|
|||
selection.ExecutableDirectories = await SteamLibrary.GetExecutableDirectories(selection.RootDirectory);
|
||||
selection.DllDirectories = dllDirectories;
|
||||
selection.Platform = Platform.Steam;
|
||||
selection.ProductUrl = "https://store.steampowered.com/app/" + appId;
|
||||
selection.IconUrl = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("icon")}.jpg";
|
||||
selection.SubIconUrl = appData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
|
||||
selection.Product = "https://store.steampowered.com/app/" + appId;
|
||||
selection.Icon = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("icon")}.jpg";
|
||||
selection.SubIcon = appData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
|
||||
+ @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("clienticon")}.ico";
|
||||
selection.Publisher = appData?.Publishers[0] ?? appInfo?.Value.GetChild("extended")?.GetChild("publisher")?.ToString();
|
||||
selection.WebsiteUrl = appData?.Website;
|
||||
selection.Website = appData?.Website;
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
selectionTreeView.Invoke(delegate
|
||||
|
@ -346,18 +357,17 @@ internal sealed partial class SelectForm : CustomForm
|
|||
programNode.Checked = selection.Enabled;
|
||||
if (programNode.TreeView is null)
|
||||
_ = selectionTreeView.Nodes.Add(programNode);
|
||||
foreach ((string appId, (DlcType type, string name, string icon) dlcApp) in dlc)
|
||||
foreach ((_, SelectionDLC dlc) in dlc)
|
||||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
selection.AllDlc[appId] = dlcApp;
|
||||
if (allCheckBox.Checked && dlcApp.name != "Unknown")
|
||||
selection.SelectedDlc[appId] = dlcApp;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == appId) ?? new TreeNode();
|
||||
dlc.Selection = selection;
|
||||
dlc.Enabled = dlc.Name != "Unknown" && allCheckBox.Checked;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == dlc.Id) ?? new TreeNode();
|
||||
dlcNode.Tag = selection.Platform;
|
||||
dlcNode.Name = appId;
|
||||
dlcNode.Text = dlcApp.name;
|
||||
dlcNode.Checked = selection.SelectedDlc.ContainsKey(appId);
|
||||
dlcNode.Name = dlc.Id;
|
||||
dlcNode.Text = dlc.Name;
|
||||
dlcNode.Checked = dlc.Enabled;
|
||||
if (dlcNode.Parent is null)
|
||||
_ = programNode.Nodes.Add(dlcNode);
|
||||
}
|
||||
|
@ -371,7 +381,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Epic))
|
||||
{
|
||||
List<Manifest> epicGames = await EpicLibrary.GetGames();
|
||||
HashSet<Manifest> epicGames = await EpicLibrary.GetGames();
|
||||
foreach (Manifest manifest in epicGames)
|
||||
{
|
||||
string @namespace = manifest.CatalogNamespace;
|
||||
|
@ -386,7 +396,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
List<string> dllDirectories = await directory.GetDllDirectoriesFromGameDirectory(Platform.Epic);
|
||||
HashSet<string> dllDirectories = await directory.GetDllDirectoriesFromGameDirectory(Platform.Epic);
|
||||
if (dllDirectories is null)
|
||||
{
|
||||
RemoveFromRemainingGames(name);
|
||||
|
@ -394,7 +404,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (uninstallAll)
|
||||
{
|
||||
ProgramSelection bareSelection = ProgramSelection.FromPlatformId(Platform.Epic, @namespace) ?? new ProgramSelection();
|
||||
Selection bareSelection = Selection.FromPlatformId(Platform.Epic, @namespace) ?? new Selection();
|
||||
bareSelection.Enabled = true;
|
||||
bareSelection.Id = @namespace;
|
||||
bareSelection.Name = name;
|
||||
|
@ -407,11 +417,13 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
ConcurrentDictionary<string, (string name, string product, string icon, string developer)> entitlements = new();
|
||||
ConcurrentDictionary<string, SelectionDLC> catalogItems = new();
|
||||
// get catalog items
|
||||
ConcurrentDictionary<string, SelectionDLC> entitlements = new();
|
||||
List<Task> dlcTasks = new();
|
||||
List<(string id, string name, string product, string icon, string developer)> entitlementIds
|
||||
= await EpicStore.QueryEntitlements(@namespace);
|
||||
if (entitlementIds.Any())
|
||||
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)
|
||||
{
|
||||
if (Program.Canceled)
|
||||
|
@ -421,16 +433,15 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
entitlements[id] = (name, product, icon, developer);
|
||||
entitlements[id] = new()
|
||||
{
|
||||
Id = id, Name = name, Product = product, Icon = icon,
|
||||
Publisher = developer
|
||||
};
|
||||
RemoveFromRemainingDLCs(id);
|
||||
});
|
||||
dlcTasks.Add(task);
|
||||
}
|
||||
if ( /*!catalogItems.Any() && */!entitlements.Any())
|
||||
{
|
||||
RemoveFromRemainingGames(name);
|
||||
return;
|
||||
}
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
foreach (Task task in dlcTasks)
|
||||
|
@ -439,8 +450,14 @@ internal sealed partial class SelectForm : CustomForm
|
|||
return;
|
||||
await task;
|
||||
}
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Epic, @namespace) ?? new ProgramSelection();
|
||||
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any();
|
||||
if (catalogItems.IsEmpty && entitlements.IsEmpty)
|
||||
{
|
||||
RemoveFromRemainingGames(name);
|
||||
return;
|
||||
}
|
||||
Selection selection = Selection.FromPlatformId(Platform.Epic, @namespace) ?? new Selection();
|
||||
selection.Enabled = allCheckBox.Checked || selection.DLC.Any(dlc => dlc.Enabled)
|
||||
|| selection.ExtraSelections.Any(extraSelection => extraSelection.DLC.Any(dlc => dlc.Enabled));
|
||||
if (koaloaderAllCheckBox.Checked)
|
||||
selection.Koaloader = true;
|
||||
selection.Id = @namespace;
|
||||
|
@ -449,12 +466,13 @@ internal sealed partial class SelectForm : CustomForm
|
|||
selection.ExecutableDirectories = await EpicLibrary.GetExecutableDirectories(selection.RootDirectory);
|
||||
selection.DllDirectories = dllDirectories;
|
||||
selection.Platform = Platform.Epic;
|
||||
foreach (KeyValuePair<string, (string name, string product, string icon, string developer)> pair in entitlements.Where(p
|
||||
=> p.Value.name == selection.Name))
|
||||
foreach (KeyValuePair<string, SelectionDLC> dlc in entitlements.Where(dlc => dlc.Value.Name == selection.Name))
|
||||
{
|
||||
selection.ProductUrl = "https://www.epicgames.com/store/product/" + pair.Value.product;
|
||||
selection.IconUrl = pair.Value.icon;
|
||||
selection.Publisher = pair.Value.developer;
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
selection.Product = "https://www.epicgames.com/store/product/" + dlc.Value.Product;
|
||||
selection.Icon = dlc.Value.Icon;
|
||||
selection.Publisher = dlc.Value.Publisher;
|
||||
}
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
|
@ -469,35 +487,49 @@ internal sealed partial class SelectForm : CustomForm
|
|||
programNode.Checked = selection.Enabled;
|
||||
if (programNode.TreeView is null)
|
||||
_ = selectionTreeView.Nodes.Add(programNode);
|
||||
/*TreeNode catalogItemsNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == @namespace + "_catalogItems") ?? new();
|
||||
catalogItemsNode.Tag = selection.Platform;
|
||||
catalogItemsNode.Name = @namespace + "_catalogItems";
|
||||
catalogItemsNode.Text = "Catalog Items";
|
||||
catalogItemsNode.Checked = selection.SelectedDlc.Any(pair => pair.Value.type == DlcType.CatalogItem);
|
||||
if (catalogItemsNode.Parent is null)
|
||||
programNode.Nodes.Add(catalogItemsNode);*/
|
||||
if (entitlements.Any())
|
||||
/*TreeNode entitlementsNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == @namespace + "_entitlements") ?? new();
|
||||
entitlementsNode.Tag = selection.Platform;
|
||||
entitlementsNode.Name = @namespace + "_entitlements";
|
||||
entitlementsNode.Text = "Entitlements";
|
||||
entitlementsNode.Checked = selection.SelectedDlc.Any(pair => pair.Value.type == DlcType.Entitlement);
|
||||
if (entitlementsNode.Parent is null)
|
||||
programNode.Nodes.Add(entitlementsNode);*/
|
||||
foreach ((string dlcId, (string name, string product, string icon, string developer) value) in entitlements)
|
||||
if (!catalogItems.IsEmpty)
|
||||
/*TreeNode catalogItemsNode = treeNodes.Find(node => node.Tag is Platform.Epic && node.Name == @namespace + "_catalogItems") ?? new();
|
||||
catalogItemsNode.Name = @namespace + "_catalogItems";
|
||||
catalogItemsNode.Text = "Catalog Items";
|
||||
catalogItemsNode.Checked = selection.DLC.Any(dlc => dlc.Type is DLCType.EpicCatalogItem && dlc.Enabled);
|
||||
if (catalogItemsNode.Parent is null)
|
||||
_ = programNode.Nodes.Add(catalogItemsNode);*/
|
||||
foreach ((_, SelectionDLC dlc) in catalogItems)
|
||||
{
|
||||
(DlcType type, string name, string icon) dlcApp = (DlcType.EpicEntitlement, value.name, value.icon);
|
||||
selection.AllDlc[dlcId] = dlcApp;
|
||||
if (allCheckBox.Checked)
|
||||
selection.SelectedDlc[dlcId] = dlcApp;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == dlcId) ?? new TreeNode();
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
dlc.Selection = selection;
|
||||
dlc.Enabled = allCheckBox.Checked;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == dlc.Id) ?? new TreeNode();
|
||||
dlcNode.Tag = selection.Platform;
|
||||
dlcNode.Name = dlcId;
|
||||
dlcNode.Text = dlcApp.name;
|
||||
dlcNode.Checked = selection.SelectedDlc.ContainsKey(dlcId);
|
||||
dlcNode.Name = dlc.Id;
|
||||
dlcNode.Text = dlc.Name;
|
||||
dlcNode.Checked = dlc.Enabled;
|
||||
if (dlcNode.Parent is null)
|
||||
_ = programNode.Nodes.Add(dlcNode); //entitlementsNode.Nodes.Add(dlcNode);
|
||||
_ = programNode.Nodes.Add(dlcNode); //_ = catalogItemsNode.Nodes.Add(dlcNode);
|
||||
}
|
||||
if (entitlements.IsEmpty)
|
||||
return;
|
||||
/*TreeNode entitlementsNode = treeNodes.Find(node => node.Tag is Platform.Epic && node.Name == @namespace + "_entitlements") ?? new();
|
||||
entitlementsNode.Name = @namespace + "_entitlements";
|
||||
entitlementsNode.Text = "Entitlements";
|
||||
entitlementsNode.Checked = selection.DLC.Any(dlc => dlc.Type is DLCType.EpicEntitlement && dlc.Enabled);
|
||||
if (entitlementsNode.Parent is null)
|
||||
_ = programNode.Nodes.Add(entitlementsNode);*/
|
||||
foreach ((_, SelectionDLC dlc) in entitlements)
|
||||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
dlc.Selection = selection;
|
||||
dlc.Enabled = allCheckBox.Checked;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == dlc.Id) ?? new TreeNode();
|
||||
dlcNode.Tag = selection.Platform;
|
||||
dlcNode.Name = dlc.Id;
|
||||
dlcNode.Text = dlc.Name;
|
||||
dlcNode.Checked = dlc.Enabled;
|
||||
if (dlcNode.Parent is null)
|
||||
_ = programNode.Nodes.Add(dlcNode); //_ = entitlementsNode.Nodes.Add(dlcNode);
|
||||
}
|
||||
});
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
|
@ -508,7 +540,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Ubisoft))
|
||||
{
|
||||
List<(string gameId, string name, string gameDirectory)> ubisoftGames = await UbisoftLibrary.GetGames();
|
||||
HashSet<(string gameId, string name, string gameDirectory)> ubisoftGames = await UbisoftLibrary.GetGames();
|
||||
foreach ((string gameId, string name, string gameDirectory) in ubisoftGames)
|
||||
{
|
||||
if (Program.Canceled)
|
||||
|
@ -520,7 +552,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
List<string> dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft);
|
||||
HashSet<string> dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft);
|
||||
if (dllDirectories is null)
|
||||
{
|
||||
RemoveFromRemainingGames(name);
|
||||
|
@ -528,7 +560,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (uninstallAll)
|
||||
{
|
||||
ProgramSelection bareSelection = ProgramSelection.FromPlatformId(Platform.Ubisoft, gameId) ?? new ProgramSelection();
|
||||
Selection bareSelection = Selection.FromPlatformId(Platform.Ubisoft, gameId) ?? new Selection();
|
||||
bareSelection.Enabled = true;
|
||||
bareSelection.Id = gameId;
|
||||
bareSelection.Name = name;
|
||||
|
@ -541,8 +573,9 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Ubisoft, gameId) ?? new ProgramSelection();
|
||||
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any();
|
||||
Selection selection = Selection.FromPlatformId(Platform.Ubisoft, gameId) ?? new Selection();
|
||||
selection.Enabled = allCheckBox.Checked || selection.DLC.Any(dlc => dlc.Enabled)
|
||||
|| selection.ExtraSelections.Any(extraSelection => extraSelection.DLC.Any(dlc => dlc.Enabled));
|
||||
if (koaloaderAllCheckBox.Checked)
|
||||
selection.Koaloader = true;
|
||||
selection.Id = gameId;
|
||||
|
@ -551,7 +584,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
selection.ExecutableDirectories = await UbisoftLibrary.GetExecutableDirectories(selection.RootDirectory);
|
||||
selection.DllDirectories = dllDirectories;
|
||||
selection.Platform = Platform.Ubisoft;
|
||||
selection.IconUrl = IconGrabber.GetDomainFaviconUrl("store.ubi.com");
|
||||
selection.Icon = IconGrabber.GetDomainFaviconUrl("store.ubi.com");
|
||||
selectionTreeView.Invoke(delegate
|
||||
{
|
||||
if (Program.Canceled)
|
||||
|
@ -603,7 +636,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
ShowProgressBar();
|
||||
await ProgramData.Setup(this);
|
||||
bool scan = forceScan;
|
||||
if (!scan && (programsToScan is null || !programsToScan.Any() || forceProvideChoices))
|
||||
if (!scan && (programsToScan is null || programsToScan.Count < 1 || forceProvideChoices))
|
||||
{
|
||||
List<(Platform platform, string id, string name, bool alreadySelected)> gameChoices = new();
|
||||
if (ParadoxLauncher.InstallPath.DirectoryExists())
|
||||
|
@ -621,7 +654,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
foreach ((string gameId, string name, string _) in (await UbisoftLibrary.GetGames()).Where(g => !Program.IsGameBlocked(g.name, g.gameDirectory)))
|
||||
gameChoices.Add((Platform.Ubisoft, gameId, name,
|
||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Ubisoft && p.id == gameId)));
|
||||
if (gameChoices.Any())
|
||||
if (gameChoices.Count > 0)
|
||||
{
|
||||
using SelectDialogForm form = new(this);
|
||||
DialogResult selectResult = form.QueryUser("Choose which programs and/or games to scan:", gameChoices,
|
||||
|
@ -649,11 +682,11 @@ internal sealed partial class SelectForm : CustomForm
|
|||
await GetApplicablePrograms(iProgress, true);
|
||||
if (!Program.Canceled)
|
||||
OnUninstall(null, null);
|
||||
ProgramSelection.All.Clear();
|
||||
Selection.All.Clear();
|
||||
programsToScan = null;
|
||||
}
|
||||
else
|
||||
scan = selectResult == DialogResult.OK && choices is not null && choices.Any();
|
||||
scan = selectResult == DialogResult.OK && choices is not null && choices.Count > 0;
|
||||
const string retry = "\n\nPress the \"Rescan\" button to re-choose.";
|
||||
if (scan)
|
||||
{
|
||||
|
@ -696,7 +729,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
setup = false;
|
||||
progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
|
||||
ProgramSelection.ValidateAll(programsToScan);
|
||||
Selection.ValidateAll(programsToScan);
|
||||
TreeNodes.ForEach(node => node.Remove());
|
||||
await GetApplicablePrograms(iProgress);
|
||||
await SteamCMD.Cleanup();
|
||||
|
@ -704,11 +737,11 @@ internal sealed partial class SelectForm : CustomForm
|
|||
OnLoadDlc(null, null);
|
||||
OnLoadKoaloader(null, null);
|
||||
HideProgressBar();
|
||||
selectionTreeView.Enabled = ProgramSelection.All.Any();
|
||||
selectionTreeView.Enabled = Selection.All.Count > 0;
|
||||
allCheckBox.Enabled = selectionTreeView.Enabled;
|
||||
koaloaderAllCheckBox.Enabled = selectionTreeView.Enabled;
|
||||
noneFoundLabel.Visible = !selectionTreeView.Enabled;
|
||||
installButton.Enabled = ProgramSelection.AllEnabled.Any();
|
||||
installButton.Enabled = Selection.AllEnabled.Count > 0;
|
||||
uninstallButton.Enabled = installButton.Enabled;
|
||||
saveButton.Enabled = CanSaveDlc();
|
||||
loadButton.Enabled = CanLoadDlc();
|
||||
|
@ -735,7 +768,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||
allCheckBox.Checked = TreeNodes.TrueForAll(node => node.Text == "Unknown" || node.Checked);
|
||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||
installButton.Enabled = ProgramSelection.AllEnabled.Any();
|
||||
installButton.Enabled = Selection.AllEnabled.Count > 0;
|
||||
uninstallButton.Enabled = installButton.Enabled;
|
||||
saveButton.Enabled = CanSaveDlc();
|
||||
resetButton.Enabled = CanResetDlc();
|
||||
|
@ -770,19 +803,15 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
string id = node.Name;
|
||||
Platform platform = (Platform)node.Tag;
|
||||
(string gameId, (DlcType type, string name, string icon) app)? dlc = ProgramSelection.GetDlcFromPlatformId(platform, id);
|
||||
if (dlc.HasValue)
|
||||
Selection selection = Selection.FromPlatformId(platform, id);
|
||||
if (selection is not null)
|
||||
{
|
||||
(string gameId, _) = dlc.Value;
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(platform, gameId);
|
||||
selection?.ToggleDlc(node.Name, node.Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(platform, id);
|
||||
if (selection is not null)
|
||||
selection.Enabled = node.Checked;
|
||||
selection.Enabled = node.Checked;
|
||||
return;
|
||||
}
|
||||
SelectionDLC dlc = SelectionDLC.FromPlatformId(platform, id);
|
||||
if (dlc is not null)
|
||||
dlc.Enabled = node.Checked;
|
||||
}
|
||||
|
||||
private static List<TreeNode> GatherTreeNodes(TreeNodeCollection nodeCollection)
|
||||
|
@ -830,31 +859,25 @@ internal sealed partial class SelectForm : CustomForm
|
|||
internal void OnNodeRightClick(TreeNode node, Point location)
|
||||
=> Invoke(() =>
|
||||
{
|
||||
ContextMenuStrip contextMenuStrip = ContextMenuStrip;
|
||||
while (ContextMenuStrip.Tag is true)
|
||||
Thread.Sleep(100);
|
||||
ContextMenuStrip.Tag = true;
|
||||
ContextMenuStrip contextMenuStrip = new();
|
||||
ToolStripItemCollection items = contextMenuStrip.Items;
|
||||
items.Clear();
|
||||
string id = node.Name;
|
||||
Platform platform = (Platform)node.Tag;
|
||||
ProgramSelection selection = ProgramSelection.FromPlatformId(platform, id);
|
||||
(string gameAppId, (DlcType type, string name, string icon) app)? dlc = null;
|
||||
Selection selection = Selection.FromPlatformId(platform, id);
|
||||
SelectionDLC dlc = null;
|
||||
if (selection is null)
|
||||
dlc = ProgramSelection.GetDlcFromPlatformId(platform, id);
|
||||
ProgramSelection dlcParentSelection = null;
|
||||
dlc = SelectionDLC.FromPlatformId(platform, id);
|
||||
Selection dlcParentSelection = null;
|
||||
if (dlc is not null)
|
||||
dlcParentSelection = ProgramSelection.FromPlatformId(platform, dlc.Value.gameAppId);
|
||||
dlcParentSelection = Selection.FromPlatformId(platform, dlc.Selection.Id);
|
||||
if (selection is null && dlcParentSelection is null)
|
||||
return;
|
||||
ContextMenuItem header;
|
||||
if (id == "PL")
|
||||
header = new(node.Text, "Paradox Launcher");
|
||||
else if (selection is not null)
|
||||
header = new(node.Text, (id, selection.IconUrl));
|
||||
else
|
||||
header = new(node.Text, (id, dlc.Value.app.icon), (id, dlcParentSelection.IconUrl));
|
||||
items.Add(header);
|
||||
ContextMenuItem header = id == "PL"
|
||||
? new(node.Text, "Paradox Launcher")
|
||||
: selection is not null
|
||||
? new(node.Text, (id, selection.Icon))
|
||||
: new(node.Text, (id, dlc.Icon), (id, dlcParentSelection.Icon));
|
||||
_ = items.Add(header);
|
||||
string appInfoVDF = $@"{SteamCMD.AppInfoPath}\{id}.vdf";
|
||||
string appInfoJSON = $@"{SteamCMD.AppInfoPath}\{id}.json";
|
||||
string cooldown = $@"{ProgramData.CooldownPath}\{id}.txt";
|
||||
|
@ -872,12 +895,12 @@ internal sealed partial class SelectForm : CustomForm
|
|||
}
|
||||
if (appInfoVDF.FileExists())
|
||||
queries.Add(new("Open SteamCMD Query", "Notepad", (_, _) => Diagnostics.OpenFileInNotepad(appInfoVDF)));
|
||||
if (queries.Any())
|
||||
if (queries.Count > 0)
|
||||
{
|
||||
items.Add(new ToolStripSeparator());
|
||||
_ = items.Add(new ToolStripSeparator());
|
||||
foreach (ContextMenuItem query in queries)
|
||||
items.Add(query);
|
||||
items.Add(new ContextMenuItem("Refresh Queries", "Command Prompt", (_, _) =>
|
||||
_ = items.Add(query);
|
||||
_ = items.Add(new ContextMenuItem("Refresh Queries", "Command Prompt", (_, _) =>
|
||||
{
|
||||
appInfoVDF.DeleteFile();
|
||||
appInfoJSON.DeleteFile();
|
||||
|
@ -890,16 +913,16 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (id == "PL")
|
||||
{
|
||||
items.Add(new ToolStripSeparator());
|
||||
_ = items.Add(new ToolStripSeparator());
|
||||
async void EventHandler(object sender, EventArgs e) => await ParadoxLauncher.Repair(this, selection);
|
||||
items.Add(new ContextMenuItem("Repair", "Command Prompt", EventHandler));
|
||||
_ = items.Add(new ContextMenuItem("Repair", "Command Prompt", EventHandler));
|
||||
}
|
||||
items.Add(new ToolStripSeparator());
|
||||
items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
|
||||
_ = items.Add(new ToolStripSeparator());
|
||||
_ = items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
|
||||
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory)));
|
||||
int executables = 0;
|
||||
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories.ToList())
|
||||
items.Add(new ContextMenuItem($"Open Executable Directory #{++executables} ({(binaryType == BinaryType.BIT32 ? "32" : "64")}-bit)",
|
||||
_ = items.Add(new ContextMenuItem($"Open Executable Directory #{++executables} ({(binaryType == BinaryType.BIT32 ? "32" : "64")}-bit)",
|
||||
"File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||
List<string> directories = selection.DllDirectories.ToList();
|
||||
int steam = 0, epic = 0, r1 = 0, r2 = 0;
|
||||
|
@ -910,7 +933,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
out string config, out string old_log, out string log, out string cache);
|
||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || old_config.FileExists()
|
||||
|| config.FileExists() || old_log.FileExists() || log.FileExists() || cache.FileExists())
|
||||
items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer",
|
||||
_ = items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer",
|
||||
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||
}
|
||||
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
||||
|
@ -919,7 +942,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
||||
out string log);
|
||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists())
|
||||
items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer",
|
||||
_ = items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer",
|
||||
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||
}
|
||||
if (selection.Platform is Platform.Ubisoft)
|
||||
|
@ -928,13 +951,13 @@ internal sealed partial class SelectForm : CustomForm
|
|||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
||||
out string log);
|
||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists())
|
||||
items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer",
|
||||
_ = items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer",
|
||||
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config,
|
||||
out log);
|
||||
if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api32_o.FileExists() || api64.FileExists()
|
||||
|| api64_o.FileExists() || config.FileExists() || log.FileExists())
|
||||
items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer",
|
||||
_ = items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer",
|
||||
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||
}
|
||||
}
|
||||
|
@ -942,39 +965,39 @@ internal sealed partial class SelectForm : CustomForm
|
|||
{
|
||||
if (selection?.Platform is Platform.Steam || dlcParentSelection?.Platform is Platform.Steam)
|
||||
{
|
||||
items.Add(new ToolStripSeparator());
|
||||
items.Add(new ContextMenuItem("Open SteamDB", "SteamDB", (_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id)));
|
||||
_ = items.Add(new ToolStripSeparator());
|
||||
_ = items.Add(new ContextMenuItem("Open SteamDB", "SteamDB",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id)));
|
||||
}
|
||||
if (selection is not null)
|
||||
switch (selection.Platform)
|
||||
{
|
||||
case Platform.Steam:
|
||||
items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl)));
|
||||
items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIconUrl), "Steam Community",
|
||||
_ = items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Product)));
|
||||
_ = items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIcon), "Steam Community",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id)));
|
||||
break;
|
||||
case Platform.Epic:
|
||||
items.Add(new ToolStripSeparator());
|
||||
items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",
|
||||
_ = items.Add(new ToolStripSeparator());
|
||||
_ = items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://scream-db.web.app/offers/" + id)));
|
||||
items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl)));
|
||||
_ = items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Product)));
|
||||
break;
|
||||
case Platform.Ubisoft:
|
||||
items.Add(new ToolStripSeparator());
|
||||
items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store",
|
||||
_ = items.Add(new ToolStripSeparator());
|
||||
_ = items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store",
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(
|
||||
"https://store.ubi.com/us/" + selection.Name.Replace(" ", "-").ToLowerInvariant())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (selection?.WebsiteUrl != null)
|
||||
items.Add(new ContextMenuItem("Open Official Website", ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.WebsiteUrl)),
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.WebsiteUrl)));
|
||||
if (selection?.Website is not null)
|
||||
_ = items.Add(new ContextMenuItem("Open Official Website", ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.Website)),
|
||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Website)));
|
||||
contextMenuStrip.Show(selectionTreeView, location);
|
||||
contextMenuStrip.Refresh();
|
||||
ContextMenuStrip.Tag = null;
|
||||
});
|
||||
|
||||
private void OnLoad(object sender, EventArgs _)
|
||||
|
@ -996,9 +1019,9 @@ internal sealed partial class SelectForm : CustomForm
|
|||
|
||||
private void OnAccept(bool uninstall = false)
|
||||
{
|
||||
if (!ProgramSelection.All.Any())
|
||||
if (Selection.All.Count < 1)
|
||||
return;
|
||||
if (ProgramSelection.AllEnabled.Any(selection => !Program.AreDllsLockedDialog(this, selection)))
|
||||
if (Selection.AllEnabled.Any(selection => !Program.AreDllsLockedDialog(this, selection)))
|
||||
return;
|
||||
if (!uninstall && ParadoxLauncher.DlcDialog(this))
|
||||
return;
|
||||
|
@ -1053,8 +1076,8 @@ internal sealed partial class SelectForm : CustomForm
|
|||
|
||||
private void OnKoaloaderAllCheckBoxChanged(object sender, EventArgs e)
|
||||
{
|
||||
bool shouldCheck = ProgramSelection.AllSafe.Any(selection => !selection.Koaloader);
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
|
||||
bool shouldCheck = Selection.AllSafe.Any(selection => !selection.Koaloader);
|
||||
foreach (Selection selection in Selection.AllSafe)
|
||||
selection.Koaloader = shouldCheck;
|
||||
selectionTreeView.Invalidate();
|
||||
koaloaderAllCheckBox.CheckedChanged -= OnKoaloaderAllCheckBoxChanged;
|
||||
|
@ -1076,7 +1099,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
if (node.Text == "Unknown" ? node.Checked : !node.Checked)
|
||||
choices.Add((platform, node.Parent.Name, node.Name));
|
||||
else
|
||||
choices.RemoveAll(n => n.platform == platform && n.gameId == parent.Name && n.dlcId == node.Name);
|
||||
_ = choices.RemoveAll(n => n.platform == platform && n.gameId == parent.Name && n.dlcId == node.Name);
|
||||
}
|
||||
choices = choices.Distinct().ToList();
|
||||
ProgramData.WriteDlcChoices(choices);
|
||||
|
@ -1111,19 +1134,19 @@ internal sealed partial class SelectForm : CustomForm
|
|||
resetButton.Enabled = CanResetDlc();
|
||||
}
|
||||
|
||||
private static bool AreKoaloaderSelectionsDefault() => ProgramSelection.AllSafe.All(selection => selection.Koaloader && selection.KoaloaderProxy is null);
|
||||
private static bool AreKoaloaderSelectionsDefault() => Selection.AllSafe.All(selection => selection.Koaloader && selection.KoaloaderProxy is null);
|
||||
|
||||
private static bool CanSaveKoaloader() => ProgramData.ReadKoaloaderChoices().Any() || !AreKoaloaderSelectionsDefault();
|
||||
|
||||
private void OnSaveKoaloader(object sender, EventArgs e)
|
||||
{
|
||||
List<(Platform platform, string id, string proxy, bool enabled)> choices = ProgramData.ReadKoaloaderChoices().ToList();
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
|
||||
foreach (Selection selection in Selection.AllSafe)
|
||||
{
|
||||
_ = choices.RemoveAll(c => c.platform == selection.Platform && c.id == selection.Id);
|
||||
if (selection.KoaloaderProxy is not null and not ProgramSelection.DefaultKoaloaderProxy || !selection.Koaloader)
|
||||
choices.Add((selection.Platform, selection.Id,
|
||||
selection.KoaloaderProxy == ProgramSelection.DefaultKoaloaderProxy ? null : selection.KoaloaderProxy, selection.Koaloader));
|
||||
if (selection.KoaloaderProxy is not null and not Selection.DefaultKoaloaderProxy || !selection.Koaloader)
|
||||
choices.Add((selection.Platform, selection.Id, selection.KoaloaderProxy == Selection.DefaultKoaloaderProxy ? null : selection.KoaloaderProxy,
|
||||
selection.Koaloader));
|
||||
}
|
||||
ProgramData.WriteKoaloaderProxyChoices(choices);
|
||||
saveKoaloaderButton.Enabled = CanSaveKoaloader();
|
||||
|
@ -1135,7 +1158,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
private void OnLoadKoaloader(object sender, EventArgs e)
|
||||
{
|
||||
List<(Platform platform, string id, string proxy, bool enabled)> choices = ProgramData.ReadKoaloaderChoices().ToList();
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
|
||||
foreach (Selection selection in Selection.AllSafe)
|
||||
if (choices.Any(c => c.platform == selection.Platform && c.id == selection.Id))
|
||||
{
|
||||
(Platform platform, string id, string proxy, bool enabled)
|
||||
|
@ -1146,12 +1169,12 @@ internal sealed partial class SelectForm : CustomForm
|
|||
proxy.GetProxyInfoFromIdentifier(out currentProxy, out _);
|
||||
if (proxy != currentProxy && choices.Remove(choice)) // convert pre-v4.1.0.0 choices
|
||||
choices.Add((platform, id, currentProxy, enabled));
|
||||
if (currentProxy is null or ProgramSelection.DefaultKoaloaderProxy && enabled)
|
||||
if (currentProxy is null or Selection.DefaultKoaloaderProxy && enabled)
|
||||
_ = choices.RemoveAll(c => c.platform == platform && c.id == id);
|
||||
else
|
||||
{
|
||||
selection.Koaloader = enabled;
|
||||
selection.KoaloaderProxy = currentProxy == ProgramSelection.DefaultKoaloaderProxy ? currentProxy : proxy;
|
||||
selection.KoaloaderProxy = currentProxy == Selection.DefaultKoaloaderProxy ? currentProxy : proxy;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1168,7 +1191,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
|
||||
private void OnResetKoaloader(object sender, EventArgs e)
|
||||
{
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
|
||||
foreach (Selection selection in Selection.AllSafe)
|
||||
{
|
||||
selection.Koaloader = true;
|
||||
selection.KoaloaderProxy = null;
|
||||
|
@ -1182,7 +1205,7 @@ internal sealed partial class SelectForm : CustomForm
|
|||
saveKoaloaderButton.Enabled = CanSaveKoaloader();
|
||||
resetKoaloaderButton.Enabled = CanResetKoaloader();
|
||||
koaloaderAllCheckBox.CheckedChanged -= OnKoaloaderAllCheckBoxChanged;
|
||||
koaloaderAllCheckBox.Checked = ProgramSelection.AllSafe.TrueForAll(selection => selection.Koaloader);
|
||||
koaloaderAllCheckBox.Checked = Selection.AllSafe.TrueForAll(selection => selection.Koaloader);
|
||||
koaloaderAllCheckBox.CheckedChanged += OnKoaloaderAllCheckBoxChanged;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,13 +27,13 @@ internal static class EpicLibrary
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
internal static async Task<HashSet<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
|
||||
internal static async Task<List<Manifest>> GetGames()
|
||||
internal static async Task<HashSet<Manifest>> GetGames()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<Manifest> games = new();
|
||||
HashSet<Manifest> games = new();
|
||||
string manifests = EpicManifestsPath;
|
||||
if (!manifests.DirectoryExists())
|
||||
return games;
|
||||
|
@ -47,7 +47,7 @@ internal static class EpicLibrary
|
|||
Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json);
|
||||
if (manifest is not null && manifest.CatalogItemId == manifest.MainGameCatalogItemId && !games.Any(g
|
||||
=> g.CatalogItemId == manifest.CatalogItemId && g.InstallLocation == manifest.InstallLocation))
|
||||
games.Add(manifest);
|
||||
_ = games.Add(manifest);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -54,7 +54,7 @@ internal static class EpicStore
|
|||
foreach (Element element in searchStore)
|
||||
{
|
||||
string title = element.Title;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() ? element.CatalogNs.Mappings.First().PageSlug : null;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Length > 0 ? element.CatalogNs.Mappings.First().PageSlug : null;
|
||||
string icon = null;
|
||||
for (int i = 0; i < element.KeyImages?.Length; i++)
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ internal static class EpicStore
|
|||
foreach (Element element in catalogOffers)
|
||||
{
|
||||
string title = element.Title;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() ? element.CatalogNs.Mappings.First().PageSlug : null;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Length > 0 ? element.CatalogNs.Mappings.First().PageSlug : null;
|
||||
string icon = null;
|
||||
for (int i = 0; i < element.KeyImages?.Length; i++)
|
||||
{
|
||||
|
|
|
@ -34,49 +34,39 @@ internal static class ParadoxLauncher
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
internal static async Task<HashSet<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(validFunc: path => !Path.GetFileName(path).Contains("bootstrapper")));
|
||||
|
||||
private static void PopulateDlc(ProgramSelection paradoxLauncher = null)
|
||||
private static void PopulateDlc(Selection paradoxLauncher = null)
|
||||
{
|
||||
paradoxLauncher ??= ProgramSelection.FromPlatformId(Platform.Paradox, "PL");
|
||||
if (paradoxLauncher is not null)
|
||||
{
|
||||
paradoxLauncher.ExtraDlc.Clear();
|
||||
paradoxLauncher.ExtraSelectedDlc.Clear();
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllEnabled.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
{
|
||||
paradoxLauncher.ExtraDlc.Add(selection.Id, (selection.Name, selection.AllDlc));
|
||||
paradoxLauncher.ExtraSelectedDlc.Add(selection.Id, (selection.Name, selection.SelectedDlc));
|
||||
}
|
||||
if (!paradoxLauncher.ExtraDlc.Any())
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
{
|
||||
paradoxLauncher.ExtraDlc.Add(selection.Id, (selection.Name, selection.AllDlc));
|
||||
paradoxLauncher.ExtraSelectedDlc.Add(selection.Id, (selection.Name, selection.AllDlc));
|
||||
}
|
||||
}
|
||||
paradoxLauncher ??= Selection.FromPlatformId(Platform.Paradox, "PL");
|
||||
if (paradoxLauncher is null)
|
||||
return;
|
||||
paradoxLauncher.ExtraSelections.Clear();
|
||||
foreach (Selection selection in Selection.AllEnabled.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
_ = paradoxLauncher.ExtraSelections.Add(selection);
|
||||
if (paradoxLauncher.ExtraSelections.Count > 0)
|
||||
return;
|
||||
foreach (Selection selection in Selection.AllSafe.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
_ = paradoxLauncher.ExtraSelections.Add(selection);
|
||||
}
|
||||
|
||||
internal static bool DlcDialog(Form form)
|
||||
{
|
||||
ProgramSelection paradoxLauncher = ProgramSelection.FromPlatformId(Platform.Paradox, "PL");
|
||||
if (paradoxLauncher is not null && paradoxLauncher.Enabled)
|
||||
{
|
||||
PopulateDlc(paradoxLauncher);
|
||||
if (!paradoxLauncher.ExtraDlc.Any())
|
||||
{
|
||||
using DialogForm dialogForm = new(form);
|
||||
return dialogForm.Show(SystemIcons.Warning,
|
||||
"WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!"
|
||||
+ "\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!", "Ignore", "Cancel",
|
||||
"Paradox Launcher") != DialogResult.OK;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
Selection paradoxLauncher = Selection.FromPlatformId(Platform.Paradox, "PL");
|
||||
if (paradoxLauncher is null || !paradoxLauncher.Enabled)
|
||||
return false;
|
||||
PopulateDlc(paradoxLauncher);
|
||||
if (paradoxLauncher.ExtraSelections.Count > 0)
|
||||
return false;
|
||||
using DialogForm dialogForm = new(form);
|
||||
return dialogForm.Show(SystemIcons.Warning,
|
||||
"WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!"
|
||||
+ "\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!", "Ignore", "Cancel",
|
||||
"Paradox Launcher") != DialogResult.OK;
|
||||
}
|
||||
|
||||
internal static async Task<RepairResult> Repair(Form form, ProgramSelection selection)
|
||||
internal static async Task<RepairResult> Repair(Form form, Selection selection)
|
||||
{
|
||||
InstallForm installForm = form as InstallForm;
|
||||
if (!Program.AreDllsLockedDialog(form, selection))
|
||||
|
|
|
@ -22,14 +22,14 @@ internal static class SteamLibrary
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
internal static async Task<HashSet<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
|
||||
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>> GetGames()
|
||||
internal static async Task<HashSet<(string appId, string name, string branch, int buildId, string gameDirectory)>> GetGames()
|
||||
=> await Task.Run(async () =>
|
||||
{
|
||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||
List<string> gameLibraryDirectories = await GetLibraryDirectories();
|
||||
HashSet<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||
HashSet<string> gameLibraryDirectories = await GetLibraryDirectories();
|
||||
foreach (string libraryDirectory in gameLibraryDirectories)
|
||||
{
|
||||
if (Program.Canceled)
|
||||
|
@ -37,7 +37,7 @@ internal static class SteamLibrary
|
|||
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in
|
||||
(await GetGamesFromLibraryDirectory(libraryDirectory)).Where(game
|
||||
=> !games.Any(_game => _game.appId == game.appId && _game.gameDirectory == game.gameDirectory)))
|
||||
games.Add(game);
|
||||
_ = games.Add(game);
|
||||
}
|
||||
return games;
|
||||
});
|
||||
|
@ -85,10 +85,10 @@ internal static class SteamLibrary
|
|||
return games;
|
||||
});
|
||||
|
||||
private static async Task<List<string>> GetLibraryDirectories()
|
||||
private static async Task<HashSet<string>> GetLibraryDirectories()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<string> gameDirectories = new();
|
||||
HashSet<string> gameDirectories = new();
|
||||
if (Program.Canceled)
|
||||
return gameDirectories;
|
||||
string steamInstallPath = InstallPath;
|
||||
|
@ -97,7 +97,7 @@ internal static class SteamLibrary
|
|||
string libraryFolder = steamInstallPath + @"\steamapps";
|
||||
if (!libraryFolder.DirectoryExists())
|
||||
return gameDirectories;
|
||||
gameDirectories.Add(libraryFolder);
|
||||
_ = gameDirectories.Add(libraryFolder);
|
||||
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
|
||||
if (!libraryFolders.FileExists() || !ValveDataFile.TryDeserialize(libraryFolders.ReadFile(), out VProperty result))
|
||||
return gameDirectories;
|
||||
|
@ -108,8 +108,8 @@ internal static class SteamLibrary
|
|||
if (string.IsNullOrWhiteSpace(path))
|
||||
continue;
|
||||
path += @"\steamapps";
|
||||
if (path.DirectoryExists() && !gameDirectories.Contains(path))
|
||||
gameDirectories.Add(path);
|
||||
if (path.DirectoryExists())
|
||||
_ = gameDirectories.Add(path);
|
||||
}
|
||||
return gameDirectories;
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ internal static class UbisoftLibrary
|
|||
{
|
||||
private static RegistryKey installsKey;
|
||||
|
||||
internal static RegistryKey InstallsKey
|
||||
private static RegistryKey InstallsKey
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -22,13 +22,13 @@ internal static class UbisoftLibrary
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
internal static async Task<HashSet<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
|
||||
internal static async Task<List<(string gameId, string name, string gameDirectory)>> GetGames()
|
||||
internal static async Task<HashSet<(string gameId, string name, string gameDirectory)>> GetGames()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<(string gameId, string name, string gameDirectory)> games = new();
|
||||
HashSet<(string gameId, string name, string gameDirectory)> games = new();
|
||||
RegistryKey installsKey = InstallsKey;
|
||||
if (installsKey is null)
|
||||
return games;
|
||||
|
@ -37,7 +37,7 @@ internal static class UbisoftLibrary
|
|||
RegistryKey installKey = installsKey.OpenSubKey(gameId);
|
||||
string installDir = installKey?.GetValue("InstallDir")?.ToString()?.BeautifyPath();
|
||||
if (installDir is not null && !games.Any(g => g.gameId == gameId && g.gameDirectory == installDir))
|
||||
games.Add((gameId, new DirectoryInfo(installDir).Name, installDir));
|
||||
_ = games.Add((gameId, new DirectoryInfo(installDir).Name, installDir));
|
||||
}
|
||||
return games;
|
||||
});
|
||||
|
|
|
@ -48,7 +48,7 @@ internal static class Program
|
|||
return ProtectedGameDirectories.Any(path => (directory + path).DirectoryExists());
|
||||
}
|
||||
|
||||
internal static bool AreDllsLockedDialog(Form form, ProgramSelection selection)
|
||||
internal static bool AreDllsLockedDialog(Form form, Selection selection)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
|
|
@ -75,7 +75,7 @@ internal static class Koaloader
|
|||
}
|
||||
SortedList<string, string> targets = new(PlatformIdComparer.String);
|
||||
SortedList<string, string> modules = new(PlatformIdComparer.String);
|
||||
if (targets.Any() || modules.Any())
|
||||
if (targets.Count > 0 || modules.Count > 0)
|
||||
{
|
||||
/*if (installForm is not null)
|
||||
installForm.UpdateUser("Generating Koaloader configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
|
@ -92,13 +92,13 @@ internal static class Koaloader
|
|||
}
|
||||
}
|
||||
|
||||
private static void WriteConfig(StreamWriter writer, SortedList<string, string> targets, SortedList<string, string> modules, InstallForm installForm = null)
|
||||
private static void WriteConfig(TextWriter writer, SortedList<string, string> targets, SortedList<string, string> modules, InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"logging\": false,");
|
||||
writer.WriteLine(" \"enabled\": true,");
|
||||
writer.WriteLine(" \"auto_load\": " + (modules.Any() ? "false" : "true") + ",");
|
||||
if (targets.Any())
|
||||
writer.WriteLine(" \"auto_load\": " + (modules.Count > 0 ? "false" : "true") + ",");
|
||||
if (targets.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"targets\": [");
|
||||
KeyValuePair<string, string> lastTarget = targets.Last();
|
||||
|
@ -112,7 +112,7 @@ internal static class Koaloader
|
|||
}
|
||||
else
|
||||
writer.WriteLine(" \"targets\": []");
|
||||
if (modules.Any())
|
||||
if (modules.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"modules\": [");
|
||||
KeyValuePair<string, string> lastModule = modules.Last();
|
||||
|
@ -166,11 +166,11 @@ internal static class Koaloader
|
|||
await Uninstall(rootDirectory, null, installForm, deleteConfig);
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, BinaryType binaryType, ProgramSelection selection, string rootDirectory = null,
|
||||
internal static async Task Install(string directory, BinaryType binaryType, Selection selection, string rootDirectory = null,
|
||||
InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy;
|
||||
string proxy = selection.KoaloaderProxy ?? Selection.DefaultKoaloaderProxy;
|
||||
string path = directory + @"\" + proxy + ".dll";
|
||||
foreach (string _path in directory.GetKoaloaderProxies().Where(p => p != path && p.FileExists() && p.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||
{
|
||||
|
|
|
@ -483,21 +483,21 @@ internal static class Resources
|
|||
|
||||
internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) => NativeImports.GetBinaryType(path, out binaryType);
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(this string rootDirectory, bool filterCommon = false,
|
||||
Func<string, bool> validFunc = null)
|
||||
internal static async Task<HashSet<(string directory, BinaryType binaryType)>> GetExecutableDirectories(this string rootDirectory,
|
||||
bool filterCommon = false, Func<string, bool> validFunc = null)
|
||||
=> await Task.Run(async ()
|
||||
=> (await rootDirectory.GetExecutables(filterCommon, validFunc)
|
||||
?? (filterCommon || validFunc is not null ? await rootDirectory.GetExecutables() : null))?.Select(e =>
|
||||
{
|
||||
e.path = Path.GetDirectoryName(e.path);
|
||||
return e;
|
||||
}).DistinctBy(e => e.path).ToList());
|
||||
}).DistinctBy(e => e.path).ToHashSet());
|
||||
|
||||
internal static async Task<List<(string path, BinaryType binaryType)>> GetExecutables(this string rootDirectory, bool filterCommon = false,
|
||||
internal static async Task<HashSet<(string path, BinaryType binaryType)>> GetExecutables(this string rootDirectory, bool filterCommon = false,
|
||||
Func<string, bool> validFunc = null)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<(string path, BinaryType binaryType)> executables = new();
|
||||
HashSet<(string path, BinaryType binaryType)> executables = new();
|
||||
if (Program.Canceled || !rootDirectory.DirectoryExists())
|
||||
return null;
|
||||
foreach (string path in rootDirectory.EnumerateDirectory("*.exe", true))
|
||||
|
@ -507,7 +507,7 @@ internal static class Resources
|
|||
if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
||||
&& (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType)
|
||||
&& binaryType is BinaryType.BIT64)
|
||||
executables.Add((path, binaryType));
|
||||
_ = executables.Add((path, binaryType));
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
foreach (string path in rootDirectory.EnumerateDirectory("*.exe", true))
|
||||
|
@ -517,10 +517,10 @@ internal static class Resources
|
|||
if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
||||
&& (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType)
|
||||
&& binaryType is BinaryType.BIT32)
|
||||
executables.Add((path, binaryType));
|
||||
_ = executables.Add((path, binaryType));
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
return !executables.Any() ? null : executables;
|
||||
return executables.Count > 0 ? executables : null;
|
||||
});
|
||||
|
||||
private static bool IsCommonIncorrectExecutable(this string rootDirectory, string path)
|
||||
|
@ -533,10 +533,10 @@ internal static class Resources
|
|||
|| subPath.Contains("ANTICHEAT");
|
||||
}
|
||||
|
||||
internal static async Task<List<string>> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform)
|
||||
internal static async Task<HashSet<string>> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<string> dllDirectories = new();
|
||||
HashSet<string> dllDirectories = new();
|
||||
if (Program.Canceled || !gameDirectory.DirectoryExists())
|
||||
return null;
|
||||
foreach (string directory in gameDirectory.EnumerateSubdirectories("*", true).Append(gameDirectory))
|
||||
|
@ -555,7 +555,7 @@ internal static class Resources
|
|||
if (api.FileExists() || api_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
||||
|| (old_config.FileExists() || config.FileExists() || old_log.FileExists() || log.FileExists() || cache.FileExists())
|
||||
&& !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
_ = dllDirectories.Add(subDirectory);
|
||||
}
|
||||
if (platform is Platform.Epic or Platform.Paradox)
|
||||
{
|
||||
|
@ -563,7 +563,7 @@ internal static class Resources
|
|||
out string log);
|
||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
||||
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
_ = dllDirectories.Add(subDirectory);
|
||||
}
|
||||
if (platform is Platform.Ubisoft)
|
||||
{
|
||||
|
@ -571,15 +571,15 @@ internal static class Resources
|
|||
out string log);
|
||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
||||
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
_ = dllDirectories.Add(subDirectory);
|
||||
subDirectory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config,
|
||||
out log);
|
||||
if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api32_o.FileExists() || api64.FileExists()
|
||||
|| api64_o.FileExists() || (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
_ = dllDirectories.Add(subDirectory);
|
||||
}
|
||||
}
|
||||
return !dllDirectories.Any() ? null : dllDirectories;
|
||||
return dllDirectories.Count > 0 ? dllDirectories : null;
|
||||
});
|
||||
|
||||
internal static void GetCreamApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
|
|
|
@ -22,27 +22,24 @@ internal static class ScreamAPI
|
|||
log = directory + @"\ScreamAPI.log";
|
||||
}
|
||||
|
||||
internal static void CheckConfig(string directory, ProgramSelection 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 _);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideCatalogItems
|
||||
= selection.AllDlc.Where(pair => pair.Value.type is DlcType.EpicCatalogItem).Except(selection.SelectedDlc);
|
||||
foreach (KeyValuePair<string, (string _, SortedList<string, (DlcType type, string name, string icon)> extraDlc)> pair in selection.ExtraSelectedDlc)
|
||||
overrideCatalogItems = overrideCatalogItems.Except(pair.Value.extraDlc);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> entitlements
|
||||
= selection.SelectedDlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement);
|
||||
foreach (KeyValuePair<string, (string _, SortedList<string, (DlcType type, string name, string icon)> dlc)> pair in selection.ExtraSelectedDlc)
|
||||
entitlements = entitlements.Concat(pair.Value.dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement));
|
||||
overrideCatalogItems = overrideCatalogItems.ToList();
|
||||
entitlements = entitlements.ToList();
|
||||
if (overrideCatalogItems.Any() || entitlements.Any())
|
||||
List<SelectionDLC> overrideCatalogItems = selection.DLC.Where(dlc => dlc.Type is DLCType.EpicCatalogItem && !dlc.Enabled).ToList();
|
||||
List<SelectionDLC> overrideEntitlements = selection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement && !dlc.Enabled).ToList();
|
||||
foreach (Selection extraSelection in selection.ExtraSelections)
|
||||
{
|
||||
overrideCatalogItems.AddRange(extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicCatalogItem && !dlc.Enabled));
|
||||
overrideEntitlements.AddRange(extraSelection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement && !dlc.Enabled));
|
||||
}
|
||||
if (overrideCatalogItems.Count > 0 || overrideEntitlements.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(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
new(entitlements.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
WriteConfig(writer, new(overrideCatalogItems.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||
new(overrideEntitlements.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
|
@ -53,8 +50,8 @@ internal static class ScreamAPI
|
|||
}
|
||||
}
|
||||
|
||||
private static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideCatalogItems,
|
||||
SortedList<string, (DlcType type, string name, string icon)> entitlements, InstallForm installForm = null)
|
||||
private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> overrideCatalogItems, SortedList<string, SelectionDLC> entitlements,
|
||||
InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"version\": 2,");
|
||||
|
@ -63,16 +60,16 @@ internal static class ScreamAPI
|
|||
writer.WriteLine(" \"block_metrics\": false,");
|
||||
writer.WriteLine(" \"catalog_items\": {");
|
||||
writer.WriteLine(" \"unlock_all\": true,");
|
||||
if (overrideCatalogItems.Any())
|
||||
if (overrideCatalogItems.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"override\": [");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastOverrideCatalogItem = overrideCatalogItems.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in overrideCatalogItems)
|
||||
KeyValuePair<string, SelectionDLC> lastOverrideCatalogItem = overrideCatalogItems.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> pair in overrideCatalogItems)
|
||||
{
|
||||
string id = pair.Key;
|
||||
(_, string name, _) = pair.Value;
|
||||
writer.WriteLine($" \"{id}\"{(pair.Equals(lastOverrideCatalogItem) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added override catalog item to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, false);
|
||||
SelectionDLC selectionDlc = pair.Value;
|
||||
writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastOverrideCatalogItem) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added locked catalog item to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
||||
false);
|
||||
}
|
||||
writer.WriteLine(" ]");
|
||||
}
|
||||
|
@ -82,16 +79,16 @@ internal static class ScreamAPI
|
|||
writer.WriteLine(" \"entitlements\": {");
|
||||
writer.WriteLine(" \"unlock_all\": true,");
|
||||
writer.WriteLine(" \"auto_inject\": true,");
|
||||
if (entitlements.Any())
|
||||
if (entitlements.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"inject\": [");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastEntitlement = entitlements.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in entitlements)
|
||||
KeyValuePair<string, SelectionDLC> lastEntitlement = entitlements.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> pair in entitlements)
|
||||
{
|
||||
string id = pair.Key;
|
||||
(_, string name, _) = pair.Value;
|
||||
writer.WriteLine($" \"{id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added entitlement to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, false);
|
||||
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,
|
||||
false);
|
||||
}
|
||||
writer.WriteLine(" ]");
|
||||
}
|
||||
|
@ -139,7 +136,7 @@ internal static class ScreamAPI
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
internal static async Task Install(string directory, Selection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _);
|
||||
|
|
|
@ -25,46 +25,38 @@ internal static class SmokeAPI
|
|||
cache = directory + @"\SmokeAPI.cache.json";
|
||||
}
|
||||
|
||||
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
|
||||
internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null)
|
||||
{
|
||||
directory.GetSmokeApiComponents(out _, out _, out _, out _, out string old_config, out string config, out _, out _, out _);
|
||||
List<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc).ToList();
|
||||
foreach (KeyValuePair<string, (string name, SortedList<string, (DlcType type, string name, string icon)> dlc)> pair in selection.ExtraDlc)
|
||||
if (selection.ExtraSelectedDlc.TryGetValue(pair.Key,
|
||||
out (string name, SortedList<string, (DlcType type, string name, string icon)> dlc) selectedPair))
|
||||
overrideDlc.AddRange(pair.Value.dlc.Except(selectedPair.dlc));
|
||||
List<KeyValuePair<string, (DlcType type, string name, string icon)>> injectDlc = new();
|
||||
if (selection.AllDlc.Count > 64)
|
||||
injectDlc.AddRange(selection.SelectedDlc.Where(pair => pair.Value.type is DlcType.SteamHidden));
|
||||
List<KeyValuePair<string, (string name, SortedList<string, (DlcType type, string name, string icon)> injectDlc)>> extraApps = new();
|
||||
if (selection.ExtraDlc.Any(e => e.Value.dlc.Count > 64))
|
||||
foreach (KeyValuePair<string, (string name, SortedList<string, (DlcType type, string name, string icon)> injectDlc)> pair in selection
|
||||
.ExtraSelectedDlc)
|
||||
if (selection.ExtraDlc.First(e => e.Key == pair.Key).Value.dlc.Count > 64)
|
||||
{
|
||||
SortedList<string, (DlcType type, string name, string icon)> extraInjectDlc = new(PlatformIdComparer.String);
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> extraPair in pair.Value.injectDlc.Where(extraPair
|
||||
=> extraPair.Value.type is DlcType.SteamHidden))
|
||||
extraInjectDlc.Add(extraPair.Key, extraPair.Value);
|
||||
KeyValuePair<string, (string name, SortedList<string, (DlcType type, string name, string icon)> injectDlc)> newExtraPair = new(pair.Key,
|
||||
(pair.Value.name, extraInjectDlc));
|
||||
extraApps.Add(newExtraPair);
|
||||
}
|
||||
injectDlc = injectDlc.ToList();
|
||||
List<SelectionDLC> overrideDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToList();
|
||||
foreach (Selection extraSelection in selection.ExtraSelections)
|
||||
overrideDlc.AddRange(extraSelection.DLC.Where(dlc => !dlc.Enabled));
|
||||
List<SelectionDLC> injectDlc = new();
|
||||
if (selection.DLC.Count() > 64)
|
||||
injectDlc.AddRange(selection.DLC.Where(dlc => dlc.Enabled && dlc.Type is DLCType.SteamHidden));
|
||||
List<KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)>> extraApps = new();
|
||||
foreach (Selection extraSelection in selection.ExtraSelections.Where(extraSelection => extraSelection.DLC.Count() > 64))
|
||||
{
|
||||
SortedList<string, SelectionDLC> extraInjectDlc = new(PlatformIdComparer.String);
|
||||
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(extraDlc => extraDlc.Enabled && extraDlc.Type is DLCType.SteamHidden))
|
||||
extraInjectDlc.Add(extraDlc.Id, extraDlc);
|
||||
if (extraInjectDlc.Count > 0)
|
||||
extraApps.Add(new(extraSelection.Id, (extraSelection.Name, extraInjectDlc)));
|
||||
}
|
||||
if (old_config.FileExists())
|
||||
{
|
||||
old_config.DeleteFile();
|
||||
installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (selection.ExtraSelectedDlc.Any(p => p.Value.dlc.Any()) || overrideDlc.Any() || injectDlc.Any())
|
||||
if (selection.ExtraSelections.Any(extraSelection => extraSelection.DLC.Any()) || overrideDlc.Count > 0 || injectDlc.Count > 0)
|
||||
{
|
||||
/*if (installForm is not null)
|
||||
installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
config.CreateFile(true, installForm).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer, selection.Id, new(extraApps.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
new(overrideDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
new(injectDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
WriteConfig(writer, selection.Id, new(extraApps.ToDictionary(extraApp => extraApp.Key, extraApp => extraApp.Value), PlatformIdComparer.String),
|
||||
new(overrideDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||
new(injectDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
|
@ -75,10 +67,8 @@ internal static class SmokeAPI
|
|||
}
|
||||
}
|
||||
|
||||
private static void WriteConfig(StreamWriter writer, string appId,
|
||||
SortedList<string, (string name, SortedList<string, (DlcType type, string name, string icon)> injectDlc)> extraApps,
|
||||
SortedList<string, (DlcType type, string name, string icon)> overrideDlc, SortedList<string, (DlcType type, string name, string icon)> injectDlc,
|
||||
InstallForm installForm = null)
|
||||
private static void WriteConfig(TextWriter writer, string appId, SortedList<string, (string name, SortedList<string, SelectionDLC> injectDlc)> extraApps,
|
||||
SortedList<string, SelectionDLC> overrideDlc, SortedList<string, SelectionDLC> injectDlc, InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"$version\": 2,");
|
||||
|
@ -89,13 +79,13 @@ internal static class SmokeAPI
|
|||
if (overrideDlc.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"override_dlc_status\": {");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastOverrideDlc = overrideDlc.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in overrideDlc)
|
||||
KeyValuePair<string, SelectionDLC> lastOverrideDlc = overrideDlc.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> pair in overrideDlc)
|
||||
{
|
||||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" \"{dlcId}\": \"locked\"{(pair.Equals(lastOverrideDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added locked DLC to SmokeAPI.config.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
SelectionDLC selectionDlc = pair.Value;
|
||||
writer.WriteLine($" \"{selectionDlc.Id}\": \"locked\"{(pair.Equals(lastOverrideDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added locked DLC to SmokeAPI.config.json with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
||||
false);
|
||||
}
|
||||
writer.WriteLine(" },");
|
||||
}
|
||||
|
@ -110,34 +100,34 @@ internal static class SmokeAPI
|
|||
{
|
||||
writer.WriteLine(" \"" + appId + "\": {");
|
||||
writer.WriteLine(" \"dlcs\": {");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastInjectDlc = injectDlc.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in injectDlc)
|
||||
KeyValuePair<string, SelectionDLC> lastInjectDlc = injectDlc.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> pair in injectDlc)
|
||||
{
|
||||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" \"{dlcId}\": \"{dlcName}\"{(pair.Equals(lastInjectDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
SelectionDLC selectionDlc = pair.Value;
|
||||
writer.WriteLine($" \"{selectionDlc.Id}\": \"{selectionDlc.Name}\"{(pair.Equals(lastInjectDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
||||
false);
|
||||
}
|
||||
writer.WriteLine(" }");
|
||||
writer.WriteLine(extraApps.Count > 0 ? " }," : " }");
|
||||
}
|
||||
if (extraApps.Count > 0)
|
||||
{
|
||||
KeyValuePair<string, (string name, SortedList<string, (DlcType type, string name, string icon)> injectDlc)> lastExtraApp = extraApps.Last();
|
||||
foreach (KeyValuePair<string, (string name, SortedList<string, (DlcType type, string name, string icon)> injectDlc)> pair in extraApps)
|
||||
KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)> lastExtraApp = extraApps.Last();
|
||||
foreach (KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)> pair in extraApps)
|
||||
{
|
||||
string extraAppId = pair.Key;
|
||||
(string _ /*extraAppName*/, SortedList<string, (DlcType type, string name, string icon)> extraInjectDlc) = pair.Value;
|
||||
(string _ /*extraAppName*/, SortedList<string, SelectionDLC> extraInjectDlc) = pair.Value;
|
||||
writer.WriteLine(" \"" + extraAppId + "\": {");
|
||||
writer.WriteLine(" \"dlcs\": {");
|
||||
//installForm?.UpdateUser($"Added extra app to SmokeAPI.config.json with appid {extraAppId} ({extraAppName})", LogTextBox.Action, false);
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastExtraAppDlc = extraInjectDlc.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> extraPair in extraInjectDlc)
|
||||
KeyValuePair<string, SelectionDLC> lastExtraAppDlc = extraInjectDlc.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> extraPair in extraInjectDlc)
|
||||
{
|
||||
string dlcId = extraPair.Key;
|
||||
(_, string dlcName, _) = extraPair.Value;
|
||||
writer.WriteLine($" \"{dlcId}\": \"{dlcName}\"{(extraPair.Equals(lastExtraAppDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
SelectionDLC selectionDlc = extraPair.Value;
|
||||
writer.WriteLine($" \"{selectionDlc.Id}\": \"{selectionDlc.Name}\"{(extraPair.Equals(lastExtraAppDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {selectionDlc.Id} ({selectionDlc.Name})",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" }");
|
||||
writer.WriteLine(pair.Equals(lastExtraApp) ? " }" : " },");
|
||||
|
@ -211,7 +201,7 @@ internal static class SmokeAPI
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
internal static async Task Install(string directory, Selection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig);
|
||||
|
|
|
@ -22,20 +22,19 @@ internal static class UplayR1
|
|||
log = directory + @"\UplayR1Unlocker.log";
|
||||
}
|
||||
|
||||
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
|
||||
internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null)
|
||||
{
|
||||
directory.GetUplayR1Components(out _, out _, out _, out _, out string config, out _);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach (KeyValuePair<string, (string _, SortedList<string, (DlcType type, string name, string icon)> extraDlc)> pair in selection.ExtraSelectedDlc)
|
||||
blacklistDlc = blacklistDlc.Except(pair.Value.extraDlc);
|
||||
blacklistDlc = blacklistDlc.ToList();
|
||||
if (blacklistDlc.Any())
|
||||
List<SelectionDLC> blacklistDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToList();
|
||||
foreach (Selection extraSelection in selection.ExtraSelections)
|
||||
blacklistDlc.AddRange(extraSelection.DLC.Where(dlc => !dlc.Enabled));
|
||||
if (blacklistDlc.Count > 0)
|
||||
{
|
||||
/*if (installForm is not null)
|
||||
installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
config.CreateFile(true, installForm).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
|
@ -46,8 +45,7 @@ internal static class UplayR1
|
|||
}
|
||||
}
|
||||
|
||||
private static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc,
|
||||
InstallForm installForm = null)
|
||||
private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> blacklistDlc, InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"logging\": false,");
|
||||
|
@ -56,13 +54,13 @@ internal static class UplayR1
|
|||
if (blacklistDlc.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"blacklist\": [");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastBlacklistDlc = blacklistDlc.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in blacklistDlc)
|
||||
KeyValuePair<string, SelectionDLC> lastBlacklistDlc = blacklistDlc.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> pair in blacklistDlc)
|
||||
{
|
||||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" {dlcId}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
SelectionDLC selectionDlc = pair.Value;
|
||||
writer.WriteLine($" {selectionDlc.Id}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
||||
false);
|
||||
}
|
||||
writer.WriteLine(" ],");
|
||||
}
|
||||
|
@ -109,7 +107,7 @@ internal static class UplayR1
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
internal static async Task Install(string directory, Selection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _);
|
||||
|
|
|
@ -24,20 +24,19 @@ internal static class UplayR2
|
|||
log = directory + @"\UplayR2Unlocker.log";
|
||||
}
|
||||
|
||||
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
|
||||
internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null)
|
||||
{
|
||||
directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config, out _);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach (KeyValuePair<string, (string _, SortedList<string, (DlcType type, string name, string icon)> extraDlc)> pair in selection.ExtraSelectedDlc)
|
||||
blacklistDlc = blacklistDlc.Except(pair.Value.extraDlc);
|
||||
blacklistDlc = blacklistDlc.ToList();
|
||||
if (blacklistDlc.Any())
|
||||
List<SelectionDLC> blacklistDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToList();
|
||||
foreach (Selection extraSelection in selection.ExtraSelections)
|
||||
blacklistDlc.AddRange(extraSelection.DLC.Where(dlc => !dlc.Enabled));
|
||||
if (blacklistDlc.Count > 0)
|
||||
{
|
||||
/*if (installForm is not null)
|
||||
installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
config.CreateFile(true, installForm).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
|
@ -48,8 +47,7 @@ internal static class UplayR2
|
|||
}
|
||||
}
|
||||
|
||||
private static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc,
|
||||
InstallForm installForm = null)
|
||||
private static void WriteConfig(TextWriter writer, SortedList<string, SelectionDLC> blacklistDlc, InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"logging\": false,");
|
||||
|
@ -60,13 +58,13 @@ internal static class UplayR2
|
|||
if (blacklistDlc.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"blacklist\": [");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastBlacklistDlc = blacklistDlc.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in blacklistDlc)
|
||||
KeyValuePair<string, SelectionDLC> lastBlacklistDlc = blacklistDlc.Last();
|
||||
foreach (KeyValuePair<string, SelectionDLC> pair in blacklistDlc)
|
||||
{
|
||||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" {dlcId}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
SelectionDLC selectionDlc = pair.Value;
|
||||
writer.WriteLine($" {selectionDlc.Id}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
||||
false);
|
||||
}
|
||||
writer.WriteLine(" ],");
|
||||
}
|
||||
|
@ -109,14 +107,13 @@ internal static class UplayR2
|
|||
config.DeleteFile();
|
||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (log.FileExists())
|
||||
{
|
||||
log.DeleteFile();
|
||||
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (!log.FileExists())
|
||||
return;
|
||||
log.DeleteFile();
|
||||
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false);
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
internal static async Task Install(string directory, Selection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CreamInstaller.Components;
|
||||
using CreamInstaller.Resources;
|
||||
using CreamInstaller.Utility;
|
||||
using static CreamInstaller.Resources.Resources;
|
||||
|
@ -13,47 +12,31 @@ public enum Platform
|
|||
Epic, Ubisoft
|
||||
}
|
||||
|
||||
public enum DlcType
|
||||
{
|
||||
Steam, SteamHidden, EpicCatalogItem,
|
||||
EpicEntitlement
|
||||
}
|
||||
|
||||
internal sealed class ProgramSelection
|
||||
internal sealed class Selection
|
||||
{
|
||||
internal const string DefaultKoaloaderProxy = "version";
|
||||
|
||||
internal static readonly List<ProgramSelection> All = new();
|
||||
internal static readonly HashSet<Selection> All = new();
|
||||
internal readonly HashSet<Selection> ExtraSelections = new();
|
||||
|
||||
internal readonly SortedList<string, (DlcType type, string name, string icon)> AllDlc = new(PlatformIdComparer.String);
|
||||
|
||||
internal readonly SortedList<string, (string name, SortedList<string, (DlcType type, string name, string icon)> dlc)> ExtraDlc = new();
|
||||
|
||||
internal readonly SortedList<string, (string name, SortedList<string, (DlcType type, string name, string icon)> dlc)> ExtraSelectedDlc = new();
|
||||
|
||||
internal readonly SortedList<string, (DlcType type, string name, string icon)> SelectedDlc = new(PlatformIdComparer.String);
|
||||
|
||||
internal List<string> DllDirectories;
|
||||
internal HashSet<string> DllDirectories;
|
||||
internal bool Enabled;
|
||||
internal List<(string directory, BinaryType binaryType)> ExecutableDirectories;
|
||||
internal string IconUrl;
|
||||
internal HashSet<(string directory, BinaryType binaryType)> ExecutableDirectories;
|
||||
internal string Icon;
|
||||
internal string Id = "0";
|
||||
internal bool Koaloader;
|
||||
internal string KoaloaderProxy;
|
||||
internal string Name = "Program";
|
||||
|
||||
internal Platform Platform;
|
||||
|
||||
internal string ProductUrl;
|
||||
|
||||
internal string Product;
|
||||
internal string Publisher;
|
||||
|
||||
internal string RootDirectory;
|
||||
internal string SubIconUrl;
|
||||
internal string SubIcon;
|
||||
internal string Website;
|
||||
|
||||
internal string WebsiteUrl;
|
||||
internal Selection() => All.Add(this);
|
||||
|
||||
internal ProgramSelection() => All.Add(this);
|
||||
internal IEnumerable<SelectionDLC> DLC => SelectionDLC.AllSafe.Where(dlc => dlc.Selection == this);
|
||||
|
||||
internal bool AreDllsLocked
|
||||
{
|
||||
|
@ -96,69 +79,41 @@ internal sealed class ProgramSelection
|
|||
}
|
||||
}
|
||||
|
||||
internal static List<ProgramSelection> AllSafe => All.ToList();
|
||||
internal static List<Selection> AllSafe => All.ToList();
|
||||
|
||||
internal static List<ProgramSelection> AllEnabled => AllSafe.FindAll(s => s.Enabled);
|
||||
internal static List<Selection> AllEnabled => AllSafe.FindAll(s => s.Enabled);
|
||||
|
||||
private void Toggle(string dlcAppId, (DlcType type, string name, string icon) dlcApp, bool enabled)
|
||||
private void Remove()
|
||||
{
|
||||
if (enabled)
|
||||
SelectedDlc[dlcAppId] = dlcApp;
|
||||
else
|
||||
_ = SelectedDlc.Remove(dlcAppId);
|
||||
}
|
||||
|
||||
internal void ToggleDlc(string dlcId, bool enabled)
|
||||
{
|
||||
foreach ((string appId, (DlcType type, string name, string icon) dlcApp) in AllDlc)
|
||||
{
|
||||
if (appId != dlcId)
|
||||
continue;
|
||||
Toggle(appId, dlcApp, enabled);
|
||||
break;
|
||||
}
|
||||
Enabled = SelectedDlc.Any() || ExtraSelectedDlc.Any();
|
||||
}
|
||||
|
||||
private void Validate()
|
||||
{
|
||||
if (Program.IsGameBlocked(Name, RootDirectory))
|
||||
{
|
||||
_ = All.Remove(this);
|
||||
return;
|
||||
}
|
||||
if (!RootDirectory.DirectoryExists())
|
||||
{
|
||||
_ = All.Remove(this);
|
||||
return;
|
||||
}
|
||||
_ = DllDirectories.RemoveAll(directory => !directory.DirectoryExists());
|
||||
if (!DllDirectories.Any())
|
||||
_ = All.Remove(this);
|
||||
_ = All.Remove(this);
|
||||
foreach (SelectionDLC dlc in DLC)
|
||||
dlc.Selection = null;
|
||||
}
|
||||
|
||||
private void Validate(List<(Platform platform, string id, string name)> programsToScan)
|
||||
{
|
||||
if (programsToScan is null || !programsToScan.Any(p => p.platform == Platform && p.id == Id))
|
||||
{
|
||||
_ = All.Remove(this);
|
||||
Remove();
|
||||
return;
|
||||
}
|
||||
Validate();
|
||||
if (Program.IsGameBlocked(Name, RootDirectory))
|
||||
{
|
||||
Remove();
|
||||
return;
|
||||
}
|
||||
if (!RootDirectory.DirectoryExists())
|
||||
{
|
||||
Remove();
|
||||
return;
|
||||
}
|
||||
_ = DllDirectories.RemoveWhere(directory => !directory.DirectoryExists());
|
||||
if (DllDirectories.Count < 1)
|
||||
Remove();
|
||||
}
|
||||
|
||||
internal static void ValidateAll() => AllSafe.ForEach(selection => selection.Validate());
|
||||
|
||||
internal static void ValidateAll(List<(Platform platform, string id, string name)> programsToScan)
|
||||
=> AllSafe.ForEach(selection => selection.Validate(programsToScan));
|
||||
|
||||
internal static ProgramSelection FromPlatformId(Platform platform, string gameId) => AllSafe.Find(s => s.Platform == platform && s.Id == gameId);
|
||||
|
||||
internal static (string gameId, (DlcType type, string name, string icon) app)? GetDlcFromPlatformId(Platform platform, string dlcId)
|
||||
{
|
||||
foreach (ProgramSelection selection in AllSafe.Where(s => s.Platform == platform))
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in selection.AllDlc.Where(p => p.Key == dlcId))
|
||||
return (selection.Id, pair.Value);
|
||||
return null;
|
||||
}
|
||||
internal static Selection FromPlatformId(Platform platform, string gameId) => AllSafe.Find(s => s.Platform == platform && s.Id == gameId);
|
||||
}
|
38
CreamInstaller/SelectionDLC.cs
Normal file
38
CreamInstaller/SelectionDLC.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CreamInstaller;
|
||||
|
||||
public enum DLCType
|
||||
{
|
||||
Steam, SteamHidden, EpicCatalogItem,
|
||||
EpicEntitlement
|
||||
}
|
||||
|
||||
internal sealed class SelectionDLC
|
||||
{
|
||||
private static readonly HashSet<SelectionDLC> All = new();
|
||||
|
||||
internal bool Enabled;
|
||||
internal string Icon;
|
||||
internal string Id;
|
||||
internal string Name;
|
||||
internal string Product;
|
||||
internal string Publisher;
|
||||
private Selection selection;
|
||||
internal DLCType Type;
|
||||
|
||||
internal Selection Selection
|
||||
{
|
||||
get => selection;
|
||||
set
|
||||
{
|
||||
selection = value;
|
||||
_ = value is null ? All.Remove(this) : All.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<SelectionDLC> AllSafe => All.ToList();
|
||||
|
||||
internal static SelectionDLC FromPlatformId(Platform platform, string dlcId) => AllSafe.Find(dlc => dlc.Selection.Platform == platform && dlc.Id == dlcId);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
|
@ -15,7 +15,7 @@ internal static class HttpClientManager
|
|||
{
|
||||
internal static HttpClient HttpClient;
|
||||
|
||||
private static readonly Dictionary<string, string> HttpContentCache = new();
|
||||
private static readonly ConcurrentDictionary<string, string> HttpContentCache = new();
|
||||
|
||||
internal static void Setup()
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ internal static class SafeIO
|
|||
while (!Program.Canceled)
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
_ = Directory.CreateDirectory(directoryPath);
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -251,6 +251,11 @@ internal static class SafeIO
|
|||
private static DialogResult IOWarnInternal(this string filePath, string message, Exception e, Form form = null)
|
||||
{
|
||||
using DialogForm dialogForm = new(form);
|
||||
return dialogForm.Show(SystemIcons.Warning, message + ": " + filePath.BeautifyPath() + "\n\n" + e.FormatException(), "Retry", "OK");
|
||||
string description = message + ": " + filePath.BeautifyPath() + "\n\n";
|
||||
if (e is IOException && (e.HResult & 0x0000FFFF) == 225) // virus or potentially unwanted software
|
||||
description += "Please resolve your anti-virus and press retry to continue . . . ";
|
||||
else
|
||||
description += e.FormatException();
|
||||
return dialogForm.Show(SystemIcons.Warning, description, "Retry", "OK");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue