Browse Source

Fix DLL conflicts, support updating GCIPA

If the mod consists of a dll then it failed to update it because it already existed
Added support for updating GCIPA, using both the existing mod info fetching and the patcher downloading code
tags/v1.3.0
NorbiPeti 3 years ago
parent
commit
f522432208
4 changed files with 56 additions and 19 deletions
  1. +7
    -5
      GCMM/MainForm.cs
  2. +6
    -1
      GCMM/MainModInstaller.cs
  3. +26
    -9
      GCMM/MainModList.cs
  4. +17
    -4
      GCMM/MainPatcher.cs

+ 7
- 5
GCMM/MainForm.cs View File

@@ -22,8 +22,9 @@ namespace GCMM
InitializeComponent();
}

private Dictionary<string, ModInfo> mods = new Dictionary<string, ModInfo>();
private string defaultInfo = @"
private readonly Dictionary<string, ModInfo> mods = new Dictionary<string, ModInfo>();
private readonly ModInfo gcipa = new ModInfo { Author = "modtainers", Name = "GCIPA" };
private const string defaultInfo = @"
Gamecraft Mod Manager

If you click on a mod it will show some info about it. The install instructions there are usually for manual installs.
@@ -234,12 +235,13 @@ You may also want to verify the game's files by right clicking the game in Steam
}
}

private void refreshbtn_Click(object sender, EventArgs e)
private async void refreshbtn_Click(object sender, EventArgs e)
{
CheckIfPatched();
CheckIfPatched(); //Set from placeholder
var mods = GetInstalledMods();
GetAvailableMods();
await GetAvailableMods();
CheckUninstalledMods(mods);
CheckIfPatched(); //Check after getting the available mods to show GCIPA updates
}

private void validatebtn_Click(object sender, EventArgs e)


+ 6
- 1
GCMM/MainModInstaller.cs View File

@@ -29,7 +29,12 @@ namespace GCMM
string disposition = client.ResponseHeaders["Content-Disposition"];
string filename = disposition.Substring(disposition.IndexOf("filename=") + 10).Replace("\"", "");
if (filename.EndsWith(".dll"))
File.Move(tmppath, plugins.FullName + Path.DirectorySeparatorChar + mod.Name + ".dll"); //Force mod name to make uninstalls & identifying easier
{
string name = plugins.FullName + Path.DirectorySeparatorChar + mod.Name + ".dll"; //Force mod name to make uninstalls & identifying easier
if (File.Exists(name))
File.Delete(name);
File.Move(tmppath, name);
}
else if (filename.EndsWith(".zip"))
{
bool pluginOnly = true;


+ 26
- 9
GCMM/MainModList.cs View File

@@ -40,10 +40,23 @@ namespace GCMM
{ //Not a .NET assembly
}
}
try
{
string ipath = GamePath("\\IPA.exe"); //Heh
if (File.Exists(ipath))
{
var an = AssemblyName.GetAssemblyName(ipath);
gcipa.Version = an.Version;
gcipa.LastUpdated = File.GetLastWriteTime(ipath);
}
}
catch (BadImageFormatException)
{ //Not a .NET assembly
}
return installed;
}

public async void GetAvailableMods()
public async Task GetAvailableMods()
{
bool preview = GetExe()?.Contains("Preview") ?? false;
using (var client = GetClient())
@@ -58,13 +71,14 @@ namespace GCMM
Author = sp[0].Trim(),
Name = sp[1].Trim()
};
if (await FetchModInfo(mod, preview)) //If it's actually a mod
if (await FetchModInfo(mod, preview, true)) //If it's actually a mod
AddUpdateModInList(mod);
}
}
await FetchModInfo(gcipa, preview, false);
}

public async Task<bool> FetchModInfo(ModInfo mod, bool preview)
public async Task<bool> FetchModInfo(ModInfo mod, bool preview, bool desc)
{
string repoURL = "/api/v1/repos/" + mod.Author + "/" + mod.Name + "/releases";
using (var client = GetClient())
@@ -108,13 +122,16 @@ namespace GCMM
int getver(byte i) => ver.Length > i ? ver[i] : 0; //By default it sets values not present to -1, but we need them to be 0
mod.LatestVersion = new Version(getver(0), getver(1), getver(2), getver(3));
mod.UpdateDetails = release["name"] + "\n\n" + release["body"].ToString();
try
if (desc)
{
var obj = JObject.Parse(await client.DownloadStringTaskAsync("/api/v1/repos/" + mod.Author + "/" + mod.Name + "/contents/README.md"));
mod.Description = Encoding.UTF8.GetString(Convert.FromBase64String(obj["content"].ToString()));
}
catch(WebException)
{ //It returns a HTTP 500 if it doesn't exist...
try
{
var obj = JObject.Parse(await client.DownloadStringTaskAsync("/api/v1/repos/" + mod.Author + "/" + mod.Name + "/contents/README.md"));
mod.Description = Encoding.UTF8.GetString(Convert.FromBase64String(obj["content"].ToString()));
}
catch (WebException)
{ //It returns a HTTP 500 if it doesn't exist...
}
}
return true;
}


+ 17
- 4
GCMM/MainPatcher.cs View File

@@ -10,6 +10,7 @@ using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;

namespace GCMM
{
@@ -29,6 +30,12 @@ namespace GCMM
playbtn.Text = pnp;
return GameState.NoPatcher;
}
if (gcipa.Updatable)
{
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);
@@ -71,31 +78,36 @@ namespace GCMM
EndWork(false);
return;
case GameState.NoPatcher:
case GameState.OldPatcher:
{
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)
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;
}
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();
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
}
}
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:
@@ -132,6 +144,7 @@ namespace GCMM
{
NotFound,
NoPatcher,
OldPatcher,
Unpatched,
Patched
}


Loading…
Cancel
Save