Decompiled source of Librarium v0.0.7

giosuel.Librarium.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Librarium.Binding;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;

[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("giosuel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A modding library that provides utilities for the Imperium mods.")]
[assembly: AssemblyFileVersion("0.0.7.0")]
[assembly: AssemblyInformationalVersion("0.0.7+a56dc6cbc9b876145c3d4c0aa17b7a754ef87e03")]
[assembly: AssemblyProduct("Librarium")]
[assembly: AssemblyTitle("giosuel.Librarium")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/giosuel/librarium")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Librarium
{
	public static class Debugging
	{
		public static List<Type> GetParentTypes(Type type)
		{
			List<Type> list = new List<Type>();
			Type type2 = type;
			while (type2 != null)
			{
				list.Add(type2);
				type2 = type2.BaseType;
			}
			return list;
		}

		public static List<Type> GetParentTypes<T>()
		{
			return GetParentTypes(typeof(T));
		}

		public static string GetTransformPath(Transform root)
		{
			if (!Object.op_Implicit((Object)(object)root))
			{
				return "";
			}
			List<string> list = new List<string>();
			while (Object.op_Implicit((Object)(object)root))
			{
				list.Add(((Object)root).name);
				root = root.parent;
			}
			return list.AsEnumerable().Reverse().Aggregate((string a, string b) => a + "/" + b);
		}

		public static string GetStackTrace()
		{
			return "Stack Trace Report\n" + (from tr in new StackTrace().GetFrames()?.ToList().Skip(1)
				select $"{tr.GetMethod().DeclaringType?.FullName} :: {tr.GetMethod()}").Aggregate((string a, string b) => a + "\n -> " + b).Trim();
		}
	}
	public static class Formatting
	{
		public static string FormatVector(Vector3 input, int roundDigits = 1, string separator = "/", string unit = "")
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			float num = ((roundDigits > -1) ? MathF.Round(input.x, roundDigits) : input.x);
			float num2 = ((roundDigits > -1) ? MathF.Round(input.y, roundDigits) : input.y);
			float num3 = ((roundDigits > -1) ? MathF.Round(input.z, roundDigits) : input.z);
			return $"({num}{unit}{separator}{num2}{unit}{separator}{num3}{unit})";
		}

		public static string FormatFloatToThreeDigits(float value)
		{
			if (!(value >= 100f))
			{
				if (value >= 10f)
				{
					return MathF.Round(value, 1).ToString(CultureInfo.InvariantCulture);
				}
				return MathF.Round(value, 2).ToString(CultureInfo.InvariantCulture);
			}
			return Mathf.RoundToInt(value).ToString();
		}

		public static string FormatSecondsMinutes(float seconds)
		{
			if (seconds < 60f)
			{
				return $"{seconds:0}s";
			}
			if (seconds % 60f != 0f)
			{
				return $"{(int)seconds / 60}m {(int)seconds % 60}s";
			}
			return $"{seconds / 60f:0}m";
		}
	}
	public static class Geometry
	{
		private const float SPHERE_RINGS_COUNT = 32f;

		private const float SPHERE_LINES_COUNT = 16f;

		public static Rect NormalizeRectTransform(RectTransform input, float canvasScale)
		{
			//IL_0001: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			return Rect.MinMaxRect(input.offsetMin.x * canvasScale / (float)Screen.width, input.offsetMin.y * canvasScale / (float)Screen.height, ((float)Screen.width + input.offsetMax.x * canvasScale) / (float)Screen.width, ((float)Screen.height + input.offsetMax.y * canvasScale) / (float)Screen.height);
		}

		public static LineRenderer CreateLine(Transform parent = null, float thickness = 0.05f, bool useWorldSpace = false, string lineName = null, Color? startColor = null, Color? endColor = null, bool spawnDisabled = false, params Vector3[] positions)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject();
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			((Renderer)val2).material = new Material(Shader.Find("Sprites/Default"));
			val2.startWidth = thickness;
			val2.endWidth = thickness;
			val2.useWorldSpace = useWorldSpace;
			val2.positionCount = 2;
			if (lineName != null)
			{
				((Object)val).name = lineName;
			}
			if (Object.op_Implicit((Object)(object)parent))
			{
				val.transform.SetParent(parent);
			}
			if (startColor.HasValue)
			{
				val2.startColor = startColor.Value;
			}
			if (endColor.HasValue)
			{
				val2.endColor = endColor.Value;
			}
			if (positions.Length != 0)
			{
				SetLinePositions(val2, positions);
			}
			if (spawnDisabled)
			{
				val.SetActive(false);
			}
			return val2;
		}

		public static void SetLineColor(LineRenderer lineRenderer, Color? startColor = null, Color? endColor = null)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (startColor.HasValue)
			{
				lineRenderer.startColor = startColor.Value;
			}
			if (endColor.HasValue)
			{
				lineRenderer.endColor = endColor.Value;
			}
		}

		public static void SetLinePositions(LineRenderer lineRenderer, params Vector3[] positions)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			lineRenderer.positionCount = positions.Length;
			for (int i = 0; i < positions.Length; i++)
			{
				lineRenderer.SetPosition(i, positions[i]);
			}
		}

		public static GameObject CreatePrimitive(PrimitiveType type, [CanBeNull] Transform parent, Color color, float size = 1f, int layer = 0, string name = null, bool removeCollider = true, bool removeRenderer = false, bool spawnDisabled = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreatePrimitive(type, parent, size, name, layer, removeCollider, removeRenderer, spawnDisabled);
			if (!removeRenderer)
			{
				Material material = ((Renderer)val.GetComponent<MeshRenderer>()).material;
				material.shader = Shader.Find("HDRP/Unlit");
				material.color = color;
			}
			if (spawnDisabled)
			{
				val.SetActive(false);
			}
			return val;
		}

		public static GameObject CreatePrimitive(PrimitiveType type, [CanBeNull] Transform parent, [CanBeNull] Material material, float size = 1f, int layer = 0, string name = null, bool removeCollider = true, bool removeRenderer = false, bool spawnDisabled = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreatePrimitive(type, parent, size, name, layer, removeCollider, removeRenderer, spawnDisabled);
			if (!removeRenderer)
			{
				MeshRenderer component = val.GetComponent<MeshRenderer>();
				if (Object.op_Implicit((Object)(object)material))
				{
					((Renderer)component).material = material;
				}
				else
				{
					((Renderer)component).material.shader = Shader.Find("HDRP/Unlit");
				}
			}
			return val;
		}

		private static GameObject CreatePrimitive(PrimitiveType type, [CanBeNull] Transform parent, float size = 1f, string name = null, int layer = 0, bool removeCollider = true, bool removeRenderer = false, bool spawnDisabled = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected I4, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive(type);
			if (name != null)
			{
				((Object)val).name = name;
			}
			val.layer = layer;
			if (removeCollider)
			{
				switch ((int)type)
				{
				case 0:
					Object.Destroy((Object)(object)val.GetComponent<SphereCollider>());
					break;
				case 2:
				case 3:
					Object.Destroy((Object)(object)val.GetComponent<BoxCollider>());
					break;
				case 4:
				case 5:
					Object.Destroy((Object)(object)val.GetComponent<MeshCollider>());
					break;
				case 1:
					Object.Destroy((Object)(object)val.GetComponent<CapsuleCollider>());
					break;
				default:
					throw new ArgumentOutOfRangeException("type", type, null);
				}
			}
			val.transform.localScale = Vector3.one * size;
			if (Object.op_Implicit((Object)(object)parent))
			{
				val.transform.position = parent.position;
				val.transform.SetParent(parent);
			}
			if (removeRenderer)
			{
				Object.Destroy((Object)(object)val.GetComponent<MeshRenderer>());
				Object.Destroy((Object)(object)val.GetComponent<MeshFilter>());
			}
			else
			{
				((Renderer)val.GetComponent<MeshRenderer>()).shadowCastingMode = (ShadowCastingMode)0;
			}
			if (spawnDisabled)
			{
				val.SetActive(false);
			}
			return val;
		}

		public static Mesh CreateCone(float angle)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh();
			angle *= 2f;
			int num = Mathf.Max(2, (int)(32f * (angle / 360f)) + 1);
			int num2 = num * 16 + 2;
			Vector3[] array = (Vector3[])(object)new Vector3[num2];
			int[] array2 = new int[6 * (num + 1) * 16];
			array[0] = new Vector3(0f, 0f, 1f);
			array[num2 - 1] = new Vector3(0f, 0f, 0f);
			for (int i = 1; i < num + 1; i++)
			{
				int num3 = (i - 1) * 16 + 1;
				float num4 = MathF.PI / 180f * angle * ((float)i / (float)num) / 2f;
				float num5 = Mathf.Cos(num4);
				float num6 = Mathf.Sin(num4);
				for (int j = 0; (float)j < 16f; j++)
				{
					float num7 = MathF.PI * -2f * ((float)j / 16f);
					int num8 = num3 + j;
					array[num8] = new Vector3(Mathf.Cos(num7), Mathf.Sin(num7), num5 / num6) * num6;
					int num9 = 6 * num3 + j * 6 - 48;
					int num10 = (int)((float)num3 + (float)(j + 1) % 16f);
					if (i != 1)
					{
						array2[num9] = num8 - 16;
						array2[num9 + 1] = num10;
						array2[num9 + 2] = num8;
						array2[num9 + 3] = num10 - 16;
						array2[num9 + 4] = num10;
						array2[num9 + 5] = num8 - 16;
					}
					else
					{
						num9 += 48;
						num9 /= 2;
						array2[num9] = 0;
						array2[num9 + 1] = num10;
						array2[num9 + 2] = num8;
					}
					if (i == num)
					{
						num9 += 96;
						array2[num9] = num2 - 1;
						array2[num9 + 1] = num8;
						array2[num9 + 2] = num10;
					}
				}
			}
			val.SetVertices(array.ToList());
			val.SetIndices(array2.ToList(), (MeshTopology)0, 0, true, 0);
			return val;
		}

		public static List<Mesh> GetNavmeshSurfaces()
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			NavMeshTriangulation triangulation = NavMesh.CalculateTriangulation();
			List<Mesh> list = new List<Mesh> { GetNavmeshMeshFromTriangulation(triangulation) };
			for (int num = 1; num <= 512; num *= 2)
			{
				list.Add(GetNavmeshMeshFromTriangulation(triangulation, num));
			}
			return list;
		}

		private static Mesh GetNavmeshMeshFromTriangulation(NavMeshTriangulation triangulation, int? bitMask = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh();
			val.SetVertices(triangulation.vertices);
			List<int> list = new List<int>();
			for (int i = 0; i < triangulation.indices.Length / 3; i++)
			{
				if (!bitMask.HasValue || (triangulation.areas[i] & bitMask) != 0)
				{
					list.Add(triangulation.indices[i * 3]);
					list.Add(triangulation.indices[i * 3 + 1]);
					list.Add(triangulation.indices[i * 3 + 2]);
				}
			}
			val.SetIndices(list, (MeshTopology)0, 0, true, 0);
			return val;
		}
	}
	public static class ImpMath
	{
		public static float SampleQuadraticBezier(float start, float end, float control, float t)
		{
			return (1f - t) * (1f - t) * start + 2f * (1f - t) * t * control + t * t * end;
		}

		public static float NormalizeFloat(float value)
		{
			string[] array = value.ToString(CultureInfo.InvariantCulture).Split('.');
			if (array.Length == 1)
			{
				return value;
			}
			if (int.Parse(array[1]) == 0)
			{
				return (int)value;
			}
			return MathF.Round(value);
		}

		public static Vector3 ClosestPointAlongRay(Ray ray, Vector3 point)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Vector3 origin = ((Ray)(ref ray)).origin;
			Vector3 val = ((Ray)(ref ray)).origin + ((Ray)(ref ray)).direction;
			Vector3 val2 = val - origin;
			float num = Vector3.Dot(point - origin, val2);
			num = Mathf.Max(num, 0f);
			return ((Ray)(ref ray)).origin + ((Ray)(ref ray)).direction * num;
		}
	}
	public class ImpTimer
	{
		private float initialTime;

		private float countdown;

		private ImpTimer()
		{
		}

		public static ImpTimer ForInterval(float seconds)
		{
			return new ImpTimer
			{
				initialTime = seconds,
				countdown = seconds
			};
		}

		public void Set(float newTime)
		{
			initialTime = newTime;
		}

		public bool Tick()
		{
			countdown -= Time.deltaTime;
			if (countdown <= 0f)
			{
				countdown = initialTime;
				return true;
			}
			return false;
		}

		public void Reset()
		{
			countdown = initialTime;
		}
	}
	[BepInPlugin("giosuel.Librarium", "Librarium", "0.0.7")]
	public class Librarium : BaseUnityPlugin
	{
		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Librarium has been loaded successfully! \\o/");
		}
	}
	public static class Log
	{
		public static string LogBlock(List<string> lines, string title)
		{
			title = "< " + title + " >";
			int width = Mathf.Min(lines.Max((string line) => line.Length) + 4, 520);
			string text = string.Concat(Enumerable.Repeat("═", width - 2));
			int num = (width - title.Length) / 2 - 1;
			if ((width - title.Length) / 2 % 2 == 0)
			{
				num++;
			}
			string text2 = string.Concat(Enumerable.Repeat(" ", num));
			string text3 = "╒" + text + "╕\n";
			text3 = text3 + "│" + text2 + title + text2 + "│\n";
			text3 = text3 + "╞" + text + "╡\n";
			text3 = lines.Aggregate(text3, delegate(string current, string line)
			{
				string text4 = ((line.Length > 512) ? (line.Substring(0, 512) + "...") : line);
				return current + ("│ " + text4).PadRight(width - 2) + " │\n";
			});
			text3 = text3 + "╘" + text + "╛";
			return text3.Split("\n").Aggregate("", (string current, string se) => current + se.Trim());
		}
	}
	public static class Reflection
	{
		public static void Invoke<T>(T instance, string methodName, params object[] parameters)
		{
			typeof(T).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic).Invoke(instance, parameters);
		}

		public static R Invoke<T, R>(T instance, string methodName, params object[] parameters)
		{
			object obj = typeof(T).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic).Invoke(instance, parameters);
			if (obj is R)
			{
				return (R)obj;
			}
			throw new ArgumentOutOfRangeException();
		}

		public static IEnumerator GetCoroutine<T>(T instance, string methodName)
		{
			return (IEnumerator)typeof(T).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic).Invoke(instance, Array.Empty<object>());
		}

		public static R Get<T, R>(T instance, string fieldName, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic)
		{
			object value = typeof(T).GetField(fieldName, bindingFlags).GetValue(instance);
			return (R)value;
		}

		public static void Set<T, V>(T instance, string fieldName, V value, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic)
		{
			typeof(T).GetField(fieldName, bindingFlags).SetValue(instance, value);
		}

		public static void SetProperty<T, V>(T instance, string propertyName, V value, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic)
		{
			typeof(T).InvokeMember(propertyName, bindingFlags | BindingFlags.SetProperty, null, instance, new object[1] { value });
		}

		public static void CopyField<T>(T source, T target, string fieldName, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic)
		{
			FieldInfo field = typeof(T).GetField(fieldName, bindingFlags);
			field.SetValue(target, field.GetValue(source));
		}
	}
	public static class RichText
	{
		public static string Strikethrough(string value)
		{
			return "<s>" + value + "</s>";
		}

		public static string Underlined(string value)
		{
			return "<u>" + value + "</u>";
		}

		public static string Bold(string value)
		{
			return "<b>" + value + "</b>";
		}

		public static string Italic(string value)
		{
			return "<i>" + value + "</i>";
		}

		public static string Size(string value, int size)
		{
			return $"<size={size}>{value}</size>";
		}
	}
	public class SettingsContainer
	{
		private ConfigFile config;

		public SettingsContainer(ConfigFile config)
		{
			this.config = config;
			base..ctor();
		}

		public void Load()
		{
			GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic).ToList().ForEach(delegate(FieldInfo field)
			{
				(field.GetValue(this) as IRefreshable)?.Refresh();
			});
		}

		public void Reset()
		{
			GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic).ToList().ForEach(delegate(FieldInfo field)
			{
				(field.GetValue(this) as IResettable)?.Reset();
			});
		}
	}
	public static class Utils
	{
		public abstract class Bindings
		{
			public static void ToggleSet<T>(IBinding<HashSet<T>> binding, T key, bool isOn)
			{
				if (isOn)
				{
					binding.Value.Add(key);
				}
				else
				{
					binding.Value.Remove(key);
				}
				binding.Set(binding.Value);
			}
		}

		public abstract class Transpiling
		{
			public static IEnumerable<CodeInstruction> SkipWaitingForSeconds(IEnumerable<CodeInstruction> instructions)
			{
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				for (int i = 0; i < list.Count; i++)
				{
					if (i >= 2 && list[i].opcode == OpCodes.Stfld && list[i - 1].opcode == OpCodes.Newobj && list[i - 2].opcode == OpCodes.Ldc_R4)
					{
						list[i - 2].operand = 0f;
					}
				}
				return list.AsEnumerable();
			}
		}

		public static T DictionaryGetOrNew<T>(IDictionary<string, T> map, string key) where T : new()
		{
			if (map.TryGetValue(key, out var value))
			{
				return value;
			}
			return map[key] = new T();
		}

		public static void ToggleGameObjects(IEnumerable<GameObject> list, bool isOn)
		{
			foreach (GameObject item in list.Where((GameObject obj) => Object.op_Implicit((Object)(object)obj)))
			{
				item.SetActive(isOn);
			}
		}

		public static Random CloneRandom(Random random)
		{
			Random random2 = new Random();
			int[] source = Reflection.Get<Random, int[]>(random, "_seedArray");
			Reflection.Set(random2, "_seedArray", source.ToArray());
			Reflection.CopyField(random, random2, "_inextp");
			Reflection.CopyField(random, random2, "_inext");
			return random2;
		}

		public static T InvokeOrDefault<T>(Func<T> callback)
		{
			try
			{
				return callback();
			}
			catch (NullReferenceException)
			{
				return default(T);
			}
		}

		public static int ToggleLayerInMask(int layerMask, int layer)
		{
			if ((layerMask & (1 << layer)) != 0)
			{
				return layerMask & ~(1 << layer);
			}
			return layerMask | (1 << layer);
		}

		public static int ToggleLayersInMask(int layerMask, params int[] layers)
		{
			return layers.Aggregate(layerMask, ToggleLayerInMask);
		}

		public static bool RunSafe(Action action, string logTitle = null)
		{
			Exception exception;
			return RunSafe(action, out exception, logTitle);
		}

		private static bool RunSafe(Action action, out Exception exception, string logTitle = null)
		{
			try
			{
				action();
				exception = null;
				return true;
			}
			catch (Exception ex)
			{
				exception = ex;
				if (logTitle != null)
				{
					Log.LogBlock((from line in exception.StackTrace.Split('\n')
						select line.Trim()).ToList(), "[ERR] " + logTitle + ": " + exception.Message);
				}
				return false;
			}
		}
	}
	internal static class LCMPluginInfo
	{
		public const string PLUGIN_GUID = "giosuel.Librarium";

		public const string PLUGIN_NAME = "Librarium";

		public const string PLUGIN_VERSION = "0.0.7";
	}
}
namespace Librarium.Binding
{
	public interface IBinding<T> : IResettable, IRefreshable
	{
		T Value { get; }

