forked from aedenthorn/ValheimMods
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLegacySettingEntry.cs
131 lines (105 loc) · 5.04 KB
/
LegacySettingEntry.cs
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Based on code made by MarC0 / ManlyMarco
// Copyright 2018 GNU General Public License v3.0
using BepInEx;
using BepInEx.Logging;
using System;
using System.Reflection;
namespace ConfigurationManager
{
internal class LegacySettingEntry : SettingEntryBase
{
private Type _settingType;
private LegacySettingEntry()
{
}
public override string DispName
{
get => string.IsNullOrEmpty(base.DispName) ? Property.Name : base.DispName;
protected internal set => base.DispName = value;
}
public object Instance { get; internal set; }
public PropertyInfo Property { get; internal set; }
public override Type SettingType => _settingType ?? (_settingType = Property.PropertyType);
public override object Get() => Property.GetValue(Instance, null);
protected override void SetValue(object newVal) => Property.SetValue(Instance, newVal, null);
/// <summary>
/// Instance of the object that holds this setting.
/// Null if setting is not in a ConfigWrapper.
/// </summary>
public object Wrapper { get; internal set; }
public static LegacySettingEntry FromConfigWrapper(object instance, PropertyInfo settingProp,
BepInPlugin pluginInfo, BaseUnityPlugin pluginInstance)
{
try
{
var wrapper = settingProp.GetValue(instance, null);
if (wrapper == null)
{
BepInExPlugin.Logger.Log(LogLevel.Debug, $"Skipping ConfigWrapper entry because it's null : {instance} | {settingProp.Name} | {pluginInfo?.Name}");
return null;
}
var innerProp = wrapper.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
var entry = new LegacySettingEntry();
entry.SetFromAttributes(settingProp.GetCustomAttributes(false), pluginInstance);
if (innerProp == null)
{
BepInExPlugin.Logger.Log(LogLevel.Error, "Failed to find property Value of ConfigWrapper");
return null;
}
entry.Browsable = innerProp.CanRead && innerProp.CanWrite && entry.Browsable != false;
entry.Property = innerProp;
entry.Instance = wrapper;
entry.Wrapper = wrapper;
if (entry.DispName == "Value")
entry.DispName = wrapper.GetType().GetProperty("Key", BindingFlags.Instance | BindingFlags.Public)
?.GetValue(wrapper, null) as string;
if (string.IsNullOrEmpty(entry.Category))
{
var section = wrapper.GetType().GetProperty("Section", BindingFlags.Instance | BindingFlags.Public)
?.GetValue(wrapper, null) as string;
if (section != pluginInfo?.GUID)
entry.Category = section;
}
var strToObj = wrapper.GetType().GetField("_strToObj",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(wrapper);
if (strToObj != null)
{
var inv = strToObj.GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public);
if (inv != null)
entry.StrToObj = s => inv.Invoke(strToObj, new object[] { s });
}
var objToStr = wrapper.GetType().GetField("_objToStr",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(wrapper);
if (objToStr != null)
{
var inv = objToStr.GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public);
if (inv != null)
entry.ObjToStr = o => inv.Invoke(objToStr, new object[] { o }) as string;
}
else
{
entry.ObjToStr = o => o.ToString();
}
return entry;
}
catch (SystemException ex)
{
BepInExPlugin.Logger.Log(LogLevel.Error,
$"Failed to create ConfigWrapper entry : {instance} | {settingProp?.Name} | {pluginInfo?.Name} | Error: {ex.Message}");
return null;
}
}
public static LegacySettingEntry FromNormalProperty(object instance, PropertyInfo settingProp,
BepInPlugin pluginInfo, BaseUnityPlugin pluginInstance)
{
var entry = new LegacySettingEntry();
entry.SetFromAttributes(settingProp.GetCustomAttributes(false), pluginInstance);
if (entry.Browsable == null)
entry.Browsable = settingProp.CanRead && settingProp.CanWrite;
entry.ReadOnly = settingProp.CanWrite;
entry.Property = settingProp;
entry.Instance = instance;
return entry;
}
}
}