forked from aedenthorn/ValheimMods
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSettingEntryBase.cs
188 lines (159 loc) · 6.99 KB
/
SettingEntryBase.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// Based on code made by MarC0 / ManlyMarco
// Copyright 2018 GNU General Public License v3.0
using BepInEx;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace ConfigurationManager
{
/// <summary>
/// Class representing all data about a setting collected by ConfigurationManager.
/// </summary>
public abstract class SettingEntryBase
{
/// <summary>
/// List of values this setting can take
/// </summary>
public object[] AcceptableValues { get; protected set; }
/// <summary>
/// Range of the values this setting can take
/// </summary>
public KeyValuePair<object, object> AcceptableValueRange { get; protected set; }
/// <summary>
/// Should the setting be shown as a percentage (only applies to value range settings)
/// </summary>
public bool? ShowRangeAsPercent { get; protected set; }
/// <summary>
/// Custom setting draw action
/// </summary>
public Action<BepInEx.Configuration.ConfigEntryBase> CustomDrawer { get; private set; }
/// <summary>
/// Show this setting in the settings screen at all? If false, don't show.
/// </summary>
public bool? Browsable { get; protected set; }
/// <summary>
/// Category the setting is under. Null to be directly under the plugin.
/// </summary>
public string Category { get; protected set; }
/// <summary>
/// If set, a "Default" button will be shown next to the setting to allow resetting to default.
/// </summary>
public object DefaultValue { get; protected set; }
/// <summary>
/// Force the "Reset" button to not be displayed, even if a valid DefaultValue is available.
/// </summary>
public bool HideDefaultButton { get; protected set; }
/// <summary>
/// Force the setting name to not be displayed. Should only be used with a <see cref="CustomDrawer"/> to get more space.
/// Can be used together with <see cref="HideDefaultButton"/> to gain even more space.
/// </summary>
public bool HideSettingName { get; protected set; }
/// <summary>
/// Optional description shown when hovering over the setting
/// </summary>
public string Description { get; protected internal set; }
/// <summary>
/// Name of the setting
/// </summary>
public virtual string DispName { get; protected internal set; }
/// <summary>
/// Plugin this setting belongs to
/// </summary>
public BepInPlugin PluginInfo { get; protected internal set; }
/// <summary>
/// Only allow showing of the value. False whenever possible by default.
/// </summary>
public bool? ReadOnly { get; protected set; }
/// <summary>
/// Type of the variable
/// </summary>
public abstract Type SettingType { get; }
/// <summary>
/// Instance of the plugin that owns this setting
/// </summary>
public BaseUnityPlugin PluginInstance { get; private set; }
/// <summary>
/// Is this setting advanced
/// </summary>
public bool? IsAdvanced { get; internal set; }
/// <summary>
/// Order of the setting on the settings list relative to other settings in a category. 0 by default, lower is higher on the list.
/// </summary>
public int Order { get; protected set; }
/// <summary>
/// Get the value of this setting
/// </summary>
public abstract object Get();
/// <summary>
/// Set the value of this setting
/// </summary>
public void Set(object newVal)
{
if (ReadOnly != true)
SetValue(newVal);
}
/// <summary>
/// Implementation of <see cref="Set"/>
/// </summary>
protected abstract void SetValue(object newVal);
/// <summary>
/// Custom converter from setting type to string for the textbox
/// </summary>
public Func<object, string> ObjToStr { get; internal set; }
/// <summary>
/// Custom converter from string to setting type for the textbox
/// </summary>
public Func<string, object> StrToObj { get; internal set; }
private static readonly PropertyInfo[] _myProperties = typeof(SettingEntryBase).GetProperties(BindingFlags.Instance | BindingFlags.Public);
internal void SetFromAttributes(object[] attribs, BaseUnityPlugin pluginInstance)
{
PluginInstance = pluginInstance;
PluginInfo = pluginInstance?.Info.Metadata;
if (attribs == null || attribs.Length == 0) return;
foreach (var attrib in attribs)
{
switch (attrib)
{
case null: break;
// Obsolete attributes from early bepin5 -----------------------
case Action<SettingEntryBase> newCustomDraw:
CustomDrawer = _ => newCustomDraw(this);
break;
case string str:
switch (str)
{
case "ReadOnly": ReadOnly = true; break;
case "Browsable": Browsable = true; break;
case "Unbrowsable": case "Hidden": Browsable = false; break;
case "Advanced": IsAdvanced = true; break;
}
break;
// Copy attributes from a specially formatted object, currently recommended
default:
var attrType = attrib.GetType();
if (attrType.Name == "ConfigurationManagerAttributes")
{
var otherFields = attrType.GetFields(BindingFlags.Instance | BindingFlags.Public);
foreach (var propertyPair in _myProperties.Join(otherFields, my => my.Name, other => other.Name, (my, other) => new { my, other }))
{
try
{
var val = propertyPair.other.GetValue(attrib);
if (val != null)
propertyPair.my.SetValue(this, val, null);
}
catch (Exception ex)
{
BepInExPlugin.Logger.LogWarning($"Failed to copy value {propertyPair.my.Name} from provided tag object {attrType.FullName} - " + ex.Message);
}
}
break;
}
return;
}
}
}
}
}