		T DefaultValue { get; }

		event Action<T> OnUpdate;

		event Action<T> OnUpdateSecondary;

		event Action OnTrigger;

		event Action OnTriggerSecondary;

		void Set(T updatedValue, bool invokePrimary = true, bool invokeSecondary = true);

		new void Refresh();

		new void Reset(bool invokePrimary = true, bool invokeSecondary = true);
	}
	public interface IRefreshable
	{
		void Refresh();
	}
	public interface IResettable
	{
		void Reset(bool invokePrimary = true, bool invokeSecondary = true);
	}
	public class ImpBinaryBinding : ImpBinding<bool>
	{
		public event Action OnTrue;

		public event Action OnFalse;

		public ImpBinaryBinding(bool currentValue, Action onTrue = null, Action onFalse = null)
			: base(currentValue, defaultValue: false, (Action<bool>)null, (Action<bool>)null, ignoreRefresh: false)
		{
			OnTrue += onTrue;
			OnFalse += onFalse;
			base.OnUpdate += OnBaseUpdate;
		}

		public void Toggle()
		{
			Set(!base.Value);
		}

		public void SetTrue()
		{
			Set(updatedValue: true);
		}

		public void SetFalse()
		{
			Set(updatedValue: false);
		}

		private void OnBaseUpdate(bool updatedValue)
		{
			if (updatedValue)
			{
				this.OnTrue?.Invoke();
			}
			else
			{
				this.OnFalse?.Invoke();
			}
		}

