internal static void Check() { if (PlayerPrefs.GetInt("QModManager_EnableUpdateCheck", 1) == 0) { Logger.Info("Update check disabled"); return; } if (!NetworkUtilities.CheckConnection()) { Logger.Warn("Cannot check for updates, internet disabled"); return; } ServicePointManager.ServerCertificateValidationCallback = NetworkUtilities.CustomSCVC; using (WebClient client = new WebClient()) { client.DownloadStringCompleted += (sender, e) => { if (e.Error != null) { Logger.Error("There was an error retrieving the latest version from GitHub!"); Logger.Exception(e.Error); return; } Parse(e.Result); }; Logger.Debug("Getting the latest version..."); client.DownloadStringAsync(new Uri(VersionURL)); } }
private static void CheckOldHarmony(IEnumerable <QMod> mods) { var modsThatUseOldHarmony = new List <QMod>(); foreach (QMod mod in mods) { if (mod.IsLoaded && mod.HarmonyOutdated) { modsThatUseOldHarmony.Add(mod); } } if (modsThatUseOldHarmony.Count > 0) { Logger.Warn($"Some mods are using an old version of harmony! This will NOT cause any problems, but it's not recommended:"); foreach (QMod mod in modsThatUseOldHarmony) { Console.WriteLine($"- {mod.DisplayName} ({mod.Id})"); } } }
internal static void Patch() { try { if (patched) { Logger.Warn("Patch method was called multiple times!"); return; } patched = true; Logger.Info($"Loading QModManager v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}..."); if (QModBaseDir == null) { Logger.Fatal("A fatal error has occurred."); Logger.Fatal("There was an error with the QMods directory"); Logger.Fatal("Please make sure that you ran Subnautica from Steam/Epic/Discord, and not from the executable file!"); return; } try { Logger.Info($"Folder structure:\n{IOUtilities.GetFolderStructureAsTree()}\n"); } catch (Exception e) { Logger.Error("There was an error while trying to display the folder structure."); Logger.Exception(e); } QModHooks.Load(); #pragma warning disable CS0618 // Type or member is obsolete Hooks.Load(); #pragma warning restore CS0618 // Type or member is obsolete PirateCheck.IsPirate(Environment.CurrentDirectory); if (!DetectGame()) { return; } PatchHarmony(); if (NitroxCheck.IsInstalled) { Logger.Fatal($"Nitrox was detected!"); Dialog.Show("Both QModManager and Nitrox detected. QModManager is not compatible with Nitrox. Please uninstall one of them.", Dialog.Button.disabled, Dialog.Button.disabled, false); return; } StartLoadingMods(); ShowErroredMods(); VersionCheck.Check(); QModHooks.Start += PrefabDebugger.Main; QModHooks.OnLoadEnd?.Invoke(); #pragma warning disable CS0618 // Type or member is obsolete Hooks.OnLoadEnd?.Invoke(); #pragma warning restore CS0618 // Type or member is obsolete Logger.Info($"Finished loading QModManager. Loaded {loadedMods.Count} mods"); } catch (Exception e) { Logger.Error("EXCEPTION CAUGHT!"); Logger.Exception(e); } }
internal static bool QModValid(QMod mod, string folderName) { bool success = true; if (mod == null) { Logger.Error($"Skipped a null mod found in folder \"{folderName}\""); return(false); } if (string.IsNullOrEmpty(mod.DisplayName)) { Logger.Error($"Mod found in folder \"{folderName}\" is missing a display name!"); success = false; } if (string.IsNullOrEmpty(mod.Id)) { Logger.Error($"Mod found in folder \"{folderName}\" is missing an ID!"); success = false; } else if (mod.Id != Regex.Replace(mod.Id, Patcher.IDRegex, "", RegexOptions.IgnoreCase)) { Logger.Warn($"Mod found in folder \"{folderName}\" has an invalid ID! All invalid characters have been removed. (This can cause issues!)"); mod.Id = Regex.Replace(mod.Id, Patcher.IDRegex, "", RegexOptions.IgnoreCase); } if (string.IsNullOrEmpty(mod.Author)) { Logger.Error($"Mod found in folder \"{folderName}\" is missing an author!"); success = false; } if (string.IsNullOrEmpty(mod.Version)) { Logger.Error($"Mod found in folder \"{folderName}\" is missing a version!"); success = false; } if (mod.ParsedVersion == null) { Logger.Warn($"Mod found in folder \"{folderName}\" has an invalid version!"); } if (string.IsNullOrEmpty(mod.AssemblyName)) { Logger.Error($"Mod found in folder \"{folderName}\" is missing an assembly name!"); success = false; } else if (!mod.AssemblyName.EndsWith(".dll")) { Logger.Error($"Mod found in folder \"{folderName}\" is has an invalid assembly name!"); success = false; } if (string.IsNullOrEmpty(mod.EntryMethod)) { Logger.Error($"Mod found in folder \"{folderName}\" is missing an entry point!"); success = false; } else if (mod.EntryMethod?.Count(c => c == '.') < 2) { Logger.Error($"Mod found in folder \"{folderName}\" has an invalid entry point!"); success = false; } for (int i = 0; i < mod.LoadAfter.Length; i++) { string good = Regex.Replace(mod.LoadAfter[i], Patcher.IDRegex, "", RegexOptions.IgnoreCase); if (mod.LoadAfter[i] != good) { mod.LoadAfter[i] = good; } } for (int i = 0; i < mod.LoadBefore.Length; i++) { string good = Regex.Replace(mod.LoadBefore[i], Patcher.IDRegex, "", RegexOptions.IgnoreCase); if (mod.LoadBefore[i] != good) { mod.LoadBefore[i] = good; } } Dictionary <string, string> versionDependenciesLoop = new Dictionary <string, string>(mod.VersionDependencies); foreach (KeyValuePair <string, string> kvp in versionDependenciesLoop) { string good = Regex.Replace(kvp.Key, Patcher.IDRegex, "", RegexOptions.IgnoreCase); if (kvp.Key != good) { mod.VersionDependencies.Remove(kvp.Key); mod.VersionDependencies.Add(good, kvp.Value); } } return(success); }