Decompiled source of FeralCommon v0.2.1

BepInEx/plugins/FeralCommon.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FeralCommon.Config;
using FeralCommon.Game;
using FeralCommon.Input;
using FeralCommon.Utils;
using FeralCommon.Utils.Extensions;
using GameNetcodeStuff;
using HarmonyLib;
using JetBrains.Annotations;
using LethalCompanyInputUtils.Api;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;

[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("Ferus LLC")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Common utilities for FeralCompany plugins")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyInformationalVersion("0.2.1+92ed5a71b0a10c096aeafc045157bc90d6bd2c73")]
[assembly: AssemblyProduct("FeralCommon")]
[assembly: AssemblyTitle("FeralCommon")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.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;
		}
	}
}
namespace FeralCommon
{
	[BepInPlugin("FeralCommon", "FeralCommon", "0.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class FeralCommonPlugin : FeralPlugin
	{
	}
	[UsedImplicitly]
	public abstract class FeralPlugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		private InputRegister? _inputRegister;

		[UsedImplicitly]
		public Harmony Harmony
		{
			get
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_001c: Expected O, but got Unknown
				Harmony obj = _harmony;
				if (obj == null)
				{
					Harmony val = new Harmony("FeralCommon");
					Harmony val2 = val;
					_harmony = val;
					obj = val2;
				}
				return obj;
			}
		}

		private void Awake()
		{
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			_inputRegister = new InputRegister(((BaseUnityPlugin)this).Info.Metadata);
			Load();
		}

		public void CompleteWorkAroundPartOne(in InputActionMapBuilder builder)
		{
			_inputRegister.CompleteWorkAroundPartOne(in builder);
		}

		public void CompleteWorkAroundPartTwo(LcInputActions binder)
		{
			_inputRegister.CompleteWorkAroundPartTwo(binder);
		}

		[UsedImplicitly]
		protected virtual void Load()
		{
		}

		[UsedImplicitly]
		protected void RegisterConfigs(Type type)
		{
			FieldSearcher.Search(type, out List<ConfigBase> fields);
			RegisterConfigs(fields, Assembly.GetCallingAssembly());
		}

		[UsedImplicitly]
		protected void RegisterConfigs(object instance)
		{
			FieldSearcher.Search(instance, out List<ConfigBase> fields);
			RegisterConfigs(fields, Assembly.GetCallingAssembly());
		}

		[UsedImplicitly]
		protected void RegisterButtons(Type type)
		{
			_inputRegister.RegisterButtons(type);
		}

		[UsedImplicitly]
		protected void RegisterButtons(object instance)
		{
			_inputRegister.RegisterButtons(instance);
		}

		private void RegisterConfigs(List<ConfigBase> configs, Assembly assembly)
		{
			foreach (ConfigBase config in configs)
			{
				config.InitConfigEntry(((BaseUnityPlugin)this).Config);
				LethalConfigManager.AddConfigItem(config.CreateConfigItem(), assembly);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "FeralCommon";

		public const string PLUGIN_NAME = "FeralCommon";

		public const string PLUGIN_VERSION = "0.2.1";
	}
}
namespace FeralCommon.Utils
{
	public static class Compat
	{
		public const string LethalConfigKey = "ainavt.lc.lethalconfig";

		public const string InputUtilsKey = "com.rune580.LethalCompanyInputUtils";

		[UsedImplicitly]
		public static bool LethalConfig => IsPluginAvailable("ainavt.lc.lethalconfig");

		[UsedImplicitly]
		public static bool InputUtils => IsPluginAvailable("com.rune580.LethalCompanyInputUtils");

		[UsedImplicitly]
		public static bool IsPluginAvailable(string key)
		{
			return Chainloader.PluginInfos.ContainsKey(key);
		}
	}
	[UsedImplicitly]
	public static class FieldSearcher
	{
		private const BindingFlags AttributeFilter = BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags StaticAttributeFilter = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		[UsedImplicitly]
		public static void Search<TType>(object from, out List<TType> fields)
		{
			fields = new List<TType>();
			SearchInternal(from.GetType(), from, BindingFlags.Public | BindingFlags.NonPublic, ref fields);
		}

		[UsedImplicitly]
		public static void Search<TType>(Type from, out List<TType> fields)
		{
			fields = new List<TType>();
			SearchInternal(from, null, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, ref fields);
			Type[] nestedTypes = from.GetNestedTypes(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < nestedTypes.Length; i++)
			{
				SearchInternal(nestedTypes[i], null, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, ref fields);
			}
		}

		private static void SearchInternal<TType>(IReflect from, object? instance, BindingFlags filter, ref List<TType> fields)
		{
			FieldInfo[] fields2 = from.GetFields(filter);
			for (int i = 0; i < fields2.Length; i++)
			{
				if (fields2[i].GetValue(instance) is TType item)
				{
					fields.Add(item);
				}
			}
		}
	}
	[UsedImplicitly]
	public static class Log
	{
		private const string LogTemplate = "{0}#{1}(L{2}): {3}";

		private static readonly Dictionary<string, ManualLogSource> Loggers = new Dictionary<string, ManualLogSource>();

		[UsedImplicitly]
		public static void Debug(string message, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0)
		{
			LogInternal(GetLogSource(Assembly.GetCallingAssembly()), (LogLevel)32, message, filePath, memberName, lineNumber);
		}

		[UsedImplicitly]
		public static void Info(string message, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0)
		{
			LogInternal(GetLogSource(Assembly.GetCallingAssembly()), (LogLevel)16, message, filePath, memberName, lineNumber);
		}

		[UsedImplicitly]
		public static void Warning(string message, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0)
		{
			LogInternal(GetLogSource(Assembly.GetCallingAssembly()), (LogLevel)4, message, filePath, memberName, lineNumber);
		}

		[UsedImplicitly]
		public static void Error(string message, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0)
		{
			LogInternal(GetLogSource(Assembly.GetCallingAssembly()), (LogLevel)2, message, filePath, memberName, lineNumber);
		}

		[UsedImplicitly]
		public static void Fatal(string message, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0)
		{
			LogInternal(GetLogSource(Assembly.GetCallingAssembly()), (LogLevel)1, message, filePath, memberName, lineNumber);
		}

		private static void LogInternal(ManualLogSource logger, LogLevel level, string message, string filePath, string memberName, int lineNumber)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			int num = filePath.LastIndexOf('\\') + 1;
			string text = filePath.Substring(num, filePath.Length - num).Replace(".cs", "");
			logger.Log(level, (object)$"{text}#{memberName}(L{lineNumber}): {message}");
		}

		private static ManualLogSource GetLogSource(Assembly assembly)
		{
			string name = assembly.GetName().Name;
			if (string.IsNullOrWhiteSpace(name))
			{
				throw new NullReferenceException("Assembly name is null or empty");
			}
			if (Loggers.TryGetValue(name, out ManualLogSource value))
			{
				return value;
			}
			return Loggers[name] = Logger.CreateLogSource(name);
		}
	}
	[UsedImplicitly]
	public class Mask
	{
		public static readonly Mask Default = new Mask(1);

		public static readonly Mask TransparentFX = new Mask(2);

		public static readonly Mask IgnoreRaycast = new Mask(4);

		public static readonly Mask Player = new Mask(8);

		public static readonly Mask Water = new Mask(16);

		public static readonly Mask UI = new Mask(32);

		public static readonly Mask Props = new Mask(64);

		public static readonly Mask HelmetVisor = new Mask(128);

		public static readonly Mask Room = new Mask(256);

		public static readonly Mask InteractableObject = new Mask(512);

		public static readonly Mask Foliage = new Mask(1024);

		public static readonly Mask Colliders = new Mask(2048);

		public static readonly Mask PhysicsObject = new Mask(4096);

		public static readonly Mask Triggers = new Mask(8192);

		public static readonly Mask MapRadar = new Mask(16384);

		public static readonly Mask NavigationSurface = new Mask(32768);

		public static readonly Mask RoomLight = new Mask(65536);

		public static readonly Mask Anomaly = new Mask(131072);

		public static readonly Mask LineOfSight = new Mask(262144);

		public static readonly Mask Enemies = new Mask(524288);

		public static readonly Mask PlayerRagdoll = new Mask(1048576);

		public static readonly Mask MapHazards = new Mask(2097152);

		public static readonly Mask ScanNode = new Mask(4194304);

		public static readonly Mask EnemiesNotRendered = new Mask(8388608);

		public static readonly Mask MiscLevelGeometry = new Mask(16777216);

		public static readonly Mask Terrain = new Mask(33554432);

		public static readonly Mask PlaceableShipObjects = new Mask(67108864);

		public static readonly Mask PlacementBlocker = new Mask(134217728);

		public static readonly Mask Railing = new Mask(268435456);

		public static readonly Mask DecalStickableSurface = new Mask(536870912);

		public static readonly Mask Unused1 = new Mask(1073741824);

		public static readonly Mask Unused2 = new Mask(int.MinValue);

		private int Value { get; }

		public Mask(int value)
		{
			Value = value;
			base..ctor();
		}

		[UsedImplicitly]
		public bool Contains(Mask mask)
		{
			return ((int)this & (int)mask) != 0;
		}

		[UsedImplicitly]
		public bool ContainsAny(params Mask[] masks)
		{
			return masks.Any((Mask m) => ((int)this & (int)m) != 0);
		}

		[UsedImplicitly]
		public Mask Add(params Mask[] masks)
		{
			return masks.Aggregate(this, (Mask current, Mask m) => (int)current | (int)m);
		}

		[UsedImplicitly]
		public Mask Remove(params Mask[] masks)
		{
			return masks.Aggregate(this, (Mask current, Mask m) => (int)current & ~(int)m);
		}

		[UsedImplicitly]
		public string[] Extract()
		{
			List<string> list = new List<string>();
			if (Contains(Default))
			{
				list.Add("Default");
			}
			if (Contains(TransparentFX))
			{
				list.Add("TransparentFX");
			}
			if (Contains(IgnoreRaycast))
			{
				list.Add("IgnoreRaycast");
			}
			if (Contains(Player))
			{
				list.Add("Player");
			}
			if (Contains(Water))
			{
				list.Add("Water");
			}
			if (Contains(UI))
			{
				list.Add("UI");
			}
			if (Contains(Props))
			{
				list.Add("Props");
			}
			if (Contains(HelmetVisor))
			{
				list.Add("HelmetVisor");
			}
			if (Contains(Room))
			{
				list.Add("Room");
			}
			if (Contains(InteractableObject))
			{
				list.Add("InteractableObject");
			}
			if (Contains(Foliage))
			{
				list.Add("Foliage");
			}
			if (Contains(Colliders))
			{
				list.Add("Colliders");
			}
			if (Contains(PhysicsObject))
			{
				list.Add("PhysicsObject");
			}
			if (Contains(Triggers))
			{
				list.Add("Triggers");
			}
			if (Contains(MapRadar))
			{
				list.Add("MapRadar");
			}
			if (Contains(NavigationSurface))
			{
				list.Add("NavigationSurface");
			}
			if (Contains(RoomLight))
			{
				list.Add("RoomLight");
			}
			if (Contains(Anomaly))
			{
				list.Add("Anomaly");
			}
			if (Contains(LineOfSight))
			{
				list.Add("LineOfSight");
			}
			if (Contains(Enemies))
			{
				list.Add("Enemies");
			}
			if (Contains(PlayerRagdoll))
			{
				list.Add("PlayerRagdoll");
			}
			if (Contains(MapHazards))
			{
				list.Add("MapHazards");
			}
			if (Contains(ScanNode))
			{
				list.Add("ScanNode");
			}
			if (Contains(EnemiesNotRendered))
			{
				list.Add("EnemiesNotRendered");
			}
			if (Contains(MiscLevelGeometry))
			{
				list.Add("MiscLevelGeometry");
			}
			if (Contains(Terrain))
			{
				list.Add("Terrain");
			}
			if (Contains(PlaceableShipObjects))
			{
				list.Add("PlaceableShipObjects");
			}
			if (Contains(PlacementBlocker))
			{
				list.Add("PlacementBlocker");
			}
			if (Contains(Railing))
			{
				list.Add("Railing");
			}
			if (Contains(DecalStickableSurface))
			{
				list.Add("DecalStickableSurface");
			}
			if (Contains(Unused1))
			{
				list.Add("Unused1");
			}
			if (Contains(Unused2))
			{
				list.Add("Unused2");
			}
			return list.ToArray();
		}

		[UsedImplicitly]
		public static Mask Combine(params Mask[] masks)
		{
			return masks.Aggregate(0, (int current, Mask m) => current | (int)m);
		}

		public static implicit operator int(Mask mask)
		{
			return mask.Value;
		}

		public static implicit operator Mask(int value)
		{
			return new Mask(value);
		}
	}
	[UsedImplicitly]
	public class ObjectInspector
	{
		[UsedImplicitly]
		public class InspectedItem
		{
			[UsedImplicitly]
			public readonly string Path;

			[UsedImplicitly]
			public readonly Type Type;

			[UsedImplicitly]
			public readonly object? Value;

			public InspectedItem(string path, Type type, object? value)
			{
				Path = path;
				Type = type;
				Value = value;
				base..ctor();
			}
		}

		public class DiffItem
		{
			[UsedImplicitly]
			public readonly object? LeftValue;

			[UsedImplicitly]
			public readonly string Path;

			[UsedImplicitly]
			public readonly object? RightValue;

			public DiffItem(string path, object? leftVal, object? rightVal)
			{
				LeftValue = leftVal;
				Path = path;
				RightValue = rightVal;
				base..ctor();
			}
		}

		private const BindingFlags DefaultBindingAttributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private readonly List<Type> _exceptionalTypes = new List<Type>(1) { typeof(string) };

		private readonly List<Type> _ignoredTypes = new List<Type>();

		private BindingFlags _bindingAttributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		[UsedImplicitly]
		public ObjectInspector WithBindingAttributes(BindingFlags bindingAttributes)
		{
			_bindingAttributes = bindingAttributes;
			return this;
		}

		[UsedImplicitly]
		public ObjectInspector AddIgnoredTypes(params Type[] ignoredTypes)
		{
			_ignoredTypes.AddRange(ignoredTypes);
			return this;
		}

		[UsedImplicitly]
		public ObjectInspector AddIgnoredTypes(List<Type> ignoredTypes)
		{
			_ignoredTypes.AddRange(ignoredTypes);
			return this;
		}

		[UsedImplicitly]
		public void Inspect(object obj, out List<InspectedItem> items)
		{
			Inspect(obj, "", items = new List<InspectedItem>(), new List<object>(1) { obj }, 0);
		}

		[UsedImplicitly]
		public void Diff<T>(T a, T b, out List<DiffItem> diffs)
		{
			if (a == null)
			{
				throw new ArgumentNullException("a");
			}
			Diff(a, b, "", diffs = new List<DiffItem>(), new List<object>(), 0);
		}

		[UsedImplicitly]
		public static void PrintInspection(List<InspectedItem> items, string title = "No Details")
		{
			Log.Info("-----------------------------------------------------------------------", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintInspection", 54);
			Log.Info("Inspection: " + title, "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintInspection", 55);
			foreach (InspectedItem item in items)
			{
				Log.Info($"{item.Path} ({item.Type.Name}): {item.Value}", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintInspection", 56);
			}
			Log.Info("-----------------------------------------------------------------------", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintInspection", 57);
		}

		[UsedImplicitly]
		public static void PrintDiff(List<DiffItem> items, string title = "No Details")
		{
			Log.Info("-----------------------------------------------------------------------", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 63);
			Log.Info("Diff Inspection: " + title, "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 64);
			foreach (DiffItem item in items)
			{
				if (item.LeftValue == null)
				{
					Log.Info($"{item.Path} ({item.RightValue.GetType().Name}): null => {item.RightValue}", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 67);
				}
				else if (item.RightValue == null)
				{
					Log.Info($"{item.Path} ({item.LeftValue.GetType().Name}): {item.LeftValue} => null", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 69);
				}
				else if (item.LeftValue.GetType() != item.RightValue.GetType())
				{
					Log.Info($"{item.Path} ({item.LeftValue.GetType().Name} => {item.RightValue.GetType().Name}): {item.LeftValue} => {item.RightValue}", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 71);
				}
				else
				{
					Log.Info($"{item.Path} ({item.RightValue.GetType().Name}): {item.LeftValue} => {item.RightValue}", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 73);
				}
			}
			Log.Info("-----------------------------------------------------------------------", "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Utils/ObjectInspector.cs", "PrintDiff", 74);
		}

		private void Diff(object leftObj, object? rightObj, string path, ICollection<DiffItem> diffs, ICollection<object> visited, int depth)
		{
			Type type = leftObj.GetType();
			FieldInfo[] fields = type.GetFields(_bindingAttributes);
			foreach (FieldInfo fieldInfo in fields)
			{
				Type fieldType = fieldInfo.FieldType;
				if (fieldType.IsByRef || _ignoredTypes.Contains(fieldType))
				{
					continue;
				}
				object value = fieldInfo.GetValue(leftObj);
				object obj = ((rightObj == null) ? null : fieldInfo.GetValue(rightObj));
				if (value == leftObj || visited.Contains(value))
				{
					continue;
				}
				visited.Add(value);
				if ((value == null && obj == null) || value == obj || (value != null && value.Equals(obj)))
				{
					continue;
				}
				string path2 = AppendPath(path, fieldInfo.Name);
				diffs.Add(new DiffItem(path2, value, obj));
				if (value != null && depth <= 2)
				{
					Type type2 = value.GetType();
					if (!type2.IsValueType && !_exceptionalTypes.Contains(type2))
					{
						Diff(value, obj, path2, diffs, visited, depth + 1);
					}
				}
			}
			PropertyInfo[] properties = type.GetProperties(_bindingAttributes);
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.GetIndexParameters().Length != 0)
				{
					continue;
				}
				Type propertyType = propertyInfo.PropertyType;
				if (propertyType.IsByRef || _ignoredTypes.Contains(propertyType))
				{
					continue;
				}
				object value2 = propertyInfo.GetValue(leftObj);
				object obj2 = ((rightObj == null) ? null : propertyInfo.GetValue(rightObj));
				if (value2 == leftObj || visited.Contains(value2))
				{
					continue;
				}
				visited.Add(value2);
				if ((value2 == null && obj2 == null) || value2 == obj2 || (value2 != null && value2.Equals(obj2)))
				{
					continue;
				}
				string path3 = AppendPath(path, propertyInfo.Name);
				diffs.Add(new DiffItem(path3, value2, obj2));
				if (value2 != null && depth <= 2)
				{
					Type type3 = value2.GetType();
					if (!type3.IsValueType && !_exceptionalTypes.Contains(type3))
					{
						Diff(value2, obj2, path3, diffs, visited, depth + 1);
					}
				}
			}
		}

		private void Inspect(object obj, string path, ICollection<InspectedItem> items, ICollection<object> visited, int depth)
		{
			Type type = obj.GetType();
			FieldInfo[] fields = type.GetFields(_bindingAttributes);
			foreach (FieldInfo fieldInfo in fields)
			{
				Type fieldType = fieldInfo.FieldType;
				if (fieldType.IsByRef || _ignoredTypes.Contains(fieldType))
				{
					continue;
				}
				object value = fieldInfo.GetValue(obj);
				if (value != obj && !visited.Contains(value))
				{
					visited.Add(value);
					string path2 = AppendPath(path, fieldInfo.Name);
					items.Add(new InspectedItem(path2, fieldType, value));
					if (value != null && depth <= 2 && !fieldType.IsValueType && !_exceptionalTypes.Contains(fieldType))
					{
						Inspect(value, path2, items, visited, depth + 1);
					}
				}
			}
			PropertyInfo[] properties = type.GetProperties(_bindingAttributes);
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.GetIndexParameters().Length != 0)
				{
					continue;
				}
				Type propertyType = propertyInfo.PropertyType;
				if (propertyType.IsByRef)
				{
					break;
				}
				if (_ignoredTypes.Contains(propertyType))
				{
					continue;
				}
				object value2 = propertyInfo.GetValue(obj);
				if (value2 != obj && !visited.Contains(value2))
				{
					visited.Add(value2);
					string path3 = AppendPath(path, propertyInfo.Name);
					items.Add(new InspectedItem(path3, propertyType, value2));
					if (value2 != null && depth <= 2 && !propertyType.IsValueType && !_exceptionalTypes.Contains(propertyType))
					{
						Inspect(value2, path3, items, visited, depth + 1);
					}
				}
			}
		}

		private static string AppendPath(string path, string name)
		{
			if (!string.IsNullOrEmpty(path))
			{
				return path + "." + name;
			}
			return name;
		}
	}
	[UsedImplicitly]
	public static class Player
	{
		[UsedImplicitly]
		public static IEnumerator WhenLocalPlayerReady(Action<PlayerControllerB> action)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController)));
			action(GameNetworkManager.Instance.localPlayerController);
		}

		[UsedImplicitly]
		public static bool IsLocalPlayer(PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance))
			{
				return (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)player;
			}
			return false;
		}

		[UsedImplicitly]
		public static PlayerControllerB LocalPlayer()
		{
			return GameNetworkManager.Instance?.localPlayerController ?? throw new InvalidOperationException("Local player not ready!");
		}

		[UsedImplicitly]
		public static PlayerControllerB? LocalPlayerNullable()
		{
			return GameNetworkManager.Instance?.localPlayerController;
		}
	}
}
namespace FeralCommon.Utils.Extensions
{
	public static class AssemblyExtensions
	{
		[UsedImplicitly]
		public static BepInPlugin GetBepInPlugin(this Assembly assembly)
		{
			foreach (Type validType in assembly.GetValidTypes())
			{
				BepInPlugin customAttribute = ((MemberInfo)validType).GetCustomAttribute<BepInPlugin>();
				if (customAttribute != null)
				{
					return customAttribute;
				}
			}
			throw new Exception("No BepInPlugin attribute found in assembly.");
		}

