Fix handling of game not found, refresh support

This commit is contained in:
Norbi Peti 2020-08-18 20:56:19 +02:00
parent 678217b281
commit 675daf1935
6 changed files with 144 additions and 68 deletions

View file

@ -49,6 +49,7 @@
this.findlog = new System.Windows.Forms.Button(); this.findlog = new System.Windows.Forms.Button();
this.unpatched = new System.Windows.Forms.CheckBox(); this.unpatched = new System.Windows.Forms.CheckBox();
this.modinfobox = new System.Windows.Forms.RichTextBox(); this.modinfobox = new System.Windows.Forms.RichTextBox();
this.refreshbtn = new System.Windows.Forms.Button();
this.SuspendLayout(); this.SuspendLayout();
// //
// modlist // modlist
@ -79,9 +80,9 @@
listViewItem1.Group = listViewGroup1; listViewItem1.Group = listViewGroup1;
this.modlist.Items.AddRange(new System.Windows.Forms.ListViewItem[] { this.modlist.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1}); listViewItem1});
this.modlist.Location = new System.Drawing.Point(12, 12); this.modlist.Location = new System.Drawing.Point(12, 47);
this.modlist.Name = "modlist"; this.modlist.Name = "modlist";
this.modlist.Size = new System.Drawing.Size(491, 468); this.modlist.Size = new System.Drawing.Size(491, 433);
this.modlist.TabIndex = 0; this.modlist.TabIndex = 0;
this.modlist.UseCompatibleStateImageBehavior = false; this.modlist.UseCompatibleStateImageBehavior = false;
this.modlist.View = System.Windows.Forms.View.Details; this.modlist.View = System.Windows.Forms.View.Details;
@ -220,12 +221,27 @@
this.modinfobox.TabIndex = 9; this.modinfobox.TabIndex = 9;
this.modinfobox.Text = ""; this.modinfobox.Text = "";
// //
// refreshbtn
//
this.refreshbtn.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Green;
this.refreshbtn.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(40)))), ((int)(((byte)(0)))));
this.refreshbtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.refreshbtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.refreshbtn.Location = new System.Drawing.Point(12, 12);
this.refreshbtn.Name = "refreshbtn";
this.refreshbtn.Size = new System.Drawing.Size(81, 29);
this.refreshbtn.TabIndex = 10;
this.refreshbtn.Text = "Refresh";
this.refreshbtn.UseVisualStyleBackColor = true;
this.refreshbtn.Click += new System.EventHandler(this.refreshbtn_Click);
//
// MainForm // MainForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black; this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(784, 561); this.ClientSize = new System.Drawing.Size(784, 561);
this.Controls.Add(this.refreshbtn);
this.Controls.Add(this.modinfobox); this.Controls.Add(this.modinfobox);
this.Controls.Add(this.unpatched); this.Controls.Add(this.unpatched);
this.Controls.Add(this.findlog); this.Controls.Add(this.findlog);
@ -260,6 +276,7 @@
private System.Windows.Forms.Button findlog; private System.Windows.Forms.Button findlog;
private System.Windows.Forms.CheckBox unpatched; private System.Windows.Forms.CheckBox unpatched;
private System.Windows.Forms.RichTextBox modinfobox; private System.Windows.Forms.RichTextBox modinfobox;
private System.Windows.Forms.Button refreshbtn;
} }
} }

View file

@ -72,9 +72,7 @@ You may also want to verify the game's files by right clicking the game in Steam
DeleteEmptyPluginsDir(out bool pexists, out bool dexists); DeleteEmptyPluginsDir(out bool pexists, out bool dexists);
if (!pexists && dexists) if (!pexists && dexists)
unpatched.Checked = true; //It will call the event but that won't do anything unpatched.Checked = true; //It will call the event but that won't do anything
CheckIfPatched(); refreshbtn_Click(refreshbtn, null);
GetInstalledMods();
GetAvailableMods();
} }
private async void playbtn_Click(object sender, EventArgs e) private async void playbtn_Click(object sender, EventArgs e)
@ -183,12 +181,16 @@ You may also want to verify the game's files by right clicking the game in Steam
{ {
if (Environment.OSVersion.Platform == PlatformID.Win32NT) if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{ {
Process.Start("explorer.exe", $@"/select,{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}Low\Freejam\{GetExe().Replace(".exe", "")}\Player.log"); if (CheckNoExe(out string exe))
return;
Process.Start("explorer.exe", $@"/select,{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}Low\Freejam\{exe.Replace(".exe", "")}\Player.log");
} }
} }
private void unpatched_CheckedChanged(object sender, EventArgs e) private void unpatched_CheckedChanged(object sender, EventArgs e)
{ //Not using the patcher's revert option because sometimes it restores the wrong files - the game can be patched without mods { //Not using the patcher's revert option because sometimes it restores the wrong files - the game can be patched without mods
if (CheckNoExe())
return;
CheckIfPatched(); CheckIfPatched();
modlist_SelectedIndexChanged(modlist, null); modlist_SelectedIndexChanged(modlist, null);
string plugins = GamePath("\\Plugins"); string plugins = GamePath("\\Plugins");
@ -231,5 +233,13 @@ You may also want to verify the game's files by right clicking the game in Steam
dexists = false; dexists = false;
} }
} }
private void refreshbtn_Click(object sender, EventArgs e)
{
CheckIfPatched();
var mods = GetInstalledMods();
GetAvailableMods();
CheckUninstalledMods(mods);
}
} }
} }

