diff --git a/GCMM/MainModder.cs b/GCMM/MainModder.cs index c617110..4401ff9 100644 --- a/GCMM/MainModder.cs +++ b/GCMM/MainModder.cs @@ -2,6 +2,7 @@ using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.Drawing; using System.IO; using System.Linq; using System.Reflection; @@ -16,15 +17,13 @@ namespace GCMM public void GetInstalledMods() { - foreach (var mod in Directory.GetFiles(Settings.Default.GamePath + @"\Plugins", "*.dll")) + foreach (var modPath in Directory.GetFiles(Settings.Default.GamePath + @"\Plugins", "*.dll")) { try { - var an = AssemblyName.GetAssemblyName(mod); + var an = AssemblyName.GetAssemblyName(modPath); if (an.Name == "0Harmony") continue; - var item = new ListViewItem(new[] { an.Name, "", an.Version.ToString(), File.GetLastWriteTime(mod).ToString() }, modlist.Groups["installed"]); - item.Name = an.Name; - modlist.Items.Add(item); + AddUpdateModInList(new ModInfo { Name = an.Name, Version = an.Version.ToString(), LastUpdated = File.GetLastWriteTime(modPath) }); } catch (BadImageFormatException) { //Not a .NET assembly @@ -41,21 +40,70 @@ namespace GCMM if (!(bool)obj["ok"]) return; foreach (var repo in obj["data"]) { - string name = repo["name"].ToString(); - if (modlist.Items.ContainsKey(name)) + var mod = new ModInfo { - var item = modlist.Items[name]; - var si = item.SubItems; - si[1] = new ListViewItem.ListViewSubItem(item, repo["owner"]["username"].ToString()); - } - else - { - var item = new ListViewItem(new[] { name, repo["owner"]["username"].ToString(), "", ((DateTime)repo["updated_at"]).ToString() }, modlist.Groups["available"]); - item.Name = name; - modlist.Items.Add(item); - } + Name = repo["name"].ToString(), + Author = repo["owner"]["username"].ToString(), + LastUpdated = (DateTime)repo["updated_at"] + }; + if (await FetchModInfo(mod)) //If it's actually a mod + AddUpdateModInList(mod); + } + } + } + + public async Task FetchModInfo(ModInfo mod) + { + string repoURL = "/api/v1/repos/" + mod.Author + "/" + mod.Name + "/releases"; + using (var client = GetClient()) + { + var obj = JArray.Parse(await client.DownloadStringTaskAsync(repoURL)); + var release = obj.FirstOrDefault(rel => !(bool)rel["prerelease"] && !(bool)rel["draft"]); + if (release == null) + return false; + else + { + mod.DownloadURL = release["assets"].First["browser_download_url"].ToString(); + mod.LastUpdated = (DateTime)release["published_at"]; + mod.LatestVersion = release["tag_name"].ToString().Replace("v", ""); + return true; } } } + + public void AddUpdateModInList(ModInfo mod) + { + if (mods.ContainsKey(mod.Name) ^ modlist.Items.ContainsKey(mod.Name)) + throw new InvalidOperationException("The mod isn't present in one of the two places: " + mod.Name); + if (modlist.Items.ContainsKey(mod.Name)) + { + var omod = mods[mod.Name]; + var item = modlist.Items[mod.Name]; + var items = item.SubItems; + omod.Author = mod.Author ?? omod.Author; + omod.Version = mod.Version ?? omod.Version; + omod.LatestVersion = mod.LatestVersion ?? omod.LatestVersion; + omod.LastUpdated = mod.LastUpdated == default ? omod.LastUpdated : mod.LastUpdated; + items[1].Text = omod.Author ?? ""; + items[2].Text = omod.Version ?? omod.LatestVersion; + items[3].Text = omod.LastUpdated.ToString(); + item.Group = omod.Installed ? modlist.Groups["installed"] : modlist.Groups["available"]; + if (mod.Version != mod.LatestVersion) + items[2].ForeColor = Color.Red; + } + else + { + mods.Add(mod.Name, mod); + var item = new ListViewItem(new[] { mod.Name, mod.Author ?? "", mod.Version ?? mod.LatestVersion ?? "", mod.LastUpdated.ToString() }, modlist.Groups[mod.Installed ? "installed" : "available"]); + item.Name = mod.Name; + modlist.Items.Add(item); + } + } + + public void RemoveModFromList(ModInfo mod) + { + if (mods.Remove(mod.Name)) + modlist.Items.RemoveByKey(mod.Name); + } } } diff --git a/GCMM/ModInfo.cs b/GCMM/ModInfo.cs index 61ff2d3..5206e52 100644 --- a/GCMM/ModInfo.cs +++ b/GCMM/ModInfo.cs @@ -6,13 +6,24 @@ using System.Threading.Tasks; namespace GCMM { - class ModInfo + public class ModInfo { public string Name { get; set; } + /// + /// Can be null. + /// public string Version { get; set; } public string LatestVersion { get; set; } + /// + /// Can be null. + /// public string Description { get; set; } + /// + /// Can be null. + /// public string Author { get; set; } public DateTime LastUpdated { get; set; } + public bool Installed => Version != null; + public string DownloadURL { get; set; } } }