		[UsedImplicitly]
		public static IEnumerable<Type> GetValidTypes(this Assembly assembly)
		{
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type type) => type != null);
			}
		}
	}
	public static class GameItemExtensions
	{
		[UsedImplicitly]
		public static string ToPropertyName(this GameItem item)
		{
			return item switch
			{
				GameItem.AirHorn => "Airhorn", 
				GameItem.BeeHive => "Hive", 
				GameItem.BigBolt => "Big bolt", 
				GameItem.BrassBell => "Brass bell", 
				GameItem.CashRegister => "Cash register", 
				GameItem.ChemicalJug => "Chemical jug", 
				GameItem.ClownHorn => "Clown horn", 
				GameItem.CoffeeMug => "Coffee mug", 
				GameItem.ComedyMask => "Comedy", 
				GameItem.CookieSheet => "Cookie mold pan", 
				GameItem.CubeToy => "Toy cube", 
				GameItem.DustPan => "Dust pan", 
				GameItem.EasterEgg => "Easter egg", 
				GameItem.EggBeater => "Egg beater", 
				GameItem.Engine => "V-type engine", 
				GameItem.ExtensionLadder => "Extension Ladder", 
				GameItem.FancyLamp => "Fancy lamp", 
				GameItem.Flashbang => "Homemade flashbang", 
				GameItem.GiftBox => "Gift", 
				GameItem.GoldBar => "Gold bar", 
				GameItem.GoldenCup => "Golden cup", 
				GameItem.HairBrush => "Hair brush", 
				GameItem.HairDryer => "Hairdryer", 
				GameItem.KitchenKnife => "Kitchen knife", 
				GameItem.LargeAxle => "Large axle", 
				GameItem.LaserPointer => "Laser pointer", 
				GameItem.LockPicker => "Lockpicker", 
				GameItem.MagicSevenBall => "Magic 7 ball", 
				GameItem.MagnifyingGlass => "Magnifying glass", 
				GameItem.MetalSheet => "Metal sheet", 
				GameItem.OldPhone => "Old phone", 
				GameItem.Perfume => "Perfume bottle", 
				GameItem.PickleJar => "Jar of pickles", 
				GameItem.Pills => "Pill bottle", 
				GameItem.PlasticFish => "Plastic fish", 
				GameItem.PlayerBody => "Player Body", 
				GameItem.ProFlashlight => "Pro-Flashlight", 
				GameItem.RadarBooster => "Radar-Booster", 
				GameItem.RobotToy => "Robot toy", 
				GameItem.RubberDucky => "Rubber Ducky", 
				GameItem.Shotgun => "Double-barrel", 
				GameItem.ShotgunShell => "Ammo", 
				GameItem.SodaCan => "Red soda", 
				GameItem.SprayPaint => "Spray Paint", 
				GameItem.SteeringWheel => "Steering wheel", 
				GameItem.StopSign => "Stop sign", 
				GameItem.StunGrenade => "Stun Grenade", 
				GameItem.TeaKettle => "Tea kettle", 
				GameItem.TragedyMask => "Tragedy", 
				GameItem.TzpInhalant => "TZP-Inhalant", 
				GameItem.WalkieTalkie => "Walkie-Talkie", 
				GameItem.WhoopieCushion => "Whoopie-Cushion", 
				GameItem.YieldSign => "Yield sign", 
				GameItem.ZapGun => "Zap Gun", 
				_ => item.ToString(), 
			};
		}

		[UsedImplicitly]
		public static bool IsConductive(this GameItem item)
		{
			return item switch
			{
				GameItem.Apparatus => true, 
				GameItem.BeeHive => true, 
				GameItem.BigBolt => true, 
				GameItem.BrassBell => true, 
				GameItem.CashRegister => true, 
				GameItem.ClownHorn => true, 
				GameItem.EggBeater => true, 
				GameItem.Engine => true, 
				GameItem.ExtensionLadder => true, 
				GameItem.FancyLamp => true, 
				GameItem.Flask => true, 
				GameItem.GoldBar => true, 
				GameItem.Jetpack => true, 
				GameItem.KitchenKnife => true, 
				GameItem.LargeAxle => true, 
				GameItem.MetalSheet => true, 
				GameItem.RadarBooster => true, 
				GameItem.Ring => true, 
				GameItem.RobotToy => true, 
				GameItem.Shovel => true, 
				GameItem.SodaCan => true, 
				GameItem.StopSign => true, 
				GameItem.TeaKettle => true, 
				GameItem.TzpInhalant => true, 
				GameItem.YieldSign => true, 
				GameItem.ZapGun => true, 
				_ => false, 
			};
		}

		[UsedImplicitly]
		public static bool IsWeapon(this GameItem item)
		{
			return item switch
			{
				GameItem.EasterEgg => true, 
				GameItem.Flashbang => true, 
				GameItem.KitchenKnife => true, 
				GameItem.Shotgun => true, 
				GameItem.ShotgunShell => true, 
				GameItem.Shovel => true, 
				GameItem.StopSign => true, 
				GameItem.StunGrenade => true, 
				GameItem.YieldSign => true, 
				GameItem.ZapGun => true, 
				_ => false, 
			};
		}

		[UsedImplicitly]
		public static bool IsTool(this GameItem item)
		{
			return item switch
			{
				GameItem.Key => true, 
				GameItem.LockPicker => true, 
				GameItem.Boombox => true, 
				GameItem.ExtensionLadder => true, 
				GameItem.Flashlight => true, 
				GameItem.Jetpack => true, 
				GameItem.ProFlashlight => true, 
				GameItem.RadarBooster => true, 
				GameItem.SprayPaint => true, 
				GameItem.TzpInhalant => true, 
				GameItem.WalkieTalkie => true, 
				_ => false, 
			};
		}
	}
	public static class GameObjectExtensions
	{
		[UsedImplicitly]
		public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return gameObject.AddComponent<T>();
			}
			return component;
		}
	}
	public static class GrabbableObjectExtensions
	{
		[UsedImplicitly]
		public static GameItem? ToGameItem(this GrabbableObject obj)
		{
			return GameItems.FromGrabbable(obj);
		}

		[UsedImplicitly]
		public static bool IsConductive(this GrabbableObject obj)
		{
			return obj.itemProperties.isConductiveMetal;
		}
	}
	public static class HarmonyExtension
	{
		[UsedImplicitly]
		public static void PatchNamespace(this Harmony harmony, string namespaceStr)
		{
			Type[] types = Assembly.GetCallingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (type.Namespace != null && type.Namespace == namespaceStr)
				{
					harmony.PatchAll(type);
				}
			}
		}
	}
	public static class NumberExtensions
	{
		[UsedImplicitly]
		public static bool IsPowerOfTwo(this int num)
		{
			if (num != 0)
			{
				return (num & (num - 1)) == 0;
			}
			return false;
		}
	}
	public static class PlayerControllerBExtensions
	{
		[UsedImplicitly]
		public static bool IsLocalPlayer(this PlayerControllerB playerControllerB)
		{
			return (Object)(object)playerControllerB == (Object)(object)GameNetworkManager.Instance.localPlayerController;
		}
	}
}
namespace FeralCommon.Input
{
	public abstract class ButtonBindingBase<TDerived> : IButtonBinding where TDerived : ButtonBindingBase<TDerived>
	{
		private string Id { get; }

