NorbiPeti
c3c9ee0a16
Sorting mods when (un)installing Added Apply to all checkbox to a custom message box that replaces the one that shows up when the mod files already exist without the mod manager knowing about it Removing IPA.zip after unzipping Fix deleting files when their folder doesn't exist
153 lines
6.4 KiB
C#
153 lines
6.4 KiB
C#
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;
|
|
using System.Reflection;
|
|
|
|
namespace GCMM
|
|
{
|
|
partial class MainForm
|
|
{
|
|
public GameState CheckIfPatched()
|
|
{
|
|
if (GetExe() == null)
|
|
{
|
|
status.Text = "Status: Game not found";
|
|
return GameState.NotFound;
|
|
}
|
|
string pnp = "Patch && Play";
|
|
if (!File.Exists(GamePath(@"\IPA.exe")))
|
|
{
|
|
status.Text = "Status: Patcher missing\nClicking Play will install it";
|
|
playbtn.Text = pnp;
|
|
return GameState.NoPatcher;
|
|
}
|
|
if (gcipa.Updatable && !(gcipa.Version == new Version(1, 0, 0, 0) && gcipa.LatestVersion == new Version(4, 0, 0, 0)))
|
|
{
|
|
status.Text = "Status: Patcher outdated\nClicking play will update it";
|
|
playbtn.Text = pnp;
|
|
return GameState.OldPatcher;
|
|
}
|
|
string nopatch = "Status: Unpatched\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 GameState.Unpatched;
|
|
}
|
|
string backup = Directory.EnumerateDirectories(backups).OrderByDescending(name => Directory.GetLastWriteTimeUtc(name)).FirstOrDefault();
|
|
if (backup == null)
|
|
{
|
|
status.Text = nopatch;
|
|
playbtn.Text = pnp;
|
|
return GameState.Unpatched;
|
|
}
|
|
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)
|
|
|| !File.Exists(GamePath($@"\{gc}_Data\Managed\IllusionInjector.dll")))
|
|
{
|
|
status.Text = nopatch;
|
|
playbtn.Text = pnp;
|
|
return GameState.Unpatched;
|
|
}
|
|
status.Text = "Status: " + (unpatched.Checked ? "Mods disabled" : "Patched");
|
|
playbtn.Text = "Play" + (unpatched.Checked ? " unmodded" : "");
|
|
return GameState.Patched;
|
|
}
|
|
|
|
public async Task PatchStartGame()
|
|
{
|
|
if (!BeginWork()) return;
|
|
foreach (ListViewItem item in modlist.SelectedItems)
|
|
item.Selected = false;
|
|
var status = CheckIfPatched();
|
|
switch (status)
|
|
{
|
|
case GameState.NotFound:
|
|
MessageBox.Show("Gamecraft not found! Set the correct path in Settings.");
|
|
EndWork(false);
|
|
return;
|
|
case GameState.NoPatcher:
|
|
case GameState.OldPatcher:
|
|
{
|
|
if (MessageBox.Show((status == GameState.NoPatcher
|
|
? "The patcher (GCIPA) is not found. It's necessary to load the mods."
|
|
: "There is a patcher update available!"
|
|
) + "\n\nIt will be downloaded from https://git.exmods.org/modtainers/GCIPA/releases and ran to patch the game. You can validate the game to restore the original game files or simply disable mods at any time.",
|
|
"Patcher download needed", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
|
|
{
|
|
EndWork();
|
|
return;
|
|
}
|
|
this.status.Text = "Status: Patching...";
|
|
using (WebClient client = GetClient())
|
|
{
|
|
string url = gcipa.DownloadURL;
|
|
await client.DownloadFileTaskAsync(url, "IPA.zip");
|
|
using (var fs = new FileStream("IPA.zip", FileMode.Open))
|
|
using (var za = new ZipArchive(fs))
|
|
za.ExtractToDirectory(Settings.Default.GamePath, true); //Overwrite files that were left from a previous install of the patcher
|
|
File.Delete("IPA.zip");
|
|
}
|
|
}
|
|
GetInstalledMods(); //Update patcher state, should be fine for this rare event
|
|
status = CheckIfPatched();
|
|
break;
|
|
}
|
|
switch (status)
|
|
{
|
|
case GameState.NoPatcher: //Make sure it actually worked
|
|
case GameState.OldPatcher:
|
|
EndWork(false);
|
|
return;
|
|
case GameState.Unpatched:
|
|
{ //TODO: Wine
|
|
var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), GetExe() + " --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;
|
|
}
|
|
break;
|
|
case GameState.Patched:
|
|
CheckStartGame(null, null);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public enum GameState
|
|
{
|
|
NotFound,
|
|
NoPatcher,
|
|
OldPatcher,
|
|
Unpatched,
|
|
Patched
|
|
}
|
|
}
|
|
}
|