diff --git a/CreamInstaller/Classes/SteamCMD.cs b/CreamInstaller/Classes/SteamCMD.cs index d2ce6bd..ef70625 100644 --- a/CreamInstaller/Classes/SteamCMD.cs +++ b/CreamInstaller/Classes/SteamCMD.cs @@ -6,7 +6,7 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; -using System.Net; +using System.Net.Http; using System.Text; using System.Windows.Forms; @@ -59,9 +59,10 @@ namespace CreamInstaller Kill(); if (!File.Exists(FilePath)) { - using (WebClient webClient = new()) + using (HttpClient httpClient = new()) { - webClient.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", ArchivePath); + byte[] file = httpClient.GetByteArrayAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip").Result; + file.Write(ArchivePath); } ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath); diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj index e655a0e..5ff1515 100644 --- a/CreamInstaller/CreamInstaller.csproj +++ b/CreamInstaller/CreamInstaller.csproj @@ -5,7 +5,7 @@ true Resources\ini.ico true - 2.0.4.2 + 2.0.5.0 Resources\ini.ico Automatically generates and installs CreamAPI files for Steam games on the user's computer. It can also generate and install CreamAPI for the Paradox Launcher should the user select a Paradox Interactive game. diff --git a/CreamInstaller/Forms/DialogForm.cs b/CreamInstaller/Forms/DialogForm.cs index 6eecf81..5af9e24 100644 --- a/CreamInstaller/Forms/DialogForm.cs +++ b/CreamInstaller/Forms/DialogForm.cs @@ -12,13 +12,21 @@ namespace CreamInstaller Icon = Properties.Resources.Icon; } - public DialogResult Show(string formName, Icon descriptionIcon, string descriptionText, string acceptButtonText, string cancelButtonText) + public DialogResult Show(string formName, Icon descriptionIcon, string descriptionText, string acceptButtonText, string cancelButtonText = null) { icon.Image = descriptionIcon.ToBitmap(); Text = formName; descriptionLabel.Text = descriptionText; acceptButton.Text = acceptButtonText; - cancelButton.Text = cancelButtonText; + if (cancelButtonText is null) + { + cancelButton.Enabled = false; + cancelButton.Visible = false; + } + else + { + cancelButton.Text = cancelButtonText; + } return ShowDialog(); } } diff --git a/CreamInstaller/Forms/SelectForm.Designer.cs b/CreamInstaller/Forms/SelectForm.Designer.cs index 113334e..870d10f 100644 --- a/CreamInstaller/Forms/SelectForm.Designer.cs +++ b/CreamInstaller/Forms/SelectForm.Designer.cs @@ -36,12 +36,18 @@ namespace CreamInstaller this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.noneFoundLabel = new System.Windows.Forms.Label(); - this.treeView1 = new CreamInstaller.CustomTreeView(); + this.selectionTreeView = new CreamInstaller.CustomTreeView(); + this.blockProtectedHelpButton = new System.Windows.Forms.Button(); + this.blockedGamesCheckBox = new System.Windows.Forms.CheckBox(); this.allCheckBox = new System.Windows.Forms.CheckBox(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.label2 = new System.Windows.Forms.Label(); this.scanButton = new System.Windows.Forms.Button(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); this.groupBox1.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.flowLayoutPanel2.SuspendLayout(); this.SuspendLayout(); // // acceptButton @@ -80,8 +86,7 @@ namespace CreamInstaller | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Controls.Add(this.noneFoundLabel); - this.groupBox1.Controls.Add(this.treeView1); - this.groupBox1.Controls.Add(this.allCheckBox); + this.groupBox1.Controls.Add(this.selectionTreeView); this.groupBox1.Location = new System.Drawing.Point(12, 12); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(560, 308); @@ -102,28 +107,58 @@ namespace CreamInstaller this.noneFoundLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.noneFoundLabel.Visible = false; // - // treeView1 + // selectionTreeView // - this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + this.selectionTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.treeView1.BackColor = System.Drawing.SystemColors.Control; - this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.treeView1.CheckBoxes = true; - this.treeView1.Enabled = false; - this.treeView1.FullRowSelect = true; - this.treeView1.HotTracking = true; - this.treeView1.Location = new System.Drawing.Point(6, 22); - this.treeView1.Name = "treeView1"; - this.treeView1.Size = new System.Drawing.Size(548, 280); - this.treeView1.TabIndex = 1001; + this.selectionTreeView.BackColor = System.Drawing.SystemColors.Control; + this.selectionTreeView.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.selectionTreeView.CheckBoxes = true; + this.selectionTreeView.Enabled = false; + this.selectionTreeView.FullRowSelect = true; + this.selectionTreeView.HotTracking = true; + this.selectionTreeView.Location = new System.Drawing.Point(6, 22); + this.selectionTreeView.Name = "selectionTreeView"; + this.selectionTreeView.Size = new System.Drawing.Size(548, 280); + this.selectionTreeView.TabIndex = 1001; + // + // blockProtectedHelpButton + // + this.blockProtectedHelpButton.Enabled = false; + this.blockProtectedHelpButton.Font = new System.Drawing.Font("Segoe UI", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.blockProtectedHelpButton.Location = new System.Drawing.Point(151, 3); + this.blockProtectedHelpButton.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3); + this.blockProtectedHelpButton.Name = "blockProtectedHelpButton"; + this.blockProtectedHelpButton.Size = new System.Drawing.Size(19, 19); + this.blockProtectedHelpButton.TabIndex = 1004; + this.blockProtectedHelpButton.Text = "?"; + this.blockProtectedHelpButton.UseVisualStyleBackColor = true; + this.blockProtectedHelpButton.Click += new System.EventHandler(this.OnBlockProtectedGamesHelpButtonClicked); + // + // blockedGamesCheckBox + // + this.blockedGamesCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.blockedGamesCheckBox.AutoSize = true; + this.blockedGamesCheckBox.Checked = true; + this.blockedGamesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.blockedGamesCheckBox.Enabled = false; + this.blockedGamesCheckBox.Location = new System.Drawing.Point(3, 3); + this.blockedGamesCheckBox.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); + this.blockedGamesCheckBox.Name = "blockedGamesCheckBox"; + this.blockedGamesCheckBox.Size = new System.Drawing.Size(148, 19); + this.blockedGamesCheckBox.TabIndex = 1003; + this.blockedGamesCheckBox.Text = "Block Protected Games"; + this.blockedGamesCheckBox.UseVisualStyleBackColor = true; + this.blockedGamesCheckBox.CheckedChanged += new System.EventHandler(this.OnBlockProtectedGamesCheckBoxChanged); // // allCheckBox // this.allCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.allCheckBox.AutoSize = true; this.allCheckBox.Enabled = false; - this.allCheckBox.Location = new System.Drawing.Point(514, 0); + this.allCheckBox.Location = new System.Drawing.Point(3, 3); + this.allCheckBox.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.allCheckBox.Name = "allCheckBox"; this.allCheckBox.Size = new System.Drawing.Size(40, 19); this.allCheckBox.TabIndex = 1; @@ -162,12 +197,37 @@ namespace CreamInstaller this.scanButton.UseVisualStyleBackColor = true; this.scanButton.Click += new System.EventHandler(this.OnScan); // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel1.Controls.Add(this.blockedGamesCheckBox); + this.flowLayoutPanel1.Controls.Add(this.blockProtectedHelpButton); + this.flowLayoutPanel1.Location = new System.Drawing.Point(230, 9); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(173, 25); + this.flowLayoutPanel1.TabIndex = 1005; + // + // flowLayoutPanel2 + // + this.flowLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.flowLayoutPanel2.AutoSize = true; + this.flowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel2.Controls.Add(this.allCheckBox); + this.flowLayoutPanel2.Location = new System.Drawing.Point(520, 9); + this.flowLayoutPanel2.Name = "flowLayoutPanel2"; + this.flowLayoutPanel2.Size = new System.Drawing.Size(43, 25); + this.flowLayoutPanel2.TabIndex = 1006; + // // SelectForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(584, 361); + this.Controls.Add(this.flowLayoutPanel1); this.Controls.Add(this.scanButton); + this.Controls.Add(this.flowLayoutPanel2); this.Controls.Add(this.groupBox1); this.Controls.Add(this.progressBar1); this.Controls.Add(this.label1); @@ -185,8 +245,12 @@ namespace CreamInstaller this.TopMost = true; this.Load += new System.EventHandler(this.OnLoad); this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.flowLayoutPanel2.ResumeLayout(false); + this.flowLayoutPanel2.PerformLayout(); this.ResumeLayout(false); + this.PerformLayout(); } @@ -201,7 +265,11 @@ namespace CreamInstaller private System.Windows.Forms.CheckBox allCheckBox; private Button scanButton; private Label noneFoundLabel; - private CustomTreeView treeView1; + private CustomTreeView selectionTreeView; + private CheckBox blockedGamesCheckBox; + private Button blockProtectedHelpButton; + private FlowLayoutPanel flowLayoutPanel1; + private FlowLayoutPanel flowLayoutPanel2; } } diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs index 0012539..daff1e0 100644 --- a/CreamInstaller/Forms/SelectForm.cs +++ b/CreamInstaller/Forms/SelectForm.cs @@ -221,17 +221,24 @@ namespace CreamInstaller { return; } - // EasyAntiCheat detects DLL changes, so skip those games - if (Directory.Exists(directory + @"\EasyAntiCheat")) + if (Program.BlockProtectedGames) { - continue; + bool blockedGame = Program.ProtectedGameNames.Contains(name); + if (!Program.ProtectedGameDirectoryExceptions.Contains(name)) + { + foreach (string path in Program.ProtectedGameDirectories) + { + if (Directory.Exists(directory + path)) + { + blockedGame = true; + } + } + } + if (blockedGame) + { + continue; + } } - // BattlEye in DayZ detects DLL changes, but not in Arma3? - if (name != "Arma 3" && Directory.Exists(directory + @"\BattlEye")) - { - continue; - } - Task task = Task.Run(() => { if (Program.Canceled || !GetDllDirectoriesFromGameDirectory(directory, out List dllDirectories)) @@ -314,6 +321,10 @@ namespace CreamInstaller selection.SteamAppId = appId; selection.SteamApiDllDirectories = dllDirectories; selection.AppInfo = appInfo; + if (allCheckBox.Checked) + { + selection.Enabled = true; + } foreach (Task task in dlcTasks.ToList()) { @@ -329,7 +340,7 @@ namespace CreamInstaller return; } - treeView1.Invoke((MethodInvoker)delegate + selectionTreeView.Invoke((MethodInvoker)delegate { if (Program.Canceled) { @@ -341,7 +352,7 @@ namespace CreamInstaller programNode.Text = /*(appId > 0 ? $"[{appId}] " : "") +*/ name; programNode.Checked = selection.Enabled; programNode.Remove(); - treeView1.Nodes.Add(programNode); + selectionTreeView.Nodes.Add(programNode); treeNodes.Remove(programNode); treeNodes.Add(programNode); if (appId == 0) // paradox launcher @@ -357,6 +368,12 @@ namespace CreamInstaller return; } + selection.AllSteamDlc[dlcApp.Key] = dlcApp.Value; + if (allCheckBox.Checked) + { + selection.SelectedSteamDlc[dlcApp.Key] = dlcApp.Value; + } + TreeNode dlcNode = treeNodes.Find(s => s.Name == "" + dlcApp.Key) ?? new(); dlcNode.Name = "" + dlcApp.Key; dlcNode.Text = dlcApp.Value; @@ -365,7 +382,6 @@ namespace CreamInstaller programNode.Nodes.Add(dlcNode); treeNodes.Remove(dlcNode); treeNodes.Add(dlcNode); - selection.AllSteamDlc[dlcApp.Key] = dlcApp.Value; } } }); @@ -390,12 +406,14 @@ namespace CreamInstaller private async void OnLoad(bool validating = false) { Program.Canceled = false; + blockedGamesCheckBox.Enabled = false; + blockProtectedHelpButton.Enabled = false; cancelButton.Enabled = true; scanButton.Enabled = false; noneFoundLabel.Visible = false; allCheckBox.Enabled = false; acceptButton.Enabled = false; - treeView1.Enabled = false; + selectionTreeView.Enabled = false; label2.Visible = true; progressBar1.Visible = true; @@ -459,6 +477,8 @@ namespace CreamInstaller setup = false; if (!validating) { + selectionTreeView.Nodes.Clear(); + Program.ProgramSelections.Clear(); label2.Text = "Gathering and caching your applicable games and their DLCs . . . "; } @@ -479,14 +499,17 @@ namespace CreamInstaller label2.Visible = false; progressBar1.Visible = false; - treeView1.Enabled = ProgramSelection.All.Any(); - allCheckBox.Enabled = treeView1.Enabled; - noneFoundLabel.Visible = !treeView1.Enabled; + selectionTreeView.Enabled = ProgramSelection.All.Any(); + allCheckBox.Enabled = selectionTreeView.Enabled; + noneFoundLabel.Visible = !selectionTreeView.Enabled; acceptButton.Enabled = ProgramSelection.AllSafeEnabled.Any(); cancelButton.Enabled = false; scanButton.Enabled = true; + blockedGamesCheckBox.Enabled = true; + blockProtectedHelpButton.Enabled = true; + label2.Text = "Validating . . . "; if (!validating && !Program.Canceled) { @@ -567,9 +590,9 @@ namespace CreamInstaller private void OnLoad(object sender, EventArgs _) { - treeView1.TreeViewNodeSorter = new TreeNodeSorter(); - treeView1.AfterCheck += OnTreeViewNodeCheckedChanged; - treeView1.NodeMouseClick += (sender, e) => + selectionTreeView.TreeViewNodeSorter = new TreeNodeSorter(); + selectionTreeView.AfterCheck += OnTreeViewNodeCheckedChanged; + selectionTreeView.NodeMouseClick += (sender, e) => { if (e.Button == MouseButtons.Right) { @@ -685,16 +708,9 @@ namespace CreamInstaller installForm.ShowDialog(); if (installForm.Reselecting) { - foreach (TreeNode treeNode in treeNodes) - { - if (!(treeNode.Parent is null) || int.Parse(treeNode.Name) == 0) - { - OnTreeViewNodeCheckedChanged(null, new(treeNode, TreeViewAction.ByMouse)); - } - } - this.InheritLocation(installForm); Show(); + OnLoad(); } else { @@ -731,5 +747,38 @@ namespace CreamInstaller } allCheckBox.Checked = shouldCheck; } + + private void OnBlockProtectedGamesCheckBoxChanged(object sender, EventArgs e) + { + Program.BlockProtectedGames = blockedGamesCheckBox.Checked; + OnLoad(); + } + + private readonly string helpButtonListPrefix = "\n • "; + private void OnBlockProtectedGamesHelpButtonClicked(object sender, EventArgs e) + { + string blockedGames = ""; + foreach (string name in Program.ProtectedGameNames) + { + blockedGames += helpButtonListPrefix + name; + } + string blockedDirectories = ""; + foreach (string path in Program.ProtectedGameDirectories) + { + blockedDirectories += helpButtonListPrefix + path; + } + string blockedDirectoryExceptions = ""; + foreach (string name in Program.ProtectedGameDirectoryExceptions) + { + blockedDirectoryExceptions += helpButtonListPrefix + name; + } + new DialogForm(this).Show(blockedGamesCheckBox.Text, SystemIcons.Information, + "Blocks the program from caching and displaying games protected by DLL checks," + + "\nanti-cheats, or that are confirmed not to be working with CreamAPI." + + "\n\nBlocked game names:" + blockedGames + + "\n\nBlocked game sub-directories:" + blockedDirectories + + "\n\nBlocked game sub-directory exceptions (not blocked):" + blockedDirectoryExceptions, + "OK"); + } } } \ No newline at end of file diff --git a/CreamInstaller/Program.cs b/CreamInstaller/Program.cs index a2fd66f..45b25f5 100644 --- a/CreamInstaller/Program.cs +++ b/CreamInstaller/Program.cs @@ -18,6 +18,11 @@ namespace CreamInstaller public static readonly string CurrentProcessDirectory = CurrentProcessFilePath.Substring(0, CurrentProcessFilePath.LastIndexOf("\\")); public static readonly string BackupFileExtension = ".creaminstaller.backup"; + public static bool BlockProtectedGames = true; + public static readonly string[] ProtectedGameNames = { "PAYDAY 2", "Call to Arms" }; // non-functioning CreamAPI or DLL detections + public static readonly string[] ProtectedGameDirectories = { @"\EasyAntiCheat", @"\BattlEye" }; // DLL detections + public static readonly string[] ProtectedGameDirectoryExceptions = { "Arma 3" }; // Arma 3's BattlEye doesn't detect DLL changes? + [STAThread] private static void Main() {