		private string Name { get; }

		private string Path { get; }

		[UsedImplicitly]
		protected InputAction Input
		{
			get
			{
				LcInputActions? binder = Binder;
				return ((binder != null) ? binder.Asset.FindAction(Id, false) : null) ?? throw new InvalidOperationException("Binder not initialized");
			}
		}

		private LcInputActions? Binder { get; set; }

		private string? Interaction { get; set; }

		string IButtonBinding.Id => Id;

		string IButtonBinding.Name => Name;

		string IButtonBinding.Path => Path;

		string? IButtonBinding.Interaction => Interaction;

		protected ButtonBindingBase(string id, string name, string path)
		{
			Id = id;
			Name = name;
			Path = path;
			base..ctor();
		}

		void IButtonBinding.Init(LcInputActions binder)
		{
			Binder = binder;
			Init();
		}

		[UsedImplicitly]
		public TDerived WithInteraction(string interaction)
		{
			Interaction = interaction;
			return (TDerived)this;
		}

		protected abstract void Init();
	}
	[UsedImplicitly]
	public class ButtonPress : ButtonBindingBase<ButtonPress>
	{
		[UsedImplicitly]
		public bool PressedThisFrame => base.Input.triggered;

		private Action? WhenPressed { get; set; }

		public ButtonPress(string id, string name, string path)
			: base(id, name, path)
		{
		}

