-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSettingSearcher.cs
More file actions
96 lines (80 loc) · 3.76 KB
/
SettingSearcher.cs
File metadata and controls
96 lines (80 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Based on code made by MarC0 / ManlyMarco
// Copyright 2018 GNU General Public License v3.0
using System;
using BepInEx;
using BepInEx.Configuration;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using BepInEx.Bootstrap;
using UnityEngine;
namespace ConfigurationManager
{
internal static class SettingSearcher
{
/// <summary>
/// Search for all instances of BaseUnityPlugin loaded by chainloader or other means.
/// </summary>
public static BaseUnityPlugin[] FindPlugins()
{
// Search for instances of BaseUnityPlugin to also find dynamically loaded plugins.
// Have to use FindObjectsOfType(Type) instead of FindObjectsOfType<T> because the latter is not available in some older unity versions.
// Still look inside Chainloader.PluginInfos in case the BepInEx_Manager GameObject uses HideFlags.HideAndDontSave, which hides it from Object.Find methods.
return Chainloader.PluginInfos.Values.Select(x => x.Instance)
.Where(plugin => plugin != null)
.Union(UnityEngine.Object.FindObjectsByType(typeof(BaseUnityPlugin), FindObjectsInactive.Exclude, FindObjectsSortMode.None).Cast<BaseUnityPlugin>())
.ToArray();
}
public static void CollectSettings(out IEnumerable<SettingEntryBase> results, out List<string> modsWithoutSettings)
{
modsWithoutSettings = new List<string>();
try
{
results = GetBepInExCoreConfig();
}
catch (Exception ex)
{
results = Enumerable.Empty<SettingEntryBase>();
ConfigurationManager.LogError(ex);
}
foreach (var plugin in FindPlugins())
{
var type = plugin.GetType();
var pluginInfo = plugin.Info.Metadata;
var pluginName = pluginInfo?.Name ?? plugin.GetType().FullName;
if (type.GetCustomAttributes(typeof(BrowsableAttribute), false).Cast<BrowsableAttribute>()
.Any(x => !x.Browsable))
{
modsWithoutSettings.Add(pluginName);
continue;
}
var detected = new List<SettingEntryBase>();
detected.AddRange(GetPluginConfig(plugin));
detected.RemoveAll(x => x.Browsable == false);
if (detected.Count == 0)
modsWithoutSettings.Add(pluginName);
if (detected.Count > 0)
results = results.Concat(detected);
}
}
/// <summary>
/// Get entries for all core BepInEx settings
/// </summary>
private static IEnumerable<SettingEntryBase> GetBepInExCoreConfig()
{
var coreConfigProp = typeof(ConfigFile).GetProperty("CoreConfig", BindingFlags.Static | BindingFlags.NonPublic);
if (coreConfigProp == null) throw new ArgumentNullException(nameof(coreConfigProp));
var coreConfig = (ConfigFile)coreConfigProp.GetValue(null, null);
var bepinMeta = new BepInPlugin("BepInEx", "BepInEx", typeof(Chainloader).Assembly.GetName().Version.ToString());
return coreConfig.Select(kvp => (SettingEntryBase)new ConfigSettingEntry(kvp.Value, null) { IsAdvanced = true, PluginInfo = bepinMeta });
}
/// <summary>
/// Get entries for all settings of a plugin
/// </summary>
private static IEnumerable<ConfigSettingEntry> GetPluginConfig(BaseUnityPlugin plugin)
{
return plugin.Config.Select(kvp => new ConfigSettingEntry(kvp.Value, plugin));
}
}
}