koaloader proxy choices

This commit is contained in:
pointfeev 2022-08-25 22:04:45 -04:00
parent f3bb5a7cc3
commit f77d01d4f8
7 changed files with 139 additions and 33 deletions

View file

@ -1,6 +1,10 @@
using System; using CreamInstaller.Resources;
using CreamInstaller.Utility;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Forms.VisualStyles; using System.Windows.Forms.VisualStyles;
@ -10,12 +14,14 @@ namespace CreamInstaller.Components;
internal class CustomTreeView : TreeView internal class CustomTreeView : TreeView
{ {
private Form form;
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
if (m.Msg == 0x203) if (m.Msg == 0x203)
m.Result = IntPtr.Zero; m.Result = IntPtr.Zero;
else else
base.WndProc(ref m); base.WndProc(ref m);
form = FindForm();
} }
internal CustomTreeView() : base() internal CustomTreeView() : base()
@ -27,6 +33,7 @@ internal class CustomTreeView : TreeView
private readonly Dictionary<TreeNode, Rectangle> selectionBounds = new(); private readonly Dictionary<TreeNode, Rectangle> selectionBounds = new();
private readonly Dictionary<ProgramSelection, Rectangle> checkBoxBounds = new(); private readonly Dictionary<ProgramSelection, Rectangle> checkBoxBounds = new();
private readonly Dictionary<ProgramSelection, Rectangle> comboBoxBounds = new();
private const string koaloaderToggleString = "Koaloader"; private const string koaloaderToggleString = "Koaloader";
private SolidBrush backBrush; private SolidBrush backBrush;
@ -118,8 +125,8 @@ internal class CustomTreeView : TreeView
size = TextRenderer.MeasureText(graphics, text, font); size = TextRenderer.MeasureText(graphics, text, font);
int left = 1; int left = 1;
bounds = new(bounds.X + bounds.Width, bounds.Y, size.Width + left, bounds.Height); bounds = new(bounds.X + bounds.Width, bounds.Y, size.Width + left, bounds.Height);
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0)); selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width, 0));
checkBoxBounds = new(checkBoxBounds.Location, checkBoxBounds.Size + new Size(bounds.Size.Width + left, 0)); checkBoxBounds = new(checkBoxBounds.Location, checkBoxBounds.Size + new Size(bounds.Size.Width, 0));
graphics.FillRectangle(backBrush, bounds); graphics.FillRectangle(backBrush, bounds);
point = new(bounds.Location.X - 1 + left, bounds.Location.Y + 1); point = new(bounds.Location.X - 1 + left, bounds.Location.Y + 1);
TextRenderer.DrawText(graphics, text, font, point, TextRenderer.DrawText(graphics, text, font, point,
@ -127,6 +134,29 @@ internal class CustomTreeView : TreeView
TextFormatFlags.Default); TextFormatFlags.Default);
this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds); this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds);
if (selection.Koaloader && selection.KoaloaderProxy is not null)
{
ComboBoxState comboBoxState = Enabled ? ComboBoxState.Normal : ComboBoxState.Disabled;
text = selection.KoaloaderProxy.GetKoaloaderProxyDisplay();
size = TextRenderer.MeasureText(graphics, text, font) + new Size(6, 0);
bounds = new(bounds.X + bounds.Width, bounds.Y, size.Width, bounds.Height);
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width, 0));
Rectangle comboBoxBounds = bounds;
graphics.FillRectangle(backBrush, bounds);
ComboBoxRenderer.DrawTextBox(graphics, bounds, text, font, comboBoxState);
size = new(16, 0);
left = -1;
bounds = new(bounds.X + bounds.Width + left, bounds.Y, size.Width, bounds.Height);
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0));
comboBoxBounds = new(comboBoxBounds.Location, comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0));
ComboBoxRenderer.DrawDropDownButton(graphics, bounds, comboBoxState);
this.comboBoxBounds[selection] = RectangleToClient(comboBoxBounds);
}
else _ = comboBoxBounds.Remove(selection);
} }
} }
@ -138,28 +168,48 @@ internal class CustomTreeView : TreeView
base.OnMouseDown(e); base.OnMouseDown(e);
Refresh(); Refresh();
Point clickPoint = PointToClient(e.Location); Point clickPoint = PointToClient(e.Location);
SelectForm selectForm = (form ??= FindForm()) as SelectForm;
foreach (KeyValuePair<TreeNode, Rectangle> pair in selectionBounds) foreach (KeyValuePair<TreeNode, Rectangle> pair in selectionBounds)
if (pair.Key.IsVisible && pair.Value.Contains(clickPoint)) if (pair.Key.IsVisible && pair.Value.Contains(clickPoint))
{ {
SelectedNode = pair.Key; SelectedNode = pair.Key;
if (e.Button is MouseButtons.Right && FindForm() is SelectForm selectForm) if (e.Button is MouseButtons.Right && selectForm is not null)
selectForm.OnNodeRightClick(pair.Key, e.Location); selectForm.OnNodeRightClick(pair.Key, e.Location);
break; break;
} }
if (e.Button is MouseButtons.Left) if (e.Button is MouseButtons.Left)
{ {
bool invalidate = false; bool invalidate = false;
foreach (KeyValuePair<ProgramSelection, Rectangle> pair in checkBoxBounds) if (comboBoxBounds.Any() && selectForm is not null)
if (pair.Value.Contains(clickPoint)) foreach (KeyValuePair<ProgramSelection, Rectangle> pair in comboBoxBounds)
{ if (pair.Value.Contains(clickPoint))
pair.Key.Koaloader = !pair.Key.Koaloader; {
invalidate = true; ContextMenuStrip contextMenuStrip = selectForm.ContextMenuStrip;
break; contextMenuStrip.Items.Clear();
} foreach (string proxy in Resources.Resources.EmbeddedResources.FindAll(r => r.StartsWith("Koaloader")))
if (invalidate) {
_ = contextMenuStrip.Items.Add(new ContextMenuItem(proxy.GetKoaloaderProxyDisplay(),
new EventHandler((sender, e) =>
{
pair.Key.KoaloaderProxy = proxy;
ProgramData.UpdateKoaloaderProxyChoices();
Invalidate();
})));
}
contextMenuStrip.Show(this, PointToScreen(new(pair.Value.Left, pair.Value.Bottom)));
invalidate = true;
break;
}
if (!invalidate)
{ {
Invalidate(); foreach (KeyValuePair<ProgramSelection, Rectangle> pair in checkBoxBounds)
if (FindForm() is SelectForm selectForm) if (pair.Value.Contains(clickPoint))
{
pair.Key.Koaloader = !pair.Key.Koaloader;
invalidate = true;
break;
}
if (invalidate && selectForm is not null)
{ {
CheckBox koaloaderAllCheckBox = selectForm.KoaloaderAllCheckBox(); CheckBox koaloaderAllCheckBox = selectForm.KoaloaderAllCheckBox();
koaloaderAllCheckBox.CheckedChanged -= selectForm.OnKoaloaderAllCheckBoxChanged; koaloaderAllCheckBox.CheckedChanged -= selectForm.OnKoaloaderAllCheckBoxChanged;
@ -167,6 +217,7 @@ internal class CustomTreeView : TreeView
koaloaderAllCheckBox.CheckedChanged += selectForm.OnKoaloaderAllCheckBoxChanged; koaloaderAllCheckBox.CheckedChanged += selectForm.OnKoaloaderAllCheckBoxChanged;
} }
} }
if (invalidate) Invalidate();
} }
} }
} }