		[UsedImplicitly]
		public ButtonPress OnPressed(Action whenPressed)
		{
			WhenPressed = (Action)Delegate.Combine(WhenPressed, whenPressed);
			return this;
		}

		protected override void Init()
		{
			base.Input.performed += delegate
			{
				WhenPressed?.Invoke();
			};
		}

		public static implicit operator bool(ButtonPress press)
		{
			return press.PressedThisFrame;
		}
	}
	[UsedImplicitly]
	public class ButtonToggle : ButtonBindingBase<ButtonToggle>
	{
		[UsedImplicitly]
		public bool Active { get; private set; }

		private Action<bool>? WhenToggled { get; set; }

		public ButtonToggle(string id, string name, string path, bool activeByDefault = false)
		{
			Active = activeByDefault;
			base..ctor(id, name, path);
		}

		[UsedImplicitly]
		public ButtonToggle OnToggle(Action<bool> action)
		{
			WhenToggled = (Action<bool>)Delegate.Combine(WhenToggled, action);
			return this;
		}

		protected override void Init()
		{
			base.Input.performed += delegate
			{
				Active = !Active;
				WhenToggled?.Invoke(Active);
			};
		}

		public static implicit operator bool(ButtonToggle toggle)
		{
			return toggle.Active;
		}
	}
	internal interface IButtonBinding
	{
		internal string Id { get; }

