reformatting
This commit is contained in:
parent
3a2d2f9e01
commit
4927a079c7
35 changed files with 1138 additions and 455 deletions
|
@ -23,17 +23,20 @@ internal sealed class ContextMenuItem : ToolStripMenuItem
|
||||||
internal ContextMenuItem(string text, string imageIdentifier, EventHandler onClick = null) : this(text, onClick)
|
internal ContextMenuItem(string text, string imageIdentifier, EventHandler onClick = null) : this(text, onClick)
|
||||||
=> _ = TryImageIdentifier(this, imageIdentifier);
|
=> _ = TryImageIdentifier(this, imageIdentifier);
|
||||||
|
|
||||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, EventHandler onClick = null) : this(text, onClick)
|
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, EventHandler onClick = null)
|
||||||
|
: this(text, onClick)
|
||||||
=> _ = TryImageIdentifierInfo(this, imageIdentifierInfo);
|
=> _ = TryImageIdentifierInfo(this, imageIdentifierInfo);
|
||||||
|
|
||||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, string imageIdentifierFallback, EventHandler onClick = null) :
|
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo,
|
||||||
|
string imageIdentifierFallback, EventHandler onClick = null) :
|
||||||
this(text, onClick)
|
this(text, onClick)
|
||||||
{
|
{
|
||||||
async void OnFail() => await TryImageIdentifier(this, imageIdentifierFallback);
|
async void OnFail() => await TryImageIdentifier(this, imageIdentifierFallback);
|
||||||
_ = TryImageIdentifierInfo(this, imageIdentifierInfo, OnFail);
|
_ = TryImageIdentifierInfo(this, imageIdentifierInfo, OnFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, (string id, string iconUrl) imageIdentifierInfoFallback,
|
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo,
|
||||||
|
(string id, string iconUrl) imageIdentifierInfoFallback,
|
||||||
EventHandler onClick = null) : this(text, onClick)
|
EventHandler onClick = null) : this(text, onClick)
|
||||||
{
|
{
|
||||||
async void OnFail() => await TryImageIdentifierInfo(this, imageIdentifierInfoFallback);
|
async void OnFail() => await TryImageIdentifierInfo(this, imageIdentifierInfoFallback);
|
||||||
|
@ -56,6 +59,7 @@ internal sealed class ContextMenuItem : ToolStripMenuItem
|
||||||
image = file.GetFileIconImage();
|
image = file.GetFileIconImage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "Notepad":
|
case "Notepad":
|
||||||
image = IconGrabber.GetNotepadImage();
|
image = IconGrabber.GetNotepadImage();
|
||||||
|
@ -67,26 +71,33 @@ internal sealed class ContextMenuItem : ToolStripMenuItem
|
||||||
image = IconGrabber.GetFileExplorerImage();
|
image = IconGrabber.GetFileExplorerImage();
|
||||||
break;
|
break;
|
||||||
case "SteamDB":
|
case "SteamDB":
|
||||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("steamdb.info"));
|
image = await HttpClientManager.GetImageFromUrl(
|
||||||
|
IconGrabber.GetDomainFaviconUrl("steamdb.info"));
|
||||||
break;
|
break;
|
||||||
case "Steam Store":
|
case "Steam Store":
|
||||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("store.steampowered.com"));
|
image = await HttpClientManager.GetImageFromUrl(
|
||||||
|
IconGrabber.GetDomainFaviconUrl("store.steampowered.com"));
|
||||||
break;
|
break;
|
||||||
case "Steam Community":
|
case "Steam Community":
|
||||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("steamcommunity.com"));
|
image = await HttpClientManager.GetImageFromUrl(
|
||||||
|
IconGrabber.GetDomainFaviconUrl("steamcommunity.com"));
|
||||||
break;
|
break;
|
||||||
case "ScreamDB":
|
case "ScreamDB":
|
||||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("scream-db.web.app"));
|
image = await HttpClientManager.GetImageFromUrl(
|
||||||
|
IconGrabber.GetDomainFaviconUrl("scream-db.web.app"));
|
||||||
break;
|
break;
|
||||||
case "Epic Games":
|
case "Epic Games":
|
||||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("epicgames.com"));
|
image = await HttpClientManager.GetImageFromUrl(
|
||||||
|
IconGrabber.GetDomainFaviconUrl("epicgames.com"));
|
||||||
break;
|
break;
|
||||||
case "Ubisoft Store":
|
case "Ubisoft Store":
|
||||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("store.ubi.com"));
|
image = await HttpClientManager.GetImageFromUrl(
|
||||||
|
IconGrabber.GetDomainFaviconUrl("store.ubi.com"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image is not null)
|
if (image is not null)
|
||||||
{
|
{
|
||||||
Images[imageIdentifier] = image;
|
Images[imageIdentifier] = image;
|
||||||
|
@ -95,7 +106,8 @@ internal sealed class ContextMenuItem : ToolStripMenuItem
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
private static async Task TryImageIdentifierInfo(ContextMenuItem item, (string id, string iconUrl) imageIdentifierInfo, Action onFail = null)
|
private static async Task TryImageIdentifierInfo(ContextMenuItem item,
|
||||||
|
(string id, string iconUrl) imageIdentifierInfo, Action onFail = null)
|
||||||
=> await Task.Run(async () =>
|
=> await Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -50,33 +50,34 @@ internal class CustomForm : Form
|
||||||
string repository = $"https://github.com/{Program.RepositoryOwner}/{Program.RepositoryName}";
|
string repository = $"https://github.com/{Program.RepositoryOwner}/{Program.RepositoryName}";
|
||||||
_ = helpDialog.Show(SystemIcons.Information,
|
_ = 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"
|
"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"
|
+ "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 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"
|
+ $"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"
|
+ "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"
|
+ " 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"
|
+ " 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"
|
+ " 3. Wait for the program to gather and cache the chosen games' information && DLCs.\n"
|
||||||
+ " May take some time on the first run; depends on how many DLCs the games you chose have.\n"
|
+ " May take some time on the first run; depends on how many DLCs the games you chose have.\n"
|
||||||
+ " 4. CAREFULLY select which games' DLCs you wish to unlock.\n"
|
+ " 4. CAREFULLY select which games' DLCs you wish to unlock.\n"
|
||||||
+ " Obviously none of the DLC unlockers are tested for every single game!\n"
|
+ " Obviously none of the DLC unlockers are tested for every single game!\n"
|
||||||
+ " 5. Choose whether or not to install with Koaloader, and if so then also pick the proxy DLL to use.\n"
|
+ " 5. Choose whether or not to install with Koaloader, and if so then also pick the proxy DLL to use.\n"
|
||||||
+ " 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"
|
+ " 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"
|
+ " 6. Click the \"Generate and Install\" button.\n" +
|
||||||
+ " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\n"
|
" 7. Click the \"OK\" button to close the program.\n"
|
||||||
+ " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n\n"
|
+ " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\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"
|
+ " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n\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"
|
+ "NOTE: This program does not automatically download nor install actual DLC files for you; as the title of the program states, this program\n"
|
||||||
+ "a good majority of games, you must find, download and install those to the game yourself. This process includes manually installing new\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"
|
||||||
+ "DLCs and manually updating the previously manually installed DLCs after game updates.\n\n"
|
+ "a good majority of games, you must find, download and install those to the game yourself. This process includes manually installing new\n"
|
||||||
+ $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n\n"
|
+ "DLCs and manually updating the previously manually installed DLCs after game updates.\n\n"
|
||||||
+ $"HOWEVER: Please read the [FAQ entry]({repository}#faq--common-issues) and/or [template issue]({repository}/issues/new/choose) corresponding to your problem should one exist! Also, note that the [GitHub Issues]({repository}/issues)\n"
|
+ $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n\n"
|
||||||
+ "page is not your personal assistance hotline, rather it is for genuine bugs/crashes/issues with the program itself. If you post an issue which\n"
|
+ $"HOWEVER: Please read the [FAQ entry]({repository}#faq--common-issues) and/or [template issue]({repository}/issues/new/choose) corresponding to your problem should one exist! Also, note that the [GitHub Issues]({repository}/issues)\n"
|
||||||
+ "has already been explained within the FAQ, template issues, and/or within this text in general, I will just close it and you will be ignored.\n\n"
|
+ "page is not your personal assistance hotline, rather it is for genuine bugs/crashes/issues with the program itself. If you post an issue which\n"
|
||||||
+ "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n"
|
+ "has already been explained within the FAQ, template issues, and/or within this text in general, I will just close it and you will be ignored.\n\n"
|
||||||
+ $"The program automatically and very quickly updates from [GitHub]({repository}) by choice of the user through a dialog on startup.\n"
|
+ "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n"
|
||||||
+ $"The program source and other information can be found on [GitHub]({repository}).");
|
+ $"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}).");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnActivation(object sender, EventArgs args) => Activate();
|
private void OnActivation(object sender, EventArgs args) => Activate();
|
||||||
|
@ -85,10 +86,12 @@ internal class CustomForm : Form
|
||||||
{
|
{
|
||||||
bool topMost = TopMost;
|
bool topMost = TopMost;
|
||||||
NativeImports.SetWindowPos(Handle, NativeImports.HWND_TOPMOST, 0, 0, 0, 0,
|
NativeImports.SetWindowPos(Handle, NativeImports.HWND_TOPMOST, 0, 0, 0, 0,
|
||||||
NativeImports.SWP_NOACTIVATE | NativeImports.SWP_SHOWWINDOW | NativeImports.SWP_NOMOVE | NativeImports.SWP_NOSIZE);
|
NativeImports.SWP_NOACTIVATE | NativeImports.SWP_SHOWWINDOW | NativeImports.SWP_NOMOVE |
|
||||||
|
NativeImports.SWP_NOSIZE);
|
||||||
if (!topMost)
|
if (!topMost)
|
||||||
NativeImports.SetWindowPos(Handle, NativeImports.HWND_NOTOPMOST, 0, 0, 0, 0,
|
NativeImports.SetWindowPos(Handle, NativeImports.HWND_NOTOPMOST, 0, 0, 0, 0,
|
||||||
NativeImports.SWP_NOACTIVATE | NativeImports.SWP_SHOWWINDOW | NativeImports.SWP_NOMOVE | NativeImports.SWP_NOSIZE);
|
NativeImports.SWP_NOACTIVATE | NativeImports.SWP_SHOWWINDOW | NativeImports.SWP_NOMOVE |
|
||||||
|
NativeImports.SWP_NOSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InheritLocation(Form fromForm)
|
internal void InheritLocation(Form fromForm)
|
||||||
|
|
|
@ -94,6 +94,7 @@ internal sealed class CustomTreeView : TreeView
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
text = platform.ToString();
|
text = platform.ToString();
|
||||||
|
|
||||||
Size size = TextRenderer.MeasureText(graphics, text, font);
|
Size size = TextRenderer.MeasureText(graphics, text, font);
|
||||||
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width };
|
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width };
|
||||||
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||||
|
@ -111,11 +112,13 @@ internal sealed class CustomTreeView : TreeView
|
||||||
size = TextRenderer.MeasureText(graphics, text, font);
|
size = TextRenderer.MeasureText(graphics, text, font);
|
||||||
const int left = -4;
|
const int left = -4;
|
||||||
bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width };
|
bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width };
|
||||||
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
selectionBounds = new(selectionBounds.Location,
|
||||||
|
selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||||
graphics.FillRectangle(brush, bounds);
|
graphics.FillRectangle(brush, bounds);
|
||||||
point = new(bounds.Location.X - 1, bounds.Location.Y + 1);
|
point = new(bounds.Location.X - 1, bounds.Location.Y + 1);
|
||||||
TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.Default);
|
TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (form is SelectForm)
|
if (form is SelectForm)
|
||||||
{
|
{
|
||||||
Selection selection = Selection.FromId(platform, id);
|
Selection selection = Selection.FromId(platform, id);
|
||||||
|
@ -127,6 +130,7 @@ internal sealed class CustomTreeView : TreeView
|
||||||
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width };
|
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width };
|
||||||
graphics.FillRectangle(brush, bounds);
|
graphics.FillRectangle(brush, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBoxState checkBoxState = selection.Koaloader
|
CheckBoxState checkBoxState = selection.Koaloader
|
||||||
? Enabled ? CheckBoxState.CheckedPressed : CheckBoxState.CheckedDisabled
|
? Enabled ? CheckBoxState.CheckedPressed : CheckBoxState.CheckedDisabled
|
||||||
: Enabled
|
: Enabled
|
||||||
|
@ -151,21 +155,25 @@ internal sealed class CustomTreeView : TreeView
|
||||||
this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds);
|
this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds);
|
||||||
if (selection.Koaloader)
|
if (selection.Koaloader)
|
||||||
{
|
{
|
||||||
comboBoxFont ??= new(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
|
comboBoxFont ??= new(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet,
|
||||||
|
font.GdiVerticalFont);
|
||||||
ComboBoxState comboBoxState = Enabled ? ComboBoxState.Normal : ComboBoxState.Disabled;
|
ComboBoxState comboBoxState = Enabled ? ComboBoxState.Normal : ComboBoxState.Disabled;
|
||||||
text = (selection.KoaloaderProxy ?? Selection.DefaultKoaloaderProxy) + ".dll";
|
text = (selection.KoaloaderProxy ?? Selection.DefaultKoaloaderProxy) + ".dll";
|
||||||
size = TextRenderer.MeasureText(graphics, text, comboBoxFont) + new Size(6, 0);
|
size = TextRenderer.MeasureText(graphics, text, comboBoxFont) + new Size(6, 0);
|
||||||
const int padding = 2;
|
const int padding = 2;
|
||||||
bounds = new(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width, bounds.Height - padding);
|
bounds = new(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width, bounds.Height - padding);
|
||||||
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
selectionBounds = new(selectionBounds.Location,
|
||||||
|
selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||||
Rectangle comboBoxBounds = bounds;
|
Rectangle comboBoxBounds = bounds;
|
||||||
graphics.FillRectangle(backBrush, bounds);
|
graphics.FillRectangle(backBrush, bounds);
|
||||||
ComboBoxRenderer.DrawTextBox(graphics, bounds, text, comboBoxFont, comboBoxState);
|
ComboBoxRenderer.DrawTextBox(graphics, bounds, text, comboBoxFont, comboBoxState);
|
||||||
size = new(14, 0);
|
size = new(14, 0);
|
||||||
left = -1;
|
left = -1;
|
||||||
bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width };
|
bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width };
|
||||||
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
selectionBounds = new(selectionBounds.Location,
|
||||||
comboBoxBounds = new(comboBoxBounds.Location, comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0));
|
selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||||
|
comboBoxBounds = new(comboBoxBounds.Location,
|
||||||
|
comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||||
ComboBoxRenderer.DrawDropDownButton(graphics, bounds, comboBoxState);
|
ComboBoxRenderer.DrawDropDownButton(graphics, bounds, comboBoxState);
|
||||||
this.comboBoxBounds[selection] = RectangleToClient(comboBoxBounds);
|
this.comboBoxBounds[selection] = RectangleToClient(comboBoxBounds);
|
||||||
}
|
}
|
||||||
|
@ -173,6 +181,7 @@ internal sealed class CustomTreeView : TreeView
|
||||||
_ = comboBoxBounds.Remove(selection);
|
_ = comboBoxBounds.Remove(selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectionBounds[node] = RectangleToClient(selectionBounds);
|
this.selectionBounds[node] = RectangleToClient(selectionBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +201,7 @@ internal sealed class CustomTreeView : TreeView
|
||||||
selectForm.OnNodeRightClick(pair.Key, e.Location);
|
selectForm.OnNodeRightClick(pair.Key, e.Location);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Button is not MouseButtons.Left)
|
if (e.Button is not MouseButtons.Left)
|
||||||
return;
|
return;
|
||||||
if (comboBoxBounds.Count > 0 && selectForm is not null)
|
if (comboBoxBounds.Count > 0 && selectForm is not null)
|
||||||
|
@ -200,11 +210,12 @@ internal sealed class CustomTreeView : TreeView
|
||||||
_ = comboBoxBounds.Remove(pair.Key);
|
_ = comboBoxBounds.Remove(pair.Key);
|
||||||
else if (pair.Value.Contains(clickPoint))
|
else if (pair.Value.Contains(clickPoint))
|
||||||
{
|
{
|
||||||
HashSet<string> proxies = EmbeddedResources.Where(r => r.StartsWith("Koaloader", StringComparison.Ordinal)).Select(p =>
|
HashSet<string> proxies = EmbeddedResources
|
||||||
{
|
.Where(r => r.StartsWith("Koaloader", StringComparison.Ordinal)).Select(p =>
|
||||||
p.GetProxyInfoFromIdentifier(out string proxyName, out _);
|
{
|
||||||
return proxyName;
|
p.GetProxyInfoFromIdentifier(out string proxyName, out _);
|
||||||
}).ToHashSet();
|
return proxyName;
|
||||||
|
}).ToHashSet();
|
||||||
comboBoxDropDown ??= new();
|
comboBoxDropDown ??= new();
|
||||||
comboBoxDropDown.ShowItemToolTips = false;
|
comboBoxDropDown.ShowItemToolTips = false;
|
||||||
comboBoxDropDown.Items.Clear();
|
comboBoxDropDown.Items.Clear();
|
||||||
|
@ -219,6 +230,7 @@ internal sealed class CustomTreeView : TreeView
|
||||||
canUse = false;
|
canUse = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canUse)
|
if (canUse)
|
||||||
_ = comboBoxDropDown.Items.Add(new ToolStripButton(proxy + ".dll", null, (_, _) =>
|
_ = comboBoxDropDown.Items.Add(new ToolStripButton(proxy + ".dll", null, (_, _) =>
|
||||||
{
|
{
|
||||||
|
@ -226,9 +238,11 @@ internal sealed class CustomTreeView : TreeView
|
||||||
selectForm.OnKoaloaderChanged();
|
selectForm.OnKoaloaderChanged();
|
||||||
}) { Font = comboBoxFont });
|
}) { Font = comboBoxFont });
|
||||||
}
|
}
|
||||||
|
|
||||||
comboBoxDropDown.Show(this, PointToScreen(new(pair.Value.Left, pair.Value.Bottom - 1)));
|
comboBoxDropDown.Show(this, PointToScreen(new(pair.Value.Left, pair.Value.Bottom - 1)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (KeyValuePair<Selection, Rectangle> pair in checkBoxBounds)
|
foreach (KeyValuePair<Selection, Rectangle> pair in checkBoxBounds)
|
||||||
if (!Selection.All.ContainsKey(pair.Key))
|
if (!Selection.All.ContainsKey(pair.Key))
|
||||||
_ = checkBoxBounds.Remove(pair.Key);
|
_ = checkBoxBounds.Remove(pair.Key);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
|
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
|
||||||
<UseWindowsForms>True</UseWindowsForms>
|
<UseWindowsForms>True</UseWindowsForms>
|
||||||
<ApplicationIcon>Resources\program.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\program.ico</ApplicationIcon>
|
||||||
<Version>4.10.1</Version>
|
<Version>4.10.2</Version>
|
||||||
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
|
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
|
||||||
<Company>CreamInstaller</Company>
|
<Company>CreamInstaller</Company>
|
||||||
<Product>Automatic DLC Unlocker Installer & Configuration Generator</Product>
|
<Product>Automatic DLC Unlocker Installer & Configuration Generator</Product>
|
||||||
|
|
|
@ -36,6 +36,7 @@ internal sealed partial class DebugForm : CustomForm
|
||||||
if (command == 0xF010) // SC_MOVE
|
if (command == 0xF010) // SC_MOVE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.WndProc(ref message);
|
base.WndProc(ref message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ internal sealed partial class DebugForm : CustomForm
|
||||||
attachedForm.SizeChanged -= OnChange;
|
attachedForm.SizeChanged -= OnChange;
|
||||||
attachedForm.VisibleChanged -= OnChange;
|
attachedForm.VisibleChanged -= OnChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
attachedForm = form;
|
attachedForm = form;
|
||||||
attachedForm.Activated += OnChange;
|
attachedForm.Activated += OnChange;
|
||||||
attachedForm.LocationChanged += OnChange;
|
attachedForm.LocationChanged += OnChange;
|
||||||
|
|
|
@ -11,7 +11,8 @@ internal sealed partial class DialogForm : CustomForm
|
||||||
{
|
{
|
||||||
internal DialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
|
internal DialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
|
||||||
|
|
||||||
internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText = "OK", string cancelButtonText = null,
|
internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText = "OK",
|
||||||
|
string cancelButtonText = null,
|
||||||
string customFormText = null, Icon customFormIcon = null)
|
string customFormText = null, Icon customFormIcon = null)
|
||||||
{
|
{
|
||||||
descriptionIcon ??= Icon;
|
descriptionIcon ??= Icon;
|
||||||
|
@ -33,6 +34,7 @@ internal sealed partial class DialogForm : CustomForm
|
||||||
descriptionText = descriptionText.Remove(i, linkRight + 1 - i).Insert(i, text);
|
descriptionText = descriptionText.Remove(i, linkRight + 1 - i).Insert(i, text);
|
||||||
links.Add(new(i, text.Length, link));
|
links.Add(new(i, text.Length, link));
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptionLabel.Text = descriptionText;
|
descriptionLabel.Text = descriptionText;
|
||||||
acceptButton.Text = acceptButtonText;
|
acceptButton.Text = acceptButtonText;
|
||||||
if (cancelButtonText is null)
|
if (cancelButtonText is null)
|
||||||
|
@ -42,6 +44,7 @@ internal sealed partial class DialogForm : CustomForm
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cancelButton.Text = cancelButtonText;
|
cancelButton.Text = cancelButtonText;
|
||||||
|
|
||||||
if (customFormText is not null)
|
if (customFormText is not null)
|
||||||
Text = customFormText;
|
Text = customFormText;
|
||||||
else
|
else
|
||||||
|
@ -49,6 +52,7 @@ internal sealed partial class DialogForm : CustomForm
|
||||||
OnResize(null, null);
|
OnResize(null, null);
|
||||||
Resize += OnResize;
|
Resize += OnResize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customFormIcon is not null)
|
if (customFormIcon is not null)
|
||||||
Icon = customFormIcon;
|
Icon = customFormIcon;
|
||||||
if (links.Count < 1)
|
if (links.Count < 1)
|
||||||
|
@ -65,6 +69,8 @@ internal sealed partial class DialogForm : CustomForm
|
||||||
|
|
||||||
private void OnResize(object s, EventArgs e)
|
private void OnResize(object s, EventArgs e)
|
||||||
=> Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100
|
=> Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100
|
||||||
? TextRenderer.MeasureText(Program.ApplicationNameShort, Font).Width > Size.Width - 100 ? Program.Name : Program.ApplicationNameShort
|
? TextRenderer.MeasureText(Program.ApplicationNameShort, Font).Width > Size.Width - 100
|
||||||
|
? Program.Name
|
||||||
|
: Program.ApplicationNameShort
|
||||||
: Program.ApplicationName;
|
: Program.ApplicationName;
|
||||||
}
|
}
|
|
@ -63,11 +63,14 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
UpdateUser("Repairing Paradox Launcher . . . ", LogTextBox.Operation);
|
UpdateUser("Repairing Paradox Launcher . . . ", LogTextBox.Operation);
|
||||||
_ = await Repair(this, selection);
|
_ = await Repair(this, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
$"{(uninstalling ? "Uninstalling" : "Installing")}" + $" {(uninstalling ? "from" : "for")} " + selection.Name
|
$"{(uninstalling ? "Uninstalling" : "Installing")}" + $" {(uninstalling ? "from" : "for")} " +
|
||||||
+ $" with root directory \"{selection.RootDirectory}\" . . . ", LogTextBox.Operation);
|
selection.Name
|
||||||
|
+ $" with root directory \"{selection.RootDirectory}\" . . . ", LogTextBox.Operation);
|
||||||
IEnumerable<string> invalidDirectories = (await selection.RootDirectory.GetExecutables())
|
IEnumerable<string> invalidDirectories = (await selection.RootDirectory.GetExecutables())
|
||||||
?.Where(d => selection.ExecutableDirectories.All(s => s.directory != Path.GetDirectoryName(d.path))).Select(d => Path.GetDirectoryName(d.path));
|
?.Where(d => selection.ExecutableDirectories.All(s => s.directory != Path.GetDirectoryName(d.path)))
|
||||||
|
.Select(d => Path.GetDirectoryName(d.path));
|
||||||
if (selection.ExecutableDirectories.All(s => s.directory != selection.RootDirectory))
|
if (selection.ExecutableDirectories.All(s => s.directory != selection.RootDirectory))
|
||||||
invalidDirectories = invalidDirectories?.Append(selection.RootDirectory);
|
invalidDirectories = invalidDirectories?.Append(selection.RootDirectory);
|
||||||
invalidDirectories = invalidDirectories?.Distinct();
|
invalidDirectories = invalidDirectories?.Distinct();
|
||||||
|
@ -77,27 +80,37 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
directory.GetKoaloaderComponents(out string old_config, out string config);
|
directory.GetKoaloaderComponents(out string old_config, out string config);
|
||||||
if (directory.GetKoaloaderProxies().Any(proxy => proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|
if (directory.GetKoaloaderProxies().Any(proxy =>
|
||||||
|| directory != selection.RootDirectory && Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists())
|
proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||||
|| old_config.FileExists() || config.FileExists())
|
|| directory != selection.RootDirectory &&
|
||||||
|
Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists())
|
||||||
|
|| old_config.FileExists() || config.FileExists())
|
||||||
{
|
{
|
||||||
UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation);
|
UpdateUser(
|
||||||
|
"Uninstalling Koaloader from " + selection.Name +
|
||||||
|
$" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||||
await Koaloader.Uninstall(directory, selection.RootDirectory, this);
|
await Koaloader.Uninstall(directory, selection.RootDirectory, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uninstalling || !selection.Koaloader)
|
if (uninstalling || !selection.Koaloader)
|
||||||
foreach ((string directory, BinaryType _) in selection.ExecutableDirectories)
|
foreach ((string directory, BinaryType _) in selection.ExecutableDirectories)
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
directory.GetKoaloaderComponents(out string old_config, out string config);
|
directory.GetKoaloaderComponents(out string old_config, out string config);
|
||||||
if (directory.GetKoaloaderProxies().Any(proxy => proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|
if (directory.GetKoaloaderProxies().Any(proxy =>
|
||||||
|| Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists()) || old_config.FileExists() || config.FileExists())
|
proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||||
|
|| Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists()) ||
|
||||||
|
old_config.FileExists() || config.FileExists())
|
||||||
{
|
{
|
||||||
UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
UpdateUser(
|
||||||
|
"Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ",
|
||||||
|
LogTextBox.Operation);
|
||||||
await Koaloader.Uninstall(directory, selection.RootDirectory, this);
|
await Koaloader.Uninstall(directory, selection.RootDirectory, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uninstallProxy = uninstalling || selection.Koaloader;
|
bool uninstallProxy = uninstalling || selection.Koaloader;
|
||||||
int count = selection.DllDirectories.Count, cur = 0;
|
int count = selection.DllDirectories.Count, cur = 0;
|
||||||
foreach (string directory in selection.DllDirectories)
|
foreach (string directory in selection.DllDirectories)
|
||||||
|
@ -106,77 +119,93 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
return;
|
return;
|
||||||
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
||||||
{
|
{
|
||||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config,
|
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string old_config,
|
||||||
out string config, out string old_log, out string log, out string cache);
|
out string config, out string old_log, out string log, out string cache);
|
||||||
if (uninstallProxy
|
if (uninstallProxy
|
||||||
? api32_o.FileExists() || api64_o.FileExists() || old_config.FileExists() || config.FileExists() || old_log.FileExists() || log.FileExists()
|
? api32_o.FileExists() || api64_o.FileExists() || old_config.FileExists() ||
|
||||||
|| cache.FileExists()
|
config.FileExists() || old_log.FileExists() || log.FileExists()
|
||||||
: api32.FileExists() || api64.FileExists())
|
|| cache.FileExists()
|
||||||
|
: api32.FileExists() || api64.FileExists())
|
||||||
{
|
{
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
$"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" +
|
||||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||||
|
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||||
if (uninstallProxy)
|
if (uninstallProxy)
|
||||||
await SmokeAPI.Uninstall(directory, this);
|
await SmokeAPI.Uninstall(directory, this);
|
||||||
else
|
else
|
||||||
await SmokeAPI.Install(directory, selection, this);
|
await SmokeAPI.Install(directory, selection, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
||||||
{
|
{
|
||||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log);
|
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string config, out string log);
|
||||||
if (uninstallProxy
|
if (uninstallProxy
|
||||||
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
|
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
|
||||||
: api32.FileExists() || api64.FileExists())
|
: api32.FileExists() || api64.FileExists())
|
||||||
{
|
{
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
$"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" +
|
||||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||||
|
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||||
if (uninstallProxy)
|
if (uninstallProxy)
|
||||||
await ScreamAPI.Uninstall(directory, this);
|
await ScreamAPI.Uninstall(directory, this);
|
||||||
else
|
else
|
||||||
await ScreamAPI.Install(directory, selection, this);
|
await ScreamAPI.Install(directory, selection, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.Platform is Platform.Ubisoft)
|
if (selection.Platform is Platform.Ubisoft)
|
||||||
{
|
{
|
||||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log);
|
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string config, out string log);
|
||||||
if (uninstallProxy
|
if (uninstallProxy
|
||||||
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
|
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
|
||||||
: api32.FileExists() || api64.FileExists())
|
: api32.FileExists() || api64.FileExists())
|
||||||
{
|
{
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
$"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" +
|
||||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||||
|
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||||
if (uninstallProxy)
|
if (uninstallProxy)
|
||||||
await UplayR1.Uninstall(directory, this);
|
await UplayR1.Uninstall(directory, this);
|
||||||
else
|
else
|
||||||
await UplayR1.Install(directory, selection, this);
|
await UplayR1.Install(directory, selection, this);
|
||||||
}
|
}
|
||||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, out log);
|
|
||||||
|
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 (uninstallProxy
|
if (uninstallProxy
|
||||||
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
|
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
|
||||||
: old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api64.FileExists())
|
: old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api64.FileExists())
|
||||||
{
|
{
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
$"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" +
|
||||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||||
|
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||||
if (uninstallProxy)
|
if (uninstallProxy)
|
||||||
await UplayR2.Uninstall(directory, this);
|
await UplayR2.Uninstall(directory, this);
|
||||||
else
|
else
|
||||||
await UplayR2.Install(directory, selection, this);
|
await UplayR2.Install(directory, selection, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateProgress(++cur / count * 100);
|
UpdateProgress(++cur / count * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.Koaloader && !uninstalling)
|
if (selection.Koaloader && !uninstalling)
|
||||||
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
|
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
UpdateUser("Installing Koaloader to " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
UpdateUser("Installing Koaloader to " + selection.Name + $" in directory \"{directory}\" . . . ",
|
||||||
|
LogTextBox.Operation);
|
||||||
await Koaloader.Install(directory, binaryType, selection, selection.RootDirectory, this);
|
await Koaloader.Install(directory, binaryType, selection, selection.RootDirectory, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateProgress(100);
|
UpdateProgress(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,8 +229,10 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
{
|
{
|
||||||
UpdateUser($"Operation failed for {selection.Name}: " + exception, LogTextBox.Error);
|
UpdateUser($"Operation failed for {selection.Name}: " + exception, LogTextBox.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
++completeOperationsCount;
|
++completeOperationsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.Cleanup();
|
Program.Cleanup();
|
||||||
int activeCount = activeSelections.Count;
|
int activeCount = activeSelections.Count;
|
||||||
if (activeCount > 0)
|
if (activeCount > 0)
|
||||||
|
@ -222,14 +253,19 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Operate();
|
await Operate();
|
||||||
UpdateUser($"DLC unlocker(s) successfully {(uninstalling ? "uninstalled" : "installed and generated")} for " + selectionCount + " program(s).",
|
UpdateUser(
|
||||||
|
$"DLC unlocker(s) successfully {(uninstalling ? "uninstalled" : "installed and generated")} for " +
|
||||||
|
selectionCount + " program(s).",
|
||||||
LogTextBox.Success);
|
LogTextBox.Success);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
UpdateUser($"DLC unlocker {(uninstalling ? "uninstallation" : "installation and/or generation")} failed: " + exception, LogTextBox.Error);
|
UpdateUser(
|
||||||
|
$"DLC unlocker {(uninstalling ? "uninstallation" : "installation and/or generation")} failed: " +
|
||||||
|
exception, LogTextBox.Error);
|
||||||
retryButton.Enabled = true;
|
retryButton.Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
userProgressBar.Value = userProgressBar.Maximum;
|
userProgressBar.Value = userProgressBar.Maximum;
|
||||||
acceptButton.Enabled = true;
|
acceptButton.Enabled = true;
|
||||||
cancelButton.Enabled = false;
|
cancelButton.Enabled = false;
|
||||||
|
@ -238,7 +274,7 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
|
|
||||||
private void OnLoad(object sender, EventArgs a)
|
private void OnLoad(object sender, EventArgs a)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
userInfoLabel.Text = "Loading . . . ";
|
userInfoLabel.Text = "Loading . . . ";
|
||||||
|
@ -249,6 +285,7 @@ internal sealed partial class InstallForm : CustomForm
|
||||||
selectionCount++;
|
selectionCount++;
|
||||||
_ = activeSelections.Add(selection);
|
_ = activeSelections.Add(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -12,7 +12,8 @@ internal sealed partial class SelectDialogForm : CustomForm
|
||||||
private readonly List<(Platform platform, string id, string name)> selected = new();
|
private readonly List<(Platform platform, string id, string name)> selected = new();
|
||||||
internal SelectDialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
|
internal SelectDialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
|
||||||
|
|
||||||
internal DialogResult QueryUser(string groupBoxText, List<(Platform platform, string id, string name, bool alreadySelected)> potentialChoices,
|
internal DialogResult QueryUser(string groupBoxText,
|
||||||
|
List<(Platform platform, string id, string name, bool alreadySelected)> potentialChoices,
|
||||||
out List<(Platform platform, string id, string name)> choices)
|
out List<(Platform platform, string id, string name)> choices)
|
||||||
{
|
{
|
||||||
choices = null;
|
choices = null;
|
||||||
|
@ -28,6 +29,7 @@ internal sealed partial class SelectDialogForm : CustomForm
|
||||||
OnTreeNodeChecked(node);
|
OnTreeNodeChecked(node);
|
||||||
_ = selectionTreeView.Nodes.Add(node);
|
_ = selectionTreeView.Nodes.Add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected.Count < 1)
|
if (selected.Count < 1)
|
||||||
OnLoad(null, null);
|
OnLoad(null, null);
|
||||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||||
|
@ -64,10 +66,13 @@ internal sealed partial class SelectDialogForm : CustomForm
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnResize(object s, EventArgs e)
|
private void OnResize(object s, EventArgs e)
|
||||||
=> Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100 ? Program.ApplicationNameShort : Program.ApplicationName;
|
=> Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100
|
||||||
|
? Program.ApplicationNameShort
|
||||||
|
: Program.ApplicationName;
|
||||||
|
|
||||||
private void OnSortCheckBoxChanged(object sender, EventArgs e)
|
private void OnSortCheckBoxChanged(object sender, EventArgs e)
|
||||||
=> selectionTreeView.TreeViewNodeSorter = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName;
|
=> selectionTreeView.TreeViewNodeSorter =
|
||||||
|
sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName;
|
||||||
|
|
||||||
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +82,7 @@ internal sealed partial class SelectDialogForm : CustomForm
|
||||||
node.Checked = shouldCheck;
|
node.Checked = shouldCheck;
|
||||||
OnTreeNodeChecked(node);
|
OnTreeNodeChecked(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||||
allCheckBox.Checked = shouldCheck;
|
allCheckBox.Checked = shouldCheck;
|
||||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||||
|
@ -96,7 +102,8 @@ internal sealed partial class SelectDialogForm : CustomForm
|
||||||
|
|
||||||
private void OnSave(object sender, EventArgs e)
|
private void OnSave(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ProgramData.WriteProgramChoices(selectionTreeView.Nodes.Cast<TreeNode>().Where(n => n.Checked).Select(node => ((Platform)node.Tag, node.Name)));
|
ProgramData.WriteProgramChoices(selectionTreeView.Nodes.Cast<TreeNode>().Where(n => n.Checked)
|
||||||
|
.Select(node => ((Platform)node.Tag, node.Name)));
|
||||||
loadButton.Enabled = ProgramData.ReadProgramChoices() is not null;
|
loadButton.Enabled = ProgramData.ReadProgramChoices() is not null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,7 +50,9 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateRemaining(Label label, ConcurrentDictionary<string, string> list, string descriptor)
|
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("&", "&&");
|
=> label.Text = list.IsEmpty
|
||||||
|
? ""
|
||||||
|
: $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list.Values).Replace("&", "&&");
|
||||||
|
|
||||||
private void UpdateRemainingGames() => UpdateRemaining(progressLabelGames, remainingGames, "games");
|
private void UpdateRemainingGames() => UpdateRemaining(progressLabelGames, remainingGames, "games");
|
||||||
|
|
||||||
|
@ -114,17 +116,20 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
return;
|
return;
|
||||||
int totalGameCount = 0;
|
int totalGameCount = 0;
|
||||||
int completeGameCount = 0;
|
int completeGameCount = 0;
|
||||||
|
|
||||||
void AddToRemainingGames(string gameName)
|
void AddToRemainingGames(string gameName)
|
||||||
{
|
{
|
||||||
this.AddToRemainingGames(gameName);
|
this.AddToRemainingGames(gameName);
|
||||||
progress.Report(-Interlocked.Increment(ref totalGameCount));
|
progress.Report(-Interlocked.Increment(ref totalGameCount));
|
||||||
progress.Report(completeGameCount);
|
progress.Report(completeGameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveFromRemainingGames(string gameName)
|
void RemoveFromRemainingGames(string gameName)
|
||||||
{
|
{
|
||||||
this.RemoveFromRemainingGames(gameName);
|
this.RemoveFromRemainingGames(gameName);
|
||||||
progress.Report(Interlocked.Increment(ref completeGameCount));
|
progress.Report(Interlocked.Increment(ref completeGameCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
remainingGames.Clear(); // for display purposes only, otherwise ignorable
|
remainingGames.Clear(); // for display purposes only, otherwise ignorable
|
||||||
|
@ -133,11 +138,14 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Paradox))
|
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Paradox))
|
||||||
{
|
{
|
||||||
AddToRemainingGames("Paradox Launcher");
|
AddToRemainingGames("Paradox Launcher");
|
||||||
HashSet<string> dllDirectories = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox);
|
HashSet<string> dllDirectories =
|
||||||
|
await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox);
|
||||||
if (dllDirectories is not null)
|
if (dllDirectories is not null)
|
||||||
{
|
{
|
||||||
Selection selection = Selection.GetOrCreate(Platform.Paradox, "PL", "Paradox Launcher", ParadoxLauncher.InstallPath, dllDirectories,
|
Selection selection = Selection.GetOrCreate(Platform.Paradox, "PL", "Paradox Launcher",
|
||||||
await ParadoxLauncher.InstallPath.GetExecutableDirectories(validFunc: path => !Path.GetFileName(path).Contains("bootstrapper")));
|
ParadoxLauncher.InstallPath, dllDirectories,
|
||||||
|
await ParadoxLauncher.InstallPath.GetExecutableDirectories(validFunc: path =>
|
||||||
|
!Path.GetFileName(path).Contains("bootstrapper")));
|
||||||
if (uninstallAll)
|
if (uninstallAll)
|
||||||
selection.Enabled = true;
|
selection.Enabled = true;
|
||||||
else if (selection.TreeNode.TreeView is null)
|
else if (selection.TreeNode.TreeView is null)
|
||||||
|
@ -145,40 +153,48 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
RemoveFromRemainingGames("Paradox Launcher");
|
RemoveFromRemainingGames("Paradox Launcher");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int steamGamesToCheck;
|
int steamGamesToCheck;
|
||||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Steam))
|
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();
|
List<(string appId, string name, string branch, int buildId, string gameDirectory)> steamGames =
|
||||||
|
await SteamLibrary.GetGames();
|
||||||
steamGamesToCheck = steamGames.Count;
|
steamGamesToCheck = steamGames.Count;
|
||||||
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in steamGames)
|
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in steamGames)
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
if (!uninstallAll && (Program.IsGameBlocked(name, gameDirectory) || !programsToScan.Any(c => c.platform is Platform.Steam && c.id == appId)))
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddToRemainingGames(name);
|
AddToRemainingGames(name);
|
||||||
Task task = Task.Run(async () =>
|
Task task = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
HashSet<string> dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam);
|
HashSet<string> dllDirectories =
|
||||||
|
await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam);
|
||||||
if (dllDirectories is null)
|
if (dllDirectories is null)
|
||||||
{
|
{
|
||||||
_ = Interlocked.Decrement(ref steamGamesToCheck);
|
_ = Interlocked.Decrement(ref steamGamesToCheck);
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uninstallAll)
|
if (uninstallAll)
|
||||||
{
|
{
|
||||||
Selection bareSelection = Selection.GetOrCreate(Platform.Steam, appId, name, gameDirectory, dllDirectories,
|
Selection bareSelection = Selection.GetOrCreate(Platform.Steam, appId, name, gameDirectory,
|
||||||
|
dllDirectories,
|
||||||
await gameDirectory.GetExecutableDirectories(true));
|
await gameDirectory.GetExecutableDirectories(true));
|
||||||
bareSelection.Enabled = true;
|
bareSelection.Enabled = true;
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
AppData appData = await SteamStore.QueryStoreAPI(appId);
|
AppData appData = await SteamStore.QueryStoreAPI(appId);
|
||||||
|
@ -189,6 +205,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
ConcurrentDictionary<SelectionDLC, byte> dlc = new();
|
ConcurrentDictionary<SelectionDLC, byte> dlc = new();
|
||||||
|
@ -233,14 +250,20 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
if (dlcAppInfo is not null)
|
if (dlcAppInfo is not null)
|
||||||
{
|
{
|
||||||
dlcName = dlcAppInfo.Value.GetChild("common")?.GetChild("name")?.ToString();
|
dlcName = dlcAppInfo.Value.GetChild("common")?.GetChild("name")?.ToString();
|
||||||
string dlcIconStaticId = dlcAppInfo.Value.GetChild("common")?.GetChild("icon")?.ToString();
|
string dlcIconStaticId = dlcAppInfo.Value.GetChild("common")?.GetChild("icon")
|
||||||
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo_small")?.ToString();
|
?.ToString();
|
||||||
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo")?.ToString();
|
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo_small")
|
||||||
|
?.ToString();
|
||||||
|
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo")
|
||||||
|
?.ToString();
|
||||||
if (dlcIconStaticId is not null)
|
if (dlcIconStaticId is not null)
|
||||||
dlcIcon = IconGrabber.SteamAppImagesPath + @$"\{dlcAppId}\{dlcIconStaticId}.jpg";
|
dlcIcon = IconGrabber.SteamAppImagesPath +
|
||||||
fullGameAppId = dlcAppInfo.Value.GetChild("common")?.GetChild("parent")?.ToString();
|
@$"\{dlcAppId}\{dlcIconStaticId}.jpg";
|
||||||
|
fullGameAppId = dlcAppInfo.Value.GetChild("common")?.GetChild("parent")
|
||||||
|
?.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullGameAppId != null && fullGameAppId != appId)
|
if (fullGameAppId != null && fullGameAppId != appId)
|
||||||
{
|
{
|
||||||
string fullGameName = null;
|
string fullGameName = null;
|
||||||
|
@ -258,29 +281,38 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
VProperty fullGameAppInfo = await SteamCMD.GetAppInfo(fullGameAppId);
|
VProperty fullGameAppInfo = await SteamCMD.GetAppInfo(fullGameAppId);
|
||||||
if (fullGameAppInfo is not null)
|
if (fullGameAppInfo is not null)
|
||||||
{
|
{
|
||||||
fullGameName = fullGameAppInfo.Value.GetChild("common")?.GetChild("name")?.ToString();
|
fullGameName = fullGameAppInfo.Value.GetChild("common")?.GetChild("name")
|
||||||
string fullGameIconStaticId = fullGameAppInfo.Value.GetChild("common")?.GetChild("icon")?.ToString();
|
?.ToString();
|
||||||
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")?.GetChild("logo_small")?.ToString();
|
string fullGameIconStaticId = fullGameAppInfo.Value.GetChild("common")
|
||||||
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")?.GetChild("logo")?.ToString();
|
?.GetChild("icon")?.ToString();
|
||||||
|
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")
|
||||||
|
?.GetChild("logo_small")?.ToString();
|
||||||
|
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")
|
||||||
|
?.GetChild("logo")?.ToString();
|
||||||
if (fullGameIconStaticId is not null)
|
if (fullGameIconStaticId is not null)
|
||||||
dlcIcon = IconGrabber.SteamAppImagesPath + @$"\{fullGameAppId}\{fullGameIconStaticId}.jpg";
|
dlcIcon = IconGrabber.SteamAppImagesPath +
|
||||||
|
@$"\{fullGameAppId}\{fullGameIconStaticId}.jpg";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
if (!string.IsNullOrWhiteSpace(fullGameName))
|
if (!string.IsNullOrWhiteSpace(fullGameName))
|
||||||
{
|
{
|
||||||
SelectionDLC fullGameDlc = SelectionDLC.GetOrCreate(fullGameOnSteamStore ? DLCType.Steam : DLCType.SteamHidden, appId,
|
SelectionDLC fullGameDlc = SelectionDLC.GetOrCreate(
|
||||||
|
fullGameOnSteamStore ? DLCType.Steam : DLCType.SteamHidden, appId,
|
||||||
fullGameAppId, fullGameName);
|
fullGameAppId, fullGameName);
|
||||||
fullGameDlc.Icon = fullGameIcon;
|
fullGameDlc.Icon = fullGameIcon;
|
||||||
_ = dlc.TryAdd(fullGameDlc, default);
|
_ = dlc.TryAdd(fullGameDlc, default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
if (string.IsNullOrWhiteSpace(dlcName))
|
if (string.IsNullOrWhiteSpace(dlcName))
|
||||||
dlcName = "Unknown";
|
dlcName = "Unknown";
|
||||||
SelectionDLC _dlc = SelectionDLC.GetOrCreate(onSteamStore ? DLCType.Steam : DLCType.SteamHidden, appId, dlcAppId, dlcName);
|
SelectionDLC _dlc = SelectionDLC.GetOrCreate(
|
||||||
|
onSteamStore ? DLCType.Steam : DLCType.SteamHidden, appId, dlcAppId, dlcName);
|
||||||
_dlc.Icon = dlcIcon;
|
_dlc.Icon = dlcIcon;
|
||||||
_ = dlc.TryAdd(_dlc, default);
|
_ = dlc.TryAdd(_dlc, default);
|
||||||
RemoveFromRemainingDLCs(dlcAppId);
|
RemoveFromRemainingDLCs(dlcAppId);
|
||||||
|
@ -292,6 +324,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
foreach (Task task in dlcTasks)
|
foreach (Task task in dlcTasks)
|
||||||
|
@ -300,19 +333,24 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
return;
|
return;
|
||||||
await task;
|
await task;
|
||||||
}
|
}
|
||||||
|
|
||||||
steamGamesToCheck = 0;
|
steamGamesToCheck = 0;
|
||||||
if (dlc.IsEmpty)
|
if (dlc.IsEmpty)
|
||||||
{
|
{
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Selection selection = Selection.GetOrCreate(Platform.Steam, appId, appData?.Name ?? name, gameDirectory, dllDirectories,
|
|
||||||
|
Selection selection = Selection.GetOrCreate(Platform.Steam, appId, appData?.Name ?? name,
|
||||||
|
gameDirectory, dllDirectories,
|
||||||
await gameDirectory.GetExecutableDirectories(true));
|
await gameDirectory.GetExecutableDirectories(true));
|
||||||
selection.Product = "https://store.steampowered.com/app/" + appId;
|
selection.Product = "https://store.steampowered.com/app/" + appId;
|
||||||
selection.Icon = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("icon")}.jpg";
|
selection.Icon = IconGrabber.SteamAppImagesPath +
|
||||||
|
@$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("icon")}.jpg";
|
||||||
selection.SubIcon = appData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
|
selection.SubIcon = appData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
|
||||||
+ @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("clienticon")}.ico";
|
+ @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("clienticon")}.ico";
|
||||||
selection.Publisher = appData?.Publishers[0] ?? appInfo?.Value.GetChild("extended")?.GetChild("publisher")?.ToString();
|
selection.Publisher = appData?.Publishers[0] ??
|
||||||
|
appInfo?.Value.GetChild("extended")?.GetChild("publisher")?.ToString();
|
||||||
selection.Website = appData?.Website;
|
selection.Website = appData?.Website;
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
|
@ -336,6 +374,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
appTasks.Add(task);
|
appTasks.Add(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Epic))
|
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Epic))
|
||||||
{
|
{
|
||||||
List<Manifest> epicGames = await EpicLibrary.GetGames();
|
List<Manifest> epicGames = await EpicLibrary.GetGames();
|
||||||
|
@ -346,7 +385,8 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
string directory = manifest.InstallLocation;
|
string directory = manifest.InstallLocation;
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
if (!uninstallAll && (Program.IsGameBlocked(name, directory) || !programsToScan.Any(c => c.platform is Platform.Epic && c.id == @namespace)))
|
if (!uninstallAll && (Program.IsGameBlocked(name, directory) ||
|
||||||
|
!programsToScan.Any(c => c.platform is Platform.Epic && c.id == @namespace)))
|
||||||
continue;
|
continue;
|
||||||
AddToRemainingGames(name);
|
AddToRemainingGames(name);
|
||||||
Task task = Task.Run(async () =>
|
Task task = Task.Run(async () =>
|
||||||
|
@ -359,19 +399,23 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uninstallAll)
|
if (uninstallAll)
|
||||||
{
|
{
|
||||||
Selection bareSelection = Selection.GetOrCreate(Platform.Epic, @namespace, name, directory, dllDirectories,
|
Selection bareSelection = Selection.GetOrCreate(Platform.Epic, @namespace, name, directory,
|
||||||
|
dllDirectories,
|
||||||
await directory.GetExecutableDirectories(true));
|
await directory.GetExecutableDirectories(true));
|
||||||
bareSelection.Enabled = true;
|
bareSelection.Enabled = true;
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
List<Task> dlcTasks = new();
|
List<Task> dlcTasks = new();
|
||||||
ConcurrentDictionary<SelectionDLC, byte> catalogItems = new();
|
ConcurrentDictionary<SelectionDLC, byte> catalogItems = new();
|
||||||
List<(string id, string name, string product, string icon, string developer)> catalogIds = await EpicStore.QueryCatalog(@namespace);
|
List<(string id, string name, string product, string icon, string developer)> catalogIds =
|
||||||
|
await EpicStore.QueryCatalog(@namespace);
|
||||||
if (catalogIds.Count > 0)
|
if (catalogIds.Count > 0)
|
||||||
foreach ((string id, string name, string product, string icon, string developer) in catalogIds)
|
foreach ((string id, string name, string product, string icon, string developer) in catalogIds)
|
||||||
{
|
{
|
||||||
|
@ -391,6 +435,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
});
|
});
|
||||||
dlcTasks.Add(task);
|
dlcTasks.Add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
foreach (Task task in dlcTasks)
|
foreach (Task task in dlcTasks)
|
||||||
|
@ -399,12 +444,15 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
return;
|
return;
|
||||||
await task;
|
await task;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (catalogItems.IsEmpty)
|
if (catalogItems.IsEmpty)
|
||||||
{
|
{
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Selection selection = Selection.GetOrCreate(Platform.Epic, @namespace, name, directory, dllDirectories,
|
|
||||||
|
Selection selection = Selection.GetOrCreate(Platform.Epic, @namespace, name, directory,
|
||||||
|
dllDirectories,
|
||||||
await directory.GetExecutableDirectories(true));
|
await directory.GetExecutableDirectories(true));
|
||||||
foreach ((SelectionDLC dlc, _) in catalogItems.Where(dlc => dlc.Key.Name == selection.Name))
|
foreach ((SelectionDLC dlc, _) in catalogItems.Where(dlc => dlc.Key.Name == selection.Name))
|
||||||
{
|
{
|
||||||
|
@ -414,6 +462,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
selection.Icon = dlc.Icon;
|
selection.Icon = dlc.Icon;
|
||||||
selection.Publisher = dlc.Publisher;
|
selection.Publisher = dlc.Publisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
Invoke(delegate
|
Invoke(delegate
|
||||||
|
@ -438,6 +487,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
appTasks.Add(task);
|
appTasks.Add(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Ubisoft))
|
if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Ubisoft))
|
||||||
{
|
{
|
||||||
List<(string gameId, string name, string gameDirectory)> ubisoftGames = await UbisoftLibrary.GetGames();
|
List<(string gameId, string name, string gameDirectory)> ubisoftGames = await UbisoftLibrary.GetGames();
|
||||||
|
@ -445,30 +495,36 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
if (!uninstallAll && (Program.IsGameBlocked(name, gameDirectory) || !programsToScan.Any(c => c.platform is Platform.Ubisoft && c.id == gameId)))
|
if (!uninstallAll && (Program.IsGameBlocked(name, gameDirectory) ||
|
||||||
|
!programsToScan.Any(c => c.platform is Platform.Ubisoft && c.id == gameId)))
|
||||||
continue;
|
continue;
|
||||||
AddToRemainingGames(name);
|
AddToRemainingGames(name);
|
||||||
Task task = Task.Run(async () =>
|
Task task = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
HashSet<string> dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft);
|
HashSet<string> dllDirectories =
|
||||||
|
await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft);
|
||||||
if (dllDirectories is null)
|
if (dllDirectories is null)
|
||||||
{
|
{
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uninstallAll)
|
if (uninstallAll)
|
||||||
{
|
{
|
||||||
Selection bareSelection = Selection.GetOrCreate(Platform.Ubisoft, gameId, name, gameDirectory, dllDirectories,
|
Selection bareSelection = Selection.GetOrCreate(Platform.Ubisoft, gameId, name, gameDirectory,
|
||||||
|
dllDirectories,
|
||||||
await gameDirectory.GetExecutableDirectories(true));
|
await gameDirectory.GetExecutableDirectories(true));
|
||||||
bareSelection.Enabled = true;
|
bareSelection.Enabled = true;
|
||||||
RemoveFromRemainingGames(name);
|
RemoveFromRemainingGames(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
Selection selection = Selection.GetOrCreate(Platform.Ubisoft, gameId, name, gameDirectory, dllDirectories,
|
Selection selection = Selection.GetOrCreate(Platform.Ubisoft, gameId, name, gameDirectory,
|
||||||
|
dllDirectories,
|
||||||
await gameDirectory.GetExecutableDirectories(true));
|
await gameDirectory.GetExecutableDirectories(true));
|
||||||
selection.Icon = IconGrabber.GetDomainFaviconUrl("store.ubi.com");
|
selection.Icon = IconGrabber.GetDomainFaviconUrl("store.ubi.com");
|
||||||
Invoke(delegate
|
Invoke(delegate
|
||||||
|
@ -485,12 +541,14 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
appTasks.Add(task);
|
appTasks.Add(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Task task in appTasks)
|
foreach (Task task in appTasks)
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return;
|
return;
|
||||||
await task;
|
await task;
|
||||||
}
|
}
|
||||||
|
|
||||||
steamGamesToCheck = 0;
|
steamGamesToCheck = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,19 +580,26 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
List<(Platform platform, string id, string name, bool alreadySelected)> gameChoices = new();
|
List<(Platform platform, string id, string name, bool alreadySelected)> gameChoices = new();
|
||||||
if (ParadoxLauncher.InstallPath.DirectoryExists())
|
if (ParadoxLauncher.InstallPath.DirectoryExists())
|
||||||
gameChoices.Add((Platform.Paradox, "PL", "Paradox Launcher",
|
gameChoices.Add((Platform.Paradox, "PL", "Paradox Launcher",
|
||||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Paradox && p.id == "PL")));
|
programsToScan is not null &&
|
||||||
|
programsToScan.Any(p => p.platform is Platform.Paradox && p.id == "PL")));
|
||||||
if (SteamLibrary.InstallPath.DirectoryExists())
|
if (SteamLibrary.InstallPath.DirectoryExists())
|
||||||
foreach ((string appId, string name, string _, int _, string _) in (await SteamLibrary.GetGames()).Where(g
|
foreach ((string appId, string name, string _, int _, string _) in
|
||||||
=> !Program.IsGameBlocked(g.name, g.gameDirectory)))
|
(await SteamLibrary.GetGames()).Where(g
|
||||||
|
=> !Program.IsGameBlocked(g.name, g.gameDirectory)))
|
||||||
gameChoices.Add((Platform.Steam, appId, name,
|
gameChoices.Add((Platform.Steam, appId, name,
|
||||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Steam && p.id == appId)));
|
programsToScan is not null &&
|
||||||
|
programsToScan.Any(p => p.platform is Platform.Steam && p.id == appId)));
|
||||||
if (EpicLibrary.EpicManifestsPath.DirectoryExists() || HeroicLibrary.HeroicLibraryPath.DirectoryExists())
|
if (EpicLibrary.EpicManifestsPath.DirectoryExists() || HeroicLibrary.HeroicLibraryPath.DirectoryExists())
|
||||||
gameChoices.AddRange((await EpicLibrary.GetGames()).Where(m => !Program.IsGameBlocked(m.DisplayName, m.InstallLocation)).Select(manifest
|
gameChoices.AddRange((await EpicLibrary.GetGames())
|
||||||
=> (Platform.Epic, manifest.CatalogNamespace, manifest.DisplayName,
|
.Where(m => !Program.IsGameBlocked(m.DisplayName, m.InstallLocation)).Select(manifest
|
||||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Epic && p.id == manifest.CatalogNamespace))));
|
=> (Platform.Epic, manifest.CatalogNamespace, manifest.DisplayName,
|
||||||
foreach ((string gameId, string name, string _) in (await UbisoftLibrary.GetGames()).Where(g => !Program.IsGameBlocked(g.name, g.gameDirectory)))
|
programsToScan is not null && programsToScan.Any(p =>
|
||||||
|
p.platform is Platform.Epic && p.id == manifest.CatalogNamespace))));
|
||||||
|
foreach ((string gameId, string name, string _) in (await UbisoftLibrary.GetGames()).Where(g =>
|
||||||
|
!Program.IsGameBlocked(g.name, g.gameDirectory)))
|
||||||
gameChoices.Add((Platform.Ubisoft, gameId, name,
|
gameChoices.Add((Platform.Ubisoft, gameId, name,
|
||||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Ubisoft && p.id == gameId)));
|
programsToScan is not null &&
|
||||||
|
programsToScan.Any(p => p.platform is Platform.Ubisoft && p.id == gameId)));
|
||||||
if (gameChoices.Count > 0)
|
if (gameChoices.Count > 0)
|
||||||
{
|
{
|
||||||
using SelectDialogForm form = new(this);
|
using SelectDialogForm form = new(this);
|
||||||
|
@ -569,6 +634,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
scan = selectResult == DialogResult.OK && choices is not null && choices.Count > 0;
|
scan = selectResult == DialogResult.OK && choices is not null && choices.Count > 0;
|
||||||
|
|
||||||
const string retry = "\n\nPress the \"Rescan\" button to re-choose.";
|
const string retry = "\n\nPress the \"Rescan\" button to re-choose.";
|
||||||
if (scan)
|
if (scan)
|
||||||
{
|
{
|
||||||
|
@ -581,6 +647,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
else
|
else
|
||||||
noneFoundLabel.Text = "No applicable programs nor games were found on your computer!";
|
noneFoundLabel.Text = "No applicable programs nor games were found on your computer!";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan)
|
if (scan)
|
||||||
{
|
{
|
||||||
bool setup = true;
|
bool setup = true;
|
||||||
|
@ -597,10 +664,14 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
else
|
else
|
||||||
curProgress = _progress;
|
curProgress = _progress;
|
||||||
int p = Math.Max(Math.Min((int)((float)curProgress / maxProgress * 100), 100), 0);
|
int p = Math.Max(Math.Min((int)((float)curProgress / maxProgress * 100), 100), 0);
|
||||||
progressLabel.Text = setup ? $"Setting up SteamCMD . . . {p}%" : $"Gathering and caching your applicable games and their DLCs . . . {p}%";
|
progressLabel.Text =
|
||||||
|
setup
|
||||||
|
? $"Setting up SteamCMD . . . {p}%"
|
||||||
|
: $"Gathering and caching your applicable games and their DLCs . . . {p}%";
|
||||||
progressBar.Value = p;
|
progressBar.Value = p;
|
||||||
};
|
};
|
||||||
if (SteamLibrary.InstallPath.DirectoryExists() && programsToScan is not null && programsToScan.Any(c => c.platform is Platform.Steam))
|
if (SteamLibrary.InstallPath.DirectoryExists() && programsToScan is not null &&
|
||||||
|
programsToScan.Any(c => c.platform is Platform.Steam))
|
||||||
{
|
{
|
||||||
progressLabel.Text = "Setting up SteamCMD . . . ";
|
progressLabel.Text = "Setting up SteamCMD . . . ";
|
||||||
if (!await SteamCMD.Setup(iProgress))
|
if (!await SteamCMD.Setup(iProgress))
|
||||||
|
@ -610,6 +681,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup = false;
|
setup = false;
|
||||||
progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
|
progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
|
||||||
Selection.ValidateAll(programsToScan);
|
Selection.ValidateAll(programsToScan);
|
||||||
|
@ -618,6 +690,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
await GetApplicablePrograms(iProgress);
|
await GetApplicablePrograms(iProgress);
|
||||||
await SteamCMD.Cleanup();
|
await SteamCMD.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
OnLoadDlc(null, null);
|
OnLoadDlc(null, null);
|
||||||
OnLoadKoaloader(null, null);
|
OnLoadKoaloader(null, null);
|
||||||
HideProgressBar();
|
HideProgressBar();
|
||||||
|
@ -649,7 +722,8 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
SyncNodeAncestors(node);
|
SyncNodeAncestors(node);
|
||||||
SyncNodeDescendants(node);
|
SyncNodeDescendants(node);
|
||||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||||
allCheckBox.Checked = EnumerateTreeNodes(selectionTreeView.Nodes).All(node => node.Text == "Unknown" || node.Checked);
|
allCheckBox.Checked = EnumerateTreeNodes(selectionTreeView.Nodes)
|
||||||
|
.All(node => node.Text == "Unknown" || node.Checked);
|
||||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||||
installButton.Enabled = Selection.AllEnabled.Any();
|
installButton.Enabled = Selection.AllEnabled.Any();
|
||||||
uninstallButton.Enabled = installButton.Enabled;
|
uninstallButton.Enabled = installButton.Enabled;
|
||||||
|
@ -699,8 +773,9 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
progressBar.Visible = true;
|
progressBar.Visible = true;
|
||||||
programsGroupBox.Size = programsGroupBox.Size with
|
programsGroupBox.Size = programsGroupBox.Size with
|
||||||
{
|
{
|
||||||
Height = programsGroupBox.Size.Height - 3 - progressLabel.Size.Height - progressLabelGames.Size.Height - progressLabelDLCs.Size.Height
|
Height = programsGroupBox.Size.Height - 3 - progressLabel.Size.Height - progressLabelGames.Size.Height -
|
||||||
- progressBar.Size.Height
|
progressLabelDLCs.Size.Height
|
||||||
|
- progressBar.Size.Height
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,8 +788,9 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
progressBar.Visible = false;
|
progressBar.Visible = false;
|
||||||
programsGroupBox.Size = programsGroupBox.Size with
|
programsGroupBox.Size = programsGroupBox.Size with
|
||||||
{
|
{
|
||||||
Height = programsGroupBox.Size.Height + 3 + progressLabel.Size.Height + progressLabelGames.Size.Height + progressLabelDLCs.Size.Height
|
Height = programsGroupBox.Size.Height + 3 + progressLabel.Size.Height + progressLabelGames.Size.Height +
|
||||||
+ progressBar.Size.Height
|
progressLabelDLCs.Size.Height
|
||||||
|
+ progressBar.Size.Height
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,10 +829,13 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
: selection.Platform is Platform.Epic
|
: selection.Platform is Platform.Epic
|
||||||
? "Epic GraphQL "
|
? "Epic GraphQL "
|
||||||
: "";
|
: "";
|
||||||
queries.Add(new($"Open {platformString}Query", "Notepad", (_, _) => Diagnostics.OpenFileInNotepad(appInfoJSON)));
|
queries.Add(new($"Open {platformString}Query", "Notepad",
|
||||||
|
(_, _) => Diagnostics.OpenFileInNotepad(appInfoJSON)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appInfoVDF.FileExists())
|
if (appInfoVDF.FileExists())
|
||||||
queries.Add(new("Open SteamCMD Query", "Notepad", (_, _) => Diagnostics.OpenFileInNotepad(appInfoVDF)));
|
queries.Add(new("Open SteamCMD Query", "Notepad",
|
||||||
|
(_, _) => Diagnostics.OpenFileInNotepad(appInfoVDF)));
|
||||||
if (queries.Count > 0)
|
if (queries.Count > 0)
|
||||||
{
|
{
|
||||||
_ = items.Add(new ToolStripSeparator());
|
_ = items.Add(new ToolStripSeparator());
|
||||||
|
@ -774,62 +853,78 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection is not null)
|
if (selection is not null)
|
||||||
{
|
{
|
||||||
if (id == "PL")
|
if (id == "PL")
|
||||||
{
|
{
|
||||||
_ = items.Add(new ToolStripSeparator());
|
_ = items.Add(new ToolStripSeparator());
|
||||||
|
|
||||||
async void EventHandler(object sender, EventArgs e)
|
async void EventHandler(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_ = await ParadoxLauncher.Repair(this, selection);
|
_ = await ParadoxLauncher.Repair(this, selection);
|
||||||
Program.Canceled = false;
|
Program.Canceled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = items.Add(new ContextMenuItem("Repair", "Command Prompt", EventHandler));
|
_ = items.Add(new ContextMenuItem("Repair", "Command Prompt", EventHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = items.Add(new ToolStripSeparator());
|
_ = items.Add(new ToolStripSeparator());
|
||||||
_ = items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
|
_ = items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
|
||||||
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory)));
|
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory)));
|
||||||
int executables = 0;
|
int executables = 0;
|
||||||
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
|
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
|
||||||
_ = 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)));
|
"File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||||
HashSet<string> directories = selection.DllDirectories;
|
HashSet<string> directories = selection.DllDirectories;
|
||||||
int steam = 0, epic = 0, r1 = 0, r2 = 0;
|
int steam = 0, epic = 0, r1 = 0, r2 = 0;
|
||||||
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config,
|
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string old_config,
|
||||||
out string config, out string old_log, out string log, out string cache);
|
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()
|
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() ||
|
||||||
|| config.FileExists() || old_log.FileExists() || log.FileExists() || cache.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)));
|
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string config,
|
||||||
out string log);
|
out string log);
|
||||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists())
|
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)));
|
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.Platform is Platform.Ubisoft)
|
if (selection.Platform is Platform.Ubisoft)
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string config,
|
||||||
out string log);
|
out string log);
|
||||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists())
|
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)));
|
(_, _) => 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,
|
directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32,
|
||||||
|
out api32_o, out api64, out api64_o, out config,
|
||||||
out log);
|
out log);
|
||||||
if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api32_o.FileExists() || api64.FileExists()
|
if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() ||
|
||||||
|| api64_o.FileExists() || config.FileExists() || log.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)));
|
(_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id != "PL")
|
if (id != "PL")
|
||||||
{
|
{
|
||||||
if (selection?.Platform is Platform.Steam || dlcParentSelection?.Platform is Platform.Steam)
|
if (selection?.Platform is Platform.Steam || dlcParentSelection?.Platform is Platform.Steam)
|
||||||
|
@ -838,19 +933,23 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
_ = items.Add(new ContextMenuItem("Open SteamDB", "SteamDB",
|
_ = items.Add(new ContextMenuItem("Open SteamDB", "SteamDB",
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id)));
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection is not null)
|
if (selection is not null)
|
||||||
switch (selection.Platform)
|
switch (selection.Platform)
|
||||||
{
|
{
|
||||||
case Platform.Steam:
|
case Platform.Steam:
|
||||||
_ = items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
|
_ = items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Product)));
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Product)));
|
||||||
_ = items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIcon), "Steam Community",
|
_ = items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIcon),
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id)));
|
"Steam Community",
|
||||||
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" +
|
||||||
|
id)));
|
||||||
break;
|
break;
|
||||||
case Platform.Epic:
|
case Platform.Epic:
|
||||||
_ = items.Add(new ToolStripSeparator());
|
_ = items.Add(new ToolStripSeparator());
|
||||||
_ = items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",
|
_ = items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://scream-db.web.app/offers/" + id)));
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser("https://scream-db.web.app/offers/" +
|
||||||
|
id)));
|
||||||
_ = items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games",
|
_ = items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games",
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Product)));
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Product)));
|
||||||
break;
|
break;
|
||||||
|
@ -858,12 +957,15 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
_ = items.Add(new ToolStripSeparator());
|
_ = items.Add(new ToolStripSeparator());
|
||||||
_ = items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store",
|
_ = items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store",
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser(
|
||||||
"https://store.ubi.com/us/" + selection.Name.Replace(" ", "-").ToLowerInvariant())));
|
"https://store.ubi.com/us/" +
|
||||||
|
selection.Name.Replace(" ", "-").ToLowerInvariant())));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection?.Website is not null)
|
if (selection?.Website is not null)
|
||||||
_ = items.Add(new ContextMenuItem("Open Official Website", ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.Website)),
|
_ = items.Add(new ContextMenuItem("Open Official Website",
|
||||||
|
("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.Website)),
|
||||||
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Website)));
|
(_, _) => Diagnostics.OpenUrlInInternetBrowser(selection.Website)));
|
||||||
contextMenuStrip.Show(selectionTreeView, location);
|
contextMenuStrip.Show(selectionTreeView, location);
|
||||||
contextMenuStrip.Refresh();
|
contextMenuStrip.Refresh();
|
||||||
|
@ -871,7 +973,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
|
|
||||||
private void OnLoad(object sender, EventArgs _)
|
private void OnLoad(object sender, EventArgs _)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HideProgressBar();
|
HideProgressBar();
|
||||||
|
@ -934,6 +1036,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
selection.Enabled = shouldEnable;
|
selection.Enabled = shouldEnable;
|
||||||
OnTreeViewNodeCheckedChanged(null, new(selection.TreeNode, TreeViewAction.ByMouse));
|
OnTreeViewNodeCheckedChanged(null, new(selection.TreeNode, TreeViewAction.ByMouse));
|
||||||
}
|
}
|
||||||
|
|
||||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||||
allCheckBox.Checked = shouldEnable;
|
allCheckBox.Checked = shouldEnable;
|
||||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||||
|
@ -953,19 +1056,23 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
|
|
||||||
private bool AreSelectionsDefault()
|
private bool AreSelectionsDefault()
|
||||||
=> EnumerateTreeNodes(selectionTreeView.Nodes).All(node
|
=> EnumerateTreeNodes(selectionTreeView.Nodes).All(node
|
||||||
=> node.Parent is null || node.Tag is not Platform and not DLCType || (node.Text == "Unknown" ? !node.Checked : node.Checked));
|
=> node.Parent is null || node.Tag is not Platform and not DLCType ||
|
||||||
|
(node.Text == "Unknown" ? !node.Checked : node.Checked));
|
||||||
|
|
||||||
private bool CanSaveDlc() => installButton.Enabled && (ProgramData.ReadDlcChoices().Any() || !AreSelectionsDefault());
|
private bool CanSaveDlc() =>
|
||||||
|
installButton.Enabled && (ProgramData.ReadDlcChoices().Any() || !AreSelectionsDefault());
|
||||||
|
|
||||||
private void OnSaveDlc(object sender, EventArgs e)
|
private void OnSaveDlc(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
List<(Platform platform, string gameId, string dlcId)> choices = ProgramData.ReadDlcChoices().ToList();
|
List<(Platform platform, string gameId, string dlcId)> choices = ProgramData.ReadDlcChoices().ToList();
|
||||||
foreach (SelectionDLC dlc in SelectionDLC.All.Keys)
|
foreach (SelectionDLC dlc in SelectionDLC.All.Keys)
|
||||||
if ((dlc.Name == "Unknown" ? dlc.Enabled : !dlc.Enabled)
|
if ((dlc.Name == "Unknown" ? dlc.Enabled : !dlc.Enabled)
|
||||||
&& !choices.Any(c => c.platform == dlc.Selection.Platform && c.gameId == dlc.Selection.Id && c.dlcId == dlc.Id))
|
&& !choices.Any(c =>
|
||||||
|
c.platform == dlc.Selection.Platform && c.gameId == dlc.Selection.Id && c.dlcId == dlc.Id))
|
||||||
choices.Add((dlc.Selection.Platform, dlc.Selection.Id, dlc.Id));
|
choices.Add((dlc.Selection.Platform, dlc.Selection.Id, dlc.Id));
|
||||||
else
|
else
|
||||||
_ = choices.RemoveAll(n => n.platform == dlc.Selection.Platform && n.gameId == dlc.Selection.Id && n.dlcId == dlc.Id);
|
_ = choices.RemoveAll(n =>
|
||||||
|
n.platform == dlc.Selection.Platform && n.gameId == dlc.Selection.Id && n.dlcId == dlc.Id);
|
||||||
ProgramData.WriteDlcChoices(choices);
|
ProgramData.WriteDlcChoices(choices);
|
||||||
loadButton.Enabled = CanLoadDlc();
|
loadButton.Enabled = CanLoadDlc();
|
||||||
saveButton.Enabled = CanSaveDlc();
|
saveButton.Enabled = CanSaveDlc();
|
||||||
|
@ -978,7 +1085,8 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
List<(Platform platform, string gameId, string dlcId)> choices = ProgramData.ReadDlcChoices().ToList();
|
List<(Platform platform, string gameId, string dlcId)> choices = ProgramData.ReadDlcChoices().ToList();
|
||||||
foreach (SelectionDLC dlc in SelectionDLC.All.Keys)
|
foreach (SelectionDLC dlc in SelectionDLC.All.Keys)
|
||||||
{
|
{
|
||||||
dlc.Enabled = choices.Any(c => c.platform == dlc.Selection?.Platform && c.gameId == dlc.Selection?.Id && c.dlcId == dlc.Id)
|
dlc.Enabled = choices.Any(c =>
|
||||||
|
c.platform == dlc.Selection?.Platform && c.gameId == dlc.Selection?.Id && c.dlcId == dlc.Id)
|
||||||
? dlc.Name == "Unknown"
|
? dlc.Name == "Unknown"
|
||||||
: dlc.Name != "Unknown";
|
: dlc.Name != "Unknown";
|
||||||
OnTreeViewNodeCheckedChanged(null, new(dlc.TreeNode, TreeViewAction.ByMouse));
|
OnTreeViewNodeCheckedChanged(null, new(dlc.TreeNode, TreeViewAction.ByMouse));
|
||||||
|
@ -994,23 +1102,29 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
dlc.Enabled = dlc.Name != "Unknown";
|
dlc.Enabled = dlc.Name != "Unknown";
|
||||||
OnTreeViewNodeCheckedChanged(null, new(dlc.TreeNode, TreeViewAction.ByMouse));
|
OnTreeViewNodeCheckedChanged(null, new(dlc.TreeNode, TreeViewAction.ByMouse));
|
||||||
}
|
}
|
||||||
|
|
||||||
resetButton.Enabled = CanResetDlc();
|
resetButton.Enabled = CanResetDlc();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool AreKoaloaderSelectionsDefault() => Selection.All.Keys.All(selection => selection.Koaloader && selection.KoaloaderProxy is null);
|
private static bool AreKoaloaderSelectionsDefault() =>
|
||||||
|
Selection.All.Keys.All(selection => selection.Koaloader && selection.KoaloaderProxy is null);
|
||||||
|
|
||||||
private static bool CanSaveKoaloader() => ProgramData.ReadKoaloaderChoices().Any() || !AreKoaloaderSelectionsDefault();
|
private static bool CanSaveKoaloader() =>
|
||||||
|
ProgramData.ReadKoaloaderChoices().Any() || !AreKoaloaderSelectionsDefault();
|
||||||
|
|
||||||
private void OnSaveKoaloader(object sender, EventArgs e)
|
private void OnSaveKoaloader(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
List<(Platform platform, string id, string proxy, bool enabled)> choices = ProgramData.ReadKoaloaderChoices().ToList();
|
List<(Platform platform, string id, string proxy, bool enabled)> choices =
|
||||||
|
ProgramData.ReadKoaloaderChoices().ToList();
|
||||||
foreach (Selection selection in Selection.All.Keys)
|
foreach (Selection selection in Selection.All.Keys)
|
||||||
{
|
{
|
||||||
_ = choices.RemoveAll(c => c.platform == selection.Platform && c.id == selection.Id);
|
_ = choices.RemoveAll(c => c.platform == selection.Platform && c.id == selection.Id);
|
||||||
if (selection.KoaloaderProxy is not null and not Selection.DefaultKoaloaderProxy || !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,
|
choices.Add((selection.Platform, selection.Id,
|
||||||
|
selection.KoaloaderProxy == Selection.DefaultKoaloaderProxy ? null : selection.KoaloaderProxy,
|
||||||
selection.Koaloader));
|
selection.Koaloader));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramData.WriteKoaloaderProxyChoices(choices);
|
ProgramData.WriteKoaloaderProxyChoices(choices);
|
||||||
saveKoaloaderButton.Enabled = CanSaveKoaloader();
|
saveKoaloaderButton.Enabled = CanSaveKoaloader();
|
||||||
loadKoaloaderButton.Enabled = CanLoadKoaloader();
|
loadKoaloaderButton.Enabled = CanLoadKoaloader();
|
||||||
|
@ -1020,7 +1134,8 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
|
|
||||||
private void OnLoadKoaloader(object sender, EventArgs e)
|
private void OnLoadKoaloader(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
List<(Platform platform, string id, string proxy, bool enabled)> choices = ProgramData.ReadKoaloaderChoices().ToList();
|
List<(Platform platform, string id, string proxy, bool enabled)> choices =
|
||||||
|
ProgramData.ReadKoaloaderChoices().ToList();
|
||||||
foreach (Selection selection in Selection.All.Keys)
|
foreach (Selection selection in Selection.All.Keys)
|
||||||
if (choices.Any(c => c.platform == selection.Platform && c.id == selection.Id))
|
if (choices.Any(c => c.platform == selection.Platform && c.id == selection.Id))
|
||||||
{
|
{
|
||||||
|
@ -1045,6 +1160,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
selection.Koaloader = true;
|
selection.Koaloader = true;
|
||||||
selection.KoaloaderProxy = null;
|
selection.KoaloaderProxy = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramData.WriteKoaloaderProxyChoices(choices);
|
ProgramData.WriteKoaloaderProxyChoices(choices);
|
||||||
loadKoaloaderButton.Enabled = CanLoadKoaloader();
|
loadKoaloaderButton.Enabled = CanLoadKoaloader();
|
||||||
OnKoaloaderChanged();
|
OnKoaloaderChanged();
|
||||||
|
@ -1059,6 +1175,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
selection.Koaloader = true;
|
selection.Koaloader = true;
|
||||||
selection.KoaloaderProxy = null;
|
selection.KoaloaderProxy = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
OnKoaloaderChanged();
|
OnKoaloaderChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,13 +1209,19 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
using DialogForm form = new(this);
|
using DialogForm form = new(this);
|
||||||
_ = form.Show(SystemIcons.Information,
|
_ = form.Show(SystemIcons.Information,
|
||||||
"Blocks the program from caching and displaying games protected by anti-cheats."
|
"Blocks the program from caching and displaying games protected by anti-cheats."
|
||||||
+ "\nYou disable this option and install DLC unlockers to protected games at your own risk!" + "\n\nBlocked games: "
|
+ "\nYou disable this option and install DLC unlockers to protected games at your own risk!" +
|
||||||
+ (string.IsNullOrWhiteSpace(blockedGames.ToString()) ? "(none)" : blockedGames) + "\n\nBlocked game sub-directories: "
|
"\n\nBlocked games: "
|
||||||
+ (string.IsNullOrWhiteSpace(blockedDirectories.ToString()) ? "(none)" : blockedDirectories) + "\n\nBlocked game sub-directory exceptions: "
|
+ (string.IsNullOrWhiteSpace(blockedGames.ToString()) ? "(none)" : blockedGames) +
|
||||||
+ (string.IsNullOrWhiteSpace(blockedDirectoryExceptions.ToString()) ? "(none)" : blockedDirectoryExceptions),
|
"\n\nBlocked game sub-directories: "
|
||||||
|
+ (string.IsNullOrWhiteSpace(blockedDirectories.ToString()) ? "(none)" : blockedDirectories) +
|
||||||
|
"\n\nBlocked game sub-directory exceptions: "
|
||||||
|
+ (string.IsNullOrWhiteSpace(blockedDirectoryExceptions.ToString())
|
||||||
|
? "(none)"
|
||||||
|
: blockedDirectoryExceptions),
|
||||||
customFormText: "Block Protected Games");
|
customFormText: "Block Protected Games");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSortCheckBoxChanged(object sender, EventArgs e)
|
private void OnSortCheckBoxChanged(object sender, EventArgs e)
|
||||||
=> selectionTreeView.TreeViewNodeSorter = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName;
|
=> selectionTreeView.TreeViewNodeSorter =
|
||||||
|
sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName;
|
||||||
}
|
}
|
|
@ -50,16 +50,21 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
updateButton.Click -= OnUpdateCancel;
|
updateButton.Click -= OnUpdateCancel;
|
||||||
progressLabel.Text = "Checking for updates . . .";
|
progressLabel.Text = "Checking for updates . . .";
|
||||||
changelogTreeView.Visible = false;
|
changelogTreeView.Visible = false;
|
||||||
changelogTreeView.Location = progressLabel.Location with { Y = progressLabel.Location.Y + progressLabel.Size.Height + 13 };
|
changelogTreeView.Location = progressLabel.Location with
|
||||||
|
{
|
||||||
|
Y = progressLabel.Location.Y + progressLabel.Size.Height + 13
|
||||||
|
};
|
||||||
Refresh();
|
Refresh();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
Version currentVersion = new(Program.Version);
|
Version currentVersion = new(Program.Version);
|
||||||
#endif
|
#endif
|
||||||
List<ProgramRelease> releases = null;
|
List<ProgramRelease> releases = null;
|
||||||
string response = await HttpClientManager.EnsureGet($"https://api.github.com/repos/{Program.RepositoryOwner}/{Program.RepositoryName}/releases");
|
string response =
|
||||||
|
await HttpClientManager.EnsureGet(
|
||||||
|
$"https://api.github.com/repos/{Program.RepositoryOwner}/{Program.RepositoryName}/releases");
|
||||||
if (response is not null)
|
if (response is not null)
|
||||||
releases = JsonConvert.DeserializeObject<List<ProgramRelease>>(response)
|
releases = JsonConvert.DeserializeObject<List<ProgramRelease>>(response)
|
||||||
?.Where(release => !release.Draft && !release.Prerelease && release.Asset is not null).ToList();
|
?.Where(release => !release.Draft && !release.Prerelease && release.Asset is not null).ToList();
|
||||||
latestRelease = releases?.FirstOrDefault();
|
latestRelease = releases?.FirstOrDefault();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (latestRelease?.Version is not { } latestVersion)
|
if (latestRelease?.Version is not { } latestVersion)
|
||||||
|
@ -101,7 +106,7 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
|
|
||||||
private void OnLoad(object sender, EventArgs _)
|
private void OnLoad(object sender, EventArgs _)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UpdaterPath.DeleteFile();
|
UpdaterPath.DeleteFile();
|
||||||
|
@ -125,7 +130,8 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
updateButton.Text = "Cancel";
|
updateButton.Text = "Cancel";
|
||||||
updateButton.Click -= OnUpdate;
|
updateButton.Click -= OnUpdate;
|
||||||
updateButton.Click += OnUpdateCancel;
|
updateButton.Click += OnUpdateCancel;
|
||||||
changelogTreeView.Location = progressBar.Location with { Y = progressBar.Location.Y + progressBar.Size.Height + 6 };
|
changelogTreeView.Location =
|
||||||
|
progressBar.Location with { Y = progressBar.Location.Y + progressBar.Size.Height + 6 };
|
||||||
Refresh();
|
Refresh();
|
||||||
Progress<int> progress = new();
|
Progress<int> progress = new();
|
||||||
IProgress<int> iProgress = progress;
|
IProgress<int> iProgress = progress;
|
||||||
|
@ -144,7 +150,8 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
{
|
{
|
||||||
if (cancellation is null || Program.Canceled)
|
if (cancellation is null || Program.Canceled)
|
||||||
throw new TaskCanceledException();
|
throw new TaskCanceledException();
|
||||||
using HttpResponseMessage response = await HttpClientManager.HttpClient.GetAsync(latestRelease.Asset.BrowserDownloadUrl,
|
using HttpResponseMessage response = await HttpClientManager.HttpClient.GetAsync(
|
||||||
|
latestRelease.Asset.BrowserDownloadUrl,
|
||||||
HttpCompletionOption.ResponseHeadersRead, cancellation.Token);
|
HttpCompletionOption.ResponseHeadersRead, cancellation.Token);
|
||||||
_ = response.EnsureSuccessStatusCode();
|
_ = response.EnsureSuccessStatusCode();
|
||||||
if (cancellation is null || Program.Canceled)
|
if (cancellation is null || Program.Canceled)
|
||||||
|
@ -155,7 +162,8 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
long bytesRead = 0;
|
long bytesRead = 0;
|
||||||
int newBytes;
|
int newBytes;
|
||||||
while (cancellation is not null && !Program.Canceled
|
while (cancellation is not null && !Program.Canceled
|
||||||
&& (newBytes = await download.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellation.Token)) != 0)
|
&& (newBytes = await download.ReadAsync(buffer.AsMemory(0, buffer.Length),
|
||||||
|
cancellation.Token)) != 0)
|
||||||
{
|
{
|
||||||
if (cancellation is null || Program.Canceled)
|
if (cancellation is null || Program.Canceled)
|
||||||
throw new TaskCanceledException();
|
throw new TaskCanceledException();
|
||||||
|
@ -166,6 +174,7 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
continue;
|
continue;
|
||||||
iProgress.Report(report);
|
iProgress.Report(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
iProgress.Report((int)(bytesRead / bytes * 100));
|
iProgress.Report((int)(bytesRead / bytes * 100));
|
||||||
if (cancellation is null || Program.Canceled)
|
if (cancellation is null || Program.Canceled)
|
||||||
throw new TaskCanceledException();
|
throw new TaskCanceledException();
|
||||||
|
@ -179,6 +188,7 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
retry = ex.HandleException(this, Program.Name + " encountered an exception while updating");
|
retry = ex.HandleException(this, Program.Name + " encountered an exception while updating");
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancellation?.Dispose();
|
cancellation?.Dispose();
|
||||||
cancellation = null;
|
cancellation = null;
|
||||||
await update.DisposeAsync();
|
await update.DisposeAsync();
|
||||||
|
@ -209,13 +219,15 @@ internal sealed partial class UpdateForm : CustomForm
|
||||||
Process process = new();
|
Process process = new();
|
||||||
ProcessStartInfo startInfo = new()
|
ProcessStartInfo startInfo = new()
|
||||||
{
|
{
|
||||||
WorkingDirectory = ProgramData.DirectoryPath, FileName = "cmd.exe", Arguments = $"/C START \"UPDATER\" /B {Path.GetFileName(UpdaterPath)}",
|
WorkingDirectory = ProgramData.DirectoryPath, FileName = "cmd.exe",
|
||||||
|
Arguments = $"/C START \"UPDATER\" /B {Path.GetFileName(UpdaterPath)}",
|
||||||
CreateNoWindow = true
|
CreateNoWindow = true
|
||||||
};
|
};
|
||||||
process.StartInfo = startInfo;
|
process.StartInfo = startInfo;
|
||||||
_ = process.Start();
|
_ = process.Start();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retry)
|
if (!retry)
|
||||||
StartProgram();
|
StartProgram();
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,8 +17,11 @@ internal static class EpicLibrary
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
epicManifestsPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Epic Games\EOS", "ModSdkMetadataDir", null) as string;
|
epicManifestsPath ??=
|
||||||
epicManifestsPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher", "AppDataPath", null) as string;
|
Registry.GetValue(@"HKEY_CURRENT_USER\Software\Epic Games\EOS", "ModSdkMetadataDir", null) as string;
|
||||||
|
epicManifestsPath ??=
|
||||||
|
Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher", "AppDataPath",
|
||||||
|
null) as string;
|
||||||
if (epicManifestsPath is not null && epicManifestsPath.EndsWith(@"\Data", StringComparison.Ordinal))
|
if (epicManifestsPath is not null && epicManifestsPath.EndsWith(@"\Data", StringComparison.Ordinal))
|
||||||
epicManifestsPath += @"\Manifests";
|
epicManifestsPath += @"\Manifests";
|
||||||
return epicManifestsPath.ResolvePath();
|
return epicManifestsPath.ResolvePath();
|
||||||
|
@ -39,8 +42,9 @@ internal static class EpicLibrary
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json);
|
Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json);
|
||||||
if (manifest is not null && (manifest.InstallLocation = manifest.InstallLocation.ResolvePath()) is not null
|
if (manifest is not null && (manifest.InstallLocation = manifest.InstallLocation.ResolvePath())
|
||||||
&& games.All(g => g.CatalogNamespace != manifest.CatalogNamespace))
|
is not null
|
||||||
|
&& games.All(g => g.CatalogNamespace != manifest.CatalogNamespace))
|
||||||
games.Add(manifest);
|
games.Add(manifest);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -48,6 +52,7 @@ internal static class EpicLibrary
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return games;
|
return games;
|
||||||
await HeroicLibrary.GetGames(games);
|
await HeroicLibrary.GetGames(games);
|
||||||
|
|
|
@ -14,7 +14,8 @@ internal static class EpicStore
|
||||||
{
|
{
|
||||||
private const int Cooldown = 600;
|
private const int Cooldown = 600;
|
||||||
|
|
||||||
internal static async Task<List<(string id, string name, string product, string icon, string developer)>> QueryCatalog(string categoryNamespace)
|
internal static async Task<List<(string id, string name, string product, string icon, string developer)>>
|
||||||
|
QueryCatalog(string categoryNamespace)
|
||||||
{
|
{
|
||||||
List<(string id, string name, string product, string icon, string developer)> dlcIds = [];
|
List<(string id, string name, string product, string icon, string developer)> dlcIds = [];
|
||||||
string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json";
|
string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json";
|
||||||
|
@ -41,13 +42,16 @@ internal static class EpicStore
|
||||||
{
|
{
|
||||||
cacheFile.DeleteFile();
|
cacheFile.DeleteFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response is null)
|
if (response is null)
|
||||||
return dlcIds;
|
return dlcIds;
|
||||||
List<Element> searchStore = [..response.Data.Catalog.SearchStore.Elements];
|
List<Element> searchStore = [..response.Data.Catalog.SearchStore.Elements];
|
||||||
foreach (Element element in searchStore)
|
foreach (Element element in searchStore)
|
||||||
{
|
{
|
||||||
string title = element.Title;
|
string title = element.Title;
|
||||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Length > 0 ? 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;
|
string icon = null;
|
||||||
for (int i = 0; i < element.KeyImages?.Length; i++)
|
for (int i = 0; i < element.KeyImages?.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -57,14 +61,18 @@ internal static class EpicStore
|
||||||
icon = keyImage.Url.ToString();
|
icon = keyImage.Url.ToString();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Item item in element.Items)
|
foreach (Item item in element.Items)
|
||||||
dlcIds.Populate(item.Id, title, product, icon, null, element.Items.Length == 1);
|
dlcIds.Populate(item.Id, title, product, icon, null, element.Items.Length == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Element> catalogOffers = [..response.Data.Catalog.CatalogOffers.Elements];
|
List<Element> catalogOffers = [..response.Data.Catalog.CatalogOffers.Elements];
|
||||||
foreach (Element element in catalogOffers)
|
foreach (Element element in catalogOffers)
|
||||||
{
|
{
|
||||||
string title = element.Title;
|
string title = element.Title;
|
||||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Length > 0 ? 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;
|
string icon = null;
|
||||||
for (int i = 0; i < element.KeyImages?.Length; i++)
|
for (int i = 0; i < element.KeyImages?.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -74,13 +82,17 @@ internal static class EpicStore
|
||||||
icon = keyImage.Url.ToString();
|
icon = keyImage.Url.ToString();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Item item in element.Items)
|
foreach (Item item in element.Items)
|
||||||
dlcIds.Populate(item.Id, title, product, icon, item.Developer, element.Items.Length == 1);
|
dlcIds.Populate(item.Id, title, product, icon, item.Developer, element.Items.Length == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dlcIds;
|
return dlcIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Populate(this List<(string id, string name, string product, string icon, string developer)> dlcIds, string id, string title,
|
private static void Populate(
|
||||||
|
this List<(string id, string name, string product, string icon, string developer)> dlcIds, string id,
|
||||||
|
string title,
|
||||||
string product, string icon, string developer, bool canOverwrite = false)
|
string product, string icon, string developer, bool canOverwrite = false)
|
||||||
{
|
{
|
||||||
if (id == null)
|
if (id == null)
|
||||||
|
@ -97,6 +109,7 @@ internal static class EpicStore
|
||||||
: (app.id, app.name ?? title, app.product ?? product, app.icon ?? icon, app.developer ?? developer);
|
: (app.id, app.name ?? title, app.product ?? product, app.icon ?? icon, app.developer ?? developer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
dlcIds.Add((id, title, product, icon, developer));
|
dlcIds.Add((id, title, product, icon, developer));
|
||||||
}
|
}
|
||||||
|
@ -113,7 +126,8 @@ internal static class EpicStore
|
||||||
HttpClient client = HttpClientManager.HttpClient;
|
HttpClient client = HttpClientManager.HttpClient;
|
||||||
if (client is null)
|
if (client is null)
|
||||||
return null;
|
return null;
|
||||||
HttpResponseMessage httpResponse = await client.PostAsync(new Uri("https://graphql.epicgames.com/graphql"), content);
|
HttpResponseMessage httpResponse =
|
||||||
|
await client.PostAsync(new Uri("https://graphql.epicgames.com/graphql"), content);
|
||||||
_ = httpResponse.EnsureSuccessStatusCode();
|
_ = httpResponse.EnsureSuccessStatusCode();
|
||||||
string response = await httpResponse.Content.ReadAsStringAsync();
|
string response = await httpResponse.Content.ReadAsStringAsync();
|
||||||
return JsonConvert.DeserializeObject<Response>(response);
|
return JsonConvert.DeserializeObject<Response>(response);
|
||||||
|
|
|
@ -10,7 +10,8 @@ namespace CreamInstaller.Platforms.Epic.Heroic;
|
||||||
internal static class HeroicLibrary
|
internal static class HeroicLibrary
|
||||||
{
|
{
|
||||||
internal static readonly string HeroicLibraryPath
|
internal static readonly string HeroicLibraryPath
|
||||||
= Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\heroic\store_cache\legendary_library.json";
|
= Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
|
||||||
|
@"\heroic\store_cache\legendary_library.json";
|
||||||
|
|
||||||
internal static async Task GetGames(List<Manifest> games)
|
internal static async Task GetGames(List<Manifest> games)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
|
@ -28,11 +29,13 @@ internal static class HeroicLibrary
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HeroicAppData appData = token.ToObject<HeroicAppData>();
|
HeroicAppData appData = token.ToObject<HeroicAppData>();
|
||||||
if (appData is null || string.IsNullOrWhiteSpace(appData.Install.InstallPath = appData.Install.InstallPath.ResolvePath()))
|
if (appData is null || string.IsNullOrWhiteSpace(appData.Install.InstallPath =
|
||||||
|
appData.Install.InstallPath.ResolvePath()))
|
||||||
continue;
|
continue;
|
||||||
Manifest manifest = new()
|
Manifest manifest = new()
|
||||||
{
|
{
|
||||||
DisplayName = appData.Title, CatalogNamespace = appData.Namespace, InstallLocation = appData.Install.InstallPath
|
DisplayName = appData.Title, CatalogNamespace = appData.Namespace,
|
||||||
|
InstallLocation = appData.Install.InstallPath
|
||||||
};
|
};
|
||||||
if (games.All(g => g.CatalogNamespace != manifest.CatalogNamespace))
|
if (games.All(g => g.CatalogNamespace != manifest.CatalogNamespace))
|
||||||
games.Add(manifest);
|
games.Add(manifest);
|
||||||
|
|
|
@ -13,7 +13,12 @@ namespace CreamInstaller.Platforms.Paradox;
|
||||||
|
|
||||||
internal static class ParadoxLauncher
|
internal static class ParadoxLauncher
|
||||||
{
|
{
|
||||||
public enum RepairResult { Failure = -1, Unnecessary = 0, Success }
|
public enum RepairResult
|
||||||
|
{
|
||||||
|
Failure = -1,
|
||||||
|
Unnecessary = 0,
|
||||||
|
Success
|
||||||
|
}
|
||||||
|
|
||||||
private static string installPath;
|
private static string installPath;
|
||||||
|
|
||||||
|
@ -21,7 +26,8 @@ internal static class ParadoxLauncher
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Paradox Interactive\Paradox Launcher v2", "LauncherInstallation", null) as string;
|
installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Paradox Interactive\Paradox Launcher v2",
|
||||||
|
"LauncherInstallation", null) as string;
|
||||||
return installPath.ResolvePath();
|
return installPath.ResolvePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,11 +38,13 @@ internal static class ParadoxLauncher
|
||||||
if (paradoxLauncher is null)
|
if (paradoxLauncher is null)
|
||||||
return;
|
return;
|
||||||
paradoxLauncher.ExtraSelections.Clear();
|
paradoxLauncher.ExtraSelections.Clear();
|
||||||
foreach (Selection selection in Selection.AllEnabled.Where(s => !s.Equals(paradoxLauncher) && s.Publisher == "Paradox Interactive"))
|
foreach (Selection selection in Selection.AllEnabled.Where(s =>
|
||||||
|
!s.Equals(paradoxLauncher) && s.Publisher == "Paradox Interactive"))
|
||||||
_ = paradoxLauncher.ExtraSelections.Add(selection);
|
_ = paradoxLauncher.ExtraSelections.Add(selection);
|
||||||
if (paradoxLauncher.ExtraSelections.Count > 0)
|
if (paradoxLauncher.ExtraSelections.Count > 0)
|
||||||
return;
|
return;
|
||||||
foreach (Selection selection in Selection.All.Keys.Where(s => !s.Equals(paradoxLauncher) && s.Publisher == "Paradox Interactive"))
|
foreach (Selection selection in Selection.All.Keys.Where(s =>
|
||||||
|
!s.Equals(paradoxLauncher) && s.Publisher == "Paradox Interactive"))
|
||||||
_ = paradoxLauncher.ExtraSelections.Add(selection);
|
_ = paradoxLauncher.ExtraSelections.Add(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +59,8 @@ internal static class ParadoxLauncher
|
||||||
using DialogForm dialogForm = new(form);
|
using DialogForm dialogForm = new(form);
|
||||||
return dialogForm.Show(SystemIcons.Warning,
|
return dialogForm.Show(SystemIcons.Warning,
|
||||||
"WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!"
|
"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",
|
+ "\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!",
|
||||||
|
"Ignore", "Cancel",
|
||||||
"Paradox Launcher") != DialogResult.OK;
|
"Paradox Launcher") != DialogResult.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +73,7 @@ internal static class ParadoxLauncher
|
||||||
Program.Canceled = false;
|
Program.Canceled = false;
|
||||||
dialogText = new();
|
dialogText = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
using DialogForm dialogForm = new(form);
|
using DialogForm dialogForm = new(form);
|
||||||
bool smokeInstalled = false;
|
bool smokeInstalled = false;
|
||||||
byte[] steamOriginalSdk32 = null;
|
byte[] steamOriginalSdk32 = null;
|
||||||
|
@ -73,36 +83,46 @@ internal static class ParadoxLauncher
|
||||||
byte[] epicOriginalSdk64 = null;
|
byte[] epicOriginalSdk64 = null;
|
||||||
foreach (string directory in selection.DllDirectories.TakeWhile(_ => !Program.Canceled))
|
foreach (string directory in selection.DllDirectories.TakeWhile(_ => !Program.Canceled))
|
||||||
{
|
{
|
||||||
bool koaloaderInstalled = Koaloader.AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
bool koaloaderInstalled = Koaloader.AutoLoadDLLs
|
||||||
.Any(pair => pair.path.FileExists() && pair.path.IsResourceFile());
|
.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config,
|
.Any(pair => pair.path.FileExists() && pair.path.IsResourceFile());
|
||||||
|
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out string old_config,
|
||||||
out string config, out _, out _, out _);
|
out string config, out _, out _, out _);
|
||||||
smokeInstalled = smokeInstalled || api32_o.FileExists() || api64_o.FileExists()
|
smokeInstalled = smokeInstalled || api32_o.FileExists() || api64_o.FileExists()
|
||||||
|| (old_config.FileExists() || config.FileExists()) && !koaloaderInstalled
|
|| (old_config.FileExists() || config.FileExists()) && !koaloaderInstalled
|
||||||
|| api32.FileExists() && api32.IsResourceFile(ResourceIdentifier.Steamworks32)
|
|| api32.FileExists() && api32.IsResourceFile(ResourceIdentifier.Steamworks32)
|
||||||
|| api64.FileExists() && api64.IsResourceFile(ResourceIdentifier.Steamworks64);
|
|| api64.FileExists() && api64.IsResourceFile(ResourceIdentifier.Steamworks64);
|
||||||
await SmokeAPI.Uninstall(directory, deleteOthers: false);
|
await SmokeAPI.Uninstall(directory, deleteOthers: false);
|
||||||
if (steamOriginalSdk32 is null && api32.FileExists() && !api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
if (steamOriginalSdk32 is null && api32.FileExists() &&
|
||||||
|
!api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
||||||
steamOriginalSdk32 = api32.ReadFileBytes(true);
|
steamOriginalSdk32 = api32.ReadFileBytes(true);
|
||||||
if (steamOriginalSdk64 is null && api64.FileExists() && !api64.IsResourceFile(ResourceIdentifier.Steamworks64))
|
if (steamOriginalSdk64 is null && api64.FileExists() &&
|
||||||
|
!api64.IsResourceFile(ResourceIdentifier.Steamworks64))
|
||||||
steamOriginalSdk64 = api64.ReadFileBytes(true);
|
steamOriginalSdk64 = api64.ReadFileBytes(true);
|
||||||
directory.GetScreamApiComponents(out api32, out api32_o, out api64, out api64_o, out config, out string log);
|
directory.GetScreamApiComponents(out api32, out api32_o, out api64, out api64_o, out config,
|
||||||
|
out string log);
|
||||||
screamInstalled = screamInstalled || api32_o.FileExists() || api64_o.FileExists()
|
screamInstalled = screamInstalled || api32_o.FileExists() || api64_o.FileExists()
|
||||||
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled
|
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled
|
||||||
|| api32.FileExists() && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)
|
|| api32.FileExists() && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)
|
||||||
|| api64.FileExists() && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64);
|
|| api64.FileExists() && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64);
|
||||||
await ScreamAPI.Uninstall(directory, deleteOthers: false);
|
await ScreamAPI.Uninstall(directory, deleteOthers: false);
|
||||||
if (epicOriginalSdk32 is null && api32.FileExists() && !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32))
|
if (epicOriginalSdk32 is null && api32.FileExists() &&
|
||||||
|
!api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32))
|
||||||
epicOriginalSdk32 = api32.ReadFileBytes(true);
|
epicOriginalSdk32 = api32.ReadFileBytes(true);
|
||||||
if (epicOriginalSdk64 is null && api64.FileExists() && !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64))
|
if (epicOriginalSdk64 is null && api64.FileExists() &&
|
||||||
|
!api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64))
|
||||||
epicOriginalSdk64 = api64.ReadFileBytes(true);
|
epicOriginalSdk64 = api64.ReadFileBytes(true);
|
||||||
}
|
}
|
||||||
if (steamOriginalSdk32 is not null || steamOriginalSdk64 is not null || epicOriginalSdk32 is not null || epicOriginalSdk64 is not null)
|
|
||||||
|
if (steamOriginalSdk32 is not null || steamOriginalSdk64 is not null || epicOriginalSdk32 is not null ||
|
||||||
|
epicOriginalSdk64 is not null)
|
||||||
{
|
{
|
||||||
bool neededRepair = false;
|
bool neededRepair = false;
|
||||||
foreach (string directory in selection.DllDirectories.TakeWhile(_ => !Program.Canceled))
|
foreach (string directory in selection.DllDirectories.TakeWhile(_ => !Program.Canceled))
|
||||||
{
|
{
|
||||||
directory.GetSmokeApiComponents(out string api32, out _, out string api64, out _, out _, out _, out _, out _, out _);
|
directory.GetSmokeApiComponents(out string api32, out _, out string api64, out _, out _, out _, out _,
|
||||||
|
out _, out _);
|
||||||
if (steamOriginalSdk32 is not null && api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
if (steamOriginalSdk32 is not null && api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
||||||
{
|
{
|
||||||
steamOriginalSdk32.WriteResource(api32);
|
steamOriginalSdk32.WriteResource(api32);
|
||||||
|
@ -112,6 +132,7 @@ internal static class ParadoxLauncher
|
||||||
dialogText.AppendLine("Corrected Steamworks: " + api32);
|
dialogText.AppendLine("Corrected Steamworks: " + api32);
|
||||||
neededRepair = true;
|
neededRepair = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (steamOriginalSdk64 is not null && api64.IsResourceFile(ResourceIdentifier.Steamworks64))
|
if (steamOriginalSdk64 is not null && api64.IsResourceFile(ResourceIdentifier.Steamworks64))
|
||||||
{
|
{
|
||||||
steamOriginalSdk64.WriteResource(api64);
|
steamOriginalSdk64.WriteResource(api64);
|
||||||
|
@ -121,6 +142,7 @@ internal static class ParadoxLauncher
|
||||||
dialogText.AppendLine("Corrected Steamworks: " + api64);
|
dialogText.AppendLine("Corrected Steamworks: " + api64);
|
||||||
neededRepair = true;
|
neededRepair = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smokeInstalled)
|
if (smokeInstalled)
|
||||||
await SmokeAPI.Install(directory, selection, generateConfig: false);
|
await SmokeAPI.Install(directory, selection, generateConfig: false);
|
||||||
directory.GetScreamApiComponents(out api32, out _, out api64, out _, out _, out _);
|
directory.GetScreamApiComponents(out api32, out _, out api64, out _, out _, out _);
|
||||||
|
@ -133,6 +155,7 @@ internal static class ParadoxLauncher
|
||||||
dialogText.AppendLine("Corrected Epic Online Services: " + api32);
|
dialogText.AppendLine("Corrected Epic Online Services: " + api32);
|
||||||
neededRepair = true;
|
neededRepair = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (epicOriginalSdk64 is not null && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64))
|
if (epicOriginalSdk64 is not null && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64))
|
||||||
{
|
{
|
||||||
epicOriginalSdk64.WriteResource(api64);
|
epicOriginalSdk64.WriteResource(api64);
|
||||||
|
@ -142,9 +165,11 @@ internal static class ParadoxLauncher
|
||||||
dialogText.AppendLine("Corrected Epic Online Services: " + api64);
|
dialogText.AppendLine("Corrected Epic Online Services: " + api64);
|
||||||
neededRepair = true;
|
neededRepair = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screamInstalled)
|
if (screamInstalled)
|
||||||
await ScreamAPI.Install(directory, selection, generateConfig: false);
|
await ScreamAPI.Install(directory, selection, generateConfig: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Program.Canceled)
|
if (!Program.Canceled)
|
||||||
{
|
{
|
||||||
if (neededRepair)
|
if (neededRepair)
|
||||||
|
@ -156,28 +181,36 @@ internal static class ParadoxLauncher
|
||||||
dialogText.AppendLine("\nParadox Launcher successfully repaired!");
|
dialogText.AppendLine("\nParadox Launcher successfully repaired!");
|
||||||
_ = dialogForm.Show(form.Icon, dialogText.ToString(), customFormText: "Paradox Launcher");
|
_ = dialogForm.Show(form.Icon, dialogText.ToString(), customFormText: "Paradox Launcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
return RepairResult.Success;
|
return RepairResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installForm is not null)
|
if (installForm is not null)
|
||||||
installForm.UpdateUser("Paradox Launcher did not need to be repaired.", LogTextBox.Success);
|
installForm.UpdateUser("Paradox Launcher did not need to be repaired.", LogTextBox.Success);
|
||||||
else
|
else
|
||||||
_ = dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", customFormText: "Paradox Launcher");
|
_ = dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.",
|
||||||
|
customFormText: "Paradox Launcher");
|
||||||
return RepairResult.Unnecessary;
|
return RepairResult.Unnecessary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
{
|
{
|
||||||
_ = form is InstallForm
|
_ = form is InstallForm
|
||||||
? throw new CustomMessageException("Repair failed! The operation was canceled.")
|
? throw new CustomMessageException("Repair failed! The operation was canceled.")
|
||||||
: dialogForm.Show(SystemIcons.Error, "Paradox Launcher repair failed! The operation was canceled.", customFormText: "Paradox Launcher");
|
: dialogForm.Show(SystemIcons.Error, "Paradox Launcher repair failed! The operation was canceled.",
|
||||||
|
customFormText: "Paradox Launcher");
|
||||||
return RepairResult.Failure;
|
return RepairResult.Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = form is InstallForm
|
_ = form is InstallForm
|
||||||
? throw new CustomMessageException("Repair failed! " + "An original Steamworks and/or Epic Online Services file could not be found. "
|
? throw new CustomMessageException(
|
||||||
+ "You will likely have to reinstall Paradox Launcher to fix this issue.")
|
"Repair failed! " + "An original Steamworks and/or Epic Online Services file could not be found. "
|
||||||
|
+ "You will likely have to reinstall Paradox Launcher to fix this issue.")
|
||||||
: dialogForm.Show(SystemIcons.Error,
|
: dialogForm.Show(SystemIcons.Error,
|
||||||
"Paradox Launcher repair failed!" + "\n\nAn original Steamworks and/or Epic Online Services file could not be found."
|
"Paradox Launcher repair failed!" + "\n\nAn original Steamworks and/or Epic Online Services file could not be found."
|
||||||
+ "\nYou will likely have to reinstall Paradox Launcher to fix this issue.", customFormText: "Paradox Launcher");
|
+ "\nYou will likely have to reinstall Paradox Launcher to fix this issue.",
|
||||||
|
customFormText: "Paradox Launcher");
|
||||||
return RepairResult.Failure;
|
return RepairResult.Failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,7 +23,8 @@ internal static class SteamCMD
|
||||||
|
|
||||||
private static readonly string FilePath = DirectoryPath + @"\steamcmd.exe";
|
private static readonly string FilePath = DirectoryPath + @"\steamcmd.exe";
|
||||||
|
|
||||||
private static readonly ConcurrentDictionary<string, int> AttemptCount = new(); // the more app_updates, the longer SteamCMD should wait for app_info_print
|
private static readonly ConcurrentDictionary<string, int>
|
||||||
|
AttemptCount = new(); // the more app_updates, the longer SteamCMD should wait for app_info_print
|
||||||
|
|
||||||
private static readonly int[] Locks = new int[ProcessLimit];
|
private static readonly int[] Locks = new int[ProcessLimit];
|
||||||
|
|
||||||
|
@ -42,13 +43,13 @@ internal static class SteamCMD
|
||||||
private static string GetArguments(string appId)
|
private static string GetArguments(string appId)
|
||||||
=> AttemptCount.TryGetValue(appId, out int attempts)
|
=> AttemptCount.TryGetValue(appId, out int attempts)
|
||||||
? $@"@ShutdownOnFailedCommand 0 +force_install_dir {DirectoryPath} +login anonymous +app_info_print {appId} "
|
? $@"@ShutdownOnFailedCommand 0 +force_install_dir {DirectoryPath} +login anonymous +app_info_print {appId} "
|
||||||
+ string.Concat(Enumerable.Repeat("+app_update 4 ", attempts)) + "+quit"
|
+ string.Concat(Enumerable.Repeat("+app_update 4 ", attempts)) + "+quit"
|
||||||
: $"+login anonymous +app_info_print {appId} +quit";
|
: $"+login anonymous +app_info_print {appId} +quit";
|
||||||
|
|
||||||
private static async Task<string> Run(string appId)
|
private static async Task<string> Run(string appId)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
wait_for_lock:
|
wait_for_lock:
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return "";
|
return "";
|
||||||
for (int i = 0; i < Locks.Length; i++)
|
for (int i = 0; i < Locks.Length; i++)
|
||||||
|
@ -62,13 +63,17 @@ internal static class SteamCMD
|
||||||
_ = AttemptCount.TryGetValue(appId, out int count);
|
_ = AttemptCount.TryGetValue(appId, out int count);
|
||||||
AttemptCount[appId] = ++count;
|
AttemptCount[appId] = ++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return "";
|
return "";
|
||||||
ProcessStartInfo processStartInfo = new()
|
ProcessStartInfo processStartInfo = new()
|
||||||
{
|
{
|
||||||
FileName = FilePath, RedirectStandardOutput = true, RedirectStandardInput = true, RedirectStandardError = true,
|
FileName = FilePath, RedirectStandardOutput = true, RedirectStandardInput = true,
|
||||||
UseShellExecute = false, Arguments = appId is null ? "+quit" : GetArguments(appId), CreateNoWindow = true,
|
RedirectStandardError = true,
|
||||||
StandardInputEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8
|
UseShellExecute = false, Arguments = appId is null ? "+quit" : GetArguments(appId),
|
||||||
|
CreateNoWindow = true,
|
||||||
|
StandardInputEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8,
|
||||||
|
StandardErrorEncoding = Encoding.UTF8
|
||||||
};
|
};
|
||||||
Process process = Process.Start(processStartInfo);
|
Process process = Process.Start(processStartInfo);
|
||||||
StringBuilder output = new();
|
StringBuilder output = new();
|
||||||
|
@ -83,6 +88,7 @@ internal static class SteamCMD
|
||||||
process.Close();
|
process.Close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int c = process.StandardOutput.Read();
|
int c = process.StandardOutput.Read();
|
||||||
if (c != -1)
|
if (c != -1)
|
||||||
{
|
{
|
||||||
|
@ -92,13 +98,15 @@ internal static class SteamCMD
|
||||||
appInfoStarted = true;
|
appInfoStarted = true;
|
||||||
_ = appInfoStarted ? appInfo.Append(ch) : output.Append(ch);
|
_ = appInfoStarted ? appInfo.Append(ch) : output.Append(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime now = DateTime.UtcNow;
|
DateTime now = DateTime.UtcNow;
|
||||||
TimeSpan timeDiff = now - lastOutput;
|
TimeSpan timeDiff = now - lastOutput;
|
||||||
if (!(timeDiff.TotalSeconds > 0.1))
|
if (!(timeDiff.TotalSeconds > 0.1))
|
||||||
continue;
|
continue;
|
||||||
process.Kill(true);
|
process.Kill(true);
|
||||||
process.Close();
|
process.Close();
|
||||||
if (appId != null && output.ToString().Contains($"No app info for AppID {appId} found, requesting..."))
|
if (appId != null &&
|
||||||
|
output.ToString().Contains($"No app info for AppID {appId} found, requesting..."))
|
||||||
{
|
{
|
||||||
AttemptCount[appId]++;
|
AttemptCount[appId]++;
|
||||||
processStartInfo.Arguments = GetArguments(appId);
|
processStartInfo.Arguments = GetArguments(appId);
|
||||||
|
@ -110,9 +118,11 @@ internal static class SteamCMD
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = Interlocked.Decrement(ref Locks[i]);
|
_ = Interlocked.Decrement(ref Locks[i]);
|
||||||
return appInfo.ToString();
|
return appInfo.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.Sleep(200);
|
Thread.Sleep(200);
|
||||||
goto wait_for_lock;
|
goto wait_for_lock;
|
||||||
});
|
});
|
||||||
|
@ -122,14 +132,16 @@ internal static class SteamCMD
|
||||||
await Cleanup();
|
await Cleanup();
|
||||||
if (!FilePath.FileExists())
|
if (!FilePath.FileExists())
|
||||||
{
|
{
|
||||||
retryDownload:
|
retryDownload:
|
||||||
HttpClient httpClient = HttpClientManager.HttpClient;
|
HttpClient httpClient = HttpClientManager.HttpClient;
|
||||||
if (httpClient is null)
|
if (httpClient is null)
|
||||||
return false;
|
return false;
|
||||||
while (!Program.Canceled)
|
while (!Program.Canceled)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] file = await httpClient.GetByteArrayAsync(new Uri("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"));
|
byte[] file =
|
||||||
|
await httpClient.GetByteArrayAsync(
|
||||||
|
new Uri("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"));
|
||||||
_ = file.WriteResource(ArchivePath);
|
_ = file.WriteResource(ArchivePath);
|
||||||
ArchivePath.ExtractZip(DirectoryPath);
|
ArchivePath.ExtractZip(DirectoryPath);
|
||||||
ArchivePath.DeleteFile();
|
ArchivePath.DeleteFile();
|
||||||
|
@ -142,9 +154,11 @@ internal static class SteamCMD
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DllPath.FileExists())
|
if (DllPath.FileExists())
|
||||||
return true;
|
return true;
|
||||||
FileSystemWatcher watcher = new(DirectoryPath) { Filter = "*", IncludeSubdirectories = true, EnableRaisingEvents = true };
|
FileSystemWatcher watcher = new(DirectoryPath)
|
||||||
|
{ Filter = "*", IncludeSubdirectories = true, EnableRaisingEvents = true };
|
||||||
if (DllPath.FileExists())
|
if (DllPath.FileExists())
|
||||||
progress.Report(-15); // update (not used at the moment)
|
progress.Report(-15); // update (not used at the moment)
|
||||||
else
|
else
|
||||||
|
@ -176,7 +190,8 @@ internal static class SteamCMD
|
||||||
file.DeleteFile();
|
file.DeleteFile();
|
||||||
foreach (string file in DirectoryPath.EnumerateDirectory("*.ntfs_transaction_failed"))
|
foreach (string file in DirectoryPath.EnumerateDirectory("*.ntfs_transaction_failed"))
|
||||||
file.DeleteFile();
|
file.DeleteFile();
|
||||||
AppCachePath.DeleteDirectory(); // this is definitely needed, so SteamCMD gets the latest information for us
|
AppCachePath
|
||||||
|
.DeleteDirectory(); // this is definitely needed, so SteamCMD gets the latest information for us
|
||||||
DumpsPath.DeleteDirectory();
|
DumpsPath.DeleteDirectory();
|
||||||
LogsPath.DeleteDirectory();
|
LogsPath.DeleteDirectory();
|
||||||
SteamAppsPath.DeleteDirectory(); // this is just a useless folder created from +app_update 4
|
SteamAppsPath.DeleteDirectory(); // this is just a useless folder created from +app_update 4
|
||||||
|
@ -196,10 +211,12 @@ internal static class SteamCMD
|
||||||
if (attempts > 10)
|
if (attempts > 10)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log("Failed to query SteamCMD after 10 tries: " + appId + " (" + branch + ")", LogTextBox.Warning);
|
DebugForm.Current.Log("Failed to query SteamCMD after 10 tries: " + appId + " (" + branch + ")",
|
||||||
|
LogTextBox.Warning);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
string appUpdateFile = $@"{AppInfoPath}\{appId}.vdf";
|
string appUpdateFile = $@"{AppInfoPath}\{appId}.vdf";
|
||||||
string output = appUpdateFile.ReadFile();
|
string output = appUpdateFile.ReadFile();
|
||||||
if (output is null)
|
if (output is null)
|
||||||
|
@ -216,27 +233,34 @@ internal static class SteamCMD
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log("SteamCMD query failed on attempt #" + attempts + " for " + appId + " (" + branch + "): Bad output",
|
DebugForm.Current.Log(
|
||||||
|
"SteamCMD query failed on attempt #" + attempts + " for " + appId + " (" + branch +
|
||||||
|
"): Bad output",
|
||||||
LogTextBox.Warning);
|
LogTextBox.Warning);
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ValveDataFile.TryDeserialize(output, out VProperty appInfo) || appInfo.Value is VValue)
|
if (!ValveDataFile.TryDeserialize(output, out VProperty appInfo) || appInfo.Value is VValue)
|
||||||
{
|
{
|
||||||
appUpdateFile.DeleteFile();
|
appUpdateFile.DeleteFile();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log("SteamCMD query failed on attempt #" + attempts + " for " + appId + " (" + branch + "): Deserialization failed",
|
DebugForm.Current.Log(
|
||||||
|
"SteamCMD query failed on attempt #" + attempts + " for " + appId + " (" + branch +
|
||||||
|
"): Deserialization failed",
|
||||||
LogTextBox.Warning);
|
LogTextBox.Warning);
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!appInfo.Value.Children().Any())
|
if (!appInfo.Value.Children().Any())
|
||||||
return appInfo;
|
return appInfo;
|
||||||
VToken type = appInfo.Value.GetChild("common")?.GetChild("type");
|
VToken type = appInfo.Value.GetChild("common")?.GetChild("type");
|
||||||
if (type is not null && type.ToString() != "Game")
|
if (type is not null && type.ToString() != "Game")
|
||||||
return appInfo;
|
return appInfo;
|
||||||
string buildid = appInfo.Value.GetChild("depots")?.GetChild("branches")?.GetChild(branch)?.GetChild("buildid")?.ToString();
|
string buildid = appInfo.Value.GetChild("depots")?.GetChild("branches")?.GetChild(branch)
|
||||||
|
?.GetChild("buildid")?.ToString();
|
||||||
if (buildid is null && type is not null)
|
if (buildid is null && type is not null)
|
||||||
return appInfo;
|
return appInfo;
|
||||||
if (type is not null && (!int.TryParse(buildid, out int gamebuildId) || gamebuildId >= buildId))
|
if (type is not null && (!int.TryParse(buildid, out int gamebuildId) || gamebuildId >= buildId))
|
||||||
|
@ -246,9 +270,12 @@ internal static class SteamCMD
|
||||||
dlcAppUpdateFile.DeleteFile();
|
dlcAppUpdateFile.DeleteFile();
|
||||||
appUpdateFile.DeleteFile();
|
appUpdateFile.DeleteFile();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log("SteamCMD query skipped on attempt #" + attempts + " for " + appId + " (" + branch + "): Outdated cache", LogTextBox.Warning);
|
DebugForm.Current.Log(
|
||||||
|
"SteamCMD query skipped on attempt #" + attempts + " for " + appId + " (" + branch +
|
||||||
|
"): Outdated cache", LogTextBox.Warning);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,15 +294,18 @@ internal static class SteamCMD
|
||||||
if (int.TryParse(id, out int appId) && appId > 0)
|
if (int.TryParse(id, out int appId) && appId > 0)
|
||||||
_ = dlcIds.Add("" + appId);
|
_ = dlcIds.Add("" + appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
VToken depots = appInfo.Value.GetChild("depots");
|
VToken depots = appInfo.Value.GetChild("depots");
|
||||||
if (depots is null)
|
if (depots is null)
|
||||||
return dlcIds;
|
return dlcIds;
|
||||||
foreach (VToken vToken in depots.Where(p => p is VProperty property && int.TryParse(property.Key, out int _)))
|
foreach (VToken vToken in depots.Where(
|
||||||
|
p => p is VProperty property && int.TryParse(property.Key, out int _)))
|
||||||
{
|
{
|
||||||
VProperty property = (VProperty)vToken;
|
VProperty property = (VProperty)vToken;
|
||||||
if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0)
|
if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0)
|
||||||
_ = dlcIds.Add("" + appId);
|
_ = dlcIds.Add("" + appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dlcIds;
|
return dlcIds;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,14 @@ internal static class SteamLibrary
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Valve\Steam", "SteamPath", null) as string;
|
installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Valve\Steam", "SteamPath", null) as string;
|
||||||
installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", null) as string;
|
installPath ??=
|
||||||
|
Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", null) as string;
|
||||||
return installPath.ResolvePath();
|
return installPath.ResolvePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>> GetGames()
|
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>>
|
||||||
|
GetGames()
|
||||||
=> await Task.Run(async () =>
|
=> await Task.Run(async () =>
|
||||||
{
|
{
|
||||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||||
|
@ -30,10 +32,12 @@ internal static class SteamLibrary
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return games;
|
return games;
|
||||||
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in (await GetGamesFromLibraryDirectory(
|
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in (await
|
||||||
libraryDirectory)).Where(game => games.All(_game => _game.appId != game.appId)))
|
GetGamesFromLibraryDirectory(
|
||||||
|
libraryDirectory)).Where(game => games.All(_game => _game.appId != game.appId)))
|
||||||
games.Add(game);
|
games.Add(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
return games;
|
return games;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -54,11 +58,13 @@ internal static class SteamLibrary
|
||||||
string installdir = result.Value.GetChild("installdir")?.ToString();
|
string installdir = result.Value.GetChild("installdir")?.ToString();
|
||||||
string name = result.Value.GetChild("name")?.ToString();
|
string name = result.Value.GetChild("name")?.ToString();
|
||||||
string buildId = result.Value.GetChild("buildid")?.ToString();
|
string buildId = result.Value.GetChild("buildid")?.ToString();
|
||||||
if (string.IsNullOrWhiteSpace(appId) || string.IsNullOrWhiteSpace(installdir) || string.IsNullOrWhiteSpace(name)
|
if (string.IsNullOrWhiteSpace(appId) || string.IsNullOrWhiteSpace(installdir) ||
|
||||||
|| string.IsNullOrWhiteSpace(buildId))
|
string.IsNullOrWhiteSpace(name)
|
||||||
|
|| string.IsNullOrWhiteSpace(buildId))
|
||||||
continue;
|
continue;
|
||||||
string gameDirectory = (libraryDirectory + @"\common\" + installdir).ResolvePath();
|
string gameDirectory = (libraryDirectory + @"\common\" + installdir).ResolvePath();
|
||||||
if (gameDirectory is null || !int.TryParse(appId, out int _) || !int.TryParse(buildId, out int buildIdInt) || games.Any(g => g.appId == appId))
|
if (gameDirectory is null || !int.TryParse(appId, out int _) ||
|
||||||
|
!int.TryParse(buildId, out int buildIdInt) || games.Any(g => g.appId == appId))
|
||||||
continue;
|
continue;
|
||||||
VToken userConfig = result.Value.GetChild("UserConfig");
|
VToken userConfig = result.Value.GetChild("UserConfig");
|
||||||
string branch = userConfig?.GetChild("BetaKey")?.ToString();
|
string branch = userConfig?.GetChild("BetaKey")?.ToString();
|
||||||
|
@ -69,10 +75,12 @@ internal static class SteamLibrary
|
||||||
branch = mountedConfig?.GetChild("BetaKey")?.ToString();
|
branch = mountedConfig?.GetChild("BetaKey")?.ToString();
|
||||||
branch ??= mountedConfig?.GetChild("betakey")?.ToString();
|
branch ??= mountedConfig?.GetChild("betakey")?.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(branch))
|
if (string.IsNullOrWhiteSpace(branch))
|
||||||
branch = "public";
|
branch = "public";
|
||||||
games.Add((appId, name, branch, buildIdInt, gameDirectory));
|
games.Add((appId, name, branch, buildIdInt, gameDirectory));
|
||||||
}
|
}
|
||||||
|
|
||||||
return games;
|
return games;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,9 +98,11 @@ internal static class SteamLibrary
|
||||||
return libraryDirectories;
|
return libraryDirectories;
|
||||||
_ = libraryDirectories.Add(libraryFolder);
|
_ = libraryDirectories.Add(libraryFolder);
|
||||||
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
|
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
|
||||||
if (!libraryFolders.FileExists() || !ValveDataFile.TryDeserialize(libraryFolders.ReadFile(), out VProperty result))
|
if (!libraryFolders.FileExists() ||
|
||||||
|
!ValveDataFile.TryDeserialize(libraryFolders.ReadFile(), out VProperty result))
|
||||||
return libraryDirectories;
|
return libraryDirectories;
|
||||||
foreach (VToken vToken in result.Value.Where(p => p is VProperty property && int.TryParse(property.Key, out int _)))
|
foreach (VToken vToken in result.Value.Where(p =>
|
||||||
|
p is VProperty property && int.TryParse(property.Key, out int _)))
|
||||||
{
|
{
|
||||||
VProperty property = (VProperty)vToken;
|
VProperty property = (VProperty)vToken;
|
||||||
string path = property.Value.GetChild("path")?.ToString();
|
string path = property.Value.GetChild("path")?.ToString();
|
||||||
|
@ -102,6 +112,7 @@ internal static class SteamLibrary
|
||||||
if (path.DirectoryExists())
|
if (path.DirectoryExists())
|
||||||
_ = libraryDirectories.Add(path);
|
_ = libraryDirectories.Add(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return libraryDirectories;
|
return libraryDirectories;
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -24,7 +24,9 @@ internal static class SteamStore
|
||||||
HashSet<string> dlcIds = new();
|
HashSet<string> dlcIds = new();
|
||||||
if (appData.DLC is null)
|
if (appData.DLC is null)
|
||||||
return dlcIds;
|
return dlcIds;
|
||||||
foreach (string dlcId in from appId in appData.DLC where appId > 0 select appId.ToString(CultureInfo.InvariantCulture))
|
foreach (string dlcId in from appId in appData.DLC
|
||||||
|
where appId > 0
|
||||||
|
select appId.ToString(CultureInfo.InvariantCulture))
|
||||||
_ = dlcIds.Add(dlcId);
|
_ = dlcIds.Add(dlcId);
|
||||||
return dlcIds;
|
return dlcIds;
|
||||||
});
|
});
|
||||||
|
@ -38,10 +40,12 @@ internal static class SteamStore
|
||||||
bool cachedExists = cacheFile.FileExists();
|
bool cachedExists = cacheFile.FileExists();
|
||||||
if (!cachedExists || ProgramData.CheckCooldown(appId, isDlc ? CooldownDlc : CooldownGame))
|
if (!cachedExists || ProgramData.CheckCooldown(appId, isDlc ? CooldownDlc : CooldownGame))
|
||||||
{
|
{
|
||||||
string response = await HttpClientManager.EnsureGet($"https://store.steampowered.com/api/appdetails?appids={appId}");
|
string response =
|
||||||
|
await HttpClientManager.EnsureGet($"https://store.steampowered.com/api/appdetails?appids={appId}");
|
||||||
if (response is not null)
|
if (response is not null)
|
||||||
{
|
{
|
||||||
Dictionary<string, JToken> apps = JsonConvert.DeserializeObject<Dictionary<string, JToken>>(response);
|
Dictionary<string, JToken> apps =
|
||||||
|
JsonConvert.DeserializeObject<Dictionary<string, JToken>>(response);
|
||||||
if (apps is not null)
|
if (apps is not null)
|
||||||
foreach (KeyValuePair<string, JToken> app in apps)
|
foreach (KeyValuePair<string, JToken> app in apps)
|
||||||
try
|
try
|
||||||
|
@ -54,12 +58,15 @@ internal static class SteamStore
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log(
|
DebugForm.Current.Log(
|
||||||
"Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "")
|
"Steam store query failed on attempt #" + attempts + " for " + appId +
|
||||||
+ ": Query unsuccessful (" + app.Value.ToString(Formatting.None) + ")", LogTextBox.Warning);
|
(isDlc ? " (DLC)" : "")
|
||||||
|
+ ": Query unsuccessful (" + app.Value.ToString(Formatting.None) + ")",
|
||||||
|
LogTextBox.Warning);
|
||||||
#endif
|
#endif
|
||||||
if (data is null)
|
if (data is null)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data is not null)
|
if (data is not null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -70,8 +77,9 @@ internal static class SteamStore
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
(Exception e)
|
(Exception e)
|
||||||
{
|
{
|
||||||
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "")
|
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts +
|
||||||
+ ": Unsuccessful serialization (" + e.Message + ")");
|
" for " + appId + (isDlc ? " (DLC)" : "")
|
||||||
|
+ ": Unsuccessful serialization (" + e.Message + ")");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -81,22 +89,27 @@ internal static class SteamStore
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "")
|
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " +
|
||||||
+ ": Response data null (" + app.Value.ToString(Formatting.None) + ")");
|
appId + (isDlc ? " (DLC)" : "")
|
||||||
|
+ ": Response data null (" +
|
||||||
|
app.Value.ToString(Formatting.None) + ")");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
else
|
else
|
||||||
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "")
|
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " +
|
||||||
+ ": Response details null (" + app.Value.ToString(Formatting.None) + ")");
|
appId + (isDlc ? " (DLC)" : "")
|
||||||
|
+ ": Response details null (" +
|
||||||
|
app.Value.ToString(Formatting.None) + ")");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
(Exception e)
|
(Exception e)
|
||||||
{
|
{
|
||||||
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "")
|
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " +
|
||||||
+ ": Unsuccessful deserialization (" + e.Message + ")");
|
appId + (isDlc ? " (DLC)" : "")
|
||||||
|
+ ": Unsuccessful deserialization (" + e.Message + ")");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -105,18 +118,22 @@ internal static class SteamStore
|
||||||
#endif
|
#endif
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
else
|
else
|
||||||
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "")
|
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId +
|
||||||
+ ": Response deserialization null");
|
(isDlc ? " (DLC)" : "")
|
||||||
|
+ ": Response deserialization null");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugForm.Current.Log("Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "") + ": Response null",
|
DebugForm.Current.Log(
|
||||||
|
"Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "") +
|
||||||
|
": Response null",
|
||||||
LogTextBox.Warning);
|
LogTextBox.Warning);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedExists)
|
if (cachedExists)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -126,6 +143,7 @@ internal static class SteamStore
|
||||||
{
|
{
|
||||||
cacheFile.DeleteFile();
|
cacheFile.DeleteFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDlc)
|
if (isDlc)
|
||||||
break;
|
break;
|
||||||
if (attempts > 10)
|
if (attempts > 10)
|
||||||
|
@ -135,8 +153,10 @@ internal static class SteamStore
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,6 +17,7 @@ internal static class ValveDataFile
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ internal static class ValveDataFile
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,6 +34,7 @@ internal static class UbisoftLibrary
|
||||||
if (installDir is not null && games.All(g => g.gameId != gameId))
|
if (installDir is not null && games.All(g => g.gameId != gameId))
|
||||||
games.Add((gameId, new DirectoryInfo(installDir).Name, installDir));
|
games.Add((gameId, new DirectoryInfo(installDir).Name, installDir));
|
||||||
}
|
}
|
||||||
|
|
||||||
return games;
|
return games;
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -13,7 +13,11 @@ internal static class Program
|
||||||
{
|
{
|
||||||
internal static readonly string Name = Application.CompanyName;
|
internal static readonly string Name = Application.CompanyName;
|
||||||
private static readonly string Description = Application.ProductName;
|
private static readonly string Description = Application.ProductName;
|
||||||
internal static readonly string Version = Application.ProductVersion[..(Application.ProductVersion.IndexOf('+') is var index && index != -1 ? index : Application.ProductVersion.Length)];
|
|
||||||
|
internal static readonly string Version = Application.ProductVersion[
|
||||||
|
..(Application.ProductVersion.IndexOf('+') is var index && index != -1
|
||||||
|
? index
|
||||||
|
: Application.ProductVersion.Length)];
|
||||||
|
|
||||||
internal const string RepositoryOwner = "pointfeev";
|
internal const string RepositoryOwner = "pointfeev";
|
||||||
internal static readonly string RepositoryName = Name;
|
internal static readonly string RepositoryName = Name;
|
||||||
|
@ -37,8 +41,9 @@ internal static class Program
|
||||||
internal static readonly string[] ProtectedGameDirectoryExceptions = [];
|
internal static readonly string[] ProtectedGameDirectoryExceptions = [];
|
||||||
|
|
||||||
internal static bool IsGameBlocked(string name, string directory = null)
|
internal static bool IsGameBlocked(string name, string directory = null)
|
||||||
=> BlockProtectedGames && (ProtectedGames.Contains(name) || directory is not null && !ProtectedGameDirectoryExceptions.Contains(name)
|
=> BlockProtectedGames && (ProtectedGames.Contains(name) || directory is not null &&
|
||||||
&& ProtectedGameDirectories.Any(path => (directory + path).DirectoryExists()));
|
!ProtectedGameDirectoryExceptions.Contains(name)
|
||||||
|
&& ProtectedGameDirectories.Any(path => (directory + path).DirectoryExists()));
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
private static void Main()
|
private static void Main()
|
||||||
|
@ -52,8 +57,9 @@ internal static class Program
|
||||||
Application.ApplicationExit += OnApplicationExit;
|
Application.ApplicationExit += OnApplicationExit;
|
||||||
Application.ThreadException += (_, e) => e.Exception.HandleFatalException();
|
Application.ThreadException += (_, e) => e.Exception.HandleFatalException();
|
||||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||||
AppDomain.CurrentDomain.UnhandledException += (_, e) => (e.ExceptionObject as Exception)?.HandleFatalException();
|
AppDomain.CurrentDomain.UnhandledException +=
|
||||||
retry:
|
(_, e) => (e.ExceptionObject as Exception)?.HandleFatalException();
|
||||||
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpClientManager.Setup();
|
HttpClientManager.Setup();
|
||||||
|
@ -71,6 +77,7 @@ internal static class Program
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex.Close();
|
mutex.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,16 @@ internal static class Koaloader
|
||||||
{
|
{
|
||||||
internal static readonly List<(string unlocker, string dll)> AutoLoadDLLs =
|
internal static readonly List<(string unlocker, string dll)> AutoLoadDLLs =
|
||||||
[
|
[
|
||||||
("Koaloader", "Unlocker.dll"), ("Koaloader", "Unlocker32.dll"), ("Koaloader", "Unlocker64.dll"), ("Lyptus", "Lyptus.dll"),
|
("Koaloader", "Unlocker.dll"), ("Koaloader", "Unlocker32.dll"), ("Koaloader", "Unlocker64.dll"),
|
||||||
("Lyptus", "Lyptus32.dll"), ("Lyptus", "Lyptus64.dll"), ("SmokeAPI", "SmokeAPI.dll"), ("SmokeAPI", "SmokeAPI32.dll"),
|
("Lyptus", "Lyptus.dll"),
|
||||||
("SmokeAPI", "SmokeAPI64.dll"), ("ScreamAPI", "ScreamAPI.dll"), ("ScreamAPI", "ScreamAPI32.dll"), ("ScreamAPI", "ScreamAPI64.dll"),
|
("Lyptus", "Lyptus32.dll"), ("Lyptus", "Lyptus64.dll"), ("SmokeAPI", "SmokeAPI.dll"),
|
||||||
("Uplay R1 Unlocker", "UplayR1Unlocker.dll"), ("Uplay R1 Unlocker", "UplayR1Unlocker32.dll"), ("Uplay R1 Unlocker", "UplayR1Unlocker64.dll"),
|
("SmokeAPI", "SmokeAPI32.dll"),
|
||||||
("Uplay R2 Unlocker", "UplayR2Unlocker.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker32.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker64.dll")
|
("SmokeAPI", "SmokeAPI64.dll"), ("ScreamAPI", "ScreamAPI.dll"), ("ScreamAPI", "ScreamAPI32.dll"),
|
||||||
|
("ScreamAPI", "ScreamAPI64.dll"),
|
||||||
|
("Uplay R1 Unlocker", "UplayR1Unlocker.dll"), ("Uplay R1 Unlocker", "UplayR1Unlocker32.dll"),
|
||||||
|
("Uplay R1 Unlocker", "UplayR1Unlocker64.dll"),
|
||||||
|
("Uplay R2 Unlocker", "UplayR2Unlocker.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker32.dll"),
|
||||||
|
("Uplay R2 Unlocker", "UplayR2Unlocker64.dll")
|
||||||
];
|
];
|
||||||
|
|
||||||
internal static IEnumerable<string> GetKoaloaderProxies(this string directory)
|
internal static IEnumerable<string> GetKoaloaderProxies(this string directory)
|
||||||
|
@ -38,7 +43,8 @@ internal static class Koaloader
|
||||||
|
|
||||||
private static void WriteProxy(this string path, string proxyName, BinaryType binaryType)
|
private static void WriteProxy(this string path, string proxyName, BinaryType binaryType)
|
||||||
{
|
{
|
||||||
foreach (string resourceIdentifier in EmbeddedResources.Where(r => r.StartsWith("Koaloader", StringComparison.Ordinal)))
|
foreach (string resourceIdentifier in EmbeddedResources.Where(r =>
|
||||||
|
r.StartsWith("Koaloader", StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
resourceIdentifier.GetProxyInfoFromIdentifier(out string _proxyName, out BinaryType _binaryType);
|
resourceIdentifier.GetProxyInfoFromIdentifier(out string _proxyName, out BinaryType _binaryType);
|
||||||
if (_proxyName != proxyName || _binaryType != binaryType)
|
if (_proxyName != proxyName || _binaryType != binaryType)
|
||||||
|
@ -48,7 +54,8 @@ internal static class Koaloader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void GetProxyInfoFromIdentifier(this string resourceIdentifier, out string proxyName, out BinaryType binaryType)
|
internal static void GetProxyInfoFromIdentifier(this string resourceIdentifier, out string proxyName,
|
||||||
|
out BinaryType binaryType)
|
||||||
{
|
{
|
||||||
string baseIdentifier = resourceIdentifier[(resourceIdentifier.IndexOf('.') + 1)..];
|
string baseIdentifier = resourceIdentifier[(resourceIdentifier.IndexOf('.') + 1)..];
|
||||||
baseIdentifier = baseIdentifier[..baseIdentifier.IndexOf('.')];
|
baseIdentifier = baseIdentifier[..baseIdentifier.IndexOf('.')];
|
||||||
|
@ -65,14 +72,18 @@ internal static class Koaloader
|
||||||
if (!config.FileExists())
|
if (!config.FileExists())
|
||||||
{
|
{
|
||||||
old_config.MoveFile(config!);
|
old_config.MoveFile(config!);
|
||||||
installForm?.UpdateUser($"Converted old configuration: {Path.GetFileName(old_config)} -> {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Converted old configuration: {Path.GetFileName(old_config)} -> {Path.GetFileName(config)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
old_config.DeleteFile();
|
old_config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedList<string, string> targets = new(PlatformIdComparer.String);
|
SortedList<string, string> targets = new(PlatformIdComparer.String);
|
||||||
SortedList<string, string> modules = new(PlatformIdComparer.String);
|
SortedList<string, string> modules = new(PlatformIdComparer.String);
|
||||||
if (targets.Count > 0 || modules.Count > 0)
|
if (targets.Count > 0 || modules.Count > 0)
|
||||||
|
@ -88,11 +99,13 @@ internal static class Koaloader
|
||||||
else if (config.FileExists())
|
else if (config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteConfig(StreamWriter writer, SortedList<string, string> targets, SortedList<string, string> modules, InstallForm installForm = null)
|
private static void WriteConfig(StreamWriter writer, SortedList<string, string> targets,
|
||||||
|
SortedList<string, string> modules, InstallForm installForm = null)
|
||||||
{
|
{
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
writer.WriteLine(" \"logging\": false,");
|
writer.WriteLine(" \"logging\": false,");
|
||||||
|
@ -108,10 +121,12 @@ internal static class Koaloader
|
||||||
writer.WriteLine($" \"{path}\"{(pair.Equals(lastTarget) ? "" : ",")}");
|
writer.WriteLine($" \"{path}\"{(pair.Equals(lastTarget) ? "" : ",")}");
|
||||||
installForm?.UpdateUser($"Added target to Koaloader.json with path {path}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Added target to Koaloader.json with path {path}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" ]");
|
writer.WriteLine(" ]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"targets\": []");
|
writer.WriteLine(" \"targets\": []");
|
||||||
|
|
||||||
if (modules.Count > 0)
|
if (modules.Count > 0)
|
||||||
{
|
{
|
||||||
writer.WriteLine(" \"modules\": [");
|
writer.WriteLine(" \"modules\": [");
|
||||||
|
@ -125,39 +140,48 @@ internal static class Koaloader
|
||||||
writer.WriteLine(" }" + (pair.Equals(lastModule) ? "" : ","));
|
writer.WriteLine(" }" + (pair.Equals(lastModule) ? "" : ","));
|
||||||
installForm?.UpdateUser($"Added module to Koaloader.json with path {path}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Added module to Koaloader.json with path {path}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" ]");
|
writer.WriteLine(" ]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"modules\": []");
|
writer.WriteLine(" \"modules\": []");
|
||||||
|
|
||||||
writer.WriteLine("}");
|
writer.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task Uninstall(string directory, string rootDirectory = null, InstallForm installForm = null, bool deleteConfig = true)
|
internal static async Task Uninstall(string directory, string rootDirectory = null, InstallForm installForm = null,
|
||||||
|
bool deleteConfig = true)
|
||||||
=> await Task.Run(async () =>
|
=> await Task.Run(async () =>
|
||||||
{
|
{
|
||||||
directory.GetKoaloaderComponents(out string old_config, out string config);
|
directory.GetKoaloaderComponents(out string old_config, out string config);
|
||||||
foreach (string proxyPath in directory.GetKoaloaderProxies().Where(proxyPath
|
foreach (string proxyPath in directory.GetKoaloaderProxies().Where(proxyPath
|
||||||
=> proxyPath.FileExists() && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader)))
|
=> proxyPath.FileExists() && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||||
{
|
{
|
||||||
proxyPath.DeleteFile(true);
|
proxyPath.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
foreach ((string unlocker, string path) in AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
|
||||||
.Where(pair => pair.path.FileExists() && pair.path.IsResourceFile()))
|
foreach ((string unlocker, string path) in AutoLoadDLLs
|
||||||
|
.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||||
|
.Where(pair => pair.path.FileExists() && pair.path.IsResourceFile()))
|
||||||
{
|
{
|
||||||
path.DeleteFile(true);
|
path.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteConfig && old_config.FileExists())
|
if (deleteConfig && old_config.FileExists())
|
||||||
{
|
{
|
||||||
old_config.DeleteFile();
|
old_config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteConfig && config.FileExists())
|
if (deleteConfig && config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await SmokeAPI.Uninstall(directory, installForm, deleteConfig);
|
await SmokeAPI.Uninstall(directory, installForm, deleteConfig);
|
||||||
await ScreamAPI.Uninstall(directory, installForm, deleteConfig);
|
await ScreamAPI.Uninstall(directory, installForm, deleteConfig);
|
||||||
await UplayR1.Uninstall(directory, installForm, deleteConfig);
|
await UplayR1.Uninstall(directory, installForm, deleteConfig);
|
||||||
|
@ -166,21 +190,27 @@ internal static class Koaloader
|
||||||
await Uninstall(rootDirectory, null, installForm, deleteConfig);
|
await Uninstall(rootDirectory, null, installForm, deleteConfig);
|
||||||
});
|
});
|
||||||
|
|
||||||
internal static async Task Install(string directory, BinaryType binaryType, Selection selection, string rootDirectory = null,
|
internal static async Task Install(string directory, BinaryType binaryType, Selection selection,
|
||||||
|
string rootDirectory = null,
|
||||||
InstallForm installForm = null, bool generateConfig = true)
|
InstallForm installForm = null, bool generateConfig = true)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
string proxy = selection.KoaloaderProxy ?? Selection.DefaultKoaloaderProxy;
|
string proxy = selection.KoaloaderProxy ?? Selection.DefaultKoaloaderProxy;
|
||||||
string path = directory + @"\" + proxy + ".dll";
|
string path = directory + @"\" + proxy + ".dll";
|
||||||
foreach (string _path in directory.GetKoaloaderProxies().Where(p => p != path && p.FileExists() && p.IsResourceFile(ResourceIdentifier.Koaloader)))
|
foreach (string _path in directory.GetKoaloaderProxies().Where(p =>
|
||||||
|
p != path && p.FileExists() && p.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||||
{
|
{
|
||||||
_path.DeleteFile(true);
|
_path.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.FileExists() && !path.IsResourceFile(ResourceIdentifier.Koaloader))
|
if (path.FileExists() && !path.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||||
throw new CustomMessageException("A non-Koaloader DLL named " + proxy + ".dll already exists in this directory!");
|
throw new CustomMessageException("A non-Koaloader DLL named " + proxy +
|
||||||
|
".dll already exists in this directory!");
|
||||||
path.WriteProxy(proxy, binaryType);
|
path.WriteProxy(proxy, binaryType);
|
||||||
installForm?.UpdateUser($"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
bool bit32 = false, bit64 = false;
|
bool bit32 = false, bit64 = false;
|
||||||
foreach (string executable in directory.EnumerateDirectory("*.exe"))
|
foreach (string executable in directory.EnumerateDirectory("*.exe"))
|
||||||
|
@ -195,9 +225,11 @@ internal static class Koaloader
|
||||||
bit64 = true;
|
bit64 = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bit32 && bit64)
|
if (bit32 && bit64)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
||||||
{
|
{
|
||||||
if (bit32)
|
if (bit32)
|
||||||
|
@ -208,15 +240,20 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\SmokeAPI32.dll";
|
path = rootDirectory + @"\SmokeAPI32.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"SmokeAPI.steam_api.dll".WriteManifestResource(path);
|
"SmokeAPI.steam_api.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bit64)
|
if (bit64)
|
||||||
{
|
{
|
||||||
path = directory + @"\SmokeAPI64.dll";
|
path = directory + @"\SmokeAPI64.dll";
|
||||||
|
@ -225,17 +262,23 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\SmokeAPI64.dll";
|
path = rootDirectory + @"\SmokeAPI64.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"SmokeAPI.steam_api64.dll".WriteManifestResource(path);
|
"SmokeAPI.steam_api64.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SmokeAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
SmokeAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (selection.Platform)
|
switch (selection.Platform)
|
||||||
{
|
{
|
||||||
case Platform.Epic or Platform.Paradox:
|
case Platform.Epic or Platform.Paradox:
|
||||||
|
@ -248,15 +291,20 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\ScreamAPI32.dll";
|
path = rootDirectory + @"\ScreamAPI32.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"ScreamAPI.EOSSDK-Win32-Shipping.dll".WriteManifestResource(path);
|
"ScreamAPI.EOSSDK-Win32-Shipping.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bit64)
|
if (bit64)
|
||||||
{
|
{
|
||||||
path = directory + @"\ScreamAPI64.dll";
|
path = directory + @"\ScreamAPI64.dll";
|
||||||
|
@ -265,15 +313,20 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\ScreamAPI64.dll";
|
path = rootDirectory + @"\ScreamAPI64.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"ScreamAPI.EOSSDK-Win64-Shipping.dll".WriteManifestResource(path);
|
"ScreamAPI.EOSSDK-Win64-Shipping.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreamAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
ScreamAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -287,16 +340,21 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\UplayR1Unlocker32.dll";
|
path = rootDirectory + @"\UplayR1Unlocker32.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"UplayR1.uplay_r1_loader.dll".WriteManifestResource(path);
|
"UplayR1.uplay_r1_loader.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bit64)
|
if (bit64)
|
||||||
{
|
{
|
||||||
path = directory + @"\UplayR1Unlocker64.dll";
|
path = directory + @"\UplayR1Unlocker64.dll";
|
||||||
|
@ -305,16 +363,21 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\UplayR1Unlocker64.dll";
|
path = rootDirectory + @"\UplayR1Unlocker64.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"UplayR1.uplay_r1_loader64.dll".WriteManifestResource(path);
|
"UplayR1.uplay_r1_loader64.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
UplayR1.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
UplayR1.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||||
if (bit32)
|
if (bit32)
|
||||||
{
|
{
|
||||||
|
@ -324,16 +387,21 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\UplayR2Unlocker32.dll";
|
path = rootDirectory + @"\UplayR2Unlocker32.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"UplayR2.upc_r2_loader.dll".WriteManifestResource(path);
|
"UplayR2.upc_r2_loader.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bit64)
|
if (bit64)
|
||||||
{
|
{
|
||||||
path = directory + @"\UplayR2Unlocker64.dll";
|
path = directory + @"\UplayR2Unlocker64.dll";
|
||||||
|
@ -342,20 +410,26 @@ internal static class Koaloader
|
||||||
if (path.FileExists())
|
if (path.FileExists())
|
||||||
{
|
{
|
||||||
path.DeleteFile();
|
path.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = rootDirectory + @"\UplayR2Unlocker64.dll";
|
path = rootDirectory + @"\UplayR2Unlocker64.dll";
|
||||||
}
|
}
|
||||||
|
|
||||||
"UplayR2.upc_r2_loader64.dll".WriteManifestResource(path);
|
"UplayR2.upc_r2_loader64.dll".WriteManifestResource(path);
|
||||||
installForm?.UpdateUser(
|
installForm?.UpdateUser(
|
||||||
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||||
LogTextBox.Action, false);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
UplayR2.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
UplayR2.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateConfig)
|
if (generateConfig)
|
||||||
CheckConfig(directory, installForm);
|
CheckConfig(directory, installForm);
|
||||||
});
|
});
|
||||||
|
|
|
@ -432,7 +432,8 @@ internal static class Resources
|
||||||
return embeddedResources;
|
return embeddedResources;
|
||||||
string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
|
string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
|
||||||
embeddedResources = [];
|
embeddedResources = [];
|
||||||
foreach (string resourceName in names.Where(n => n.StartsWith("CreamInstaller.Resources.", StringComparison.Ordinal)))
|
foreach (string resourceName in names.Where(n =>
|
||||||
|
n.StartsWith("CreamInstaller.Resources.", StringComparison.Ordinal)))
|
||||||
_ = embeddedResources.Add(resourceName[25..]);
|
_ = embeddedResources.Add(resourceName[25..]);
|
||||||
return embeddedResources;
|
return embeddedResources;
|
||||||
}
|
}
|
||||||
|
@ -443,14 +444,16 @@ internal static class Resources
|
||||||
while (!Program.Canceled)
|
while (!Program.Canceled)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("CreamInstaller.Resources." + resourceIdentifier);
|
using Stream resource = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream("CreamInstaller.Resources." + resourceIdentifier);
|
||||||
using FileStream file = new(filePath, FileMode.Create, FileAccess.Write);
|
using FileStream file = new(filePath, FileMode.Create, FileAccess.Write);
|
||||||
resource?.CopyTo(file);
|
resource?.CopyTo(file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (filePath.IOWarn("Failed to write a crucial manifest resource (" + resourceIdentifier + ")", e) is not DialogResult.OK)
|
if (filePath.IOWarn("Failed to write a crucial manifest resource (" + resourceIdentifier + ")", e) is
|
||||||
|
not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -469,22 +472,26 @@ internal static class Resources
|
||||||
if (filePath.IOWarn("Failed to write a crucial resource", e) is not DialogResult.OK)
|
if (filePath.IOWarn("Failed to write a crucial resource", e) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) => NativeImports.GetBinaryType(path, out binaryType);
|
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,
|
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(
|
||||||
|
this string rootDirectory, bool filterCommon = false,
|
||||||
Func<string, bool> validFunc = null)
|
Func<string, bool> validFunc = null)
|
||||||
=> await Task.Run(async ()
|
=> await Task.Run(async ()
|
||||||
=> (await rootDirectory.GetExecutables(filterCommon, validFunc)
|
=> (await rootDirectory.GetExecutables(filterCommon, validFunc)
|
||||||
?? (filterCommon || validFunc is not null ? await rootDirectory.GetExecutables() : null))?.Select(e =>
|
?? (filterCommon || validFunc is not null ? await rootDirectory.GetExecutables() : null))?.Select(e =>
|
||||||
{
|
{
|
||||||
e.path = Path.GetDirectoryName(e.path);
|
e.path = Path.GetDirectoryName(e.path);
|
||||||
return e;
|
return e;
|
||||||
}).DistinctBy(e => e.path).ToList() ?? []);
|
}).DistinctBy(e => e.path).ToList() ?? []);
|
||||||
|
|
||||||
internal static async Task<List<(string path, BinaryType binaryType)>> GetExecutables(this string rootDirectory, bool filterCommon = false,
|
internal static async Task<List<(string path, BinaryType binaryType)>> GetExecutables(this string rootDirectory,
|
||||||
|
bool filterCommon = false,
|
||||||
Func<string, bool> validFunc = null)
|
Func<string, bool> validFunc = null)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
@ -495,18 +502,26 @@ internal static class Resources
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return null;
|
return null;
|
||||||
if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
if (executables.All(e => e.path != path) && (!filterCommon ||
|
||||||
&& (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType) && binaryType is BinaryType.BIT64)
|
!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));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string path in rootDirectory.EnumerateDirectory("*.exe", true))
|
foreach (string path in rootDirectory.EnumerateDirectory("*.exe", true))
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
if (Program.Canceled)
|
||||||
return null;
|
return null;
|
||||||
if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
if (executables.All(e => e.path != path) && (!filterCommon ||
|
||||||
&& (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType) && binaryType is BinaryType.BIT32)
|
!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));
|
||||||
}
|
}
|
||||||
|
|
||||||
return executables.Count > 0 ? executables : null;
|
return executables.Count > 0 ? executables : null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -514,12 +529,16 @@ internal static class Resources
|
||||||
{
|
{
|
||||||
string subPath = path[rootDirectory.Length..].ToUpperInvariant();
|
string subPath = path[rootDirectory.Length..].ToUpperInvariant();
|
||||||
return subPath.Contains("SETUP") || subPath.Contains("REDIST") || subPath.Contains("SUPPORT")
|
return subPath.Contains("SETUP") || subPath.Contains("REDIST") || subPath.Contains("SUPPORT")
|
||||||
|| subPath.Contains("CRASH") && (subPath.Contains("PAD") || subPath.Contains("REPORT")) || subPath.Contains("HELPER") || subPath.Contains("CEFPROCESS")
|
|| subPath.Contains("CRASH") && (subPath.Contains("PAD") || subPath.Contains("REPORT")) ||
|
||||||
|| subPath.Contains("ZFGAMEBROWSER") || subPath.Contains("MONO") || subPath.Contains("PLUGINS") || subPath.Contains("MODDING")
|
subPath.Contains("HELPER") || subPath.Contains("CEFPROCESS")
|
||||||
|| subPath.Contains("MOD") && subPath.Contains("MANAGER") || subPath.Contains("BATTLEYE") || subPath.Contains("ANTICHEAT");
|
|| subPath.Contains("ZFGAMEBROWSER") || subPath.Contains("MONO") || subPath.Contains("PLUGINS") ||
|
||||||
|
subPath.Contains("MODDING")
|
||||||
|
|| subPath.Contains("MOD") && subPath.Contains("MANAGER") || subPath.Contains("BATTLEYE") ||
|
||||||
|
subPath.Contains("ANTICHEAT");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<HashSet<string>> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform)
|
internal static async Task<HashSet<string>> GetDllDirectoriesFromGameDirectory(this string gameDirectory,
|
||||||
|
Platform platform)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
HashSet<string> dllDirectories = [];
|
HashSet<string> dllDirectories = [];
|
||||||
|
@ -532,43 +551,54 @@ internal static class Resources
|
||||||
string subDirectory = directory.ResolvePath();
|
string subDirectory = directory.ResolvePath();
|
||||||
if (subDirectory is null || dllDirectories.Contains(subDirectory))
|
if (subDirectory is null || dllDirectories.Contains(subDirectory))
|
||||||
continue;
|
continue;
|
||||||
bool koaloaderInstalled = Koaloader.AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
bool koaloaderInstalled = Koaloader.AutoLoadDLLs
|
||||||
.Any(pair => pair.path.FileExists() && pair.path.IsResourceFile());
|
.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||||
|
.Any(pair => pair.path.FileExists() && pair.path.IsResourceFile());
|
||||||
if (platform is Platform.Steam or Platform.Paradox)
|
if (platform is Platform.Steam or Platform.Paradox)
|
||||||
{
|
{
|
||||||
subDirectory.GetSmokeApiComponents(out string api, out string api_o, out string api64, out string api64_o, out string old_config,
|
subDirectory.GetSmokeApiComponents(out string api, out string api_o, out string api64,
|
||||||
|
out string api64_o, out string old_config,
|
||||||
out string config, out string old_log, out string log, out string cache);
|
out string config, out string old_log, out string log, out string cache);
|
||||||
if (api.FileExists() || api_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
if (api.FileExists() || api_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
||||||
|| (old_config.FileExists() || config.FileExists() || old_log.FileExists() || log.FileExists() || cache.FileExists())
|
|| (old_config.FileExists() || config.FileExists() || old_log.FileExists() ||
|
||||||
&& !koaloaderInstalled)
|
log.FileExists() || cache.FileExists())
|
||||||
|
&& !koaloaderInstalled)
|
||||||
_ = dllDirectories.Add(subDirectory);
|
_ = dllDirectories.Add(subDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform is Platform.Epic or Platform.Paradox)
|
if (platform is Platform.Epic or Platform.Paradox)
|
||||||
{
|
{
|
||||||
subDirectory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
subDirectory.GetScreamApiComponents(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string config,
|
||||||
out string log);
|
out string log);
|
||||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
||||||
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
||||||
_ = dllDirectories.Add(subDirectory);
|
_ = dllDirectories.Add(subDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform is Platform.Ubisoft)
|
if (platform is Platform.Ubisoft)
|
||||||
{
|
{
|
||||||
subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64,
|
||||||
|
out string api64_o, out string config,
|
||||||
out string log);
|
out string log);
|
||||||
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists()
|
||||||
|| (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
|| (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,
|
subDirectory.GetUplayR2Components(out string old_api32, out string old_api64, out api32,
|
||||||
|
out api32_o, out api64, out api64_o, out config,
|
||||||
out log);
|
out log);
|
||||||
if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api32_o.FileExists() || api64.FileExists()
|
if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() ||
|
||||||
|| api64_o.FileExists() || (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
api32_o.FileExists() || api64.FileExists()
|
||||||
|
|| api64_o.FileExists() || (config.FileExists() || log.FileExists()) && !koaloaderInstalled)
|
||||||
_ = dllDirectories.Add(subDirectory);
|
_ = dllDirectories.Add(subDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dllDirectories.Count > 0 ? dllDirectories : null;
|
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,
|
internal static void GetCreamApiComponents(this string directory, out string api32, out string api32_o,
|
||||||
|
out string api64, out string api64_o,
|
||||||
out string config)
|
out string config)
|
||||||
{
|
{
|
||||||
api32 = directory + @"\steam_api.dll";
|
api32 = directory + @"\steam_api.dll";
|
||||||
|
@ -588,14 +618,27 @@ internal static class Resources
|
||||||
internal static bool IsResourceFile(this string filePath, ResourceIdentifier identifier)
|
internal static bool IsResourceFile(this string filePath, ResourceIdentifier identifier)
|
||||||
=> filePath.ComputeMD5() is { } hash && ResourceMD5s[identifier].Contains(hash);
|
=> filePath.ComputeMD5() is { } hash && ResourceMD5s[identifier].Contains(hash);
|
||||||
|
|
||||||
internal static bool IsResourceFile(this string filePath) => filePath.ComputeMD5() is { } hash && ResourceMD5s.Values.Any(hashes => hashes.Contains(hash));
|
internal static bool IsResourceFile(this string filePath) => filePath.ComputeMD5() is { } hash &&
|
||||||
|
ResourceMD5s.Values.Any(
|
||||||
|
hashes => hashes.Contains(hash));
|
||||||
|
|
||||||
internal enum BinaryType { Unknown = -1, BIT32 = 0, BIT64 = 6 }
|
internal enum BinaryType
|
||||||
|
{
|
||||||
|
Unknown = -1,
|
||||||
|
BIT32 = 0,
|
||||||
|
BIT64 = 6
|
||||||
|
}
|
||||||
|
|
||||||
internal enum ResourceIdentifier
|
internal enum ResourceIdentifier
|
||||||
{
|
{
|
||||||
Koaloader, Steamworks32, Steamworks64,
|
Koaloader,
|
||||||
EpicOnlineServices32, EpicOnlineServices64, Uplay32,
|
Steamworks32,
|
||||||
Uplay64, Upc32, Upc64
|
Steamworks64,
|
||||||
|
EpicOnlineServices32,
|
||||||
|
EpicOnlineServices64,
|
||||||
|
Uplay32,
|
||||||
|
Uplay64,
|
||||||
|
Upc32,
|
||||||
|
Upc64
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,8 @@ namespace CreamInstaller.Resources;
|
||||||
|
|
||||||
internal static class ScreamAPI
|
internal static class ScreamAPI
|
||||||
{
|
{
|
||||||
internal static void GetScreamApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
internal static void GetScreamApiComponents(this string directory, out string api32, out string api32_o,
|
||||||
|
out string api64, out string api64_o,
|
||||||
out string config, out string log)
|
out string config, out string log)
|
||||||
{
|
{
|
||||||
api32 = directory + @"\EOSSDK-Win32-Shipping.dll";
|
api32 = directory + @"\EOSSDK-Win32-Shipping.dll";
|
||||||
|
@ -25,7 +26,8 @@ internal static class ScreamAPI
|
||||||
internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null)
|
internal static void CheckConfig(string directory, Selection selection, InstallForm installForm = null)
|
||||||
{
|
{
|
||||||
directory.GetScreamApiComponents(out _, out _, out _, out _, out string config, out _);
|
directory.GetScreamApiComponents(out _, out _, out _, out _, out string config, out _);
|
||||||
HashSet<SelectionDLC> overrideCatalogItems = selection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !dlc.Enabled).ToHashSet();
|
HashSet<SelectionDLC> overrideCatalogItems =
|
||||||
|
selection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !dlc.Enabled).ToHashSet();
|
||||||
int entitlementCount = 0;
|
int entitlementCount = 0;
|
||||||
HashSet<SelectionDLC> injectedEntitlements = [];
|
HashSet<SelectionDLC> injectedEntitlements = [];
|
||||||
foreach (SelectionDLC dlc in selection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement))
|
foreach (SelectionDLC dlc in selection.DLC.Where(dlc => dlc.Type is DLCType.EpicEntitlement))
|
||||||
|
@ -34,6 +36,7 @@ internal static class ScreamAPI
|
||||||
_ = injectedEntitlements.Add(dlc);
|
_ = injectedEntitlements.Add(dlc);
|
||||||
entitlementCount++;
|
entitlementCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Selection extraSelection in selection.ExtraSelections)
|
foreach (Selection extraSelection in selection.ExtraSelections)
|
||||||
{
|
{
|
||||||
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !dlc.Enabled))
|
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(dlc => dlc.Type is DLCType.Epic && !dlc.Enabled))
|
||||||
|
@ -45,6 +48,7 @@ internal static class ScreamAPI
|
||||||
entitlementCount++;
|
entitlementCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (injectedEntitlements.Count == entitlementCount)
|
if (injectedEntitlements.Count == entitlementCount)
|
||||||
injectedEntitlements.Clear();
|
injectedEntitlements.Clear();
|
||||||
if (overrideCatalogItems.Count > 0 || injectedEntitlements.Count > 0)
|
if (overrideCatalogItems.Count > 0 || injectedEntitlements.Count > 0)
|
||||||
|
@ -53,15 +57,18 @@ internal static class ScreamAPI
|
||||||
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||||
config.CreateFile(true, installForm)?.Close();
|
config.CreateFile(true, installForm)?.Close();
|
||||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||||
WriteConfig(writer, new(overrideCatalogItems.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
WriteConfig(writer,
|
||||||
new(injectedEntitlements.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
new(overrideCatalogItems.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||||
|
new(injectedEntitlements.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||||
|
installForm);
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
writer.Close();
|
writer.Close();
|
||||||
}
|
}
|
||||||
else if (config.FileExists())
|
else if (config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,13 +90,17 @@ internal static class ScreamAPI
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = pair.Value;
|
SelectionDLC selectionDlc = pair.Value;
|
||||||
writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastOverrideCatalogItem) ? "" : ",")}");
|
writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastOverrideCatalogItem) ? "" : ",")}");
|
||||||
installForm?.UpdateUser($"Added locked catalog item to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Added locked catalog item to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" ]");
|
writer.WriteLine(" ]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"override\": []");
|
writer.WriteLine(" \"override\": []");
|
||||||
|
|
||||||
writer.WriteLine(" },");
|
writer.WriteLine(" },");
|
||||||
writer.WriteLine(" \"entitlements\": {");
|
writer.WriteLine(" \"entitlements\": {");
|
||||||
if (injectedEntitlements.Count > 0)
|
if (injectedEntitlements.Count > 0)
|
||||||
|
@ -102,9 +113,12 @@ internal static class ScreamAPI
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = pair.Value;
|
SelectionDLC selectionDlc = pair.Value;
|
||||||
writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}");
|
writer.WriteLine($" \"{selectionDlc.Id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}");
|
||||||
installForm?.UpdateUser($"Added injected entitlement to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Added injected entitlement to ScreamAPI.json with id {selectionDlc.Id} ({selectionDlc.Name})",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" ]");
|
writer.WriteLine(" ]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -113,6 +127,7 @@ internal static class ScreamAPI
|
||||||
writer.WriteLine(" \"auto_inject\": true,");
|
writer.WriteLine(" \"auto_inject\": true,");
|
||||||
writer.WriteLine(" \"inject\": []");
|
writer.WriteLine(" \"inject\": []");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" }");
|
writer.WriteLine(" }");
|
||||||
writer.WriteLine("}");
|
writer.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
@ -120,7 +135,8 @@ internal static class ScreamAPI
|
||||||
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true)
|
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log);
|
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out string config, out string log);
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
if (api32.FileExists())
|
if (api32.FileExists())
|
||||||
|
@ -128,9 +144,12 @@ internal static class ScreamAPI
|
||||||
api32.DeleteFile(true);
|
api32.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api32_o.MoveFile(api32!);
|
api32_o.MoveFile(api32!);
|
||||||
installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
if (api64.FileExists())
|
if (api64.FileExists())
|
||||||
|
@ -138,9 +157,12 @@ internal static class ScreamAPI
|
||||||
api64.DeleteFile(true);
|
api64.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api64_o.MoveFile(api64!);
|
api64_o.MoveFile(api64!);
|
||||||
installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deleteOthers)
|
if (!deleteOthers)
|
||||||
return;
|
return;
|
||||||
if (config.FileExists())
|
if (config.FileExists())
|
||||||
|
@ -148,6 +170,7 @@ internal static class ScreamAPI
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.FileExists())
|
if (log.FileExists())
|
||||||
{
|
{
|
||||||
log.DeleteFile();
|
log.DeleteFile();
|
||||||
|
@ -155,30 +178,38 @@ internal static class ScreamAPI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
internal static async Task Install(string directory, Selection 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(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _);
|
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out _, out _);
|
||||||
if (api32.FileExists() && !api32_o.FileExists())
|
if (api32.FileExists() && !api32_o.FileExists())
|
||||||
{
|
{
|
||||||
api32.MoveFile(api32_o!, true);
|
api32.MoveFile(api32_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
"ScreamAPI.EOSSDK-Win32-Shipping.dll".WriteManifestResource(api32);
|
"ScreamAPI.EOSSDK-Win32-Shipping.dll".WriteManifestResource(api32);
|
||||||
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64.FileExists() && !api64_o.FileExists())
|
if (api64.FileExists() && !api64_o.FileExists())
|
||||||
{
|
{
|
||||||
api64.MoveFile(api64_o!, true);
|
api64.MoveFile(api64_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
"ScreamAPI.EOSSDK-Win64-Shipping.dll".WriteManifestResource(api64);
|
"ScreamAPI.EOSSDK-Win64-Shipping.dll".WriteManifestResource(api64);
|
||||||
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateConfig)
|
if (generateConfig)
|
||||||
CheckConfig(directory, selection, installForm);
|
CheckConfig(directory, selection, installForm);
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,8 @@ namespace CreamInstaller.Resources;
|
||||||
|
|
||||||
internal static class SmokeAPI
|
internal static class SmokeAPI
|
||||||
{
|
{
|
||||||
internal static void GetSmokeApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
internal static void GetSmokeApiComponents(this string directory, out string api32, out string api32_o,
|
||||||
|
out string api64, out string api64_o,
|
||||||
out string old_config, out string config, out string old_log, out string log, out string cache)
|
out string old_config, out string config, out string old_log, out string log, out string cache)
|
||||||
{
|
{
|
||||||
api32 = directory + @"\steam_api.dll";
|
api32 = directory + @"\steam_api.dll";
|
||||||
|
@ -27,35 +28,46 @@ internal static class SmokeAPI
|
||||||
|
|
||||||
internal static void CheckConfig(string directory, Selection 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 _);
|
directory.GetSmokeApiComponents(out _, out _, out _, out _, out string old_config, out string config, out _,
|
||||||
|
out _, out _);
|
||||||
HashSet<SelectionDLC> overrideDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToHashSet();
|
HashSet<SelectionDLC> overrideDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToHashSet();
|
||||||
foreach (SelectionDLC extraDlc in selection.ExtraSelections.SelectMany(extraSelection => extraSelection.DLC.Where(dlc => !dlc.Enabled)))
|
foreach (SelectionDLC extraDlc in selection.ExtraSelections.SelectMany(extraSelection =>
|
||||||
|
extraSelection.DLC.Where(dlc => !dlc.Enabled)))
|
||||||
_ = overrideDlc.Add(extraDlc);
|
_ = overrideDlc.Add(extraDlc);
|
||||||
HashSet<SelectionDLC> injectDlc = [];
|
HashSet<SelectionDLC> injectDlc = [];
|
||||||
if (selection.DLC.Count() > 64)
|
if (selection.DLC.Count() > 64)
|
||||||
foreach (SelectionDLC hiddenDlc in selection.DLC.Where(dlc => dlc.Enabled && dlc.Type is DLCType.SteamHidden))
|
foreach (SelectionDLC hiddenDlc in selection.DLC.Where(
|
||||||
|
dlc => dlc.Enabled && dlc.Type is DLCType.SteamHidden))
|
||||||
_ = injectDlc.Add(hiddenDlc);
|
_ = injectDlc.Add(hiddenDlc);
|
||||||
List<KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)>> extraApps = [];
|
List<KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)>> extraApps = [];
|
||||||
foreach (Selection extraSelection in selection.ExtraSelections.Where(extraSelection => extraSelection.DLC.Count() > 64))
|
foreach (Selection extraSelection in selection.ExtraSelections.Where(extraSelection =>
|
||||||
|
extraSelection.DLC.Count() > 64))
|
||||||
{
|
{
|
||||||
SortedList<string, SelectionDLC> extraInjectDlc = new(PlatformIdComparer.String);
|
SortedList<string, SelectionDLC> extraInjectDlc = new(PlatformIdComparer.String);
|
||||||
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(extraDlc => extraDlc.Enabled && extraDlc.Type is DLCType.SteamHidden))
|
foreach (SelectionDLC extraDlc in extraSelection.DLC.Where(extraDlc =>
|
||||||
|
extraDlc.Enabled && extraDlc.Type is DLCType.SteamHidden))
|
||||||
extraInjectDlc.Add(extraDlc.Id, extraDlc);
|
extraInjectDlc.Add(extraDlc.Id, extraDlc);
|
||||||
if (extraInjectDlc.Count > 0)
|
if (extraInjectDlc.Count > 0)
|
||||||
extraApps.Add(new(extraSelection.Id, (extraSelection.Name, extraInjectDlc)));
|
extraApps.Add(new(extraSelection.Id, (extraSelection.Name, extraInjectDlc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_config.FileExists())
|
if (old_config.FileExists())
|
||||||
{
|
{
|
||||||
old_config.DeleteFile();
|
old_config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
if (selection.ExtraSelections.Any(extraSelection => extraSelection.DLC.Any()) || overrideDlc.Count > 0 || injectDlc.Count > 0)
|
|
||||||
|
if (selection.ExtraSelections.Any(extraSelection => extraSelection.DLC.Any()) || overrideDlc.Count > 0 ||
|
||||||
|
injectDlc.Count > 0)
|
||||||
{
|
{
|
||||||
/*if (installForm is not null)
|
/*if (installForm is not null)
|
||||||
installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||||
config.CreateFile(true, installForm)?.Close();
|
config.CreateFile(true, installForm)?.Close();
|
||||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||||
WriteConfig(writer, selection.Id, new(extraApps.ToDictionary(extraApp => extraApp.Key, extraApp => extraApp.Value), PlatformIdComparer.String),
|
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(overrideDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||||
new(injectDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
new(injectDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
|
@ -64,12 +76,15 @@ internal static class SmokeAPI
|
||||||
else if (config.FileExists())
|
else if (config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteConfig(StreamWriter writer, string appId, SortedList<string, (string name, SortedList<string, SelectionDLC> injectDlc)> extraApps,
|
private static void WriteConfig(StreamWriter writer, string appId,
|
||||||
SortedList<string, SelectionDLC> overrideDlc, SortedList<string, SelectionDLC> injectDlc, InstallForm installForm = null)
|
SortedList<string, (string name, SortedList<string, SelectionDLC> injectDlc)> extraApps,
|
||||||
|
SortedList<string, SelectionDLC> overrideDlc, SortedList<string, SelectionDLC> injectDlc,
|
||||||
|
InstallForm installForm = null)
|
||||||
{
|
{
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
writer.WriteLine(" \"$version\": 2,");
|
writer.WriteLine(" \"$version\": 2,");
|
||||||
|
@ -85,13 +100,17 @@ internal static class SmokeAPI
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = pair.Value;
|
SelectionDLC selectionDlc = pair.Value;
|
||||||
writer.WriteLine($" \"{selectionDlc.Id}\": \"locked\"{(pair.Equals(lastOverrideDlc) ? "" : ",")}");
|
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,
|
installForm?.UpdateUser(
|
||||||
|
$"Added locked DLC to SmokeAPI.config.json with appid {selectionDlc.Id} ({selectionDlc.Name})",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" },");
|
writer.WriteLine(" },");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"override_dlc_status\": {},");
|
writer.WriteLine(" \"override_dlc_status\": {},");
|
||||||
|
|
||||||
writer.WriteLine(" \"auto_inject_inventory\": true,");
|
writer.WriteLine(" \"auto_inject_inventory\": true,");
|
||||||
writer.WriteLine(" \"extra_inventory_items\": [],");
|
writer.WriteLine(" \"extra_inventory_items\": [],");
|
||||||
if (injectDlc.Count > 0 || extraApps.Count > 0)
|
if (injectDlc.Count > 0 || extraApps.Count > 0)
|
||||||
|
@ -105,17 +124,24 @@ internal static class SmokeAPI
|
||||||
foreach (KeyValuePair<string, SelectionDLC> pair in injectDlc)
|
foreach (KeyValuePair<string, SelectionDLC> pair in injectDlc)
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = pair.Value;
|
SelectionDLC selectionDlc = pair.Value;
|
||||||
writer.WriteLine($" \"{selectionDlc.Id}\": \"{selectionDlc.Name}\"{(pair.Equals(lastInjectDlc) ? "" : ",")}");
|
writer.WriteLine(
|
||||||
installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
$" \"{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);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" }");
|
writer.WriteLine(" }");
|
||||||
writer.WriteLine(extraApps.Count > 0 ? " }," : " }");
|
writer.WriteLine(extraApps.Count > 0 ? " }," : " }");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extraApps.Count > 0)
|
if (extraApps.Count > 0)
|
||||||
{
|
{
|
||||||
KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)> lastExtraApp = extraApps.Last();
|
KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)> lastExtraApp =
|
||||||
foreach (KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)> pair in extraApps)
|
extraApps.Last();
|
||||||
|
foreach (KeyValuePair<string, (string name, SortedList<string, SelectionDLC> injectDlc)> pair in
|
||||||
|
extraApps)
|
||||||
{
|
{
|
||||||
string extraAppId = pair.Key;
|
string extraAppId = pair.Key;
|
||||||
(string _ /*extraAppName*/, SortedList<string, SelectionDLC> extraInjectDlc) = pair.Value;
|
(string _ /*extraAppName*/, SortedList<string, SelectionDLC> extraInjectDlc) = pair.Value;
|
||||||
|
@ -126,18 +152,23 @@ internal static class SmokeAPI
|
||||||
foreach (KeyValuePair<string, SelectionDLC> extraPair in extraInjectDlc)
|
foreach (KeyValuePair<string, SelectionDLC> extraPair in extraInjectDlc)
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = extraPair.Value;
|
SelectionDLC selectionDlc = extraPair.Value;
|
||||||
writer.WriteLine($" \"{selectionDlc.Id}\": \"{selectionDlc.Name}\"{(extraPair.Equals(lastExtraAppDlc) ? "" : ",")}");
|
writer.WriteLine(
|
||||||
installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {selectionDlc.Id} ({selectionDlc.Name})",
|
$" \"{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);
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" }");
|
writer.WriteLine(" }");
|
||||||
writer.WriteLine(pair.Equals(lastExtraApp) ? " }" : " },");
|
writer.WriteLine(pair.Equals(lastExtraApp) ? " }" : " },");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" },");
|
writer.WriteLine(" },");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"extra_dlcs\": {},");
|
writer.WriteLine(" \"extra_dlcs\": {},");
|
||||||
|
|
||||||
writer.WriteLine(" \"store_config\": null");
|
writer.WriteLine(" \"store_config\": null");
|
||||||
writer.WriteLine("}");
|
writer.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
@ -149,9 +180,12 @@ internal static class SmokeAPI
|
||||||
if (oldConfig.FileExists())
|
if (oldConfig.FileExists())
|
||||||
{
|
{
|
||||||
oldConfig.DeleteFile();
|
oldConfig.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config,
|
|
||||||
|
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out string old_config,
|
||||||
out string config, out string old_log, out string log, out string cache);
|
out string config, out string old_log, out string log, out string cache);
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
|
@ -160,9 +194,13 @@ internal static class SmokeAPI
|
||||||
api32.DeleteFile(true);
|
api32.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api32_o.MoveFile(api32!);
|
api32_o.MoveFile(api32!);
|
||||||
installForm?.UpdateUser($"Restored Steamworks: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Restored Steamworks: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
if (api64.FileExists())
|
if (api64.FileExists())
|
||||||
|
@ -170,31 +208,40 @@ internal static class SmokeAPI
|
||||||
api64.DeleteFile(true);
|
api64.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api64_o.MoveFile(api64!);
|
api64_o.MoveFile(api64!);
|
||||||
installForm?.UpdateUser($"Restored Steamworks: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser(
|
||||||
|
$"Restored Steamworks: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deleteOthers)
|
if (!deleteOthers)
|
||||||
return;
|
return;
|
||||||
if (old_config.FileExists())
|
if (old_config.FileExists())
|
||||||
{
|
{
|
||||||
old_config.DeleteFile();
|
old_config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.FileExists())
|
if (config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache.FileExists())
|
if (cache.FileExists())
|
||||||
{
|
{
|
||||||
cache.DeleteFile();
|
cache.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted cache: {Path.GetFileName(cache)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted cache: {Path.GetFileName(cache)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_log.FileExists())
|
if (old_log.FileExists())
|
||||||
{
|
{
|
||||||
old_log.DeleteFile();
|
old_log.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(old_log)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(old_log)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.FileExists())
|
if (log.FileExists())
|
||||||
{
|
{
|
||||||
log.DeleteFile();
|
log.DeleteFile();
|
||||||
|
@ -202,36 +249,46 @@ internal static class SmokeAPI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
internal static async Task Install(string directory, Selection 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(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig);
|
directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig);
|
||||||
if (oldConfig.FileExists())
|
if (oldConfig.FileExists())
|
||||||
{
|
{
|
||||||
oldConfig.DeleteFile();
|
oldConfig.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _, out _, out _, out _);
|
|
||||||
|
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out _, out _, out _, out _, out _);
|
||||||
if (api32.FileExists() && !api32_o.FileExists())
|
if (api32.FileExists() && !api32_o.FileExists())
|
||||||
{
|
{
|
||||||
api32.MoveFile(api32_o!, true);
|
api32.MoveFile(api32_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
"SmokeAPI.steam_api.dll".WriteManifestResource(api32);
|
"SmokeAPI.steam_api.dll".WriteManifestResource(api32);
|
||||||
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64.FileExists() && !api64_o.FileExists())
|
if (api64.FileExists() && !api64_o.FileExists())
|
||||||
{
|
{
|
||||||
api64.MoveFile(api64_o!, true);
|
api64.MoveFile(api64_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
"SmokeAPI.steam_api64.dll".WriteManifestResource(api64);
|
"SmokeAPI.steam_api64.dll".WriteManifestResource(api64);
|
||||||
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateConfig)
|
if (generateConfig)
|
||||||
CheckConfig(directory, selection, installForm);
|
CheckConfig(directory, selection, installForm);
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,8 @@ namespace CreamInstaller.Resources;
|
||||||
|
|
||||||
internal static class UplayR1
|
internal static class UplayR1
|
||||||
{
|
{
|
||||||
internal static void GetUplayR1Components(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
internal static void GetUplayR1Components(this string directory, out string api32, out string api32_o,
|
||||||
|
out string api64, out string api64_o,
|
||||||
out string config, out string log)
|
out string config, out string log)
|
||||||
{
|
{
|
||||||
api32 = directory + @"\uplay_r1_loader.dll";
|
api32 = directory + @"\uplay_r1_loader.dll";
|
||||||
|
@ -26,7 +27,8 @@ internal static class UplayR1
|
||||||
{
|
{
|
||||||
directory.GetUplayR1Components(out _, out _, out _, out _, out string config, out _);
|
directory.GetUplayR1Components(out _, out _, out _, out _, out string config, out _);
|
||||||
HashSet<SelectionDLC> blacklistDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToHashSet();
|
HashSet<SelectionDLC> blacklistDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToHashSet();
|
||||||
foreach (SelectionDLC extraDlc in selection.ExtraSelections.SelectMany(extraSelection => extraSelection.DLC.Where(dlc => !dlc.Enabled)))
|
foreach (SelectionDLC extraDlc in selection.ExtraSelections.SelectMany(extraSelection =>
|
||||||
|
extraSelection.DLC.Where(dlc => !dlc.Enabled)))
|
||||||
_ = blacklistDlc.Add(extraDlc);
|
_ = blacklistDlc.Add(extraDlc);
|
||||||
if (blacklistDlc.Count > 0)
|
if (blacklistDlc.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -34,18 +36,21 @@ internal static class UplayR1
|
||||||
installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||||
config.CreateFile(true, installForm)?.Close();
|
config.CreateFile(true, installForm)?.Close();
|
||||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
WriteConfig(writer, new(blacklistDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||||
|
installForm);
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
writer.Close();
|
writer.Close();
|
||||||
}
|
}
|
||||||
else if (config.FileExists())
|
else if (config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteConfig(StreamWriter writer, SortedList<string, SelectionDLC> blacklistDlc, InstallForm installForm = null)
|
private static void WriteConfig(StreamWriter writer, SortedList<string, SelectionDLC> blacklistDlc,
|
||||||
|
InstallForm installForm = null)
|
||||||
{
|
{
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
writer.WriteLine(" \"logging\": false,");
|
writer.WriteLine(" \"logging\": false,");
|
||||||
|
@ -59,40 +64,53 @@ internal static class UplayR1
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = pair.Value;
|
SelectionDLC selectionDlc = pair.Value;
|
||||||
writer.WriteLine($" {selectionDlc.Id}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
writer.WriteLine($" {selectionDlc.Id}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {selectionDlc.Id} ({selectionDlc.Name})",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" ],");
|
writer.WriteLine(" ],");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"blacklist\": [],");
|
writer.WriteLine(" \"blacklist\": [],");
|
||||||
|
|
||||||
writer.WriteLine("}");
|
writer.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true)
|
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log);
|
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out string config, out string log);
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
if (api32.FileExists())
|
if (api32.FileExists())
|
||||||
{
|
{
|
||||||
api32.DeleteFile(true);
|
api32.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api32_o.MoveFile(api32!);
|
api32_o.MoveFile(api32!);
|
||||||
installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
if (api64.FileExists())
|
if (api64.FileExists())
|
||||||
{
|
{
|
||||||
api64.DeleteFile(true);
|
api64.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api64_o.MoveFile(api64!);
|
api64_o.MoveFile(api64!);
|
||||||
installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deleteOthers)
|
if (!deleteOthers)
|
||||||
return;
|
return;
|
||||||
if (config.FileExists())
|
if (config.FileExists())
|
||||||
|
@ -100,36 +118,47 @@ internal static class UplayR1
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!log.FileExists())
|
if (!log.FileExists())
|
||||||
return;
|
return;
|
||||||
log.DeleteFile();
|
log.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
internal static async Task Install(string directory, Selection 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(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _);
|
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||||
|
out _, out _);
|
||||||
if (api32.FileExists() && !api32_o.FileExists())
|
if (api32.FileExists() && !api32_o.FileExists())
|
||||||
{
|
{
|
||||||
api32.MoveFile(api32_o!, true);
|
api32.MoveFile(api32_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
"UplayR1.uplay_r1_loader.dll".WriteManifestResource(api32);
|
"UplayR1.uplay_r1_loader.dll".WriteManifestResource(api32);
|
||||||
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64.FileExists() && !api64_o.FileExists())
|
if (api64.FileExists() && !api64_o.FileExists())
|
||||||
{
|
{
|
||||||
api64.MoveFile(api64_o!, true);
|
api64.MoveFile(api64_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
"UplayR1.uplay_r1_loader64.dll".WriteManifestResource(api64);
|
"UplayR1.uplay_r1_loader64.dll".WriteManifestResource(api64);
|
||||||
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateConfig)
|
if (generateConfig)
|
||||||
CheckConfig(directory, selection, installForm);
|
CheckConfig(directory, selection, installForm);
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,8 @@ namespace CreamInstaller.Resources;
|
||||||
|
|
||||||
internal static class UplayR2
|
internal static class UplayR2
|
||||||
{
|
{
|
||||||
internal static void GetUplayR2Components(this string directory, out string old_api32, out string old_api64, out string api32, out string api32_o,
|
internal static void GetUplayR2Components(this string directory, out string old_api32, out string old_api64,
|
||||||
|
out string api32, out string api32_o,
|
||||||
out string api64, out string api64_o, out string config, out string log)
|
out string api64, out string api64_o, out string config, out string log)
|
||||||
{
|
{
|
||||||
old_api32 = directory + @"\uplay_r2_loader.dll";
|
old_api32 = directory + @"\uplay_r2_loader.dll";
|
||||||
|
@ -28,7 +29,8 @@ internal static class UplayR2
|
||||||
{
|
{
|
||||||
directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config, out _);
|
directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config, out _);
|
||||||
HashSet<SelectionDLC> blacklistDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToHashSet();
|
HashSet<SelectionDLC> blacklistDlc = selection.DLC.Where(dlc => !dlc.Enabled).ToHashSet();
|
||||||
foreach (SelectionDLC extraDlc in selection.ExtraSelections.SelectMany(extraSelection => extraSelection.DLC.Where(dlc => !dlc.Enabled)))
|
foreach (SelectionDLC extraDlc in selection.ExtraSelections.SelectMany(extraSelection =>
|
||||||
|
extraSelection.DLC.Where(dlc => !dlc.Enabled)))
|
||||||
_ = blacklistDlc.Add(extraDlc);
|
_ = blacklistDlc.Add(extraDlc);
|
||||||
if (blacklistDlc.Count > 0)
|
if (blacklistDlc.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -36,18 +38,21 @@ internal static class UplayR2
|
||||||
installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||||
config.CreateFile(true, installForm)?.Close();
|
config.CreateFile(true, installForm)?.Close();
|
||||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String), installForm);
|
WriteConfig(writer, new(blacklistDlc.ToDictionary(dlc => dlc.Id, dlc => dlc), PlatformIdComparer.String),
|
||||||
|
installForm);
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
writer.Close();
|
writer.Close();
|
||||||
}
|
}
|
||||||
else if (config.FileExists())
|
else if (config.FileExists())
|
||||||
{
|
{
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteConfig(StreamWriter writer, SortedList<string, SelectionDLC> blacklistDlc, InstallForm installForm = null)
|
private static void WriteConfig(StreamWriter writer, SortedList<string, SelectionDLC> blacklistDlc,
|
||||||
|
InstallForm installForm = null)
|
||||||
{
|
{
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
writer.WriteLine(" \"logging\": false,");
|
writer.WriteLine(" \"logging\": false,");
|
||||||
|
@ -63,20 +68,25 @@ internal static class UplayR2
|
||||||
{
|
{
|
||||||
SelectionDLC selectionDlc = pair.Value;
|
SelectionDLC selectionDlc = pair.Value;
|
||||||
writer.WriteLine($" {selectionDlc.Id}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
writer.WriteLine($" {selectionDlc.Id}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {selectionDlc.Id} ({selectionDlc.Name})", LogTextBox.Action,
|
installForm?.UpdateUser(
|
||||||
|
$"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {selectionDlc.Id} ({selectionDlc.Name})",
|
||||||
|
LogTextBox.Action,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(" ],");
|
writer.WriteLine(" ],");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writer.WriteLine(" \"blacklist\": [],");
|
writer.WriteLine(" \"blacklist\": [],");
|
||||||
|
|
||||||
writer.WriteLine("}");
|
writer.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true)
|
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true)
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64,
|
directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32,
|
||||||
|
out string api32_o, out string api64,
|
||||||
out string api64_o, out string config, out string log);
|
out string api64_o, out string config, out string log);
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
|
@ -84,22 +94,30 @@ internal static class UplayR2
|
||||||
if (api.FileExists())
|
if (api.FileExists())
|
||||||
{
|
{
|
||||||
api.DeleteFile(true);
|
api.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api32_o.MoveFile(api!);
|
api32_o.MoveFile(api!);
|
||||||
installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
string api = old_api64.FileExists() ? old_api64 : api64;
|
string api = old_api64.FileExists() ? old_api64 : api64;
|
||||||
if (api.FileExists())
|
if (api.FileExists())
|
||||||
{
|
{
|
||||||
api.DeleteFile(true);
|
api.DeleteFile(true);
|
||||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api64_o.MoveFile(api!);
|
api64_o.MoveFile(api!);
|
||||||
installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deleteOthers)
|
if (!deleteOthers)
|
||||||
return;
|
return;
|
||||||
if (config.FileExists())
|
if (config.FileExists())
|
||||||
|
@ -107,39 +125,48 @@ internal static class UplayR2
|
||||||
config.DeleteFile();
|
config.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!log.FileExists())
|
if (!log.FileExists())
|
||||||
return;
|
return;
|
||||||
log.DeleteFile();
|
log.DeleteFile();
|
||||||
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
internal static async Task Install(string directory, Selection 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(() =>
|
=> await Task.Run(() =>
|
||||||
{
|
{
|
||||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64,
|
directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32,
|
||||||
|
out string api32_o, out string api64,
|
||||||
out string api64_o, out _, out _);
|
out string api64_o, out _, out _);
|
||||||
string api = old_api32.FileExists() ? old_api32 : api32;
|
string api = old_api32.FileExists() ? old_api32 : api32;
|
||||||
if (api.FileExists() && !api32_o.FileExists())
|
if (api.FileExists() && !api32_o.FileExists())
|
||||||
{
|
{
|
||||||
api.MoveFile(api32_o!, true);
|
api.MoveFile(api32_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api32_o.FileExists())
|
if (api32_o.FileExists())
|
||||||
{
|
{
|
||||||
"UplayR2.upc_r2_loader.dll".WriteManifestResource(api);
|
"UplayR2.upc_r2_loader.dll".WriteManifestResource(api);
|
||||||
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
api = old_api64.FileExists() ? old_api64 : api64;
|
api = old_api64.FileExists() ? old_api64 : api64;
|
||||||
if (api.FileExists() && !api64_o.FileExists())
|
if (api.FileExists() && !api64_o.FileExists())
|
||||||
{
|
{
|
||||||
api.MoveFile(api64_o!, true);
|
api.MoveFile(api64_o!, true);
|
||||||
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}",
|
||||||
|
LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api64_o.FileExists())
|
if (api64_o.FileExists())
|
||||||
{
|
{
|
||||||
"UplayR2.upc_r2_loader64.dll".WriteManifestResource(api);
|
"UplayR2.upc_r2_loader64.dll".WriteManifestResource(api);
|
||||||
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateConfig)
|
if (generateConfig)
|
||||||
CheckConfig(directory, selection, installForm);
|
CheckConfig(directory, selection, installForm);
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,8 +11,11 @@ namespace CreamInstaller;
|
||||||
|
|
||||||
public enum Platform
|
public enum Platform
|
||||||
{
|
{
|
||||||
None = 0, Paradox, Steam,
|
None = 0,
|
||||||
Epic, Ubisoft
|
Paradox,
|
||||||
|
Steam,
|
||||||
|
Epic,
|
||||||
|
Ubisoft
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class Selection : IEquatable<Selection>
|
internal sealed class Selection : IEquatable<Selection>
|
||||||
|
@ -57,15 +60,23 @@ internal sealed class Selection : IEquatable<Selection>
|
||||||
|
|
||||||
internal static IEnumerable<Selection> AllEnabled => All.Keys.Where(s => s.Enabled);
|
internal static IEnumerable<Selection> AllEnabled => All.Keys.Where(s => s.Enabled);
|
||||||
|
|
||||||
internal bool Enabled { get => TreeNode.Checked; set => TreeNode.Checked = value; }
|
internal bool Enabled
|
||||||
|
{
|
||||||
|
get => TreeNode.Checked;
|
||||||
|
set => TreeNode.Checked = value;
|
||||||
|
}
|
||||||
|
|
||||||
internal IEnumerable<SelectionDLC> DLC => SelectionDLC.All.Keys.Where(dlc => Equals(dlc.Selection, this));
|
internal IEnumerable<SelectionDLC> DLC => SelectionDLC.All.Keys.Where(dlc => Equals(dlc.Selection, this));
|
||||||
|
|
||||||
public bool Equals(Selection other) => other is not null && (ReferenceEquals(this, other) || Id == other.Id && Platform == other.Platform);
|
public bool Equals(Selection other) => other is not null &&
|
||||||
|
(ReferenceEquals(this, other) ||
|
||||||
|
Id == other.Id && Platform == other.Platform);
|
||||||
|
|
||||||
internal static Selection GetOrCreate(Platform platform, string id, string name, string rootDirectory, HashSet<string> dllDirectories,
|
internal static Selection GetOrCreate(Platform platform, string id, string name, string rootDirectory,
|
||||||
|
HashSet<string> dllDirectories,
|
||||||
List<(string directory, BinaryType binaryType)> executableDirectories)
|
List<(string directory, BinaryType binaryType)> executableDirectories)
|
||||||
=> FromId(platform, id) ?? new Selection(platform, id, name, rootDirectory, dllDirectories, executableDirectories);
|
=> FromId(platform, id) ??
|
||||||
|
new Selection(platform, id, name, rootDirectory, dllDirectories, executableDirectories);
|
||||||
|
|
||||||
internal void Remove()
|
internal void Remove()
|
||||||
{
|
{
|
||||||
|
@ -82,16 +93,19 @@ internal sealed class Selection : IEquatable<Selection>
|
||||||
Remove();
|
Remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.IsGameBlocked(Name, RootDirectory))
|
if (Program.IsGameBlocked(Name, RootDirectory))
|
||||||
{
|
{
|
||||||
Remove();
|
Remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RootDirectory.DirectoryExists())
|
if (!RootDirectory.DirectoryExists())
|
||||||
{
|
{
|
||||||
Remove();
|
Remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = DllDirectories.RemoveWhere(directory => !directory.DirectoryExists());
|
_ = DllDirectories.RemoveWhere(directory => !directory.DirectoryExists());
|
||||||
if (DllDirectories.Count < 1)
|
if (DllDirectories.Count < 1)
|
||||||
Remove();
|
Remove();
|
||||||
|
@ -103,7 +117,8 @@ internal sealed class Selection : IEquatable<Selection>
|
||||||
selection.Validate(programsToScan);
|
selection.Validate(programsToScan);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Selection FromId(Platform platform, string gameId) => All.Keys.FirstOrDefault(s => s.Platform == platform && s.Id == gameId);
|
internal static Selection FromId(Platform platform, string gameId) =>
|
||||||
|
All.Keys.FirstOrDefault(s => s.Platform == platform && s.Id == gameId);
|
||||||
|
|
||||||
public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is Selection other && Equals(other);
|
public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is Selection other && Equals(other);
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,11 @@ namespace CreamInstaller;
|
||||||
|
|
||||||
public enum DLCType
|
public enum DLCType
|
||||||
{
|
{
|
||||||
None = 0, Steam, SteamHidden,
|
None = 0,
|
||||||
Epic, EpicEntitlement
|
Steam,
|
||||||
|
SteamHidden,
|
||||||
|
Epic,
|
||||||
|
EpicEntitlement
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class SelectionDLC : IEquatable<SelectionDLC>
|
internal sealed class SelectionDLC : IEquatable<SelectionDLC>
|
||||||
|
@ -32,7 +35,11 @@ internal sealed class SelectionDLC : IEquatable<SelectionDLC>
|
||||||
TreeNode = new() { Tag = Type, Name = Id, Text = Name };
|
TreeNode = new() { Tag = Type, Name = Id, Text = Name };
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool Enabled { get => TreeNode.Checked; set => TreeNode.Checked = value; }
|
internal bool Enabled
|
||||||
|
{
|
||||||
|
get => TreeNode.Checked;
|
||||||
|
set => TreeNode.Checked = value;
|
||||||
|
}
|
||||||
|
|
||||||
internal Selection Selection
|
internal Selection Selection
|
||||||
{
|
{
|
||||||
|
@ -57,7 +64,8 @@ internal sealed class SelectionDLC : IEquatable<SelectionDLC>
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(SelectionDLC other)
|
public bool Equals(SelectionDLC other)
|
||||||
=> other is not null && (ReferenceEquals(this, other) || Type == other.Type && Selection?.Id == other.Selection?.Id && Id == other.Id);
|
=> other is not null && (ReferenceEquals(this, other) ||
|
||||||
|
Type == other.Type && Selection?.Id == other.Selection?.Id && Id == other.Id);
|
||||||
|
|
||||||
internal static SelectionDLC GetOrCreate(DLCType type, string gameId, string id, string name)
|
internal static SelectionDLC GetOrCreate(DLCType type, string gameId, string id, string name)
|
||||||
=> FromId(type, gameId, id) ?? new SelectionDLC(type, id, name);
|
=> FromId(type, gameId, id) ?? new SelectionDLC(type, id, name);
|
||||||
|
|
|
@ -34,13 +34,17 @@ internal static class Diagnostics
|
||||||
OpenFileInWindowsNotepad(path);
|
OpenFileInWindowsNotepad(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OpenFileInNotepadPlusPlus(string npp, string path) => Process.Start(new ProcessStartInfo { FileName = npp, Arguments = path });
|
private static void OpenFileInNotepadPlusPlus(string npp, string path) =>
|
||||||
|
Process.Start(new ProcessStartInfo { FileName = npp, Arguments = path });
|
||||||
|
|
||||||
private static void OpenFileInWindowsNotepad(string path) => Process.Start(new ProcessStartInfo { FileName = "notepad.exe", Arguments = path });
|
private static void OpenFileInWindowsNotepad(string path) => Process.Start(new ProcessStartInfo
|
||||||
|
{ FileName = "notepad.exe", Arguments = path });
|
||||||
|
|
||||||
internal static void OpenDirectoryInFileExplorer(string path) => Process.Start(new ProcessStartInfo { FileName = "explorer.exe", Arguments = path });
|
internal static void OpenDirectoryInFileExplorer(string path) => Process.Start(new ProcessStartInfo
|
||||||
|
{ FileName = "explorer.exe", Arguments = path });
|
||||||
|
|
||||||
internal static void OpenUrlInInternetBrowser(string url) => Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true });
|
internal static void OpenUrlInInternetBrowser(string url) =>
|
||||||
|
Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true });
|
||||||
|
|
||||||
internal static string ResolvePath(this string path)
|
internal static string ResolvePath(this string path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,20 +30,27 @@ internal static class ExceptionHandler
|
||||||
int ciNum = line.LastIndexOf(@"CreamInstaller\", StringComparison.Ordinal);
|
int ciNum = line.LastIndexOf(@"CreamInstaller\", StringComparison.Ordinal);
|
||||||
int lineNum = line.LastIndexOf(":line ", StringComparison.Ordinal);
|
int lineNum = line.LastIndexOf(":line ", StringComparison.Ordinal);
|
||||||
if (atNum != -1)
|
if (atNum != -1)
|
||||||
_ = output.Append("\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..]) + (inNum != -1
|
_ = output.Append("\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..]) +
|
||||||
? "\n " + (ciNum != -1
|
(inNum != -1
|
||||||
? "in " + (lineNum != -1 ? line[ciNum..lineNum] + "\n on " + line[(lineNum + 1)..] : line[ciNum..])
|
? "\n " + (ciNum != -1
|
||||||
: line[inNum..])
|
? "in " + (lineNum != -1
|
||||||
: null));
|
? line[ciNum..lineNum] + "\n on " +
|
||||||
|
line[(lineNum + 1)..]
|
||||||
|
: line[ciNum..])
|
||||||
|
: line[inNum..])
|
||||||
|
: null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e = e.InnerException;
|
e = e.InnerException;
|
||||||
stackDepth++;
|
stackDepth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output.ToString();
|
return output.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool HandleException(this Exception e, Form form = null, string caption = null, string acceptButtonText = "Retry",
|
internal static bool HandleException(this Exception e, Form form = null, string caption = null,
|
||||||
|
string acceptButtonText = "Retry",
|
||||||
string cancelButtonText = "Cancel")
|
string cancelButtonText = "Cancel")
|
||||||
{
|
{
|
||||||
caption ??= Program.Name + " encountered an exception";
|
caption ??= Program.Name + " encountered an exception";
|
||||||
|
@ -51,12 +58,14 @@ internal static class ExceptionHandler
|
||||||
if (string.IsNullOrWhiteSpace(outputString))
|
if (string.IsNullOrWhiteSpace(outputString))
|
||||||
outputString = e?.ToString() ?? "Unknown exception";
|
outputString = e?.ToString() ?? "Unknown exception";
|
||||||
using DialogForm dialogForm = new(form ?? Form.ActiveForm);
|
using DialogForm dialogForm = new(form ?? Form.ActiveForm);
|
||||||
return dialogForm.Show(SystemIcons.Error, outputString, acceptButtonText, cancelButtonText, caption) is DialogResult.OK;
|
return dialogForm.Show(SystemIcons.Error, outputString, acceptButtonText, cancelButtonText, caption) is
|
||||||
|
DialogResult.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void HandleFatalException(this Exception e)
|
internal static void HandleFatalException(this Exception e)
|
||||||
{
|
{
|
||||||
e.HandleException(caption: Program.Name + " encountered a fatal exception", acceptButtonText: "OK", cancelButtonText: null);
|
e.HandleException(caption: Program.Name + " encountered a fatal exception", acceptButtonText: "OK",
|
||||||
|
cancelButtonText: null);
|
||||||
Application.Exit();
|
Application.Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,10 @@ internal static class HttpClientManager
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using HttpRequestMessage request = new(HttpMethod.Get, url);
|
using HttpRequestMessage request = new(HttpMethod.Get, url);
|
||||||
using HttpResponseMessage response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
using HttpResponseMessage response =
|
||||||
if (response.StatusCode is HttpStatusCode.NotModified && HttpContentCache.TryGetValue(url, out string content))
|
await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||||
|
if (response.StatusCode is HttpStatusCode.NotModified &&
|
||||||
|
HttpContentCache.TryGetValue(url, out string content))
|
||||||
return content;
|
return content;
|
||||||
_ = response.EnsureSuccessStatusCode();
|
_ = response.EnsureSuccessStatusCode();
|
||||||
content = await response.Content.ReadAsStringAsync();
|
content = await response.Content.ReadAsStringAsync();
|
||||||
|
|
|
@ -5,7 +5,8 @@ namespace CreamInstaller.Utility;
|
||||||
|
|
||||||
internal static class IconGrabber
|
internal static class IconGrabber
|
||||||
{
|
{
|
||||||
internal const string SteamAppImagesPath = "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/";
|
internal const string SteamAppImagesPath =
|
||||||
|
"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/";
|
||||||
|
|
||||||
private const string GoogleFaviconsApiUrl = "https://www.google.com/s2/favicons";
|
private const string GoogleFaviconsApiUrl = "https://www.google.com/s2/favicons";
|
||||||
|
|
||||||
|
@ -15,13 +16,16 @@ internal static class IconGrabber
|
||||||
return Icon.FromHandle(dialogIconBitmap.GetHicon());
|
return Icon.FromHandle(dialogIconBitmap.GetHicon());
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetDomainFaviconUrl(string domain, int size = 16) => GoogleFaviconsApiUrl + $"?domain={domain}&sz={size}";
|
internal static string GetDomainFaviconUrl(string domain, int size = 16) =>
|
||||||
|
GoogleFaviconsApiUrl + $"?domain={domain}&sz={size}";
|
||||||
|
|
||||||
internal static Image GetFileIconImage(this string path) => path.FileExists() ? Icon.ExtractAssociatedIcon(path)?.ToBitmap() : null;
|
internal static Image GetFileIconImage(this string path) =>
|
||||||
|
path.FileExists() ? Icon.ExtractAssociatedIcon(path)?.ToBitmap() : null;
|
||||||
|
|
||||||
internal static Image GetNotepadImage() => GetFileIconImage(Diagnostics.GetNotepadPath());
|
internal static Image GetNotepadImage() => GetFileIconImage(Diagnostics.GetNotepadPath());
|
||||||
|
|
||||||
internal static Image GetCommandPromptImage() => GetFileIconImage(Environment.SystemDirectory + @"\cmd.exe");
|
internal static Image GetCommandPromptImage() => GetFileIconImage(Environment.SystemDirectory + @"\cmd.exe");
|
||||||
|
|
||||||
internal static Image GetFileExplorerImage() => GetFileIconImage(Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\explorer.exe");
|
internal static Image GetFileExplorerImage() =>
|
||||||
|
GetFileIconImage(Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\explorer.exe");
|
||||||
}
|
}
|
|
@ -15,8 +15,10 @@ internal static partial class NativeImports
|
||||||
|
|
||||||
[LibraryImport("kernel32.dll", SetLastError = true), DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
[LibraryImport("kernel32.dll", SetLastError = true), DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
internal static partial bool GetBinaryType([MarshalAs(UnmanagedType.LPStr)] string lpApplicationName, out BinaryType lpBinaryType);
|
internal static partial bool GetBinaryType([MarshalAs(UnmanagedType.LPStr)] string lpApplicationName,
|
||||||
|
out BinaryType lpBinaryType);
|
||||||
|
|
||||||
[LibraryImport("user32.dll", SetLastError = true), DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
[LibraryImport("user32.dll", SetLastError = true), DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||||
internal static partial void SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
internal static partial void SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy,
|
||||||
|
uint uFlags);
|
||||||
}
|
}
|
|
@ -10,8 +10,11 @@ namespace CreamInstaller.Utility;
|
||||||
|
|
||||||
internal static class ProgramData
|
internal static class ProgramData
|
||||||
{
|
{
|
||||||
private static readonly string DirectoryPathOld = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\CreamInstaller";
|
private static readonly string DirectoryPathOld =
|
||||||
internal static readonly string DirectoryPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\CreamInstaller";
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\CreamInstaller";
|
||||||
|
|
||||||
|
internal static readonly string DirectoryPath =
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\CreamInstaller";
|
||||||
|
|
||||||
internal static readonly string AppInfoPath = DirectoryPath + @"\appinfo";
|
internal static readonly string AppInfoPath = DirectoryPath + @"\appinfo";
|
||||||
private static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt";
|
private static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt";
|
||||||
|
@ -33,13 +36,17 @@ internal static class ProgramData
|
||||||
DirectoryPath.DeleteDirectory();
|
DirectoryPath.DeleteDirectory();
|
||||||
DirectoryPathOld.MoveDirectory(DirectoryPath, true, form);
|
DirectoryPathOld.MoveDirectory(DirectoryPath, true, form);
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryPath.CreateDirectory();
|
DirectoryPath.CreateDirectory();
|
||||||
if (!AppInfoVersionPath.FileExists() || !Version.TryParse(AppInfoVersionPath.ReadFile(), out Version version) || version < MinimumAppInfoVersion)
|
if (!AppInfoVersionPath.FileExists() ||
|
||||||
|
!Version.TryParse(AppInfoVersionPath.ReadFile(), out Version version) ||
|
||||||
|
version < MinimumAppInfoVersion)
|
||||||
{
|
{
|
||||||
AppInfoPath.DeleteDirectory();
|
AppInfoPath.DeleteDirectory();
|
||||||
AppInfoPath.CreateDirectory();
|
AppInfoPath.CreateDirectory();
|
||||||
AppInfoVersionPath.WriteFile(Program.Version);
|
AppInfoVersionPath.WriteFile(Program.Version);
|
||||||
}
|
}
|
||||||
|
|
||||||
CooldownPath.CreateDirectory();
|
CooldownPath.CreateDirectory();
|
||||||
if (OldProgramChoicesPath.FileExists())
|
if (OldProgramChoicesPath.FileExists())
|
||||||
OldProgramChoicesPath.DeleteFile();
|
OldProgramChoicesPath.DeleteFile();
|
||||||
|
@ -71,6 +78,7 @@ internal static class ProgramData
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +101,8 @@ internal static class ProgramData
|
||||||
if (ProgramChoicesPath.FileExists())
|
if (ProgramChoicesPath.FileExists())
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (JsonConvert.DeserializeObject(ProgramChoicesPath.ReadFile(), typeof(List<(Platform platform, string id)>)) is
|
if (JsonConvert.DeserializeObject(ProgramChoicesPath.ReadFile(),
|
||||||
|
typeof(List<(Platform platform, string id)>)) is
|
||||||
List<(Platform platform, string id)> choices)
|
List<(Platform platform, string id)> choices)
|
||||||
return choices;
|
return choices;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +110,7 @@ internal static class ProgramData
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<(Platform platform, string id)>();
|
return Enumerable.Empty<(Platform platform, string id)>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +134,8 @@ internal static class ProgramData
|
||||||
if (DlcChoicesPath.FileExists())
|
if (DlcChoicesPath.FileExists())
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (JsonConvert.DeserializeObject(DlcChoicesPath.ReadFile(), typeof(IEnumerable<(Platform platform, string gameId, string dlcId)>)) is
|
if (JsonConvert.DeserializeObject(DlcChoicesPath.ReadFile(),
|
||||||
|
typeof(IEnumerable<(Platform platform, string gameId, string dlcId)>)) is
|
||||||
IEnumerable<(Platform platform, string gameId, string dlcId)> choices)
|
IEnumerable<(Platform platform, string gameId, string dlcId)> choices)
|
||||||
return choices;
|
return choices;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +143,7 @@ internal static class ProgramData
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<(Platform platform, string gameId, string dlcId)>();
|
return Enumerable.Empty<(Platform platform, string gameId, string dlcId)>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,10 +176,12 @@ internal static class ProgramData
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<(Platform platform, string id, string proxy, bool enabled)>();
|
return Enumerable.Empty<(Platform platform, string id, string proxy, bool enabled)>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteKoaloaderProxyChoices(IEnumerable<(Platform platform, string id, string proxy, bool enabled)> choices)
|
internal static void WriteKoaloaderProxyChoices(
|
||||||
|
IEnumerable<(Platform platform, string id, string proxy, bool enabled)> choices)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,12 +26,14 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || directoryPath.DirectoryExists() || directoryPath.IOWarn("Failed to create a crucial directory", e, form) is not DialogResult.OK)
|
if (!crucial || directoryPath.DirectoryExists() ||
|
||||||
|
directoryPath.IOWarn("Failed to create a crucial directory", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void MoveDirectory(this string directoryPath, string newDirectoryPath, bool crucial = false, Form form = null)
|
internal static void MoveDirectory(this string directoryPath, string newDirectoryPath, bool crucial = false,
|
||||||
|
Form form = null)
|
||||||
{
|
{
|
||||||
if (!directoryPath.DirectoryExists())
|
if (!directoryPath.DirectoryExists())
|
||||||
return;
|
return;
|
||||||
|
@ -43,7 +45,8 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !directoryPath.DirectoryExists() || directoryPath.IOWarn("Failed to move a crucial directory", e, form) is not DialogResult.OK)
|
if (!crucial || !directoryPath.DirectoryExists() ||
|
||||||
|
directoryPath.IOWarn("Failed to move a crucial directory", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,12 +64,14 @@ internal static class SafeIO
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !directoryPath.DirectoryExists()
|
if (!crucial || !directoryPath.DirectoryExists()
|
||||||
|| directoryPath.IOWarn("Failed to delete a crucial directory", e, form) is not DialogResult.OK)
|
|| directoryPath.IOWarn("Failed to delete a crucial directory", e, form) is not
|
||||||
|
DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IEnumerable<string> EnumerateDirectory(this string directoryPath, string filePattern, bool subdirectories = false, bool crucial = false,
|
internal static IEnumerable<string> EnumerateDirectory(this string directoryPath, string filePattern,
|
||||||
|
bool subdirectories = false, bool crucial = false,
|
||||||
Form form = null)
|
Form form = null)
|
||||||
{
|
{
|
||||||
if (!directoryPath.DirectoryExists())
|
if (!directoryPath.DirectoryExists())
|
||||||
|
@ -75,19 +80,23 @@ internal static class SafeIO
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return subdirectories
|
return subdirectories
|
||||||
? Directory.EnumerateFiles(directoryPath, filePattern, new EnumerationOptions { RecurseSubdirectories = true })
|
? Directory.EnumerateFiles(directoryPath, filePattern,
|
||||||
|
new EnumerationOptions { RecurseSubdirectories = true })
|
||||||
: Directory.EnumerateFiles(directoryPath, filePattern);
|
: Directory.EnumerateFiles(directoryPath, filePattern);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !directoryPath.DirectoryExists()
|
if (!crucial || !directoryPath.DirectoryExists()
|
||||||
|| directoryPath.IOWarn("Failed to enumerate a crucial directory's files", e, form) is not DialogResult.OK)
|
|| directoryPath.IOWarn("Failed to enumerate a crucial directory's files", e, form) is not
|
||||||
|
DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<string>();
|
return Enumerable.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IEnumerable<string> EnumerateSubdirectories(this string directoryPath, string directoryPattern, bool subdirectories = false,
|
internal static IEnumerable<string> EnumerateSubdirectories(this string directoryPath, string directoryPattern,
|
||||||
|
bool subdirectories = false,
|
||||||
bool crucial = false, Form form = null)
|
bool crucial = false, Form form = null)
|
||||||
{
|
{
|
||||||
if (!directoryPath.DirectoryExists())
|
if (!directoryPath.DirectoryExists())
|
||||||
|
@ -96,15 +105,18 @@ internal static class SafeIO
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return subdirectories
|
return subdirectories
|
||||||
? Directory.EnumerateDirectories(directoryPath, directoryPattern, new EnumerationOptions { RecurseSubdirectories = true })
|
? Directory.EnumerateDirectories(directoryPath, directoryPattern,
|
||||||
|
new EnumerationOptions { RecurseSubdirectories = true })
|
||||||
: Directory.EnumerateDirectories(directoryPath, directoryPattern);
|
: Directory.EnumerateDirectories(directoryPath, directoryPattern);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !directoryPath.DirectoryExists()
|
if (!crucial || !directoryPath.DirectoryExists()
|
||||||
|| directoryPath.IOWarn("Failed to enumerate a crucial directory's subdirectories", e, form) is not DialogResult.OK)
|
|| directoryPath.IOWarn("Failed to enumerate a crucial directory's subdirectories", e,
|
||||||
|
form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<string>();
|
return Enumerable.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +134,7 @@ internal static class SafeIO
|
||||||
if (!crucial || filePath.IOWarn("Failed to create a crucial file", e, form) is not DialogResult.OK)
|
if (!crucial || filePath.IOWarn("Failed to create a crucial file", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +150,8 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to move a crucial file", e, form) is not DialogResult.OK)
|
if (!crucial || !filePath.FileExists() ||
|
||||||
|
filePath.IOWarn("Failed to move a crucial file", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +168,8 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to delete a crucial file", e, form) is not DialogResult.OK)
|
if (!crucial || !filePath.FileExists() ||
|
||||||
|
filePath.IOWarn("Failed to delete a crucial file", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,9 +185,11 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to read a crucial file", e, form) is not DialogResult.OK)
|
if (!crucial || !filePath.FileExists() ||
|
||||||
|
filePath.IOWarn("Failed to read a crucial file", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,9 +204,11 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to read a crucial file", e, form) is not DialogResult.OK)
|
if (!crucial || !filePath.FileExists() ||
|
||||||
|
filePath.IOWarn("Failed to read a crucial file", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +227,8 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ExtractZip(this string archivePath, string destinationPath, bool crucial = false, Form form = null)
|
internal static void ExtractZip(this string archivePath, string destinationPath, bool crucial = false,
|
||||||
|
Form form = null)
|
||||||
{
|
{
|
||||||
if (!archivePath.FileExists())
|
if (!archivePath.FileExists())
|
||||||
return;
|
return;
|
||||||
|
@ -220,7 +240,8 @@ internal static class SafeIO
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!crucial || !archivePath.FileExists() || archivePath.IOWarn("Failed to extract a crucial zip file", e, form) is not DialogResult.OK)
|
if (!crucial || !archivePath.FileExists() ||
|
||||||
|
archivePath.IOWarn("Failed to extract a crucial zip file", e, form) is not DialogResult.OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,6 +276,7 @@ internal static class SafeIO
|
||||||
description += e.FormatException();
|
description += e.FormatException();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogResult result = dialogForm.Show(SystemIcons.Warning, description, "Retry", "Cancel");
|
DialogResult result = dialogForm.Show(SystemIcons.Warning, description, "Retry", "Cancel");
|
||||||
if (result is not DialogResult.OK)
|
if (result is not DialogResult.OK)
|
||||||
Program.Canceled = true;
|
Program.Canceled = true;
|
||||||
|
|
Loading…
Reference in a new issue