NorbiPeti
e69b357da1
Handling "install and update" button label Fixed mod updating New version detection fixed, highlighting and showing a message in the info section Showing release information for mods that have a new version available Added information about mod requirements Added a button to find the game log Added a checkbox to run the game unpatched Added information about using the program
131 lines
5.6 KiB
C#
131 lines
5.6 KiB
C#
using GCMM.Properties;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace GCMM
|
|
{
|
|
partial class MainForm
|
|
{
|
|
public async Task InstallMod(ModInfo mod)
|
|
{
|
|
if (mod.DownloadURL == null) return;
|
|
if (!File.Exists(Settings.Default.GamePath + @"\Gamecraft.exe"))
|
|
{
|
|
MessageBox.Show("Gamecraft not found. Set the correct path in Settings.");
|
|
return;
|
|
}
|
|
var tmp = Directory.CreateDirectory("temp");
|
|
var plugins = Directory.CreateDirectory(Settings.Default.GamePath + @"\Plugins");
|
|
string tmppath = tmp.FullName + "\\" + mod.Name;
|
|
using (var client = GetClient())
|
|
{
|
|
await client.DownloadFileTaskAsync(mod.DownloadURL, tmppath);
|
|
string disposition = client.ResponseHeaders["Content-Disposition"];
|
|
string filename = disposition.Substring(disposition.IndexOf("filename=") + 10).Replace("\"", "");
|
|
if (filename.EndsWith(".dll"))
|
|
File.Move(tmppath, plugins.FullName + "\\" + mod.Name + ".dll"); //Force mod name to make uninstalls & identifying easier
|
|
else if (filename.EndsWith(".zip"))
|
|
{
|
|
bool pluginOnly = true;
|
|
using (var archive = ZipFile.OpenRead(tmppath))
|
|
{
|
|
bool modFound = false;
|
|
foreach (var entry in archive.Entries)
|
|
{
|
|
if (entry.FullName == "Plugins/")
|
|
pluginOnly = false;
|
|
if (entry.FullName == "Plugins/" + mod.Name + ".dll")
|
|
modFound = true;
|
|
if (!pluginOnly && modFound) break;
|
|
}
|
|
if (!modFound && !pluginOnly)
|
|
if (MessageBox.Show("The mod was not found in the downloaded archive. It likely means it's using a different name for the dll file. The mod manager will not be able to track this mod if you continue. Do you want to continue?", "Mod not found in archive", MessageBoxButtons.YesNo) == DialogResult.No)
|
|
return;
|
|
ExtractMod(archive, pluginOnly ? plugins.FullName : Settings.Default.GamePath, mod);
|
|
}
|
|
File.Delete(tmppath);
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Don't know how to install file: " + filename);
|
|
return;
|
|
}
|
|
GetInstalledMods(); //Update list
|
|
}
|
|
}
|
|
|
|
public void ExtractMod(ZipArchive archive, string destinationDirectoryName, ModInfo mod)
|
|
{
|
|
LoadFileList(mod);
|
|
DirectoryInfo di = Directory.CreateDirectory(destinationDirectoryName);
|
|
string destinationDirectoryFullPath = di.FullName;
|
|
|
|
foreach (ZipArchiveEntry file in archive.Entries)
|
|
{
|
|
string completeFileName = Path.GetFullPath(Path.Combine(destinationDirectoryFullPath, file.FullName));
|
|
|
|
if (!completeFileName.StartsWith(destinationDirectoryFullPath, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
throw new IOException("Trying to extract file outside of destination directory. See this link for more info: https://snyk.io/research/zip-slip-vulnerability");
|
|
}
|
|
|
|
if (file.Name == "")
|
|
{// Assuming Empty for Directory
|
|
Directory.CreateDirectory(Path.GetDirectoryName(completeFileName));
|
|
continue;
|
|
}
|
|
|
|
if (File.Exists(completeFileName) && !mod.ModFiles.Contains(completeFileName))
|
|
{ //If it's part of the mod files, then it's an update and it didn't originally exist in the game
|
|
MessageBox.Show("The mod zip contains a file that exists as part of the game. Skipping file: " + file.FullName);
|
|
continue;
|
|
}
|
|
|
|
mod.ModFiles.Add(completeFileName);
|
|
file.ExtractToFile(completeFileName, true);
|
|
}
|
|
SaveFileList(mod);
|
|
}
|
|
|
|
public void SaveFileList(ModInfo mod)
|
|
{
|
|
if (mod.ModFiles != null)
|
|
File.WriteAllText(mod.Name + ".json", JsonConvert.SerializeObject(mod.ModFiles));
|
|
}
|
|
|
|
public void LoadFileList(ModInfo mod)
|
|
{
|
|
if (File.Exists(mod.Name + ".json"))
|
|
mod.ModFiles = JsonConvert.DeserializeObject<HashSet<string>>(File.ReadAllText(mod.Name + ".json"));
|
|
else
|
|
mod.ModFiles = new HashSet<string>();
|
|
}
|
|
|
|
public void UninstallMod(ModInfo mod)
|
|
{
|
|
LoadFileList(mod);
|
|
if (mod.ModFiles.Count == 0) //A single DLL
|
|
File.Delete(Settings.Default.GamePath + @"\Plugins\" + mod.Name + ".dll");
|
|
else //A ZIP
|
|
{
|
|
foreach (string file in mod.ModFiles)
|
|
{
|
|
File.Delete(file);
|
|
var parent = Directory.GetParent(file);
|
|
if (!parent.EnumerateFiles().Any())
|
|
parent.Delete();
|
|
}
|
|
}
|
|
File.Delete(mod.Name + ".json");
|
|
mod.Version = null; //Not installed
|
|
AddUpdateModInList(mod); //Update list
|
|
}
|
|
}
|
|
}
|