public static void TypeLoaderFindPluginTypesPostfix(ref Dictionary <string, List <PluginInfo> > __result, string directory) { if (directory != Paths.PluginPath) { return; } if (!(__result.Values.SelectMany(x => x).SingleOrDefault(x => x.Metadata.GUID == "QModManager.QMMLoader") is PluginInfo qmmLoaderPluginInfo)) { return; } try { var result = new Dictionary <string, List <PluginInfo> >(); QModPluginInfos = new Dictionary <string, PluginInfo>(); InitialisedQModPlugins = new List <PluginInfo>(); IPluginCollection pluginCollection = new PluginCollection(__result.Values.SelectMany(x => x).ToList()); IQModFactory factory = new QModFactory(pluginCollection); QModsToLoad = factory.BuildModLoadingList(QModsPath); QModServices.LoadKnownMods(QModsToLoad.ToList()); QModsToLoadById = QModsToLoad.ToDictionary(qmod => qmod.Id); foreach (var mod in QModsToLoad.Where(mod => mod.Status == ModStatus.Success)) { var dll = Path.Combine(mod.SubDirectory, mod.AssemblyName); var manifest = Path.Combine(mod.SubDirectory, "mod.json"); if (PluginCache != null && PluginCache.TryGetValue(dll, out var cacheEntry)) { var lastWrite = Math.Max(File.GetLastWriteTimeUtc(dll).Ticks, File.GetLastWriteTimeUtc(manifest).Ticks); if (lastWrite == cacheEntry.Timestamp) { result[dll] = cacheEntry.CacheItems; QModPluginInfos[mod.Id] = cacheEntry.CacheItems.FirstOrDefault(); continue; } } var loadBeforeQmodIds = mod.LoadBefore.Where(id => QModPluginInfos.ContainsKey(id)); foreach (var id in loadBeforeQmodIds) { QModPluginInfos[id].Dependencies.AddItem(new BepInDependency(mod.Id, BepInDependency.DependencyFlags.SoftDependency)); } foreach (var id in mod.LoadBefore.Where(id => pluginCollection.AllPlugins.Select(x => x.Metadata.GUID).Contains(id)).Except(loadBeforeQmodIds)) { if (__result.Values.SelectMany(x => x).SingleOrDefault(x => x.Metadata.GUID == id) is PluginInfo bepinexPlugin) { Traverse.Create(bepinexPlugin) .Property <IEnumerable <BepInDependency> >(nameof(PluginInfo.Dependencies)).Value = bepinexPlugin.Dependencies.Concat(new[] { new BepInDependency(mod.Id, BepInDependency.DependencyFlags.SoftDependency) }); } } var pluginInfo = new PluginInfo(); var traverseablePluginInfo = Traverse.Create(pluginInfo); traverseablePluginInfo.Property <IEnumerable <BepInDependency> >(nameof(PluginInfo.Dependencies)).Value = new List <BepInDependency>(new[] { new BepInDependency(qmmLoaderPluginInfo.Metadata.GUID) }); foreach (var id in mod.Dependencies) { traverseablePluginInfo.Property <IEnumerable <BepInDependency> >(nameof(PluginInfo.Dependencies)).Value = pluginInfo.Dependencies.AddItem(new BepInDependency(id, BepInDependency.DependencyFlags.HardDependency)); } foreach (var versionDependency in mod.VersionDependencies) { var version = VersionParserService.GetVersion(versionDependency.Value); traverseablePluginInfo.Property <IEnumerable <BepInDependency> >(nameof(PluginInfo.Dependencies)).Value = pluginInfo.Dependencies.AddItem(new BepInDependency(versionDependency.Key, version.ToString())); } foreach (var id in mod.LoadAfter) { traverseablePluginInfo.Property <IEnumerable <BepInDependency> >(nameof(PluginInfo.Dependencies)).Value = pluginInfo.Dependencies.AddItem(new BepInDependency(id, BepInDependency.DependencyFlags.SoftDependency)); } traverseablePluginInfo.Property <IEnumerable <BepInProcess> >(nameof(PluginInfo.Processes)).Value = new BepInProcess[0]; traverseablePluginInfo.Property <IEnumerable <BepInIncompatibility> >(nameof(PluginInfo.Incompatibilities)).Value = new BepInIncompatibility[0]; traverseablePluginInfo.Property <BepInPlugin>(nameof(PluginInfo.Metadata)).Value = new BepInPlugin(mod.Id, mod.DisplayName, mod.ParsedVersion.ToString()); traverseablePluginInfo.Property <string>("TypeName").Value = typeof(QModPlugin).FullName; traverseablePluginInfo.Property <Version>("TargettedBepInExVersion").Value = Assembly.GetExecutingAssembly().GetReferencedAssemblies().FirstOrDefault(x => x.Name == "BepInEx").Version; result.Add(dll, new[] { pluginInfo }.ToList()); QModPluginInfos.Add(mod.Id, pluginInfo); } __result[Assembly.GetExecutingAssembly().Location] = QModPluginInfos.Values.Distinct().ToList(); TypeLoader.SaveAssemblyCache(GeneratedPluginCache, result); } catch (Exception ex) { Logger.LogFatal($"Failed to emulate QMods as plugins"); Logger.LogFatal(ex.ToString()); } }
internal RequiredQMod(string id, string minimumVersion) : this(id, !string.IsNullOrEmpty(minimumVersion), VersionParserService.GetVersion(minimumVersion)) { }