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
This commit is contained in:
parent
f271028001
commit
f522432208
4 changed files with 56 additions and 19 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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…
Reference in a new issue