		public static bool operator true(ImpBinaryBinding obj)
		{
			return obj.Value;
		}

		public static bool operator false(ImpBinaryBinding obj)
		{
			return !obj.Value;
		}

		public static bool operator !(ImpBinaryBinding obj)
		{
			return !obj.Value;
		}

		public static ImpBinaryBinding CreateAnd((IBinding<bool>, bool)[] bindingPairs)
		{
			ImpBinaryBinding combinedBinding = new ImpBinaryBinding(GetCombinedAndValue(bindingPairs));
			(IBinding<bool>, bool)[] array = bindingPairs;
			for (int i = 0; i < array.Length; i++)
			{
				(IBinding<bool>, bool) tuple = array[i];
				tuple.Item1.OnTrigger += delegate
				{
					combinedBinding.Set(GetCombinedAndValue(bindingPairs));
				};
			}
			return combinedBinding;
			static bool GetCombinedAndValue((IBinding<bool>, bool)[] pairs)
			{
				return pairs.Aggregate(seed: true, (bool combined, (IBinding<bool>, bool) current) => combined && (current.Item2 ^ current.Item1.Value));
			}
		}

		public static ImpBinaryBinding CreateOr((IBinding<bool>, bool)[] bindingPairs)
		{
			ImpBinaryBinding combinedBinding = new ImpBinaryBinding(GetCombinedOrValue(bindingPairs));
			(IBinding<bool>, bool)[] array = bindingPairs;
			for (int i = 0; i < array.Length; i++)
			{
				(IBinding<bool>, bool) tuple = array[i];
				tuple.Item1.OnTrigger += delegate
				{
					combinedBinding.Set(GetCombinedOrValue(bindingPairs));
				};
			}
			return combinedBinding;
			static bool GetCombinedOrValue((IBinding<bool>, bool)[] pairs)
			{
				return pairs.Aggregate(seed: false, (bool combined, (IBinding<bool>, bool) current) => combined || (current.Item2 ^ current.Item1.Value));
			}
		}
	}
	public class ImpBinding<T> : IBinding<T>, IResettable, IRefreshable
	{
		private readonly bool ignoreRefresh;