		internal string Name { get; }

		internal string Path { get; }

		internal string? Interaction { get; }

		internal void Init(LcInputActions binder);
	}
	internal class InputRegister
	{
		private readonly List<IButtonBinding> _buttons = new List<IButtonBinding>();

		private bool _registrationClosed;

		public InputRegister(BepInPlugin plugin)
		{
		}

		internal void RegisterButtons(Type type)
		{
			if (_registrationClosed)
			{
				throw new InvalidOperationException("Cannot register buttons after registration has been closed");
			}
			FieldSearcher.Search(type, out List<IButtonBinding> fields);
			_buttons.AddRange(fields);
		}

		internal void RegisterButtons(object instance)
		{
			if (_registrationClosed)
			{
				throw new InvalidOperationException("Cannot register buttons after registration has been closed");
			}
			FieldSearcher.Search(instance, out List<IButtonBinding> fields);
			_buttons.AddRange(fields);
		}

		internal void CompleteWorkAroundPartOne(in InputActionMapBuilder builder)
		{
			_registrationClosed = true;
			foreach (IButtonBinding button in _buttons)
			{
				builder.NewActionBinding().WithActionId(button.Id).WithBindingName(button.Name)
					.WithKbmPath(button.Path)
					.WithKbmInteractions(button.Interaction)
					.Finish();
			}
		}

