Core Keeper is now using mod.io for their official mod support Read more here
Decompiled source of ModIOManager v1.0.0
ModIOManager.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ModIOManager")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ModIOManager")] [assembly: AssemblyTitle("ModIOManager")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ModIOManager { [BepInPlugin("prodzpod.ModIOManager", "ModIOManager", "1.0.0")] public class Main : BaseUnityPlugin { public const string PluginGUID = "prodzpod.ModIOManager"; public const string PluginAuthor = "prodzpod"; public const string PluginName = "ModIOManager"; public const string PluginVersion = "1.0.0"; public static ManualLogSource Log; public static PluginInfo pluginInfo; public static Harmony Harmony; public static ConfigFile Config; public static ConfigEntry<string> GameID; public static ConfigEntry<bool> Check; public static ConfigEntry<bool> Reset; public static List<string> Mods = new List<string>(); public static Main Instance; public static string Folder; public static HttpClient Client = new HttpClient(); public static string API_KEY = "e573f74ee80400ebed17a32740527333"; public static string downloadLink = null; public void Awake() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; pluginInfo = ((BaseUnityPlugin)this).Info; Log = ((BaseUnityPlugin)this).Logger; Instance = this; Harmony = new Harmony("prodzpod.ModIOManager"); Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "prodzpod.ModIOManager.cfg"), true); GameID = Config.Bind<string>("General", "Game ID", "5289", "default is core keeper"); Check = Config.Bind<bool>("General", "Check for Newest Version", true, "requires network connection, may take a while loading if set to true"); Reset = Config.Bind<bool>("General", "Redownload All", false, "if set to true, will download every mod from mod.io regardless of if the mod is present."); ConfigEntry<string> val = Config.Bind<string>("General", "Mod List", "CoreLib, CoreLib.Localization, CoreLib.RewiredExtension", "Current Mod List. if the list disagrees with the current modlist, will install new ones."); Folder = Path.Combine(Paths.GameRootPath, "CoreKeeper_Data\\StreamingAssets\\Mods"); if (!Directory.Exists(Folder)) { Log.LogInfo((object)"Creating Mod.io Directory"); Directory.CreateDirectory(Folder); } Mods = (from x in val.Value.Split(',') where !string.IsNullOrWhiteSpace(x) select x.Trim()).ToList(); Client.DefaultRequestHeaders.Accept.Clear(); Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Client.DefaultRequestHeaders.Add("User-Agent", "Other"); string[] directories = Directory.GetDirectories(Folder); foreach (string text in directories) { string fileName = Path.GetFileName(text); if (fileName.IndexOf('=') == -1) { Log.LogWarning((object)("Removing non-modiomanager mod " + text + ". please install it through here or refer to the readme!")); Directory.Delete(text); } try { string text2 = fileName.Substring(0, fileName.IndexOf('=')); string text3 = fileName; int num = fileName.IndexOf("=") + 1; long num2 = long.Parse(text3.Substring(num, text3.Length - num)); if (!Mods.Contains(text2)) { Log.LogInfo((object)("Removing " + text)); Directory.Delete(text); continue; } bool flag = Reset.Value; if (!flag && Check.Value) { long num3 = CheckVersion(text2); flag = num2 < num3; num2 = num3; } if (flag) { Log.LogInfo((object)("Updating " + text2)); Download(text2, num2); } Mods.Remove(text2); } catch { Log.LogWarning((object)("Removing non-modiomanager mod " + text + ". please install it through here or refer to the readme!")); Directory.Delete(text); } } foreach (string mod in Mods) { Log.LogInfo((object)("Installing " + mod)); Download(mod, CheckVersion(mod)); } Check.Value = false; Reset.Value = false; Client.Dispose(); } public static long CheckVersion(string mod) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) HttpRequestMessage httpRequestMessage = new HttpRequestMessage(); httpRequestMessage.RequestUri = new Uri("https://api.mod.io/v1/games/" + GameID.Value + "/mods?api_key=" + API_KEY + "&name=" + mod); httpRequestMessage.Method = HttpMethod.Get; HttpRequestMessage httpRequestMessage2 = httpRequestMessage; httpRequestMessage2.Headers.Add("User-Agent", "Other"); HttpResponseMessage result = Client.SendAsync(httpRequestMessage2).GetAwaiter().GetResult(); JObject val = JObject.Parse(result.Content.ReadAsStringAsync().GetAwaiter().GetResult()); List<JToken> list = ((IEnumerable<JToken>)(object)val["data"].Children()).ToList(); if (list.Count == 0) { throw new Exception("Mod " + mod + " does not exist!"); } downloadLink = Extensions.Value<string>((IEnumerable<JToken>)list[0][(object)"modfile"][(object)"download"][(object)"binary_url"]); return Extensions.Value<long>((IEnumerable<JToken>)list[0][(object)"date_updated"]); } public static void Download(string mod, long version) { string fname = Path.Combine(Folder, mod + ".zip"); if (downloadLink == null) { version = CheckVersion(mod); } Log.LogInfo((object)downloadLink); HttpRequestMessage httpRequestMessage = new HttpRequestMessage { RequestUri = new Uri(downloadLink), Method = HttpMethod.Get }; httpRequestMessage.Headers.Add("User-Agent", "Other"); using (HttpResponseMessage httpResponseMessage = Client.SendAsync(httpRequestMessage).GetAwaiter().GetResult()) { using Stream stream = httpResponseMessage.Content.ReadAsStreamAsync().GetAwaiter().GetResult(); using FileStream fileStream = File.OpenWrite(fname); Log.LogInfo((object)fileStream); stream.CopyToAsync(fileStream).GetAwaiter().GetResult(); Log.LogInfo((object)"done"); } ZipFile.ExtractToDirectory(fname, Path.Combine(Folder, mod + "=" + version), overwriteFiles: true); Task.Run(delegate { File.Delete(fname); }); downloadLink = null; } } }