		public T DefaultValue { get; }

		public T Value { get; protected set; }

		public event Action<T> OnUpdate;

		public event Action<T> OnUpdateSecondary;

		public event Action OnTrigger;

		public event Action OnTriggerSecondary;

		public ImpBinding()
		{
		}

		public ImpBinding(T currentValue = default(T), T defaultValue = default(T), Action<T> primaryUpdate = null, Action<T> onUpdateSecondary = null, bool ignoreRefresh = false)
		{
			Value = currentValue;
			DefaultValue = ((!EqualityComparer<T>.Default.Equals(defaultValue, default(T))) ? defaultValue : currentValue);
			this.ignoreRefresh = ignoreRefresh;
			OnUpdate += primaryUpdate;
			OnUpdateSecondary += onUpdateSecondary;
		}

		public virtual void Set(T updatedValue, bool invokePrimary = true, bool invokeSecondary = true)
		{
			bool flag = EqualityComparer<T>.Default.Equals(updatedValue, Value);
			Value = updatedValue;
			if (invokePrimary)
			{
				this.OnUpdate?.Invoke(Value);
				this.OnTrigger?.Invoke();
			}
			if (invokeSecondary && !flag)
			{
				this.OnUpdateSecondary?.Invoke(updatedValue);
				this.OnTriggerSecondary?.Invoke();
			}
		}

