예제 #1
0
        /// <summary>
        /// Loads a list of types from a directory containing assemblies, that derive from a base type.
        /// </summary>
        /// <typeparam name="T">The specfiic base type to search for.</typeparam>
        /// <param name="directory">The directory to search for assemblies.</param>
        /// <returns>Returns a list of found derivative types.</returns>
        public static IEnumerable <Type> LoadTypes <T>(string directory)
        {
            List <Type> types      = new List <Type>();
            Type        pluginType = typeof(T);

            foreach (string dll in Directory.GetFiles(Path.GetFullPath(directory), "*.dll"))
            {
                try
                {
                    AssemblyName an       = AssemblyName.GetAssemblyName(dll);
                    Assembly     assembly = Assembly.Load(an);

                    foreach (Type type in assembly.GetTypes())
                    {
                        if (type.IsInterface || type.IsAbstract)
                        {
                            continue;
                        }
                        else
                        {
                            if (type.BaseType == pluginType)
                            {
                                types.Add(type);
                            }
                        }
                    }
                }
                catch (BadImageFormatException) { } //unmanaged DLL
                catch (ReflectionTypeLoadException)
                {
                    BepInLogger.Log($"ERROR! Could not load \"{Path.GetFileName(dll)}\" as a plugin!");
                }
            }

            return(types);
        }
예제 #2
0
        /// <summary>
        /// The entry point for BepInEx, called on the very first LoadScene() from UnityEngine.
        /// </summary>
        public static void Initialize()
        {
            if (loaded)
            {
                return;
            }

            if (!Directory.Exists(Common.Utility.PluginsDirectory))
            {
                Directory.CreateDirectory(Utility.PluginsDirectory);
            }

            if (bool.Parse(Config.GetEntry("console", "false")) || bool.Parse(Config.GetEntry("console-shiftjis", "false")))
            {
                try
                {
                    UnityInjector.ConsoleUtil.ConsoleWindow.Attach();

                    if (bool.Parse(Config.GetEntry("console-shiftjis", "false")))
                    {
                        UnityInjector.ConsoleUtil.ConsoleEncoding.ConsoleCodePage = 932;
                    }
                }
                catch
                {
                    BepInLogger.Log("Failed to allocate console!", true);
                }
            }

            try
            {
                BepInLogger.Log($"BepInEx {Assembly.GetExecutingAssembly().GetName().Version}");
                BepInLogger.Log("Chainloader started");

                UnityEngine.Object.DontDestroyOnLoad(ManagerObject);


                string currentProcess = Process.GetCurrentProcess().ProcessName.ToLower();

                var pluginTypes = TypeLoader.LoadTypes <BaseUnityPlugin>(Utility.PluginsDirectory)
                                  .Where(plugin =>
                {
                    //Perform a filter for currently running process
                    var filters = TypeLoader.GetAttributes <BepInProcess>(plugin);

                    if (!filters.Any())
                    {
                        return(true);
                    }

                    return(filters.Any(x => x.ProcessName.ToLower().Replace(".exe", "") == currentProcess));
                })
                                  .ToList();

                BepInLogger.Log($"{pluginTypes.Count} plugins selected");

                Dictionary <Type, IEnumerable <Type> > dependencyDict = new Dictionary <Type, IEnumerable <Type> >();

                foreach (Type t in pluginTypes)
                {
                    try
                    {
                        IEnumerable <Type> dependencies = TypeLoader.GetDependencies(t, pluginTypes);

                        dependencyDict[t] = dependencies;
                    }
                    catch (MissingDependencyException)
                    {
                        var metadata = TypeLoader.GetMetadata(t);

                        BepInLogger.Log($"Cannot load [{metadata.Name}] due to missing dependencies.");
                    }
                }

                pluginTypes = TopologicalSort(dependencyDict.Keys, x => dependencyDict[x]).ToList();

                foreach (Type t in pluginTypes)
                {
                    try
                    {
                        var metadata = TypeLoader.GetMetadata(t);

                        var plugin = (BaseUnityPlugin)ManagerObject.AddComponent(t);

                        Plugins.Add(plugin);
                        BepInLogger.Log($"Loaded [{metadata.Name} {metadata.Version}]");
                    }
                    catch (Exception ex)
                    {
                        BepInLogger.Log($"Error loading [{t.Name}] : {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                UnityInjector.ConsoleUtil.ConsoleWindow.Attach();

                Console.WriteLine("Error occurred starting the game");
                Console.WriteLine(ex.ToString());
            }

            loaded = true;
        }