		internal void CompleteWorkAroundPartTwo(LcInputActions binder)
		{
			foreach (IButtonBinding button in _buttons)
			{
				button.Init(binder);
			}
		}
	}
}
namespace FeralCommon.Game
{
	public enum GameItem
	{
		AirHorn,
		Apparatus,
		BeeHive,
		BigBolt,
		Boombox,
		Bottles,
		BrassBell,
		Candy,
		CashRegister,
		ChemicalJug,
		Clipboard,
		ClownHorn,
		CoffeeMug,
		ComedyMask,
		CookieSheet,
		CubeToy,
		DustPan,
		EasterEgg,
		EggBeater,
		Engine,
		ExtensionLadder,
		FancyLamp,
		Flashbang,
		Flashlight,
		Flask,
		GiftBox,
		GoldBar,
		GoldenCup,
		HairBrush,
		HairDryer,
		Jetpack,
		Key,
		KitchenKnife,
		LargeAxle,
		LaserPointer,
		LockPicker,
		MagicSevenBall,
		MagnifyingGlass,
		MetalSheet,
		OldPhone,
		Painting,
		Perfume,
		PickleJar,
		Pills,
		PlasticFish,
		PlayerBody,
		ProFlashlight,
		RadarBooster,
		Remote,
		Ring,
		RobotToy,
		RubberDucky,
		Shotgun,
		ShotgunShell,
		Shovel,
		SodaCan,
		SprayPaint,
		SteeringWheel,
		StickyNote,
		StopSign,
		StunGrenade,
		TeaKettle,
		Teeth,
		Toothpaste,
		TragedyMask,
		TzpInhalant,
		WalkieTalkie,
		WhoopieCushion,
		YieldSign,
		ZapGun
	}
	public static class GameItems
	{
		public static readonly List<GameItem> All = Enum.GetValues(typeof(GameItem)).OfType<GameItem>().ToList();

		public static readonly List<GameItem> Conductive = All.Where((GameItem x) => x.IsConductive()).ToList();

		public static readonly List<GameItem> Weapons = All.Where((GameItem x) => x.IsWeapon()).ToList();

		public static readonly List<GameItem> Tools = All.Where((GameItem x) => x.IsTool()).ToList();

		public static readonly Dictionary<string, GameItem> PropertyNameToGameItem = All.ToDictionary((GameItem x) => x.ToPropertyName(), (GameItem x) => x);

		public static GameItem? FromPropertyName(string propertyName)
		{
			if (PropertyNameToGameItem.TryGetValue(propertyName, out var value))
			{
				return value;
			}
			Log.Error("No GameItem with property name: " + propertyName, "/home/runner/work/FeralCommon/FeralCommon/FeralCommon/Game/GameItems.cs", "FromPropertyName", 22);
			return null;
		}