View file

@ -31,7 +31,6 @@ namespace CreamInstaller
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.components = new System.ComponentModel.Container();
this.installButton = new System.Windows.Forms.Button(); this.installButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
@ -53,7 +52,6 @@ namespace CreamInstaller
this.progressLabelGames = new System.Windows.Forms.Label(); this.progressLabelGames = new System.Windows.Forms.Label();
this.progressLabelDLCs = new System.Windows.Forms.Label(); this.progressLabelDLCs = new System.Windows.Forms.Label();
this.sortCheckBox = new System.Windows.Forms.CheckBox(); this.sortCheckBox = new System.Windows.Forms.CheckBox();
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.groupBox1.SuspendLayout(); this.groupBox1.SuspendLayout();
this.flowLayoutPanel4.SuspendLayout(); this.flowLayoutPanel4.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout(); this.flowLayoutPanel1.SuspendLayout();
@ -340,15 +338,6 @@ namespace CreamInstaller
this.sortCheckBox.Text = "Sort By Name"; this.sortCheckBox.Text = "Sort By Name";
this.sortCheckBox.CheckedChanged += new System.EventHandler(this.OnSortCheckBoxChanged); this.sortCheckBox.CheckedChanged += new System.EventHandler(this.OnSortCheckBoxChanged);
// //
// contextMenuStrip
//
this.contextMenuStrip.AllowMerge = false;
this.contextMenuStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.contextMenuStrip.Name = "contextMenuStrip";
this.contextMenuStrip.ShowItemToolTips = false;
this.contextMenuStrip.Size = new System.Drawing.Size(61, 4);
this.contextMenuStrip.TabStop = true;
//
// SelectForm // SelectForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
@ -406,7 +395,6 @@ namespace CreamInstaller
private Label progressLabelDLCs; private Label progressLabelDLCs;
private CheckBox sortCheckBox; private CheckBox sortCheckBox;
private FlowLayoutPanel flowLayoutPanel3; private FlowLayoutPanel flowLayoutPanel3;
private ContextMenuStrip contextMenuStrip;
private FlowLayoutPanel flowLayoutPanel4; private FlowLayoutPanel flowLayoutPanel4;
private CheckBox koaloaderAllCheckBox; private CheckBox koaloaderAllCheckBox;
} }

