mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Make significant changes to ConfigFile API
This commit is contained in:
10 files changed
+251
-132
No files matched your search
@@ -283,17 +283,17 @@ namespace BepInEx.Preloader.Patching
|
||||
|
||||
#region Config
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigDumpAssemblies = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigDumpAssemblies = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader", "DumpAssemblies",
|
||||
false,
|
||||
"If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.\nThis can be used by developers to inspect and debug preloader patchers.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigLoadDumpedAssemblies = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigLoadDumpedAssemblies = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader", "LoadDumpedAssemblies",
|
||||
false,
|
||||
"If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.\nThis can be used to be able to load patched assemblies into debuggers like dnSpy.\nIf set to true, will override DumpAssemblies.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigBreakBeforeLoadAssemblies = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigBreakBeforeLoadAssemblies = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader", "BreakBeforeLoadAssemblies",
|
||||
false,
|
||||
"If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.\nThis can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded.");
|
||||
|
||||
@@ -237,32 +237,32 @@ namespace BepInEx.Preloader
|
||||
|
||||
#region Config
|
||||
|
||||
private static readonly ConfigEntry<string> ConfigEntrypointAssembly = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<string> ConfigEntrypointAssembly = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader.Entrypoint", "Assembly",
|
||||
IsPostUnity2017 ? "UnityEngine.CoreModule.dll" : "UnityEngine.dll",
|
||||
"The local filename of the assembly to target.");
|
||||
|
||||
private static readonly ConfigEntry<string> ConfigEntrypointType = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<string> ConfigEntrypointType = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader.Entrypoint", "Type",
|
||||
"Application",
|
||||
"The name of the type in the entrypoint assembly to search for the entrypoint method.");
|
||||
|
||||
private static readonly ConfigEntry<string> ConfigEntrypointMethod = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<string> ConfigEntrypointMethod = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader.Entrypoint", "Method",
|
||||
".cctor",
|
||||
"The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigApplyRuntimePatches = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigApplyRuntimePatches = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader", "ApplyRuntimePatches",
|
||||
true,
|
||||
"Enables or disables runtime patches.\nThis should always be true, unless you cannot start the game due to a Harmony related issue (such as running .NET Standard runtime) or you know what you're doing.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigShimHarmony = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigShimHarmony = ConfigFile.CoreConfig.Bind(
|
||||
"Preloader", "ShimHarmonySupport",
|
||||
!Utility.CLRSupportsDynamicAssemblies,
|
||||
"If enabled, basic Harmony functionality is patched to use MonoMod's RuntimeDetour instead.\nTry using this if Harmony does not work in a game.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigPreloaderCOutLogging = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigPreloaderCOutLogging = ConfigFile.CoreConfig.Bind(
|
||||
"Logging", "PreloaderConsoleOutRedirection",
|
||||
true,
|
||||
"Redirects text from Console.Out during preloader patch loading to the BepInEx logging system.");
|
||||
|
||||
@@ -357,27 +357,27 @@ namespace BepInEx.Bootstrap
|
||||
#region Config
|
||||
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigUnityLogging = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigUnityLogging = ConfigFile.CoreConfig.Bind(
|
||||
"Logging", "UnityLogListening",
|
||||
true,
|
||||
"Enables showing unity log messages in the BepInEx logging system.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigDiskWriteUnityLog = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigDiskWriteUnityLog = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Disk", "WriteUnityLog",
|
||||
false,
|
||||
"Include unity log messages in log file output.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigDiskAppend = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigDiskAppend = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Disk", "AppendLog",
|
||||
false,
|
||||
"Appends to the log file instead of overwriting, on game startup.");
|
||||
|
||||
private static readonly ConfigEntry<bool> ConfigDiskLogging = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> ConfigDiskLogging = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Disk", "Enabled",
|
||||
true,
|
||||
"Enables writing log messages to disk.");
|
||||
|
||||
private static readonly ConfigEntry<LogLevel> ConfigDiskConsoleDisplayedLevel = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<LogLevel> ConfigDiskConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Disk", "DisplayedLogLevel",
|
||||
LogLevel.Info,
|
||||
"Only displays the specified log level and above in the console output.");
|
||||
|
||||
@@ -251,7 +251,7 @@ namespace BepInEx.Bootstrap
|
||||
|
||||
#region Config
|
||||
|
||||
private static readonly ConfigEntry<bool> EnableAssemblyCache = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<bool> EnableAssemblyCache = ConfigFile.CoreConfig.Bind(
|
||||
"Caching", "EnableAssemblyCache",
|
||||
true,
|
||||
"Enable/disable assembly metadata cache\nEnabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers.");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
@@ -11,7 +12,7 @@ namespace BepInEx.Configuration
|
||||
/// <summary>
|
||||
/// A helper class to handle persistent data. All public methods are thread-safe.
|
||||
/// </summary>
|
||||
public class ConfigFile
|
||||
public class ConfigFile : IDictionary<ConfigDefinition, ConfigEntryBase>
|
||||
{
|
||||
private readonly BepInPlugin _ownerMetadata;
|
||||
|
||||
@@ -22,30 +23,23 @@ namespace BepInEx.Configuration
|
||||
/// </summary>
|
||||
protected Dictionary<ConfigDefinition, ConfigEntryBase> Entries { get; } = new Dictionary<ConfigDefinition, ConfigEntryBase>();
|
||||
|
||||
private Dictionary<ConfigDefinition, string> HomelessEntries { get; } = new Dictionary<ConfigDefinition, string>();
|
||||
private Dictionary<ConfigDefinition, string> OrphanedEntries { get; } = new Dictionary<ConfigDefinition, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Create a list with all config entries inside of this config file.
|
||||
/// </summary>
|
||||
[Obsolete("Use GetConfigEntries instead")]
|
||||
[Obsolete("Use Keys instead")]
|
||||
public ReadOnlyCollection<ConfigDefinition> ConfigDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_ioLock) return Entries.Keys.ToList().AsReadOnly();
|
||||
lock (_ioLock)
|
||||
{
|
||||
return Entries.Keys.ToList().AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an array with all config entries inside of this config file. Should be only used for metadata purposes.
|
||||
/// If you want to access and modify an existing setting then use <see cref="AddSetting{T}(ConfigDefinition,T,ConfigDescription)"/>
|
||||
/// instead with no description.
|
||||
/// </summary>
|
||||
public ConfigEntryBase[] GetConfigEntries()
|
||||
{
|
||||
lock (_ioLock) return Entries.Values.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full path to the config file. The file might not exist until a setting is added and changed, or <see cref="Save"/> is called.
|
||||
/// </summary>
|
||||
@@ -87,7 +81,6 @@ namespace BepInEx.Configuration
|
||||
#region Save/Load
|
||||
|
||||
private readonly object _ioLock = new object();
|
||||
private bool _disableSaving;
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the config from disk. Unsaved changes are lost.
|
||||
@@ -96,47 +89,38 @@ namespace BepInEx.Configuration
|
||||
{
|
||||
lock (_ioLock)
|
||||
{
|
||||
HomelessEntries.Clear();
|
||||
OrphanedEntries.Clear();
|
||||
|
||||
try
|
||||
string currentSection = string.Empty;
|
||||
|
||||
foreach (string rawLine in File.ReadAllLines(ConfigFilePath))
|
||||
{
|
||||
_disableSaving = true;
|
||||
string line = rawLine.Trim();
|
||||
|
||||
string currentSection = string.Empty;
|
||||
if (line.StartsWith("#")) //comment
|
||||
continue;
|
||||
|
||||
foreach (string rawLine in File.ReadAllLines(ConfigFilePath))
|
||||
if (line.StartsWith("[") && line.EndsWith("]")) //section
|
||||
{
|
||||
string line = rawLine.Trim();
|
||||
|
||||
if (line.StartsWith("#")) //comment
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("[") && line.EndsWith("]")) //section
|
||||
{
|
||||
currentSection = line.Substring(1, line.Length - 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
string[] split = line.Split('='); //actual config line
|
||||
if (split.Length != 2)
|
||||
continue; //empty/invalid line
|
||||
|
||||
string currentKey = split[0].Trim();
|
||||
string currentValue = split[1].Trim();
|
||||
|
||||
var definition = new ConfigDefinition(currentSection, currentKey);
|
||||
|
||||
Entries.TryGetValue(definition, out ConfigEntryBase entry);
|
||||
|
||||
if (entry != null)
|
||||
entry.SetSerializedValue(currentValue);
|
||||
else
|
||||
HomelessEntries[definition] = currentValue;
|
||||
currentSection = line.Substring(1, line.Length - 2);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_disableSaving = false;
|
||||
|
||||
string[] split = line.Split('='); //actual config line
|
||||
if (split.Length != 2)
|
||||
continue; //empty/invalid line
|
||||
|
||||
string currentKey = split[0].Trim();
|
||||
string currentValue = split[1].Trim();
|
||||
|
||||
var definition = new ConfigDefinition(currentSection, currentKey);
|
||||
|
||||
Entries.TryGetValue(definition, out ConfigEntryBase entry);
|
||||
|
||||
if (entry != null)
|
||||
entry.SetSerializedValue(currentValue);
|
||||
else
|
||||
OrphanedEntries[definition] = currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,8 +134,6 @@ namespace BepInEx.Configuration
|
||||
{
|
||||
lock (_ioLock)
|
||||
{
|
||||
if (_disableSaving) return;
|
||||
|
||||
string directoryName = Path.GetDirectoryName(ConfigFilePath);
|
||||
if (directoryName != null) Directory.CreateDirectory(directoryName);
|
||||
|
||||
@@ -165,7 +147,7 @@ namespace BepInEx.Configuration
|
||||
}
|
||||
|
||||
var allConfigEntries = Entries.Select(x => new { x.Key, entry = x.Value, value = x.Value.GetSerializedValue() })
|
||||
.Concat(HomelessEntries.Select(x => new { x.Key, entry = (ConfigEntryBase)null, value = x.Value }));
|
||||
.Concat(OrphanedEntries.Select(x => new { x.Key, entry = (ConfigEntryBase)null, value = x.Value }));
|
||||
|
||||
foreach (var sectionKv in allConfigEntries.GroupBy(x => x.Key.Section).OrderBy(x => x.Key))
|
||||
{
|
||||
@@ -192,32 +174,40 @@ namespace BepInEx.Configuration
|
||||
#region Wraps
|
||||
|
||||
/// <summary>
|
||||
/// Access one of the existing settings. If the setting has not been added yet, null is returned.
|
||||
/// Access one of the existing settings. If the setting has not been added yet, false is returned. Otherwise, true.
|
||||
/// If the setting exists but has a different type than T, an exception is thrown.
|
||||
/// New settings should be added with <see cref="AddSetting{T}(ConfigDefinition,T,ConfigDescription)"/>.
|
||||
/// New settings should be added with <see cref="Bind{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the value contained in this setting.</typeparam>
|
||||
/// <param name="configDefinition">Section and Key of the setting.</param>
|
||||
public ConfigEntry<T> GetSetting<T>(ConfigDefinition configDefinition)
|
||||
/// <param name="entry">The ConfigEntry value to return.</param>
|
||||
public bool TryGetEntry<T>(ConfigDefinition configDefinition, out ConfigEntry<T> entry)
|
||||
{
|
||||
lock (_ioLock)
|
||||
{
|
||||
Entries.TryGetValue(configDefinition, out var entry);
|
||||
return (ConfigEntry<T>)entry;
|
||||
if (Entries.TryGetValue(configDefinition, out var rawEntry))
|
||||
{
|
||||
entry = (ConfigEntry<T>)rawEntry;
|
||||
return true;
|
||||
}
|
||||
|
||||
entry = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Access one of the existing settings. If the setting has not been added yet, null is returned.
|
||||
/// If the setting exists but has a different type than T, an exception is thrown.
|
||||
/// New settings should be added with <see cref="AddSetting{T}(ConfigDefinition,T,ConfigDescription)"/>.
|
||||
/// New settings should be added with <see cref="Bind{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the value contained in this setting.</typeparam>
|
||||
/// <param name="section">Section/category/group of the setting. Settings are grouped by this.</param>
|
||||
/// <param name="key">Name of the setting.</param>
|
||||
public ConfigEntry<T> GetSetting<T>(string section, string key)
|
||||
/// <param name="entry">The ConfigEntry value to return.</param>
|
||||
public bool TryGetEntry<T>(string section, string key, out ConfigEntry<T> entry)
|
||||
{
|
||||
return GetSetting<T>(new ConfigDefinition(section, key));
|
||||
return TryGetEntry<T>(new ConfigDefinition(section, key), out entry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -228,39 +218,30 @@ namespace BepInEx.Configuration
|
||||
/// <param name="configDefinition">Section and Key of the setting.</param>
|
||||
/// <param name="defaultValue">Value of the setting if the setting was not created yet.</param>
|
||||
/// <param name="configDescription">Description of the setting shown to the user and other metadata.</param>
|
||||
public ConfigEntry<T> AddSetting<T>(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null)
|
||||
public ConfigEntry<T> Bind<T>(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null)
|
||||
{
|
||||
if (!TomlTypeConverter.CanConvert(typeof(T)))
|
||||
throw new ArgumentException($"Type {typeof(T)} is not supported by the config system. Supported types: {string.Join(", ", TomlTypeConverter.GetSupportedTypes().Select(x => x.Name).ToArray())}");
|
||||
|
||||
lock (_ioLock)
|
||||
{
|
||||
if (Entries.ContainsKey(configDefinition))
|
||||
throw new ArgumentException("The setting " + configDefinition + " has already been created. Use GetSetting to get it.");
|
||||
if (Entries.TryGetValue(configDefinition, out var rawEntry))
|
||||
return (ConfigEntry<T>)rawEntry;
|
||||
|
||||
try
|
||||
var entry = new ConfigEntry<T>(this, configDefinition, defaultValue, configDescription);
|
||||
|
||||
Entries[configDefinition] = entry;
|
||||
|
||||
if (OrphanedEntries.TryGetValue(configDefinition, out string homelessValue))
|
||||
{
|
||||
_disableSaving = true;
|
||||
|
||||
var entry = new ConfigEntry<T>(this, configDefinition, defaultValue, configDescription);
|
||||
Entries[configDefinition] = entry;
|
||||
|
||||
if (HomelessEntries.TryGetValue(configDefinition, out string homelessValue))
|
||||
{
|
||||
entry.SetSerializedValue(homelessValue);
|
||||
HomelessEntries.Remove(configDefinition);
|
||||
}
|
||||
|
||||
_disableSaving = false;
|
||||
if (SaveOnConfigSet)
|
||||
Save();
|
||||
|
||||
return entry;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_disableSaving = false;
|
||||
entry.SetSerializedValue(homelessValue);
|
||||
OrphanedEntries.Remove(configDefinition);
|
||||
}
|
||||
|
||||
if (SaveOnConfigSet)
|
||||
Save();
|
||||
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,8 +254,8 @@ namespace BepInEx.Configuration
|
||||
/// <param name="key">Name of the setting.</param>
|
||||
/// <param name="defaultValue">Value of the setting if the setting was not created yet.</param>
|
||||
/// <param name="configDescription">Description of the setting shown to the user and other metadata.</param>
|
||||
public ConfigEntry<T> AddSetting<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null)
|
||||
=> AddSetting(new ConfigDefinition(section, key), defaultValue, configDescription);
|
||||
public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null)
|
||||
=> Bind(new ConfigDefinition(section, key), defaultValue, configDescription);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new setting. The setting is saved to drive and loaded automatically.
|
||||
@@ -285,27 +266,27 @@ namespace BepInEx.Configuration
|
||||
/// <param name="key">Name of the setting.</param>
|
||||
/// <param name="defaultValue">Value of the setting if the setting was not created yet.</param>
|
||||
/// <param name="description">Simple description of the setting shown to the user.</param>
|
||||
public ConfigEntry<T> AddSetting<T>(string section, string key, T defaultValue, string description)
|
||||
=> AddSetting(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description));
|
||||
public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description)
|
||||
=> Bind(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description));
|
||||
|
||||
/// <summary>
|
||||
/// Access a setting. Use AddSetting and GetSetting instead.
|
||||
/// Access a setting. Use Bind and GetSetting instead.
|
||||
/// </summary>
|
||||
[Obsolete("Use AddSetting and GetSetting instead")]
|
||||
[Obsolete("Use Bind instead")]
|
||||
public ConfigWrapper<T> Wrap<T>(string section, string key, string description = null, T defaultValue = default(T))
|
||||
{
|
||||
lock (_ioLock)
|
||||
{
|
||||
var definition = new ConfigDefinition(section, key, description);
|
||||
var setting = GetSetting<T>(definition) ?? AddSetting(definition, defaultValue, string.IsNullOrEmpty(description) ? null : new ConfigDescription(description));
|
||||
var setting = Bind(definition, defaultValue, string.IsNullOrEmpty(description) ? null : new ConfigDescription(description));
|
||||
return new ConfigWrapper<T>(setting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Access a setting. Use AddSetting and GetSetting instead.
|
||||
/// Access a setting. Use Bind and GetSetting instead.
|
||||
/// </summary>
|
||||
[Obsolete("Use AddSetting and GetSetting instead")]
|
||||
[Obsolete("Use Bind instead")]
|
||||
public ConfigWrapper<T> Wrap<T>(ConfigDefinition configDefinition, T defaultValue = default(T))
|
||||
=> Wrap(configDefinition.Section, configDefinition.Key, null, defaultValue);
|
||||
|
||||
@@ -354,5 +335,143 @@ namespace BepInEx.Configuration
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<KeyValuePair<ConfigDefinition, ConfigEntryBase>> GetEnumerator()
|
||||
{
|
||||
// We can't really do a read lock for this
|
||||
return Entries.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>.Add(KeyValuePair<ConfigDefinition, ConfigEntryBase> item)
|
||||
{
|
||||
lock (_ioLock)
|
||||
Entries.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Contains(KeyValuePair<ConfigDefinition, ConfigEntryBase> item)
|
||||
{
|
||||
lock (_ioLock)
|
||||
return ((ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)Entries).Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>.CopyTo(KeyValuePair<ConfigDefinition, ConfigEntryBase>[] array, int arrayIndex)
|
||||
{
|
||||
lock (_ioLock)
|
||||
((ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)Entries).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<ConfigDefinition, ConfigEntryBase>>.Remove(KeyValuePair<ConfigDefinition, ConfigEntryBase> item)
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.Remove(item.Key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ContainsKey(ConfigDefinition key)
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Add(ConfigDefinition key, ConfigEntryBase value)
|
||||
{
|
||||
throw new InvalidOperationException("Directly adding a config entry is not supported");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Remove(ConfigDefinition key)
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.Remove(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear()
|
||||
{
|
||||
lock (_ioLock)
|
||||
Entries.Clear();
|
||||
}
|
||||
|
||||
bool IDictionary<ConfigDefinition, ConfigEntryBase>.TryGetValue(ConfigDefinition key, out ConfigEntryBase value)
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
ConfigEntryBase IDictionary<ConfigDefinition, ConfigEntryBase>.this[ConfigDefinition key]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries[key];
|
||||
}
|
||||
set => throw new InvalidOperationException("Directly setting a config entry is not supported");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConfigEntryBase this[ConfigDefinition key]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries[key];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
public ConfigEntryBase this[string section, string key]
|
||||
=> this[new ConfigDefinition(section, key)];
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ConfigDefinitions that the ConfigFile contains.
|
||||
/// <para>Creates a new array when the property is accessed. Thread-safe.</para>
|
||||
/// </summary>
|
||||
public ICollection<ConfigDefinition> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.Keys.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ConfigEntryBase values that the ConfigFile contains.
|
||||
/// <para>Creates a new array when the property is accessed. Thread-safe.</para>
|
||||
/// </summary>
|
||||
ICollection<ConfigEntryBase> IDictionary<ConfigDefinition, ConfigEntryBase>.Values
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_ioLock)
|
||||
return Entries.Values.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace BepInEx.Configuration
|
||||
/// Provides access to a single setting inside of a <see cref="Configuration.ConfigFile"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the setting.</typeparam>
|
||||
[Obsolete("Use ConfigFile from new AddSetting overloads instead")]
|
||||
[Obsolete("Use ConfigFile from new Bind overloads instead")]
|
||||
public sealed class ConfigWrapper<T>
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace BepInEx.Configuration
|
||||
/// triggered when the user presses the exact combination. For example, <c>F + LeftCtrl</c> will trigger only if user
|
||||
/// presses and holds only LeftCtrl, and then presses F. If any other keys are pressed, the shortcut will not trigger.
|
||||
///
|
||||
/// Can be used as a value of a setting in <see cref="ConfigFile.AddSetting{T}(ConfigDefinition,T,ConfigDescription)"/>
|
||||
/// Can be used as a value of a setting in <see cref="ConfigFile.Bind{T}(ConfigDefinition,T,ConfigDescription)"/>
|
||||
/// to allow user to change this shortcut and have the changes saved.
|
||||
///
|
||||
/// How to use: Use <see cref="IsDown"/> in this class instead of <see cref="Input.GetKeyDown(KeyCode)"/> in the Update loop.
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace UnityInjector.ConsoleUtil
|
||||
{
|
||||
internal class ConsoleWindow
|
||||
{
|
||||
public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.AddSetting(
|
||||
public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Console", "Enabled",
|
||||
false,
|
||||
"Enables showing a console for log output.");
|
||||
|
||||
public static readonly ConfigEntry<bool> ConfigConsoleShiftJis = ConfigFile.CoreConfig.AddSetting(
|
||||
public static readonly ConfigEntry<bool> ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Console", "ShiftJisEncoding",
|
||||
false,
|
||||
"If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.");
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace BepInEx.Logging
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.AddSetting(
|
||||
private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind(
|
||||
"Logging.Console","DisplayedLogLevel",
|
||||
LogLevel.Info,
|
||||
"Only displays the specified log level and above in the console output.");
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace BepInEx.Configuration.Tests
|
||||
{
|
||||
var c = MakeConfig();
|
||||
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
var lines = File.ReadAllLines(c.ConfigFilePath);
|
||||
Assert.AreEqual(1, lines.Count(x => x.Equals("[Cat]")));
|
||||
Assert.AreEqual(1, lines.Count(x => x.Equals("## Test")));
|
||||
@@ -69,7 +69,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void AutoSaveTest()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
c.Bind("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
|
||||
var eventFired = new AutoResetEvent(false);
|
||||
c.ConfigReloaded += (sender, args) => eventFired.Set();
|
||||
@@ -85,9 +85,9 @@ namespace BepInEx.Configuration.Tests
|
||||
var c = MakeConfig();
|
||||
File.WriteAllText(c.ConfigFilePath, "[Cat]\n# Test\nKey=1\n");
|
||||
c.Reload();
|
||||
var w = c.AddSetting("Cat", "Key", 0, "Test");
|
||||
var w = c.Bind("Cat", "Key", 0, "Test");
|
||||
Assert.AreEqual(w.Value, 1);
|
||||
var w2 = c.AddSetting("Cat", "Key2", 0, new ConfigDescription("Test"));
|
||||
var w2 = c.Bind("Cat", "Key2", 0, new ConfigDescription("Test"));
|
||||
Assert.AreEqual(w2.Value, 0);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void ReadTest2()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
Assert.AreEqual(w.Value, 0);
|
||||
|
||||
File.WriteAllText(c.ConfigFilePath, "[Cat]\n# Test\nKey = 1 \n");
|
||||
@@ -121,7 +121,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void EventTestWrapper()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
|
||||
File.WriteAllText(c.ConfigFilePath, "[Cat]\n# Test\nKey=1\n");
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace BepInEx.Configuration.Tests
|
||||
File.WriteAllText(c.ConfigFilePath, "[Cat]\n# Test\nKey=1\nHomeless=0");
|
||||
c.Reload();
|
||||
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
|
||||
c.Save();
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace BepInEx.Configuration.Tests
|
||||
var c = MakeConfig();
|
||||
var eventFired = false;
|
||||
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test"));
|
||||
w.SettingChanged += (sender, args) => eventFired = true;
|
||||
|
||||
Assert.IsFalse(eventFired);
|
||||
@@ -169,7 +169,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void ValueRangeTest()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<int>(0, 2)));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<int>(0, 2)));
|
||||
|
||||
Assert.AreEqual(0, w.Value);
|
||||
w.Value = 2;
|
||||
@@ -185,7 +185,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void ValueRangeBadTypeTest()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<float>(1, 2)));
|
||||
c.Bind("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<float>(1, 2)));
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void ValueRangeDefaultTest()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<int>(1, 2)));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<int>(1, 2)));
|
||||
|
||||
Assert.AreEqual(w.Value, 1);
|
||||
}
|
||||
@@ -206,7 +206,7 @@ namespace BepInEx.Configuration.Tests
|
||||
File.WriteAllText(c.ConfigFilePath, "[Cat]\nKey = 1\n");
|
||||
c.Reload();
|
||||
|
||||
var w = c.AddSetting("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<int>(0, 2)));
|
||||
var w = c.Bind("Cat", "Key", 0, new ConfigDescription("Test", new AcceptableValueRange<int>(0, 2)));
|
||||
|
||||
Assert.AreEqual(w.Value, 1);
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void ValueListTest()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", "kek", new ConfigDescription("Test", new AcceptableValueList<string>("lel", "kek", "wew", "why")));
|
||||
var w = c.Bind("Cat", "Key", "kek", new ConfigDescription("Test", new AcceptableValueList<string>("lel", "kek", "wew", "why")));
|
||||
|
||||
Assert.AreEqual("kek", w.Value);
|
||||
w.Value = "wew";
|
||||
@@ -240,7 +240,7 @@ namespace BepInEx.Configuration.Tests
|
||||
Assert.AreEqual(shortcut, d);
|
||||
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", new KeyboardShortcut(KeyCode.A, KeyCode.LeftShift));
|
||||
var w = c.Bind("Cat", "Key", new KeyboardShortcut(KeyCode.A, KeyCode.LeftShift));
|
||||
Assert.AreEqual(new KeyboardShortcut(KeyCode.A, KeyCode.LeftShift), w.Value);
|
||||
|
||||
w.Value = shortcut;
|
||||
@@ -255,7 +255,7 @@ namespace BepInEx.Configuration.Tests
|
||||
|
||||
var c = MakeConfig();
|
||||
|
||||
var w = c.AddSetting("Cat", "Key", KeyboardShortcut.Empty, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", KeyboardShortcut.Empty, new ConfigDescription("Test"));
|
||||
|
||||
Assert.AreEqual("", w.GetSerializedValue());
|
||||
|
||||
@@ -280,7 +280,7 @@ namespace BepInEx.Configuration.Tests
|
||||
const string testVal = "new line\n test \t\0";
|
||||
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", testVal, new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", testVal, new ConfigDescription("Test"));
|
||||
|
||||
Assert.AreEqual(testVal, w.Value);
|
||||
Assert.IsFalse(w.GetSerializedValue().Any(x => x == '\n'));
|
||||
@@ -298,7 +298,7 @@ namespace BepInEx.Configuration.Tests
|
||||
public void UnescapedPathString()
|
||||
{
|
||||
var c = MakeConfig();
|
||||
var w = c.AddSetting("Cat", "Key", "", new ConfigDescription("Test"));
|
||||
var w = c.Bind("Cat", "Key", "", new ConfigDescription("Test"));
|
||||
|
||||
var unescaped = @"D:\test\p ath";
|
||||
foreach (string testVal in new[] { unescaped, @"D:\\test\\p ath" })
|
||||
|
||||
Reference in new issue
Block a user