		public static GameItem? FromGrabbable(GrabbableObject obj)
		{
			return FromPropertyName(obj.itemProperties.itemName);
		}
	}
}
namespace FeralCommon.Config
{
	[UsedImplicitly]
	public class BoolConfig : Config<BoolConfig, bool>
	{
		public BoolConfig(string section, string key)
			: base(section, key)
		{
		}

		protected internal override BaseConfigItem CreateConfigItem()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			BoolCheckBoxOptions options = new BoolCheckBoxOptions();
			return (BaseConfigItem)new BoolCheckBoxConfigItem(base.ValidatedEntry, FillBaseOptions<BoolCheckBoxOptions>(options));
		}
	}
	[UsedImplicitly]
	public class ColorConfig : Config<ColorConfig, string>
	{
		public ColorConfig(string section, string key)
			: base(section, key)
		{
		}

		[UsedImplicitly]
		public Color GetColor()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			if (!ColorUtility.TryParseHtmlString((string)(Config<ColorConfig, string>)this, ref result))
			{
				return Color.white;
			}
			return result;
		}

		protected internal override BaseConfigItem CreateConfigItem()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			TextInputFieldOptions options = new TextInputFieldOptions
			{
				CharacterLimit = 7
			};
			return (BaseConfigItem)new TextInputFieldConfigItem(base.ValidatedEntry, FillBaseOptions<TextInputFieldOptions>(options));
		}

		public static implicit operator Color(ColorConfig config)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return config.GetColor();
		}
	}
	public abstract class Config<TDerived, TType> : ConfigBase where TDerived : Config<TDerived, TType> where TType : IConvertible
	{
		private string Section { get; }

		private string Key { get; }

		private string Description { get; set; }

		private TType? DefaultValue { get; set; }

		private bool RequiresRestart { get; set; }

		private List<Action<TType>> ValueChangedActions { get; }

		private List<Func<CanModifyResult>> CanModifyChecks { get; }

		private ConfigEntry<TType>? Entry { get; set; }

		protected ConfigEntry<TType> ValidatedEntry => Entry ?? throw new InvalidOperationException("Config entry must be initialized before getting value.");

		[UsedImplicitly]
		public TType Value => ((ConfigEntry<?>)(object)ValidatedEntry).Value;

		protected Config(string section, string key)
		{
			Section = section;
			Key = key;
			Description = "No description provided.";
			ValueChangedActions = new List<Action<TType>>();
			CanModifyChecks = new List<Func<CanModifyResult>>();
			base..ctor();
		}

		[UsedImplicitly]
		public TDerived WithDescription(string description)
		{
			Description = description;
			return (TDerived)this;
		}

		[UsedImplicitly]
		public TDerived WithDefaultValue(TType defaultValue)
		{
			DefaultValue = defaultValue;
			return (TDerived)this;
		}

		[UsedImplicitly]
		public TDerived SetRequiresRestart()
		{
			RequiresRestart = true;
			return (TDerived)this;
		}

		[UsedImplicitly]
		public TDerived OnValueChanged(Action<TType> action)
		{
			ValueChangedActions.Add(action);
			return (TDerived)this;
		}

		[UsedImplicitly]
		public TDerived CanModify(Func<CanModifyResult> check)
		{
			CanModifyChecks.Add(check);
			return (TDerived)this;
		}

		private CanModifyResult CanModifyValue()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (CanModifyChecks.Count == 0)
			{
				return CanModifyResult.True();
			}
			List<string> list = (from check in CanModifyChecks
				select check() into result
				where !CanModifyResult.op_Implicit(result)
				select ((CanModifyResult)(ref result)).Reason).ToList();
			if (!list.Any())
			{
				return CanModifyResult.True();
			}
			return CanModifyResult.False(string.Join(Environment.NewLine, list));
		}

		internal override void InitConfigEntry(ConfigFile configFile)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			if (DefaultValue == null)
			{
				throw new InvalidOperationException("Default value must be set before initializing config entry.");
			}
			ConfigDefinition val = new ConfigDefinition(Section, Key);
			ConfigDescription val2 = new ConfigDescription(Description, CreateAcceptableValue(), Array.Empty<object>());
			ConfigEntry<TType> entry = configFile.Bind<TType>(val, DefaultValue, val2);
			((ConfigEntry<?>)(object)entry).SettingChanged += delegate
			{
				TType value = ((ConfigEntry<?>)(object)entry).Value;
				ValueChangedActions.ForEach(delegate(Action<TType> e)
				{
					e(value);
				});
			};
			Entry = entry;
		}

		protected virtual AcceptableValueBase? CreateAcceptableValue()
		{
			return null;
		}

		protected TBaseOptions FillBaseOptions<TBaseOptions>(TBaseOptions options) where TBaseOptions : BaseOptions
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			((BaseOptions)options).Section = Section;
			((BaseOptions)options).Name = Key;
			((BaseOptions)options).Description = Description;
			((BaseOptions)options).RequiresRestart = RequiresRestart;
			((BaseOptions)options).CanModifyCallback = new CanModifyDelegate(CanModifyValue);
			return options;
		}

		public static implicit operator TType(Config<TDerived, TType> config)
		{
			return config.Value;
		}
	}
	public abstract class ConfigBase
	{
		internal abstract void InitConfigEntry(ConfigFile configFile);

		protected internal abstract BaseConfigItem CreateConfigItem();
	}
	[UsedImplicitly]
	public class EnumConfig<TEnum> : Config<EnumConfig<TEnum>, TEnum> where TEnum : Enum
	{
		public EnumConfig(string section, string key)
			: base(section, key)
		{
		}

		protected internal override BaseConfigItem CreateConfigItem()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (BaseConfigItem)(object)new EnumDropDownConfigItem<TEnum>(base.ValidatedEntry, FillBaseOptions<EnumDropDownOptions>(new EnumDropDownOptions()));
		}
	}
	[UsedImplicitly]
	public class FloatConfig : RangeConfig<FloatConfig, float>
	{
		private bool Slider { get; set; } = true;


		private float Step { get; set; } = 0.1f;


		public FloatConfig(string section, string key)
			: base(section, key)
		{
		}

		[UsedImplicitly]
		public FloatConfig NoSlider()
		{
			Slider = false;
			return this;
		}

		[UsedImplicitly]
		public FloatConfig WithStep(float step)
		{
			Step = step;
			return this;
		}

		protected internal override BaseConfigItem CreateConfigItem()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_007a: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (Slider && base.IsRanged)
			{
				FloatStepSliderOptions val = new FloatStepSliderOptions();
				((BaseRangeOptions<float>)val).Min = base.Min;
				((BaseRangeOptions<float>)val).Max = base.Max;
				val.Step = Step;
				FloatStepSliderOptions options = val;
				return (BaseConfigItem)new FloatSliderConfigItem(base.ValidatedEntry, (FloatSliderOptions)(object)FillBaseOptions<FloatStepSliderOptions>(options));
			}
			FloatInputFieldOptions val2;
			if (!base.IsRanged)
			{
				val2 = new FloatInputFieldOptions();
			}
			else
			{
				val2 = new FloatInputFieldOptions();
				((BaseRangeOptions<float>)val2).Min = base.Min;
				((BaseRangeOptions<float>)val2).Max = base.Max;
			}
			FloatInputFieldOptions options2 = val2;
			return (BaseConfigItem)new FloatInputFieldConfigItem(base.ValidatedEntry, FillBaseOptions<FloatInputFieldOptions>(options2));
		}
	}
	[UsedImplicitly]
	public class IntConfig : RangeConfig<IntConfig, int>
	{
		private bool Slider { get; set; } = true;


		public IntConfig(string section, string key)
			: base(section, key)
		{
		}

		[UsedImplicitly]
		public IntConfig NoSlider()
		{
			Slider = false;
			return this;
		}

		protected internal override BaseConfigItem CreateConfigItem()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_006e: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if (Slider && base.IsRanged)
			{
				IntSliderOptions val = new IntSliderOptions();
				((BaseRangeOptions<int>)val).Min = base.Min;
				((BaseRangeOptions<int>)val).Max = base.Max;
				IntSliderOptions options = val;
				return (BaseConfigItem)new IntSliderConfigItem(base.ValidatedEntry, FillBaseOptions<IntSliderOptions>(options));
			}
			IntInputFieldOptions val2;
			if (!base.IsRanged)
			{
				val2 = new IntInputFieldOptions();
			}
			else
			{
				val2 = new IntInputFieldOptions();
				((BaseRangeOptions<int>)val2).Min = base.Min;
				((BaseRangeOptions<int>)val2).Max = base.Max;
			}
			IntInputFieldOptions options2 = val2;
			return (BaseConfigItem)new IntInputFieldConfigItem(base.ValidatedEntry, FillBaseOptions<IntInputFieldOptions>(options2));
		}
	}
	public abstract class RangeConfig<TDerived, TType> : Config<TDerived, TType> where TDerived : RangeConfig<TDerived, TType> where TType : struct, IComparable, IComparable<TType>, IConvertible, IEquatable<TType>
	{
		protected TType Min { get; private set; }

		protected TType Max { get; private set; }

		protected bool IsRanged { get; private set; }

		protected RangeConfig(string section, string key)
			: base(section, key)
		{
		}

		[UsedImplicitly]
		public TDerived WithMin(TType min)
		{
			IsRanged = true;
			Min = min;
			return (TDerived)this;
		}

		[UsedImplicitly]
		public TDerived WithMax(TType max)
		{
			IsRanged = true;
			Max = max;
			return (TDerived)this;
		}

		protected override AcceptableValueBase? CreateAcceptableValue()
		{
			if (!IsRanged)
			{
				return null;
			}
			return (AcceptableValueBase?)(object)new AcceptableValueRange<?>(Min, Max);
		}
	}
	[UsedImplicitly]
	public class StringConfig : Config<StringConfig, string>
	{
		private List<string> AcceptableValues { get; } = new List<string>();


		private bool HasAcceptableValues => AcceptableValues.Count > 0;

		private int CharacterLimit { get; set; }

		private int NumberOfLines { get; set; } = 1;


		private bool TrimText { get; set; }

		public StringConfig(string section, string key)
			: base(section, key)
		{
		}

		[UsedImplicitly]
		public StringConfig AddAcceptableValue(string value)
		{
			AcceptableValues.Add(value);
			return this;
		}

		[UsedImplicitly]
		public StringConfig AddAcceptableValues(params string[] values)
		{
			AcceptableValues.AddRange(values);
			return this;
		}

		[UsedImplicitly]
		public StringConfig AddAcceptableValues(IEnumerable<string> values)
		{
			AcceptableValues.AddRange(values);
			return this;
		}

		[UsedImplicitly]
		public StringConfig WithCharacterLimit(int limit)
		{
			CharacterLimit = limit;
			return this;
		}

		[UsedImplicitly]
		public StringConfig WithNumberOfLines(int lines)
		{
			NumberOfLines = lines;
			return this;
		}

		[UsedImplicitly]
		public StringConfig SetTrimText()
		{
			TrimText = true;
			return this;
		}

		protected override AcceptableValueBase? CreateAcceptableValue()
		{
			if (!HasAcceptableValues)
			{
				return null;
			}
			return (AcceptableValueBase?)(object)new AcceptableValueList<string>(AcceptableValues.ToArray());
		}

		protected internal override BaseConfigItem CreateConfigItem()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (HasAcceptableValues)
			{
				TextDropDownOptions options = new TextDropDownOptions(Array.Empty<string>())
				{
					Values = AcceptableValues.ToArray()
				};
				return (BaseConfigItem)new TextDropDownConfigItem(base.ValidatedEntry, FillBaseOptions<TextDropDownOptions>(options));
			}
			TextInputFieldOptions options2 = new TextInputFieldOptions
			{
				CharacterLimit = CharacterLimit,
				NumberOfLines = NumberOfLines,
				TrimText = TrimText
			};
			return (BaseConfigItem)new TextInputFieldConfigItem(base.ValidatedEntry, FillBaseOptions<TextInputFieldOptions>(options2));
		}
	}
}