using GCMM.Properties; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO.Compression; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace GCMM { partial class MainForm { public bool? CheckIfPatched() { string pnp = unpatched.Checked ? "Play" : "Patch && Play"; if (!File.Exists(GamePath(@"\IPA.exe"))) { status.Text = "Status: Patcher missing\nClicking Play will install it"; playbtn.Text = pnp; return null; } string nopatch = "Status: Unpatched" + (unpatched.Checked ? "" : "\nClicking Play patches it"); string gc = GetExe().Replace(".exe", ""); string backups = GamePath(@"\IPA\Backups\" + gc); if (!Directory.Exists(backups)) { status.Text = nopatch; playbtn.Text = pnp; return false; } string backup = Directory.EnumerateDirectories(backups).OrderByDescending(s => s).FirstOrDefault(); if (backup == null) { status.Text = nopatch; playbtn.Text = pnp; return false; } if (File.GetLastWriteTime(GamePath($@"\{gc}_Data\Managed\Assembly-CSharp.dll")) > //If the file was updated at least 2 minutes after patching Directory.GetLastWriteTime(backup).AddMinutes(2)) { status.Text = nopatch; playbtn.Text = pnp; return false; } status.Text = "Status: Patched" + (unpatched.Checked ? "\nClicking Play unpatches it" : ""); playbtn.Text = unpatched.Checked ? "Unpatch && Play" : "Play"; return true; } public async Task PatchStartGame() { if (!BeginWork()) return; foreach (ListViewItem item in modlist.SelectedItems) item.Selected = false; if (!CheckIfPatched().HasValue) { if (MessageBox.Show("The patcher (GCIPA) is not found. It's necessary to load the mods. It will be downloaded from https://git.exmods.org/modtainers/GCIPA/releases and ran to patch the game. You can unpatch to run without mods at any time.", "Patcher download needed", MessageBoxButtons.OKCancel) == DialogResult.Cancel) { EndWork(); return; } string releases = "/api/v1/repos/modtainers/GCIPA/releases"; string url; this.status.Text = "Status: Patching..."; using (WebClient client = GetClient()) { url = JArray.Parse(await client.DownloadStringTaskAsync(releases)).First["assets"].First["browser_download_url"].ToString(); await client.DownloadFileTaskAsync(url, "IPA.zip"); ZipFile.ExtractToDirectory("IPA.zip", Settings.Default.GamePath); } } bool? status = CheckIfPatched(); if (!status.HasValue) //Make sure it actually worked { EndWork(false); return; } if (!status.Value ^ unpatched.Checked) { //TODO: Wine var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), GetExe() + " " + (unpatched.Checked ? "--revert " : "") + "--nowait") { UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, WorkingDirectory = Settings.Default.GamePath, 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); } } }