cleanup
This commit is contained in:
parent
0e48a18eee
commit
05e2ea5519
32 changed files with 1391 additions and 1735 deletions
|
@ -21,31 +21,25 @@ internal class ContextMenuItem : ToolStripMenuItem
|
|||
OnClickEvent = onClick;
|
||||
}
|
||||
|
||||
internal ContextMenuItem(string text, string imageIdentifier, EventHandler onClick = null)
|
||||
: this(text, onClick) => _ = TryImageIdentifier(this, imageIdentifier);
|
||||
internal ContextMenuItem(string text, string imageIdentifier, EventHandler onClick = null) : this(text, onClick)
|
||||
=> _ = TryImageIdentifier(this, imageIdentifier);
|
||||
|
||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, EventHandler onClick = null)
|
||||
: this(text, onClick) => _ = TryImageIdentifierInfo(this, imageIdentifierInfo);
|
||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, EventHandler onClick = null) : this(text, onClick)
|
||||
=> _ = TryImageIdentifierInfo(this, imageIdentifierInfo);
|
||||
|
||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo,
|
||||
string imageIdentifierFallback, EventHandler onClick = null)
|
||||
: this(text, onClick) => _ = TryImageIdentifierInfo(this, imageIdentifierInfo,
|
||||
async () => await TryImageIdentifier(
|
||||
this, imageIdentifierFallback));
|
||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, string imageIdentifierFallback, EventHandler onClick = null) :
|
||||
this(text, onClick)
|
||||
=> _ = TryImageIdentifierInfo(this, imageIdentifierInfo, async () => await TryImageIdentifier(this, imageIdentifierFallback));
|
||||
|
||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo,
|
||||
(string id, string iconUrl) imageIdentifierInfoFallback, EventHandler onClick = null)
|
||||
: this(text, onClick) => _ = TryImageIdentifierInfo(this, imageIdentifierInfo,
|
||||
async () => await TryImageIdentifierInfo(
|
||||
this, imageIdentifierInfoFallback));
|
||||
internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, (string id, string iconUrl) imageIdentifierInfoFallback,
|
||||
EventHandler onClick = null) : this(text, onClick)
|
||||
=> _ = TryImageIdentifierInfo(this, imageIdentifierInfo, async () => await TryImageIdentifierInfo(this, imageIdentifierInfoFallback));
|
||||
|
||||
private static async Task TryImageIdentifier(ContextMenuItem item, string imageIdentifier) => await Task.Run(
|
||||
async () =>
|
||||
private static async Task TryImageIdentifier(ContextMenuItem item, string imageIdentifier)
|
||||
=> await Task.Run(async () =>
|
||||
{
|
||||
if (images.TryGetValue(imageIdentifier, out Image image) && image is not null)
|
||||
{
|
||||
item.Image = image;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (imageIdentifier)
|
||||
|
@ -68,28 +62,22 @@ internal class ContextMenuItem : ToolStripMenuItem
|
|||
image = IconGrabber.GetFileExplorerImage();
|
||||
break;
|
||||
case "SteamDB":
|
||||
image = await HttpClientManager.GetImageFromUrl(
|
||||
IconGrabber.GetDomainFaviconUrl("steamdb.info"));
|
||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("steamdb.info"));
|
||||
break;
|
||||
case "Steam Store":
|
||||
image = await HttpClientManager.GetImageFromUrl(
|
||||
IconGrabber.GetDomainFaviconUrl("store.steampowered.com"));
|
||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("store.steampowered.com"));
|
||||
break;
|
||||
case "Steam Community":
|
||||
image = await HttpClientManager.GetImageFromUrl(
|
||||
IconGrabber.GetDomainFaviconUrl("steamcommunity.com"));
|
||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("steamcommunity.com"));
|
||||
break;
|
||||
case "ScreamDB":
|
||||
image = await HttpClientManager.GetImageFromUrl(
|
||||
IconGrabber.GetDomainFaviconUrl("scream-db.web.app"));
|
||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("scream-db.web.app"));
|
||||
break;
|
||||
case "Epic Games":
|
||||
image = await HttpClientManager.GetImageFromUrl(
|
||||
IconGrabber.GetDomainFaviconUrl("epicgames.com"));
|
||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("epicgames.com"));
|
||||
break;
|
||||
case "Ubisoft Store":
|
||||
image = await HttpClientManager.GetImageFromUrl(
|
||||
IconGrabber.GetDomainFaviconUrl("store.ubi.com"));
|
||||
image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("store.ubi.com"));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
@ -102,35 +90,31 @@ internal class ContextMenuItem : ToolStripMenuItem
|
|||
}
|
||||
});
|
||||
|
||||
private static async Task TryImageIdentifierInfo(ContextMenuItem item,
|
||||
(string id, string iconUrl) imageIdentifierInfo,
|
||||
Action onFail = null) => await Task.Run(async () =>
|
||||
{
|
||||
(string id, string iconUrl) = imageIdentifierInfo;
|
||||
string imageIdentifier = "Icon_" + id;
|
||||
if (images.TryGetValue(imageIdentifier, out Image image) && image is not null)
|
||||
private static async Task TryImageIdentifierInfo(ContextMenuItem item, (string id, string iconUrl) imageIdentifierInfo, Action onFail = null)
|
||||
=> await Task.Run(async () =>
|
||||
{
|
||||
item.Image = image;
|
||||
}
|
||||
else
|
||||
{
|
||||
image = await HttpClientManager.GetImageFromUrl(iconUrl);
|
||||
if (image is not null)
|
||||
{
|
||||
images[imageIdentifier] = image;
|
||||
(string id, string iconUrl) = imageIdentifierInfo;
|
||||
string imageIdentifier = "Icon_" + id;
|
||||
if (images.TryGetValue(imageIdentifier, out Image image) && image is not null)
|
||||
item.Image = image;
|
||||
}
|
||||
else if (onFail is not null)
|
||||
else
|
||||
{
|
||||
onFail();
|
||||
image = await HttpClientManager.GetImageFromUrl(iconUrl);
|
||||
if (image is not null)
|
||||
{
|
||||
images[imageIdentifier] = image;
|
||||
item.Image = image;
|
||||
}
|
||||
else if (onFail is not null)
|
||||
onFail();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
protected override void OnClick(EventArgs e)
|
||||
{
|
||||
base.OnClick(e);
|
||||
if (OnClickEvent is null) return;
|
||||
if (OnClickEvent is null)
|
||||
return;
|
||||
OnClickEvent.Invoke(this, e);
|
||||
}
|
||||
}
|
|
@ -58,46 +58,38 @@ internal class CustomForm : Form
|
|||
string acidicoala = "https://github.com/acidicoala";
|
||||
string repository = $"https://github.com/{Program.RepositoryOwner}/{Program.RepositoryName}";
|
||||
_ = helpDialog.Show(SystemIcons.Information,
|
||||
"Automatically finds all installed Steam, Epic and Ubisoft games with their respective DLC-related DLL locations on the user's computer,\n"
|
||||
+ "parses SteamCMD, Steam Store and Epic Games Store for user-selected games' DLCs, then provides a very simple graphical interface\n"
|
||||
+ "utilizing the gathered information for the maintenance of DLC unlockers.\n"
|
||||
+ "\n"
|
||||
+ $"The program utilizes the latest versions of [Koaloader]({acidicoala}/Koaloader), [SmokeAPI]({acidicoala}/SmokeAPI), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1 Unlocker]({acidicoala}/UplayR1Unlocker) and [Uplay R2 Unlocker]({acidicoala}/UplayR2Unlocker), all by\n"
|
||||
+ $"the wonderful [acidicoala]({acidicoala}), and all downloaded and embedded into the program itself; no further downloads necessary on your part!\n"
|
||||
+ "\n"
|
||||
+ "NOTE: This program does not automatically download nor install actual DLC files for you. As the title of the program says, it's\n"
|
||||
+ "only a DLC Unlocker installer. Should the game you wish to unlock DLC for not already come with the DLCs installed (very many\n"
|
||||
+ "do not), you have to find, download, and install those yourself. Preferably, you should be referring to the proper cs.rin.ru post for\n"
|
||||
+ "the game(s) you're tinkering with; you'll usually find any answer to your problems there.\n"
|
||||
+ "\n"
|
||||
+ "USAGE:\n"
|
||||
+ " 1. Choose which programs and/or games the program should scan for DLC.\n"
|
||||
+ " The program automatically gathers all installed games from Steam, Epic and Ubisoft directories.\n"
|
||||
+ " 2. Wait for the program to download and install SteamCMD (if you chose a Steam game).\n"
|
||||
+ " 3. Wait for the program to gather and cache the chosen games' information && DLCs.\n"
|
||||
+ " 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"
|
||||
+ " 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"
|
||||
+ " If the default \'version.dll\' doesn't work, then see [here](https://cs.rin.ru/forum/viewtopic.php?p=2552172#p2552172) to find one that does.\n"
|
||||
+ " 6. Click the \"Generate and Install\" button.\n"
|
||||
+ " 7. Click the \"OK\" button to close the program.\n"
|
||||
+ " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\n"
|
||||
+ " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n"
|
||||
+ "\n"
|
||||
+ $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n"
|
||||
+ "\n"
|
||||
+ "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n"
|
||||
+ $"The program automatically and very quickly updates from [GitHub]({repository}) using [Onova](https://github.com/Tyrrrz/Onova). (updates can be ignored)\n"
|
||||
+ $"The program source and other information can be found on [GitHub]({repository}).");
|
||||
"Automatically finds all installed Steam, Epic and Ubisoft games with their respective DLC-related DLL locations on the user's computer,\n"
|
||||
+ "parses SteamCMD, Steam Store and Epic Games Store for user-selected games' DLCs, then provides a very simple graphical interface\n"
|
||||
+ "utilizing the gathered information for the maintenance of DLC unlockers.\n" + "\n"
|
||||
+ $"The program utilizes the latest versions of [Koaloader]({acidicoala}/Koaloader), [SmokeAPI]({acidicoala}/SmokeAPI), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1 Unlocker]({acidicoala}/UplayR1Unlocker) and [Uplay R2 Unlocker]({acidicoala}/UplayR2Unlocker), all by\n"
|
||||
+ $"the wonderful [acidicoala]({acidicoala}), and all downloaded and embedded into the program itself; no further downloads necessary on your part!\n"
|
||||
+ "\n" + "NOTE: This program does not automatically download nor install actual DLC files for you. As the title of the program says, it's\n"
|
||||
+ "only a DLC Unlocker installer. Should the game you wish to unlock DLC for not already come with the DLCs installed (very many\n"
|
||||
+ "do not), you have to find, download, and install those yourself. Preferably, you should be referring to the proper cs.rin.ru post for\n"
|
||||
+ "the game(s) you're tinkering with; you'll usually find any answer to your problems there.\n" + "\n" + "USAGE:\n"
|
||||
+ " 1. Choose which programs and/or games the program should scan for DLC.\n"
|
||||
+ " The program automatically gathers all installed games from Steam, Epic and Ubisoft directories.\n"
|
||||
+ " 2. Wait for the program to download and install SteamCMD (if you chose a Steam game).\n"
|
||||
+ " 3. Wait for the program to gather and cache the chosen games' information && DLCs.\n"
|
||||
+ " 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"
|
||||
+ " 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"
|
||||
+ " If the default \'version.dll\' doesn't work, then see [here](https://cs.rin.ru/forum/viewtopic.php?p=2552172#p2552172) to find one that does.\n"
|
||||
+ " 6. Click the \"Generate and Install\" button.\n" + " 7. Click the \"OK\" button to close the program.\n"
|
||||
+ " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\n"
|
||||
+ " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n" + "\n"
|
||||
+ $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n"
|
||||
+ "\n" + "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n"
|
||||
+ $"The program automatically and very quickly updates from [GitHub]({repository}) using [Onova](https://github.com/Tyrrrz/Onova). (updates can be ignored)\n"
|
||||
+ $"The program source and other information can be found on [GitHub]({repository}).");
|
||||
}
|
||||
|
||||
internal void OnActivation(object sender, EventArgs args) => Activate();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
internal static extern void SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy,
|
||||
uint uFlags);
|
||||
internal static extern void SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
internal void BringToFrontWithoutActivation()
|
||||
{
|
||||
|
@ -113,12 +105,13 @@ internal class CustomForm : Form
|
|||
return;
|
||||
int X = fromForm.Location.X + fromForm.Size.Width / 2 - Size.Width / 2;
|
||||
int Y = fromForm.Location.Y + fromForm.Size.Height / 2 - Size.Height / 2;
|
||||
Location = new Point(X, Y);
|
||||
Location = new(X, Y);
|
||||
}
|
||||
|
||||
private void OnKeyPress(object s, KeyPressEventArgs e)
|
||||
{
|
||||
if (e.KeyChar != 'S') return; // Shift + S
|
||||
if (e.KeyChar != 'S')
|
||||
return; // Shift + S
|
||||
UpdateBounds();
|
||||
Rectangle bounds = Bounds;
|
||||
using Bitmap bitmap = new(Size.Width - 14, Size.Height - 7);
|
||||
|
@ -127,8 +120,7 @@ internal class CustomForm : Form
|
|||
using EncoderParameters encoding = new(1);
|
||||
using EncoderParameter encoderParam = new(Encoder.Quality, 100L);
|
||||
encoding.Param[0] = encoderParam;
|
||||
graphics.CopyFromScreen(new Point(bounds.Left + 7, bounds.Top), Point.Empty,
|
||||
new Size(Size.Width - 14, Size.Height - 7));
|
||||
graphics.CopyFromScreen(new(bounds.Left + 7, bounds.Top), Point.Empty, new(Size.Width - 14, Size.Height - 7));
|
||||
Clipboard.SetImage(bitmap);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,7 @@ internal class CustomTreeView : TreeView
|
|||
Size size;
|
||||
Rectangle bounds = node.Bounds;
|
||||
Rectangle selectionBounds = bounds;
|
||||
Color
|
||||
color; // = highlighted ? SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor;
|
||||
Color color; // = highlighted ? SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor;
|
||||
Point point;
|
||||
/*Size textSize = TextRenderer.MeasureText(text, font);
|
||||
Point textLoc = new(bounds.X - 1, bounds.Y);
|
||||
|
@ -88,8 +87,7 @@ internal class CustomTreeView : TreeView
|
|||
text = platform.ToString();
|
||||
size = TextRenderer.MeasureText(graphics, text, font);
|
||||
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width };
|
||||
selectionBounds
|
||||
= new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
graphics.FillRectangle(brush, bounds);
|
||||
point = new Point(bounds.Location.X - 1, bounds.Location.Y + 1);
|
||||
TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.Default);
|
||||
|
@ -104,8 +102,7 @@ internal class CustomTreeView : TreeView
|
|||
size = TextRenderer.MeasureText(graphics, text, font);
|
||||
int left = -4;
|
||||
bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width };
|
||||
selectionBounds = new Rectangle(selectionBounds.Location,
|
||||
selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||
selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||
graphics.FillRectangle(brush, bounds);
|
||||
point = new Point(bounds.Location.X - 1, bounds.Location.Y + 1);
|
||||
TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.Default);
|
||||
|
@ -130,8 +127,7 @@ internal class CustomTreeView : TreeView
|
|||
: CheckBoxState.UncheckedDisabled;
|
||||
size = CheckBoxRenderer.GetGlyphSize(graphics, checkBoxState);
|
||||
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width };
|
||||
selectionBounds = new Rectangle(selectionBounds.Location,
|
||||
selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
Rectangle checkBoxBounds = bounds;
|
||||
graphics.FillRectangle(backBrush, bounds);
|
||||
point = new Point(bounds.Left, bounds.Top + bounds.Height / 2 - size.Height / 2 - 1);
|
||||
|
@ -140,41 +136,31 @@ internal class CustomTreeView : TreeView
|
|||
size = TextRenderer.MeasureText(graphics, text, font);
|
||||
int left = 1;
|
||||
bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width + left };
|
||||
selectionBounds = new Rectangle(selectionBounds.Location,
|
||||
selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
checkBoxBounds = new Rectangle(checkBoxBounds.Location,
|
||||
checkBoxBounds.Size + bounds.Size with { Height = 0 });
|
||||
selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
checkBoxBounds = new Rectangle(checkBoxBounds.Location, checkBoxBounds.Size + bounds.Size with { Height = 0 });
|
||||
graphics.FillRectangle(backBrush, bounds);
|
||||
point = new Point(bounds.Location.X - 1 + left, bounds.Location.Y + 1);
|
||||
TextRenderer.DrawText(graphics, text, font, point,
|
||||
Enabled
|
||||
? ColorTranslator.FromHtml("#006900")
|
||||
: ColorTranslator.FromHtml("#69AA69"),
|
||||
TextFormatFlags.Default);
|
||||
TextRenderer.DrawText(graphics, text, font, point, Enabled ? ColorTranslator.FromHtml("#006900") : ColorTranslator.FromHtml("#69AA69"),
|
||||
TextFormatFlags.Default);
|
||||
this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds);
|
||||
string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy;
|
||||
if (selection.Koaloader && proxy is not null)
|
||||
{
|
||||
comboBoxFont ??= new Font(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet,
|
||||
font.GdiVerticalFont);
|
||||
comboBoxFont ??= new Font(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont);
|
||||
ComboBoxState comboBoxState = Enabled ? ComboBoxState.Normal : ComboBoxState.Disabled;
|
||||
text = proxy + ".dll";
|
||||
size = TextRenderer.MeasureText(graphics, text, comboBoxFont) + new Size(6, 0);
|
||||
int padding = 2;
|
||||
bounds = new Rectangle(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width,
|
||||
bounds.Height - padding);
|
||||
selectionBounds = new Rectangle(selectionBounds.Location,
|
||||
selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
bounds = new Rectangle(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width, bounds.Height - padding);
|
||||
selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 });
|
||||
Rectangle comboBoxBounds = bounds;
|
||||
graphics.FillRectangle(backBrush, bounds);
|
||||
ComboBoxRenderer.DrawTextBox(graphics, bounds, text, comboBoxFont, comboBoxState);
|
||||
size = new Size(14, 0);
|
||||
left = -1;
|
||||
bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width };
|
||||
selectionBounds = new Rectangle(selectionBounds.Location,
|
||||
selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||
comboBoxBounds = new Rectangle(comboBoxBounds.Location,
|
||||
comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||
selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||
comboBoxBounds = new Rectangle(comboBoxBounds.Location, comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0));
|
||||
ComboBoxRenderer.DrawDropDownButton(graphics, bounds, comboBoxState);
|
||||
this.comboBoxBounds[selection] = RectangleToClient(comboBoxBounds);
|
||||
}
|
||||
|
@ -215,13 +201,11 @@ internal class CustomTreeView : TreeView
|
|||
}
|
||||
else if (pair.Value.Contains(clickPoint))
|
||||
{
|
||||
List<string> proxies = EmbeddedResources.FindAll(r => r.StartsWith("Koaloader"))
|
||||
.Select(p =>
|
||||
{
|
||||
p.GetProxyInfoFromIdentifier(
|
||||
out string proxyName, out _);
|
||||
return proxyName;
|
||||
}).Distinct().ToList();
|
||||
List<string> proxies = EmbeddedResources.FindAll(r => r.StartsWith("Koaloader")).Select(p =>
|
||||
{
|
||||
p.GetProxyInfoFromIdentifier(out string proxyName, out _);
|
||||
return proxyName;
|
||||
}).Distinct().ToList();
|
||||
comboBoxDropDown ??= new ToolStripDropDown();
|
||||
comboBoxDropDown.ShowItemToolTips = false;
|
||||
comboBoxDropDown.Items.Clear();
|
||||
|
@ -240,8 +224,7 @@ internal class CustomTreeView : TreeView
|
|||
if (canUse)
|
||||
_ = comboBoxDropDown.Items.Add(new ToolStripButton(proxy + ".dll", null, (s, e) =>
|
||||
{
|
||||
pair.Key.KoaloaderProxy
|
||||
= proxy == ProgramSelection.DefaultKoaloaderProxy ? null : proxy;
|
||||
pair.Key.KoaloaderProxy = proxy == ProgramSelection.DefaultKoaloaderProxy ? null : proxy;
|
||||
selectForm.OnKoaloaderChanged();
|
||||
}) { Font = comboBoxFont });
|
||||
}
|
||||
|
|
|
@ -14,16 +14,16 @@ internal static class PlatformIdComparer
|
|||
private static NodeNameComparer nodeNameComparer;
|
||||
|
||||
private static NodeTextComparer nodeTextComparer;
|
||||
internal static StringComparer String => stringComparer ??= new StringComparer();
|
||||
internal static NodeComparer Node => nodeComparer ??= new NodeComparer();
|
||||
internal static NodeNameComparer NodeName => nodeNameComparer ??= new NodeNameComparer();
|
||||
internal static NodeTextComparer NodeText => nodeTextComparer ??= new NodeTextComparer();
|
||||
internal static StringComparer String => stringComparer ??= new();
|
||||
internal static NodeComparer Node => nodeComparer ??= new();
|
||||
internal static NodeNameComparer NodeName => nodeNameComparer ??= new();
|
||||
internal static NodeTextComparer NodeText => nodeTextComparer ??= new();
|
||||
}
|
||||
|
||||
internal class StringComparer : IComparer<string>
|
||||
{
|
||||
public int Compare(string a, string b) =>
|
||||
!int.TryParse(a, out _) && !int.TryParse(b, out _)
|
||||
public int Compare(string a, string b)
|
||||
=> !int.TryParse(a, out _) && !int.TryParse(b, out _)
|
||||
? string.Compare(a, b, StringComparison.Ordinal)
|
||||
: !int.TryParse(a, out int A)
|
||||
? 1
|
||||
|
@ -38,8 +38,8 @@ internal class StringComparer : IComparer<string>
|
|||
|
||||
internal class NodeComparer : IComparer<TreeNode>
|
||||
{
|
||||
public int Compare(TreeNode a, TreeNode b) =>
|
||||
a.Tag is not Platform A
|
||||
public int Compare(TreeNode a, TreeNode b)
|
||||
=> a.Tag is not Platform A
|
||||
? 1
|
||||
: b.Tag is not Platform B
|
||||
? -1
|
||||
|
@ -52,8 +52,8 @@ internal class NodeComparer : IComparer<TreeNode>
|
|||
|
||||
internal class NodeNameComparer : IComparer
|
||||
{
|
||||
public int Compare(object a, object b) =>
|
||||
a is not TreeNode A
|
||||
public int Compare(object a, object b)
|
||||
=> a is not TreeNode A
|
||||
? 1
|
||||
: b is not TreeNode B
|
||||
? -1
|
||||
|
@ -64,8 +64,8 @@ internal class NodeNameComparer : IComparer
|
|||
|
||||
internal class NodeTextComparer : IComparer
|
||||
{
|
||||
public int Compare(object a, object b) =>
|
||||
a is not TreeNode A
|
||||
public int Compare(object a, object b)
|
||||
=> a is not TreeNode A
|
||||
? 1
|
||||
: b is not TreeNode B
|
||||
? -1
|
||||
|
|
|
@ -24,7 +24,7 @@ internal partial class DebugForm : CustomForm
|
|||
{
|
||||
if (current is not null && (current.Disposing || current.IsDisposed))
|
||||
current = null;
|
||||
return current ??= new DebugForm();
|
||||
return current ??= new();
|
||||
}
|
||||
set => current = value;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ internal partial class DebugForm : CustomForm
|
|||
if (attachedForm is not null && attachedForm.Visible)
|
||||
{
|
||||
//Size = new(Size.Width, attachedForm.Size.Height);
|
||||
Location = new Point(attachedForm.Right, attachedForm.Top);
|
||||
Location = new(attachedForm.Right, attachedForm.Top);
|
||||
BringToFrontWithoutActivation();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ internal partial class DialogForm : CustomForm
|
|||
{
|
||||
internal DialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
|
||||
|
||||
internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText = "OK",
|
||||
string cancelButtonText = null, string customFormText = null, Icon customFormIcon = null)
|
||||
internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText = "OK", string cancelButtonText = null,
|
||||
string customFormText = null, Icon customFormIcon = null)
|
||||
{
|
||||
descriptionIcon ??= Icon;
|
||||
icon.Image = descriptionIcon.ToBitmap();
|
||||
|
@ -32,7 +32,7 @@ internal partial class DialogForm : CustomForm
|
|||
if (string.IsNullOrWhiteSpace(link))
|
||||
link = text;
|
||||
descriptionText = descriptionText.Remove(i, linkRight + 1 - i).Insert(i, text);
|
||||
links.Add(new LinkLabel.Link(i, text.Length, link));
|
||||
links.Add(new(i, text.Length, link));
|
||||
}
|
||||
}
|
||||
descriptionLabel.Text = descriptionText;
|
||||
|
@ -43,13 +43,9 @@ internal partial class DialogForm : CustomForm
|
|||
cancelButton.Visible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelButton.Text = cancelButtonText;
|
||||
}
|
||||
if (customFormText is not null)
|
||||
{
|
||||
Text = customFormText;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnResize(null, null);
|
||||
|
@ -61,16 +57,13 @@ internal partial class DialogForm : CustomForm
|
|||
{
|
||||
foreach (LinkLabel.Link link in links)
|
||||
_ = descriptionLabel.Links.Add(link);
|
||||
descriptionLabel.LinkClicked += (s, e)
|
||||
=> Process.Start(new ProcessStartInfo((string)e.Link.LinkData) { UseShellExecute = true });
|
||||
descriptionLabel.LinkClicked += (s, e) => Process.Start(new ProcessStartInfo((string)e.Link.LinkData) { UseShellExecute = true });
|
||||
}
|
||||
return ShowDialog();
|
||||
}
|
||||
|
||||
private void OnResize(object s, EventArgs e) =>
|
||||
Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100
|
||||
? TextRenderer.MeasureText(Program.ApplicationNameShort, Font).Width > Size.Width - 100
|
||||
? Program.Name
|
||||
: Program.ApplicationNameShort
|
||||
private void OnResize(object s, EventArgs e)
|
||||
=> Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100
|
||||
? TextRenderer.MeasureText(Program.ApplicationNameShort, Font).Width > Size.Width - 100 ? Program.Name : Program.ApplicationNameShort
|
||||
: Program.ApplicationName;
|
||||
}
|
||||
|
|
|
@ -38,18 +38,21 @@ internal partial class InstallForm : CustomForm
|
|||
userProgressBar.Invoke(() =>
|
||||
{
|
||||
int value = (int)((float)CompleteOperationsCount / OperationsCount * 100) + progress / OperationsCount;
|
||||
if (value < userProgressBar.Value) return;
|
||||
if (value < userProgressBar.Value)
|
||||
return;
|
||||
userProgressBar.Value = value;
|
||||
});
|
||||
}
|
||||
|
||||
internal void UpdateUser(string text, Color color, bool info = true, bool log = true)
|
||||
{
|
||||
if (info) _ = userInfoLabel.Invoke(() => userInfoLabel.Text = text);
|
||||
if (info)
|
||||
_ = userInfoLabel.Invoke(() => userInfoLabel.Text = text);
|
||||
if (log && !logTextBox.Disposing && !logTextBox.IsDisposed)
|
||||
logTextBox.Invoke(() =>
|
||||
{
|
||||
if (logTextBox.Text.Length > 0) logTextBox.AppendText(Environment.NewLine, color);
|
||||
if (logTextBox.Text.Length > 0)
|
||||
logTextBox.AppendText(Environment.NewLine, color);
|
||||
logTextBox.AppendText(text, color);
|
||||
logTextBox.Invalidate();
|
||||
});
|
||||
|
@ -63,12 +66,11 @@ internal partial class InstallForm : CustomForm
|
|||
UpdateUser("Repairing Paradox Launcher . . . ", LogTextBox.Operation);
|
||||
_ = await Repair(this, selection);
|
||||
}
|
||||
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")}" +
|
||||
$" {(Uninstalling ? "from" : "for")} " + selection.Name
|
||||
+ $" with root directory \"{selection.RootDirectory}\" . . . ", LogTextBox.Operation);
|
||||
UpdateUser(
|
||||
$"{(Uninstalling ? "Uninstalling" : "Installing")}" + $" {(Uninstalling ? "from" : "for")} " + selection.Name
|
||||
+ $" with root directory \"{selection.RootDirectory}\" . . . ", LogTextBox.Operation);
|
||||
IEnumerable<string> invalidDirectories = (await selection.RootDirectory.GetExecutables())
|
||||
?.Where(d => !selection.ExecutableDirectories.Any(
|
||||
s => s.directory == Path.GetDirectoryName(d.path)))
|
||||
?.Where(d => !selection.ExecutableDirectories.Any(s => s.directory == Path.GetDirectoryName(d.path)))
|
||||
?.Select(d => Path.GetDirectoryName(d.path));
|
||||
if (!selection.ExecutableDirectories.Any(s => s.directory == selection.RootDirectory))
|
||||
invalidDirectories = invalidDirectories?.Append(selection.RootDirectory);
|
||||
|
@ -76,16 +78,13 @@ internal partial class InstallForm : CustomForm
|
|||
if (invalidDirectories is not null)
|
||||
foreach (string directory in invalidDirectories)
|
||||
{
|
||||
if (Program.Canceled) throw new CustomMessageException("The operation was canceled.");
|
||||
if (Program.Canceled)
|
||||
throw new CustomMessageException("The operation was canceled.");
|
||||
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
|
||||
if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||
|| (directory != selection.RootDirectory
|
||||
&& Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll)))
|
||||
|| File.Exists(config))
|
||||
|| directory != selection.RootDirectory && Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll)) || File.Exists(config))
|
||||
{
|
||||
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);
|
||||
}
|
||||
Thread.Sleep(1);
|
||||
|
@ -93,15 +92,13 @@ internal partial class InstallForm : CustomForm
|
|||
if (Uninstalling || !selection.Koaloader)
|
||||
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
|
||||
{
|
||||
if (Program.Canceled) throw new CustomMessageException("The operation was canceled.");
|
||||
if (Program.Canceled)
|
||||
throw new CustomMessageException("The operation was canceled.");
|
||||
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
|
||||
if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||
|| Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll))
|
||||
|| File.Exists(config))
|
||||
|| Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll)) || File.Exists(config))
|
||||
{
|
||||
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);
|
||||
}
|
||||
Thread.Sleep(1);
|
||||
|
@ -110,18 +107,19 @@ internal partial class InstallForm : CustomForm
|
|||
int count = selection.DllDirectories.Count, cur = 0;
|
||||
foreach (string directory in selection.DllDirectories)
|
||||
{
|
||||
if (Program.Canceled) throw new CustomMessageException("The operation was canceled.");
|
||||
if (Program.Canceled)
|
||||
throw new CustomMessageException("The operation was canceled.");
|
||||
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 config, out string cache);
|
||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config,
|
||||
out string cache);
|
||||
if (uninstallProxy
|
||||
? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(cache)
|
||||
: File.Exists(api32) || File.Exists(api64))
|
||||
{
|
||||
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" +
|
||||
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
UpdateUser(
|
||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
if (uninstallProxy)
|
||||
await SmokeAPI.Uninstall(directory, this);
|
||||
else
|
||||
|
@ -130,15 +128,12 @@ internal partial class InstallForm : CustomForm
|
|||
}
|
||||
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);
|
||||
if (uninstallProxy
|
||||
? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config)
|
||||
: File.Exists(api32) || File.Exists(api64))
|
||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(api32) || File.Exists(api64))
|
||||
{
|
||||
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" +
|
||||
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
UpdateUser(
|
||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
if (uninstallProxy)
|
||||
await ScreamAPI.Uninstall(directory, this);
|
||||
else
|
||||
|
@ -147,29 +142,25 @@ internal partial class InstallForm : CustomForm
|
|||
}
|
||||
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);
|
||||
if (uninstallProxy
|
||||
? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config)
|
||||
: File.Exists(api32) || File.Exists(api64))
|
||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(api32) || File.Exists(api64))
|
||||
{
|
||||
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" +
|
||||
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
UpdateUser(
|
||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
if (uninstallProxy)
|
||||
await UplayR1.Uninstall(directory, this);
|
||||
else
|
||||
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);
|
||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config);
|
||||
if (uninstallProxy
|
||||
? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config)
|
||||
: File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api64))
|
||||
{
|
||||
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" +
|
||||
$" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
UpdateUser(
|
||||
$"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name
|
||||
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
if (uninstallProxy)
|
||||
await UplayR2.Uninstall(directory, this);
|
||||
else
|
||||
|
@ -182,9 +173,9 @@ internal partial class InstallForm : CustomForm
|
|||
if (selection.Koaloader && !Uninstalling)
|
||||
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
|
||||
{
|
||||
if (Program.Canceled) throw new CustomMessageException("The operation was canceled.");
|
||||
UpdateUser("Installing Koaloader to " + selection.Name + $" in directory \"{directory}\" . . . ",
|
||||
LogTextBox.Operation);
|
||||
if (Program.Canceled)
|
||||
throw new CustomMessageException("The operation was canceled.");
|
||||
UpdateUser("Installing Koaloader to " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
|
||||
await Koaloader.Install(directory, binaryType, selection, selection.RootDirectory, this);
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
@ -236,13 +227,12 @@ internal partial class InstallForm : CustomForm
|
|||
try
|
||||
{
|
||||
await Operate();
|
||||
UpdateUser($"DLC unlocker(s) successfully {(Uninstalling ? "uninstalled" : "installed and generated")} for "
|
||||
+ ProgramCount + " program(s).", LogTextBox.Success);
|
||||
UpdateUser($"DLC unlocker(s) successfully {(Uninstalling ? "uninstalled" : "installed and generated")} for " + ProgramCount + " program(s).",
|
||||
LogTextBox.Success);
|
||||
}
|
||||
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;
|
||||
}
|
||||
userProgressBar.Value = userProgressBar.Maximum;
|
||||
|
@ -262,7 +252,8 @@ internal partial class InstallForm : CustomForm
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e.HandleException(this)) goto retry;
|
||||
if (e.HandleException(this))
|
||||
goto retry;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,24 +58,18 @@ internal partial class MainForm : CustomForm
|
|||
updateButton.Click -= OnUpdateCancel;
|
||||
progressLabel.Text = "Checking for updates . . .";
|
||||
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();
|
||||
#if DEBUG
|
||||
DebugForm.Current.Attach(this);
|
||||
#endif
|
||||
GithubPackageResolver resolver = new(Program.RepositoryOwner, Program.RepositoryName,
|
||||
Program.RepositoryPackage);
|
||||
GithubPackageResolver resolver = new(Program.RepositoryOwner, Program.RepositoryName, Program.RepositoryPackage);
|
||||
ZipPackageExtractor extractor = new();
|
||||
updateManager
|
||||
= new UpdateManager(AssemblyMetadata.FromAssembly(Program.EntryAssembly, Program.CurrentProcessFilePath),
|
||||
resolver, extractor);
|
||||
updateManager = new(AssemblyMetadata.FromAssembly(Program.EntryAssembly, Program.CurrentProcessFilePath), resolver, extractor);
|
||||
if (latestVersion is null)
|
||||
{
|
||||
CheckForUpdatesResult checkForUpdatesResult = null;
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
cancellationTokenSource = new();
|
||||
try
|
||||
{
|
||||
checkForUpdatesResult = await updateManager.CheckForUpdatesAsync(cancellationTokenSource.Token);
|
||||
|
@ -93,8 +87,7 @@ internal partial class MainForm : CustomForm
|
|||
catch (TaskCanceledException) { }
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugForm.Current.Log($"Exception while checking for updates: {e.GetType()} ({e.Message})",
|
||||
LogTextBox.Warning);
|
||||
DebugForm.Current.Log($"Exception while checking for updates: {e.GetType()} ({e.Message})", LogTextBox.Warning);
|
||||
}
|
||||
#else
|
||||
catch { }
|
||||
|
@ -120,8 +113,7 @@ internal partial class MainForm : CustomForm
|
|||
changelogTreeView.Visible = true;
|
||||
Version currentVersion = new(Program.Version);
|
||||
#if DEBUG
|
||||
foreach (Version version in versions.Where(v => (v > currentVersion || v == latestVersion)
|
||||
&& !changelogTreeView.Nodes.ContainsKey(v.ToString())))
|
||||
foreach (Version version in versions.Where(v => (v > currentVersion || v == latestVersion) && !changelogTreeView.Nodes.ContainsKey(v.ToString())))
|
||||
#else
|
||||
foreach (Version version in versions.Where(v => v > currentVersion && !changelogTreeView.Nodes.ContainsKey(v.ToString())))
|
||||
#endif
|
||||
|
@ -162,9 +154,8 @@ internal partial class MainForm : CustomForm
|
|||
{
|
||||
using DialogForm form = new(this);
|
||||
if (form.Show(SystemIcons.Warning,
|
||||
"WARNING: " + Program.ApplicationExecutable + " was renamed!" +
|
||||
"\n\nThis will cause undesirable behavior when updating the program!",
|
||||
"Ignore", "Abort") == DialogResult.Cancel)
|
||||
"WARNING: " + Program.ApplicationExecutable + " was renamed!" + "\n\nThis will cause undesirable behavior when updating the program!",
|
||||
"Ignore", "Abort") == DialogResult.Cancel)
|
||||
{
|
||||
Application.Exit();
|
||||
return;
|
||||
|
@ -174,7 +165,8 @@ internal partial class MainForm : CustomForm
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e.HandleException(this)) goto retry;
|
||||
if (e.HandleException(this))
|
||||
goto retry;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
@ -188,8 +180,7 @@ internal partial class MainForm : CustomForm
|
|||
updateButton.Text = "Cancel";
|
||||
updateButton.Click -= OnUpdate;
|
||||
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();
|
||||
Progress<double> progress = new();
|
||||
progress.ProgressChanged += delegate(object sender, double _progress)
|
||||
|
@ -198,7 +189,7 @@ internal partial class MainForm : CustomForm
|
|||
progressBar.Value = (int)_progress;
|
||||
};
|
||||
progressLabel.Text = "Updating . . . ";
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
cancellationTokenSource = new();
|
||||
try
|
||||
{
|
||||
await updateManager.PrepareUpdateAsync(latestVersion, progress, cancellationTokenSource.Token);
|
||||
|
@ -207,8 +198,7 @@ internal partial class MainForm : CustomForm
|
|||
catch (TaskCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugForm.Current.Log($"Exception while preparing update: {ex.GetType()} ({ex.Message})",
|
||||
LogTextBox.Warning);
|
||||
DebugForm.Current.Log($"Exception while preparing update: {ex.GetType()} ({ex.Message})", LogTextBox.Warning);
|
||||
}
|
||||
#else
|
||||
catch { }
|
||||
|
|
|
@ -12,10 +12,11 @@ internal partial class SelectDialogForm : CustomForm
|
|||
private readonly List<(Platform platform, string id, string name)> selected = new();
|
||||
internal SelectDialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
|
||||
|
||||
internal List<(Platform platform, string id, string name)> QueryUser(
|
||||
string groupBoxText, List<(Platform platform, string id, string name, bool alreadySelected)> choices)
|
||||
internal List<(Platform platform, string id, string name)> QueryUser(string groupBoxText,
|
||||
List<(Platform platform, string id, string name, bool alreadySelected)> choices)
|
||||
{
|
||||
if (!choices.Any()) return null;
|
||||
if (!choices.Any())
|
||||
return null;
|
||||
groupBox.Text = groupBoxText;
|
||||
allCheckBox.Enabled = false;
|
||||
acceptButton.Enabled = false;
|
||||
|
@ -26,7 +27,8 @@ internal partial class SelectDialogForm : CustomForm
|
|||
OnTreeNodeChecked(node);
|
||||
_ = selectionTreeView.Nodes.Add(node);
|
||||
}
|
||||
if (!selected.Any()) OnLoad(null, null);
|
||||
if (!selected.Any())
|
||||
OnLoad(null, null);
|
||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||
allCheckBox.Checked = selectionTreeView.Nodes.Cast<TreeNode>().All(n => n.Checked);
|
||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||
|
@ -59,13 +61,11 @@ internal partial class SelectDialogForm : CustomForm
|
|||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||
}
|
||||
|
||||
private void OnResize(object s, EventArgs e) =>
|
||||
Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100
|
||||
? Program.ApplicationNameShort
|
||||
: Program.ApplicationName;
|
||||
private void OnResize(object s, EventArgs e)
|
||||
=> Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100 ? Program.ApplicationNameShort : Program.ApplicationName;
|
||||
|
||||
private void OnSortCheckBoxChanged(object sender, EventArgs e) => selectionTreeView.TreeViewNodeSorter
|
||||
= sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName;
|
||||
private void OnSortCheckBoxChanged(object sender, EventArgs e)
|
||||
=> selectionTreeView.TreeViewNodeSorter = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName;
|
||||
|
||||
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
@ -85,7 +85,8 @@ internal partial class SelectDialogForm : CustomForm
|
|||
private void OnLoad(object sender, EventArgs e)
|
||||
{
|
||||
List<(Platform platform, string id)> choices = ProgramData.ReadProgramChoices();
|
||||
if (choices is null) return;
|
||||
if (choices is null)
|
||||
return;
|
||||
foreach (TreeNode node in selectionTreeView.Nodes)
|
||||
{
|
||||
node.Checked = choices.Any(n => n.platform == (Platform)node.Tag && n.id == node.Name);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,48 +17,41 @@ internal static class EpicLibrary
|
|||
{
|
||||
get
|
||||
{
|
||||
epicManifestsPath
|
||||
??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Epic Games\EOS", "ModSdkMetadataDir",
|
||||
null) as string;
|
||||
epicManifestsPath
|
||||
??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Wow6432Node\Epic Games\EOS", "ModSdkMetadataDir",
|
||||
null) as string;
|
||||
epicManifestsPath
|
||||
??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher", "AppDataPath",
|
||||
null) as string;
|
||||
epicManifestsPath
|
||||
??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher",
|
||||
"AppDataPath", null) as string;
|
||||
epicManifestsPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Epic Games\EOS", "ModSdkMetadataDir", null) as string;
|
||||
epicManifestsPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Wow6432Node\Epic Games\EOS", "ModSdkMetadataDir", null) as string;
|
||||
epicManifestsPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher", "AppDataPath", null) as string;
|
||||
epicManifestsPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher", "AppDataPath", null) as string;
|
||||
if (epicManifestsPath is not null && epicManifestsPath.EndsWith(@"\Data"))
|
||||
epicManifestsPath += @"\Manifests";
|
||||
return epicManifestsPath.BeautifyPath();
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(
|
||||
string gameDirectory) =>
|
||||
await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
|
||||
internal static async Task<List<Manifest>> GetGames() => await Task.Run(() =>
|
||||
{
|
||||
List<Manifest> games = new();
|
||||
string manifests = EpicManifestsPath;
|
||||
if (!Directory.Exists(manifests)) return games;
|
||||
foreach (string file in Directory.EnumerateFiles(manifests, "*.item"))
|
||||
internal static async Task<List<Manifest>> GetGames()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
if (Program.Canceled) return games;
|
||||
string json = File.ReadAllText(file);
|
||||
try
|
||||
List<Manifest> games = new();
|
||||
string manifests = EpicManifestsPath;
|
||||
if (!Directory.Exists(manifests))
|
||||
return games;
|
||||
foreach (string file in Directory.EnumerateFiles(manifests, "*.item"))
|
||||
{
|
||||
Manifest manifest = JsonSerializer.Deserialize<Manifest>(json);
|
||||
if (manifest is not null && manifest.CatalogItemId == manifest.MainGameCatalogItemId
|
||||
&& !games.Any(g => g.CatalogItemId == manifest.CatalogItemId
|
||||
&& g.InstallLocation == manifest.InstallLocation))
|
||||
games.Add(manifest);
|
||||
if (Program.Canceled)
|
||||
return games;
|
||||
string json = File.ReadAllText(file);
|
||||
try
|
||||
{
|
||||
Manifest manifest = JsonSerializer.Deserialize<Manifest>(json);
|
||||
if (manifest is not null && manifest.CatalogItemId == manifest.MainGameCatalogItemId && !games.Any(g
|
||||
=> g.CatalogItemId == manifest.CatalogItemId && g.InstallLocation == manifest.InstallLocation))
|
||||
games.Add(manifest);
|
||||
}
|
||||
catch { }
|
||||
;
|
||||
}
|
||||
catch { }
|
||||
;
|
||||
}
|
||||
return games;
|
||||
});
|
||||
return games;
|
||||
});
|
||||
}
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using CreamInstaller.Platforms.Epic.GraphQL;
|
||||
|
@ -23,8 +22,7 @@ internal static class EpicStore
|
|||
|
||||
private const int COOLDOWN_ENTITLEMENT = 600;
|
||||
|
||||
internal static async Task<List<(string id, string name, string product, string icon, string developer)>>
|
||||
QueryEntitlements(string categoryNamespace)
|
||||
internal static async Task<List<(string id, string name, string product, string icon, string developer)>> QueryEntitlements(string categoryNamespace)
|
||||
{
|
||||
List<(string id, string name, string product, string icon, string developer)> dlcIds = new();
|
||||
string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json";
|
||||
|
@ -40,7 +38,6 @@ internal static class EpicStore
|
|||
catch { }
|
||||
}
|
||||
else if (cachedExists)
|
||||
{
|
||||
try
|
||||
{
|
||||
response = JsonConvert.DeserializeObject<Response>(await File.ReadAllTextAsync(cacheFile));
|
||||
|
@ -49,16 +46,13 @@ internal static class EpicStore
|
|||
{
|
||||
File.Delete(cacheFile);
|
||||
}
|
||||
}
|
||||
if (response is null)
|
||||
return dlcIds;
|
||||
List<Element> searchStore = new(response.Data.Catalog.SearchStore.Elements);
|
||||
foreach (Element element in searchStore)
|
||||
{
|
||||
string title = element.Title;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any()
|
||||
? element.CatalogNs.Mappings.First().PageSlug
|
||||
: null;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() ? element.CatalogNs.Mappings.First().PageSlug : null;
|
||||
string icon = null;
|
||||
for (int i = 0; i < element.KeyImages?.Length; i++)
|
||||
{
|
||||
|
@ -76,9 +70,7 @@ internal static class EpicStore
|
|||
foreach (Element element in catalogOffers)
|
||||
{
|
||||
string title = element.Title;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any()
|
||||
? element.CatalogNs.Mappings.First().PageSlug
|
||||
: null;
|
||||
string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() ? element.CatalogNs.Mappings.First().PageSlug : null;
|
||||
string icon = null;
|
||||
for (int i = 0; i < element.KeyImages?.Length; i++)
|
||||
{
|
||||
|
@ -95,11 +87,11 @@ internal static class EpicStore
|
|||
return dlcIds;
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (id == null) return;
|
||||
if (id == null)
|
||||
return;
|
||||
bool found = false;
|
||||
for (int i = 0; i < dlcIds.Count; i++)
|
||||
{
|
||||
|
@ -113,7 +105,8 @@ internal static class EpicStore
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!found) dlcIds.Add((id, title, product, icon, developer));
|
||||
if (!found)
|
||||
dlcIds.Add((id, title, product, icon, developer));
|
||||
}
|
||||
|
||||
private static async Task<Response> QueryGraphQL(string categoryNamespace)
|
||||
|
@ -124,11 +117,11 @@ internal static class EpicStore
|
|||
Request request = new(encoded);
|
||||
string payload = JsonConvert.SerializeObject(request);
|
||||
using HttpContent content = new StringContent(payload);
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
content.Headers.ContentType = new("application/json");
|
||||
HttpClient client = HttpClientManager.HttpClient;
|
||||
if (client is null) return null;
|
||||
HttpResponseMessage httpResponse
|
||||
= await client.PostAsync(new Uri("https://graphql.epicgames.com/graphql"), content);
|
||||
if (client is null)
|
||||
return null;
|
||||
HttpResponseMessage httpResponse = await client.PostAsync(new Uri("https://graphql.epicgames.com/graphql"), content);
|
||||
_ = httpResponse.EnsureSuccessStatusCode();
|
||||
string response = await httpResponse.Content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<Response>(response);
|
||||
|
|
|
@ -9,10 +9,11 @@ namespace CreamInstaller.Platforms.Epic.GraphQL;
|
|||
|
||||
internal class Request
|
||||
{
|
||||
internal Request(string @namespace) => Vars = new Variables(@namespace);
|
||||
internal Request(string @namespace) => Vars = new(@namespace);
|
||||
|
||||
[JsonProperty(PropertyName = "query")]
|
||||
private string Query => @"query searchOffers($namespace: String!) {
|
||||
private string Query
|
||||
=> @"query searchOffers($namespace: String!) {
|
||||
Catalog {
|
||||
searchStore(category: ""*"", namespace: $namespace){
|
||||
elements {
|
||||
|
|
|
@ -27,20 +27,16 @@ internal static class ParadoxLauncher
|
|||
{
|
||||
get
|
||||
{
|
||||
installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Paradox Interactive\Paradox Launcher v2",
|
||||
"LauncherInstallation", null) as string;
|
||||
installPath ??= Registry.GetValue(
|
||||
@"HKEY_CURRENT_USER\Software\Wow6432Node\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;
|
||||
installPath
|
||||
??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Wow6432Node\Paradox Interactive\Paradox Launcher v2", "LauncherInstallation",
|
||||
null) as string;
|
||||
return installPath.BeautifyPath();
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(
|
||||
string gameDirectory) =>
|
||||
await Task.Run(async () => await gameDirectory.GetExecutableDirectories(validFunc: path
|
||||
=> !Path.GetFileName(path)
|
||||
.Contains("bootstrapper")));
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(validFunc: path => !Path.GetFileName(path).Contains("bootstrapper")));
|
||||
|
||||
private static void PopulateDlc(ProgramSelection paradoxLauncher = null)
|
||||
{
|
||||
|
@ -49,26 +45,24 @@ internal static class ParadoxLauncher
|
|||
{
|
||||
paradoxLauncher.ExtraDlc.Clear();
|
||||
paradoxLauncher.ExtraSelectedDlc.Clear();
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllEnabled.Where(
|
||||
s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllEnabled.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
{
|
||||
paradoxLauncher.ExtraDlc.Add(
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(
|
||||
selection.Id, selection.Name, selection.AllDlc));
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(selection.Id, selection.Name,
|
||||
selection.AllDlc));
|
||||
paradoxLauncher.ExtraSelectedDlc.Add(
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(
|
||||
selection.Id, selection.Name, selection.SelectedDlc));
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(selection.Id, selection.Name,
|
||||
selection.SelectedDlc));
|
||||
}
|
||||
if (!paradoxLauncher.ExtraDlc.Any())
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe.Where(
|
||||
s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive"))
|
||||
{
|
||||
paradoxLauncher.ExtraDlc.Add(
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(
|
||||
selection.Id, selection.Name, selection.AllDlc));
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(selection.Id, selection.Name,
|
||||
selection.AllDlc));
|
||||
paradoxLauncher.ExtraSelectedDlc.Add(
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(
|
||||
selection.Id, selection.Name, selection.AllDlc));
|
||||
new ValueTuple<string, string, SortedList<string, (DlcType type, string name, string icon)>>(selection.Id, selection.Name,
|
||||
selection.AllDlc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,10 +77,9 @@ internal static class ParadoxLauncher
|
|||
{
|
||||
using DialogForm dialogForm = new(form);
|
||||
return dialogForm.Show(SystemIcons.Warning,
|
||||
"WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!"
|
||||
+
|
||||
"\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!",
|
||||
"Ignore", "Cancel", "Paradox Launcher") != DialogResult.OK;
|
||||
"WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!"
|
||||
+ "\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!", "Ignore", "Cancel",
|
||||
"Paradox Launcher") != DialogResult.OK;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -96,9 +89,7 @@ internal static class ParadoxLauncher
|
|||
{
|
||||
InstallForm installForm = form as InstallForm;
|
||||
if (!Program.IsProgramRunningDialog(form, selection))
|
||||
return form is InstallForm
|
||||
? throw new CustomMessageException("Repair failed! The launcher is currently running!")
|
||||
: RepairResult.ProgramRunning;
|
||||
return form is InstallForm ? throw new CustomMessageException("Repair failed! The launcher is currently running!") : RepairResult.ProgramRunning;
|
||||
bool smokeInstalled = false;
|
||||
byte[] steamOriginalSdk32 = null;
|
||||
byte[] steamOriginalSdk64 = null;
|
||||
|
@ -107,40 +98,29 @@ internal static class ParadoxLauncher
|
|||
byte[] epicOriginalSdk64 = null;
|
||||
foreach (string directory in selection.DllDirectories)
|
||||
{
|
||||
bool koaloaderInstalled = Koaloader.AutoLoadDlls
|
||||
.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||
bool koaloaderInstalled = Koaloader.AutoLoadDlls.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||
.Any(pair => File.Exists(pair.path) && pair.path.IsResourceFile());
|
||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
out string config, out _);
|
||||
smokeInstalled = smokeInstalled
|
||||
|| File.Exists(api32_o) || File.Exists(api64_o)
|
||||
|| (File.Exists(config) && !koaloaderInstalled)
|
||||
|| (File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
||||
|| (File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.Steamworks64));
|
||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out _);
|
||||
smokeInstalled = smokeInstalled || File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled
|
||||
|| File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.Steamworks32)
|
||||
|| File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.Steamworks64);
|
||||
await SmokeAPI.Uninstall(directory, deleteConfig: false);
|
||||
if (steamOriginalSdk32 is null && File.Exists(api32)
|
||||
&& !api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
||||
if (steamOriginalSdk32 is null && File.Exists(api32) && !api32.IsResourceFile(ResourceIdentifier.Steamworks32))
|
||||
steamOriginalSdk32 = await File.ReadAllBytesAsync(api32);
|
||||
if (steamOriginalSdk64 is null && File.Exists(api64)
|
||||
&& !api64.IsResourceFile(ResourceIdentifier.Steamworks64))
|
||||
if (steamOriginalSdk64 is null && File.Exists(api64) && !api64.IsResourceFile(ResourceIdentifier.Steamworks64))
|
||||
steamOriginalSdk64 = await File.ReadAllBytesAsync(api64);
|
||||
directory.GetScreamApiComponents(out api32, out api32_o, out api64, out api64_o, out config);
|
||||
screamInstalled = screamInstalled
|
||||
|| File.Exists(api32_o) || File.Exists(api64_o)
|
||||
|| (File.Exists(config) && !koaloaderInstalled)
|
||||
|| (File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32))
|
||||
|| (File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64));
|
||||
screamInstalled = screamInstalled || File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled
|
||||
|| File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)
|
||||
|| File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64);
|
||||
await ScreamAPI.Uninstall(directory, deleteConfig: false);
|
||||
if (epicOriginalSdk32 is null && File.Exists(api32)
|
||||
&& !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32))
|
||||
if (epicOriginalSdk32 is null && File.Exists(api32) && !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32))
|
||||
epicOriginalSdk32 = await File.ReadAllBytesAsync(api32);
|
||||
if (epicOriginalSdk64 is null && File.Exists(api64)
|
||||
&& !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64))
|
||||
if (epicOriginalSdk64 is null && File.Exists(api64) && !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64))
|
||||
epicOriginalSdk64 = await File.ReadAllBytesAsync(api64);
|
||||
}
|
||||
using DialogForm dialogForm = new(form);
|
||||
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;
|
||||
foreach (string directory in selection.DllDirectories)
|
||||
|
@ -181,26 +161,22 @@ internal static class ParadoxLauncher
|
|||
if (installForm is not null)
|
||||
installForm.UpdateUser("Paradox Launcher successfully repaired!", LogTextBox.Success);
|
||||
else
|
||||
_ = dialogForm.Show(form.Icon, "Paradox Launcher successfully repaired!", "OK",
|
||||
customFormText: "Paradox Launcher");
|
||||
_ = dialogForm.Show(form.Icon, "Paradox Launcher successfully repaired!", "OK", customFormText: "Paradox Launcher");
|
||||
return RepairResult.Success;
|
||||
}
|
||||
if (installForm is not null)
|
||||
installForm.UpdateUser("Paradox Launcher did not need to be repaired.", LogTextBox.Success);
|
||||
else
|
||||
_ = dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", "OK",
|
||||
customFormText: "Paradox Launcher");
|
||||
_ = dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", "OK", customFormText: "Paradox Launcher");
|
||||
return RepairResult.Unnecessary;
|
||||
}
|
||||
_ = form is InstallForm
|
||||
? throw new CustomMessageException("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, "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.",
|
||||
"OK", customFormText: "Paradox Launcher");
|
||||
? throw new CustomMessageException("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,
|
||||
"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.", "OK",
|
||||
customFormText: "Paradox Launcher");
|
||||
return RepairResult.Failure;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@ internal static class SteamCMD
|
|||
|
||||
internal 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];
|
||||
|
||||
|
@ -38,84 +37,86 @@ internal static class SteamCMD
|
|||
internal static string DirectoryPath => ProgramData.DirectoryPath;
|
||||
internal static string AppInfoPath => ProgramData.AppInfoPath;
|
||||
|
||||
private static string GetArguments(string appId) => AttemptCount.TryGetValue(appId, out int attempts)
|
||||
? $@"@ShutdownOnFailedCommand 0 +force_install_dir {DirectoryPath} +login anonymous +app_info_print {appId} "
|
||||
+ string.Concat(Enumerable.Repeat("+app_update 4 ", attempts)) + "+quit"
|
||||
: $"+login anonymous +app_info_print {appId} +quit";
|
||||
private static string GetArguments(string appId)
|
||||
=> AttemptCount.TryGetValue(appId, out int attempts)
|
||||
? $@"@ShutdownOnFailedCommand 0 +force_install_dir {DirectoryPath} +login anonymous +app_info_print {appId} "
|
||||
+ string.Concat(Enumerable.Repeat("+app_update 4 ", attempts)) + "+quit"
|
||||
: $"+login anonymous +app_info_print {appId} +quit";
|
||||
|
||||
internal static async Task<string> Run(string appId) => await Task.Run(() =>
|
||||
{
|
||||
wait_for_lock:
|
||||
if (Program.Canceled) return "";
|
||||
for (int i = 0; i < locks.Length; i++)
|
||||
internal static async Task<string> Run(string appId)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
if (Program.Canceled) return "";
|
||||
if (Interlocked.CompareExchange(ref locks[i], 1, 0) == 0)
|
||||
wait_for_lock:
|
||||
if (Program.Canceled)
|
||||
return "";
|
||||
for (int i = 0; i < locks.Length; i++)
|
||||
{
|
||||
if (appId is not null)
|
||||
{
|
||||
AttemptCount.TryGetValue(appId, out int count);
|
||||
AttemptCount[appId] = ++count;
|
||||
}
|
||||
if (Program.Canceled) return "";
|
||||
ProcessStartInfo processStartInfo = new()
|
||||
{
|
||||
FileName = FilePath, RedirectStandardOutput = true, RedirectStandardInput = true,
|
||||
RedirectStandardError = true, 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);
|
||||
StringBuilder output = new();
|
||||
StringBuilder appInfo = new();
|
||||
bool appInfoStarted = false;
|
||||
DateTime lastOutput = DateTime.UtcNow;
|
||||
while (true)
|
||||
if (Program.Canceled)
|
||||
return "";
|
||||
if (Interlocked.CompareExchange(ref locks[i], 1, 0) == 0)
|
||||
{
|
||||
if (appId is not null)
|
||||
{
|
||||
AttemptCount.TryGetValue(appId, out int count);
|
||||
AttemptCount[appId] = ++count;
|
||||
}
|
||||
if (Program.Canceled)
|
||||
return "";
|
||||
ProcessStartInfo processStartInfo = new()
|
||||
{
|
||||
process.Kill(true);
|
||||
process.Close();
|
||||
break;
|
||||
}
|
||||
int c = process.StandardOutput.Read();
|
||||
if (c != -1)
|
||||
FileName = FilePath, RedirectStandardOutput = true, RedirectStandardInput = true, RedirectStandardError = true,
|
||||
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);
|
||||
StringBuilder output = new();
|
||||
StringBuilder appInfo = new();
|
||||
bool appInfoStarted = false;
|
||||
DateTime lastOutput = DateTime.UtcNow;
|
||||
while (true)
|
||||
{
|
||||
lastOutput = DateTime.UtcNow;
|
||||
char ch = (char)c;
|
||||
if (ch == '{') appInfoStarted = true;
|
||||
_ = appInfoStarted ? appInfo.Append(ch) : output.Append(ch);
|
||||
}
|
||||
DateTime now = DateTime.UtcNow;
|
||||
TimeSpan timeDiff = now - lastOutput;
|
||||
if (timeDiff.TotalSeconds > 0.1)
|
||||
{
|
||||
process.Kill(true);
|
||||
process.Close();
|
||||
if (output.ToString().Contains($"No app info for AppID {appId} found, requesting..."))
|
||||
{
|
||||
AttemptCount[appId]++;
|
||||
processStartInfo.Arguments = GetArguments(appId);
|
||||
process = Process.Start(processStartInfo);
|
||||
appInfoStarted = false;
|
||||
_ = output.Clear();
|
||||
_ = appInfo.Clear();
|
||||
}
|
||||
else
|
||||
if (Program.Canceled)
|
||||
{
|
||||
process.Kill(true);
|
||||
process.Close();
|
||||
break;
|
||||
}
|
||||
int c = process.StandardOutput.Read();
|
||||
if (c != -1)
|
||||
{
|
||||
lastOutput = DateTime.UtcNow;
|
||||
char ch = (char)c;
|
||||
if (ch == '{')
|
||||
appInfoStarted = true;
|
||||
_ = appInfoStarted ? appInfo.Append(ch) : output.Append(ch);
|
||||
}
|
||||
DateTime now = DateTime.UtcNow;
|
||||
TimeSpan timeDiff = now - lastOutput;
|
||||
if (timeDiff.TotalSeconds > 0.1)
|
||||
{
|
||||
process.Kill(true);
|
||||
process.Close();
|
||||
if (output.ToString().Contains($"No app info for AppID {appId} found, requesting..."))
|
||||
{
|
||||
AttemptCount[appId]++;
|
||||
processStartInfo.Arguments = GetArguments(appId);
|
||||
process = Process.Start(processStartInfo);
|
||||
appInfoStarted = false;
|
||||
_ = output.Clear();
|
||||
_ = appInfo.Clear();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ = Interlocked.Decrement(ref locks[i]);
|
||||
return appInfo.ToString();
|
||||
}
|
||||
_ = Interlocked.Decrement(ref locks[i]);
|
||||
return appInfo.ToString();
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
Thread.Sleep(200);
|
||||
goto wait_for_lock;
|
||||
});
|
||||
goto wait_for_lock;
|
||||
});
|
||||
|
||||
internal static async Task Setup(IProgress<int> progress)
|
||||
{
|
||||
|
@ -123,21 +124,20 @@ internal static class SteamCMD
|
|||
if (!File.Exists(FilePath))
|
||||
{
|
||||
HttpClient httpClient = HttpClientManager.HttpClient;
|
||||
if (httpClient is null) return;
|
||||
byte[] file = await httpClient.GetByteArrayAsync(
|
||||
new Uri("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"));
|
||||
if (httpClient is null)
|
||||
return;
|
||||
byte[] file = await httpClient.GetByteArrayAsync(new Uri("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"));
|
||||
file.Write(ArchivePath);
|
||||
ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath);
|
||||
File.Delete(ArchivePath);
|
||||
}
|
||||
if (!File.Exists(DllPath))
|
||||
{
|
||||
FileSystemWatcher watcher = new(DirectoryPath)
|
||||
{
|
||||
Filter = "*", IncludeSubdirectories = true, EnableRaisingEvents = true
|
||||
};
|
||||
if (File.Exists(DllPath)) progress.Report(-15); // update (not used at the moment)
|
||||
else progress.Report(-1660); // install
|
||||
FileSystemWatcher watcher = new(DirectoryPath) { Filter = "*", IncludeSubdirectories = true, EnableRaisingEvents = true };
|
||||
if (File.Exists(DllPath))
|
||||
progress.Report(-15); // update (not used at the moment)
|
||||
else
|
||||
progress.Report(-1660); // install
|
||||
int cur = 0;
|
||||
progress.Report(cur);
|
||||
watcher.Changed += (sender, e) => progress.Report(++cur);
|
||||
|
@ -146,45 +146,47 @@ internal static class SteamCMD
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task Cleanup() => await Task.Run(async () =>
|
||||
{
|
||||
if (!Directory.Exists(DirectoryPath)) return;
|
||||
await Kill();
|
||||
try
|
||||
internal static async Task Cleanup()
|
||||
=> await Task.Run(async () =>
|
||||
{
|
||||
if (Directory.Exists(ConfigPath))
|
||||
foreach (string file in Directory.EnumerateFiles(ConfigPath, "*.tmp"))
|
||||
if (!Directory.Exists(DirectoryPath))
|
||||
return;
|
||||
await Kill();
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(ConfigPath))
|
||||
foreach (string file in Directory.EnumerateFiles(ConfigPath, "*.tmp"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.old"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.old"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.delete"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.crash"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.ntfs_transaction_failed"))
|
||||
File.Delete(file);
|
||||
if (Directory.Exists(AppCachePath))
|
||||
Directory.Delete(AppCachePath,
|
||||
true); // this is definitely needed, so SteamCMD gets the latest information for us
|
||||
if (Directory.Exists(DumpsPath))
|
||||
Directory.Delete(DumpsPath, true);
|
||||
if (Directory.Exists(LogsPath))
|
||||
Directory.Delete(LogsPath, true);
|
||||
if (Directory.Exists(SteamAppsPath))
|
||||
Directory.Delete(SteamAppsPath, true); // this is just a useless folder created from +app_update 4
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.delete"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.crash"))
|
||||
File.Delete(file);
|
||||
foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.ntfs_transaction_failed"))
|
||||
File.Delete(file);
|
||||
if (Directory.Exists(AppCachePath))
|
||||
Directory.Delete(AppCachePath, true); // this is definitely needed, so SteamCMD gets the latest information for us
|
||||
if (Directory.Exists(DumpsPath))
|
||||
Directory.Delete(DumpsPath, true);
|
||||
if (Directory.Exists(LogsPath))
|
||||
Directory.Delete(LogsPath, true);
|
||||
if (Directory.Exists(SteamAppsPath))
|
||||
Directory.Delete(SteamAppsPath, true); // this is just a useless folder created from +app_update 4
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
internal static async Task<VProperty> GetAppInfo(string appId, string branch = "public", int buildId = 0)
|
||||
{
|
||||
if (Program.Canceled) return null;
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
string output;
|
||||
string appUpdateFile = $@"{AppInfoPath}\{appId}.vdf";
|
||||
restart:
|
||||
if (Program.Canceled) return null;
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
if (File.Exists(appUpdateFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
output = await File.ReadAllTextAsync(appUpdateFile, Encoding.UTF8);
|
||||
|
@ -193,7 +195,6 @@ internal static class SteamCMD
|
|||
{
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = await Run(appId) ?? "";
|
||||
|
@ -213,74 +214,75 @@ internal static class SteamCMD
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
if (Program.Canceled) return null;
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
if (!ValveDataFile.TryDeserialize(output, out VProperty appInfo) || appInfo.Value is VValue)
|
||||
{
|
||||
File.Delete(appUpdateFile);
|
||||
goto restart;
|
||||
}
|
||||
if (appInfo is null || appInfo.Value?.Children()?.ToList()?.Count == 0) return appInfo;
|
||||
if (appInfo is null || appInfo.Value?.Children()?.ToList()?.Count == 0)
|
||||
return appInfo;
|
||||
VToken type = appInfo.Value?.GetChild("common")?.GetChild("type");
|
||||
if (type is not null && type.ToString() != "Game")
|
||||
return appInfo;
|
||||
string buildid = appInfo.Value?.GetChild("depots")?.GetChild("branches")?.GetChild(branch)
|
||||
?.GetChild("buildid")?.ToString();
|
||||
if (buildid is null && type is not null) return appInfo;
|
||||
string buildid = appInfo.Value?.GetChild("depots")?.GetChild("branches")?.GetChild(branch)?.GetChild("buildid")?.ToString();
|
||||
if (buildid is null && type is not null)
|
||||
return appInfo;
|
||||
if (type is not null && (!int.TryParse(buildid, out int gamebuildId) || gamebuildId >= buildId))
|
||||
return appInfo;
|
||||
List<string> dlcAppIds = await ParseDlcAppIds(appInfo);
|
||||
foreach (string dlcAppUpdateFile in dlcAppIds.Select(id => $@"{AppInfoPath}\{id}.vdf"))
|
||||
if (File.Exists(dlcAppUpdateFile))
|
||||
File.Delete(dlcAppUpdateFile);
|
||||
if (File.Exists(appUpdateFile)) File.Delete(appUpdateFile);
|
||||
if (File.Exists(appUpdateFile))
|
||||
File.Delete(appUpdateFile);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
internal static async Task<List<string>> ParseDlcAppIds(VProperty appInfo) => await Task.Run(() =>
|
||||
{
|
||||
List<string> dlcIds = new();
|
||||
if (Program.Canceled || appInfo is null) return dlcIds;
|
||||
VToken extended = appInfo.Value.GetChild("extended");
|
||||
if (extended is not null)
|
||||
foreach (VToken vToken in extended.Where(p => p is VProperty { Key: "listofdlc" }))
|
||||
internal static async Task<List<string>> ParseDlcAppIds(VProperty appInfo)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<string> dlcIds = new();
|
||||
if (Program.Canceled || appInfo is null)
|
||||
return dlcIds;
|
||||
VToken extended = appInfo.Value.GetChild("extended");
|
||||
if (extended is not null)
|
||||
foreach (VToken vToken in extended.Where(p => p is VProperty { Key: "listofdlc" }))
|
||||
{
|
||||
VProperty property = (VProperty)vToken;
|
||||
foreach (string id in property.Value.ToString().Split(","))
|
||||
if (int.TryParse(id, out int appId) && appId > 0 && !dlcIds.Contains("" + appId))
|
||||
dlcIds.Add("" + appId);
|
||||
}
|
||||
VToken depots = appInfo.Value.GetChild("depots");
|
||||
if (depots is null)
|
||||
return dlcIds;
|
||||
foreach (VToken vToken in depots.Where(p => p is VProperty property && int.TryParse(property.Key, out int _)))
|
||||
{
|
||||
VProperty property = (VProperty)vToken;
|
||||
foreach (string id in property.Value.ToString().Split(","))
|
||||
if (int.TryParse(id, out int appId) && appId > 0 && !dlcIds.Contains("" + appId))
|
||||
dlcIds.Add("" + appId);
|
||||
if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0 && !dlcIds.Contains("" + appId))
|
||||
dlcIds.Add("" + appId);
|
||||
}
|
||||
VToken depots = appInfo.Value.GetChild("depots");
|
||||
if (depots is null)
|
||||
return dlcIds;
|
||||
foreach (VToken vToken in depots.Where(p => p is VProperty property && int.TryParse(property.Key, out int _)))
|
||||
{
|
||||
VProperty property = (VProperty)vToken;
|
||||
if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0
|
||||
&& !dlcIds.Contains("" + appId))
|
||||
dlcIds.Add("" + appId);
|
||||
}
|
||||
return dlcIds;
|
||||
});
|
||||
});
|
||||
|
||||
private static async Task Kill()
|
||||
{
|
||||
List<Task> tasks = Process.GetProcessesByName("steamcmd")
|
||||
.Select(process => Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill(true);
|
||||
process.WaitForExit();
|
||||
process.Close();
|
||||
}
|
||||
catch { }
|
||||
}))
|
||||
.ToList();
|
||||
foreach (Task task in tasks) await task;
|
||||
List<Task> tasks = Process.GetProcessesByName("steamcmd").Select(process => Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill(true);
|
||||
process.WaitForExit();
|
||||
process.Close();
|
||||
}
|
||||
catch { }
|
||||
})).ToList();
|
||||
foreach (Task task in tasks)
|
||||
await task;
|
||||
}
|
||||
|
||||
internal static void Dispose()
|
||||
|
|
|
@ -18,93 +18,96 @@ internal static class SteamLibrary
|
|||
{
|
||||
get
|
||||
{
|
||||
installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath",
|
||||
null) as string;
|
||||
installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Valve\Steam", "InstallPath",
|
||||
null) as string;
|
||||
installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", null) as string;
|
||||
installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Valve\Steam", "InstallPath", null) as string;
|
||||
return installPath.BeautifyPath();
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(
|
||||
string gameDirectory) =>
|
||||
await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
|
||||
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>>
|
||||
GetGames() => await Task.Run(async () =>
|
||||
{
|
||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||
List<string> gameLibraryDirectories = await GetLibraryDirectories();
|
||||
foreach (string libraryDirectory in gameLibraryDirectories)
|
||||
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>> GetGames()
|
||||
=> await Task.Run(async () =>
|
||||
{
|
||||
if (Program.Canceled) return games;
|
||||
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in
|
||||
(await GetGamesFromLibraryDirectory(libraryDirectory))
|
||||
.Where(game => !games.Any(_game => _game.appId == game.appId
|
||||
&& _game.gameDirectory == game.gameDirectory)))
|
||||
games.Add(game);
|
||||
}
|
||||
return games;
|
||||
});
|
||||
|
||||
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>>
|
||||
GetGamesFromLibraryDirectory(string libraryDirectory) => await Task.Run(() =>
|
||||
{
|
||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||
if (Program.Canceled || !Directory.Exists(libraryDirectory)) return games;
|
||||
foreach (string file in Directory.EnumerateFiles(libraryDirectory, "*.acf"))
|
||||
{
|
||||
if (Program.Canceled) return games;
|
||||
if (ValveDataFile.TryDeserialize(File.ReadAllText(file, Encoding.UTF8), out VProperty result))
|
||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||
List<string> gameLibraryDirectories = await GetLibraryDirectories();
|
||||
foreach (string libraryDirectory in gameLibraryDirectories)
|
||||
{
|
||||
string appId = result.Value.GetChild("appid")?.ToString();
|
||||
string installdir = result.Value.GetChild("installdir")?.ToString();
|
||||
string name = result.Value.GetChild("name")?.ToString();
|
||||
string buildId = result.Value.GetChild("buildid")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(appId)
|
||||
|| string.IsNullOrWhiteSpace(installdir)
|
||||
|| string.IsNullOrWhiteSpace(name)
|
||||
|| string.IsNullOrWhiteSpace(buildId))
|
||||
continue;
|
||||
string gameDirectory = (libraryDirectory + @"\common\" + installdir).BeautifyPath();
|
||||
if (games.Any(g => g.appId == appId && g.gameDirectory == gameDirectory)) continue;
|
||||
if (!int.TryParse(appId, out int appIdInt)) continue;
|
||||
if (!int.TryParse(buildId, out int buildIdInt)) continue;
|
||||
string branch = result.Value.GetChild("UserConfig")?.GetChild("betakey")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(branch)) branch = "public";
|
||||
games.Add((appId, name, branch, buildIdInt, gameDirectory));
|
||||
if (Program.Canceled)
|
||||
return games;
|
||||
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in
|
||||
(await GetGamesFromLibraryDirectory(libraryDirectory)).Where(game
|
||||
=> !games.Any(_game => _game.appId == game.appId && _game.gameDirectory == game.gameDirectory)))
|
||||
games.Add(game);
|
||||
}
|
||||
}
|
||||
return games;
|
||||
});
|
||||
return games;
|
||||
});
|
||||
|
||||
internal static async Task<List<string>> GetLibraryDirectories() => await Task.Run(() =>
|
||||
{
|
||||
List<string> gameDirectories = new();
|
||||
if (Program.Canceled) return gameDirectories;
|
||||
string steamInstallPath = InstallPath;
|
||||
if (steamInstallPath != null && Directory.Exists(steamInstallPath))
|
||||
internal static async Task<List<(string appId, string name, string branch, int buildId, string gameDirectory)>>
|
||||
GetGamesFromLibraryDirectory(string libraryDirectory)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
string libraryFolder = steamInstallPath + @"\steamapps";
|
||||
if (Directory.Exists(libraryFolder))
|
||||
List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new();
|
||||
if (Program.Canceled || !Directory.Exists(libraryDirectory))
|
||||
return games;
|
||||
foreach (string file in Directory.EnumerateFiles(libraryDirectory, "*.acf"))
|
||||
{
|
||||
gameDirectories.Add(libraryFolder);
|
||||
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
|
||||
if (File.Exists(libraryFolders)
|
||||
&& ValveDataFile.TryDeserialize(File.ReadAllText(libraryFolders, Encoding.UTF8), out VProperty result))
|
||||
if (Program.Canceled)
|
||||
return games;
|
||||
if (ValveDataFile.TryDeserialize(File.ReadAllText(file, Encoding.UTF8), out VProperty result))
|
||||
{
|
||||
string appId = result.Value.GetChild("appid")?.ToString();
|
||||
string installdir = result.Value.GetChild("installdir")?.ToString();
|
||||
string name = result.Value.GetChild("name")?.ToString();
|
||||
string buildId = result.Value.GetChild("buildid")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(appId) || string.IsNullOrWhiteSpace(installdir) || string.IsNullOrWhiteSpace(name)
|
||||
|| string.IsNullOrWhiteSpace(buildId))
|
||||
continue;
|
||||
string gameDirectory = (libraryDirectory + @"\common\" + installdir).BeautifyPath();
|
||||
if (games.Any(g => g.appId == appId && g.gameDirectory == gameDirectory))
|
||||
continue;
|
||||
if (!int.TryParse(appId, out int appIdInt))
|
||||
continue;
|
||||
if (!int.TryParse(buildId, out int buildIdInt))
|
||||
continue;
|
||||
string branch = result.Value.GetChild("UserConfig")?.GetChild("betakey")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(branch))
|
||||
branch = "public";
|
||||
games.Add((appId, name, branch, buildIdInt, gameDirectory));
|
||||
}
|
||||
}
|
||||
return games;
|
||||
});
|
||||
|
||||
internal static async Task<List<string>> GetLibraryDirectories()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<string> gameDirectories = new();
|
||||
if (Program.Canceled)
|
||||
return gameDirectories;
|
||||
string steamInstallPath = InstallPath;
|
||||
if (steamInstallPath != null && Directory.Exists(steamInstallPath))
|
||||
{
|
||||
string libraryFolder = steamInstallPath + @"\steamapps";
|
||||
if (Directory.Exists(libraryFolder))
|
||||
{
|
||||
gameDirectories.Add(libraryFolder);
|
||||
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
|
||||
if (File.Exists(libraryFolders) && ValveDataFile.TryDeserialize(File.ReadAllText(libraryFolders, Encoding.UTF8), out VProperty result))
|
||||
#pragma warning disable IDE0220 // Add explicit cast
|
||||
foreach (VProperty property in result.Value.Where(
|
||||
p => p is VProperty && int.TryParse((p as VProperty).Key, out int _)))
|
||||
{
|
||||
string path = property.Value.GetChild("path")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(path)) continue;
|
||||
path += @"\steamapps";
|
||||
if (Directory.Exists(path) && !gameDirectories.Contains(path))
|
||||
gameDirectories.Add(path);
|
||||
}
|
||||
foreach (VProperty property in result.Value.Where(p => p is VProperty && int.TryParse((p as VProperty).Key, out int _)))
|
||||
{
|
||||
string path = property.Value.GetChild("path")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
continue;
|
||||
path += @"\steamapps";
|
||||
if (Directory.Exists(path) && !gameDirectories.Contains(path))
|
||||
gameDirectories.Add(path);
|
||||
}
|
||||
#pragma warning restore IDE0220 // Add explicit cast
|
||||
}
|
||||
}
|
||||
}
|
||||
return gameDirectories;
|
||||
});
|
||||
return gameDirectories;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,23 +18,25 @@ internal static class SteamStore
|
|||
private const int COOLDOWN_GAME = 600;
|
||||
private const int COOLDOWN_DLC = 1200;
|
||||
|
||||
internal static async Task<List<string>> ParseDlcAppIds(AppData appData) => await Task.Run(() =>
|
||||
{
|
||||
List<string> dlcIds = new();
|
||||
if (appData.dlc is null) return dlcIds;
|
||||
dlcIds.AddRange(from appId in appData.dlc where appId > 0 select appId.ToString());
|
||||
return dlcIds;
|
||||
});
|
||||
internal static async Task<List<string>> ParseDlcAppIds(AppData appData)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<string> dlcIds = new();
|
||||
if (appData.dlc is null)
|
||||
return dlcIds;
|
||||
dlcIds.AddRange(from appId in appData.dlc where appId > 0 select appId.ToString());
|
||||
return dlcIds;
|
||||
});
|
||||
|
||||
internal static async Task<AppData> QueryStoreAPI(string appId, bool isDlc = false, int attempts = 0)
|
||||
{
|
||||
if (Program.Canceled) return null;
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
string cacheFile = ProgramData.AppInfoPath + @$"\{appId}.json";
|
||||
bool cachedExists = File.Exists(cacheFile);
|
||||
if (!cachedExists || ProgramData.CheckCooldown(appId, isDlc ? COOLDOWN_DLC : COOLDOWN_GAME))
|
||||
{
|
||||
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)
|
||||
{
|
||||
IDictionary<string, JToken> apps = (IDictionary<string, JToken>)JsonConvert.DeserializeObject(response);
|
||||
|
@ -60,8 +62,7 @@ internal static class SteamStore
|
|||
{
|
||||
try
|
||||
{
|
||||
await File.WriteAllTextAsync(
|
||||
cacheFile, JsonConvert.SerializeObject(data, Formatting.Indented));
|
||||
await File.WriteAllTextAsync(cacheFile, JsonConvert.SerializeObject(data, Formatting.Indented));
|
||||
}
|
||||
catch
|
||||
#if DEBUG
|
||||
|
@ -76,16 +77,13 @@ internal static class SteamStore
|
|||
return data;
|
||||
}
|
||||
#if DEBUG
|
||||
DebugForm.Current.Log(
|
||||
$"Response data null for appid {appId}{(isDlc ? " (DLC)" : "")}: {app.Value.ToString(Formatting.None)}");
|
||||
DebugForm.Current.Log($"Response data null for appid {appId}{(isDlc ? " (DLC)" : "")}: {app.Value.ToString(Formatting.None)}");
|
||||
#endif
|
||||
}
|
||||
#if DEBUG
|
||||
else
|
||||
{
|
||||
DebugForm.Current.Log(
|
||||
$"Response details null for appid {appId}{(isDlc ? " (DLC)" : "")}: {app.Value.ToString(Formatting.None)}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
|
@ -99,7 +97,8 @@ internal static class SteamStore
|
|||
{ }
|
||||
#endif
|
||||
#if DEBUG
|
||||
else DebugForm.Current.Log("Response deserialization null for appid " + appId);
|
||||
else
|
||||
DebugForm.Current.Log("Response deserialization null for appid " + appId);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
|
@ -22,16 +22,16 @@ internal static class UbisoftLibrary
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(
|
||||
string gameDirectory) =>
|
||||
await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(string gameDirectory)
|
||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||
|
||||
internal static async Task<List<(string gameId, string name, string gameDirectory)>> GetGames() => await Task.Run(
|
||||
() =>
|
||||
internal static async Task<List<(string gameId, string name, string gameDirectory)>> GetGames()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<(string gameId, string name, string gameDirectory)> games = new();
|
||||
RegistryKey installsKey = InstallsKey;
|
||||
if (installsKey is null) return games;
|
||||
if (installsKey is null)
|
||||
return games;
|
||||
foreach (string gameId in installsKey.GetSubKeyNames())
|
||||
{
|
||||
RegistryKey installKey = installsKey.OpenSubKey(gameId);
|
||||
|
|
|
@ -42,8 +42,10 @@ internal static class Program
|
|||
|
||||
internal static bool IsGameBlocked(string name, string directory = null)
|
||||
{
|
||||
if (!BlockProtectedGames) return false;
|
||||
if (ProtectedGames.Contains(name)) return true;
|
||||
if (!BlockProtectedGames)
|
||||
return false;
|
||||
if (ProtectedGames.Contains(name))
|
||||
return true;
|
||||
if (directory is not null && !ProtectedGameDirectoryExceptions.Contains(name))
|
||||
foreach (string path in ProtectedGameDirectories)
|
||||
if (Directory.Exists(directory + path))
|
||||
|
@ -56,16 +58,12 @@ internal static class Program
|
|||
if (selection.AreDllsLocked)
|
||||
{
|
||||
using DialogForm dialogForm = new(form);
|
||||
if (dialogForm.Show(SystemIcons.Error,
|
||||
$"ERROR: {selection.Name} is currently running!" +
|
||||
"\n\nPlease close the program/game to continue . . . ",
|
||||
"Retry", "Cancel") == DialogResult.OK)
|
||||
if (dialogForm.Show(SystemIcons.Error, $"ERROR: {selection.Name} is currently running!" + "\n\nPlease close the program/game to continue . . . ",
|
||||
"Retry", "Cancel") == DialogResult.OK)
|
||||
return IsProgramRunningDialog(form, selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -81,8 +79,7 @@ internal static class Program
|
|||
Application.ApplicationExit += OnApplicationExit;
|
||||
Application.ThreadException += (s, e) => e.Exception?.HandleFatalException();
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||
AppDomain.CurrentDomain.UnhandledException += (s, e)
|
||||
=> (e.ExceptionObject as Exception)?.HandleFatalException();
|
||||
AppDomain.CurrentDomain.UnhandledException += (s, e) => (e.ExceptionObject as Exception)?.HandleFatalException();
|
||||
retry:
|
||||
try
|
||||
{
|
||||
|
@ -95,7 +92,8 @@ internal static class Program
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e.HandleException()) goto retry;
|
||||
if (e.HandleException())
|
||||
goto retry;
|
||||
Application.Exit();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,17 +25,14 @@ internal class ProgramSelection
|
|||
|
||||
internal static readonly List<ProgramSelection> All = new();
|
||||
|
||||
internal readonly SortedList<string, (DlcType type, string name, string icon)> AllDlc
|
||||
= new(PlatformIdComparer.String);
|
||||
internal readonly SortedList<string, (DlcType type, string name, string icon)> AllDlc = new(PlatformIdComparer.String);
|
||||
|
||||
internal readonly List<(string id, string name, SortedList<string, (DlcType type, string name, string icon)> dlc)>
|
||||
ExtraDlc = new(); // for Paradox Launcher
|
||||
internal readonly List<(string id, string name, SortedList<string, (DlcType type, string name, string icon)> dlc)> ExtraDlc = new(); // for Paradox Launcher
|
||||
|
||||
internal readonly List<(string id, string name, SortedList<string, (DlcType type, string name, string icon)> dlc)>
|
||||
ExtraSelectedDlc = new(); // for Paradox Launcher
|
||||
|
||||
internal readonly SortedList<string, (DlcType type, string name, string icon)> SelectedDlc
|
||||
= new(PlatformIdComparer.String);
|
||||
internal readonly SortedList<string, (DlcType type, string name, string icon)> SelectedDlc = new(PlatformIdComparer.String);
|
||||
|
||||
internal List<string> DllDirectories;
|
||||
internal bool Enabled;
|
||||
|
@ -67,54 +64,31 @@ internal class ProgramSelection
|
|||
{
|
||||
if (Platform is Platform.Steam or Platform.Paradox)
|
||||
{
|
||||
directory.GetCreamApiComponents(out string api32, out string api32_o, out string api64,
|
||||
out string api64_o, out string config);
|
||||
if (api32.IsFilePathLocked()
|
||||
|| api32_o.IsFilePathLocked()
|
||||
|| api64.IsFilePathLocked()
|
||||
|| api64_o.IsFilePathLocked()
|
||||
directory.GetCreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked()
|
||||
|| config.IsFilePathLocked())
|
||||
return true;
|
||||
directory.GetSmokeApiComponents(out api32, out api32_o, out api64, out api64_o, out config,
|
||||
out string cache);
|
||||
if (api32.IsFilePathLocked()
|
||||
|| api32_o.IsFilePathLocked()
|
||||
|| api64.IsFilePathLocked()
|
||||
|| api64_o.IsFilePathLocked()
|
||||
|| config.IsFilePathLocked()
|
||||
|| cache.IsFilePathLocked())
|
||||
directory.GetSmokeApiComponents(out api32, out api32_o, out api64, out api64_o, out config, out string cache);
|
||||
if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked()
|
||||
|| config.IsFilePathLocked() || cache.IsFilePathLocked())
|
||||
return true;
|
||||
}
|
||||
if (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);
|
||||
if (api32.IsFilePathLocked()
|
||||
|| api32_o.IsFilePathLocked()
|
||||
|| api64.IsFilePathLocked()
|
||||
|| api64_o.IsFilePathLocked()
|
||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked()
|
||||
|| config.IsFilePathLocked())
|
||||
return true;
|
||||
}
|
||||
if (Platform is Platform.Ubisoft)
|
||||
{
|
||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64,
|
||||
out string api64_o, out string config);
|
||||
if (api32.IsFilePathLocked()
|
||||
|| api32_o.IsFilePathLocked()
|
||||
|| api64.IsFilePathLocked()
|
||||
|| api64_o.IsFilePathLocked()
|
||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked()
|
||||
|| config.IsFilePathLocked())
|
||||
return true;
|
||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o,
|
||||
out api64, out api64_o, out config);
|
||||
if (old_api32.IsFilePathLocked()
|
||||
|| old_api64.IsFilePathLocked()
|
||||
|| api32.IsFilePathLocked()
|
||||
|| api32_o.IsFilePathLocked()
|
||||
|| api64.IsFilePathLocked()
|
||||
|| api64_o.IsFilePathLocked()
|
||||
|| config.IsFilePathLocked())
|
||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config);
|
||||
if (old_api32.IsFilePathLocked() || old_api64.IsFilePathLocked() || api32.IsFilePathLocked() || api32_o.IsFilePathLocked()
|
||||
|| api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.IsFilePathLocked())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +102,10 @@ internal class ProgramSelection
|
|||
|
||||
private void Toggle(string dlcAppId, (DlcType type, string name, string icon) dlcApp, bool enabled)
|
||||
{
|
||||
if (enabled) SelectedDlc[dlcAppId] = dlcApp;
|
||||
else _ = SelectedDlc.Remove(dlcAppId);
|
||||
if (enabled)
|
||||
SelectedDlc[dlcAppId] = dlcApp;
|
||||
else
|
||||
_ = SelectedDlc.Remove(dlcAppId);
|
||||
}
|
||||
|
||||
internal void ToggleDlc(string dlcId, bool enabled)
|
||||
|
@ -160,7 +136,8 @@ internal class ProgramSelection
|
|||
return;
|
||||
}
|
||||
_ = DllDirectories.RemoveAll(directory => !Directory.Exists(directory));
|
||||
if (!DllDirectories.Any()) _ = All.Remove(this);
|
||||
if (!DllDirectories.Any())
|
||||
_ = All.Remove(this);
|
||||
}
|
||||
|
||||
internal void Validate(List<(Platform platform, string id, string name)> programsToScan)
|
||||
|
@ -178,15 +155,12 @@ internal class ProgramSelection
|
|||
internal static void ValidateAll(List<(Platform platform, string id, string name)> programsToScan)
|
||||
=> AllSafe.ForEach(selection => selection.Validate(programsToScan));
|
||||
|
||||
internal static ProgramSelection FromPlatformId(Platform platform, string gameId)
|
||||
=> AllSafe.Find(s => s.Platform == platform && s.Id == gameId);
|
||||
internal static ProgramSelection FromPlatformId(Platform platform, string gameId) => AllSafe.Find(s => s.Platform == platform && s.Id == gameId);
|
||||
|
||||
internal static (string gameId, (DlcType type, string name, string icon) app)? GetDlcFromPlatformId(
|
||||
Platform platform, string dlcId)
|
||||
internal static (string gameId, (DlcType type, string name, string icon) app)? GetDlcFromPlatformId(Platform platform, string dlcId)
|
||||
{
|
||||
foreach (ProgramSelection selection in AllSafe.Where(s => s.Platform == platform))
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in selection.AllDlc.Where(
|
||||
p => p.Key == dlcId))
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in selection.AllDlc.Where(p => p.Key == dlcId))
|
||||
return (selection.Id, pair.Value);
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -14,27 +14,22 @@ internal static class Koaloader
|
|||
{
|
||||
internal static readonly List<(string unlocker, string dll)> AutoLoadDlls = new()
|
||||
{
|
||||
("Koaloader", "Unlocker.dll"), ("Koaloader", "Unlocker32.dll"), ("Koaloader", "Unlocker64.dll"),
|
||||
("Lyptus", "Lyptus.dll"), ("Lyptus", "Lyptus32.dll"), ("Lyptus", "Lyptus64.dll"),
|
||||
("SmokeAPI", "SmokeAPI.dll"), ("SmokeAPI", "SmokeAPI32.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")
|
||||
("Koaloader", "Unlocker.dll"), ("Koaloader", "Unlocker32.dll"), ("Koaloader", "Unlocker64.dll"), ("Lyptus", "Lyptus.dll"),
|
||||
("Lyptus", "Lyptus32.dll"), ("Lyptus", "Lyptus64.dll"), ("SmokeAPI", "SmokeAPI.dll"), ("SmokeAPI", "SmokeAPI32.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 void GetKoaloaderComponents(
|
||||
this string directory,
|
||||
out List<string> proxies,
|
||||
out string config
|
||||
)
|
||||
internal static void GetKoaloaderComponents(this string directory, out List<string> proxies, out string config)
|
||||
{
|
||||
proxies = new List<string>();
|
||||
proxies = new();
|
||||
foreach (string proxy in EmbeddedResources.Select(proxy =>
|
||||
{
|
||||
proxy = proxy[(proxy.IndexOf('.') + 1)..];
|
||||
return proxy[(proxy.IndexOf('.') + 1)..];
|
||||
})) proxies.Add(directory + @"\" + proxy);
|
||||
}))
|
||||
proxies.Add(directory + @"\" + proxy);
|
||||
config = directory + @"\Koaloader.json";
|
||||
}
|
||||
|
||||
|
@ -51,8 +46,7 @@ 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)..];
|
||||
baseIdentifier = baseIdentifier[..baseIdentifier.IndexOf('.')];
|
||||
|
@ -83,13 +77,12 @@ internal static class Koaloader
|
|||
else if (File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteConfig(StreamWriter writer, SortedList<string, string> targets,
|
||||
SortedList<string, string> modules, InstallForm installForm = null)
|
||||
internal static void WriteConfig(StreamWriter writer, SortedList<string, string> targets, SortedList<string, string> modules,
|
||||
InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"logging\": false,");
|
||||
|
@ -108,9 +101,7 @@ internal static class Koaloader
|
|||
writer.WriteLine(" ]");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"targets\": []");
|
||||
}
|
||||
if (modules.Any())
|
||||
{
|
||||
writer.WriteLine(" \"modules\": [");
|
||||
|
@ -127,235 +118,216 @@ internal static class Koaloader
|
|||
writer.WriteLine(" ]");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"modules\": []");
|
||||
}
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
|
||||
internal static async Task Uninstall(string directory, string rootDirectory = null, InstallForm installForm = null,
|
||||
bool deleteConfig = true) => await Task.Run(async () =>
|
||||
{
|
||||
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
|
||||
foreach (string proxyPath in proxies.Where(
|
||||
proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||
internal static async Task Uninstall(string directory, string rootDirectory = null, InstallForm installForm = null, bool deleteConfig = true)
|
||||
=> await Task.Run(async () =>
|
||||
{
|
||||
File.Delete(proxyPath);
|
||||
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 => File.Exists(pair.path) && pair.path.IsResourceFile()))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (deleteConfig && File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
await SmokeAPI.Uninstall(directory, installForm, deleteConfig);
|
||||
await ScreamAPI.Uninstall(directory, installForm, deleteConfig);
|
||||
await UplayR1.Uninstall(directory, installForm, deleteConfig);
|
||||
await UplayR2.Uninstall(directory, installForm, deleteConfig);
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
await Uninstall(rootDirectory, null, installForm, deleteConfig);
|
||||
});
|
||||
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
|
||||
foreach (string proxyPath in proxies.Where(proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||
{
|
||||
File.Delete(proxyPath);
|
||||
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 => File.Exists(pair.path) && pair.path.IsResourceFile()))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (deleteConfig && File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
await SmokeAPI.Uninstall(directory, installForm, deleteConfig);
|
||||
await ScreamAPI.Uninstall(directory, installForm, deleteConfig);
|
||||
await UplayR1.Uninstall(directory, installForm, deleteConfig);
|
||||
await UplayR2.Uninstall(directory, installForm, deleteConfig);
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
await Uninstall(rootDirectory, null, installForm, deleteConfig);
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, BinaryType binaryType, ProgramSelection selection,
|
||||
string rootDirectory = null, InstallForm installForm = null,
|
||||
bool generateConfig = true) => await Task.Run(() =>
|
||||
{
|
||||
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
|
||||
string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy;
|
||||
string path = directory + @"\" + proxy + ".dll";
|
||||
foreach (string _path in proxies.Where(p => p != path && File.Exists(p)
|
||||
&& p.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||
internal static async Task Install(string directory, BinaryType binaryType, ProgramSelection selection, string rootDirectory = null,
|
||||
InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
File.Delete(_path);
|
||||
installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(path) && !path.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||
throw new CustomMessageException("A non-Koaloader DLL named " + proxy
|
||||
+ ".dll already exists in this directory!");
|
||||
path.WriteProxy(proxy, binaryType);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
bool bit32 = false, bit64 = false;
|
||||
foreach (string executable in Directory.EnumerateFiles(directory, "*.exe"))
|
||||
if (executable.TryGetFileBinaryType(out BinaryType binaryType))
|
||||
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
|
||||
string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy;
|
||||
string path = directory + @"\" + proxy + ".dll";
|
||||
foreach (string _path in proxies.Where(p => p != path && File.Exists(p) && p.IsResourceFile(ResourceIdentifier.Koaloader)))
|
||||
{
|
||||
if (binaryType == BinaryType.BIT32)
|
||||
bit32 = true;
|
||||
else if (binaryType == BinaryType.BIT64)
|
||||
bit64 = true;
|
||||
if (bit32 && bit64)
|
||||
break;
|
||||
File.Delete(_path);
|
||||
installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
||||
{
|
||||
if (bit32)
|
||||
{
|
||||
path = directory + @"\SmokeAPI32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
if (File.Exists(path) && !path.IsResourceFile(ResourceIdentifier.Koaloader))
|
||||
throw new CustomMessageException("A non-Koaloader DLL named " + proxy + ".dll already exists in this directory!");
|
||||
path.WriteProxy(proxy, binaryType);
|
||||
installForm?.UpdateUser($"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}", LogTextBox.Action,
|
||||
false);
|
||||
bool bit32 = false, bit64 = false;
|
||||
foreach (string executable in Directory.EnumerateFiles(directory, "*.exe"))
|
||||
if (executable.TryGetFileBinaryType(out BinaryType binaryType))
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\SmokeAPI32.dll";
|
||||
if (binaryType == BinaryType.BIT32)
|
||||
bit32 = true;
|
||||
else if (binaryType == BinaryType.BIT64)
|
||||
bit64 = true;
|
||||
if (bit32 && bit64)
|
||||
break;
|
||||
}
|
||||
"SmokeAPI.steam_api.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (bit64)
|
||||
if (selection.Platform is Platform.Steam or Platform.Paradox)
|
||||
{
|
||||
path = directory + @"\SmokeAPI64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
if (bit32)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
path = directory + @"\SmokeAPI32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\SmokeAPI32.dll";
|
||||
}
|
||||
path = rootDirectory + @"\SmokeAPI64.dll";
|
||||
"SmokeAPI.steam_api.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
"SmokeAPI.steam_api64.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (bit64)
|
||||
{
|
||||
path = directory + @"\SmokeAPI64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\SmokeAPI64.dll";
|
||||
}
|
||||
"SmokeAPI.steam_api64.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
SmokeAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
}
|
||||
SmokeAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
}
|
||||
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
||||
{
|
||||
if (bit32)
|
||||
if (selection.Platform is Platform.Epic or Platform.Paradox)
|
||||
{
|
||||
path = directory + @"\ScreamAPI32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
if (bit32)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
path = directory + @"\ScreamAPI32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
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".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
"ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (bit64)
|
||||
{
|
||||
path = directory + @"\ScreamAPI64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\ScreamAPI64.dll";
|
||||
}
|
||||
"ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
ScreamAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
}
|
||||
if (bit64)
|
||||
if (selection.Platform is Platform.Ubisoft)
|
||||
{
|
||||
path = directory + @"\ScreamAPI64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
if (bit32)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
path = directory + @"\UplayR1Unlocker32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\UplayR1Unlocker32.dll";
|
||||
}
|
||||
path = rootDirectory + @"\ScreamAPI64.dll";
|
||||
"UplayR1.uplay_r1_loader.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
"ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
ScreamAPI.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
}
|
||||
if (selection.Platform is Platform.Ubisoft)
|
||||
{
|
||||
if (bit32)
|
||||
{
|
||||
path = directory + @"\UplayR1Unlocker32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
if (bit64)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
path = directory + @"\UplayR1Unlocker64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\UplayR1Unlocker64.dll";
|
||||
}
|
||||
path = rootDirectory + @"\UplayR1Unlocker32.dll";
|
||||
"UplayR1.uplay_r1_loader64.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
"UplayR1.uplay_r1_loader.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (bit64)
|
||||
{
|
||||
path = directory + @"\UplayR1Unlocker64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
UplayR1.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
if (bit32)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
path = directory + @"\UplayR2Unlocker32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\UplayR2Unlocker32.dll";
|
||||
}
|
||||
path = rootDirectory + @"\UplayR1Unlocker64.dll";
|
||||
"UplayR2.upc_r2_loader.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
"UplayR1.uplay_r1_loader64.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
UplayR1.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
if (bit32)
|
||||
{
|
||||
path = directory + @"\UplayR2Unlocker32.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
if (bit64)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
path = directory + @"\UplayR2Unlocker64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\UplayR2Unlocker64.dll";
|
||||
}
|
||||
path = rootDirectory + @"\UplayR2Unlocker32.dll";
|
||||
"UplayR2.upc_r2_loader64.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
"UplayR2.upc_r2_loader.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
UplayR2.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
}
|
||||
if (bit64)
|
||||
{
|
||||
path = directory + @"\UplayR2Unlocker64.dll";
|
||||
if (rootDirectory is not null && directory != rootDirectory)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
path = rootDirectory + @"\UplayR2Unlocker64.dll";
|
||||
}
|
||||
"UplayR2.upc_r2_loader64.dll".Write(path);
|
||||
installForm?.UpdateUser(
|
||||
$"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
UplayR2.CheckConfig(rootDirectory ?? directory, selection, installForm);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -335,7 +335,7 @@ internal static class Resources
|
|||
if (embeddedResources is null)
|
||||
{
|
||||
string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
|
||||
embeddedResources = new List<string>();
|
||||
embeddedResources = new();
|
||||
foreach (string resourceName in names.Where(n => n.StartsWith("CreamInstaller.Resources.")))
|
||||
embeddedResources.Add(resourceName[25..]);
|
||||
}
|
||||
|
@ -345,8 +345,7 @@ internal static class Resources
|
|||
|
||||
internal static void Write(this string resourceIdentifier, string filePath)
|
||||
{
|
||||
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);
|
||||
resource.CopyTo(file);
|
||||
}
|
||||
|
@ -378,45 +377,42 @@ internal static class Resources
|
|||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
private static extern bool GetBinaryType(string lpApplicationName, out BinaryType lpBinaryType);
|
||||
|
||||
internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType)
|
||||
=> GetBinaryType(path, out binaryType);
|
||||
internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) => GetBinaryType(path, out binaryType);
|
||||
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(
|
||||
this string rootDirectory, bool filterCommon = false, Func<string, bool> validFunc = null) =>
|
||||
await Task.Run(async () => (await rootDirectory.GetExecutables(filterCommon, validFunc)
|
||||
?? (filterCommon || validFunc is not null
|
||||
? await rootDirectory.GetExecutables()
|
||||
: null))?.Select(e =>
|
||||
{
|
||||
e.path = Path.GetDirectoryName(e.path);
|
||||
return e;
|
||||
})?.DistinctBy(e => e.path).ToList());
|
||||
internal static async Task<List<(string directory, BinaryType binaryType)>> GetExecutableDirectories(this string rootDirectory, bool filterCommon = false,
|
||||
Func<string, bool> validFunc = null)
|
||||
=> await Task.Run(async ()
|
||||
=> (await rootDirectory.GetExecutables(filterCommon, validFunc)
|
||||
?? (filterCommon || validFunc is not null ? await rootDirectory.GetExecutables() : null))?.Select(e =>
|
||||
{
|
||||
e.path = Path.GetDirectoryName(e.path);
|
||||
return e;
|
||||
})?.DistinctBy(e => e.path).ToList());
|
||||
|
||||
internal static async Task<List<(string path, BinaryType binaryType)>> GetExecutables(
|
||||
this string rootDirectory, bool filterCommon = false, Func<string, bool> validFunc = null) => await Task.Run(
|
||||
() =>
|
||||
internal static async Task<List<(string path, BinaryType binaryType)>> GetExecutables(this string rootDirectory, bool filterCommon = false,
|
||||
Func<string, bool> validFunc = null)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
List<(string path, BinaryType binaryType)> executables = new();
|
||||
if (Program.Canceled || !Directory.Exists(rootDirectory)) return null;
|
||||
foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe",
|
||||
new EnumerationOptions { RecurseSubdirectories = true }))
|
||||
if (Program.Canceled || !Directory.Exists(rootDirectory))
|
||||
return null;
|
||||
foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe", new EnumerationOptions { RecurseSubdirectories = true }))
|
||||
{
|
||||
if (Program.Canceled) return null;
|
||||
if (executables.All(e => e.path != path)
|
||||
&& (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
||||
&& (validFunc is null || validFunc(path))
|
||||
&& path.TryGetFileBinaryType(out BinaryType binaryType) && binaryType is BinaryType.BIT64)
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
||||
&& (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType)
|
||||
&& binaryType is BinaryType.BIT64)
|
||||
executables.Add((path, binaryType));
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe",
|
||||
new EnumerationOptions { RecurseSubdirectories = true }))
|
||||
foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe", new EnumerationOptions { RecurseSubdirectories = true }))
|
||||
{
|
||||
if (Program.Canceled) return null;
|
||||
if (executables.All(e => e.path != path)
|
||||
&& (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
||||
&& (validFunc is null || validFunc(path))
|
||||
&& path.TryGetFileBinaryType(out BinaryType binaryType) && binaryType is BinaryType.BIT32)
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path))
|
||||
&& (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType)
|
||||
&& binaryType is BinaryType.BIT32)
|
||||
executables.Add((path, binaryType));
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
@ -426,91 +422,62 @@ internal static class Resources
|
|||
internal static bool IsCommonIncorrectExecutable(this string rootDirectory, string path)
|
||||
{
|
||||
string subPath = path[rootDirectory.Length..].ToUpperInvariant().BeautifyPath();
|
||||
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("ZFGAMEBROWSER")
|
||||
|| subPath.Contains("MONO")
|
||||
|| subPath.Contains("PLUGINS")
|
||||
|| subPath.Contains("MODDING")
|
||||
|| (subPath.Contains("MOD") && subPath.Contains("MANAGER"))
|
||||
|| subPath.Contains("BATTLEYE")
|
||||
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("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<List<string>> GetDllDirectoriesFromGameDirectory(
|
||||
this string gameDirectory, Platform platform) => await Task.Run(() =>
|
||||
{
|
||||
List<string> dllDirectories = new();
|
||||
if (Program.Canceled || !Directory.Exists(gameDirectory)) return null;
|
||||
foreach (string directory in Directory
|
||||
.EnumerateDirectories(gameDirectory, "*",
|
||||
new EnumerationOptions { RecurseSubdirectories = true })
|
||||
.Append(gameDirectory))
|
||||
internal static async Task<List<string>> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
if (Program.Canceled) return null;
|
||||
string subDirectory = directory.BeautifyPath();
|
||||
if (!dllDirectories.Contains(subDirectory))
|
||||
List<string> dllDirectories = new();
|
||||
if (Program.Canceled || !Directory.Exists(gameDirectory))
|
||||
return null;
|
||||
foreach (string directory in Directory.EnumerateDirectories(gameDirectory, "*", new EnumerationOptions { RecurseSubdirectories = true })
|
||||
.Append(gameDirectory))
|
||||
{
|
||||
bool koaloaderInstalled = Koaloader.AutoLoadDlls
|
||||
.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||
.Any(pair => File.Exists(pair.path) && pair.path.IsResourceFile());
|
||||
if (platform is Platform.Steam or Platform.Paradox)
|
||||
if (Program.Canceled)
|
||||
return null;
|
||||
string subDirectory = directory.BeautifyPath();
|
||||
if (!dllDirectories.Contains(subDirectory))
|
||||
{
|
||||
subDirectory.GetSmokeApiComponents(out string api, out string api_o, out string api64,
|
||||
out string api64_o, out string config, out string cache);
|
||||
if (File.Exists(api)
|
||||
|| File.Exists(api_o)
|
||||
|| File.Exists(api64)
|
||||
|| File.Exists(api64_o)
|
||||
|| (File.Exists(config) && !koaloaderInstalled)
|
||||
|| (File.Exists(cache) && !koaloaderInstalled))
|
||||
dllDirectories.Add(subDirectory);
|
||||
}
|
||||
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);
|
||||
if (File.Exists(api32)
|
||||
|| File.Exists(api32_o)
|
||||
|| File.Exists(api64)
|
||||
|| File.Exists(api64_o)
|
||||
|| (File.Exists(config) && !koaloaderInstalled))
|
||||
dllDirectories.Add(subDirectory);
|
||||
}
|
||||
if (platform is Platform.Ubisoft)
|
||||
{
|
||||
subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64,
|
||||
out string api64_o, out string config);
|
||||
if (File.Exists(api32)
|
||||
|| File.Exists(api32_o)
|
||||
|| File.Exists(api64)
|
||||
|| File.Exists(api64_o)
|
||||
|| (File.Exists(config) && !koaloaderInstalled))
|
||||
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);
|
||||
if (File.Exists(old_api32)
|
||||
|| File.Exists(old_api64)
|
||||
|| File.Exists(api32)
|
||||
|| File.Exists(api32_o)
|
||||
|| File.Exists(api64)
|
||||
|| File.Exists(api64_o)
|
||||
|| (File.Exists(config) && !koaloaderInstalled))
|
||||
dllDirectories.Add(subDirectory);
|
||||
bool koaloaderInstalled = Koaloader.AutoLoadDlls.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
|
||||
.Any(pair => File.Exists(pair.path) && pair.path.IsResourceFile());
|
||||
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 config,
|
||||
out string cache);
|
||||
if (File.Exists(api) || File.Exists(api_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled
|
||||
|| File.Exists(cache) && !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
}
|
||||
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);
|
||||
if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o)
|
||||
|| File.Exists(config) && !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
}
|
||||
if (platform is Platform.Ubisoft)
|
||||
{
|
||||
subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o)
|
||||
|| File.Exists(config) && !koaloaderInstalled)
|
||||
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);
|
||||
if (File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64)
|
||||
|| File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled)
|
||||
dllDirectories.Add(subDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !dllDirectories.Any() ? null : dllDirectories;
|
||||
});
|
||||
return !dllDirectories.Any() ? null : dllDirectories;
|
||||
});
|
||||
|
||||
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)
|
||||
{
|
||||
api32 = directory + @"\steam_api.dll";
|
||||
|
@ -522,7 +489,8 @@ internal static class Resources
|
|||
|
||||
internal static string ComputeMD5(this string filePath)
|
||||
{
|
||||
if (!File.Exists(filePath)) return null;
|
||||
if (!File.Exists(filePath))
|
||||
return null;
|
||||
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
using MD5 md5 = MD5.Create();
|
||||
#pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
|
@ -534,9 +502,8 @@ internal static class Resources
|
|||
internal static bool IsResourceFile(this string filePath, ResourceIdentifier identifier)
|
||||
=> filePath.ComputeMD5() is string hash && ResourceMD5s[identifier].Contains(hash);
|
||||
|
||||
internal static bool IsResourceFile(this string filePath) => filePath.ComputeMD5() is string hash
|
||||
&& ResourceMD5s.Values.Any(
|
||||
hashes => hashes.Contains(hash));
|
||||
internal static bool IsResourceFile(this string filePath)
|
||||
=> filePath.ComputeMD5() is string hash && ResourceMD5s.Values.Any(hashes => hashes.Contains(hash));
|
||||
|
||||
internal enum BinaryType
|
||||
{
|
||||
|
|
|
@ -11,12 +11,8 @@ namespace CreamInstaller.Resources;
|
|||
|
||||
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,
|
||||
out string config
|
||||
)
|
||||
internal static void GetScreamApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
out string config)
|
||||
{
|
||||
api32 = directory + @"\EOSSDK-Win32-Shipping.dll";
|
||||
api32_o = directory + @"\EOSSDK-Win32-Shipping_o.dll";
|
||||
|
@ -30,13 +26,11 @@ internal static class ScreamAPI
|
|||
directory.GetScreamApiComponents(out _, out _, out _, out _, out string config);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideCatalogItems
|
||||
= selection.AllDlc.Where(pair => pair.Value.type is DlcType.EpicCatalogItem).Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in
|
||||
selection.ExtraSelectedDlc)
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
|
||||
overrideCatalogItems = overrideCatalogItems.Except(extraDlc);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> entitlements
|
||||
= selection.SelectedDlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> _dlc) in
|
||||
selection.ExtraSelectedDlc)
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> _dlc) in selection.ExtraSelectedDlc)
|
||||
entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement));
|
||||
if (overrideCatalogItems.Any() || entitlements.Any())
|
||||
{
|
||||
|
@ -44,28 +38,20 @@ internal static class ScreamAPI
|
|||
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
File.Create(config).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer,
|
||||
new SortedList<string, (DlcType type, string name, string icon)>(
|
||||
overrideCatalogItems.ToDictionary(pair => pair.Key, pair => pair.Value),
|
||||
PlatformIdComparer.String),
|
||||
new SortedList<string, (DlcType type, string name, string icon)>(
|
||||
entitlements.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
installForm);
|
||||
WriteConfig(writer, new(overrideCatalogItems.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
new(entitlements.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
else if (File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteConfig(StreamWriter writer,
|
||||
SortedList<string, (DlcType type, string name, string icon)> overrideCatalogItems,
|
||||
SortedList<string, (DlcType type, string name, string icon)> entitlements,
|
||||
InstallForm installForm = null)
|
||||
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideCatalogItems,
|
||||
SortedList<string, (DlcType type, string name, string icon)> entitlements, InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"version\": 2,");
|
||||
|
@ -77,22 +63,18 @@ internal static class ScreamAPI
|
|||
if (overrideCatalogItems.Any())
|
||||
{
|
||||
writer.WriteLine(" \"override\": [");
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastOverrideCatalogItem
|
||||
= overrideCatalogItems.Last();
|
||||
KeyValuePair<string, (DlcType type, string name, string icon)> lastOverrideCatalogItem = overrideCatalogItems.Last();
|
||||
foreach (KeyValuePair<string, (DlcType type, string name, string icon)> pair in overrideCatalogItems)
|
||||
{
|
||||
string id = pair.Key;
|
||||
(_, string name, _) = pair.Value;
|
||||
writer.WriteLine($" \"{id}\"{(pair.Equals(lastOverrideCatalogItem) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added override catalog item to ScreamAPI.json with id {id} ({name})",
|
||||
LogTextBox.Action, false);
|
||||
installForm?.UpdateUser($"Added override catalog item to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" ]");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"override\": []");
|
||||
}
|
||||
writer.WriteLine(" },");
|
||||
writer.WriteLine(" \"entitlements\": {");
|
||||
writer.WriteLine(" \"unlock_all\": true,");
|
||||
|
@ -106,15 +88,12 @@ internal static class ScreamAPI
|
|||
string id = pair.Key;
|
||||
(_, string name, _) = pair.Value;
|
||||
writer.WriteLine($" \"{id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added entitlement to ScreamAPI.json with id {id} ({name})", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Added entitlement to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" ]");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"inject\": []");
|
||||
}
|
||||
writer.WriteLine(" }");
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
|
@ -122,8 +101,7 @@ internal static class ScreamAPI
|
|||
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
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);
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
if (File.Exists(api32))
|
||||
|
@ -132,8 +110,7 @@ internal static class ScreamAPI
|
|||
installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api32_o, 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 (File.Exists(api64_o))
|
||||
{
|
||||
|
@ -143,8 +120,7 @@ internal static class ScreamAPI
|
|||
installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api64_o, 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 (deleteConfig && File.Exists(config))
|
||||
{
|
||||
|
@ -153,34 +129,31 @@ internal static class ScreamAPI
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null,
|
||||
bool generateConfig = true) => await Task.Run(() =>
|
||||
{
|
||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
out string config);
|
||||
if (File.Exists(api32) && !File.Exists(api32_o))
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
File.Move(api32, api32_o);
|
||||
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(api32);
|
||||
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api64, api64_o);
|
||||
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(api64);
|
||||
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (File.Exists(api32) && !File.Exists(api32_o))
|
||||
{
|
||||
File.Move(api32, api32_o);
|
||||
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(api32);
|
||||
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api64, api64_o);
|
||||
installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(api64);
|
||||
installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,12 +11,8 @@ namespace CreamInstaller.Resources;
|
|||
|
||||
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,
|
||||
out string config,
|
||||
out string cache)
|
||||
internal static void GetSmokeApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
out string config, out string cache)
|
||||
{
|
||||
api32 = directory + @"\steam_api.dll";
|
||||
api32_o = directory + @"\steam_api_o.dll";
|
||||
|
@ -29,18 +25,15 @@ internal static class SmokeAPI
|
|||
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
|
||||
{
|
||||
directory.GetSmokeApiComponents(out _, out _, out _, out _, out string config, out _);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideDlc
|
||||
= selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in
|
||||
selection.ExtraSelectedDlc)
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
|
||||
overrideDlc = overrideDlc.Except(extraDlc);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> injectDlc
|
||||
= new List<KeyValuePair<string, (DlcType type, string name, string icon)>>();
|
||||
if (selection.AllDlc.Count > 64 || selection.ExtraDlc.Any(e => e.dlc.Count > 64))
|
||||
{
|
||||
injectDlc = injectDlc.Concat(selection.SelectedDlc.Where(pair => pair.Value.type is DlcType.SteamHidden));
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in
|
||||
selection.ExtraSelectedDlc)
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
|
||||
if (selection.ExtraDlc.Where(e => e.id == id).Single().dlc.Count > 64)
|
||||
injectDlc = injectDlc.Concat(extraDlc.Where(pair => pair.Value.type is DlcType.SteamHidden));
|
||||
}
|
||||
|
@ -50,27 +43,20 @@ internal static class SmokeAPI
|
|||
installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
File.Create(config).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer,
|
||||
new SortedList<string, (DlcType type, string name, string icon)>(
|
||||
overrideDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
new SortedList<string, (DlcType type, string name, string icon)>(
|
||||
injectDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
installForm);
|
||||
WriteConfig(writer, new(overrideDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
new(injectDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
else if (File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteConfig(StreamWriter writer,
|
||||
SortedList<string, (DlcType type, string name, string icon)> overrideDlc,
|
||||
SortedList<string, (DlcType type, string name, string icon)> injectDlc,
|
||||
InstallForm installForm = null)
|
||||
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideDlc,
|
||||
SortedList<string, (DlcType type, string name, string icon)> injectDlc, InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"$version\": 1,");
|
||||
|
@ -86,15 +72,12 @@ internal static class SmokeAPI
|
|||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" {dlcId}{(pair.Equals(lastOverrideDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added override DLC to SmokeAPI.json with appid {dlcId} ({dlcName})",
|
||||
LogTextBox.Action, false);
|
||||
installForm?.UpdateUser($"Added override DLC to SmokeAPI.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" ],");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"override\": [],");
|
||||
}
|
||||
if (injectDlc.Count > 0)
|
||||
{
|
||||
writer.WriteLine(" \"dlc_ids\": [");
|
||||
|
@ -104,15 +87,12 @@ internal static class SmokeAPI
|
|||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" {dlcId}{(pair.Equals(lastInjectDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added inject DLC to SmokeAPI.json with appid {dlcId} ({dlcName})",
|
||||
LogTextBox.Action, false);
|
||||
installForm?.UpdateUser($"Added inject DLC to SmokeAPI.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" ],");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"dlc_ids\": [],");
|
||||
}
|
||||
writer.WriteLine(" \"auto_inject_inventory\": true,");
|
||||
writer.WriteLine(" \"inventory_items\": []");
|
||||
writer.WriteLine("}");
|
||||
|
@ -125,11 +105,9 @@ internal static class SmokeAPI
|
|||
if (File.Exists(oldConfig))
|
||||
{
|
||||
File.Delete(oldConfig);
|
||||
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 config, out string cache);
|
||||
directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string cache);
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
if (File.Exists(api32))
|
||||
|
@ -138,9 +116,7 @@ internal static class SmokeAPI
|
|||
installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api32_o, 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 (File.Exists(api64_o))
|
||||
{
|
||||
|
@ -150,9 +126,7 @@ internal static class SmokeAPI
|
|||
installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api64_o, 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 (deleteConfig && File.Exists(config))
|
||||
{
|
||||
|
@ -166,41 +140,37 @@ internal static class SmokeAPI
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null,
|
||||
bool generateConfig = true) => await Task.Run(() =>
|
||||
{
|
||||
directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig);
|
||||
if (File.Exists(oldConfig))
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
File.Delete(oldConfig);
|
||||
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 config, out _);
|
||||
if (File.Exists(api32) && !File.Exists(api32_o))
|
||||
{
|
||||
File.Move(api32, api32_o);
|
||||
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"SmokeAPI.steam_api.dll".Write(api32);
|
||||
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api64, api64_o);
|
||||
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"SmokeAPI.steam_api64.dll".Write(api64);
|
||||
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig);
|
||||
if (File.Exists(oldConfig))
|
||||
{
|
||||
File.Delete(oldConfig);
|
||||
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 config, out _);
|
||||
if (File.Exists(api32) && !File.Exists(api32_o))
|
||||
{
|
||||
File.Move(api32, api32_o);
|
||||
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"SmokeAPI.steam_api.dll".Write(api32);
|
||||
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api64, api64_o);
|
||||
installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"SmokeAPI.steam_api64.dll".Write(api64);
|
||||
installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,12 +11,8 @@ namespace CreamInstaller.Resources;
|
|||
|
||||
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,
|
||||
out string config
|
||||
)
|
||||
internal static void GetUplayR1Components(this string directory, out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
out string config)
|
||||
{
|
||||
api32 = directory + @"\uplay_r1_loader.dll";
|
||||
api32_o = directory + @"\uplay_r1_loader_o.dll";
|
||||
|
@ -28,10 +24,8 @@ internal static class UplayR1
|
|||
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
|
||||
{
|
||||
directory.GetUplayR1Components(out _, out _, out _, out _, out string config);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc
|
||||
= selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in
|
||||
selection.ExtraSelectedDlc)
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
|
||||
blacklistDlc = blacklistDlc.Except(extraDlc);
|
||||
if (blacklistDlc.Any())
|
||||
{
|
||||
|
@ -39,24 +33,19 @@ internal static class UplayR1
|
|||
installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
File.Create(config).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer,
|
||||
new SortedList<string, (DlcType type, string name, string icon)>(
|
||||
blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
installForm);
|
||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
else if (File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteConfig(StreamWriter writer,
|
||||
SortedList<string, (DlcType type, string name, string icon)> blacklistDlc,
|
||||
InstallForm installForm = null)
|
||||
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc,
|
||||
InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"logging\": false,");
|
||||
|
@ -71,46 +60,38 @@ internal static class UplayR1
|
|||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" {dlcId}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {dlcId} ({dlcName})",
|
||||
LogTextBox.Action, false);
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" ],");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"blacklist\": [],");
|
||||
}
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
|
||||
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
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);
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
if (File.Exists(api32))
|
||||
{
|
||||
File.Delete(api32);
|
||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api32_o, 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 (File.Exists(api64_o))
|
||||
{
|
||||
if (File.Exists(api64))
|
||||
{
|
||||
File.Delete(api64);
|
||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api64_o, 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 (deleteConfig && File.Exists(config))
|
||||
{
|
||||
|
@ -119,34 +100,31 @@ internal static class UplayR1
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null,
|
||||
bool generateConfig = true) => await Task.Run(() =>
|
||||
{
|
||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o,
|
||||
out string config);
|
||||
if (File.Exists(api32) && !File.Exists(api32_o))
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
File.Move(api32, api32_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"UplayR1.uplay_r1_loader.dll".Write(api32);
|
||||
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api64, api64_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"UplayR1.uplay_r1_loader64.dll".Write(api64);
|
||||
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
|
||||
if (File.Exists(api32) && !File.Exists(api32_o))
|
||||
{
|
||||
File.Move(api32, api32_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"UplayR1.uplay_r1_loader.dll".Write(api32);
|
||||
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api64, api64_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"UplayR1.uplay_r1_loader64.dll".Write(api64);
|
||||
installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,12 +11,8 @@ namespace CreamInstaller.Resources;
|
|||
|
||||
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,
|
||||
out string api64, out string api64_o,
|
||||
out string config)
|
||||
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)
|
||||
{
|
||||
old_api32 = directory + @"\uplay_r2_loader.dll";
|
||||
old_api64 = directory + @"\uplay_r2_loader64.dll";
|
||||
|
@ -30,10 +26,8 @@ internal static class UplayR2
|
|||
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
|
||||
{
|
||||
directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config);
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc
|
||||
= selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in
|
||||
selection.ExtraSelectedDlc)
|
||||
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
|
||||
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
|
||||
blacklistDlc = blacklistDlc.Except(extraDlc);
|
||||
if (blacklistDlc.Any())
|
||||
{
|
||||
|
@ -41,24 +35,19 @@ internal static class UplayR2
|
|||
installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/
|
||||
File.Create(config).Close();
|
||||
StreamWriter writer = new(config, true, Encoding.UTF8);
|
||||
WriteConfig(writer,
|
||||
new SortedList<string, (DlcType type, string name, string icon)>(
|
||||
blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String),
|
||||
installForm);
|
||||
WriteConfig(writer, new(blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
else if (File.Exists(config))
|
||||
{
|
||||
File.Delete(config);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteConfig(StreamWriter writer,
|
||||
SortedList<string, (DlcType type, string name, string icon)> blacklistDlc,
|
||||
InstallForm installForm = null)
|
||||
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc,
|
||||
InstallForm installForm = null)
|
||||
{
|
||||
writer.WriteLine("{");
|
||||
writer.WriteLine(" \"logging\": false,");
|
||||
|
@ -75,35 +64,30 @@ internal static class UplayR2
|
|||
string dlcId = pair.Key;
|
||||
(_, string dlcName, _) = pair.Value;
|
||||
writer.WriteLine($" {dlcId}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}");
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {dlcId} ({dlcName})",
|
||||
LogTextBox.Action, false);
|
||||
installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {dlcId} ({dlcName})", LogTextBox.Action, false);
|
||||
}
|
||||
writer.WriteLine(" ],");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine(" \"blacklist\": [],");
|
||||
}
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
|
||||
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
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);
|
||||
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);
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
string api = File.Exists(old_api32) ? old_api32 : api32;
|
||||
if (File.Exists(api))
|
||||
{
|
||||
File.Delete(api);
|
||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api32_o, 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 (File.Exists(api64_o))
|
||||
{
|
||||
|
@ -111,12 +95,10 @@ internal static class UplayR2
|
|||
if (File.Exists(api))
|
||||
{
|
||||
File.Delete(api);
|
||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action,
|
||||
false);
|
||||
installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||
}
|
||||
File.Move(api64_o, 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 (deleteConfig && File.Exists(config))
|
||||
{
|
||||
|
@ -125,36 +107,34 @@ internal static class UplayR2
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null,
|
||||
bool generateConfig = true) => await Task.Run(() =>
|
||||
{
|
||||
directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o,
|
||||
out string api64, out string api64_o, out string config);
|
||||
string api = File.Exists(old_api32) ? old_api32 : api32;
|
||||
if (File.Exists(api) && !File.Exists(api32_o))
|
||||
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
File.Move(api, api32_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"UplayR2.upc_r2_loader.dll".Write(api);
|
||||
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||
}
|
||||
api = File.Exists(old_api64) ? old_api64 : api64;
|
||||
if (File.Exists(api) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api, api64_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}",
|
||||
LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"UplayR2.upc_r2_loader64.dll".Write(api);
|
||||
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
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);
|
||||
string api = File.Exists(old_api32) ? old_api32 : api32;
|
||||
if (File.Exists(api) && !File.Exists(api32_o))
|
||||
{
|
||||
File.Move(api, api32_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api32_o))
|
||||
{
|
||||
"UplayR2.upc_r2_loader.dll".Write(api);
|
||||
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||
}
|
||||
api = File.Exists(old_api64) ? old_api64 : api64;
|
||||
if (File.Exists(api) && !File.Exists(api64_o))
|
||||
{
|
||||
File.Move(api, api64_o);
|
||||
installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (File.Exists(api64_o))
|
||||
{
|
||||
"UplayR2.upc_r2_loader64.dll".Write(api);
|
||||
installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false);
|
||||
}
|
||||
if (generateConfig)
|
||||
CheckConfig(directory, selection, installForm);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@ internal static class Diagnostics
|
|||
get
|
||||
{
|
||||
notepadPlusPlusPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Notepad++", "", null) as string;
|
||||
notepadPlusPlusPath
|
||||
??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\Notepad++", "", null) as string;
|
||||
notepadPlusPlusPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\Notepad++", "", null) as string;
|
||||
return notepadPlusPlusPath;
|
||||
}
|
||||
}
|
||||
|
@ -35,18 +34,13 @@ internal static class Diagnostics
|
|||
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 BeautifyPath(this string path)
|
||||
=> path is null ? null : Path.TrimEndingDirectorySeparator(Path.GetFullPath(path));
|
||||
internal static string BeautifyPath(this string path) => path is null ? null : Path.TrimEndingDirectorySeparator(Path.GetFullPath(path));
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ namespace CreamInstaller.Utility;
|
|||
|
||||
internal static class ExceptionHandler
|
||||
{
|
||||
internal static bool HandleException(this Exception e, Form form = null, string caption = null,
|
||||
string acceptButtonText = "Retry", string cancelButtonText = "Cancel")
|
||||
internal static bool HandleException(this Exception e, Form form = null, string caption = null, string acceptButtonText = "Retry",
|
||||
string cancelButtonText = "Cancel")
|
||||
{
|
||||
caption ??= Program.Name + " encountered an exception";
|
||||
StringBuilder output = new();
|
||||
|
@ -32,31 +32,23 @@ internal static class ExceptionHandler
|
|||
int ciNum = line.LastIndexOf(@"CreamInstaller\", StringComparison.Ordinal);
|
||||
int lineNum = line.LastIndexOf(":line ", StringComparison.Ordinal);
|
||||
if (atNum != -1)
|
||||
_ = output.Append("\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..])
|
||||
+ (inNum != -1
|
||||
? "\n "
|
||||
+ (ciNum != -1
|
||||
? "in "
|
||||
+ (lineNum != -1
|
||||
? line[ciNum..lineNum]
|
||||
+ "\n on " + line[(lineNum + 1)..]
|
||||
: line[ciNum..])
|
||||
: line[inNum..])
|
||||
: null));
|
||||
_ = output.Append("\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..]) + (inNum != -1
|
||||
? "\n " + (ciNum != -1
|
||||
? "in " + (lineNum != -1 ? line[ciNum..lineNum] + "\n on " + line[(lineNum + 1)..] : line[ciNum..])
|
||||
: line[inNum..])
|
||||
: null));
|
||||
}
|
||||
}
|
||||
e = e.InnerException;
|
||||
stackDepth++;
|
||||
}
|
||||
using DialogForm dialogForm = new(form ?? Form.ActiveForm);
|
||||
return dialogForm.Show(SystemIcons.Error, output.ToString(), acceptButtonText, cancelButtonText, caption)
|
||||
== DialogResult.OK;
|
||||
return dialogForm.Show(SystemIcons.Error, output.ToString(), acceptButtonText, cancelButtonText, caption) == DialogResult.OK;
|
||||
}
|
||||
|
||||
internal static void HandleFatalException(this Exception e)
|
||||
{
|
||||
bool? restart = e?.HandleException(caption: Program.Name + " encountered a fatal exception",
|
||||
acceptButtonText: "Restart");
|
||||
bool? restart = e?.HandleException(caption: Program.Name + " encountered a fatal exception", acceptButtonText: "Restart");
|
||||
if (restart.HasValue && restart.Value)
|
||||
Application.Restart();
|
||||
Application.Exit();
|
||||
|
|
|
@ -12,7 +12,7 @@ internal static class HttpClientManager
|
|||
|
||||
internal static void Setup()
|
||||
{
|
||||
HttpClient = new HttpClient();
|
||||
HttpClient = new();
|
||||
HttpClient.DefaultRequestHeaders.Add("User-Agent", $"CI{Program.Version.Replace(".", "")}");
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,7 @@ internal static class HttpClientManager
|
|||
try
|
||||
{
|
||||
using HttpRequestMessage request = new(HttpMethod.Get, url);
|
||||
using HttpResponseMessage response
|
||||
= await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
using HttpResponseMessage response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
_ = response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
@ -42,8 +41,7 @@ internal static class HttpClientManager
|
|||
internal static async Task<HtmlNodeCollection> GetDocumentNodes(string url, string xpath)
|
||||
=> (await EnsureGet(url))?.ToHtmlDocument()?.DocumentNode?.SelectNodes(xpath);
|
||||
|
||||
internal static HtmlNodeCollection GetDocumentNodes(this HtmlDocument htmlDocument, string xpath)
|
||||
=> htmlDocument.DocumentNode?.SelectNodes(xpath);
|
||||
internal static HtmlNodeCollection GetDocumentNodes(this HtmlDocument htmlDocument, string xpath) => htmlDocument.DocumentNode?.SelectNodes(xpath);
|
||||
|
||||
internal static async Task<Image> GetImageFromUrl(string url)
|
||||
{
|
||||
|
|
|
@ -6,27 +6,23 @@ namespace CreamInstaller.Utility;
|
|||
|
||||
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/";
|
||||
|
||||
internal const string GoogleFaviconsApiUrl = "https://www.google.com/s2/favicons";
|
||||
|
||||
internal static Icon ToIcon(this Image image)
|
||||
{
|
||||
using Bitmap dialogIconBitmap = new(image, new Size(image.Width, image.Height));
|
||||
using Bitmap dialogIconBitmap = new(image, new(image.Width, image.Height));
|
||||
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)
|
||||
=> File.Exists(path) ? Icon.ExtractAssociatedIcon(path)?.ToBitmap() : null;
|
||||
internal static Image GetFileIconImage(this string path) => File.Exists(path) ? Icon.ExtractAssociatedIcon(path)?.ToBitmap() : null;
|
||||
|
||||
internal static Image GetNotepadImage() => GetFileIconImage(Diagnostics.GetNotepadPath());
|
||||
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -18,9 +18,11 @@ internal static class LogTextBox
|
|||
textBox.SelectionStart = textBox.TextLength;
|
||||
textBox.SelectionLength = 0;
|
||||
textBox.SelectionColor = color;
|
||||
if (scroll) textBox.ScrollToCaret();
|
||||
if (scroll)
|
||||
textBox.ScrollToCaret();
|
||||
textBox.AppendText(text);
|
||||
if (scroll) textBox.ScrollToCaret();
|
||||
if (scroll)
|
||||
textBox.ScrollToCaret();
|
||||
textBox.SelectionColor = textBox.ForeColor;
|
||||
textBox.Invalidate();
|
||||
}
|
||||
|
|
|
@ -11,11 +11,9 @@ namespace CreamInstaller.Utility;
|
|||
|
||||
internal static class ProgramData
|
||||
{
|
||||
internal static readonly string DirectoryPathOld
|
||||
= Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\CreamInstaller";
|
||||
internal static readonly string DirectoryPathOld = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\CreamInstaller";
|
||||
|
||||
internal static readonly string DirectoryPath
|
||||
= Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\CreamInstaller";
|
||||
internal static readonly string DirectoryPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\CreamInstaller";
|
||||
|
||||
internal static readonly string AppInfoPath = DirectoryPath + @"\appinfo";
|
||||
internal static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt";
|
||||
|
@ -29,27 +27,30 @@ internal static class ProgramData
|
|||
internal static readonly string DlcChoicesPath = DirectoryPath + @"\dlc.json";
|
||||
internal static readonly string KoaloaderProxyChoicesPath = DirectoryPath + @"\proxies.json";
|
||||
|
||||
internal static async Task Setup() => await Task.Run(() =>
|
||||
{
|
||||
if (Directory.Exists(DirectoryPathOld))
|
||||
internal static async Task Setup()
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
if (Directory.Exists(DirectoryPath)) Directory.Delete(DirectoryPath, true);
|
||||
Directory.Move(DirectoryPathOld, DirectoryPath);
|
||||
}
|
||||
if (!Directory.Exists(DirectoryPath)) _ = Directory.CreateDirectory(DirectoryPath);
|
||||
if (!File.Exists(AppInfoVersionPath)
|
||||
|| !Version.TryParse(File.ReadAllText(AppInfoVersionPath, Encoding.UTF8), out Version version)
|
||||
|| version < MinimumAppInfoVersion)
|
||||
{
|
||||
if (Directory.Exists(AppInfoPath)) Directory.Delete(AppInfoPath, true);
|
||||
_ = Directory.CreateDirectory(AppInfoPath);
|
||||
File.WriteAllText(AppInfoVersionPath, Program.Version, Encoding.UTF8);
|
||||
}
|
||||
if (!Directory.Exists(CooldownPath))
|
||||
_ = Directory.CreateDirectory(CooldownPath);
|
||||
if (File.Exists(OldProgramChoicesPath))
|
||||
File.Delete(OldProgramChoicesPath);
|
||||
});
|
||||
if (Directory.Exists(DirectoryPathOld))
|
||||
{
|
||||
if (Directory.Exists(DirectoryPath))
|
||||
Directory.Delete(DirectoryPath, true);
|
||||
Directory.Move(DirectoryPathOld, DirectoryPath);
|
||||
}
|
||||
if (!Directory.Exists(DirectoryPath))
|
||||
_ = Directory.CreateDirectory(DirectoryPath);
|
||||
if (!File.Exists(AppInfoVersionPath) || !Version.TryParse(File.ReadAllText(AppInfoVersionPath, Encoding.UTF8), out Version version)
|
||||
|| version < MinimumAppInfoVersion)
|
||||
{
|
||||
if (Directory.Exists(AppInfoPath))
|
||||
Directory.Delete(AppInfoPath, true);
|
||||
_ = Directory.CreateDirectory(AppInfoPath);
|
||||
File.WriteAllText(AppInfoVersionPath, Program.Version, Encoding.UTF8);
|
||||
}
|
||||
if (!Directory.Exists(CooldownPath))
|
||||
_ = Directory.CreateDirectory(CooldownPath);
|
||||
if (File.Exists(OldProgramChoicesPath))
|
||||
File.Delete(OldProgramChoicesPath);
|
||||
});
|
||||
|
||||
internal static bool CheckCooldown(string identifier, int cooldown)
|
||||
{
|
||||
|
@ -91,16 +92,16 @@ internal static class ProgramData
|
|||
|
||||
internal static List<(Platform platform, string id)> ReadProgramChoices()
|
||||
{
|
||||
if (!File.Exists(ProgramChoicesPath)) return null;
|
||||
if (!File.Exists(ProgramChoicesPath))
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(File.ReadAllText(ProgramChoicesPath),
|
||||
typeof(List<(Platform platform, string id)>)) as
|
||||
return JsonConvert.DeserializeObject(File.ReadAllText(ProgramChoicesPath), typeof(List<(Platform platform, string id)>)) as
|
||||
List<(Platform platform, string id)>;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<(Platform platform, string id)>();
|
||||
return new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,16 +119,16 @@ internal static class ProgramData
|
|||
|
||||
internal static List<(Platform platform, string gameId, string dlcId)> ReadDlcChoices()
|
||||
{
|
||||
if (!File.Exists(DlcChoicesPath)) return null;
|
||||
if (!File.Exists(DlcChoicesPath))
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(File.ReadAllText(DlcChoicesPath),
|
||||
typeof(List<(Platform platform, string gameId, string dlcId)>)) as
|
||||
return JsonConvert.DeserializeObject(File.ReadAllText(DlcChoicesPath), typeof(List<(Platform platform, string gameId, string dlcId)>)) as
|
||||
List<(Platform platform, string gameId, string dlcId)>;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<(Platform platform, string gameId, string dlcId)>();
|
||||
return new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,22 +146,20 @@ internal static class ProgramData
|
|||
|
||||
internal static List<(Platform platform, string id, string proxy, bool enabled)> ReadKoaloaderChoices()
|
||||
{
|
||||
if (!File.Exists(KoaloaderProxyChoicesPath)) return null;
|
||||
if (!File.Exists(KoaloaderProxyChoicesPath))
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(File.ReadAllText(KoaloaderProxyChoicesPath),
|
||||
typeof(
|
||||
List<(Platform platform, string id, string proxy, bool enabled)>))
|
||||
as List<(Platform platform, string id, string proxy, bool enabled)>;
|
||||
typeof(List<(Platform platform, string id, string proxy, bool enabled)>)) as List<(Platform platform, string id, string proxy, bool enabled)>;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<(Platform platform, string id, string proxy, bool enabled)>();
|
||||
return new();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteKoaloaderProxyChoices(
|
||||
List<(Platform platform, string id, string proxy, bool enabled)> choices)
|
||||
internal static void WriteKoaloaderProxyChoices(List<(Platform platform, string id, string proxy, bool enabled)> choices)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue