예제 #1
0
        public static void CollectSettings(out IEnumerable <SettingEntryBase> results, out List <string> modsWithoutSettings, bool showDebug)
        {
            modsWithoutSettings = new List <string>();

            try
            {
                results = GetBepInExCoreConfig();
            }
            catch (Exception ex)
            {
                results = Enumerable.Empty <SettingEntryBase>();
                BepInExPlugin.Logger.LogError(ex);
            }

            foreach (var plugin in Utils.FindPlugins())
            {
                if (plugin.Info.Metadata.GUID == "com.bepis.bepinex.configurationmanager" || plugin.enabled == false)
                {
                    BepInExPlugin.Dbgl($"plugin: {plugin.Info.Metadata.Name} enabled {plugin.enabled}");
                }

                var type = plugin.GetType();

                var pluginInfo = plugin.Info.Metadata;

                if (type.GetCustomAttributes(typeof(BrowsableAttribute), false).Cast <BrowsableAttribute>()
                    .Any(x => !x.Browsable))
                {
                    modsWithoutSettings.Add(pluginInfo.Name);
                    continue;
                }

                var detected = new List <SettingEntryBase>();

                detected.AddRange(GetPluginConfig(plugin).Cast <SettingEntryBase>());

                detected.RemoveAll(x => x.Browsable == false);

                if (!detected.Any())
                {
                    modsWithoutSettings.Add(pluginInfo.Name);
                }

                // Allow to enable/disable plugin if it uses any update methods ------
                if (showDebug && type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(x => _updateMethodNames.Contains(x.Name)))
                {
                    // todo make a different class for it and fix access modifiers?
                    var enabledSetting = LegacySettingEntry.FromNormalProperty(plugin, type.GetProperty("enabled"), pluginInfo, plugin);
                    enabledSetting.DispName    = "!Allow plugin to run on every frame";
                    enabledSetting.Description = "Disabling this will disable some or all of the plugin's functionality.\nHooks and event-based functionality will not be disabled.\nThis setting will be lost after game restart.";
                    enabledSetting.IsAdvanced  = true;
                    detected.Add(enabledSetting);
                }

                if (detected.Any())
                {
                    results = results.Concat(detected);
                }
            }
        }
예제 #2
0
        public static void CollectSettings(out IEnumerable <SettingEntryBase> results, out List <string> modsWithoutSettings, bool showDebug)
        {
            var configProperty = typeof(BaseUnityPlugin).GetProperty("Config", BindingFlags.Instance | BindingFlags.NonPublic);

            if (configProperty == null)
            {
                throw new ArgumentNullException(nameof(configProperty));
            }

            results             = Enumerable.Empty <SettingEntryBase>();
            modsWithoutSettings = new List <string>();

            // Core BepInEx config
            results = results.Concat(GetBepInExConfig());

            foreach (var plugin in Utils.FindPlugins())
            {
                var type = plugin.GetType();

                var pluginInfo = plugin.Info.Metadata;

                if (type.GetCustomAttributes(typeof(BrowsableAttribute), false).Cast <BrowsableAttribute>()
                    .Any(x => !x.Browsable))
                {
                    modsWithoutSettings.Add(pluginInfo.Name);
                    continue;
                }

                var detected = new List <SettingEntryBase>();

                var config = (ConfigFile)configProperty.GetValue(plugin, null);
                detected.AddRange(config.GetConfigEntries().Select(x => new ConfigSettingEntry(x, plugin)).Cast <SettingEntryBase>());

                detected.AddRange(GetLegacyPluginConfig(plugin).Cast <SettingEntryBase>());

                detected.RemoveAll(x => x.Browsable == false);

                if (!detected.Any())
                {
                    modsWithoutSettings.Add(pluginInfo.Name);
                }

                // Allow to enable/disable plugin if it uses any update methods ------
                if (showDebug && type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(x => _updateMethodNames.Contains(x.Name)))
                {
                    var enabledSetting = LegacySettingEntry.FromNormalProperty(plugin, type.GetProperty("enabled"), pluginInfo, plugin);
                    enabledSetting.DispName    = "!Allow plugin to run on every frame";
                    enabledSetting.Description =
                        "Disabling this will disable some or all of the plugin's functionality.\nHooks and event-based functionality will not be disabled.\nThis setting will be lost after game restart.";
                    enabledSetting.IsAdvanced = true;
                    detected.Add(enabledSetting);
                }

                if (detected.Any())
                {
                    var isAdvancedPlugin = type.GetCustomAttributes(typeof(AdvancedAttribute), false).Cast <AdvancedAttribute>()
                                           .Any(x => x.IsAdvanced);
                    if (isAdvancedPlugin)
                    {
                        detected.ForEach(entry => entry.IsAdvanced = true);
                    }

                    results = results.Concat(detected);
                }
            }
        }
