Пример #1
0
        private static TypeloaderCache GetPluginCache()
        {
            LoadQMMAssemblyCache();

            if (QMMAssemblyCache == null)
            {
                ClearBepInExCache();
                QMMAssemblyCache = GetNewQMMAssemblyCache();
                SaveQMMAssemblyCache();
            }
            else
            {
                var qmmAssemblyCache = GetNewQMMAssemblyCache();

                if (!qmmAssemblyCache.Keys.SequenceEqual(QMMAssemblyCache.Keys) ||
                    qmmAssemblyCache.Any(x => x.Value != QMMAssemblyCache[x.Key]))
                {
                    ClearBepInExCache();
                    QMMAssemblyCache = qmmAssemblyCache;
                    SaveQMMAssemblyCache();
                }
            }
            return(TypeLoader.LoadAssemblyCache <PluginInfo>(GeneratedPluginCache));
        }
Пример #2
0
        public static void TypeLoadHook(ref Dictionary <string, List <PluginInfo> > __result, string directory,
                                        Func <TypeDefinition, PluginInfo> typeSelector)
        {
            if (directory != Paths.PluginPath)
            {
                return;
            }

            var results = new Dictionary <string, List <PluginInfo> >();
            var cache   = TypeLoader.LoadAssemblyCache <PluginInfo>("bepinex4_chainloader");

            foreach (var dll in Directory.GetFiles(Path.GetFullPath(PluginsPath), "*.dll",
                                                   SearchOption.TopDirectoryOnly))
            {
                try
                {
                    if (cache != null && cache.TryGetValue(dll, out var cacheEntry))
                    {
                        var lastWrite = File.GetLastWriteTimeUtc(dll).Ticks;
                        if (lastWrite == cacheEntry.Timestamp)
                        {
                            __result[dll] = cacheEntry.CacheItems;
                            results[dll]  = cacheEntry.CacheItems;
                            continue;
                        }
                    }

                    var ass = AssemblyDefinition.ReadAssembly(dll, readerParameters);

                    if (shimmedAssemblies.TryGetValue(ass.FullName, out var memAsm))
                    {
                        ass.Dispose();
                        ass = AssemblyDefinition.ReadAssembly(new MemoryStream(memAsm.data), readerParameters);
                    }

                    var matches = ass.MainModule.Types.Select(typeSelector).Where(t => t != null).ToList();

                    if (matches.Count == 0)
                    {
                        ass.Dispose();
                        continue;
                    }

                    if (memAsm != null)
                    {
                        foreach (var pluginInfo in matches)
                        {
                            typeof(PluginInfo).GetProperty(nameof(PluginInfo.Location))
                            .SetValue(pluginInfo, memAsm.path, null);
                            loadedMemoryAssemblies[ass.FullName] = Assembly.Load(memAsm.data);
                        }
                    }

                    __result[dll] = matches;
                    results[dll]  = matches;
                    ass.Dispose();
                }
                catch (Exception e)
                {
                    Logger.LogError(e.ToString());
                }
            }

            TypeLoader.SaveAssemblyCache("bepinex4_chainloader", results);
        }