View file

@ -16,11 +16,8 @@ namespace GCMM
public async Task InstallMod(ModInfo mod) public async Task InstallMod(ModInfo mod)
{ {
if (mod.DownloadURL == null) return; if (mod.DownloadURL == null) return;
if (GetExe() == null) if (CheckNoExe())
{
MessageBox.Show("Gamecraft not found. Set the correct path in Settings.");
return; return;
}
if (mod.Name != "GamecraftModdingAPI") if (mod.Name != "GamecraftModdingAPI")
await UpdateAPI(); await UpdateAPI();
var tmp = Directory.CreateDirectory("temp"); var tmp = Directory.CreateDirectory("temp");
@ -140,6 +137,8 @@ namespace GCMM
public async Task UpdateAPI() public async Task UpdateAPI()
{ {
if (!mods.ContainsKey("GamecraftModdingAPI"))
return;
var gcmapi = mods["GamecraftModdingAPI"]; var gcmapi = mods["GamecraftModdingAPI"];
if (!gcmapi.Installed || gcmapi.Updatable) if (!gcmapi.Installed || gcmapi.Updatable)
{ {

View file

@ -17,13 +17,14 @@ namespace GCMM
partial class MainForm partial class MainForm
{ {
public void GetInstalledMods() public HashSet<string> GetInstalledMods()
{ {
bool disabled = false; bool disabled = false;
if (!Directory.Exists(GamePath("\\Plugins"))) if (!Directory.Exists(GamePath("\\Plugins")))
if (Directory.Exists(GamePath("\\Plugins_Disabled"))) if (Directory.Exists(GamePath("\\Plugins_Disabled")))
disabled = true; disabled = true;
else return; else return new HashSet<string>();
var installed = new HashSet<string>();
foreach (var modPath in Directory.GetFiles(GamePath(disabled ? @"\Plugins_Disabled" : @"\Plugins"), "*.dll")) foreach (var modPath in Directory.GetFiles(GamePath(disabled ? @"\Plugins_Disabled" : @"\Plugins"), "*.dll"))
{ {
try try
@ -31,12 +32,15 @@ namespace GCMM
var an = AssemblyName.GetAssemblyName(modPath); var an = AssemblyName.GetAssemblyName(modPath);
if (an.Name == "0Harmony") continue; if (an.Name == "0Harmony") continue;
//Use filename to avoid differences between repository & assembly name casing //Use filename to avoid differences between repository & assembly name casing
AddUpdateModInList(new ModInfo { Name = Path.GetFileNameWithoutExtension(modPath), Version = an.Version, LastUpdated = File.GetLastWriteTime(modPath) }); var mod = new ModInfo { Name = Path.GetFileNameWithoutExtension(modPath), Version = an.Version, LastUpdated = File.GetLastWriteTime(modPath) };
AddUpdateModInList(mod);
installed.Add(mod.Name);
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ //Not a .NET assembly { //Not a .NET assembly
} }
} }
return installed;
} }
public async void GetAvailableMods() public async void GetAvailableMods()
@ -127,7 +131,7 @@ namespace GCMM
item = modlist.Items[mod.Name]; item = modlist.Items[mod.Name];
var items = item.SubItems; var items = item.SubItems;
omod.Author = mod.Author ?? omod.Author; omod.Author = mod.Author ?? omod.Author;
omod.Version = mod.Version ?? omod.Version; omod.Version = mod.Version ?? omod.Version; //If the object comes from the dictionary then it's directly modified (uninstall)
omod.LatestVersion = mod.LatestVersion ?? omod.LatestVersion; omod.LatestVersion = mod.LatestVersion ?? omod.LatestVersion;
omod.LastUpdated = mod.LastUpdated == default ? omod.LastUpdated : mod.LastUpdated; omod.LastUpdated = mod.LastUpdated == default ? omod.LastUpdated : mod.LastUpdated;
omod.Description = mod.Description ?? omod.Description; omod.Description = mod.Description ?? omod.Description;
@ -152,10 +156,14 @@ namespace GCMM
item.ForeColor = modlist.ForeColor; item.ForeColor = modlist.ForeColor;
} }
public void RemoveModFromList(ModInfo mod) public void CheckUninstalledMods(HashSet<string> installed)
{ {
if (mods.Remove(mod.Name)) foreach (string name in mods.Keys.Except(installed))
modlist.Items.RemoveByKey(mod.Name); {
var mod = mods[name];
mod.Version = null;
AddUpdateModInList(mod);
}
} }
} }
} }

View file