예제 #3
0
        private static IEnumerable <LegacySettingEntry> GetLegacyPluginConfig(BaseUnityPlugin plugin)
        {
            if (_bepin4BaseSettingType == null)
            {
                return(Enumerable.Empty <LegacySettingEntry>());
            }

            var type       = plugin.GetType();
            var pluginInfo = plugin.Info.Metadata;

            // Config wrappers ------

            var settingProps = type
                               .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                               .FilterBrowsable(true, true);

            var settingFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public)
                                .Where(f => !f.IsSpecialName)
                                .FilterBrowsable(true, true)
                                .Select(f => new FieldToPropertyInfoWrapper(f));

            var settingEntries = settingProps.Concat(settingFields.Cast <PropertyInfo>())
                                 .Where(x => x.PropertyType.IsSubclassOfRawGeneric(_bepin4BaseSettingType));

            var results = settingEntries.Select(x => LegacySettingEntry.FromConfigWrapper(plugin, x, pluginInfo, plugin)).Where(x => x != null);

            // Config wrappers static ------

            var settingStaticProps = type
                                     .GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                                     .FilterBrowsable(true, true);

            var settingStaticFields = type.GetFields(BindingFlags.Static | BindingFlags.Public)
                                      .Where(f => !f.IsSpecialName)
                                      .FilterBrowsable(true, true)
                                      .Select(f => new FieldToPropertyInfoWrapper(f));

            var settingStaticEntries = settingStaticProps.Concat(settingStaticFields.Cast <PropertyInfo>())
                                       .Where(x => x.PropertyType.IsSubclassOfRawGeneric(_bepin4BaseSettingType));

            results = results.Concat(settingStaticEntries.Select(x => LegacySettingEntry.FromConfigWrapper(null, x, pluginInfo, plugin)).Where(x => x != null));

            // Normal properties ------

            bool IsPropSafeToShow(PropertyInfo p) => p.GetSetMethod()?.IsPublic == true && (p.PropertyType.IsValueType || p.PropertyType == typeof(string));

            var normalPropsSafeToShow = type
                                        .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                                        .Where(IsPropSafeToShow)
                                        .FilterBrowsable(true, true)
                                        .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(_bepin4BaseSettingType));

            var normalPropsWithBrowsable = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
                                           .FilterBrowsable(true, false)
                                           .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(_bepin4BaseSettingType));

            var normalProps = normalPropsSafeToShow.Concat(normalPropsWithBrowsable).Distinct();

            results = results.Concat(normalProps.Select(x => LegacySettingEntry.FromNormalProperty(plugin, x, pluginInfo, plugin)).Where(x => x != null));

            // Normal static properties ------

            var normalStaticPropsSafeToShow = type
                                              .GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)
                                              .Where(IsPropSafeToShow)
                                              .FilterBrowsable(true, true)
                                              .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(_bepin4BaseSettingType));

            var normalStaticPropsWithBrowsable = type.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
                                                 .FilterBrowsable(true, false)
                                                 .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(_bepin4BaseSettingType));

            var normalStaticProps = normalStaticPropsSafeToShow.Concat(normalStaticPropsWithBrowsable).Distinct();

            results = results.Concat(normalStaticProps.Select(x => LegacySettingEntry.FromNormalProperty(null, x, pluginInfo, plugin)).Where(x => x != null));

            return(results);
        }