View file

@ -31,6 +31,8 @@ internal partial class SelectForm : CustomForm
Text = Program.ApplicationName; Text = Program.ApplicationName;
} }
public override ContextMenuStrip ContextMenuStrip => base.ContextMenuStrip ??= new();
private static void UpdateRemaining(Label label, SynchronizedCollection<string> list, string descriptor) => private static void UpdateRemaining(Label label, SynchronizedCollection<string> list, string descriptor) =>
label.Text = list.Any() ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") : ""; label.Text = list.Any() ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") : "";
@ -558,6 +560,8 @@ internal partial class SelectForm : CustomForm
await SteamCMD.Cleanup(); await SteamCMD.Cleanup();
} }
ProgramData.UpdateKoaloaderProxyChoices();
HideProgressBar(); HideProgressBar();
selectionTreeView.Enabled = ProgramSelection.All.Any(); selectionTreeView.Enabled = ProgramSelection.All.Any();
allCheckBox.Enabled = selectionTreeView.Enabled; allCheckBox.Enabled = selectionTreeView.Enabled;
@ -668,6 +672,7 @@ internal partial class SelectForm : CustomForm
internal void OnNodeRightClick(TreeNode node, Point location) internal void OnNodeRightClick(TreeNode node, Point location)
{ {
ContextMenuStrip contextMenuStrip = ContextMenuStrip;
contextMenuStrip.Items.Clear(); contextMenuStrip.Items.Clear();
string id = node.Name; string id = node.Name;
Platform platform = (Platform)node.Tag; Platform platform = (Platform)node.Tag;

View file

@ -57,7 +57,4 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root> </root>

View file

@ -28,7 +28,7 @@ internal class ProgramSelection
{ {
internal bool Enabled; internal bool Enabled;
internal bool Koaloader; internal bool Koaloader;
internal string KoaloaderProxy = "Koaloader.version_64.version.dll"; internal string KoaloaderProxy;
internal Platform Platform; internal Platform Platform;
internal string Id = "0"; internal string Id = "0";

View file

@ -26,6 +26,15 @@ internal static class Koaloader
config = directory + @"\Koaloader.json"; config = directory + @"\Koaloader.json";
} }
internal static string GetKoaloaderProxyDisplay(this string proxy)
{
string proxyDisplay = proxy[(proxy.IndexOf('.') + 1)..];
proxyDisplay = proxyDisplay[..proxyDisplay.IndexOf('.')];
string name = proxyDisplay[..proxyDisplay.LastIndexOf('_')];
string bitness = proxyDisplay[(proxyDisplay.LastIndexOf('_') + 1)..];
return $"{name}.dll ({bitness}-bit)";
}
internal static readonly List<(string unlocker, string dll)> AutoLoadDlls = new() internal static readonly List<(string unlocker, string dll)> AutoLoadDlls = new()
{ {
("SmokeAPI", "SmokeAPI32.dll"), ("SmokeAPI", "SmokeAPI64.dll"), ("SmokeAPI", "SmokeAPI32.dll"), ("SmokeAPI", "SmokeAPI64.dll"),
@ -102,11 +111,11 @@ internal static class Koaloader
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) => await Task.Run(async () => internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) => await Task.Run(async () =>
{ {
directory.GetKoaloaderComponents(out List<string> proxies, out string config); directory.GetKoaloaderComponents(out List<string> proxies, out string config);
foreach (string proxy in proxies.Where(proxy => File.Exists(proxy) && proxy.IsResourceFile(Resources.ResourceIdentifier.Koaloader))) foreach (string proxyPath in proxies.Where(proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(Resources.ResourceIdentifier.Koaloader)))
{ {
File.Delete(proxy); File.Delete(proxyPath);
if (installForm is not null) if (installForm is not null)
installForm.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxy)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", InstallationLog.Action, info: false);
} }
foreach ((string unlocker, string path) in AutoLoadDlls foreach ((string unlocker, string path) in AutoLoadDlls
.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) .Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll))
@ -135,6 +144,12 @@ internal static class Koaloader
proxy = proxy[(proxy.IndexOf('.') + 1)..]; proxy = proxy[(proxy.IndexOf('.') + 1)..];
proxy = proxy[(proxy.IndexOf('.') + 1)..]; proxy = proxy[(proxy.IndexOf('.') + 1)..];
string path = directory + @"\" + proxy; string path = directory + @"\" + proxy;
foreach (string proxyPath in proxies.Where(proxyPath => proxyPath != path && File.Exists(proxyPath) && proxyPath.IsResourceFile(Resources.ResourceIdentifier.Koaloader)))
{
File.Delete(proxyPath);
if (installForm is not null)
installForm.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", InstallationLog.Action, info: false);
}
selection.KoaloaderProxy.Write(path); selection.KoaloaderProxy.Write(path);
if (installForm is not null) if (installForm is not null)
installForm.UpdateUser($"Wrote Koaloader: {Path.GetFileName(path)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Wrote Koaloader: {Path.GetFileName(path)}", InstallationLog.Action, info: false);

View file

@ -3,10 +3,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Windows.Foundation.Metadata;
namespace CreamInstaller.Utility; namespace CreamInstaller.Utility;
internal static class ProgramData internal static class ProgramData
@ -24,6 +27,8 @@ internal static class ProgramData
internal static readonly string OldChoicesPath = DirectoryPath + @"\choices.txt"; internal static readonly string OldChoicesPath = DirectoryPath + @"\choices.txt";
internal static readonly string ChoicesPath = DirectoryPath + @"\choices.json"; internal static readonly string ChoicesPath = DirectoryPath + @"\choices.json";
internal static readonly string KoaloaderProxyChoicesPath = DirectoryPath + @"\proxies.json";
internal static async Task Setup() => await Task.Run(() => internal static async Task Setup() => await Task.Run(() =>
{ {
if (Directory.Exists(DirectoryPathOld)) if (Directory.Exists(DirectoryPathOld))
@ -103,4 +108,49 @@ internal static class ProgramData
} }
catch { } catch { }
} }
internal static List<(Platform platform, string id, string proxy)> ReadKoaloaderProxyChoices()
{
if (!File.Exists(KoaloaderProxyChoicesPath)) return null;
try
{
return JsonConvert.DeserializeObject(File.ReadAllText(KoaloaderProxyChoicesPath),
typeof(List<(Platform platform, string id, string proxy)>)) as List<(Platform platform, string id, string proxy)>;
}
catch
{
return new();
}
}
internal static void WriteKoaloaderProxyChoices(List<(Platform platform, string id, string proxy)> choices)
{
try
{
File.WriteAllText(KoaloaderProxyChoicesPath, JsonConvert.SerializeObject(choices));
}
catch { }
}
internal static void UpdateKoaloaderProxyChoices()
{
string defaultProxy = Resources.Resources.EmbeddedResources.Find(r => r.Contains("version_64"));
List<(Platform platform, string id, string proxy)> choices = ReadKoaloaderProxyChoices() ?? new();
foreach ((Platform platform, string id, string proxy) choice in choices.ToList())
if (ProgramSelection.FromPlatformId(choice.platform, choice.id) is ProgramSelection selection)
{
if (selection.KoaloaderProxy is null)
selection.KoaloaderProxy = choice.proxy;
else if (selection.KoaloaderProxy != choice.proxy && choices.Remove(choice))
choices.Add((selection.Platform, selection.Id, selection.KoaloaderProxy));
}
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
if (selection.KoaloaderProxy is null)
{
selection.KoaloaderProxy = defaultProxy;
choices.Add((selection.Platform, selection.Id, selection.KoaloaderProxy));
}
if (choices.Any())
WriteKoaloaderProxyChoices(choices);
}
} }