/// <summary> /// Loads and registers the <see cref="GadgetMod"/> represented by the given directory. Will log a warning and return null if the given directory is not a valid <see cref="GadgetMod"/>. Will also add the name to <see cref="ErroredMods"/> if the directory was valid, but an error occured during the mod-loading process. /// </summary> public static GadgetMod LoadModDir(string modDir) { string modName = null; try { string manifestFile = Path.Combine(modDir, "Manifest.ini"); if (File.Exists(manifestFile)) { if (Directory.Exists(Path.Combine(modDir, "Libs"))) { foreach (string lib in Directory.GetFiles(Path.Combine(modDir, "Libs"))) { string existingFilePath = Path.Combine(GadgetPaths.LibsPath, Path.GetFileName(lib)); FileInfo libFile = new FileInfo(lib); if (!File.Exists(existingFilePath) || libFile.LastWriteTime > new FileInfo(existingFilePath).LastWriteTime) { libFile.CopyTo(existingFilePath, true); } } } IniData manifest = manifestIniParser.ReadFile(manifestFile); modName = manifest["Metadata"]["Name"]; Assembly modAssembly = Assembly.LoadFile(Path.Combine(modDir, manifest["Metadata"]["Assembly"])); GadgetCore.LoadedAssemblies[modAssembly.GetName().Name] = modAssembly; GadgetMod mod = new GadgetMod(modDir, manifest, modAssembly); GadgetMods.RegisterMod(mod); if (!BatchLoading) { LoadGadgetMod(mod); } return(mod); } else { Logger.LogWarning("Invalid or non-mod directory '" + Path.GetFileName(modDir) + "' in Mods directory!"); } } catch (Exception e) { Logger.LogError("Exception loading mod directory '" + Path.GetFileName(modDir) + "':"); Logger.LogError(e.ToString()); if (modName != null) { Tuple <string, string> erroredMod = Tuple.Create(modName, modDir); if (!m_ErroredMods.Contains(erroredMod)) { m_ErroredMods.Add(erroredMod); } } } return(null); }
/// <summary> /// Loads and registers the <see cref="GadgetMod"/> represented by the given file. Will log a warning and return null if the given file is not a valid <see cref="GadgetMod"/>. Will also add the name to <see cref="ErroredMods"/> if the file was valid, but an error occured during the mod-loading process. /// </summary> public static GadgetMod LoadModFile(string modFile) { string modName = null; ZipFile modZip = null; try { modZip = new ZipFile(modFile); if (Path.GetExtension(modFile) == ".umfmod") { GadgetCore.CoreLib.DecryptUMFModFile(modZip); } if (modZip.ContainsEntry("Manifest.ini")) { if (modZip.ContainsEntry("Libs")) { foreach (ZipEntry lib in modZip.Entries.Where(x => !x.IsDirectory && x.FileName.StartsWith("Libs"))) { string existingFilePath = Path.Combine(GadgetPaths.GadgetCorePath, lib.FileName); if (!File.Exists(existingFilePath) || lib.ModifiedTime > new FileInfo(existingFilePath).LastWriteTime) { lib.Extract(GadgetPaths.GadgetCorePath, ExtractExistingFileAction.OverwriteSilently); } } } using (MemoryStream stream = new MemoryStream()) { modZip["Manifest.ini"].Extract(stream); stream.Position = 0; IniData manifest = manifestIniParser.ReadData(new StreamReader(stream)); modName = manifest["Metadata"]["Name"]; stream.SetLength(0); if (manifest["Metadata"]["Assembly"] != null && modZip.ContainsEntry(manifest["Metadata"]["Assembly"])) { modZip[manifest["Metadata"]["Assembly"]].Extract(stream); } else { Logger.LogWarning("Failed to load mod `" + modName + "` because " + (manifest["Metadata"]["Assembly"] != null ? "the assembly name in its manifest is not valid!" : "its manifest does not contain the name of its asembly!")); return(null); } Assembly modAssembly = Assembly.Load(stream.ToArray()); GadgetCore.LoadedAssemblies[modAssembly.GetName().Name] = modAssembly; GadgetMod mod = new GadgetMod(modFile, manifest, modAssembly, modZip); GadgetMods.RegisterMod(mod); if (!BatchLoading) { LoadGadgetMod(mod); } modZip = null; return(mod); } } else { Logger.LogWarning("Invalid or non-mod file '" + Path.GetFileName(modFile) + "' in Mods directory!"); } } catch (Exception e) { Logger.LogError("Exception loading mod file '" + Path.GetFileName(modFile) + "':"); Logger.LogError(e.ToString()); if (modName != null) { Tuple <string, string> erroredMod = Tuple.Create(modName, modFile); if (!m_ErroredMods.Contains(erroredMod)) { m_ErroredMods.Add(erroredMod); } } } finally { modZip?.Dispose(); } return(null); }