Decompiled source of RandomAvatar v1.2.0

Mods/RandomAvatar.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.SceneStreaming;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using LabFusion;
using LabFusion.Data;
using LabFusion.Entities;
using LabFusion.Extensions;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.SDK.Metadata;
using LabFusion.Senders;
using LabFusion.Utilities;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using RandomAvatar;
using RandomAvatar.Helper;
using RandomAvatar.Menu;
using RandomAvatar.Menu.Elements;
using RandomAvatar.Patches;
using RandomAvatar.Utilities;
using Semver;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "RandomAvatar", "1.2.0", "HAHOOS", "https://thunderstore.io/c/bonelab/p/HAHOOS/RandomAvatar")]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonColor(0, 255, 0, 255)]
[assembly: MelonAuthorColor(0, 255, 165, 0)]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[assembly: AssemblyTitle("Lets you switch to a random avatar by pressing button, as well in other ways")]
[assembly: AssemblyDescription("Lets you switch to a random avatar by pressing button, as well in other ways")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HAHOOS")]
[assembly: AssemblyProduct("RandomAvatar")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: ComVisible(false)]
[assembly: Guid("6c044178-2021-4782-90bf-1dc7b0a93b08")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RandomAvatar
{
	internal static class BlacklistWhitelist
	{
		public enum SortMode
		{
			Amount,
			Alphabetical
		}

		public enum SortDirection
		{
			Ascending,
			Descending
		}

		public static MelonPreferences_Category Category;

		public static MelonPreferences_Entry<bool> IsWhitelist;

		public static MelonPreferences_Entry<bool> Enabled;

		public static MelonPreferences_Entry<List<string>> TagsList;

		public static MelonPreferences_Entry<List<string>> AvatarList;

		public static MelonPreferences_Entry<List<string>> PalletList;

		public static Dictionary<string, int> Tags = new Dictionary<string, int>();

		public static Dictionary<string, string> Avatars = new Dictionary<string, string>();

		public static List<PalletRef> PalletRefs = new List<PalletRef>();

		internal static bool refreshRequired = false;

		private static SortDirection tags_sortDirection = SortDirection.Descending;

		private static SortMode tags_sortMode = SortMode.Amount;

		private static SortDirection avatars_sortDirection = SortDirection.Ascending;

		private static SortDirection pallets_sortDirection = SortDirection.Descending;

		private static SortMode pallets_sortMode = SortMode.Amount;

		private static readonly List<FunctionElement> tagElements = new List<FunctionElement>();

		private static readonly List<FunctionElement> avatarElements = new List<FunctionElement>();

		private static readonly List<FunctionElement> palletElements = new List<FunctionElement>();

		private static bool mainPageSetup = false;

		public static Page Page { get; internal set; }

		private static Page TagsPage { get; set; }

		private static Page AvatarPage { get; set; }

		private static Page PalletPage { get; set; }

		public static bool IsSetup { get; private set; } = false;


		public static void Setup()
		{
			if (!IsSetup)
			{
				IsSetup = true;
				Category = MelonPreferences.CreateCategory("RandomAvatar_BlacklistWhitelist");
				Enabled = Category.CreateEntry<bool>("Enabled", false, "Enabled", "If true, whitelist/blacklist will be checked when changing into random avatar", false, false, (ValueValidator)null, (string)null);
				IsWhitelist = Category.CreateEntry<bool>("IsWhitelist", false, "Is Whitelist", "If true, the avatar will be allowed if it has the tags, if false, it will be allowed only if it doesn't have the tag", false, false, (ValueValidator)null, (string)null);
				TagsList = Category.CreateEntry<List<string>>("TagsList", new List<string>(), "Tags List", "List of all tags/groups", false, false, (ValueValidator)null, (string)null);
				AvatarList = Category.CreateEntry<List<string>>("AvatarList", new List<string>(), "Avatar List", "List of all avatar", false, false, (ValueValidator)null, (string)null);
				PalletList = Category.CreateEntry<List<string>>("PalletList", new List<string>(), "Pallet List", "List of all pallets", false, false, (ValueValidator)null, (string)null);
				Category.SetFilePath(Path.Combine(MelonEnvironment.UserDataDirectory, "RandomAvatar.cfg"));
				Category.SaveToFile(false);
				if (AssetWarehouse.ready)
				{
					Hooks();
				}
				else
				{
					Hooking.OnWarehouseReady += Hooks;
				}
			}
		}

		private static void Hooks()
		{
			AssetWarehouse instance = AssetWarehouse.Instance;
			instance.OnChanged += Action.op_Implicit((Action)delegate
			{
				refreshRequired = true;
				SetupPage();
			});
			AssetWarehouse instance2 = AssetWarehouse.Instance;
			instance2.OnCrateAdded += Action<Barcode>.op_Implicit((Action<Barcode>)delegate
			{
				refreshRequired = true;
				SetupPage();
			});
		}

		private static Dictionary<string, int> GetAllTags(SortMode mode, SortDirection direction)
		{
			if (!AssetWarehouse.ready)
			{
				return null;
			}
			Dictionary<string, int> tags = new Dictionary<string, int>();
			if (Tags == null || Tags.Count == 0 || refreshRequired)
			{
				List<AvatarCrate> crates = AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null);
				Tags?.Clear();
				crates.ForEach(Action<AvatarCrate>.op_Implicit((Action<AvatarCrate>)delegate(AvatarCrate x)
				{
					((Crate)x).Tags.ForEach(Action<string>.op_Implicit((Action<string>)delegate(string x)
					{
						if (tags.ContainsKey(x))
						{
							tags[x]++;
						}
						else
						{
							tags.Add(x, 1);
						}
					}));
				}));
			}
			else
			{
				tags = Tags ?? new Dictionary<string, int>();
			}
			if (mode == SortMode.Amount)
			{
				if (direction != 0)
				{
					return tags.OrderByDescending((KeyValuePair<string, int> x) => x.Value).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
				}
				return tags.OrderBy((KeyValuePair<string, int> x) => x.Value).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
			}
			if (direction != 0)
			{
				return tags.OrderByDescending((KeyValuePair<string, int> x) => x.Key).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
			}
			return tags.OrderBy((KeyValuePair<string, int> x) => x.Key).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
		}

		private static Dictionary<string, string> GetAllAvatars(SortDirection direction)
		{
			if (!AssetWarehouse.ready)
			{
				return null;
			}
			Dictionary<string, string> avatars = new Dictionary<string, string>();
			if (Avatars == null || Avatars.Count == 0 || refreshRequired)
			{
				List<AvatarCrate> crates = AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null);
				Avatars?.Clear();
				crates.ForEach(Action<AvatarCrate>.op_Implicit((Action<AvatarCrate>)delegate(AvatarCrate x)
				{
					if (Core.Entry_UseRedacted.Value || !((Scannable)x).Redacted)
					{
						avatars.Add(((Scannable)x).Barcode.ID, ((Scannable)x).Title);
					}
				}));
			}
			else
			{
				avatars = Avatars ?? new Dictionary<string, string>();
			}
			if (direction != 0)
			{
				return avatars.OrderByDescending((KeyValuePair<string, string> x) => x.Value).ToDictionary((KeyValuePair<string, string> x) => x.Key, (KeyValuePair<string, string> x) => x.Value);
			}
			return avatars.OrderBy((KeyValuePair<string, string> x) => x.Value).ToDictionary((KeyValuePair<string, string> x) => x.Key, (KeyValuePair<string, string> x) => x.Value);
		}

		private static List<PalletRef> GetAllPallets(SortMode mode, SortDirection direction)
		{
			if (!AssetWarehouse.ready)
			{
				return null;
			}
			List<PalletRef> list = new List<PalletRef>();
			if (PalletRefs == null || PalletRefs.Count == 0 || refreshRequired)
			{
				Enumerator<Pallet> enumerator = AssetWarehouse.Instance.GetPallets().GetEnumerator();
				while (enumerator.MoveNext())
				{
					PalletRef palletRef = new PalletRef(enumerator.Current);
					if (palletRef != null)
					{
						List<Crate> avatars = palletRef.Avatars;
						if (avatars != null && avatars.Count > 0)
						{
							list.Add(palletRef);
						}
					}
				}
			}
			else
			{
				list = PalletRefs ?? new List<PalletRef>();
			}
			if (mode == SortMode.Alphabetical)
			{
				if (direction != 0)
				{
					return list.OrderByDescending((PalletRef x) => ((Scannable)x.Pallet).Title).ToList();
				}
				return list.OrderBy((PalletRef x) => ((Scannable)x.Pallet).Title).ToList();
			}
			if (direction != 0)
			{
				return list.OrderByDescending((PalletRef x) => x.Avatars.Count).ToList();
			}
			return list.OrderBy((PalletRef x) => x.Avatars.Count).ToList();
		}

		public static void CleanupPage(Page page)
		{
			Dictionary<Page, List<Element>> elements = new Dictionary<Page, List<Element>> { 
			{
				page,
				new List<Element>(page.Elements)
			} };
			page.SubPages.ForEach(delegate(SubPage subPage)
			{
				if (subPage != null)
				{
					IReadOnlyList<Element> elements2 = ((Page)subPage).Elements;
					if (elements2 != null && elements2.Count > 0)
					{
						elements.Add((Page)(object)subPage, new List<Element>(((Page)subPage).Elements));
					}
				}
			});
			foreach (KeyValuePair<Page, List<Element>> item in elements)
			{
				foreach (Element item2 in item.Value)
				{
					item.Key.Remove(item2);
				}
			}
			_ = page.SubPages.Count;
		}

		public static void SetupTagsPage(bool refreshRequiredSet = true)
		{
			//IL_005e: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			if (!IsSetup)
			{
				return;
			}
			Tags = GetAllTags(tags_sortMode, tags_sortDirection);
			if (refreshRequiredSet)
			{
				refreshRequired = false;
			}
			if (TagsPage == null)
			{
				TagsPage = Page.CreatePage("Tags", Color.red, 10, true);
			}
			CleanupPage(TagsPage);
			TagsPage.CreateEnum("Sort Direction", Color.yellow, (Enum)tags_sortDirection, (Action<Enum>)delegate(Enum val)
			{
				tags_sortDirection = (SortDirection)(object)val;
				SetupTagsPage();
			});
			TagsPage.CreateEnum("Sort Mode", Color.blue, (Enum)tags_sortMode, (Action<Enum>)delegate(Enum val)
			{
				tags_sortMode = (SortMode)(object)val;
				SetupTagsPage();
			});
			TagsPage.CreateFunction("Add all", new Color(0f, 1f, 0f), (Action)delegate
			{
				List<string> list = new List<string>();
				foreach (KeyValuePair<string, int> tag2 in Tags)
				{
					list.Add(tag2.Key);
				}
				TagsList.Value = list;
				tagElements.ForEach(delegate(FunctionElement item)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					((Element)item).ElementColor = new Color(0f, 1f, 0f);
				});
				Category.SaveToFile(false);
			});
			TagsPage.CreateFunction("Remove all", new Color(0f, 1f, 0f), (Action)delegate
			{
				TagsList.Value = new List<string>();
				tagElements.ForEach(delegate(FunctionElement item)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					((Element)item).ElementColor = Color.red;
				});
				Category.SaveToFile(false);
			});
			TagsPage.CreateFunction("Refresh", Color.yellow, (Action)delegate
			{
				refreshRequired = true;
				SetupTagsPage();
			});
			TagsPage.CreateBlank();
			TagsPage.CreateBlank();
			TagsPage.CreateLabel("Go to the next page to see all the tags", Color.white);
			TagsPage.CreateBlank();
			TagsPage.CreateBlank();
			tagElements.Clear();
			foreach (KeyValuePair<string, int> tag in Tags)
			{
				FunctionElement element = null;
				element = TagsPage.CreateFunction($"{tag.Key} [{tag.Value}]", (Color)(TagsList.Value.Contains(tag.Key) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
				{
					//IL_0078: Unknown result type (might be due to invalid IL or missing references)
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					if (TagsList.Value.Contains(tag.Key))
					{
						TagsList.Value.Remove(tag.Key);
						((Element)element).ElementColor = Color.red;
					}
					else
					{
						TagsList.Value.Add(tag.Key);
						((Element)element).ElementColor = new Color(0f, 1f, 0f);
					}
					Category.SaveToFile(false);
				});
				tagElements.Add(element);
			}
		}

		public static void SetupAvatarsPage(bool refreshRequiredSet = true)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			if (!IsSetup)
			{
				return;
			}
			Avatars = GetAllAvatars(avatars_sortDirection);
			if (refreshRequiredSet)
			{
				refreshRequired = false;
			}
			if (AvatarPage == null)
			{
				AvatarPage = Page.CreatePage("Avatars", Color.magenta, 10, true);
			}
			CleanupPage(AvatarPage);
			AvatarPage.CreateEnum("Sort Direction", Color.yellow, (Enum)avatars_sortDirection, (Action<Enum>)delegate(Enum val)
			{
				avatars_sortDirection = (SortDirection)(object)val;
				SetupAvatarsPage();
			});
			AvatarPage.CreateFunction("Add all", new Color(0f, 1f, 0f), (Action)delegate
			{
				List<string> list = new List<string>();
				foreach (KeyValuePair<string, string> avatar2 in Avatars)
				{
					list.Add(avatar2.Value);
				}
				AvatarList.Value = list;
				avatarElements.ForEach(delegate(FunctionElement item)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					((Element)item).ElementColor = new Color(0f, 1f, 0f);
				});
				Category.SaveToFile(false);
			});
			AvatarPage.CreateFunction("Remove all", new Color(0f, 1f, 0f), (Action)delegate
			{
				AvatarList.Value = new List<string>();
				avatarElements.ForEach(delegate(FunctionElement item)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					((Element)item).ElementColor = Color.red;
				});
				Category.SaveToFile(false);
			});
			AvatarPage.CreateFunction("Refresh", Color.yellow, (Action)delegate
			{
				refreshRequired = true;
				SetupAvatarsPage();
			});
			AvatarPage.CreateBlank();
			AvatarPage.CreateBlank();
			AvatarPage.CreateLabel("Go to the next page to see all the avatars", Color.white);
			AvatarPage.CreateBlank();
			AvatarPage.CreateBlank();
			AvatarPage.CreateBlank();
			avatarElements.Clear();
			foreach (KeyValuePair<string, string> avatar in Avatars)
			{
				FunctionElement element = null;
				element = AvatarPage.CreateFunction(avatar.Value, (Color)(AvatarList.Value.Contains(avatar.Key) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
				{
					//IL_0078: Unknown result type (might be due to invalid IL or missing references)
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					if (AvatarList.Value.Contains(avatar.Key))
					{
						AvatarList.Value.Remove(avatar.Key);
						((Element)element).ElementColor = Color.red;
					}
					else
					{
						AvatarList.Value.Add(avatar.Key);
						((Element)element).ElementColor = new Color(0f, 1f, 0f);
					}
					Category.SaveToFile(false);
				});
				avatarElements.Add(element);
			}
		}

		public static void SetupPalletsPage(bool refreshRequiredSet = true)
		{
			//IL_005e: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			if (!IsSetup)
			{
				return;
			}
			PalletRefs = GetAllPallets(pallets_sortMode, pallets_sortDirection);
			if (refreshRequiredSet)
			{
				refreshRequired = false;
			}
			if (PalletPage == null)
			{
				PalletPage = Page.CreatePage("Pallets", Color.cyan, 10, true);
			}
			CleanupPage(PalletPage);
			PalletPage.CreateEnum("Sort Direction", Color.yellow, (Enum)pallets_sortDirection, (Action<Enum>)delegate(Enum val)
			{
				pallets_sortDirection = (SortDirection)(object)val;
				SetupPalletsPage();
			});
			PalletPage.CreateEnum("Sort Mode", Color.blue, (Enum)pallets_sortMode, (Action<Enum>)delegate(Enum val)
			{
				pallets_sortMode = (SortMode)(object)val;
				SetupPalletsPage();
			});
			PalletPage.CreateFunction("Add all", new Color(0f, 1f, 0f), (Action)delegate
			{
				List<string> list = new List<string>();
				foreach (PalletRef palletRef in PalletRefs)
				{
					list.Add(((Scannable)palletRef.Pallet).Barcode.ID);
				}
				PalletList.Value = list;
				palletElements.ForEach(delegate(FunctionElement item)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					((Element)item).ElementColor = new Color(0f, 1f, 0f);
				});
				Category.SaveToFile(false);
			});
			PalletPage.CreateFunction("Remove all", new Color(0f, 1f, 0f), (Action)delegate
			{
				PalletList.Value = new List<string>();
				palletElements.ForEach(delegate(FunctionElement item)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					((Element)item).ElementColor = Color.red;
				});
				Category.SaveToFile(false);
			});
			PalletPage.CreateFunction("Refresh", Color.yellow, (Action)delegate
			{
				refreshRequired = true;
				SetupPalletsPage();
			});
			PalletPage.CreateBlank();
			PalletPage.CreateBlank();
			PalletPage.CreateLabel("Go to the next page to see all the tags", Color.white);
			PalletPage.CreateBlank();
			PalletPage.CreateBlank();
			palletElements.Clear();
			foreach (PalletRef pallet in PalletRefs)
			{
				FunctionElement element = null;
				element = PalletPage.CreateFunction($"{((Scannable)pallet.Pallet).Title} [{pallet.Avatars.Count}]", (Color)(PalletList.Value.Contains(((Scannable)pallet.Pallet).Barcode.ID) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
				{
					//IL_0096: Unknown result type (might be due to invalid IL or missing references)
					//IL_0051: Unknown result type (might be due to invalid IL or missing references)
					if (PalletList.Value.Contains(((Scannable)pallet.Pallet).Barcode.ID))
					{
						PalletList.Value.Remove(((Scannable)pallet.Pallet).Barcode.ID);
						((Element)element).ElementColor = Color.red;
					}
					else
					{
						PalletList.Value.Add(((Scannable)pallet.Pallet).Barcode.ID);
						((Element)element).ElementColor = new Color(0f, 1f, 0f);
					}
					Category.SaveToFile(false);
				});
				palletElements.Add(element);
			}
		}

		public static void SetupPage()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (IsSetup)
			{
				if (!mainPageSetup)
				{
					Page.CreateBoolPref("Enabled", Color.red, ref Enabled, Category);
					Page.CreateBoolPref("Is Whitelist", Color.cyan, ref IsWhitelist, Category);
					Page.CreateBlank();
					mainPageSetup = true;
				}
				SetupTagsPage(refreshRequiredSet: false);
				SetupAvatarsPage(refreshRequiredSet: false);
				SetupPalletsPage();
			}
		}

		public static bool IsAvatarAllowed(AvatarCrate crate)
		{
			if ((Object)(object)crate == (Object)null)
			{
				return false;
			}
			if (!IsSetup)
			{
				return true;
			}
			if (!Enabled.Value)
			{
				return true;
			}
			bool found = false;
			TagsList.Value.ForEach(delegate(string x)
			{
				if (((Crate)crate).Tags.Contains(x))
				{
					found = true;
				}
			});
			if (!found)
			{
				AvatarList.Value.ForEach(delegate(string x)
				{
					if (((Scannable)crate).Barcode.ID == x)
					{
						found = true;
					}
				});
			}
			if (!found)
			{
				PalletList.Value.ForEach(delegate(string x)
				{
					if (((Scannable)((Crate)crate).Pallet).Barcode.ID == x)
					{
						found = true;
					}
				});
			}
			if (found)
			{
				return IsWhitelist.Value;
			}
			return !IsWhitelist.Value;
		}
	}
	internal class PalletRef
	{
		public Pallet Pallet { get; set; }

		public List<Crate> Avatars => Pallet.Crates.FindAll(Predicate<Crate>.op_Implicit((Func<Crate, bool>)((Crate x) => ((MemberInfo)((Object)x).GetIl2CppType()).Name == "AvatarCrate")));

		public PalletRef(Pallet pallet)
		{
			Pallet = pallet;
		}
	}
	public class Core : MelonMod
	{
		public const string Version = "1.2.0";

		internal static MelonPreferences_Entry<bool> Entry_UseRedacted;

		internal static MelonPreferences_Entry<bool> Entry_EffectWhenSwitching;

		internal static MelonPreferences_Entry<bool> Entry_AllowRandomAvatarInYourLobbies;

		internal static MelonPreferences_Entry<int> Entry_MinimumFusionDelay;

		internal static Dictionary<DateTimeOffset, AvatarCrate> _avatarHistory = new Dictionary<DateTimeOffset, AvatarCrate>();

		internal static Thunderstore Thunderstore;

		internal static Package ThunderstorePackage;

		internal static bool IsLatestVersion = false;

		internal static MelonPreferences_Category Preferences_Category { get; private set; }

		internal static Instance Logger { get; private set; }

		internal static LevelInfo LevelInfo { get; private set; }

		public static bool SwapOnDeath { get; internal set; } = false;


		public static bool SwapOnLevelChange { get; internal set; } = false;


		public static bool SwapOnNextLevelChange { get; internal set; } = false;


		public static void SwapAvatar(string barcode, bool usePCFC)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrWhiteSpace(barcode) && AssetWarehouse.Instance.HasCrate(new Barcode(barcode)) && !((Object)(object)Player.RigManager == (Object)null))
			{
				if (usePCFC)
				{
					PullCordForceChange obj = ((GameObject)(((object)GameObject.Find("RandomAvatar")) ?? ((object)new GameObject("RandomAvatar")))).AddComponent<PullCordForceChange>();
					obj.avatarCrate = new AvatarCrateReference(barcode);
					obj.rigManager = Player.RigManager;
					Fusion.SendPullCordEffect();
					obj.ForceChange(((Component)obj.rigManager).gameObject);
				}
				else
				{
					Player.RigManager.SwapAvatarCrate(new Barcode(barcode), true, (Action<bool>)null);
				}
			}
		}

		public static Barcode RandomAvatar()
		{
			if (BlacklistWhitelist.Enabled.Value && (BlacklistWhitelist.TagsList.Value == null || BlacklistWhitelist.TagsList.Value.Count == 0) && (BlacklistWhitelist.AvatarList.Value == null || BlacklistWhitelist.AvatarList.Value.Count == 0) && (BlacklistWhitelist.PalletList.Value == null || BlacklistWhitelist.PalletList.Value.Count == 0))
			{
				BLHelper.SendNotification("Failure", "When having blacklist/whitelist enabled, you need to have at least one tag, avatar and/or pallet selected!", showTitleOnPopup: true, 3f, (NotificationType)2);
				Logger.Error("Cannot swap to random avatar. When having blacklist/whitelist enabled, you need to have at least one tag, avatar and/or pallet selected!");
				return null;
			}
			Random random = new Random();
			List<AvatarCrate> crates = AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null);
			crates.RemoveAll(Predicate<AvatarCrate>.op_Implicit((Func<AvatarCrate, bool>)delegate(AvatarCrate x)
			{
				if ((Object)(object)x == (Object)null)
				{
					return true;
				}
				if (!Entry_UseRedacted.Value && ((Scannable)x).Redacted)
				{
					return true;
				}
				return (!BlacklistWhitelist.IsAvatarAllowed(x)) ? true : false;
			}));
			AvatarCrate val = crates[random.Next(crates.Count)];
			_avatarHistory.Add(DateTimeOffset.Now, val);
			BoneMenu.SetupHistoryPage();
			return ((Scannable)val).Barcode;
		}

		public static void SwapToRandom()
		{
			if (!AssetWarehouse.ready)
			{
				BLHelper.SendNotification("Failure", "Asset Warehouse is not ready and therefore the avatar cannot be switched", showTitleOnPopup: true, 2f, (NotificationType)2);
				return;
			}
			if (!Fusion.IsAllowed())
			{
				BLHelper.SendNotification("Disallowed", "The host of this server has disabled the usage of RandomAvatar, cannot change you into a random avatar", showTitleOnPopup: true, 3.5f, (NotificationType)2);
				return;
			}
			if (BoneMenu.Cooldown > 0)
			{
				BLHelper.SendNotification("Cooldown", $"Wait {BoneMenu.Cooldown} more seconds", showTitleOnPopup: true, 1.5f, (NotificationType)1);
				return;
			}
			Barcode val = RandomAvatar();
			if (!(val == (Barcode)null))
			{
				if (Fusion.IsConnected())
				{
					BoneMenu.Cooldown = BoneMenu.MinimumDelay;
				}
				SwapAvatar(val.ID, Entry_EffectWhenSwitching.Value);
			}
		}

		private void PatchFusion()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(LocalRagdoll).GetMethod("Knockout"), (HarmonyMethod)null, new HarmonyMethod(typeof(LocalRagdollPatches).GetMethod("Postfix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(FusionMod).GetMethod("OnMainSceneInitializeDelayed"), (HarmonyMethod)null, new HarmonyMethod(typeof(FusionPatches).GetMethod("Postfix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public override void OnInitializeMelon()
		{
			Logger = ((MelonBase)this).LoggerInstance;
			try
			{
				Thunderstore = new Thunderstore("RandomAvatar / 1.2.0 A BONELAB Code Mod");
				ThunderstorePackage = Thunderstore.GetPackage("HAHOOS", "RandomAvatar");
				if (ThunderstorePackage != null)
				{
					if (ThunderstorePackage.Latest != null && !string.IsNullOrWhiteSpace(ThunderstorePackage.Latest.Version))
					{
						IsLatestVersion = ThunderstorePackage.IsLatestVersion("1.2.0");
						if (!IsLatestVersion)
						{
							((MelonBase)this).LoggerInstance.Msg(Color.Aqua, "A new version of RandomAvatar is available: v" + ThunderstorePackage.Latest.Version + " while the current is v1.2.0");
						}
						else if (SemVersion.Parse("1.2.0", false) == ThunderstorePackage.Latest.SemVersion)
						{
							((MelonBase)this).LoggerInstance.Msg("Latest version of RandomAvatar is installed! --> v1.2.0");
						}
						else
						{
							((MelonBase)this).LoggerInstance.Msg($"Beta release of RandomAvatar is installed (v{ThunderstorePackage.Latest.Version} is newest, v{"1.2.0"} is installed)");
						}
					}
					else
					{
						((MelonBase)this).LoggerInstance.Error("Latest version could not be found or the version is empty");
					}
				}
				else
				{
					((MelonBase)this).LoggerInstance.Error("Could not find Thunderstore package for RandomAvatar");
				}
			}
			catch (Exception value)
			{
				((MelonBase)this).LoggerInstance.Error($"An unexpected error has occurred while trying to gather thunderstore package information, exception:\n{value}");
			}
			((MelonBase)this).LoggerInstance.Msg("Setting up preferences");
			Preferences_Category = MelonPreferences.CreateCategory("RandomAvatar");
			Entry_UseRedacted = Preferences_Category.CreateEntry<bool>("UseRedacted", false, "Use Redacted", "If true, when switching to random avatar the mod will also include redacted avatars", false, false, (ValueValidator)null, (string)null);
			Entry_EffectWhenSwitching = Preferences_Category.CreateEntry<bool>("EffectWhenSwitching", true, "Effect When Switching", "If true, when switching to random avatar there will be an effect with the Pull Cord Device like when going into an area in a level that changes your avatar", false, false, (ValueValidator)null, (string)null);
			Entry_AllowRandomAvatarInYourLobbies = Preferences_Category.CreateEntry<bool>("AllowRandomAvatarInYourLobbies", true, "Allow Random Avatar In Your Lobbies", "If true, random avatar will work for players when you create your lobby/server, if false they won't be able to use it on versions after 1.1.0", false, false, (ValueValidator)null, (string)null);
			Entry_MinimumFusionDelay = Preferences_Category.CreateEntry<int>("MinimumFusionDelay", 60, "Minimum Fusion Delay", "The minimum delay value (in seconds) for all players using RandomAvatar on versions after 1.1.0", false, false, (ValueValidator)null, (string)null);
			Preferences_Category.SetFilePath(Path.Combine(MelonEnvironment.UserDataDirectory, "RandomAvatar.cfg"));
			Preferences_Category.SaveToFile(false);
			if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
			{
				((MelonBase)this).LoggerInstance.Msg("Setting up Fusion");
				PatchFusion();
				Fusion.Setup();
			}
			((MelonBase)this).LoggerInstance.Msg("Setting up blacklist/whitelist");
			BlacklistWhitelist.Setup();
			((MelonBase)this).LoggerInstance.Msg("Creating BoneMenu");
			BoneMenu.Setup();
			((MelonBase)this).LoggerInstance.Msg("Adding hooks");
			Hooking.OnLevelLoaded += delegate(LevelInfo info)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				LevelInfo = info;
				if (!Fusion.IsConnected())
				{
					LevelLoaded();
				}
			};
			((MelonBase)this).LoggerInstance.Msg("Initialized.");
		}

		internal static void LevelLoaded()
		{
			if ((SwapOnLevelChange || SwapOnNextLevelChange) && !((Object)(object)PlayerRefs.Instance == (Object)null))
			{
				SwapOnNextLevelChange = false;
				if (PlayerRefs.Instance.HasRefs)
				{
					SwapToRandom();
					return;
				}
				PlayerRefs instance = PlayerRefs.Instance;
				instance.OnRefsComplete += Action.op_Implicit((Action)SwapToRandom);
			}
		}

		public override void OnFixedUpdate()
		{
			TimeUtilities.OnEarlyFixedUpdate();
		}

		public override void OnUpdate()
		{
			TimeUtilities.OnEarlyUpdate();
			BoneMenu.Update();
		}
	}
}
namespace RandomAvatar.Utilities
{
	public static class Fusion
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ServerEvent <>9__12_0;

