Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ZioConfigFile v1.0.2
ZioConfigFile.dll
Decompiled 2 years agousing 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 { } }