Exemple #1
0
        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))
 {
 }