			public static ServerEvent <>9__12_1;

			public static ServerEvent <>9__12_2;

			internal void <Internal_Setup>b__12_0()
			{
				ServerChanged?.Invoke();
			}

			internal void <Internal_Setup>b__12_1()
			{
				ServerChanged?.Invoke();
			}

			internal void <Internal_Setup>b__12_2()
			{
				ServerChanged?.Invoke();
			}
		}

		internal const string Allow_MetadataKey = "RandomAvatar.Allow";

		internal const string Delay_MetadataKey = "RandomAvatar.Delay";

		internal const int FusionDelay = 60;

		internal const int DefaultDelay = 10;

		internal static Action ServerChanged;

		internal static void Internal_SendPullCordEffect()
		{
			PullCordSender.SendBodyLogEffect();
		}

		public static void SendPullCordEffect()
		{
			if (IsConnected())
			{
				Internal_SendPullCordEffect();
			}
		}

		internal static bool Internal_IsConnected()
		{
			return NetworkInfo.HasServer;
		}

		internal static bool Internal_IsMine(Component comp)
		{
			if (ComponentExtensions.IsPartOfSelf(comp))
			{
				return ComponentExtensions.IsPartOfPlayer(comp);
			}
			return false;
		}

		internal static bool IsMine(Component comp)
		{
			if (IsConnected())
			{
				return Internal_IsMine(comp);
			}
			return true;
		}

		internal static void Internal_UpdateMetadata()
		{
			if (Core.Entry_AllowRandomAvatarInYourLobbies != null && NetworkInfo.IsServer && LocalPlayer.Metadata != null)
			{
				LocalPlayer.Metadata.TrySetMetadata("RandomAvatar.Allow", Core.Entry_AllowRandomAvatarInYourLobbies.Value.ToString());
				LocalPlayer.Metadata.TrySetMetadata("RandomAvatar.Delay", Core.Entry_MinimumFusionDelay.Value.ToString());
			}
		}

		internal static void UpdateMetadata()
		{
			if (IsConnected())
			{
				Internal_UpdateMetadata();
			}
		}

		internal static void Internal_Setup()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//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_0067: Expected O, but got Unknown
			object obj = <>c.<>9__12_0;
			if (obj == null)
			{
				ServerEvent val = delegate
				{
					ServerChanged?.Invoke();
				};
				<>c.<>9__12_0 = val;
				obj = (object)val;
			}
			MultiplayerHooking.OnJoinServer += (ServerEvent)obj;
			object obj2 = <>c.<>9__12_1;
			if (obj2 == null)
			{
				ServerEvent val2 = delegate
				{
					ServerChanged?.Invoke();
				};
				<>c.<>9__12_1 = val2;
				obj2 = (object)val2;
			}
			MultiplayerHooking.OnStartServer += (ServerEvent)obj2;
			object obj3 = <>c.<>9__12_2;
			if (obj3 == null)
			{
				ServerEvent val3 = delegate
				{
					ServerChanged?.Invoke();
				};
				<>c.<>9__12_2 = val3;
				obj3 = (object)val3;
			}
			MultiplayerHooking.OnDisconnect += (ServerEvent)obj3;
		}

		internal static int Internal_GetMinimumDelay()
		{
			if (Core.Entry_MinimumFusionDelay == null)
			{
				return 10;
			}
			if (!NetworkInfo.HasServer)
			{
				return 10;
			}
			NetworkPlayer val = default(NetworkPlayer);
			if (!NetworkPlayerManager.TryGetPlayer((byte)0, ref val))
			{
				return 10;
			}
			NetworkMetadata metadata = val.PlayerId.Metadata;
			if (metadata != null)
			{
				string s = default(string);
				metadata.TryGetMetadata("RandomAvatar.Delay", ref s);
				if (0 == 0)
				{
					if (!int.TryParse(s, out var result))
					{
						return 60;
					}
					return result;
				}
			}
			return 60;
		}

		internal static int GetMinimumDelay()
		{
			if (!IsConnected())
			{
				return 10;
			}
			return Internal_GetMinimumDelay();
		}

		internal static void Setup()
		{
			if (IsConnected())
			{
				Internal_Setup();
			}
		}

		internal static bool Internal_IsAllowed()
		{
			NetworkPlayer val = default(NetworkPlayer);
			if (!NetworkPlayerManager.TryGetPlayer((byte)0, ref val))
			{
				return true;
			}
			NetworkMetadata metadata = val.PlayerId.Metadata;
			if (metadata != null)
			{
				string value = default(string);
				metadata.TryGetMetadata("RandomAvatar.Allow", ref value);
				if (0 == 0)
				{
					if (!bool.TryParse(value, out var result))
					{
						return true;
					}
					return result;
				}
			}
			return true;
		}

		public static bool IsAllowed()
		{
			if (!IsConnected())
			{
				return true;
			}
			return Internal_IsAllowed();
		}

		internal static void Internal_EnsureSync()
		{
			if (NetworkInfo.IsServer)
			{
				if (IsAllowed() != Core.Entry_AllowRandomAvatarInYourLobbies.Value)
				{
					UpdateMetadata();
				}
				else if (GetMinimumDelay() != Core.Entry_MinimumFusionDelay.Value)
				{
					UpdateMetadata();
				}
			}
		}

		public static void EnsureSync()
		{
			if (IsConnected())
			{
				Internal_EnsureSync();
			}
		}

		public static bool IsConnected()
		{
			if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
			{
				return Internal_IsConnected();
			}
			return false;
		}
	}
	public class Thunderstore
	{
		public readonly string UserAgent;

		public bool IsV1Deprecated;

		public Thunderstore(string userAgent)
		{
			UserAgent = userAgent;
		}

		public Thunderstore(string userAgent, bool isV1Deprecated)
			: this(userAgent)
		{
			IsV1Deprecated = isV1Deprecated;
		}

		public Thunderstore()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			if (executingAssembly != null)
			{
				AssemblyName name = executingAssembly.GetName();
				if (name != null)
				{
					UserAgent = $"{name.Name} / {name.Version} C# Application";
				}
			}
		}

		public Thunderstore(bool isV1Deprecated)
		{
			IsV1Deprecated = isV1Deprecated;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			if (executingAssembly != null)
			{
				AssemblyName name = executingAssembly.GetName();
				if (name != null)
				{
					UserAgent = $"{name.Name} / {name.Version}";
				}
			}
		}

		public Package GetPackage(string @namespace, string name)
		{
			Task<HttpResponseMessage> async = new HttpClient
			{
				DefaultRequestHeaders = 
				{
					{ "User-Agent", UserAgent },
					{ "Accept", "application/json" }
				}
			}.GetAsync($"https://thunderstore.io/api/experimental/package/{@namespace}/{name}/");
			async.Wait();
			HttpResponseMessage httpResponseMessage = async?.Result;
			if (async != null && httpResponseMessage != null && async.IsCompletedSuccessfully)
			{
				if (httpResponseMessage.IsSuccessStatusCode)
				{
					Task<string> task = httpResponseMessage.Content.ReadAsStringAsync();
					task.Wait();
					string text = task?.Result;
					if (task != null && text != null && task.IsCompletedSuccessfully)
					{
						Package package = JsonSerializer.Deserialize<Package>(text);
						if (!IsV1Deprecated && package != null)
						{
							V1PackageMetrics packageMetrics = GetPackageMetrics(@namespace, name);
							if (packageMetrics != null)
							{
								package.TotalDownloads = packageMetrics.Downloads;
								package.RatingScore = packageMetrics.RatingScore;
							}
						}
						return package;
					}
				}
				else
				{
					if (IsThunderstoreError(httpResponseMessage))
					{
						if (IsPackageNotFound(httpResponseMessage))
						{
							throw new ThunderstorePackageNotFoundException($"Thunderstore could not find a package with name '{name}' & namespace '{@namespace}'", @namespace, name, httpResponseMessage);
						}
						throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", httpResponseMessage);
					}
					httpResponseMessage.EnsureSuccessStatusCode();
				}
			}
			return null;
		}

		public V1PackageMetrics GetPackageMetrics(string @namespace, string name)
		{
			if (IsV1Deprecated)
			{
				return null;
			}
			Task<HttpResponseMessage> async = new HttpClient
			{
				DefaultRequestHeaders = 
				{
					{ "User-Agent", UserAgent },
					{ "Accept", "application/json" }
				}
			}.GetAsync($"https://thunderstore.io/api/v1/package-metrics/{@namespace}/{name}/");
			async.Wait();
			HttpResponseMessage httpResponseMessage = async?.Result;
			if (async != null && httpResponseMessage != null && async.IsCompletedSuccessfully)
			{
				if (httpResponseMessage.IsSuccessStatusCode)
				{
					Task<string> task = httpResponseMessage.Content.ReadAsStringAsync();
					task.Wait();
					string text = task?.Result;
					if (task != null && text != null && task.IsCompletedSuccessfully)
					{
						return JsonSerializer.Deserialize<V1PackageMetrics>(text);
					}
				}
				else
				{
					if (IsThunderstoreError(httpResponseMessage))
					{
						if (IsPackageNotFound(httpResponseMessage))
						{
							throw new ThunderstorePackageNotFoundException($"Thunderstore could not find a package with name '{name}' & namespace '{@namespace}'", @namespace, name, httpResponseMessage);
						}
						throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", httpResponseMessage);
					}
					httpResponseMessage.EnsureSuccessStatusCode();
				}
			}
			return null;
		}

		public PackageVersion GetPackage(string @namespace, string name, string version)
		{
			Task<HttpResponseMessage> async = new HttpClient
			{
				DefaultRequestHeaders = 
				{
					{ "User-Agent", UserAgent },
					{ "Accept", "application/json" }
				}
			}.GetAsync($"https://thunderstore.io/api/experimental/package/{@namespace}/{name}/{version}");
			async.Wait();
			HttpResponseMessage httpResponseMessage = async?.Result;
			if (async != null && httpResponseMessage != null && async.IsCompletedSuccessfully)
			{
				if (httpResponseMessage.IsSuccessStatusCode)
				{
					Task<string> task = httpResponseMessage.Content.ReadAsStringAsync();
					task.Wait();
					string text = task?.Result;
					if (task != null && text != null && task.IsCompletedSuccessfully)
					{
						return JsonSerializer.Deserialize<PackageVersion>(text);
					}
				}
				else
				{
					if (IsThunderstoreError(httpResponseMessage))
					{
						if (IsPackageNotFound(httpResponseMessage))
						{
							throw new ThunderstorePackageNotFoundException($"Thunderstore could not find a package with name '{name}', namespace '{@namespace}' & version '{version}'", @namespace, name, version, httpResponseMessage);
						}
						throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", httpResponseMessage);
					}
					httpResponseMessage.EnsureSuccessStatusCode();
				}
			}
			return null;
		}

		public bool IsLatestVersion(string @namespace, string name, string currentVersion)
		{
			SemVersion currentVersion2 = default(SemVersion);
			if (SemVersion.TryParse(currentVersion, ref currentVersion2, false))
			{
				return IsLatestVersion(@namespace, name, currentVersion2);
			}
			return false;
		}

		public bool IsLatestVersion(string @namespace, string name, Version currentVersion)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			return IsLatestVersion(@namespace, name, new SemVersion(currentVersion));
		}

		public bool IsLatestVersion(string @namespace, string name, SemVersion currentVersion)
		{
			if (!IsV1Deprecated)
			{
				return GetPackageMetrics(@namespace, name)?.IsLatestVersion(currentVersion) ?? false;
			}
			return GetPackage(@namespace, name)?.IsLatestVersion(currentVersion) ?? false;
		}

		private static bool IsPackageNotFound(HttpResponseMessage response)
		{
			if (response.StatusCode != HttpStatusCode.NotFound)
			{
				return false;
			}
			Task<string> task = response.Content.ReadAsStringAsync();
			task.Wait();
			string result = task.Result;
			if (string.IsNullOrWhiteSpace(result))
			{
				return false;
			}
			ThunderstoreErrorResponse thunderstoreErrorResponse;
			try
			{
				thunderstoreErrorResponse = JsonSerializer.Deserialize<ThunderstoreErrorResponse>(result);
			}
			catch (JsonException)
			{
				return false;
			}
			if (thunderstoreErrorResponse != null)
			{
				return string.Equals(thunderstoreErrorResponse.Details, "Not found.", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static bool IsThunderstoreError(HttpResponseMessage response)
		{
			if (response.IsSuccessStatusCode)
			{
				return false;
			}
			Task<string> task = response.Content.ReadAsStringAsync();
			task.Wait();
			string result = task.Result;
			if (string.IsNullOrWhiteSpace(result))
			{
				return false;
			}
			ThunderstoreErrorResponse thunderstoreErrorResponse;
			try
			{
				thunderstoreErrorResponse = JsonSerializer.Deserialize<ThunderstoreErrorResponse>(result);
			}
			catch (JsonException)
			{
				return false;
			}
			if (thunderstoreErrorResponse != null)
			{
				return !string.IsNullOrWhiteSpace(thunderstoreErrorResponse.Details);
			}
			return false;
		}
	}
	public class Package
	{
		[JsonPropertyName("namespace")]
		[JsonInclude]
		public string Namespace { get; internal set; }

		[JsonPropertyName("name")]
		[JsonInclude]
		public string Name { get; internal set; }

		[JsonPropertyName("full_name")]
		[JsonInclude]
		public string FullName { get; internal set; }

		[JsonPropertyName("owner")]
		[JsonInclude]
		public string Owner { get; internal set; }

		[JsonPropertyName("package_url")]
		[JsonInclude]
		public string PackageUrl { get; internal set; }

		[JsonPropertyName("date_created")]
		[JsonInclude]
		public DateTime CreatedAt { get; internal set; }

		[JsonPropertyName("date_updated")]
		[JsonInclude]
		public DateTime UpdatedAt { get; internal set; }

		[JsonPropertyName("rating_score")]
		[JsonInclude]
		public int RatingScore { get; internal set; }

		[JsonPropertyName("is_pinned")]
		[JsonInclude]
		public bool IsPinned { get; internal set; }

		[JsonPropertyName("is_deprecated")]
		[JsonInclude]
		public bool IsDeprecated { get; internal set; }

		[JsonPropertyName("total_downloads")]
		[JsonInclude]
		public int TotalDownloads { get; internal set; }

		[JsonPropertyName("latest")]
		[JsonInclude]
		public PackageVersion Latest { get; internal set; }

		[JsonPropertyName("community_listings")]
		[JsonInclude]
		public PackageListing[] CommunityListings { get; internal set; }

		public bool IsLatestVersion(string current)
		{
			if (string.IsNullOrWhiteSpace(current))
			{
				return false;
			}
			if (Latest == null || Latest.SemVersion == (SemVersion)null)
			{
				return false;
			}
			SemVersion val = default(SemVersion);
			if (SemVersion.TryParse(current, ref val, false))
			{
				return val >= Latest.SemVersion;
			}
			return false;
		}

		public bool IsLatestVersion(SemVersion current)
		{
			if (current == (SemVersion)null)
			{
				return false;
			}
			if (Latest == null || Latest.SemVersion == (SemVersion)null)
			{
				return false;
			}
			return current >= Latest.SemVersion;
		}

		public bool IsLatestVersion(Version current)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (current == null)
			{
				return false;
			}
			if (Latest == null || Latest.SemVersion == (SemVersion)null)
			{
				return false;
			}
			return new SemVersion(current) >= Latest.SemVersion;
		}
	}
	public class PackageVersion
	{
		[JsonPropertyName("namespace")]
		[JsonInclude]
		public string Namespace { get; internal set; }

		[JsonPropertyName("name")]
		[JsonInclude]
		public string Name { get; internal set; }

		[JsonPropertyName("version_number")]
		[JsonInclude]
		public string Version
		{
			get
			{
				return ((object)SemVersion).ToString();
			}
			internal set
			{
				SemVersion = SemVersion.Parse(value, false);
			}
		}

		[JsonIgnore]
		public SemVersion SemVersion { get; internal set; }

		[JsonPropertyName("full_name")]
		[JsonInclude]
		public string FullName { get; internal set; }

		[JsonPropertyName("description")]
		[JsonInclude]
		public string Description { get; internal set; }

		[JsonPropertyName("icon")]
		[JsonInclude]
		public string Icon { get; internal set; }

		[JsonPropertyName("dependencies")]
		[JsonInclude]
		public List<string> Dependencies { get; internal set; }

		[JsonPropertyName("download_url")]
		[JsonInclude]
		public string DownloadUrl { get; internal set; }

		[JsonPropertyName("date_created")]
		[JsonInclude]
		public DateTime CreatedAt { get; internal set; }

		[JsonPropertyName("downloads")]
		[JsonInclude]
		public int Downloads { get; internal set; }

		[JsonPropertyName("website_url")]
		[JsonInclude]
		public string WebsiteURL { get; internal set; }

		[JsonPropertyName("is_active")]
		[JsonInclude]
		public bool IsActive { get; internal set; }
	}
	public class PackageListing
	{
		public enum ReviewStatusEnum
		{
			UNREVIEWED,
			APPROVED,
			REJECTED
		}

		[JsonPropertyName("has_nsfw_content")]
		[JsonInclude]
		public bool HasNSFWContent { get; internal set; }

		[JsonPropertyName("categories")]
		[JsonInclude]
		public List<string> Categories { get; internal set; }

		[JsonPropertyName("community")]
		[JsonInclude]
		public string Community { get; internal set; }

		[JsonPropertyName("review_status")]
		[JsonInclude]
		public string ReviewStatusString
		{
			get
			{
				return ReviewStatus.ToString();
			}
			internal set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (string.Equals(value, "unreviewed", StringComparison.OrdinalIgnoreCase))
				{
					ReviewStatus = ReviewStatusEnum.UNREVIEWED;
				}
				else if (string.Equals(value, "approved", StringComparison.OrdinalIgnoreCase))
				{
					ReviewStatus = ReviewStatusEnum.APPROVED;
				}
				else if (string.Equals(value, "rejected", StringComparison.OrdinalIgnoreCase))
				{
					ReviewStatus = ReviewStatusEnum.REJECTED;
				}
			}
		}

		[JsonIgnore]
		public ReviewStatusEnum ReviewStatus { get; internal set; }
	}
	public class V1PackageMetrics
	{
		[JsonPropertyName("downloads")]
		[JsonInclude]
		public int Downloads { get; internal set; }

		[JsonPropertyName("rating_score")]
		[JsonInclude]
		public int RatingScore { get; internal set; }

		[JsonPropertyName("latest_version")]
		[JsonInclude]
		public string LatestVersion
		{
			get
			{
				return ((object)LatestSemVersion).ToString();
			}
			internal set
			{
				LatestSemVersion = SemVersion.Parse(value, false);
			}
		}

		[JsonIgnore]
		public SemVersion LatestSemVersion { get; internal set; }

		public bool IsLatestVersion(string current)
		{
			if (string.IsNullOrWhiteSpace(current))
			{
				return false;
			}
			if (LatestSemVersion == (SemVersion)null)
			{
				return false;
			}
			SemVersion val = default(SemVersion);
			if (SemVersion.TryParse(current, ref val, false))
			{
				return val >= LatestSemVersion;
			}
			return false;
		}

		public bool IsLatestVersion(SemVersion current)
		{
			if (current == (SemVersion)null)
			{
				return false;
			}
			if (LatestSemVersion == (SemVersion)null)
			{
				return false;
			}
			return current >= LatestSemVersion;
		}

		public bool IsLatestVersion(Version current)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (current == null)
			{
				return false;
			}
			if (LatestSemVersion == (SemVersion)null)
			{
				return false;
			}
			return new SemVersion(current) >= LatestSemVersion;
		}
	}
	public class ThunderstoreErrorResponse
	{
		[JsonPropertyName("detail")]
		[JsonInclude]
		public string Details { get; internal set; }
	}
	public class ThunderstoreErrorException : Exception
	{
		public string Details { get; }

		public HttpStatusCode HttpStatusCode { get; }

		public ThunderstoreErrorException()
		{
		}

		public ThunderstoreErrorException(string message)
			: base(message)
		{
		}

		public ThunderstoreErrorException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public ThunderstoreErrorException(string message, string details, HttpStatusCode httpStatusCode, Exception innerException)
			: base(message, innerException)
		{
			Details = details;
			HttpStatusCode = httpStatusCode;
		}

		public ThunderstoreErrorException(string message, HttpResponseMessage response)
			: base(message)
		{
			if (response.IsSuccessStatusCode)
			{
				return;
			}
			HttpStatusCode = response.StatusCode;
			Task<string> task = response.Content.ReadAsStringAsync();
			task.Wait();
			string result = task.Result;
			if (string.IsNullOrWhiteSpace(result))
			{
				Details = string.Empty;
				return;
			}
			ThunderstoreErrorResponse thunderstoreErrorResponse;
			try
			{
				thunderstoreErrorResponse = JsonSerializer.Deserialize<ThunderstoreErrorResponse>(result);
			}
			catch (JsonException)
			{
				Details = string.Empty;
				return;
			}
			if (thunderstoreErrorResponse != null)
			{
				Details = thunderstoreErrorResponse.Details;
			}
		}
	}
	public class ThunderstorePackageNotFoundException : ThunderstoreErrorException
	{
		public string Namespace { get; }

		public string Name { get; }

		public string Version { get; }

		public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string details, HttpStatusCode httpStatusCode, Exception innerException)
			: base(message, details, httpStatusCode, innerException)
		{
			Namespace = @namespace;
			Name = name;
		}

		public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string version, string details, HttpStatusCode httpStatusCode, Exception innerException)
			: base(message, details, httpStatusCode, innerException)
		{
			Namespace = @namespace;
			Name = name;
			Version = version;
		}

		public ThunderstorePackageNotFoundException(string message, string @namespace, string name, HttpResponseMessage response)
			: base(message, response)
		{
			Namespace = @namespace;
			Name = name;
		}

		public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string version, HttpResponseMessage response)
			: base(message, response)
		{
			Namespace = @namespace;
			Name = name;
			Version = version;
		}

		public ThunderstorePackageNotFoundException()
		{
		}

		public ThunderstorePackageNotFoundException(string message)
			: base(message)
		{
		}

		public ThunderstorePackageNotFoundException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public ThunderstorePackageNotFoundException(string message, string details, HttpStatusCode httpStatusCode, Exception innerException)
			: base(message, details, httpStatusCode, innerException)
		{
		}

		public ThunderstorePackageNotFoundException(string message, HttpResponseMessage response)
			: base(message, response)
		{
		}
	}
	internal static class TimeUtilities
	{
		private static float _deltaTime = 1f;

		private static float _fixedDeltaTime = 0.02f;

		private static float _timeSinceStartup = 0f;

		private static float _timeScale = 1f;

		private static int _frameCount = 0;

		public static float DeltaTime => _deltaTime;

		public static float FixedDeltaTime => _fixedDeltaTime;

		public static float TimeSinceStartup => _timeSinceStartup;

		public static float TimeScale => _timeScale;

		public static int FrameCount => _frameCount;

		internal static void OnEarlyUpdate()
		{
			_timeScale = Time.timeScale;
			_deltaTime = Time.deltaTime;
			_timeSinceStartup += _deltaTime;
			_frameCount++;
		}

		internal static void OnEarlyFixedUpdate()
		{
			_fixedDeltaTime = Time.fixedDeltaTime;
		}

		public static bool IsMatchingFrame(int interval)
		{
			return FrameCount % interval == 0;
		}

		public static bool IsMatchingFrame(int interval, int offset)
		{
			return (FrameCount + offset) % interval == 0;
		}
	}
}
namespace RandomAvatar.Patches
{
	public static class FusionPatches
	{
		public static void Postfix()
		{
			if (Fusion.IsConnected())
			{
				Core.LevelLoaded();
			}
		}
	}
	public static class LocalRagdollPatches
	{
		public static void Postfix()
		{
			if (RigData.HasPlayer && Core.SwapOnDeath)
			{
				Core.SwapToRandom();
			}
		}
	}
	[HarmonyPatch]
	public static class ModConsolePatches
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.FirstMethod(AccessTools.TypeByName("BoneLib.ModConsole"), (Func<MethodInfo, bool>)delegate(MethodInfo x)
			{
				List<ParameterInfo> list = x.GetParameters().ToList();
				if (list.Count != 2)
				{
					return false;
				}
				return list[0].Name == "txt" && list[1].Name == "loggingMode";
			});
		}

		public static bool Prefix(string txt)
		{
			return txt != "Remove Element";
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	public static class PlayerHealthPatches
	{
		[HarmonyPatch("Death")]
		public static void Postfix(Player_Health __instance)
		{
			if (Fusion.IsMine((Component)(object)__instance) && Core.SwapOnDeath)
			{
				PlayerHealthDecorator val = default(PlayerHealthDecorator);
				if (Core.Entry_EffectWhenSwitching.Value && (Object)(object)PlayerMarkerPatches.Instance != (Object)null && (!((Component)PlayerMarkerPatches.Instance).TryGetComponent<PlayerHealthDecorator>(ref val) || !val._reloadLevelOnDeath))
				{
					Core.SwapOnNextLevelChange = true;
				}
				Core.SwapToRandom();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMarker))]
	public static class PlayerMarkerPatches
	{
		public static PlayerMarker Instance { get; private set; }

		[HarmonyPatch("Awake")]
		public static void Postfix(PlayerMarker __instance)
		{
			Instance = __instance;
		}
	}
}
namespace RandomAvatar.Menu
{
	public static class BoneMenu
	{
		private static float elapsed = 0f;