@ -15,14 +15,19 @@ namespace GCMM
{ {
partial class MainForm partial class MainForm
{ {
public bool? CheckIfPatched() public GameState CheckIfPatched()
{ {
if (GetExe() == null)
{
status.Text = "Status: Game not found";
return GameState.NotFound;
}
string pnp = "Patch && Play"; string pnp = "Patch && Play";
if (!File.Exists(GamePath(@"\IPA.exe"))) if (!File.Exists(GamePath(@"\IPA.exe")))
{ {
status.Text = "Status: Patcher missing\nClicking Play will install it"; status.Text = "Status: Patcher missing\nClicking Play will install it";
playbtn.Text = pnp; playbtn.Text = pnp;
return null; return GameState.NoPatcher;
} }
string nopatch = "Status: Unpatched\nClicking Play patches it"; string nopatch = "Status: Unpatched\nClicking Play patches it";
string gc = GetExe().Replace(".exe", ""); string gc = GetExe().Replace(".exe", "");
@ -31,14 +36,14 @@ namespace GCMM
{ {
status.Text = nopatch; status.Text = nopatch;
playbtn.Text = pnp; playbtn.Text = pnp;
return false; return GameState.Unpatched;
} }
string backup = Directory.EnumerateDirectories(backups).OrderByDescending(s => s).FirstOrDefault(); string backup = Directory.EnumerateDirectories(backups).OrderByDescending(s => s).FirstOrDefault();
if (backup == null) if (backup == null)
{ {
status.Text = nopatch; status.Text = nopatch;
playbtn.Text = pnp; playbtn.Text = pnp;
return false; return GameState.Unpatched;
} }
if (File.GetLastWriteTime(GamePath($@"\{gc}_Data\Managed\Assembly-CSharp.dll")) if (File.GetLastWriteTime(GamePath($@"\{gc}_Data\Managed\Assembly-CSharp.dll"))
> //If the file was updated at least 2 minutes after patching > //If the file was updated at least 2 minutes after patching
@ -46,11 +51,11 @@ namespace GCMM
{ {
status.Text = nopatch; status.Text = nopatch;
playbtn.Text = pnp; playbtn.Text = pnp;
return false; return GameState.Unpatched;
} }
status.Text = "Status: " + (unpatched.Checked ? "Mods disabled" : "Patched"); status.Text = "Status: " + (unpatched.Checked ? "Mods disabled" : "Patched");
playbtn.Text = "Play" + (unpatched.Checked ? " unmodded" : ""); playbtn.Text = "Play" + (unpatched.Checked ? " unmodded" : "");
return true; return GameState.Patched;
} }
public async Task PatchStartGame() public async Task PatchStartGame()
@ -58,7 +63,14 @@ namespace GCMM
if (!BeginWork()) return; if (!BeginWork()) return;
foreach (ListViewItem item in modlist.SelectedItems) foreach (ListViewItem item in modlist.SelectedItems)
item.Selected = false; item.Selected = false;
if (!CheckIfPatched().HasValue) 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:
{ {
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) 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) == DialogResult.Cancel)
@ -76,13 +88,16 @@ namespace GCMM
ZipFile.ExtractToDirectory("IPA.zip", Settings.Default.GamePath); ZipFile.ExtractToDirectory("IPA.zip", Settings.Default.GamePath);
} }
} }
bool? status = CheckIfPatched(); break;
if (!status.HasValue) //Make sure it actually worked }
if (status != GameState.NotFound && status != GameState.NoPatcher)
status = CheckIfPatched();
switch (status)
{ {
case GameState.NoPatcher: //Make sure it actually worked
EndWork(false); EndWork(false);
return; return;
} case GameState.Unpatched:
if (!status.Value)
{ //TODO: Wine { //TODO: Wine
var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), GetExe() + " --nowait") var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), GetExe() + " --nowait")
{ {
@ -105,8 +120,19 @@ namespace GCMM
process.ErrorDataReceived += onoutput; process.ErrorDataReceived += onoutput;
process.Exited += CheckStartGame; process.Exited += CheckStartGame;
} }
else break;
case GameState.Patched:
CheckStartGame(null, null); CheckStartGame(null, null);
break;
}
}
public enum GameState
{
NotFound,
NoPatcher,
Unpatched,
Patched
} }
} }
} }

View file

@ -76,7 +76,7 @@ namespace GCMM
status.Text = "Status: Patching failed"; status.Text = "Status: Patching failed";
return; return;
} }
if ((CheckIfPatched() ?? false) || unpatched.Checked) if (CheckIfPatched() == GameState.Patched || unpatched.Checked)
if (Environment.OSVersion.Platform == PlatformID.Win32NT) if (Environment.OSVersion.Platform == PlatformID.Win32NT)
Process.Start("steam://run/1078000/"); Process.Start("steam://run/1078000/");
else else
@ -144,5 +144,21 @@ namespace GCMM
return "GamecraftPreview.exe"; return "GamecraftPreview.exe";
return null; return null;
} }
private bool CheckNoExe()
{
return CheckNoExe(out _);
}
private bool CheckNoExe(out string path)
{
path = GetExe();
if (path == null)
{
MessageBox.Show("Gamecraft not found! Set the correct path in Settings.");
return true;
}
return false;
}
} }
} }