Decompiled source of Almanac v3.4.0

Almanac.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Almanac.API;
using Almanac.Achievements;
using Almanac.Bounties;
using Almanac.Data;
using Almanac.FileSystem;
using Almanac.TreasureHunt;
using Almanac.UI;
using Almanac.Utilities;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Groups;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: AssemblyFileVersion("3.4.0")]
[assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyProduct("Almanac")]
[assembly: AssemblyCompany("RustyMods")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("Almanac")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.4.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<ad0ed7b4-5060-46de-9a2c-ca086eeee794>Embedded]
	internal sealed class <ad0ed7b4-5060-46de-9a2c-ca086eeee794>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[<ad0ed7b4-5060-46de-9a2c-ca086eeee794>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <d1ec2403-44c3-457e-bfc2-a82017bdc7a5>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <d1ec2403-44c3-457e-bfc2-a82017bdc7a5>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <d1ec2403-44c3-457e-bfc2-a82017bdc7a5>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<ad0ed7b4-5060-46de-9a2c-ca086eeee794>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <95fcf0cd-774f-48db-8185-aea0576159b3>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <95fcf0cd-774f-48db-8185-aea0576159b3>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Almanac
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("randyknapp.mods.auga")]
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("RustyMods.Almanac", "Almanac", "3.4.0")]
	public class AlmanacPlugin : BaseUnityPlugin
	{
		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)]
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)]
		public enum WorkingAs
		{
			Client,
			Server,
			Both
		}

		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)]
		public enum DataPath
		{
			LocalLow,
			ConfigPath
		}

		internal const string ModName = "Almanac";

		internal const string ModVersion = "3.4.0";

		internal const string Author = "RustyMods";

		private const string ModGUID = "RustyMods.Almanac";

		private static readonly string ConfigFileName = "RustyMods.Almanac.cfg";

		private static readonly string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("RustyMods.Almanac");

		public static readonly ManualLogSource AlmanacLogger;

		public static readonly ConfigSync ConfigSync;

		public static AlmanacPlugin _plugin;

		public static AssetBundle _assets;

		public static GameObject _root;

		public static bool KrumpacLoaded;

		public static bool JewelCraftLoaded;

		public static bool KGEnchantmentLoaded;

		public static WorkingAs WorkingAsType;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		public static ConfigEntry<Toggle> _KnowledgeWall;

		public static ConfigEntry<Toggle> _UseIgnoreList;

		public static ConfigEntry<Toggle> _AchievementIcons;

		public static ConfigEntry<Toggle> _AchievementPowers;

		public static ConfigEntry<int> _AchievementThreshold;

		public static ConfigEntry<Toggle> _ShowAllData;

		public static ConfigEntry<DataPath> _RootPath;

		public static ConfigEntry<Toggle> _PanelImage;

		public static ConfigEntry<Color> _OutlineColor;

		public static ConfigEntry<KeyCode> _AlmanacHotKey;

		public static ConfigEntry<Toggle> _LoadDefaultAchievements;

		public static ConfigEntry<int> _TreasureCooldown;

		public static ConfigEntry<int> _BountyCooldown;

		public static ConfigEntry<Toggle> _TreasureEnabled;

		public static ConfigEntry<Toggle> _BountyEnabled;

		public static ConfigEntry<Toggle> _AchievementsEnabled;

		public static ConfigEntry<Toggle> _showLore;

		public void SpawnBounty()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			Almanac.Bounties.Data.BountyLocation activeBountyLocation = Bounty.ActiveBountyLocation;
			if (activeBountyLocation != null)
			{
				GameObject val = Object.Instantiate<GameObject>(activeBountyLocation.m_critter, activeBountyLocation.m_position, Quaternion.identity);
				Bounty bounty = val.AddComponent<Bounty>();
				ISerializer serializer = new SerializerBuilder().Build();
				string text = serializer.Serialize(activeBountyLocation.data);
				bounty._znv.GetZDO().Set(Bounty.bountyHash, text);
				CachedEffects.DoneSpawnEffectList.Create(val.transform.position, Quaternion.identity, (Transform)null, 1f, -1);
			}
		}

		public void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			Localizer.Load();
			_plugin = this;
			WorkingAsType = (((int)SystemInfo.graphicsDeviceType == 4) ? WorkingAs.Server : WorkingAs.Client);
			_assets = GetAssetBundle("almanacbundle");
			_root = new GameObject("root");
			Object.DontDestroyOnLoad((Object)(object)_root);
			_root.SetActive(false);
			InitConfigs();
			CheckChainLoader();
			AlmanacPaths.CreateFolderDirectories();
			CacheAssets.LoadAssets();
			AchievementYML.InitDefaultAchievements();
			Filters.InitFilters();
			FileWatcher.InitFileSystemWatch();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
			TrackMinimalUI.SetupWatcher();
		}

		public void Update()
		{
			UpdateAlmanac.UpdateGUI();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private static void CheckChainLoader()
		{
			if (Chainloader.PluginInfos.ContainsKey("kg.ValheimEnchantmentSystem"))
			{
				AlmanacLogger.LogInfo((object)"KG Enchantment System Loaded");
				KGEnchantmentLoaded = true;
			}
			if (Chainloader.PluginInfos.ContainsKey("Krumpac.Krumpac_Reforge_Core"))
			{
				AlmanacLogger.LogInfo((object)"Krumpac Loaded");
				KrumpacLoaded = true;
			}
			if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.jewelcrafting"))
			{
				AlmanacLogger.LogInfo((object)"Jewel Crafting Loaded");
				JewelCraftLoaded = true;
			}
		}

		private static AssetBundle GetAssetBundle(string fileName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single([<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] (string str) => str.EndsWith(fileName));
			using Stream stream = executingAssembly.GetManifestResourceStream(name);
			return AssetBundle.LoadFromStream(stream);
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				AlmanacLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				AlmanacLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				AlmanacLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private void InitConfigs()
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			_serverConfigLocked = config("1 - General", "0 - Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
			_KnowledgeWall = config("1 - General", "1 - Knowledge Wall", Toggle.On, "If on, the plugin blacks out unknown items from the almanac");
			_UseIgnoreList = config("1 - General", "2 - Use Ignore List", Toggle.On, "If on, the plugin uses the IgnoreList.yml to filter almanac");
			_ShowAllData = config("1 - General", "3 - Show All Data", Toggle.Off, "If on, Almanac does not filter extra data, like prefab name and material name");
			_AchievementIcons = config("Achievements", "HUD Icons", Toggle.Off, "If on, achievements icons appear alongside status effects on HUD");
			_AchievementIcons.SettingChanged += AchievementManager.OnAchievementConfigChanged;
			_AchievementPowers = config("Achievements", "Bonuses Enabled", Toggle.On, "If on, achievements are interactable and reward players with bonuses");
			_AchievementPowers.SettingChanged += AchievementManager.OnAchievementConfigChanged;
			_AchievementThreshold = config("Achievements", "Threshold", 3, new ConfigDescription("Total amount of achievement effects allowed at the same time", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>()));
			_PanelImage = config("1 - General", "4 - Transparent", Toggle.Off, "Compatibility with minimalUI, set transparency of almanac panel", synchronizedSetting: false);
			_PanelImage.SettingChanged += CreateAlmanac.OnPanelTransparencyConfigChange;
			_RootPath = config("1 - General", "5 - Player Data", DataPath.ConfigPath, "Set the root path where to save player data");
			_OutlineColor = config<Color>("1 - General", "6 - Outline Color", Color.yellow, "Set the color of the outline for selected items");
			_AlmanacHotKey = config<KeyCode>("1 - General", "7 - Almanac HotKey", (KeyCode)287, "Set the hotkey to open almanac", synchronizedSetting: false);
			_LoadDefaultAchievements = config("1 - General", "8 - Load Default Achievements", Toggle.Off, "If on, Almanac will write any missing default achievements to file", synchronizedSetting: false);
			_TreasureCooldown = config("Cooldown", "Treasure Hunt", 30, "Set cooldown between treasure hunts, in minutes");
			_BountyCooldown = config("Cooldown", "Bounties", 30, "Set cooldown between bounty hunts, in minutes");
			_BountyEnabled = config("2 - Settings", "Bounties", Toggle.On, "If on, bounty feature is enabled");
			_TreasureEnabled = config("2 - Settings", "Treasures", Toggle.On, "If on, treasure feature is enabled");
			_AchievementsEnabled = config("3 - Achievements", "Enabled", Toggle.On, "If on, achievements is enabled");
			_showLore = config("3 - Achievements", "Always Show Lore", Toggle.On, "If on, achievements lore is always displayed");
		}

		private ConfigEntry<T> config<[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		private ConfigEntry<T> config<[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		static AlmanacPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			AlmanacLogger = Logger.CreateLogSource("Almanac");
			ConfigSync = new ConfigSync("RustyMods.Almanac")
			{
				DisplayName = "Almanac",
				CurrentVersion = "3.4.0",
				MinimumRequiredVersion = "3.4.0"
			};
			_plugin = null;
			_assets = null;
			_root = null;
			KrumpacLoaded = false;
			JewelCraftLoaded = false;
			KGEnchantmentLoaded = false;
			_serverConfigLocked = null;
			_KnowledgeWall = null;
			_UseIgnoreList = null;
			_AchievementIcons = null;
			_AchievementPowers = null;
			_AchievementThreshold = null;
			_ShowAllData = null;
			_RootPath = null;
			_PanelImage = null;
			_OutlineColor = null;
			_AlmanacHotKey = null;
			_LoadDefaultAchievements = null;
			_TreasureCooldown = null;
			_BountyCooldown = null;
			_TreasureEnabled = null;
			_BountyEnabled = null;
			_AchievementsEnabled = null;
			_showLore = null;
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			AlmanacPlugin.AlmanacLogger.LogDebug((object)"Registering version RPC handler");
			peer.m_rpc.Register<ZPackage>("Almanac_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_Almanac_Version);
			AlmanacPlugin.AlmanacLogger.LogDebug((object)"Invoking version check");
			ZPackage val = new ZPackage();
			val.Write("3.4.0");
			peer.m_rpc.Invoke("Almanac_VersionCheck", new object[1] { val });
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			AlmanacPlugin.AlmanacLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "RequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				__instance.m_connectionFailedError.fontSizeMax = 25f;
				__instance.m_connectionFailedError.fontSizeMax = 15f;
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + AlmanacPlugin.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				AlmanacPlugin.AlmanacLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_Almanac_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			AlmanacPlugin.AlmanacLogger.LogInfo((object)("Version check, local: 3.4.0,  remote: " + text));
			if (text != "3.4.0")
			{
				AlmanacPlugin.ConnectionError = "Almanac Installed: 3.4.0\n Needed: " + text;
				if (ZNet.instance.IsServer())
				{
					AlmanacPlugin.AlmanacLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting"));
					rpc.Invoke("Error", new object[1] { 3 });
				}
			}
			else if (!ZNet.instance.IsServer())
			{
				AlmanacPlugin.AlmanacLogger.LogInfo((object)"Received same version from server!");
			}
			else
			{
				AlmanacPlugin.AlmanacLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}
	}
}
namespace Almanac.Utilities
{
	[PublicAPI]
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out var value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out var value2))
			{
				text = value2.Aggregate(text, [<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null)
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = [<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] [return: <d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(1)] (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += [<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1];
				if (dictionary.ContainsKey(text))
				{
					Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
				}
				else
				{
					dictionary[text] = item;
				}
			}
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.ContainsKey(language))
				{
					text2 = File.ReadAllText(dictionary[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text2 = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text2 == null && dictionary.ContainsKey("English"))
			{
				text2 = File.ReadAllText(dictionary["English"]);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		[return: <d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(2)]
		private static byte[] LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(2)]
		public static byte[] ReadEmbeddedFileBytes([<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(1)] string resourceFileName, Assembly containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(2)]
	public static class SpriteManager
	{
		public static readonly Sprite AlmanacIcon = RegisterSprite("AlmanacIconButton.png");

		private static readonly Sprite boneSkullIcon = RegisterSprite("bone_skull.png");

		private static readonly Sprite swordBasicBlueIcon = RegisterSprite("sword_basic_blue.png");

		private static readonly Sprite swordBasicBrownIcon = RegisterSprite("sword_basic4_blue.png");

		private static readonly Sprite arrowBasicIcon = RegisterSprite("arrow_basic.png");

		private static readonly Sprite capeHoodIcon = RegisterSprite("cape_hood_darkyellow.png");

		private static readonly Sprite bottleStandardEmptyIcon = RegisterSprite("bottle_standard_empty.png");

		private static readonly Sprite bottleStandardBlueIcon = RegisterSprite("bottle_standard_blue.png");

		private static readonly Sprite fishGreenIcon = RegisterSprite("fish_green.png");

		private static readonly Sprite bowWoodIcon = RegisterSprite("bow_wood1.png");

		private static readonly Sprite necklaceSilverRed = RegisterSprite("necklace_silver_red.png");

		private static readonly Sprite mushroomBigRedIcon = RegisterSprite("mushroom_big_red.png");

		private static readonly Sprite goldCoinsPileIcon = RegisterSprite("gold_coins_many.png");

		private static readonly Sprite keySilverIcon = RegisterSprite("key_silver.png");

		private static readonly Sprite boneWhiteIcon = RegisterSprite("bone_white.png");

		public static readonly Sprite bookClosedRedIcon = RegisterSprite("book_closed_red.png");

		private static readonly Sprite bottleStandardGreenIcon = RegisterSprite("bottle_standard_green.png");

		public static readonly Sprite crownGoldIcon = RegisterSprite("crown_gold.png");

		private static readonly Sprite gemDiamondRedIcon = RegisterSprite("gem_diamond_red.png");

		private static readonly Sprite goldBarsIcon = RegisterSprite("gold_bars_three.png");

		private static readonly Sprite scrollMapIcon = RegisterSprite("scroll_map2.png");

		private static readonly Sprite shieldBasicIcon = RegisterSprite("shield_basic_metal.png");

		private static readonly Sprite silverBarsIcon = RegisterSprite("silver_bars.png");

		private static readonly Sprite silverCoinsIcon = RegisterSprite("silver_coins_many.png");

		private static readonly Sprite woodLogIcon = RegisterSprite("wood_log.png");

		private static readonly Sprite woodLogsIcon = RegisterSprite("wood_logs_three.png");

		private static readonly Sprite ringGoldMagic = RegisterSprite("ring_gold_magic.png");

		public static readonly Sprite Checkmark = RegisterSprite("Checkmark.png");

		public static readonly Sprite FlatDaggers = RegisterSprite("Daggers_Icon.png");

		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
		public static bool GetSprite(string name, [<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(2)] out Sprite sprite)
		{
			if (1 == 0)
			{
			}
			Sprite val = (Sprite)(name switch
			{
				"skull" => boneSkullIcon, 
				"sword_blue" => swordBasicBlueIcon, 
				"sword_brown" => swordBasicBrownIcon, 
				"arrow" => arrowBasicIcon, 
				"hood" => capeHoodIcon, 
				"bottle_empty" => bottleStandardEmptyIcon, 
				"bottle_blue" => bottleStandardBlueIcon, 
				"bottle_green" => bottleStandardGreenIcon, 
				"fish" => fishGreenIcon, 
				"bow" => bowWoodIcon, 
				"necklace" => necklaceSilverRed, 
				"mushroom" => mushroomBigRedIcon, 
				"coins_gold" => goldCoinsPileIcon, 
				"key" => keySilverIcon, 
				"bone" => boneWhiteIcon, 
				"book" => bookClosedRedIcon, 
				"crown" => crownGoldIcon, 
				"gem" => gemDiamondRedIcon, 
				"gold" => goldBarsIcon, 
				"map" => scrollMapIcon, 
				"shield" => shieldBasicIcon, 
				"silver" => silverBarsIcon, 
				"coins_silver" => silverCoinsIcon, 
				"log" => woodLogIcon, 
				"log_stack" => woodLogsIcon, 
				"ring" => ringGoldMagic, 
				"checkmark" => Checkmark, 
				_ => null, 
			});
			if (1 == 0)
			{
			}
			sprite = val;
			return Object.op_Implicit((Object)(object)sprite);
		}

		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
		[return: <d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(2)]
		private static Sprite RegisterSprite(string fileName, string folderName = "icons")
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = "Almanac." + folderName + "." + fileName;
			using Stream stream = executingAssembly.GetManifestResourceStream(name);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2);
			return ImageConversion.LoadImage(val, array) ? Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), Vector2.zero) : null;
		}
	}
	public static class TerminalCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEventFailable <>9__0_0;

			public static ConsoleOptionsFetcher <>9__0_1;

			public static ConsoleEventFailable <>9__0_2;

			public static ConsoleOptionsFetcher <>9__0_3;

			internal object <AddAlmanacCommands>b__0_0(ConsoleEventArgs args)
			{
				if (args.Length < 2)
				{
					return false;
				}
				if (!PlayerStats.LocalPlayerData.Player_Kill_Deaths.TryGetValue(args[1], out var value))
				{
					return false;
				}
				AlmanacPlugin.AlmanacLogger.LogInfo((object)$"Key: {args[1]} , kills: {value.kills} , deaths: {value.deaths}");
				return true;
			}

			internal List<string> <AddAlmanacCommands>b__0_1()
			{
				return CreatureDataCollector.TempDefeatKeys;
			}

			internal object <AddAlmanacCommands>b__0_2(ConsoleEventArgs args)
			{
				if (args.Length < 2)
				{
					return false;
				}
				switch (args[1])
				{
				case "help":
				{
					Dictionary<string, string> dictionary = new Dictionary<string, string>
					{
						{ "keys", "Similar to listkeys, almanac keys prints all the current global keys and private keys the player current holds" },
						{ "size", "Prints the kilobyte size of almanac custom data saved in player save file" },
						{ "write_achievements", "Writes to file all the default achievements for the almanac" },
						{ "pickable [PrefabName]", "Prints total amount of picked item, you can use 'all' to print a list of entire pickable data" },
						{ "almanac_data [defeat key]", "Prints total kills and deaths for defeat key" },
						{ "reload", "Reloads graphic assets" }
					};
					foreach (KeyValuePair<string, string> item in dictionary)
					{
						AlmanacPlugin.AlmanacLogger.LogInfo((object)("almanac " + item.Key + ": " + item.Value));
					}
					break;
				}
				case "keys":
				{
					List<string> globalKeys = ZoneSystem.instance.GetGlobalKeys();
					AlmanacPlugin.AlmanacLogger.LogInfo((object)"Global keys: ");
					foreach (string item2 in globalKeys)
					{
						AlmanacPlugin.AlmanacLogger.LogInfo((object)item2);
					}
					AlmanacPlugin.AlmanacLogger.LogInfo((object)"Private Keys: ");
					foreach (string tempDefeatKey in CreatureDataCollector.TempDefeatKeys)
					{
						if (ZoneSystem.instance.GetGlobalKey(tempDefeatKey))
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)tempDefeatKey);
						}
					}
					break;
				}
				case "size":
				{
					if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
					{
						return false;
					}
					if (!Player.m_localPlayer.m_customData.TryGetValue(PlayerStats.AlmanacStatsKey, out var value2))
					{
						AlmanacPlugin.AlmanacLogger.LogInfo((object)"No Almanac custom player data found");
						return false;
					}
					int byteCount = Encoding.UTF8.GetByteCount(value2);
					double num = (double)byteCount / 1024.0;
					AlmanacPlugin.AlmanacLogger.LogInfo((object)("Almanac Custom Data size: " + num + " kilobytes"));
					break;
				}
				case "write_achievements":
					AlmanacPlugin.AlmanacLogger.LogInfo((object)"Almanac writing default achievements to file");
					AlmanacPlugin.AlmanacLogger.LogInfo((object)AlmanacPaths.AchievementFolderPath);
					AchievementYML.InitDefaultAchievements(overwrite: true);
					break;
				case "pickable":
				{
					if (args.Length < 3)
					{
						AlmanacPlugin.AlmanacLogger.LogInfo((object)"Invalid information: ex: almanac pickable [pickable prefab name]");
						return false;
					}
					if (args[2] == "all")
					{
						foreach (KeyValuePair<string, int> player_Pickable_Datum in PlayerStats.LocalPlayerData.Player_Pickable_Data)
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)(player_Pickable_Datum.Key + " : " + player_Pickable_Datum.Value));
						}
						return true;
					}
					if (!PlayerStats.GetPlayerPickableValue(args[2], out var value))
					{
						AlmanacPlugin.AlmanacLogger.LogInfo((object)"Failed to get pickable value");
						return false;
					}
					AlmanacPlugin.AlmanacLogger.LogInfo((object)(((Character)Player.m_localPlayer).GetHoverName() + " has picked " + value + " " + args[2]));
					break;
				}
				case "reload":
					CacheAssets.ReloadAssets();
					AlmanacPlugin.AlmanacLogger.LogDebug((object)"Reloaded graphics");
					break;
				}
				return true;
			}

			internal List<string> <AddAlmanacCommands>b__0_3()
			{
				return new List<string> { "help", "keys", "size", "write_achievements", "pickable" };
			}
		}

		public static void AddAlmanacCommands()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			AlmanacPlugin.AlmanacLogger.LogDebug((object)"Client: Adding almanac commands to terminal");
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEventFailable val = delegate(ConsoleEventArgs args)
				{
					if (args.Length < 2)
					{
						return false;
					}
					if (!PlayerStats.LocalPlayerData.Player_Kill_Deaths.TryGetValue(args[1], out var value3))
					{
						return false;
					}
					AlmanacPlugin.AlmanacLogger.LogInfo((object)$"Key: {args[1]} , kills: {value3.kills} , deaths: {value3.deaths}");
					return true;
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleOptionsFetcher val2 = () => CreatureDataCollector.TempDefeatKeys;
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			ConsoleCommand val3 = new ConsoleCommand("almanac_data", "Local player tracker data, searchable using currently registered defeat keys", (ConsoleEventFailable)obj, false, false, false, true, false, (ConsoleOptionsFetcher)obj2, false, false, false);
			object obj3 = <>c.<>9__0_2;
			if (obj3 == null)
			{
				ConsoleEventFailable val4 = delegate(ConsoleEventArgs args)
				{
					if (args.Length < 2)
					{
						return false;
					}
					switch (args[1])
					{
					case "help":
					{
						Dictionary<string, string> dictionary = new Dictionary<string, string>
						{
							{ "keys", "Similar to listkeys, almanac keys prints all the current global keys and private keys the player current holds" },
							{ "size", "Prints the kilobyte size of almanac custom data saved in player save file" },
							{ "write_achievements", "Writes to file all the default achievements for the almanac" },
							{ "pickable [PrefabName]", "Prints total amount of picked item, you can use 'all' to print a list of entire pickable data" },
							{ "almanac_data [defeat key]", "Prints total kills and deaths for defeat key" },
							{ "reload", "Reloads graphic assets" }
						};
						foreach (KeyValuePair<string, string> item in dictionary)
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)("almanac " + item.Key + ": " + item.Value));
						}
						break;
					}
					case "keys":
					{
						List<string> globalKeys = ZoneSystem.instance.GetGlobalKeys();
						AlmanacPlugin.AlmanacLogger.LogInfo((object)"Global keys: ");
						foreach (string item2 in globalKeys)
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)item2);
						}
						AlmanacPlugin.AlmanacLogger.LogInfo((object)"Private Keys: ");
						foreach (string tempDefeatKey in CreatureDataCollector.TempDefeatKeys)
						{
							if (ZoneSystem.instance.GetGlobalKey(tempDefeatKey))
							{
								AlmanacPlugin.AlmanacLogger.LogInfo((object)tempDefeatKey);
							}
						}
						break;
					}
					case "size":
					{
						if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
						{
							return false;
						}
						if (!Player.m_localPlayer.m_customData.TryGetValue(PlayerStats.AlmanacStatsKey, out var value2))
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)"No Almanac custom player data found");
							return false;
						}
						int byteCount = Encoding.UTF8.GetByteCount(value2);
						double num = (double)byteCount / 1024.0;
						AlmanacPlugin.AlmanacLogger.LogInfo((object)("Almanac Custom Data size: " + num + " kilobytes"));
						break;
					}
					case "write_achievements":
						AlmanacPlugin.AlmanacLogger.LogInfo((object)"Almanac writing default achievements to file");
						AlmanacPlugin.AlmanacLogger.LogInfo((object)AlmanacPaths.AchievementFolderPath);
						AchievementYML.InitDefaultAchievements(overwrite: true);
						break;
					case "pickable":
					{
						if (args.Length < 3)
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)"Invalid information: ex: almanac pickable [pickable prefab name]");
							return false;
						}
						if (args[2] == "all")
						{
							foreach (KeyValuePair<string, int> player_Pickable_Datum in PlayerStats.LocalPlayerData.Player_Pickable_Data)
							{
								AlmanacPlugin.AlmanacLogger.LogInfo((object)(player_Pickable_Datum.Key + " : " + player_Pickable_Datum.Value));
							}
							return true;
						}
						if (!PlayerStats.GetPlayerPickableValue(args[2], out var value))
						{
							AlmanacPlugin.AlmanacLogger.LogInfo((object)"Failed to get pickable value");
							return false;
						}
						AlmanacPlugin.AlmanacLogger.LogInfo((object)(((Character)Player.m_localPlayer).GetHoverName() + " has picked " + value + " " + args[2]));
						break;
					}
					case "reload":
						CacheAssets.ReloadAssets();
						AlmanacPlugin.AlmanacLogger.LogDebug((object)"Reloaded graphics");
						break;
					}
					return true;
				};
				<>c.<>9__0_2 = val4;
				obj3 = (object)val4;
			}
			object obj4 = <>c.<>9__0_3;
			if (obj4 == null)
			{
				ConsoleOptionsFetcher val5 = () => new List<string> { "help", "keys", "size", "write_achievements", "pickable" };
				<>c.<>9__0_3 = val5;
				obj4 = (object)val5;
			}
			ConsoleCommand val6 = new ConsoleCommand("almanac", "Utility commands for the almanac", (ConsoleEventFailable)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)obj4, false, false, false);
		}
	}
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	public static class Utility
	{
		private static readonly Color32 OrangeColor = new Color32(byte.MaxValue, (byte)164, (byte)0, byte.MaxValue);

		public static string FormatTreasureRewardText(Almanac.TreasureHunt.Data.ValidatedTreasure data)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			string text = "$almanac_reward:\n";
			foreach (DropData drop in data.m_dropTable.m_drops)
			{
				string arg = Localization.instance.Localize(drop.m_item.GetComponent<ItemDrop>().m_itemData.m_shared.m_name);
				text += $"<color=orange>{drop.m_stackMin}</color> - <color=orange>{drop.m_stackMax}</color> x <color=yellow>{arg}</color>\n";
			}
			return text;
		}

		public static string FormatBountyRewardText(Almanac.Bounties.Data.ValidatedBounty data)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			switch (data.m_rewardType)
			{
			case Almanac.Bounties.Data.QuestRewardType.Item:
				if ((Object)(object)data.m_itemReward == (Object)null)
				{
					return "";
				}
				return $"$almanac_reward:\n <color=orange>{data.m_itemAmount}</color>x {data.m_itemReward.m_itemData.m_shared.m_name}";
			case Almanac.Bounties.Data.QuestRewardType.Skill:
				return $"$almanac_reward:\n <color=orange>{data.m_skillAmount}</color>$almanac_xp <color=orange>{ConvertSkills(data.m_skill)}</color>";
			default:
				return "";
			}
		}

		public static string FormatBountyDetails(Almanac.Bounties.Data.ValidatedBounty data)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			return "                       $almanac_bounty: <color=yellow>" + ((Object)data.m_critter).name + "</color>" + $"\n                       $almanac_biome: <color=orange>{data.m_biome}</color>" + $"\n                       $almanac_health: <color=orange>{data.m_health}</color>" + $"\n                       $almanac_damage Multiplier: <color=orange>{data.m_damageMultiplier}</color>" + $"\n                       $almanac_level: <color=orange>{data.m_level}</color>" + "\n                       " + FormatBountyDamages(data);
		}

		private static string FormatBountyDamages(Almanac.Bounties.Data.ValidatedBounty data)
		{
			string text = "";
			if (data.m_damages.blunt > 0f)
			{
				text += $"$almanac_blunt: <color=orange>{data.m_damages.blunt}</color> ";
			}
			if (data.m_damages.slash > 0f)
			{
				text += $"$almanac_slash: <color=orange>{data.m_damages.slash}</color> ";
			}
			if (data.m_damages.pierce > 0f)
			{
				text += $"$almanac_pierce: <color=orange>{data.m_damages.pierce}</color> ";
			}
			if (data.m_damages.fire > 0f)
			{
				text += $"$almanac_fire: <color=orange>{data.m_damages.fire}</color> ";
			}
			if (data.m_damages.frost > 0f)
			{
				text += $"$almanac_frost: <color=orange>{data.m_damages.frost}</color> ";
			}
			if (data.m_damages.lightning > 0f)
			{
				text += $"$almanac_lightning: <color=orange>{data.m_damages.lightning}</color> ";
			}
			if (data.m_damages.poison > 0f)
			{
				text += $"$almanac_poison: <color=orange>{data.m_damages.poison}</color> ";
			}
			if (data.m_damages.spirit > 0f)
			{
				text += $"$almanac_spirit: <color=orange>{data.m_damages.spirit}</color> ";
			}
			return text;
		}

		public static string ReplaceSpaceWithNewLine(string input)
		{
			return input.Replace(' ', '\n');
		}

		public static void MergeDictionaries(Dictionary<string, string> destination, Dictionary<string, string> source)
		{
			foreach (KeyValuePair<string, string> item in source)
			{
				if (destination.ContainsKey(item.Key))
				{
					if (!destination.ContainsKey(item.Key + 1))
					{
						destination.Add(item.Key + 1, item.Value);
					}
				}
				else
				{
					destination.Add(item.Key, item.Value);
				}
			}
		}

		public static string RemoveNumbers(string input)
		{
			return Regex.Replace(input, "\\d", "");
		}

		public static string SplitCamelCase(string input)
		{
			string input2 = Regex.Replace(input, "([A-Z])", " $1");
			input2 = Regex.Replace(input2, "([A-Z]+)([A-Z][a-z])", "$1 $2");
			return input2.TrimStart(Array.Empty<char>());
		}

		public static string RemoveParentheses(string input)
		{
			return Regex.Replace(input, "\\([^)]*\\)", "");
		}

		public static TextMeshProUGUI AddTextMeshProGUI(GameObject prefab, bool bold = false, TextWrappingModes wrap = 1)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = prefab.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val).font = (bold ? CacheAssets.NorseFontBold : CacheAssets.NorseFont);
			if (bold)
			{
				((TMP_Text)val).fontMaterial = ((TMP_Text)CacheAssets.TopicTextMeshPro).fontMaterial;
			}
			if (bold)
			{
				((Graphic)val).material = ((Graphic)CacheAssets.TopicTextMeshPro).material;
			}
			((TMP_Text)val).fontSize = 14f;
			((TMP_Text)val).fontSizeMin = 12f;
			((TMP_Text)val).fontSizeMax = 16f;
			((TMP_Text)val).autoSizeTextContainer = false;
			((TMP_Text)val).textWrappingMode = wrap;
			((TMP_Text)val).overflowMode = (TextOverflowModes)0;
			((TMP_Text)val).verticalAlignment = (VerticalAlignmentOptions)512;
			((TMP_Text)val).horizontalAlignment = (HorizontalAlignmentOptions)2;
			((Graphic)val).color = Color32.op_Implicit(OrangeColor);
			((TMP_Text)val).richText = true;
			return val;
		}

		public static string ConvertDamageModifiers(DamageModifier mod)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			string result = (int)mod switch
			{
				0 => "$almanac_normal", 
				4 => "$almanac_ignore", 
				3 => "$almanac_immune", 
				5 => "$almanac_very_resistant", 
				1 => "$almanac_resistant", 
				2 => "$almanac_weak", 
				6 => "$almanac_very_weak", 
				_ => "Unknown Damage Modifier", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ConvertDamageTypes(DamageType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_000e: 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_0026: Expected I4, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			if (1 == 0)
			{
			}
			string result;
			if ((int)type <= 32)
			{
				if ((int)type <= 8)
				{
					switch (type - 1)
					{
					case 0:
						goto IL_0083;
					case 1:
						goto IL_008b;
					case 3:
						goto IL_0093;
					case 2:
						goto IL_00e3;
					}
					if ((int)type != 8)
					{
						goto IL_00e3;
					}
					result = "$almanac_chop";
				}
				else if ((int)type != 16)
				{
					if ((int)type != 31)
					{
						if ((int)type != 32)
						{
							goto IL_00e3;
						}
						result = "$almanac_fire";
					}
					else
					{
						result = "$almanac_physical";
					}
				}
				else
				{
					result = "$almanac_pickaxe";
				}
			}
			else if ((int)type <= 128)
			{
				if ((int)type != 64)
				{
					if ((int)type != 128)
					{
						goto IL_00e3;
					}
					result = "$almanac_lightning";
				}
				else
				{
					result = "$almanac_frost";
				}
			}
			else if ((int)type != 224)
			{
				if ((int)type != 256)
				{
					if ((int)type != 512)
					{
						goto IL_00e3;
					}
					result = "$almanac_spirit";
				}
				else
				{
					result = "$almanac_poison";
				}
			}
			else
			{
				result = "$almanac_elemental";
			}
			goto IL_00eb;
			IL_0093:
			result = "$almanac_pierce";
			goto IL_00eb;
			IL_008b:
			result = "$almanac_slash";
			goto IL_00eb;
			IL_00eb:
			if (1 == 0)
			{
			}
			return result;
			IL_0083:
			result = "$almanac_blunt";
			goto IL_00eb;
			IL_00e3:
			result = "Unknown Damage Type";
			goto IL_00eb;
		}

		public static string ConvertSkills(SkillType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected I4, but got Unknown
			//IL_0049: 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_007e: Expected I4, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			if (1 == 0)
			{
			}
			string result;
			switch ((int)type)
			{
			default:
				switch (type - 100)
				{
				case 0:
					goto IL_0112;
				case 1:
					goto IL_011a;
				case 2:
					goto IL_0122;
				case 3:
					goto IL_012a;
				case 4:
					goto IL_0132;
				case 10:
					goto IL_013a;
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
					goto IL_014a;
				}
				if ((int)type != 999)
				{
					goto IL_014a;
				}
				result = "$skill_all";
				break;
			case 0:
				result = "$almanac_none";
				break;
			case 1:
				result = "$skill_swords";
				break;
			case 2:
				result = "$skill_knives";
				break;
			case 3:
				result = "$skill_clubs";
				break;
			case 4:
				result = "$skill_polearms";
				break;
			case 5:
				result = "$skill_spears";
				break;
			case 6:
				result = "$skill_shields";
				break;
			case 7:
				result = "$skill_axes";
				break;
			case 8:
				result = "$skill_bows";
				break;
			case 9:
				result = "$skill_elementalmagic";
				break;
			case 10:
				result = "$skill_bloodmagic";
				break;
			case 11:
				result = "$skill_unarmed";
				break;
			case 13:
				result = "$skill_woodcutting";
				break;
			case 14:
				result = "$skill_crossbows";
				break;
			case 12:
				goto IL_014a;
				IL_013a:
				result = "$skill_ride";
				break;
				IL_0132:
				result = "$skill_fishing";
				break;
				IL_012a:
				result = "$skill_swim";
				break;
				IL_0122:
				result = "$skill_run";
				break;
				IL_011a:
				result = "$skill_sneak";
				break;
				IL_0112:
				result = "$skill_jump";
				break;
				IL_014a:
				result = "Unknown Skill";
				break;
			}
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ConvertAttackTypes(AttackType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			string result = (int)type switch
			{
				0 => "$almanac_horizontal", 
				1 => "$almanac_vertical", 
				2 => "$almanac_ammo_button", 
				3 => "$almanac_none", 
				4 => "$almanac_area", 
				5 => "$almanac_trigger_projectile", 
				_ => "Unknown Attack Type", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ConvertItemType(ItemType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			string result = (int)type switch
			{
				0 => "$almanac_none", 
				1 => "$almanac_material_button", 
				2 => "$almanac_consumable_button", 
				3 => "$item_onehanded", 
				4 => "$skill_bow", 
				5 => "$skill_shields", 
				6 => "$almanac_helmet", 
				7 => "$almanac_chest", 
				9 => "$almanac_ammo_button", 
				10 => "$almanac_customization", 
				11 => "$almanac_legs", 
				12 => "$almanac_hands", 
				13 => "$almanac_trophies_button", 
				14 => "$item_twohanded", 
				15 => "$item_torch", 
				16 => "$almanac_miscPieces_button", 
				17 => "$almanac_shoulder", 
				18 => "$almanac_utility", 
				19 => "$almanac_tool", 
				20 => "$almanac_attach_atgeir", 
				21 => "$almanac_fish_button", 
				22 => "$item_twohanded $almanac_left", 
				23 => "$almanac_ammo_non_equip", 
				_ => "Unknown Item Type", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ConvertFactions(Faction faction)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			string result = (int)faction switch
			{
				0 => "$almanac_players", 
				1 => "$almanac_animals_veg", 
				2 => "$almanac_forest_monsters", 
				3 => "$almanac_undead", 
				4 => "$almanac_demon", 
				5 => "$almanac_mountain_monsters", 
				6 => "$almanac_sea_monsters", 
				7 => "$almanac_plains_monsters", 
				8 => "$almanac_boss", 
				10 => "$almanac_dverger", 
				9 => "$almanac_mistlands_monsters", 
				_ => "Unknown Faction", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ConvertBoolean(bool input)
		{
			if (1 == 0)
			{
			}
			string result = ((!input) ? "$almanac_false" : "$almanac_true");
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ConvertEffectModifiers(AlmanacEffectManager.Modifier type)
		{
			if (1 == 0)
			{
			}
			string result = type switch
			{
				AlmanacEffectManager.Modifier.None => "$almanac_none", 
				AlmanacEffectManager.Modifier.Attack => "$almanac_attack", 
				AlmanacEffectManager.Modifier.HealthRegen => "$se_healthregen", 
				AlmanacEffectManager.Modifier.StaminaRegen => "$se_staminaregen", 
				AlmanacEffectManager.Modifier.RaiseSkills => "$almanac_raise_skill", 
				AlmanacEffectManager.Modifier.Speed => "$almanac_speed", 
				AlmanacEffectManager.Modifier.Noise => "$almanac_noise", 
				AlmanacEffectManager.Modifier.MaxCarryWeight => "$almanac_max_carry_weight", 
				AlmanacEffectManager.Modifier.Stealth => "$almanac_stealth", 
				AlmanacEffectManager.Modifier.RunStaminaDrain => "$almanac_run_stamina_drain", 
				AlmanacEffectManager.Modifier.DamageReduction => "$almanac_damage_reduction", 
				AlmanacEffectManager.Modifier.FallDamage => "$almanac_fall_damage", 
				AlmanacEffectManager.Modifier.EitrRegen => "$se_eitrregen", 
				AlmanacEffectManager.Modifier.Health => "$se_health", 
				AlmanacEffectManager.Modifier.Stamina => "$se_stamina", 
				AlmanacEffectManager.Modifier.Eitr => "$se_eitr", 
				AlmanacEffectManager.Modifier.LifeSteal => "$se_lifesteal", 
				AlmanacEffectManager.Modifier.Armor => "$se_armor", 
				_ => "Unknown Modifier", 
			};
			if (1 == 0)
			{
			}
			return result;
		}
	}
}
namespace Almanac.UI
{
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	public static class CacheAssets
	{
		public static TMP_FontAsset NorseFont;

		public static TMP_FontAsset NorseFontBold;

		public static TextMeshProUGUI TopicTextMeshPro;

		public static ButtonSfx ButtonSFX;

		public static Image ButtonImage;

		public static Button ButtonComponent;

		public static Image TrophyImage;

		public static Image WoodPanel;

		public static Transform TrophiesFrame;

		public static Image BraidLeft;

		public static Image BraidRight;

		public static GameObject Panel;

		public static GameObject Item;

		public static GameObject Drops;

		public static GameObject ItemTitle;

		public static GameObject AchievementPanel;

		public static GameObject SearchBar;

		public static GameObject LeaderboardItem;

		public static GameObject TrophyElement;

		[HarmonyWrapSafe]
		public static void GetAssets(InventoryGui GUI, bool reload = false)
		{
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)GUI))
			{
				TrophiesFrame = Utils.FindChild(((Component)GUI).transform, "TrophiesFrame", (IterativeSearchType)0);
				Transform val = Utils.FindChild(TrophiesFrame, "Closebutton", (IterativeSearchType)0);
				Transform val2 = Utils.FindChild(TrophiesFrame, "border (1)", (IterativeSearchType)0);
				Transform val3 = Utils.FindChild(TrophiesFrame, "topic", (IterativeSearchType)0);
				Transform val4 = Utils.FindChild(TrophiesFrame, "Text", (IterativeSearchType)0);
				Transform val5 = Utils.FindChild(TrophiesFrame, "icon_bkg", (IterativeSearchType)0);
				NorseFont = ((TMP_Text)((Component)val4).GetComponent<TextMeshProUGUI>()).font;
				TopicTextMeshPro = ((Component)val3).GetComponent<TextMeshProUGUI>();
				NorseFontBold = ((TMP_Text)TopicTextMeshPro).font;
				ButtonSFX = ((Component)val).GetComponent<ButtonSfx>();
				ButtonImage = ((Component)val).GetComponent<Image>();
				ButtonComponent = ((Component)val).GetComponent<Button>();
				TrophyImage = ((Component)val5).GetComponent<Image>();
				WoodPanel = ((Component)val2).GetComponent<Image>();
				BraidLeft = ((Component)((Component)GUI.m_info).transform.Find("TitlePanel/BraidLineHorisontalMedium (1)")).GetComponent<Image>();
				BraidRight = ((Component)((Component)GUI.m_info).transform.Find("TitlePanel/BraidLineHorisontalMedium (2)")).GetComponent<Image>();
				if (!reload)
				{
					TrophyElement = Object.Instantiate<GameObject>(GUI.m_trophieElementPrefab, AlmanacPlugin._root.transform, false);
					((Object)TrophyElement).name = "AlmanacElement";
					GameObject val6 = new GameObject("$part_outline");
					RectTransform val7 = val6.AddComponent<RectTransform>();
					((Transform)val7).SetParent(TrophyElement.transform);
					val7.anchoredPosition = new Vector2(0f, 50f);
					val7.sizeDelta = new Vector2(72f, 72f);
					((Transform)val7).SetAsFirstSibling();
					Image val8 = val6.AddComponent<Image>();
					((Graphic)val8).color = AlmanacPlugin._OutlineColor.Value;
					val6.SetActive(false);
					UITools.AddButtonComponent(TrophyElement);
				}
			}
		}

		public static void ReloadAssets()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GetAssets(InventoryGui.instance, reload: true);
				((Graphic)CreateAlmanac.PanelImage).material = ((Graphic)WoodPanel).material;
				CreateAlmanac.PanelImage.sprite = WoodPanel.sprite;
				((Graphic)CreateAlmanac.PanelImage).color = ((Graphic)WoodPanel).color;
				((Graphic)CreateAlmanac.AchievementPanelImage).material = ((Graphic)WoodPanel).material;
				CreateAlmanac.AchievementPanelImage.sprite = WoodPanel.sprite;
				((Graphic)CreateAlmanac.AchievementPanelImage).color = ((Graphic)WoodPanel).color;
			}
			catch
			{
				AlmanacPlugin.AlmanacLogger.LogDebug((object)"Failed to reload graphics");
			}
		}

		public static void LoadAssets()
		{
			Panel = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_gui");
			Item = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_item");
			Drops = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_drops");
			ItemTitle = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_item_title");
			AchievementPanel = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_achievement");
			SearchBar = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_search");
			LeaderboardItem = AlmanacPlugin._assets.LoadAsset<GameObject>("almanac_leaderboard");
		}
	}
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	public static class Categories
	{
		private static GameObject ItemTabs = null;

		private static GameObject PieceTabs = null;

		private static GameObject AlmanacTabs = null;

		private static GameObject SpecialTabs = null;

		public static GameObject BaseTab = null;

		public static string SelectedTab = "$almanac_trophies_button";

		public static readonly Dictionary<string, Action<InventoryGui, string>> m_tabs = new Dictionary<string, Action<InventoryGui, string>>();

		private static readonly List<string> ItemOptions = new List<string> { "$almanac_trophies_button", "$almanac_fish_button", "$almanac_ammo_button", "$almanac_consumable_button", "$almanac_material_button", "$almanac_weapon_button", "$almanac_gear_button", "$almanac_creature_button" };

		private static readonly List<string> PieceOptions = new List<string> { "$almanac_miscPieces_button", "$almanac_craftingPieces_button", "$almanac_buildPieces_button", "$almanac_furniturePieces_button", "$almanac_plantPieces_button", "$almanac_other_button", "$almanac_comfortPieces_button" };

		private static readonly List<string> AlmanacOptions = new List<string> { "$almanac_achievements_button", "$almanac_quests_button", "$almanac_treasure_hunt_button" };

		private static readonly List<string> SpecialOptions = new List<string>();

		public static void Setup()
		{
			m_tabs["$almanac_scroll_button"] = delegate(InventoryGui GUI, string filter)
			{
				UpdateAlmanac.UpdateItemList(GUI, ItemDataCollector.GetScrolls(filter));
			};
		}

		public static void CreateTabs()
		{
			if (Object.op_Implicit((Object)(object)ItemTabs) && Object.op_Implicit((Object)(object)PieceTabs) && Object.op_Implicit((Object)(object)AlmanacTabs) && Object.op_Implicit((Object)(object)BaseTab))
			{
				SpecialOptions.Clear();
				if (AlmanacPlugin.JewelCraftLoaded)
				{
					SpecialOptions.Add("$almanac_jewel_button");
				}
				if (AlmanacPlugin.KGEnchantmentLoaded)
				{
					SpecialOptions.Add("$almanac_scroll_button");
				}
				if (PieceDataCollector.modPieces.Count > 0 && !PieceOptions.Contains("$almanac_modPieces_button"))
				{
					PieceOptions.Add("$almanac_modPieces_button");
				}
				AlmanacOptions.Clear();
				if (AlmanacPlugin._AchievementsEnabled.Value == AlmanacPlugin.Toggle.On)
				{
					AlmanacOptions.Add("$almanac_achievements_button");
				}
				if (AlmanacPlugin._BountyEnabled.Value == AlmanacPlugin.Toggle.On)
				{
					AlmanacOptions.Add("$almanac_quests_button");
				}
				if (AlmanacPlugin._TreasureEnabled.Value == AlmanacPlugin.Toggle.On)
				{
					AlmanacOptions.Add("$almanac_treasure_hunt_button");
				}
				CreateBaseTabs(ItemTabs, ItemOptions, -750f, 425f);
				CreateBaseTabs(PieceTabs, PieceOptions, -750f, -425f);
				CreateBaseTabs(AlmanacTabs, AlmanacOptions, 530f + 75f * (float)(3 - AlmanacOptions.Count), 425f);
				CreateBaseTabs(SpecialTabs, SpecialOptions, -750f, 473f);
			}
		}

		private static void CreateBaseTabs(GameObject parent, List<string> options, float x, float y)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			parent.SetActive(true);
			foreach (Transform item in parent.transform)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			RectTransform val3 = default(RectTransform);
			TextMeshProUGUI val5 = default(TextMeshProUGUI);
			Button val6 = default(Button);
			for (int i = 0; i < options.Count; i++)
			{
				string selection = options[i];
				GameObject val2 = Object.Instantiate<GameObject>(BaseTab, parent.transform);
				if (!val2.TryGetComponent<RectTransform>(ref val3))
				{
					continue;
				}
				val3.anchoredPosition = new Vector2(x + (float)i * 152f, y);
				Transform val4 = Utils.FindChild(val2.transform, "text", (IterativeSearchType)0);
				if (!((Component)val4).TryGetComponent<TextMeshProUGUI>(ref val5))
				{
					continue;
				}
				((TMP_Text)val5).text = Localization.instance.Localize(selection);
				if (!val2.TryGetComponent<Button>(ref val6))
				{
					continue;
				}
				((UnityEvent)val6.onClick).AddListener((UnityAction)delegate
				{
					SelectedTab = selection;
					if (Object.op_Implicit((Object)(object)InventoryGui.instance))
					{
						InventoryGui.instance.UpdateTrophyList();
					}
				});
			}
		}

		public static void DestroyTabs()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)BaseTab) || !Object.op_Implicit((Object)(object)ItemTabs) || !Object.op_Implicit((Object)(object)PieceTabs) || !Object.op_Implicit((Object)(object)AlmanacTabs) || !Object.op_Implicit((Object)(object)SpecialTabs))
			{
				return;
			}
			ItemTabs.SetActive(false);
			PieceTabs.SetActive(false);
			AlmanacTabs.SetActive(false);
			SpecialTabs.SetActive(false);
			foreach (Transform item in PieceTabs.transform)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			foreach (Transform item2 in ItemTabs.transform)
			{
				Transform val2 = item2;
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			foreach (Transform item3 in AlmanacTabs.transform)
			{
				Transform val3 = item3;
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
			foreach (Transform item4 in SpecialTabs.transform)
			{
				Transform val4 = item4;
				Object.Destroy((Object)(object)((Component)val4).gameObject);
			}
		}

		public static bool AreTabsVisible()
		{
			return Object.op_Implicit((Object)(object)ItemTabs) && ItemTabs.activeSelf && Object.op_Implicit((Object)(object)PieceTabs) && PieceTabs.activeSelf && Object.op_Implicit((Object)(object)AlmanacTabs) && AlmanacTabs.activeSelf;
		}

		public static void CreateAssets(InventoryGui GUI)
		{
			if (Object.op_Implicit((Object)(object)InventoryGui.instance))
			{
				if ((Object)(object)ItemTabs == (Object)null)
				{
					ItemTabs = CreateTabContainer(GUI);
				}
				if ((Object)(object)PieceTabs == (Object)null)
				{
					PieceTabs = CreateTabContainer(GUI);
				}
				if ((Object)(object)AlmanacTabs == (Object)null)
				{
					AlmanacTabs = CreateTabContainer(GUI);
				}
				if ((Object)(object)SpecialTabs == (Object)null)
				{
					SpecialTabs = CreateTabContainer(GUI);
				}
				if ((Object)(object)BaseTab == (Object)null)
				{
					BaseTab = CreateBaseTab();
				}
			}
		}

		private static GameObject CreateBaseTab()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00d7: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			GameObject val = new GameObject("tab");
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(150f, 46f);
			Image val3 = val.AddComponent<Image>();
			val3.sprite = CacheAssets.ButtonImage.sprite;
			((Graphic)val3).material = ((Graphic)CacheAssets.ButtonImage).material;
			((Graphic)val3).raycastPadding = ((Graphic)CacheAssets.ButtonImage).raycastPadding;
			((Graphic)val3).raycastTarget = ((Graphic)CacheAssets.ButtonImage).raycastTarget;
			((MaskableGraphic)val3).maskable = ((MaskableGraphic)CacheAssets.ButtonImage).maskable;
			val3.type = CacheAssets.ButtonImage.type;
			val3.fillCenter = CacheAssets.ButtonImage.fillCenter;
			val3.pixelsPerUnitMultiplier = CacheAssets.ButtonImage.pixelsPerUnitMultiplier;
			GameObject val4 = new GameObject("text");
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.sizeDelta = new Vector2(150f, 30f);
			((Transform)val5).SetParent((Transform)(object)val2);
			TextMeshProUGUI val6 = val4.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val6).font = CacheAssets.NorseFont;
			((TMP_Text)val6).fontSize = 18f;
			((TMP_Text)val6).overflowMode = (TextOverflowModes)3;
			((Graphic)val6).color = new Color(0.8f, 0.5f, 0f, 1f);
			((MaskableGraphic)val6).maskable = true;
			((TMP_Text)val6).horizontalAlignment = (HorizontalAlignmentOptions)2;
			((TMP_Text)val6).verticalAlignment = (VerticalAlignmentOptions)512;
			Button val7 = val.AddComponent<Button>();
			((Selectable)val7).interactable = true;
			((Selectable)val7).targetGraphic = (Graphic)(object)val3;
			((Selectable)val7).transition = (Transition)2;
			((Selectable)val7).spriteState = ((Selectable)CacheAssets.ButtonComponent).spriteState;
			val7.onClick = new ButtonClickedEvent();
			ButtonSfx val8 = val.AddComponent<ButtonSfx>();
			val8.m_sfxPrefab = CacheAssets.ButtonSFX.m_sfxPrefab;
			return val;
		}

		private static GameObject CreateTabContainer(InventoryGui GUI)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("container");
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(((Component)GUI).transform);
			val2.sizeDelta = Vector2.zero;
			val2.anchoredPosition = default(Vector2);
			return val;
		}
	}
	[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
	[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
	public static class CreateAlmanac
	{
		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)]
		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		private static class ModifyInventoryGUI
		{
			[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(1)]
			private static void Postfix(InventoryGui __instance)
			{
				if (Object.op_Implicit((Object)(object)__instance))
				{
					CacheAssets.GetAssets(__instance);
					Categories.CreateAssets(__instance);
					RepositionTrophyPanel(-220f, 0f);
					CreateAlmanacPanel(__instance);
					CreateAchievementPanel(__instance);
					EditPanelItem();
					EditDropItem();
					EditTitleItem();
					EditInventoryGUI(__instance);
					AddSearchBar();
					EditLeaderboardItem();
					CreateFilterCompletedAchievementsButton(__instance.m_trophiesPanel);
					if ((Object)(object)CreaturePanelElement == (Object)null)
					{
						CreaturePanelElement = CreateCreaturePanelElement();
					}
					CreatureDataCollector.GetSortedCreatureData();
					CreatureLists.InitCreatureLists();
					if (AlmanacPlugin.JewelCraftLoaded)
					{
						ItemDataCollector.GetJewels();
					}
				}
			}
		}

		[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)]
		[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
		private static class PlayerControllerOverride
		{
			private static bool Prefix()
			{
				return !Object.op_Implicit((Object)(object)InventoryGui.instance) || !InventoryGui.instance.m_trophiesPanel.activeInHierarchy;
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
			public static readonly <>c <>9 = new <>c();

			[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
			public static UnityAction <>9__23_0;

			[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
			public static UnityAction <>9__25_0;

			[<d1ec2403-44c3-457e-bfc2-a82017bdc7a5>Nullable(0)]
			public static Predicate<StatusEffect> <>9__26_0;

			internal void <CreateFilterCompletedAchievementsButton>b__23_0()
			{
				if (Object.op_Implicit((Object)(object)InventoryGui.instance))
				{
					UpdateAlmanac.DestroyTrophies(InventoryGui.instance);
					UpdateAlmanac.UpdateAchievementList(InventoryGui.instance, AchievementManager.GetAchievements(), completed: true);
				}
			}

			internal void <CreateAchievementPanel>b__25_0()
			{
				AchievementPanelIcon.sprite = SpriteManager.AlmanacIcon;
				((TMP_Text)AchievementPanelTitle).text = Localization.instance.Localize("$almanac_name");
				((TMP_Text)AchievementPanelDesc).text = "";
				((TMP_Text)AchievementPanelLore).text = "";
				((TMP_Text)AchievementPanelTooltip).text = "";
				ToggleButtonOptions();
			}

			[<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)]
			internal bool <OnClickAchievement>b__26_0(StatusEffect effect)
			{
				return effect is AlmanacEffectManager.AchievementEffect;
			}
		}

		public static GameObject AlmanacGUI;

		public static Image PanelIcon;

		public static TextMeshProUGUI PanelTitle;

		public static Transform PanelContent;

		public static GameObject CreaturePanelElement;

		public static GameObject AchievementGUI;

		public static Image AchievementPanelIcon;

		public static TextMeshProUGUI AchievementPanelTitle;

		public static TextMeshProUGUI AchievementPanelDesc;

		public static TextMeshProUGUI AchievementPanelTooltip;

		public static TextMeshProUGUI AchievementPanelLore;

		public static Button AchievementButton;

		public static TextMeshProUGUI PanelButton;

		public static TextMeshProUGUI AchievementPanelButton;

		public static Image PanelImage;

		public static Image AchievementPanelImage;

		private static GameObject AchievementCheckmark;

		public static void OnPanelTransparencyConfigChange(object sender, EventArgs e)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			((Graphic)PanelImage).color = ((AlmanacPlugin._PanelImage.Value == AlmanacPlugin.Toggle.On) ? Color.clear : Color.white);
			((Graphic)AchievementPanelImage).color = ((AlmanacPlugin._PanelImage.Value == AlmanacPlugin.Toggle.On) ? Color.clear : Color.white);
		}

		private static void RepositionTrophyPanel(float x, float y)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Transform trophiesFrame = CacheAssets.TrophiesFrame;
			RectTransform val = (RectTransform)(object)((trophiesFrame is RectTransform) ? trophiesFrame : null);
			if (!((Object)(object)val == (Object)null))
			{
				val.anchoredPosition = new Vector2(x, y);
			}
		}

		public static bool IsPanelActive()
		{
			return Object.op_Implicit((Object)(object)AlmanacGUI) && AlmanacGUI.activeInHierarchy;
		}

		public static bool IsAchievementActive()
		{
			return Object.op_Implicit((Object)(object)AchievementGUI) && AchievementGUI.activeInHierarchy;
		}

		private static void CreateAlmanacPanel(InventoryGui GUI)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Expected O, but got Unknown
			if ((Object)(object)AlmanacGUI != (Object)null)
			{
				return;
			}
			AlmanacGUI = Object.Instantiate<GameObject>(CacheAssets.Panel, ((Component)GUI).transform);
			AlmanacGUI.SetActive(false);
			Transform transform = AlmanacGUI.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			val.anchoredPosition = new Vector2(680f, 0f);
			PanelImage = ((Component)Utils.FindChild(AlmanacGUI.transform, "Panel", (IterativeSearchType)0)).GetComponent<Image>();
			((Graphic)PanelImage).material = ((Graphic)CacheAssets.WoodPanel).material;
			PanelImage.sprite = CacheAssets.WoodPanel.sprite;
			((Graphic)PanelImage).color = ((AlmanacPlugin._PanelImage.Value == AlmanacPlugin.Toggle.Off) ? Color.white : Color.clear);
			Image val2 = default(Image);
			Image val3 = default(Image);
			if (!((Component)Utils.FindChild(AlmanacGUI.transform, "$part_left_braid", (IterativeSearchType)0)).TryGetComponent<Image>(ref val2) || !((Component)Utils.FindChild(AlmanacGUI.transform, "$part_right_braid", (IterativeSearchType)0)).TryGetComponent<Image>(ref val3))
			{
				return;
			}
			val2.sprite = CacheAssets.BraidLeft.sprite;
			val3.sprite = CacheAssets.BraidRight.sprite;
			PanelIcon = ((Component)Utils.FindChild(AlmanacGUI.transform, "$part_icon", (IterativeSearchType)0)).GetComponent<Image>();
			PanelIcon.sprite = SpriteManager.AlmanacIcon;
			PanelTitle = Utility.AddTextMeshProGUI(((Component)Utils.FindChild(AlmanacGUI.transform, "$part_name", (IterativeSearchType)0)).gameObject, bold: true, (TextWrappingModes)1);
			((TMP_Text)PanelTitle).fontSize = 40f;
			((TMP_Text)PanelTitle).fontSizeMin = 20f;
			((TMP_Text)PanelTitle).fontSizeMax = 50f;
			((TMP_Text)PanelTitle).text = Localization.instance.Localize("$almanac_name");
			PanelContent = Utils.FindChild(AlmanacGUI.transform, "$part_Content", (IterativeSearchType)0);
			Transform val4 = Utils.FindChild(AlmanacGUI.transform, "$part_CloseButton", (IterativeSearchType)0);
			Image val5 = default(Image);
			if (((Component)val4).TryGetComponent<Image>(ref val5))
			{
				val5.sprite = CacheAssets.ButtonImage.sprite;
				((Graphic)val5).material = ((Graphic)CacheAssets.ButtonImage).material;
				Button val6 = default(Button);
				if (((Component)val4).TryGetComponent<Button>(ref val6))
				{
					((Selectable)val6).transition = (Transition)2;
					((Selectable)val6).spriteState = ((Selectable)CacheAssets.ButtonComponent).spriteState;
					((UnityEvent)val6.onClick).AddListener(new UnityAction(ToggleButtonOptions));
					ButtonSfx val7 = ((Component)val4).gameObject.AddComponent<ButtonSfx>();
					val7.m_sfxPrefab = CacheAssets.ButtonSFX.m_sfxPrefab;
					PanelButton = Utility.AddTextMeshProGUI(((Component)val4.Find("Text")).gameObject, bold: false, (TextWrappingModes)1);
					((TMP_Text)PanelButton).fontSize = 16f;
					((TMP_Text)PanelButton).fontSizeMin = 5f;
					((TMP_Text)PanelButton).fontSizeMax = 20f;
					((TMP_Text)PanelButton).text = Localization.instance.Localize("$almanac_stats_button");
				}
			}
		}

		public static void SetCheckmarkVisible()
		{
			AchievementCheckmark.SetActive(Categories.SelectedTab == "$almanac_achievements_button");
		}

		private static void CreateFilterCompletedAchievementsButton(GameObject parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			GameObject val = new GameObject("completed_achievements");
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = new Vector2(150f, 905f);
			val2.sizeDelta = new Vector2(50f, 50f);
			((Transform)val2).SetParent(parent.transform);
			val.SetActive(true);
			Image val3 = val.AddComponent<Image>();
			val3.sprite = SpriteManager.Checkmark;
			val3.type = (Type)0;
			val3.pixelsPerUnitMultiplier = 1f;
			val3.preserveAspect = true;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).interactable = true;
			((Behaviour)val4).enabled = true;
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			((Selectable)val4).transition = (Transition)1;
			ColorBlock colors = default(ColorBlock);
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 1f, 1f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.5f, 0.5f, 0.5f, 1f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0f, 0f, 0f, 1f);
			((ColorBlock)(ref colors)).colorMultiplier = 1f;
			((ColorBlock)(ref colors)).fadeDuration = 0.1f;
			((ColorBlock)(ref colors)).normalColor = new Color(0.5f, 0.5f, 0.5f, 1f);
			((ColorBlock)(ref colors)).selectedColor = Color.white;
			((Selectable)val4).colors = colors;
			ButtonClickedEvent onClick = val4.onClick;
			object obj = <>c.<>9__23_0;
			if (obj == null)
			{
				UnityAction val5 = delegate
				{
					if (Object.op_Implicit((Object)(object)InventoryGui.instance))
					{
						UpdateAlmanac.DestroyTrophies(InventoryGui.instance);
						UpdateAlmanac.UpdateAchievementList(InventoryGui.instance, AchievementManager.GetAchievements(), completed: true);
					}
				};
				<>c.<>9__23_0 = val5;
				obj = (object)val5;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			val.AddComponent<ButtonSfx>().m_sfxPrefab = CacheAssets.ButtonSFX.m_sfxPrefab;
			AchievementCheckmark = val;
		}

		private static void ToggleButtonOptions()
		{
			if (UpdateAlmanac.isMetricsActive)
			{
				UpdateAlmanac.UpdateLeaderboardPanel();
			}
			else
			{
				UpdateAlmanac.UpdateMetricsPanel();
			}
		}

		private static void CreateAchievementPanel(InventoryGui GUI)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Expected O, but got Unknown
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Expected O, but got Unknown
			if ((Object)(object)AchievementGUI != (Object)null)
			{
				return;
			}
			AchievementGUI = Object.Instantiate<GameObject>(CacheAssets.AchievementPanel, ((Component)GUI).transform);
			AchievementGUI.SetActive(false);
			Transform transform = AchievementGUI.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			val.anchoredPosition = new Vector2(680f, 0f);
			AchievementPanelImage = ((Component)Utils.FindChild(AchievementGUI.transform, "Panel", (IterativeSearchType)0)).GetComponent<Image>();
			((Graphic)AchievementPanelImage).material = ((Graphic)CacheAssets.WoodPanel).material;
			AchievementPanelImage.sprite = CacheAssets.WoodPanel.sprite;
			((Graphic)AchievementPanelImage).color = ((AlmanacPlugin._PanelImage.Value == AlmanacPlugin.Toggle.Off) ? Color.white : Color.clear);
			Transform val2 = Utils.FindChild(AchievementGUI.transform, "icon_bkg", (IterativeSearchType)0);
			Image val3 = default(Image);
			if (!((Component)val2).TryGetComponent<Image>(ref val3))
			{
				return;
			}
			val3.sprite = CacheAssets.TrophyImage.sprite;
			((Graphic)val3).material = ((Graphic)CacheAssets.TrophyImage).material;
			Transform val4 = Utils.FindChild(AchievementGUI.transform, "$part_icon", (IterativeSearchType)0);
			if (!Object.op_Implicit((Object)(object)((Component)val4).GetComponent<ButtonSfx>()))
			{
				ButtonSfx val5 = ((Component)val4).gameObject.AddComponent<ButtonSfx>();
				val5.m_sfxPrefab = CacheAssets.ButtonSFX.m_sfxPrefab;
			}
			Button achievementButton = default(Button);
			if (!((Component)val4).TryGetComponent<Button>(ref achievementButton))
			{
				return;
			}
			AchievementButton = achievementButton;
			AchievementPanelIcon = ((Component)val4).GetComponent<Image>();
			AchievementPanelIcon.sprite = SpriteManager.AlmanacIcon;
			AchievementPanelTitle = Utility.AddTextMeshProGUI(((Component)Utils.FindChild(AchievementGUI.transform, "$part_name", (IterativeSearchType)0)).gameObject, bold: true, (TextWrappingModes)1);
			((TMP_Text)AchievementPanelTitle).fontSize = 40f;
			((TMP_Text)AchievementPanelTitle).fontSizeMin = 20f;
			((TMP_Text)AchievementPanelTitle).fontSizeMax = 50f;
			((TMP_Text)AchievementPanelTitle).text = "Achievement";
			AchievementPanelDesc = Utility.AddTextMeshProGUI(((Component)Utils.FindChild(AchievementGUI.transform, "$part_desc", (IterativeSearchType)0)).gameObject, bold: false, (TextWrappingModes)1);
			((TMP_Text)AchievementPanelDesc).fontSize = 25f;
			((TMP_Text)AchievementPanelDesc).fontSizeMin = 16f;
			((TMP_Text)AchievementPanelDesc).fontSizeMax = 30f;
			((TMP_Text)AchievementPanelDesc).text = "Description";
			((Graphic)AchievementPanelDesc).color = Color.white;
			AchievementPanelTooltip = Utility.AddTextMeshProGUI(((Component)Utils.FindChild(AchievementGUI.transform, "$part_tooltip", (IterativeSearchType)0)).gameObject, bold: false, (TextWrappingModes)1);
			((TMP_Text)AchievementPanelTooltip).fontSize = 16f;
			((TMP_Text)AchievementPanelTooltip).fontSizeMin = 14f;
			((TMP_Text)AchievementPanelTooltip).fontSizeMax = 20f;
			((TMP_Text)AchievementPanelTooltip).text = "Tooltip";
			((Graphic)AchievementPanelTooltip).color = Color.white;
			AchievementPanelLore = Utility.AddTextMeshProGUI(((Component)Utils.FindChild(AchievementGUI.transform, "$part_lore", (IterativeSearchType)0)).gameObject, bold: false, (TextWrappingModes)1);
			((TMP_Text)AchievementPanelLore).fontSize = 18f;
			((TMP_Text)AchievementPanelLore).fontSizeMin = 12f;
			((TMP_Text)AchievementPanelLore).fontSizeMax = 25f;
			((TMP_Text)AchievementPanelLore).text = "Lore";
			((Graphic)AchievementPanelLore).color = Color.white;
			Transform val6 = Utils.FindChild(AchievementGUI.transform, "$part_CloseButton", (IterativeSearchType)0);
			Image val7 = default(Image);
			if (((Component)val6).TryGetComponent<Image>(ref val7))
			{
				val7.sprite = CacheAssets.ButtonImage.sprite;
				((Graphic)val7).material = ((Graphic)CacheAssets.ButtonImage).material;
			}
			Button val8 = default(Button);
			if (((Component)val6).TryGetComponent<Button>(ref val8))
			{
				((Selectable)val8).transition = (Transition)2;
				((Selectable)val8).spriteState = ((Selectable)CacheAssets.ButtonComponent).spriteState;
				ButtonClickedEvent onClick = val8.onClick;
				object obj = <>c.<>9__25_0;
				if (obj == null)
				{
					UnityAction val9 = delegate
					{
						AchievementPanelIcon.sprite = SpriteManager.AlmanacIcon;
						((TMP_Text)AchievementPanelTitle).text = Localization.instance.Localize("$almanac_name");
						((TMP_Text)AchievementPanelDesc).text = "";
						((TMP_Text)AchievementPanelLore).text = "";
						((TMP_Text)AchievementPanelTooltip).text = "";
						ToggleButtonOptions();
					};
					<>c.<>9__25_0 = val9;
					obj = (object)val9;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
			}
			ButtonSfx val10 = ((Component)val6).gameObject.AddComponent<ButtonSfx>();
			val10.m_sfxPrefab = CacheAssets.ButtonSFX.m_sfxPrefab;
			AchievementPanelButton = Utility.AddTextMeshProGUI(((Component)val6.Find("Text")).gameObject, bold: true, (TextWrappingModes)1);
			((TMP_Text)AchievementPanelButton).fontSize = 16f;
			((TMP_Text)AchievementPanelButton).fontSizeMin = 5f;
			((TMP_Text)AchievementPanelButton).fontSizeMax = 20f;
			((TMP_Text)AchievementPanelButton).text = Localization.instance.Localize("$almanac_stats_button");
			((UnityEvent)AchievementButton.onClick).AddListener(new UnityAction(OnClickAchievement));
		}

		private static void OnClickAchievement()
		{
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return;
			}
			ISerializer serializer = new SerializerBuilder().Build();
			IDeserializer deserializer = new DeserializerBuilder().Build();
			if (UpdateAlmanac.SelectedAchievement.m_rewardType == AchievementTypes.AchievementRewardType.Item)
			{
				if (UpdateAlmanac.SelectedAchievement.m_collectedReward)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$almanac_collected_reward_already", 0, (Sprite)null);
					return;
				}
				if (UpdateAlmanac.SelectedAchievement.m_item == null || UpdateAlmanac.SelectedAchievement.m_item_amount <= 0)
				{
					return;
				}
				Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
				if (!inventory.CanAddItem(UpdateAlmanac.SelectedAchievement.m_item, UpdateAlmanac.SelectedAchievement.m_item_amount))
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$almanac_inventory_full", 0, (Sprite)null);
					return;
				}
				ItemData val = UpdateAlmanac.SelectedAchievement.m_item.Clone();
				val.m_stack = UpdateAlmanac.SelectedAchievement.m_item_amount;
				inventory.AddItem(val);
				UpdateAlmanac.SelectedAchievement.m_collectedReward = true;
				((Character)Player.m_localPlayer).Message((MessageType)2, $"$almanac_collected_item {val.m_shared.m_name} x{UpdateAlmanac.SelectedAchievement.m_item_amount}", 0, (Sprite)null);
				if (Player.m_localPlayer.m_customData.TryGetValue(AchievementManager.CollectedRewardKey, out var value))
				{
					List<string> list = deserializer.Deserialize<List<string>>(value);
					list.Add(UpdateAlmanac.SelectedAchievement.m_uniqueName);
					string value2 = serializer.Serialize(list);
					Player.m_localPlayer.m_customData[AchievementManager.CollectedRewardKey] = value2;
				}
				else
				{
					List<string> graph = new List<string> { UpdateAlmanac.SelectedAchievement.m_uniqueName };
					string value3 = serializer.Serialize(graph);
					Player.m_localPlayer.m_customData[AchievementManager.CollectedRewardKey] = value3;
				}
				if (UpdateAlmanac.SelectedAchievement.m_class_experience > 0)
				{
					ClassesAPI.AddEXP(UpdateAlmanac.SelectedAchievement.m_class_experience);
				}
			}
			if (UpdateAlmanac.SelectedAchievement.m_rewardType == AchievementTypes.AchievementRewardType.Skill)
			{
				if (UpdateAlmanac.SelectedAchievement.m_collectedReward)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$almanac_collected_reward_already", 0, (Sprite)null);
					return;
				}
				if ((int)UpdateAlmanac.SelectedAchievement.m_skill == 0 || UpdateAlmanac.SelectedAchievement.m_skillAmount <= 0)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$almanac_failed_to_find_skill", 0, (Sprite)null);
					return;
				}
				((Character)Player.m_localPlayer).RaiseSkill(UpdateAlmanac.SelectedAchievement.m_skill, (float)UpdateAlmanac.SelectedAchievement.m_skillAmount);
				UpdateAlmanac.SelectedAchievement.m_collectedReward = true;
				if (Player.m_localPlayer.m_customData.TryGetValue(AchievementManager.CollectedRewardKey, out var value4))
				{
					List<string> list2 = deserializer.Deserialize<List<string>>(value4);
					list2.Add(UpdateAlmanac.SelectedAchievement.m_uniqueName);
					string value5 = serializer.Serialize(list2);
					Player.m_localPlayer.m_customData[AchievementManager.CollectedRewardKey] = value5;
				}
				else
				{
					List<string> graph2 = new List<string> { UpdateAlmanac.SelectedAchievement.m_uniqueName };
					string value6 = serializer.Serialize(graph2);
					Player.m_localPlayer.m_customData[AchievementManager.CollectedRewardKey] = value6;
				}
				((Character)Player.m_localPlayer).Message((MessageType)2, $"$almanac_raised_skill {Utility.SplitCamelCase(((object)(SkillType)(ref UpdateAlmanac.SelectedAchievement.m_skill)).ToString())} $almanac_by {UpdateAlmanac.SelectedAchievement.m_skillAmount}", 0, (Sprite)null);
			}
			if (UpdateAlmanac.SelectedAchievement.m_rewardType != 0 || (Object)(object)UpdateAlmanac.SelectedAchievement.m_statusEffect == (Object)null)
			{
				return;
			}
			if (UpdateAlmanac.SelectedAchievement.m_statusEffect.m_ttl > 0f)
			{
				Player.m_localPlayer.m_guardianSE = UpdateAlmanac.SelectedAchievement.m_statusEffect;
				Player.m_localPlayer.m_guardianPower = ((Object)UpdateAlmanac.SelectedAchievement.m_statusEffect).name;
				Player.m_localPlayer.m_guardianPowerHash = StringExtensionMethods.GetStableHashCode(((Object)UpdateAlmanac.SelectedAchievement.m_statusEffect).name);
				return;
			}
			SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan();
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode(((Object)UpdateAlmanac.SelectedAchievement.m_statusEffect).name)))
			{
				if (sEMan.RemoveStatusEffect(UpdateAlmanac.SelectedAchievement.m_statusEffect, true))
				{
					AlmanacEffectManager.ActiveAchievementEffects.Remove(UpdateAlmanac.SelectedAchievement.m_statusEffect);
					AlmanacEffectManager.SavedAchievementEffectNames.Remove(((Object)UpdateAlmanac.SelectedAchievement.m_statusEffect).name);
					Player.m_localPlayer.m_customData[AlmanacEffectManager.AchievementKey] = serializer.Serialize(AlmanacEffectManager.SavedAchievementEffectNames);
					((Character)Player.m_localPlayer).Message((MessageType)2, "$almanac_removed_effect " + UpdateAlmanac.SelectedAchievement.m_statusEffect.m_name, 0, (Sprite)null);
					if (Object.op_Implicit((Object)(object)InventoryGui.instance))
					{
						UpdateAlmanac.UpdateList(InventoryGui.instance);
					}
				}
				return;
			}
			int count = sEMan.GetStatusEffects().FindAll([<95fcf0cd-774f-48db-8185-aea0576159b3>NullableContext(0)] (StatusEffect effect) => effect is AlmanacEffectManager.AchievementEffect).Count;
			if (count >= AlmanacPlugin._AchievementThreshold.Value)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "$almanac_too_many_achievements", 0, (Sprite)null);
				return;
			}
			sEMan.AddStatusEffect(UpdateAlmanac.SelectedAchievement.m_statusEffect, false, 0, 0f);
			AlmanacEffectManager.ActiveAchievementEffects.Add(UpdateAlmanac.SelectedAchievement.m_statusEffect);
			if (AlmanacEffectManager.SavedAchievementEffectNames.Count <= 3)
			{
				AlmanacEffectManager.SavedAchievementEffectNames.Add(((Object)UpdateAlmanac.SelectedAchievement.m_statusEffect).name);
				Player.m_localPlayer.m_customData[AlmanacEffectManager.AchievementKey] = serializer.Serialize(AlmanacEffectManager.SavedAchievementEffectNames);
				if (Object.op_Implicit((Object)(object)InventoryGui