		private static IntElement DelayElement;

		internal const int _rmd = 10;

		internal static bool IsSetup = false;

		internal static Action EverySecond;

		internal static int Cooldown = 0;

		internal static FunctionElement IsAllowedLabel;

		internal static FunctionElement FusionDelayLabel;

		internal static KeyValuePair<string, string> SelectedAvatarHistory;

		private static float _generalElapsed;

		private static float _lastDelay;

		private static int _lastMinimumDelay;

		public static Page AuthorPage { get; private set; }

		public static Page ModPage { get; private set; }

		public static Page SettingsPage { get; private set; }

		public static Page RepeatingPage { get; private set; }

		public static Page ChallengesPage { get; private set; }

		public static Page FusionPage { get; private set; }

		public static Page HistoryPage { get; private set; }

		public static Page AvatarHistoryPage { get; private set; }

		public static Page AvatarHistoryTagsPage { get; private set; }

		public static Page BlacklistWhitelistPage { get; private set; }

		internal static FunctionElement RemainingLabel { get; private set; }

		public static int Delay { get; private set; } = 30;


		public static int Remaining { get; private set; } = 0;


		public static bool SwitchEvery { get; private set; } = false;


		public static bool SwapOnStart { get; private set; } = true;


		public static int MinimumDelay => Fusion.GetMinimumDelay();

