Decompiled source of MavsCoreLibrary v0.0.4

MavsLibCore.dll

Decompiled 9 months ago
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Gameplay.Utilities;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Mav's Work")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyDescription("Common functionality for my plugins, including implementing the base plugin structure and custom storage & logging support.")]
[assembly: AssemblyFileVersion("0.0.4.0")]
[assembly: AssemblyInformationalVersion("0.0.4+9a291d1228113adca1476a07141f1741227c36f6")]
[assembly: AssemblyProduct("Void Crew - Mavs Core Library")]
[assembly: AssemblyTitle("Mavs Core Library")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Maverik/VoidCrewMods/tree/main/MavsLibCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.4.0")]
[module: UnverifiableCode]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
public sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace MavsLibCore
{
	public interface IKey<out TKey> where TKey : IEquatable<TKey>
	{
		TKey Id { get; }
	}
	public interface IMetadata<out TKey> : IKey<TKey> where TKey : IEquatable<TKey>
	{
		string DisplayName { get; }

		Version Version { get; }
	}
	public interface ISupportsConfigFile
	{
		static ConfigDefinition SettingsVersionConfigDefinition => new ConfigDefinition("Config", "SettingsVersion");

		static ConfigDescription SettingsVersionConfigDescription => new ConfigDescription("Internal plugin configuration revision. Do NOT change.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				ReadOnly = false,
				IsAdvanced = true
			}
		});

		ulong SettingsVersion { get; set; }

		void LoadFrom(ConfigFile config);
	}
	public interface IVersionedMetadata<out TKey> : IMetadata<TKey>, IKey<TKey> where TKey : IEquatable<TKey>
	{
		uint SchemaRevision { get; }
	}
	public static class Extensions
	{
		public static T? As<T>(this object value, T? defaultValue = null) where T : class
		{
			return (value as T) ?? defaultValue;
		}

		public static T Cast<T>(this object value)
		{
			return (T)value;
		}

		public static T BindValue<T>(this ConfigFile config, ConfigDefinition definition, ConfigDescription description)
		{
			if (description != null)
			{
				object[] tags = description.Tags;
				if (tags != null && tags.Length > 0)
				{
					return config.Bind<T>(definition, (from x in description.Tags.OfType<ConfigurationManagerAttributes>()
						select (T)x.DefaultValue).SingleOrDefault(), description).Value;
				}
			}
			return default(T);
		}
	}
	public static class SetExtensions
	{
		public static T Set<T>(ref T field, T value, ManualLogSource? pluginLogger = null, [CallerArgumentExpression("field")] string fieldName = null)
		{
			ref T reference = ref field;
			T val = default(T);
			if (val == null)
			{
				val = reference;
				reference = ref val;
				if (val == null)
				{
					goto IL_003f;
				}
			}
			if (reference.Equals(value))
			{
				return field;
			}
			goto IL_003f;
			IL_003f:
			object obj = ((object)pluginLogger) ?? ((object)MavLogger.Default);
			((ManualLogSource)obj).LogDebug((object)$"{fieldName} was {field}");
			field = value;
			((ManualLogSource)obj).LogInfo((object)$"{fieldName} is {field}");
			return field;
		}

		public static TInstance Set<TInstance, TValue>(this TInstance? instance, MemberInfo info, Func<TValue, TValue> valueFunc, ManualLogSource? pluginLogger = null, [CallerArgumentExpression("info")] string infoName = null)
		{
			if (instance == null)
			{
				throw new ArgumentNullException("instance");
			}
			if ((object)info == null)
			{
				throw new ArgumentNullException("info");
			}
			ManualLogSource val = (ManualLogSource)(((object)pluginLogger) ?? ((object)MavLogger.Default));
			string name = typeof(TInstance).Name;
			FieldInfo fieldInfo = info as FieldInfo;
			PropertyInfo propertyInfo = info as PropertyInfo;
			if ((object)fieldInfo == null && (object)propertyInfo == null)
			{
				throw new InvalidOperationException("No supported member type found for Set");
			}
			bool flag = (object)fieldInfo != null;
			TValue val2 = (TValue)(flag ? fieldInfo.GetValue(instance) : propertyInfo.GetValue(instance));
			FieldInfo field = (flag ? fieldInfo.FieldType : propertyInfo.PropertyType).GetField("Amount");
			PropertyInfo property = (flag ? fieldInfo.FieldType : propertyInfo.PropertyType).GetProperty("Value");
			object effectiveDisplayValue = GetEffectiveDisplayValue(val2, property, field);
			TValue val3 = valueFunc(val2);
			if (string.Equals(effectiveDisplayValue?.ToString(), GetEffectiveDisplayValue(val3, property, field)?.ToString(), StringComparison.Ordinal))
			{
				return instance;
			}
			val.LogDebug((object)$"{name}.{infoName} was {effectiveDisplayValue}");
			if (flag)
			{
				fieldInfo?.SetValue(instance, val3);
			}
			else
			{
				propertyInfo?.SetValue(instance, val3);
			}
			val2 = (TValue)(flag ? fieldInfo.GetValue(instance) : propertyInfo.GetValue(instance));
			effectiveDisplayValue = GetEffectiveDisplayValue(val2, property, field);
			val.LogInfo((object)$"{name}.{infoName} is {effectiveDisplayValue}");
			return instance;
		}

		private static object? GetEffectiveDisplayValue<T>(T? fiValue, PropertyInfo? fiValueHasValue, FieldInfo? fiValueHasAmount)
		{
			object result = fiValue;
			if (fiValue != null && (object)fiValueHasAmount != null)
			{
				result = fiValueHasAmount.GetValue(fiValue);
			}
			else if (fiValue != null && (object)fiValueHasValue != null)
			{
				result = fiValueHasValue.GetValue(fiValue);
			}
			return result;
		}

		public static TInstance? Set<TInstance, TValue>(this TInstance? instance, Expression<Func<TInstance, TValue>> selector, Func<TValue, TValue> valueFunc, ManualLogSource? pluginLogger = null, [CallerArgumentExpression("instance")] string infoName = null)
		{
			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}
			if ((infoName == "__instance" || infoName == "__result") ? true : false)
			{
				infoName = typeof(TInstance).Name;
			}
			ManualLogSource val = (ManualLogSource)(((object)pluginLogger) ?? ((object)MavLogger.Default));
			if (instance == null)
			{
				val.LogDebug((object)(infoName + " was null"));
				return instance;
			}
			if (selector.Body is MemberExpression memberExpression)
			{
				instance.Set(memberExpression.Member, valueFunc, val, infoName + ":" + memberExpression.Member.Name);
			}
			else
			{
				val.LogError((object)"Unsupported expression given for SetValue. No configuration value set.");
			}
			return instance;
		}

		public static TInstance? Set<TInstance, TValue>(this TInstance? instance, TValue value, ManualLogSource? pluginLogger = null, [CallerArgumentExpression("instance")] string fieldName = null) where TInstance : PrimitiveModifier<TValue>
		{
			ManualLogSource val = (ManualLogSource)(((object)pluginLogger) ?? ((object)MavLogger.Default));
			if ((fieldName == "__instance" || fieldName == "__result") ? true : false)
			{
				fieldName = typeof(TInstance).Name;
			}
			if (instance == null)
			{
				val.LogDebug((object)(fieldName + " was null"));
				return instance;
			}
			val.LogDebug((object)$"{fieldName} was {((PrimitiveModifier<TValue>)(object)instance).Amount}");
			((PrimitiveModifier<TValue>)(object)instance).Amount = value;
			ModifiablePrimitive affectedMod = ((PrimitiveModifier)(object)instance).AffectedMod;
			if (affectedMod != null)
			{
				affectedMod.RecalculateValue();
			}
			val.LogInfo((object)$"{fieldName} is {((PrimitiveModifier<TValue>)(object)instance).Amount}");
			return instance;
		}

		public static TInstance? Set<TInstance, TValue, TValueModifier>(this TInstance? instance, TValue value, ManualLogSource? pluginLogger = null, [CallerArgumentExpression("instance")] string fieldName = null) where TInstance : ModifiablePrimitive<TValue, TValueModifier> where TValueModifier : PrimitiveModifier<TValue>
		{
			ManualLogSource val = (ManualLogSource)(((object)pluginLogger) ?? ((object)MavLogger.Default));
			if (instance == null)
			{
				val.LogDebug((object)(fieldName + " was null"));
				return instance;
			}
			if (object.Equals(((ModifiablePrimitive<TValue, TValueModifier>)instance).Value, value))
			{
				return instance;
			}
			if ((fieldName == "__instance" || fieldName == "__result") ? true : false)
			{
				fieldName = typeof(TInstance).Name;
			}
			val.LogDebug((object)$"{fieldName} was base: {((ModifiablePrimitive<TValue, TValueModifier>)(object)instance).BaseValue}, value: {((ModifiablePrimitive<TValue, TValueModifier>)instance).Value}");
			((ModifiablePrimitive<TValue, TValueModifier>)instance).SetBaseValue(value);
			val.LogInfo((object)$"{fieldName} is base: {((ModifiablePrimitive<TValue, TValueModifier>)(object)instance).BaseValue}, value: {((ModifiablePrimitive<TValue, TValueModifier>)instance).Value}");
			return instance;
		}
	}
	public class KVStorage<T, TKey> where T : IKey<TKey> where TKey : IEquatable<TKey>
	{
		public static MavLogger<T> Logger => MavLogger<T>.Default;

		public static KVStorage<T, TKey> Default { get; } = new KVStorage<T, TKey>();


		public static int ExceptionCount { get; set; }

		public static int MaxAllowedExceptionCount => 5;

		public T? Load(TKey keyId)
		{
			TKey keyId2 = keyId;
			return LoggedExceptions(delegate
			{
				using FileStream stream = new FileStream(Path.Combine(Paths.ConfigPath, $"{keyId2}.json"), FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
				using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
				return JsonConvert.DeserializeObject<T>(streamReader.ReadToEnd(), MavsDefaults.DefaultJsonSerializerOptions);
			});
		}

		public bool Store(T entry)
		{
			T entry2 = entry;
			return LoggedExceptions(delegate
			{
				using FileStream stream = new FileStream(Path.Combine(Paths.ConfigPath, $"{entry2.Id}.json"), FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
				using StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8);
				string value = JsonConvert.SerializeObject((object)entry2, MavsDefaults.DefaultJsonSerializerOptions);
				streamWriter.Write(value);
				streamWriter.Flush();
				return true;
			}, exceptionValue: false);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static TValue? LoggedExceptions<TValue>(Func<TValue>? action, TValue? exceptionValue = default(TValue?))
		{
			try
			{
				return (TValue?)((ExceptionCount < MaxAllowedExceptionCount && action != null) ? ((object)action()) : ((object)exceptionValue));
			}
			catch (Exception ex)
			{
				ExceptionCount++;
				Exception ex2 = ex;
				while (ex2.InnerException != null)
				{
					ex2 = ex2.InnerException;
				}
				((ManualLogSource)Logger).LogError((object)$"Exception count tripped {ExceptionCount} of {MaxAllowedExceptionCount}: {ex2.Message}\r\n{ex.Message}\r\n-- Innermost stacktrace:\r\n{ex2.StackTrace}\r\n-- Stacktrace:\r\n{ex.StackTrace}");
				return exceptionValue;
			}
		}
	}
	public class MavLogger<T> : MavLogger
	{
		public new static MavLogger<T> Default { get; }

		public MavLogger()
			: base(typeof(T).Name)
		{
		}

		static MavLogger()
		{
			Default = new MavLogger<T>();
			Logger.Sources.Add((ILogSource)(object)Default);
		}
	}
	public class MavLogger : ManualLogSource
	{
		public static string SharedLoggerName => "Mavs Common Logger";

		public static MavLogger Default { get; }

		public MavLogger(string sourceName)
			: base(sourceName)
		{
		}

		static MavLogger()
		{
			Default = new MavLogger(SharedLoggerName);
			Logger.Sources.Add((ILogSource)(object)Default);
		}
	}
	[PublicAPI]
	public abstract class MavsBepInExPlugin<T> : BaseUnityPlugin, IMetadata<string>, IKey<string> where T : MavsBepInExPlugin<T>, new()
	{
		protected static byte ExceptionCount;

		private string? _harmonyPatcherId;

		protected static MavLogger<T> Logger => MavLogger<T>.Default;

		protected static int MaxAllowedExceptionCount { get; set; } = 5;


		public static T? Instance { get; protected set; }

		public abstract string DisplayName { get; }

		public abstract Version Version { get; }

		public abstract string Id { get; }

		protected virtual void Awake()
		{
			LoggedExceptions(delegate
			{
				((ManualLogSource)Logger).LogDebug((object)"Plugin is awake...");
				if (!string.IsNullOrEmpty(_harmonyPatcherId))
				{
					Harmony.UnpatchID(_harmonyPatcherId);
				}
				_harmonyPatcherId = Harmony.CreateAndPatchAll(typeof(T), (string)null).Id;
				if (Instance != null && (Object)(object)Instance != (Object)(object)this)
				{
					Object.DestroyImmediate((Object)(object)Instance);
				}
				Instance = (T)this;
				((Object)Chainloader.ManagerObject).hideFlags = (HideFlags)61;
				((ManualLogSource)Logger).LogInfo((object)"Plugin initialized.");
			});
		}

		protected virtual void OnDestroy()
		{
			((ManualLogSource)Logger).LogInfo((object)"Plugin is unloading...");
			LoggedExceptions(delegate
			{
				Instance = null;
				if (!string.IsNullOrEmpty(_harmonyPatcherId))
				{
					Harmony.UnpatchID(_harmonyPatcherId);
				}
				((ManualLogSource)Logger).LogInfo((object)"Plugin has unloaded.");
			});
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void LoggedExceptions(Action? action)
		{
			try
			{
				if (ExceptionCount < MaxAllowedExceptionCount)
				{
					action?.Invoke();
				}
			}
			catch (Exception ex)
			{
				ExceptionCount++;
				Exception ex2 = ex;
				while (ex2.InnerException != null)
				{
					ex2 = ex2.InnerException;
				}
				((ManualLogSource)Logger).LogError((object)((ex2 != ex) ? $"Exception count tripped {ExceptionCount} of {MaxAllowedExceptionCount}: {ex2.Message}\r\n{ex.Message}\r\n-- Innermost stacktrace:\r\n{ex2.StackTrace}\r\n-- Stacktrace:\r\n{ex.StackTrace}" : $"Exception count tripped {ExceptionCount} of {MaxAllowedExceptionCount}: {ex2.Message}\r\n{ex.Message}\r\n-- Stacktrace:\r\n{ex.StackTrace}"));
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static TValue? LoggedExceptions<TValue>(Func<TValue>? action, TValue? exceptionValue = default(TValue?))
		{
			try
			{
				return (TValue?)((ExceptionCount < MaxAllowedExceptionCount && action != null) ? ((object)action()) : ((object)exceptionValue));
			}
			catch (Exception ex)
			{
				ExceptionCount++;
				Exception ex2 = ex;
				while (ex2.InnerException != null)
				{
					ex2 = ex2.InnerException;
				}
				((ManualLogSource)Logger).LogError((object)((ex2 != ex) ? $"Exception count tripped {ExceptionCount} of {MaxAllowedExceptionCount}: {ex2.Message}\r\n{ex.Message}\r\n-- Innermost stacktrace:\r\n{ex2.StackTrace}\r\n-- Stacktrace:\r\n{ex.StackTrace}" : $"Exception count tripped {ExceptionCount} of {MaxAllowedExceptionCount}: {ex2.Message}\r\n{ex.Message}\r\n-- Stacktrace:\r\n{ex.StackTrace}"));
				return exceptionValue;
			}
		}

		public TConfig? RefreshConfiguration<TConfig, TKey>(TConfig referenceConfig) where TConfig : IVersionedMetadata<TKey> where TKey : IEquatable<TKey>
		{
			TConfig referenceConfig2 = referenceConfig;
			return LoggedExceptions(delegate
			{
				KVStorage<TConfig, TKey> @default = KVStorage<TConfig, TKey>.Default;
				TConfig val = @default.Load(referenceConfig2.Id);
				if (val == null || val.SchemaRevision != referenceConfig2.SchemaRevision || !val.Version.Equals(referenceConfig2.Version))
				{
					((ManualLogSource)Logger).LogDebug((object)"Metadata has changed. Forcing configuration update.");
					bool flag = @default.Store(referenceConfig2);
					if (flag)
					{
						val = referenceConfig2;
					}
					((ManualLogSource)Logger).LogDebug((object)$"Config update: {flag}");
				}
				((ManualLogSource)Logger).LogMessage((object)$"Configuration successfully loaded: {val}");
				return val;
			});
		}
	}
	public abstract class MavsBepInExPlugin<T, TConfig> : MavsBepInExPlugin<T> where T : MavsBepInExPlugin<T>, new() where TConfig : ISupportsConfigFile, new()
	{
		protected static TConfig Configuration { get; set; } = new TConfig();


		public virtual void Start()
		{
			MavsBepInExPlugin<T>.LoggedExceptions(delegate
			{
				((ManualLogSource)MavsBepInExPlugin<T>.Logger).LogDebug((object)("Configuration was: " + JsonConvert.SerializeObject((object)Configuration, MavsDefaults.DefaultJsonSerializerOptions)));
				ulong settingsVersion = Configuration.SettingsVersion;
				((ManualLogSource)MavsBepInExPlugin<T>.Logger).LogDebug((object)$"Current Version: {settingsVersion}");
				if (settingsVersion != 0)
				{
					ConfigEntry<ulong> val = ((BaseUnityPlugin)this).Config.Bind<ulong>(ISupportsConfigFile.SettingsVersionConfigDefinition, 0uL, ISupportsConfigFile.SettingsVersionConfigDescription);
					((ManualLogSource)MavsBepInExPlugin<T>.Logger).LogDebug((object)$"Saved Version: {val.Value}");
					if (settingsVersion != val.Value)
					{
						((ManualLogSource)MavsBepInExPlugin<T>.Logger).LogInfo((object)$"Configuration version mismatch. Was: '{val.Value}', expected: '{settingsVersion}'. Forcing reset.");
						using FileStream fileStream = new FileStream(((BaseUnityPlugin)this).Config.ConfigFilePath, FileMode.Create);
						fileStream.Close();
						((BaseUnityPlugin)this).Config.Reload();
						val.Value = settingsVersion;
					}
				}
				Configuration.LoadFrom(((BaseUnityPlugin)this).Config);
				((ManualLogSource)MavsBepInExPlugin<T>.Logger).LogDebug((object)("Configuration is: " + JsonConvert.SerializeObject((object)Configuration, MavsDefaults.DefaultJsonSerializerOptions)));
				((ManualLogSource)MavsBepInExPlugin<T>.Logger).LogInfo((object)"Configuration loaded.");
			});
		}
	}
	public static class MavsDefaults
	{
		public const string ConfigSectionName = "Config";

		public static JsonSerializerSettings DefaultJsonSerializerOptions { get; } = new JsonSerializerSettings
		{
			EqualityComparer = StructuralComparisons.StructuralEqualityComparer,
			ContractResolver = (IContractResolver)new CamelCasePropertyNamesContractResolver(),
			Formatting = (Formatting)1,
			NullValueHandling = (NullValueHandling)1,
			ReferenceLoopHandling = (ReferenceLoopHandling)1
		};

	}
	[CompilerGenerated]
	public static class PluginInfo
	{
		public const string PackageId = "Maverik-MavsCoreLibrary";

		public const string Title = "Mavs Core Library";

		public const string VersionString = "0.0.4";

		public static Version Version = Version.Parse("0.0.4");
	}
}