diff --git a/GCMM/GCMM.csproj b/GCMM/GCMM.csproj index de80f0f..c4f3c1f 100644 --- a/GCMM/GCMM.csproj +++ b/GCMM/GCMM.csproj @@ -6,6 +6,14 @@ true + + + + + + + + Form diff --git a/GCMM/MainForm.Designer.cs b/GCMM/MainForm.Designer.cs index 6ee7fb1..612bcee 100644 --- a/GCMM/MainForm.Designer.cs +++ b/GCMM/MainForm.Designer.cs @@ -28,9 +28,9 @@ /// private void InitializeComponent() { - System.Windows.Forms.ListViewGroup listViewGroup9 = new System.Windows.Forms.ListViewGroup("Installed", System.Windows.Forms.HorizontalAlignment.Center); - System.Windows.Forms.ListViewGroup listViewGroup10 = new System.Windows.Forms.ListViewGroup("Available", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem(new string[] { + System.Windows.Forms.ListViewGroup listViewGroup13 = new System.Windows.Forms.ListViewGroup("Installed", System.Windows.Forms.HorizontalAlignment.Center); + System.Windows.Forms.ListViewGroup listViewGroup14 = new System.Windows.Forms.ListViewGroup("Available", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewItem listViewItem7 = new System.Windows.Forms.ListViewItem(new string[] { "Mod", "1.0", "2020.06.15. 2:01:43", @@ -63,19 +63,19 @@ this.latestVersion}); this.modlist.ForeColor = System.Drawing.Color.Green; this.modlist.FullRowSelect = true; - listViewGroup9.Header = "Installed"; - listViewGroup9.HeaderAlignment = System.Windows.Forms.HorizontalAlignment.Center; - listViewGroup9.Name = "installed"; - listViewGroup10.Header = "Available"; - listViewGroup10.Name = "available"; + listViewGroup13.Header = "Installed"; + listViewGroup13.HeaderAlignment = System.Windows.Forms.HorizontalAlignment.Center; + listViewGroup13.Name = "installed"; + listViewGroup14.Header = "Available"; + listViewGroup14.Name = "available"; this.modlist.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] { - listViewGroup9, - listViewGroup10}); + listViewGroup13, + listViewGroup14}); this.modlist.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.modlist.HideSelection = false; - listViewItem5.Group = listViewGroup9; + listViewItem7.Group = listViewGroup13; this.modlist.Items.AddRange(new System.Windows.Forms.ListViewItem[] { - listViewItem5}); + listViewItem7}); this.modlist.Location = new System.Drawing.Point(12, 12); this.modlist.Name = "modlist"; this.modlist.Size = new System.Drawing.Size(491, 468); diff --git a/GCMM/MainForm.cs b/GCMM/MainForm.cs index 1a067a2..ed98267 100644 --- a/GCMM/MainForm.cs +++ b/GCMM/MainForm.cs @@ -1,12 +1,13 @@ using GCMM.Properties; +using Newtonsoft.Json.Linq; using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; +using System.Diagnostics; using System.Drawing; using System.IO; +using System.IO.Compression; using System.Linq; -using System.Text; +using System.Net; +using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; @@ -34,6 +35,13 @@ namespace GCMM MessageBox.Show("Found game at " + Settings.Default.GamePath); Settings.Default.Save(); } + if(string.IsNullOrWhiteSpace(Settings.Default.GamePath)) + { + status.Text = "Status: Game not found"; + return; + } + CheckIfPatched(); + GetInstalledMods(); } public void UpdateButton(Button button, bool enabled) @@ -88,13 +96,129 @@ namespace GCMM return Directory.GetParent(ofd.FileName).FullName; } - private void playbtn_Click(object sender, EventArgs e) + public void GetInstalledMods() { + foreach (var mod in Directory.GetFiles(Settings.Default.GamePath + @"\Plugins", "*.dll")) + { + try + { + var an = AssemblyName.GetAssemblyName(mod); + if (an.Name == "0Harmony") continue; + modlist.Items.Add(new ListViewItem(new[] { an.Name, an.Version.ToString(), File.GetLastWriteTime(mod).ToString(), "" }, modlist.Groups["installed"])); + } + catch (BadImageFormatException) + { //Not a .NET assembly + } + } + } + public bool? CheckIfPatched() + { + if (!File.Exists(Settings.Default.GamePath + @"\IPA.exe")) + { + status.Text = "Status: Patcher missing\nInstalling a mod downloads it"; + return null; + } + string nopatch = "Status: Unpatched\nClick play"; + if (!Directory.Exists(Settings.Default.GamePath + @"\IPA\Backups\Gamecraft")) + { + status.Text = nopatch; + return false; + } + string backup = Directory.EnumerateDirectories(Settings.Default.GamePath + @"\IPA\Backups\Gamecraft").OrderByDescending(s => s).FirstOrDefault(); + if (backup == null) + { + status.Text = nopatch; + return false; + } + if (File.GetLastWriteTime(Settings.Default.GamePath + @"\Gamecraft_Data\Managed\Assembly-CSharp.dll") + > //If the file was updated at least a minute after patching + Directory.GetLastWriteTime(backup).AddMinutes(1)) + { + status.Text = nopatch; + return false; + } + status.Text = "Status: Patched"; + return true; + } + + public async void PatchGame() + { + UpdateButton(playbtn, false); + UpdateButton(installbtn, false); + UpdateButton(uninstallbtn, false); + UpdateButton(settingsbtn, false); + if (!CheckIfPatched().HasValue) + { + if (MessageBox.Show("The patcher (GCIPA) is not found. It will be downloaded from https://git.exmods.org/modtainers/GCIPA/releases and ran to patch the game.", "Patcher download needed", MessageBoxButtons.OKCancel) + == DialogResult.Cancel) + return; + string releases = "https://git.exmods.org/api/v1/repos/modtainers/GCIPA/releases"; + string url; + this.status.Text = "Status: Patching..."; + await Task.Run(() => + { + using (WebClient client = new WebClient()) + { + url = JArray.Parse(client.DownloadString(releases)).First["assets"].First["browser_download_url"].ToString(); + client.DownloadFile(url, "IPA.zip"); + ZipFile.ExtractToDirectory("IPA.zip", Settings.Default.GamePath); + } + }); + } + bool? status = CheckIfPatched(); + if (!status.HasValue) //Make sure it actually worked + return; + if (!status.Value) + { + var psi = new ProcessStartInfo(Settings.Default.GamePath + @"\IPA.exe", "Gamecraft.exe --nowait"); + psi.UseShellExecute = false; + psi.RedirectStandardError = true; + psi.RedirectStandardOutput = true; + psi.WorkingDirectory = Settings.Default.GamePath; + psi.CreateNoWindow = true; + var process = Process.Start(psi); + process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + process.EnableRaisingEvents = true; + modinfobox.Text = ""; + DataReceivedEventHandler onoutput = (sender, e) => + { + Invoke((Action)(() => modinfobox.Text += e.Data + Environment.NewLine)); + }; + process.OutputDataReceived += onoutput; + process.ErrorDataReceived += onoutput; + process.Exited += CheckStartGame; + } + else + CheckStartGame(null, null); + } + + private void CheckStartGame(object sender, EventArgs e) + { + Action act = () => + { + if ((sender as Process).ExitCode != 0) + { + status.Text = "Status: Patching failed"; + return; + } + if (CheckIfPatched() ?? false) + Process.Start("steam://run/1078000/"); + }; + if (InvokeRequired) + Invoke(act); + } + + private void playbtn_Click(object sender, EventArgs e) + { + if (playbtn.ForeColor == Color.Green) return; //Disabled + PatchGame(); } private void settingsbtn_Click(object sender, EventArgs e) { + if (settingsbtn.ForeColor == Color.Green) return; //Disabled var sf = new SettingsForm(); sf.ShowDialog(this); }