		private static int RepeatingMinimumDelay
		{
			get
			{
				int num = Fusion.GetMinimumDelay();
				if (num < 10)
				{
					num = 10;
				}
				return num;
			}
		}

		internal static FunctionElement CooldownLabel { get; private set; }

		internal static void AssetWarehouseReady()
		{
			BlacklistWhitelist.SetupPage();
			Hooking.OnWarehouseReady -= AssetWarehouseReady;
		}

		internal static void Setup()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			if (IsSetup)
			{
				return;
			}
			IsSetup = true;
			AuthorPage = Page.Root.CreatePage("HAHOOS", Color.white, 0, true);
			ModPage = AuthorPage.CreatePage("RandomAvatar", Color.magenta, 0, true);
			SettingsPage = ModPage.CreatePage("Settings", Color.cyan, 4, true);
			SettingsPage.CreateBoolPref("Use Redacted Avatars", Color.cyan, ref Core.Entry_UseRedacted);
			SettingsPage.CreateBoolPref("Add effect when switching avatar", Color.magenta, ref Core.Entry_EffectWhenSwitching);
			BlacklistWhitelistPage = ModPage.CreatePage("Blacklist/Whitelist", Color.magenta, 10, true);
			BlacklistWhitelist.Page = BlacklistWhitelistPage;
			if (!AssetWarehouse.ready)
			{
				Hooking.OnWarehouseReady += AssetWarehouseReady;
			}
			else
			{
				BlacklistWhitelist.SetupPage();
			}
			_lastMinimumDelay = MinimumDelay;
			HistoryPage = ModPage.CreatePage("History", Color.yellow, 10, true);
			AvatarHistoryPage = HistoryPage.CreatePage("Placeholder", Color.white, 0, false);
			AvatarHistoryTagsPage = HistoryPage.CreatePage("Tags", Color.red, 0, false);
			SetupHistoryPage();
			RepeatingPage = ModPage.CreatePage("Repeating", Color.red, 4, true);
			UpdateRepeating();
			ChallengesPage = ModPage.CreatePage("Challenges", Color.yellow, 2, true);
			ChallengesPage.CreateBool("Switch to random avatar on death", Color.cyan, false, (Action<bool>)delegate(bool v)
			{
				Core.SwapOnDeath = v;
			});
			ChallengesPage.CreateBool("Switch to random avatar on level change", Color.yellow, false, (Action<bool>)delegate(bool v)
			{
				Core.SwapOnLevelChange = v;
			});
			if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
			{
				FusionPage = ModPage.CreatePage("Fusion", Color.cyan, 0, true);
				SetupFusionPage();
				Fusion.ServerChanged = (Action)Delegate.Combine(Fusion.ServerChanged, (Action)delegate
				{
					SetupFusionPage();
					Cooldown = 0;
				});
				EverySecond = (Action)Delegate.Combine(EverySecond, new Action(UpdateLabels));
				EverySecond = (Action)Delegate.Combine(EverySecond, new Action(Fusion.EnsureSync));
			}
			EverySecond = (Action)Delegate.Combine(EverySecond, new Action(CheckDelay));
			ModPage.CreateFunction("Switch to random avatar", Color.white, (Action)Core.SwapToRandom);
			if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
			{
				CooldownLabel = ModPage.CreateLabel(((Cooldown > 0) ? $"Cooldown: {Cooldown}" : "Ready to use") ?? "", Color.white);
			}
			EverySecond = (Action)Delegate.Combine(EverySecond, (Action)delegate
			{
				if (CooldownLabel != null)
				{
					if (Fusion.IsConnected() && Cooldown > 0)
					{
						Cooldown--;
					}
					else if (!Fusion.IsConnected())
					{
						Cooldown = 0;
					}
					if (Fusion.IsConnected())
					{
						((Element)CooldownLabel).ElementName = ((Cooldown > 0) ? $"Cooldown: {Cooldown}" : "Ready to use") ?? "";
					}
					else
					{
						((Element)CooldownLabel).ElementName = string.Empty;
					}
				}
			});
			ModPage.CreateLabel("Version: v1.2.0" + (Core.IsLatestVersion ? string.Empty : "<br><color=#2EFF2E>(Update Available)</color>"), Color.white);
		}