		public virtual void Refresh()
		{
			if (!ignoreRefresh)
			{
				Set(Value);
			}
		}

		public void Reset(bool invokePrimary = true, bool invokeSecondary = true)
		{
			Set(DefaultValue, invokePrimary, invokeSecondary);
		}
	}
	public sealed class ImpConfig<T> : ImpBinding<T>
	{
		private readonly ConfigEntry<T> config;

		private readonly Func<bool> isDisabled;

		private readonly bool allowWhenDisabled;

		public new T Value
		{
			get
			{
				Func<bool> func = isDisabled;
				if (func != null && func() && !allowWhenDisabled)
				{
					return base.DefaultValue;
				}
				return base.Value;
			}
		}

		public ImpConfig(ConfigFile configFile, string section, string key, T defaultValue, Action<T> primaryUpdate = null, Action<T> secondaryUpdate = null, bool ignoreRefresh = false, bool allowWhenDisabled = false, string description = null, Func<bool> isDisabled = null)
			: base(defaultValue, default(T), primaryUpdate, secondaryUpdate, ignoreRefresh)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			this.allowWhenDisabled = allowWhenDisabled;
			this.isDisabled = isDisabled;
			object obj = this;
			object obj2 = configFile;
			string text = section;
			text = key;
			obj2 = defaultValue;
			obj = (object)(string.IsNullOrEmpty(description) ? ((ConfigDescription)null) : new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
			((ImpConfig<T>)obj).config = ((ConfigFile)obj2).Bind<T>(text, text, (T)obj2, (ConfigDescription)obj);
			base.Value = config.Value;
		}

