using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Zio;
using Zio.FileSystems;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ZioConfigFile")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+989b526372e295d2a3d8d6eff4aa3222af20bb5c")]
[assembly: AssemblyProduct("ZioConfigFile")]
[assembly: AssemblyTitle("ZioConfigFile")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ZioConfigFile
{
public class ZioConfigEntry<T> : ZioConfigEntryBase
{
private T _typedValue;
public T Value
{
get
{
return _typedValue;
}
set
{
value = ClampValue(value);
if (!value.Equals(_typedValue))
{
T typedValue = _typedValue;
_typedValue = value;
OnSettingChanged(this, typedValue);
}
}
}
public override object BoxedValue
{
get
{
return Value;
}
set
{
Value = (T)value;
}
}
public ZioConfigEntry(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription)
: base(configDefinition, typeof(T), defaultValue, configDescription)
{
}
public static implicit operator ConfigEntry<T>(ZioConfigEntry<T> zioEntry)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
if (zioEntry.configEntryFallback != null)
{
return (ConfigEntry<T>)(object)zioEntry.configEntryFallback;
}
if (ZioConfigEntryBase.fallbackConfigFile == null)
{
ZioConfigEntryBase.fallbackConfigFile = new ConfigFile("", false)
{
SaveOnConfigSet = false
};
}
ConfigEntry<T> fallback = new ConfigEntry<T>(ZioConfigEntryBase.fallbackConfigFile, zioEntry.Definition, (T)zioEntry.DefaultValue, zioEntry.Description);
fallback.SettingChanged += delegate
{
if (!zioEntry.duckChanged)
{
zioEntry.duckFallbackChanged = true;
zioEntry.Value = fallback.Value;
zioEntry.duckFallbackChanged = false;
}
};
zioEntry.SettingChanged += delegate
{
if (!zioEntry.duckFallbackChanged)
{
zioEntry.duckChanged = true;
fallback.Value = zioEntry.Value;
zioEntry.duckChanged = false;
}
};
zioEntry.configEntryFallback = (ConfigEntryBase)(object)fallback;
return (ConfigEntry<T>)(object)zioEntry.configEntryFallback;
}
}
public abstract class ZioConfigEntryBase
{
public bool DontSaveOnChange;
protected ConfigEntryBase configEntryFallback;
protected bool duckChanged;
protected bool duckFallbackChanged;
protected static ConfigFile fallbackConfigFile;
public ConfigDefinition Definition { get; }
public ConfigDescription Description { get; }
public Type SettingType { get; }
public object DefaultValue { get; }
public abstract object BoxedValue { get; set; }
public event Action<ZioConfigEntryBase, object, bool> SettingChanged;
protected ZioConfigEntryBase(ConfigDefinition configDefinition, Type settingType, object defaultValue, ConfigDescription configDescription)
{
Definition = configDefinition ?? throw new ArgumentNullException("configDefinition");
SettingType = settingType ?? throw new ArgumentNullException("settingType");
Description = configDescription ?? ConfigDescription.Empty;
if (Description.AcceptableValues != null && !SettingType.IsAssignableFrom(Description.AcceptableValues.ValueType))
{
throw new AggregateException("configDescription.AcceptableValues is for a different type than the type of this setting");
}
DefaultValue = defaultValue;
BoxedValue = defaultValue;
}
public string GetSerializedValue()
{
return TomlTypeConverter.ConvertToString(BoxedValue, SettingType);
}
public void SetSerializedValue(string value)
{
try
{
BoxedValue = TomlTypeConverter.ConvertToValue(value, SettingType);
}
catch (Exception ex)
{
ZioConfigFile.Logger.LogWarning((object)$"Config value of setting \"{Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
}
}
public T ClampValue<T>(T value)
{
return (Description.AcceptableValues != null) ? ((T)Description.AcceptableValues.Clamp((object)value)) : value;
}
public void OnSettingChanged(ZioConfigEntryBase config, object oldValue)
{
this.SettingChanged?.Invoke(config, oldValue, DontSaveOnChange);
}
public void WriteDescription(StreamWriter writer)
{
if (!string.IsNullOrEmpty(Description.Description))
{
writer.WriteLine("## " + Description.Description.Replace("\n", "\n## "));
}
writer.WriteLine("# Setting type: " + SettingType.Name);
writer.WriteLine("# Default value: " + TomlTypeConverter.ConvertToString(DefaultValue, SettingType));
if (Description.AcceptableValues != null)
{
writer.WriteLine(Description.AcceptableValues.ToDescriptionString());
}
else if (SettingType.IsEnum)
{
writer.WriteLine("# Acceptable values: " + string.Join(", ", Enum.GetNames(SettingType)));
if (SettingType.GetCustomAttributes(typeof(FlagsAttribute), inherit: true).Any())
{
writer.WriteLine("# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)");
}
}
}
}
public class ZioConfigFile : IDictionary<ConfigDefinition, ZioConfigEntryBase>, ICollection<KeyValuePair<ConfigDefinition, ZioConfigEntryBase>>, IEnumerable<KeyValuePair<ConfigDefinition, ZioConfigEntryBase>>, IEnumerable
{
protected object _ioLock = new object();
private static readonly FileSystem InternalFileSystem = (FileSystem)new PhysicalFileSystem();
private readonly Stopwatch saveStopwatch = new Stopwatch();
private bool _waitingForSaves;
public int waitDuration = 1000;
public BepInPlugin OwnerMetadata { get; }
public FileSystem FileSystem { get; }
public UPath FilePath { get; }
public Dictionary<ConfigDefinition, ZioConfigEntryBase> Entries { get; } = new Dictionary<ConfigDefinition, ZioConfigEntryBase>();
protected Dictionary<ConfigDefinition, string> OrphanedEntries { get; } = new Dictionary<ConfigDefinition, string>();
public static ManualLogSource Logger { get; } = new ManualLogSource("ZioConfigFile");
public static FileSystem BepinConfigFileSystem { get; } = (FileSystem)new SubFileSystem((IFileSystem)(object)InternalFileSystem, InternalFileSystem.ConvertPathFromInternal(Paths.ConfigPath), true);
public bool SaveOnConfigSet { get; set; } = true;
public int Count
{
get
{
lock (_ioLock)
{
return Entries.Count;
}
}
}
public bool IsReadOnly => false;
ZioConfigEntryBase IDictionary<ConfigDefinition, ZioConfigEntryBase>.this[ConfigDefinition key]
{
get
{
lock (_ioLock)
{
return Entries[key];
}
}
set
{
throw new InvalidOperationException("Directly setting a config entry is not supported");
}
}
public ZioConfigEntryBase this[ConfigDefinition key]
{
get
{
lock (_ioLock)
{
return Entries[key];
}
}
}
public ZioConfigEntryBase this[string section, string key] => this[new ConfigDefinition(section, key)];
public ICollection<ConfigDefinition> Keys
{
get
{
lock (_ioLock)
{
return Entries.Keys;
}
}
}
ICollection<ZioConfigEntryBase> IDictionary<ConfigDefinition, ZioConfigEntryBase>.Values
{
get
{
lock (_ioLock)
{
return Entries.Values;
}
}
}
public event Action ConfigReloaded;
public event Action<ZioConfigEntryBase, object> SettingChanged;
public ZioConfigFile(BepInPlugin plugin, bool saveOnInit = true)
: this(BepinConfigFileSystem, UPath.op_Implicit(plugin.Name), saveOnInit, plugin)
{
}//IL_000c: Unknown result type (might be due to invalid IL or missing references)
public ZioConfigFile(FileSystem fileSystem, UPath path, bool saveOnInit, BaseUnityPlugin unityPlugin)
: this(fileSystem, path, saveOnInit, unityPlugin.Info.Metadata)
{
}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
public ZioConfigFile(FileSystem fileSystem, UPath path, bool saveOnInit, BepInPlugin bepInPlugin = null)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
OwnerMetadata = bepInPlugin;
FileSystem = fileSystem;
FilePath = path;
if (fileSystem.FileExists(path))
{
Reload();
}
else if (saveOnInit)
{
Save();
}
}
public void Reload()
{
InternalReload();
}
protected virtual void InternalReload()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Expected O, but got Unknown
lock (_ioLock)
{
if (!FileSystem.FileExists(FilePath))
{
return;
}
OrphanedEntries.Clear();
using Stream stream = FileSystem.OpenFile(FilePath, FileMode.Open, FileAccess.Read, FileShare.None);
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
if (!streamReader.EndOfStream)
{
string text = "";
string text2 = streamReader.ReadLine();
do
{
string text3 = text2.Trim();
if (text3.StartsWith("#"))
{
continue;
}
if (text3.StartsWith("[") && text3.EndsWith("]"))
{
text = text3.Substring(1, text3.Length - 2);
continue;
}
string[] array = text3.Split('=');
if (array.Length == 2)
{
ConfigDefinition key = new ConfigDefinition(text, array[0].Trim());
if (Entries.TryGetValue(key, out var value))
{
value.SetSerializedValue(array[1].Trim());
}
else
{
OrphanedEntries[key] = array[1].Trim();
}
}
}
while ((text2 = streamReader.ReadLine()) != null);
}
}
OnConfigReloaded();
}
public void OnConfigReloaded()
{
Delegate[] array = this.ConfigReloaded?.GetInvocationList();
if (array == null)
{
return;
}
Delegate[] array2 = array;
foreach (Delegate @delegate in array2)
{
try
{
(@delegate as Action)?.Invoke();
}
catch (Exception ex)
{
Logger.LogError((object)ex);
}
}
}
public void OnSettingChanged(ZioConfigEntryBase changedSetting, object valueBefore, bool ignoreSave)
{
if (!ignoreSave && SaveOnConfigSet)
{
Save();
}
Delegate[] array = this.SettingChanged?.GetInvocationList();
if (array == null)
{
return;
}
Delegate[] array2 = array;
foreach (Delegate @delegate in array2)
{
try
{
(@delegate as Action<ZioConfigEntryBase, object>)?.Invoke(changedSetting, valueBefore);
}
catch (Exception ex)
{
Logger.LogError((object)ex);
}
}
}
protected virtual void SaveThread()
{
//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
//IL_0239: Unknown result type (might be due to invalid IL or missing references)
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_024f: Unknown result type (might be due to invalid IL or missing references)
//IL_025b: Unknown result type (might be due to invalid IL or missing references)
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_029a: Unknown result type (might be due to invalid IL or missing references)
while (saveStopwatch.ElapsedMilliseconds < waitDuration)
{
Task.Delay(Mathf.FloorToInt((float)waitDuration * 0.1f));
}
using MemoryStream memoryStream = new MemoryStream();
using StreamWriter streamWriter = new StreamWriter(memoryStream, Encoding.UTF8);
if (OwnerMetadata != null)
{
streamWriter.WriteLine($"## Settings file was created by plugin {OwnerMetadata.Name} v{OwnerMetadata.Version}");
streamWriter.WriteLine("## Plugin GUID: " + OwnerMetadata.GUID);
streamWriter.WriteLine();
}
lock (_ioLock)
{
foreach (IGrouping<string, (ConfigDefinition, ZioConfigEntryBase, string)> item in from x in Entries.Select((KeyValuePair<ConfigDefinition, ZioConfigEntryBase> x) => (x.Key, x.Value, x.Value.GetSerializedValue())).Concat(((IEnumerable<KeyValuePair<ConfigDefinition, string>>)OrphanedEntries).Select((Func<KeyValuePair<ConfigDefinition, string>, (ConfigDefinition, ZioConfigEntryBase, string)>)((KeyValuePair<ConfigDefinition, string> x) => (x.Key, null, x.Value))))
group x by x.Key.Section into x
orderby x.Key
select x)
{
streamWriter.WriteLine("[" + item.Key + "]");
foreach (var item2 in item)
{
streamWriter.WriteLine();
item2.Item2?.WriteDescription(streamWriter);
streamWriter.WriteLine(item2.Item1.Key + " = " + item2.Item3);
}
streamWriter.WriteLine();
}
streamWriter.Flush();
}
try
{
UPath filePath = FilePath;
if (((UPath)(ref filePath)).IsNull)
{
goto IL_0278;
}
filePath = FilePath;
if (((UPath)(ref filePath)).IsEmpty || FilePath == UPath.op_Implicit("/"))
{
goto IL_0278;
}
FileSystem.CreateDirectory(UPathExtensions.GetDirectory(FilePath));
goto end_IL_0237;
IL_0278:
Logger.LogWarning((object)"Tried to create a ZioConfigFile with a null, empty or root path, escaping.");
return;
end_IL_0237:;
}
catch (UnauthorizedAccessException ex)
{
Debug.LogError((object)ex);
}
using Stream stream = FileSystem.OpenFile(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
stream.Write(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
stream.Close();
_waitingForSaves = false;
}
public void Save()
{
saveStopwatch.Restart();
if (!_waitingForSaves)
{
new Thread(SaveThread).Start();
}
_waitingForSaves = true;
}
public bool TryGetEntry<T>(string section, string key, out ZioConfigEntry<T> entry)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
return TryGetEntry(new ConfigDefinition(section, key), out entry);
}
public bool TryGetEntry<T>(ConfigDefinition configDefinition, out ZioConfigEntry<T> entry)
{
lock (_ioLock)
{
if (Entries.TryGetValue(configDefinition, out var value))
{
entry = (ZioConfigEntry<T>)value;
return true;
}
entry = null;
return false;
}
}
public virtual ZioConfigEntry<T> Bind<T>(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null)
{
if (!TomlTypeConverter.CanConvert(typeof(T)))
{
throw new ArgumentException(string.Format("Type {0} is not supported by the config system. Supported types: {1}", typeof(T), string.Join(", ", (from x in TomlTypeConverter.GetSupportedTypes()
select x.Name).ToArray())));
}
lock (_ioLock)
{
if (Entries.TryGetValue(configDefinition, out var value))
{
return (ZioConfigEntry<T>)value;
}
ZioConfigEntry<T> zioConfigEntry = new ZioConfigEntry<T>(configDefinition, defaultValue, configDescription);
Entries[configDefinition] = zioConfigEntry;
zioConfigEntry.SettingChanged += OnSettingChanged;
if (OrphanedEntries.TryGetValue(configDefinition, out var value2))
{
zioConfigEntry.SetSerializedValue(value2);
OrphanedEntries.Remove(configDefinition);
}
if (SaveOnConfigSet)
{
Save();
}
return zioConfigEntry;
}
}
public ZioConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_001b: Expected O, but got Unknown
return Bind(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
}
public ZioConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
return Bind(new ConfigDefinition(section, key), defaultValue, configDescription);
}
public IEnumerator<KeyValuePair<ConfigDefinition, ZioConfigEntryBase>> GetEnumerator()
{
return Entries.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
void ICollection<KeyValuePair<ConfigDefinition, ZioConfigEntryBase>>.Add(KeyValuePair<ConfigDefinition, ZioConfigEntryBase> item)
{
lock (_ioLock)
{
Entries.Add(item.Key, item.Value);
}
}
public bool Contains(KeyValuePair<ConfigDefinition, ZioConfigEntryBase> item)
{
return Entries.Contains(item);
}
public void CopyTo(KeyValuePair<ConfigDefinition, ZioConfigEntryBase>[] array, int arrayIndex)
{
lock (_ioLock)
{
((ICollection<KeyValuePair<ConfigDefinition, ZioConfigEntryBase>>)Entries).CopyTo(array, arrayIndex);
}
}
public bool Remove(KeyValuePair<ConfigDefinition, ZioConfigEntryBase> item)
{
lock (_ioLock)
{
return Entries.Remove(item.Key);
}
}
public bool ContainsKey(ConfigDefinition key)
{
lock (_ioLock)
{
return Entries.ContainsKey(key);
}
}
public void Add(ConfigDefinition key, ZioConfigEntryBase value)
{
throw new InvalidOperationException("Directly adding a config entry is not supported");
}
public bool Remove(ConfigDefinition key)
{
lock (_ioLock)
{
return Entries.Remove(key);
}
}
public void Clear()
{
lock (_ioLock)
{
Entries.Clear();
}
}
public bool TryGetValue(ConfigDefinition key, out ZioConfigEntryBase value)
{
lock (_ioLock)
{
return Entries.TryGetValue(key, out value);
}
}
}
[BepInPlugin("bubbet.zioconfigfile", "Zio Config File", "1.0.1")]
public class ZioConfigFilePlugin : BaseUnityPlugin
{
}
}