		internal static void SetupTagsPage(AvatarCrate crate)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			BlacklistWhitelist.refreshRequired = true;
			BlacklistWhitelist.SetupTagsPage();
			BlacklistWhitelist.CleanupPage(AvatarHistoryTagsPage);
			if (((Crate)crate).Tags.Count <= 0)
			{
				AvatarHistoryTagsPage.CreateLabel("Nothing to show here :(", Color.white);
				return;
			}
			((Crate)crate).Tags.ForEach(Action<string>.op_Implicit((Action<string>)delegate(string x)
			{
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				if (!string.IsNullOrWhiteSpace(x))
				{
					int value = (BlacklistWhitelist.Tags.ContainsKey(x) ? BlacklistWhitelist.Tags[x] : 0);
					FunctionElement element = null;
					element = AvatarHistoryTagsPage.CreateFunction($"{x} [{value}]", (Color)(BlacklistWhitelist.TagsList.Value.Contains(x) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
					{
						//IL_0069: Unknown result type (might be due to invalid IL or missing references)
						//IL_0033: Unknown result type (might be due to invalid IL or missing references)
						if (BlacklistWhitelist.TagsList.Value.Contains(x))
						{
							BlacklistWhitelist.TagsList.Value.Remove(x);
							((Element)element).ElementColor = Color.red;
						}
						else
						{
							BlacklistWhitelist.TagsList.Value.Add(x);
							((Element)element).ElementColor = new Color(0f, 1f, 0f);
						}
						BlacklistWhitelist.Category.SaveToFile(false);
					});
				}
			}));
		}