		public override void Set(T updatedValue, bool invokePrimary = true, bool invokeSecondary = true)
		{
			config.Value = updatedValue;
			base.Set(updatedValue, invokePrimary, invokeSecondary);
		}

		public override void Refresh()
		{
			Func<bool> func = isDisabled;
			base.Value = ((func == null || !func() || allowWhenDisabled) ? base.Value : base.DefaultValue);
			base.Refresh();
		}
	}
	public class ImpEvent
	{
		public event Action OnTrigger;

		public void Trigger()
		{
			this.OnTrigger?.Invoke();
		}
	}
	public class ImpExternalBinding<T, R> : ImpBinding<T>
	{
		private readonly Func<T> valueGetter;

		public ImpExternalBinding(Func<T> valueGetter, IBinding<R> refresher = null, Action<T> onPrimaryUpdate = null, Action<T> secondaryUpdate = null)
			: base(Utils.InvokeOrDefault(valueGetter), default(T), onPrimaryUpdate, secondaryUpdate, ignoreRefresh: false)
		{
			ImpExternalBinding<T, R> impExternalBinding = this;
			this.valueGetter = valueGetter;
			if (refresher != null)
			{
				refresher.OnUpdate += delegate
				{
					impExternalBinding.Set(Utils.InvokeOrDefault(valueGetter));
				};
			}
		}