		internal static void SetupPageForAvatar(DateTimeOffset offset, AvatarCrate crate)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			AvatarHistoryPage.Name = ((Scannable)crate).Title;
			AvatarHistoryPage.RemoveAll();
			AvatarHistoryPage.CreateFunction(((Scannable)crate).Title, Color.white, (Action)null);
			AvatarHistoryPage.CreateFunction(((Scannable)crate).Barcode.ID, Color.white, (Action)null);
			FunctionElement palletElement = null;
			palletElement = AvatarHistoryPage.CreateFunction(((Scannable)((Crate)crate).Pallet).Title, (Color)(BlacklistWhitelist.PalletList.Value.Contains(((Scannable)((Crate)crate).Pallet).Barcode.ID) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
			{
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				if (BlacklistWhitelist.PalletList.Value.Contains(((Scannable)((Crate)crate).Pallet).Barcode.ID))
				{
					BlacklistWhitelist.PalletList.Value.Remove(((Scannable)((Crate)crate).Pallet).Barcode.ID);
					((Element)palletElement).ElementColor = Color.red;
				}
				else
				{
					BlacklistWhitelist.PalletList.Value.Add(((Scannable)((Crate)crate).Pallet).Barcode.ID);
					((Element)palletElement).ElementColor = new Color(0f, 1f, 0f);
				}
				BlacklistWhitelist.Category.SaveToFile(false);
			});
			AvatarHistoryPage.CreateFunction($"Tags ({((Crate)crate).Tags.Count})", Color.red, (Action)delegate
			{
				SetupTagsPage(crate);
				Menu.OpenPage(AvatarHistoryTagsPage);
			});
			AvatarHistoryPage.CreateFunction("Time: " + offset.ToString("T"), Color.white, (Action)null);
			FunctionElement element = null;
			element = AvatarHistoryPage.CreateFunction((!BlacklistWhitelist.AvatarList.Value.Contains(((Scannable)crate).Barcode.ID)) ? (BlacklistWhitelist.IsWhitelist.Value ? "Not Whitelisted" : "Not Blacklisted") : (BlacklistWhitelist.IsWhitelist.Value ? "Whitelisted" : "Blacklisted"), (Color)(BlacklistWhitelist.AvatarList.Value.Contains(((Scannable)crate).Barcode.ID) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
			{
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				if (BlacklistWhitelist.AvatarList.Value.Contains(((Scannable)crate).Barcode.ID))
				{
					BlacklistWhitelist.AvatarList.Value.Remove(((Scannable)crate).Barcode.ID);
					((Element)element).ElementName = (BlacklistWhitelist.IsWhitelist.Value ? "Not Whitelisted" : "Not Blacklisted");
					((Element)element).ElementColor = Color.red;
				}
				else
				{
					BlacklistWhitelist.AvatarList.Value.Add(((Scannable)crate).Barcode.ID);
					((Element)element).ElementName = (BlacklistWhitelist.IsWhitelist.Value ? "Whitelisted" : "Blacklisted");
					((Element)element).ElementColor = new Color(0f, 1f, 0f);
				}
				BlacklistWhitelist.Category.SaveToFile(false);
			});
		}

		internal static void SetupHistoryPage()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (HistoryPage == null)
			{
				return;
			}
			BlacklistWhitelist.CleanupPage(HistoryPage);
			((Element)HistoryPage.CreateFunction("Clear all", Color.red, (Action)delegate
			{
				Core._avatarHistory.Clear();
				SetupHistoryPage();
			})).SetProperty((ElementProperties)1);
			HistoryPage.CreateBlank();
			if (Core._avatarHistory.Count <= 0)
			{
				HistoryPage.CreateLabel("Nothing to show here :(", Color.white);
				return;
			}
			Core._avatarHistory = Core._avatarHistory.OrderByDescending((KeyValuePair<DateTimeOffset, AvatarCrate> x) => x.Key.ToUnixTimeMilliseconds()).ToDictionary((KeyValuePair<DateTimeOffset, AvatarCrate> x) => x.Key, (KeyValuePair<DateTimeOffset, AvatarCrate> x) => x.Value);
			Core._avatarHistory.ForEach(delegate(KeyValuePair<DateTimeOffset, AvatarCrate> y)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				AvatarCrate x2 = y.Value;
				((Element)HistoryPage.CreateFunction(((Scannable)x2).Title, Color.yellow, (Action)delegate
				{
					SetupPageForAvatar(y.Key, x2);
					Menu.OpenPage(AvatarHistoryPage);
				})).SetProperty((ElementProperties)1);
			});
		}

		internal static void UpdateRepeating()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			if (RepeatingPage == null)
			{
				return;
			}
			RepeatingPage.RemoveAll();
			DelayElement = RepeatingPage.CreateInt("Change Delay", Color.yellow, Delay, 10, RepeatingMinimumDelay, 3600, (Action<int>)delegate(int v)
			{
				Delay = v;
			});
			RepeatingPage.CreateBool("Swap on start", Color.red, SwapOnStart, (Action<bool>)delegate(bool v)
			{
				SwapOnStart = v;
			});
			ToggleFunctionElement _switchEvery = RepeatingPage.CreateToggleFunction("Switch to random avatar every set seconds", Color.white, null);
			_switchEvery.Started += delegate
			{
				if (!SwitchEvery)
				{
					if (Delay < RepeatingMinimumDelay)
					{
						Core.Logger.Error("Cannot use repeated avatar change, set delay is below minimum");
						_switchEvery.Cancel();
					}
					else
					{
						Remaining = Delay;
						if (SwapOnStart)
						{
							Core.SwapToRandom();
						}
						_lastDelay = Delay;
						SwitchEvery = true;
					}
				}
			};
			_switchEvery.Cancelled += delegate
			{
				SwitchEvery = false;
			};
			if (SwitchEvery)
			{
				_switchEvery.Start();
			}
			FunctionElement obj = RepeatingPage.CreateFunction("Time until switch: N/A", Color.white, (Action)null);
			((Element)obj).SetProperty((ElementProperties)1);
			RemainingLabel = obj;
		}

		internal static void UpdateLabels()
		{
			if (IsAllowedLabel != null)
			{
				if (Fusion.IsConnected())
				{
					((Element)IsAllowedLabel).ElementName = "Is currently allowed: " + (Fusion.IsAllowed() ? "<color=#2EFF2E>Yes</color>" : "<color=#FF0000>No</color>");
					((Element)FusionDelayLabel).ElementName = $"Minimum Delay: <color=#00FFFF>{MinimumDelay}{((MinimumDelay != RepeatingMinimumDelay) ? $" (Repeated {RepeatingMinimumDelay})" : "")}</color>";
				}
				else
				{
					((Element)IsAllowedLabel).ElementName = string.Empty;
					((Element)FusionDelayLabel).ElementName = string.Empty;
				}
			}
		}

		internal static void CheckDelay()
		{
			if (DelayElement != null && Delay < RepeatingMinimumDelay)
			{
				Delay = RepeatingMinimumDelay;
				DelayElement.Value = Delay;
			}
		}

		internal static void SetupFusionPage()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			if (FusionPage != null && IsSetup)
			{
				FusionPage.RemoveAll();
				FusionPage.CreateBoolPref("Allow Random Avatar", Color.cyan, ref Core.Entry_AllowRandomAvatarInYourLobbies, null, delegate
				{
					Fusion.UpdateMetadata();
				});
				FusionPage.CreateIntPref("Delay/Cooldown", Color.yellow, ref Core.Entry_MinimumFusionDelay, 5, 0, 3600, null, delegate
				{
					Fusion.UpdateMetadata();
				});
				Fusion.UpdateMetadata();
				IsAllowedLabel = FusionPage.CreateLabel("Is currently allowed: " + (Fusion.IsAllowed() ? "<color=#2EFF2E>Yes</color>" : "<color=#FF0000>No</color>"), Color.white);
				FusionDelayLabel = FusionPage.CreateLabel($"Minimum Delay/Cooldown: <color=#00FFFF>{MinimumDelay}{((MinimumDelay != RepeatingMinimumDelay) ? $" (Repeated {RepeatingMinimumDelay})" : "")}</color>", Color.white);
			}
		}

		internal static void Update()
		{
			if (_lastMinimumDelay != RepeatingMinimumDelay)
			{
				UpdateRepeating();
				_lastMinimumDelay = RepeatingMinimumDelay;
			}
			_generalElapsed += TimeUtilities.DeltaTime;
			if (_generalElapsed >= 1f)
			{
				_generalElapsed = 0f;
				EverySecond?.Invoke();
			}
			if (RemainingLabel == null)
			{
				return;
			}
			if (SwitchEvery)
			{
				if (Fusion.IsAllowed())
				{
					if (_lastDelay == (float)Delay)
					{
						elapsed += TimeUtilities.DeltaTime;
						if (elapsed >= 1f)
						{
							Remaining--;
							elapsed = 0f;
						}
						if (Remaining <= 0)
						{
							Core.SwapToRandom();
							Remaining = Delay;
						}
					}
					else
					{
						_lastDelay = Delay;
						Remaining = Delay;
						elapsed = 0f;
					}
				}
				else
				{
					_lastDelay = 0f;
					Remaining = 0;
					elapsed = 0f;
					SwitchEvery = false;
				}
				if (!((Element)RemainingLabel).ElementName.EndsWith(Remaining.ToString()))
				{
					((Element)RemainingLabel).ElementName = $"Time until switch: {Remaining}";
				}
			}
			else if (!((Element)RemainingLabel).ElementName.EndsWith("N/A"))
			{
				((Element)RemainingLabel).ElementName = "Time until switch: N/A";
			}
		}
	}
}
namespace RandomAvatar.Menu.Elements
{
	public class BlankElement
	{
		public readonly FunctionElement Element;

		public BlankElement()
		{
			//IL_000c: 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_001c: Expected O, but got Unknown
			Element = new FunctionElement(string.Empty, Color.white, (Action)null);
			((Element)Element).SetProperty((ElementProperties)1);
		}
	}
	public class ToggleFunctionElement
	{
		public readonly FunctionElement Element;

		public Action<ToggleFunctionElement> Callback;

		public Color OffColor;

		public Color OnColor;

		public bool IsRunning { get; private set; }

		public event Action Started;

		public event Action Cancelled;

		public void Start()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!IsRunning)
			{
				IsRunning = true;
				((Element)Element).ElementColor = OnColor;
				this.Started?.Invoke();
				Callback?.Invoke(this);
			}
		}

		public void Cancel()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (IsRunning)
			{
				IsRunning = false;
				((Element)Element).ElementColor = OffColor;
				this.Cancelled?.Invoke();
			}
		}

		public ToggleFunctionElement(string name, Color offColor, Color onColor, Action<ToggleFunctionElement> callback)
		{
			//IL_000f: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			Callback = callback;
			OffColor = offColor;
			OnColor = onColor;
			Element = new FunctionElement(name, offColor, (Action)delegate
			{
				if (IsRunning)
				{
					Cancel();
				}
				else
				{
					Start();
				}
			});
		}

		public ToggleFunctionElement(string name, Color offColor, Action<ToggleFunctionElement> callback)
		{
			//IL_000e: 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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			Callback = callback;
			OffColor = offColor;
			OnColor = Color.red;
			Element = new FunctionElement(name, offColor, (Action)delegate
			{
				if (IsRunning)
				{
					Cancel();
				}
				else
				{
					Start();
				}
			});
		}
	}
}
namespace RandomAvatar.Helper
{
	internal static class BLHelper
	{
		private static readonly MelonPreferences_Category prefs = Core.Preferences_Category;