		public override void Refresh()
		{
			base.Set(Utils.InvokeOrDefault(valueGetter));
		}
	}
	public class ImpImmutableBinding<T> : IBinding<T>, IResettable, IRefreshable
	{
		private readonly IBinding<T> parentWritableBinding;

		public T Value => parentWritableBinding.Value;

		public T DefaultValue => parentWritableBinding.DefaultValue;

		public event Action<T> OnUpdate;

		public event Action OnTrigger;

		public event Action<T> OnUpdateSecondary;

		public event Action OnTriggerSecondary;

		public static ImpImmutableBinding<T> Wrap(IBinding<T> parent)
		{
			return new ImpImmutableBinding<T>(parent);
		}

		private ImpImmutableBinding(IBinding<T> parentWritableBinding)
		{
			this.parentWritableBinding = parentWritableBinding;
			parentWritableBinding.OnUpdate += delegate(T value)
			{
				this.OnUpdate?.Invoke(value);
			};
			parentWritableBinding.OnTrigger += delegate
			{
				this.OnTrigger?.Invoke();
			};
			parentWritableBinding.OnUpdateSecondary += delegate(T value)
			{
				this.OnUpdateSecondary?.Invoke(value);
			};
			parentWritableBinding.OnTriggerSecondary += delegate
			{
				this.OnTriggerSecondary?.Invoke();
			};
		}

		public void Set(T updatedValue, bool invokePrimary = true, bool invokeSecondary = true)
		{
		}

		public void Refresh()
		{
		}

		public void Reset(bool invokePrimary, bool invokeSecondary)
		{
		}
	}
}