		internal static IntElement CreateIntPref(this Page page, string name, Color color, ref MelonPreferences_Entry<int> value, int increment, int minValue, int maxValue, MelonPreferences_Category category = null, Action<int> callback = null, string prefName = null, int prefDefaultValue = 0)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (category == null)
			{
				category = prefs;
			}
			if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
			{
				if (prefName == null)
				{
					prefName = name;
				}
				if (!category.HasEntry(prefName))
				{
					value = category.CreateEntry<int>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				}
			}
			MelonPreferences_Entry<int> val = value;
			IntElement val2 = page.CreateInt(name, color, val.Value, increment, minValue, maxValue, (Action<int>)delegate(int x)
			{
				val.Value = x;
				category.SaveToFile(false);
				Action<int> action = callback;
				if (action != null)
				{
					Extensions.InvokeActionSafe<int>(action, x);
				}
			});
			if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
			{
				((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
			}
			return val2;
		}

		internal static FloatElement CreateFloatPref(this Page page, string name, Color color, ref MelonPreferences_Entry<float> value, float increment, float minValue, float maxValue, MelonPreferences_Category category = null, Action<float> callback = null, string prefName = null, float prefDefaultValue = 0f)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (category == null)
			{
				category = prefs;
			}
			if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
			{
				if (prefName == null)
				{
					prefName = name;
				}
				if (!category.HasEntry(prefName))
				{
					value = category.CreateEntry<float>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				}
			}
			MelonPreferences_Entry<float> val = value;
			FloatElement val2 = page.CreateFloat(name, color, val.Value, increment, minValue, maxValue, (Action<float>)delegate(float x)
			{
				val.Value = x;
				category.SaveToFile(false);
				Action<float> action = callback;
				if (action != null)
				{
					Extensions.InvokeActionSafe<float>(action, x);
				}
			});
			if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
			{
				((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
			}
			return val2;
		}

		internal static BoolElement CreateBoolPref(this Page page, string name, Color color, ref MelonPreferences_Entry<bool> value, MelonPreferences_Category category = null, Action<bool> callback = null, string prefName = null, bool prefDefaultValue = false)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (category == null)
			{
				category = prefs;
			}
			if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
			{
				if (prefName == null)
				{
					prefName = name;
				}
				if (!category.HasEntry(prefName))
				{
					value = category.CreateEntry<bool>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				}
			}
			MelonPreferences_Entry<bool> val = value;
			BoolElement val2 = page.CreateBool(name, color, val.Value, (Action<bool>)delegate(bool x)
			{
				val.Value = x;
				category.SaveToFile(false);
				Action<bool> action = callback;
				if (action != null)
				{
					Extensions.InvokeActionSafe<bool>(action, x);
				}
			});
			if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
			{
				((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
			}
			return val2;
		}

		internal static EnumElement CreateEnumPref<T>(this Page page, string name, Color color, ref MelonPreferences_Entry<T> value, MelonPreferences_Category category = null, Action<Enum> callback = null, string prefName = null, Enum prefDefaultValue = null) where T : Enum
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (category == null)
			{
				category = prefs;
			}
			if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
			{
				if (prefName == null)
				{
					prefName = name;
				}
				if (!category.HasEntry(prefName))
				{
					value = category.CreateEntry<T>(prefName, (T)prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				}
			}
			MelonPreferences_Entry<T> val = value;
			EnumElement val2 = page.CreateEnum(name, color, (Enum)val.Value, (Action<Enum>)delegate(Enum x)
			{
				val.Value = (T)x;
				category.SaveToFile(false);
				Action<Enum> action = callback;
				if (action != null)
				{
					Extensions.InvokeActionSafe<Enum>(action, x);
				}
			});
			if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
			{
				((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
			}
			return val2;
		}

		internal static StringElement CreateStringPref(this Page page, string name, Color color, ref MelonPreferences_Entry<string> value, MelonPreferences_Category category = null, Action<string> callback = null, string prefName = null, string prefDefaultValue = null)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (category == null)
			{
				category = prefs;
			}
			if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
			{
				if (prefName == null)
				{
					prefName = name;
				}
				if (!category.HasEntry(prefName))
				{
					value = category.CreateEntry<string>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				}
			}
			MelonPreferences_Entry<string> val = value;
			StringElement val2 = page.CreateString(name, color, val.Value, (Action<string>)delegate(string x)
			{
				val.Value = x;
				category.SaveToFile(false);
				Action<string> action = callback;
				if (action != null)
				{
					Extensions.InvokeActionSafe<string>(action, x);
				}
			});
			val2.Value = value.Value;
			if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
			{
				((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
			}
			return val2;
		}

		public static FunctionElement CreateLabel(this Page page, string text, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			FunctionElement val = new FunctionElement(text, color, (Action)null);
			((Element)val).SetProperty((ElementProperties)1);
			page.Add((Element)(object)val);
			return val;
		}

		public static ToggleFunctionElement CreateToggleFunction(this Page page, string name, Color offColor, Color onColor, Action<ToggleFunctionElement> callback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ToggleFunctionElement toggleFunctionElement = new ToggleFunctionElement(name, offColor, onColor, callback);
			page.Add((Element)(object)toggleFunctionElement.Element);
			return toggleFunctionElement;
		}

		public static ToggleFunctionElement CreateToggleFunction(this Page page, string name, Color offColor, Action<ToggleFunctionElement> callback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ToggleFunctionElement toggleFunctionElement = new ToggleFunctionElement(name, offColor, callback);
			page.Add((Element)(object)toggleFunctionElement.Element);
			return toggleFunctionElement;
		}

		public static BlankElement CreateBlank(this Page page)
		{
			BlankElement blankElement = new BlankElement();
			page.Add((Element)(object)blankElement.Element);
			return blankElement;
		}

		internal static void SendNotification(string title, string message, bool showTitleOnPopup = false, float popupLength = 2f, NotificationType type = 0, Texture2D customIcon = null)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0021: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			Notifier.Send(new Notification
			{
				Title = new NotificationText("RandomAvatar | " + title, Color.white, true),
				Message = new NotificationText(message, Color.white, true),
				ShowTitleOnPopup = showTitleOnPopup,
				CustomIcon = customIcon,
				PopupLength = popupLength,
				Type = type
			});
		}

		internal static void SendNotification(NotificationText title, NotificationText message, bool showTitleOnPopup = false, float popupLength = 2f, NotificationType type = 0, Texture2D customIcon = null)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			title.Text = "RandomAvatar | " + title.Text;
			Notifier.Send(new Notification
			{
				Title = title,
				Message = message,
				ShowTitleOnPopup = showTitleOnPopup,
				CustomIcon = customIcon,
				PopupLength = popupLength,
				Type = type
			});
		}

		internal static void SendNotification(Notification notification)
		{
			Notifier.Send(notification);
		}
	}
	public static class OtherHelpers
	{
		public static void ForEach<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, Action<KeyValuePair<TKey, TValue>> action)
		{
			foreach (KeyValuePair<TKey, TValue> item in dictionary)
			{
				action?.Invoke(item);
			}
		}

		public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
		{
			foreach (T item in enumerable)
			{
				action?.Invoke(item);
			}
		}
	}
}